/// <summary> /// Draws a bitmap image. /// </summary> /// <param name="source">The bitmap image.</param> /// <param name="opacity">The opacity to draw with.</param> /// <param name="sourceRect">The rect in the image to draw.</param> /// <param name="destRect">The rect in the output to draw to.</param> public void DrawImage(IBitmapImpl bitmap, double opacity, Rect sourceRect, Rect destRect) { var pixbuf = bitmap as Gdk.Pixbuf; var rtb = bitmap as RenderTargetBitmapImpl; var size = new Size(pixbuf?.Width ?? rtb.PixelWidth, pixbuf?.Height ?? rtb.PixelHeight); var scale = new Vector(destRect.Width / sourceRect.Width, destRect.Height / sourceRect.Height); _context.Save(); _context.Scale(scale.X, scale.Y); destRect /= scale; _context.PushGroup(); if (pixbuf != null) { Gdk.CairoHelper.SetSourcePixbuf( _context, pixbuf, -sourceRect.X + destRect.X, -sourceRect.Y + destRect.Y); } else { _context.SetSourceSurface( rtb.Surface, (int)(-sourceRect.X + destRect.X), (int)(-sourceRect.Y + destRect.Y)); } _context.Rectangle(destRect.ToCairo()); _context.Fill(); _context.PopGroupToSource(); _context.PaintWithAlpha(opacityOverride); _context.Restore(); }
void DrawPixbuf(Cairo.Context ctx, Gdk.Pixbuf img, double x, double y, ImageDescription idesc) { ctx.Save(); ctx.Translate(x, y); ctx.Scale(idesc.Size.Width / (double)img.Width, idesc.Size.Height / (double)img.Height); Gdk.CairoHelper.SetSourcePixbuf(ctx, img, 0, 0); #pragma warning disable 618 using (var p = ctx.Source) { var pattern = p as Cairo.SurfacePattern; if (pattern != null) { if (idesc.Size.Width > img.Width || idesc.Size.Height > img.Height) { // Fixes blur issue when rendering on an image surface pattern.Filter = Cairo.Filter.Fast; } else { pattern.Filter = Cairo.Filter.Good; } } } #pragma warning restore 618 if (idesc.Alpha >= 1) { ctx.Paint(); } else { ctx.PaintWithAlpha(idesc.Alpha); } ctx.Restore(); }
void RenderIcon(Cairo.Context context, SurfaceWrapper surface, double opacity) { context.SetSourceSurface(surface.Surface, Allocation.X + (Allocation.Width - surface.Width) / 2, Allocation.Y + (Allocation.Height - surface.Height) / 2); context.PaintWithAlpha(opacity); }
public static Gdk.Pixbuf WithAlpha (this Gdk.Pixbuf image, double opacity) { using (var surf = new Cairo.ImageSurface (Cairo.Format.Argb32, image.Width, image.Height)) { using (var g = new Cairo.Context (surf)) { CairoHelper.SetSourcePixbuf (g, image, 0, 0); g.PaintWithAlpha (opacity); } return new Gdk.Pixbuf (surf.Data, true, 8, surf.Width, surf.Height, surf.Stride); } }
public static Gdk.Pixbuf WithAlpha(this Gdk.Pixbuf image, double opacity) { using (var surf = new Cairo.ImageSurface(Cairo.Format.Argb32, image.Width, image.Height)) { using (var g = new Cairo.Context(surf)) { CairoHelper.SetSourcePixbuf(g, image, 0, 0); g.PaintWithAlpha(opacity); } return(new Gdk.Pixbuf(surf.Data, true, 8, surf.Width, surf.Height, surf.Stride)); } }
protected override void TileDrawer(int index, Cairo.Context cr) { int roomIndex = (Map.MainGroup << 8) | index; base.TileDrawer(index, cr); if (DarkenUsedDungeonRooms && Project.RoomUsedInDungeon(roomIndex)) { cr.SetSourceRGB(0, 0, 0); cr.PaintWithAlpha(0.8); } }
/// <summary> /// Draws a bitmap image. /// </summary> /// <param name="source">The bitmap image.</param> /// <param name="opacity">The opacity to draw with.</param> /// <param name="sourceRect">The rect in the image to draw.</param> /// <param name="destRect">The rect in the output to draw to.</param> public void DrawImage(IBitmap bitmap, double opacity, Rect sourceRect, Rect destRect) { var impl = bitmap.PlatformImpl as BitmapImpl; var size = new Size(impl.PixelWidth, impl.PixelHeight); var scale = new Vector(destRect.Width / sourceRect.Width, destRect.Height / sourceRect.Height); _context.Save(); _context.Scale(scale.X, scale.Y); destRect /= scale; if (opacityOverride < 1.0f) { _context.PushGroup(); Gdk.CairoHelper.SetSourcePixbuf( _context, impl.Surface, -sourceRect.X + destRect.X, -sourceRect.Y + destRect.Y); _context.Rectangle(destRect.ToCairo()); _context.Fill(); _context.PopGroupToSource(); _context.PaintWithAlpha(opacityOverride); } else { _context.PushGroup(); Gdk.CairoHelper.SetSourcePixbuf( _context, impl.Surface, -sourceRect.X + destRect.X, -sourceRect.Y + destRect.Y); _context.Rectangle(destRect.ToCairo()); _context.Fill(); _context.PopGroupToSource(); _context.PaintWithAlpha(opacityOverride); } _context.Restore(); }
// Used by the workspace drawing area expose render loop. // Takes care of the clipping. public void RenderLivePreviewLayer(Cairo.Context ctx, double opacity) { if (!IsEnabled) { throw new InvalidOperationException("Tried to render a live preview after live preview has ended."); } // TODO remove seam around selection during live preview. ctx.Save(); if (selection_path != null) { // Paint area outsize of the selection path, with the pre-effect image. var imageSize = PintaCore.Workspace.ImageSize; ctx.Rectangle(0, 0, imageSize.Width, imageSize.Height); ctx.AppendPath(selection_path); ctx.Clip(); ctx.SetSourceSurface(layer.Surface, (int)layer.Offset.X, (int)layer.Offset.Y); ctx.PaintWithAlpha(opacity); ctx.ResetClip(); // Paint area inside the selection path, with the post-effect image. ctx.AppendPath(selection_path); ctx.Clip(); ctx.SetSourceSurface(live_preview_surface, (int)layer.Offset.X, (int)layer.Offset.Y); ctx.PaintWithAlpha(opacity); ctx.AppendPath(selection_path); ctx.FillRule = Cairo.FillRule.EvenOdd; ctx.Clip(); } else { ctx.SetSourceSurface(live_preview_surface, (int)layer.Offset.X, (int)layer.Offset.Y); ctx.PaintWithAlpha(opacity); } ctx.Restore(); }
private void UpdateThumbnail() { double scalex = (double)Allocation.Width / (double)PintaCore.Workspace.ImageSize.Width; double scaley = (double)Allocation.Height / (double)PintaCore.Workspace.ImageSize.Height; thumbnail = new Cairo.ImageSurface(Cairo.Format.Argb32, Allocation.Width, Allocation.Height); using (Cairo.Context g = new Cairo.Context(thumbnail)) { g.Scale(scalex, scaley); foreach (Layer layer in PintaCore.Layers.GetLayersToPaint()) { g.SetSourceSurface(layer.Surface, (int)layer.Offset.X, (int)layer.Offset.Y); g.PaintWithAlpha(layer.Opacity); } } }
void DrawPixbuf(Cairo.Context ctx, Gdk.Pixbuf img, double x, double y, ImageDescription idesc) { ctx.Save(); ctx.Translate(x, y); ctx.Scale(idesc.Size.Width / (double)img.Width, idesc.Size.Height / (double)img.Height); Gdk.CairoHelper.SetSourcePixbuf(ctx, img, 0, 0); if (idesc.Alpha == 1) { ctx.Paint(); } else { ctx.PaintWithAlpha(idesc.Alpha); } ctx.Restore(); }
public void Fill(object backend) { var gtkc = (CairoContextBackend)backend; Cairo.Context ctx = gtkc.Context; if (gtkc.GlobalAlpha == 1) { ctx.Fill(); } else { ctx.PushGroup(); ctx.Fill(); ctx.PopGroupToSource(); ctx.PaintWithAlpha(gtkc.GlobalAlpha); } }
protected override void TileDrawer(int index, Cairo.Context cr) { base.TileDrawer(index, cr); int x = index % Width; int y = index / Width; cr.Save(); if (GetSelected(x, y)) { cr.SetSourceRGB(1.0, 0, 0); //cr.Rectangle(0, 0, TileWidth, TileHeight); cr.PaintWithAlpha(0.4); CairoHelper.DrawRectOutline(cr, 1, new Cairo.Rectangle(0, 0, TileWidth, TileHeight)); } cr.Restore(); }
/// TODO: CairoExtensions.CachedDraw seems not to work correctly for me. public static void CachedDraw(Cairo.Context self, ref SurfaceWrapper surface, Gdk.Rectangle region, object parameters = null, float opacity = 1.0f, Action <Cairo.Context, float> draw = null, double?forceScale = null) { double displayScale = forceScale.HasValue ? forceScale.Value : QuartzSurface.GetRetinaScale(self); int targetWidth = (int)(region.Width * displayScale); int targetHeight = (int)(region.Height * displayScale); bool redraw = false; if (surface == null || surface.Width != targetWidth || surface.Height != targetHeight) { if (surface != null) { surface.Dispose(); } surface = new SurfaceWrapper(self, targetWidth, targetHeight); redraw = true; } else if ((surface.Data == null && parameters != null) || (surface.Data != null && !surface.Data.Equals(parameters))) { redraw = true; } if (redraw) { surface.Data = parameters; using (var context = new Cairo.Context(surface.Surface)) { context.Operator = Cairo.Operator.Clear; context.Paint(); context.Operator = Cairo.Operator.Over; context.Save(); context.Scale(displayScale, displayScale); draw(context, 1.0f); context.Restore(); } } self.Save(); self.Translate(region.X, region.Y); self.Scale(1 / displayScale, 1 / displayScale); self.SetSourceSurface(surface.Surface, 0, 0); self.PaintWithAlpha(opacity); self.Restore(); }
public override void FillPreserve(object backend) { var gtkc = (CairoContextBackend)backend; Cairo.Context ctx = gtkc.Context; var alpha = gtkc.GlobalAlpha * gtkc.PatternAlpha; if (alpha == 1) { ctx.FillPreserve(); } else { ctx.Save(); ctx.ClipPreserve(); ctx.PaintWithAlpha(alpha); ctx.Restore(); } }
public virtual void Render(Cairo.Context cr) { double opacity = Opacity; if (ContentAllocation.Width <= 0 || ContentAllocation.Height <= 0 || opacity <= 0) { return; } cr.Save(); if (opacity < 1.0) { cr.PushGroup(); } MarginStyle margin_style = MarginStyle; if (margin_style != null && margin_style != MarginStyle.None) { cr.Translate(Math.Round(Allocation.X), Math.Round(Allocation.Y)); cr.Save(); margin_style.Apply(this, cr); cr.Restore(); cr.Translate(Math.Round(Margin.Left), Math.Round(Margin.Top)); } else { cr.Translate(Math.Round(ContentAllocation.X), Math.Round(ContentAllocation.Y)); } cr.Antialias = Cairo.Antialias.Default; ClippedRender(cr); if (opacity < 1.0) { cr.PopGroupToSource(); cr.PaintWithAlpha(Opacity); } cr.Restore(); }
private static void MakeReflection(Cairo.Context context, Cairo.ImageSurface source, int w, int h) { context.ResetClip(); context.SetSourceSurface(source, 2, 2); context.Paint(); double alpha = -0.3; double step = 1.0 / (double)source.Height; context.Translate(0, h); context.Scale(1, -1); context.SetSourceSurface(source, 2, 2); for (int i = 0; i < source.Height; i++) { context.Rectangle(0, i + 2, w, 1); context.Clip(); alpha += step; context.PaintWithAlpha(Math.Max(Math.Min(alpha, 0.7), 0.0)); context.ResetClip(); } }
protected override bool OnExposeEvent(EventExpose e) { base.OnExposeEvent(e); if (!PintaCore.Workspace.HasOpenDocuments) { return(true); } double scale = PintaCore.Workspace.Scale; int x = (int)PintaCore.Workspace.Offset.X; int y = (int)PintaCore.Workspace.Offset.Y; // Translate our expose area for the whole drawingarea to just our canvas Rectangle canvas_bounds = new Rectangle(x, y, PintaCore.Workspace.CanvasSize.Width, PintaCore.Workspace.CanvasSize.Height); canvas_bounds.Intersect(e.Area); if (canvas_bounds.IsEmpty) { return(true); } canvas_bounds.X -= x; canvas_bounds.Y -= y; // Resize our offscreen surface to a surface the size of our drawing area if (canvas == null || canvas.Width != canvas_bounds.Width || canvas.Height != canvas_bounds.Height) { if (canvas != null) { (canvas as IDisposable).Dispose(); } canvas = new Cairo.ImageSurface(Cairo.Format.Argb32, canvas_bounds.Width, canvas_bounds.Height); } cr.Initialize(PintaCore.Workspace.ImageSize, PintaCore.Workspace.CanvasSize); using (Cairo.Context g = CairoHelper.Create(GdkWindow)) { // Draw our 1 px black border g.DrawRectangle(new Cairo.Rectangle(x, y, PintaCore.Workspace.CanvasSize.Width + 1, PintaCore.Workspace.CanvasSize.Height + 1), new Cairo.Color(0, 0, 0), 1); // Set up our clip rectangle g.Rectangle(new Cairo.Rectangle(x, y, PintaCore.Workspace.CanvasSize.Width, PintaCore.Workspace.CanvasSize.Height)); g.Clip(); g.Translate(x, y); bool checker = true; // Resize each layer and paint it to the screen foreach (Layer layer in PintaCore.Layers.GetLayersToPaint()) { cr.Render(layer.Surface, canvas, canvas_bounds.Location, checker); g.SetSourceSurface(canvas, canvas_bounds.X + (int)(layer.Offset.X * scale), canvas_bounds.Y + (int)(layer.Offset.Y * scale)); g.PaintWithAlpha(layer.Opacity); if (layer == PintaCore.Layers.CurrentLayer && PintaCore.LivePreview.IsEnabled) { cr.Render(PintaCore.LivePreview.LivePreviewSurface, canvas, canvas_bounds.Location, checker); g.Save(); g.Scale(scale, scale); g.AppendPath(PintaCore.Layers.SelectionPath); g.Clip(); g.Scale(1 / scale, 1 / scale); g.SetSourceSurface(canvas, canvas_bounds.X, canvas_bounds.Y); g.PaintWithAlpha(layer.Opacity); g.Restore(); } checker = false; } // If we are at least 200% and grid is requested, draw it if (PintaCore.Actions.View.PixelGrid.Active && cr.ScaleFactor.Ratio <= 0.5d) { gr.Render(canvas, canvas_bounds.Location); g.SetSourceSurface(canvas, canvas_bounds.X, canvas_bounds.Y); g.Paint(); } // Selection outline if (PintaCore.Layers.ShowSelection) { g.Save(); g.Translate(0.5, 0.5); g.Scale(scale, scale); g.AppendPath(PintaCore.Layers.SelectionPath); if (PintaCore.Tools.CurrentTool.Name.Contains("Select") && !PintaCore.Tools.CurrentTool.Name.Contains("Selected")) { g.Color = new Cairo.Color(0.7, 0.8, 0.9, 0.2); g.FillRule = Cairo.FillRule.EvenOdd; g.FillPreserve(); } g.LineWidth = 1 / scale; // Draw a white line first so it shows up on dark backgrounds g.Color = new Cairo.Color(1, 1, 1); g.StrokePreserve(); // Draw a black dashed line over the white line g.SetDash(new double[] { 2 / scale, 4 / scale }, 0); g.Color = new Cairo.Color(0, 0, 0); g.Stroke(); g.Restore(); } } return(true); }
private void UpdateThumbnail() { double scalex = (double)Allocation.Width / (double)PintaCore.Workspace.ImageSize.Width; double scaley = (double)Allocation.Height / (double)PintaCore.Workspace.ImageSize.Height; thumbnail = new Cairo.ImageSurface (Cairo.Format.Argb32, Allocation.Width, Allocation.Height); using (Cairo.Context g = new Cairo.Context (thumbnail)) { g.Scale (scalex, scaley); foreach (Layer layer in PintaCore.Layers.GetLayersToPaint ()) { g.SetSourceSurface (layer.Surface, (int)layer.Offset.X, (int)layer.Offset.Y); g.PaintWithAlpha (layer.Opacity); } } }