public static SurfacePattern CreateImageBrush(ImageBrush brush, Size targetSize) { if (brush.Source == null) { return null; } // TODO: This is directly ported from Direct2D and could probably be made more // efficient on cairo by taking advantage of the fact that cairo has Extend.None. var image = ((BitmapImpl)brush.Source.PlatformImpl).Surface; var imageSize = new Size(brush.Source.PixelWidth, brush.Source.PixelHeight); var tileMode = brush.TileMode; var sourceRect = brush.SourceRect.ToPixels(imageSize); var destinationRect = brush.DestinationRect.ToPixels(targetSize); var scale = brush.Stretch.CalculateScaling(destinationRect.Size, sourceRect.Size); var translate = CalculateTranslate(brush, sourceRect, destinationRect, scale); var intermediateSize = CalculateIntermediateSize(tileMode, targetSize, destinationRect.Size); var intermediate = new ImageSurface (Format.ARGB32, (int)intermediateSize.Width, (int)intermediateSize.Height); using (var context = new Context(intermediate)) { Rect drawRect; var transform = CalculateIntermediateTransform( tileMode, sourceRect, destinationRect, scale, translate, out drawRect); context.Rectangle(drawRect.ToCairo()); context.Clip(); context.Transform(transform.ToCairo()); Gdk.CairoHelper.SetSourcePixbuf(context, image, 0, 0); context.Rectangle(0, 0, imageSize.Width, imageSize.Height); context.Fill(); var result = new SurfacePattern(intermediate); if ((brush.TileMode & TileMode.FlipXY) != 0) { // TODO: Currently always FlipXY as that's all cairo supports natively. // Support separate FlipX and FlipY by drawing flipped images to intermediate // surface. result.Extend = Extend.Reflect; } else { result.Extend = Extend.Repeat; } if (brush.TileMode != TileMode.None) { var matrix = result.Matrix; matrix.InitTranslate(-destinationRect.X, -destinationRect.Y); result.Matrix = matrix; } return result; } }
public static void ShowWithOptions(this DockySurface self, DockySurface target, PointD point, double zoom, double rotation, double opacity) { if (target == null) { throw new ArgumentNullException("target"); } Cairo.Context cr = target.Context; double cos, sin; cos = Math.Cos(rotation); sin = Math.Sin(rotation); Matrix m = new Matrix(cos, sin, -sin, cos, point.X, point.Y); cr.Transform(m); if (zoom != 1) { cr.Scale(zoom, zoom); } cr.SetSource(self.Internal, -self.Width / 2, -self.Height / 2); cr.PaintWithAlpha(opacity); cr.IdentityMatrix(); }
public static void ShowAsReflection(this DockySurface self, DockySurface target, PointD point, double zoom, double rotation, double opacity, double height, DockPosition position) { if (target == null) { throw new ArgumentNullException("target"); } Cairo.Context cr = target.Context; switch (position) { case DockPosition.Left: point.X -= self.Width * zoom + height; break; case DockPosition.Top: point.Y -= self.Height * zoom + height; break; case DockPosition.Right: point.X += self.Width * zoom + height; break; case DockPosition.Bottom: point.Y += self.Height * zoom + height; break; } double cos, sin; cos = Math.Cos(rotation); sin = Math.Sin(rotation); Matrix m = new Matrix(cos, sin, -sin, cos, point.X, point.Y); cr.Transform(m); if (zoom != 1) { cr.Scale(zoom, zoom); } if (position == DockPosition.Left || position == DockPosition.Right) { cr.Scale(-1, 1); } else { cr.Scale(1, -1); } cr.SetSource(self.Internal, -self.Width / 2, -self.Height / 2); cr.PaintWithAlpha(opacity * .3); cr.IdentityMatrix(); }
protected override bool OnExposeEvent(Gdk.EventExpose evnt) { if (evnt.Window != GdkWindow) { return(base.OnExposeEvent(evnt)); } Cairo.Context cr = Gdk.CairoHelper.Create(evnt.Window); if (reflect) { CairoExtensions.PushGroup(cr); } cr.Operator = Operator.Over; cr.Translate(Allocation.X + h_padding, Allocation.Y); cr.Rectangle(0, 0, Allocation.Width - h_padding, Math.Max(2 * bar_height, bar_height + bar_label_spacing + layout_height)); cr.Clip(); Pattern bar = RenderBar(Allocation.Width - 2 * h_padding, bar_height); cr.Save(); cr.SetSource(bar); cr.Paint(); cr.Restore(); if (reflect) { cr.Save(); cr.Rectangle(0, bar_height, Allocation.Width - h_padding, bar_height); cr.Clip(); var matrix = new Matrix(); matrix.InitScale(1, -1); matrix.Translate(0, -(2 * bar_height) + 1); cr.Transform(matrix); cr.SetSource(bar); var mask = new LinearGradient(0, 0, 0, bar_height); mask.AddColorStop(0.25, new Color(0, 0, 0, 0)); mask.AddColorStop(0.5, new Color(0, 0, 0, 0.125)); mask.AddColorStop(0.75, new Color(0, 0, 0, 0.4)); mask.AddColorStop(1.0, new Color(0, 0, 0, 0.7)); cr.Mask(mask); mask.Dispose(); cr.Restore(); CairoExtensions.PopGroupToSource(cr); cr.Paint(); } if (show_labels) { cr.Translate((reflect ? Allocation.X : -h_padding) + (Allocation.Width - layout_width) / 2, (reflect ? Allocation.Y : 0) + bar_height + bar_label_spacing); RenderLabels(cr); } bar.Dispose(); CairoExtensions.DisposeContext(cr); return(true); }
public static SurfacePattern CreateVisualBrush(VisualBrush brush, Size targetSize) { var visual = brush.Visual; if (visual == null) { return null; } var layoutable = visual as ILayoutable; if (layoutable?.IsArrangeValid == false) { layoutable.Measure(Size.Infinity); layoutable.Arrange(new Rect(layoutable.DesiredSize)); } // TODO: This is directly ported from Direct2D and could probably be made more // efficient on cairo by taking advantage of the fact that cairo has Extend.None. var tileMode = brush.TileMode; var sourceRect = brush.SourceRect.ToPixels(layoutable.Bounds.Size); var destinationRect = brush.DestinationRect.ToPixels(targetSize); var scale = brush.Stretch.CalculateScaling(destinationRect.Size, sourceRect.Size); var translate = CalculateTranslate(brush, sourceRect, destinationRect, scale); var intermediateSize = CalculateIntermediateSize(tileMode, targetSize, destinationRect.Size); using (var intermediate = new ImageSurface(Format.ARGB32, (int)intermediateSize.Width, (int)intermediateSize.Height)) using (var context = new Context(intermediate)) { Rect drawRect; var transform = CalculateIntermediateTransform( tileMode, sourceRect, destinationRect, scale, translate, out drawRect); var renderer = new Renderer(intermediate); context.Rectangle(drawRect.ToCairo()); context.Clip(); context.Transform(transform.ToCairo()); renderer.Render(visual, new PlatformHandle(IntPtr.Zero, "RTB"), transform, drawRect); var result = new SurfacePattern(intermediate); if ((brush.TileMode & TileMode.FlipXY) != 0) { // TODO: Currently always FlipXY as that's all cairo supports natively. // Support separate FlipX and FlipY by drawing flipped images to intermediate // surface. result.Extend = Extend.Reflect; } else { result.Extend = Extend.Repeat; } if (brush.TileMode != TileMode.None) { var matrix = result.Matrix; matrix.InitTranslate(-destinationRect.X, -destinationRect.Y); result.Matrix = matrix; } return result; } }
private Surface CreateScene (Cairo.Context window_cr, ImageSurface image, int reflect) { Surface surface = window_cr.Target.CreateSimilar (window_cr.Target.Content, image.Width, image.Height + reflect); Cairo.Context cr = new Context (surface); cr.Save (); cr.SetSource (image); cr.Paint (); cr.Rectangle (0, image.Height, image.Width, reflect); cr.Clip (); Matrix matrix = new Matrix (); matrix.InitScale (1, -1); matrix.Translate (0, -(2 * image.Height) + 1); cr.Transform (matrix); cr.SetSource (image); cr.Paint (); cr.Restore (); Color bg_transparent = BackgroundColor; bg_transparent.A = 0.65; LinearGradient mask = new LinearGradient (0, image.Height, 0, image.Height + reflect); mask.AddColorStop (0, bg_transparent); mask.AddColorStop (1, BackgroundColor); cr.Rectangle (0, image.Height, image.Width, reflect); cr.Pattern = mask; cr.Fill (); ((IDisposable)cr).Dispose (); return surface; }
public static void TileOntoSurface(this DockySurface self, DockySurface target, Gdk.Rectangle area, int edgeBuffer, double tilt, DockPosition orientation) { if (orientation == DockPosition.Left || orientation == DockPosition.Right) { int x = area.X; if (orientation == DockPosition.Left) { x -= self.Width - area.Width; } Cairo.Context cr = target.Context; // draw left edge cr.Rectangle(area.X, area.Y, area.Width, edgeBuffer); cr.SetSource(self.Internal, x, area.Y); cr.Fill(); int maxMiddleMove = self.Height - 2 * edgeBuffer; int position = area.Y + edgeBuffer; int edgeTarget = area.Y + area.Height - edgeBuffer; while (position < edgeTarget) { int height = Math.Min(edgeTarget - position, maxMiddleMove); cr.Rectangle(area.X, position, area.Width, height); cr.SetSource(self.Internal, x, position - edgeBuffer); cr.Fill(); position += height; } cr.Rectangle(area.X, position, area.Width, edgeBuffer); cr.SetSource(self.Internal, x, area.Y + area.Height - self.Height); cr.Fill(); } else { if (tilt != 1) { area.Y += (int)(area.Height * tilt); area.Height -= (int)(area.Height * tilt); } int y = area.Y; if (orientation == DockPosition.Top) { y -= self.Height - area.Height; } Cairo.Context cr = target.Context; cr.Rectangle(area.X - 100, area.Y, edgeBuffer + 100, area.Height); Matrix m = new Matrix(1, 0, -tilt, 1, 0, y); cr.Transform(m); // draw left edge cr.SetSource(self.Internal, area.X, 0); cr.Fill(); cr.IdentityMatrix(); int maxMiddleMove = self.Width - 2 * edgeBuffer; int position = area.X + edgeBuffer; int edgeTarget = area.X + area.Width - edgeBuffer; while (position < edgeTarget) { int width = Math.Min(edgeTarget - position, maxMiddleMove); cr.Rectangle(position, area.Y, width, area.Height); cr.SetSource(self.Internal, position - edgeBuffer, y); cr.Fill(); position += width; } cr.Rectangle(position, area.Y, edgeBuffer + 100, area.Height); m = new Matrix(1, 0, tilt, 1, 0, y); cr.Transform(m); cr.SetSource(self.Internal, area.X + area.Width - self.Width, 0); cr.Fill(); cr.IdentityMatrix(); } }
public void Draw(Context ctx, ImageSurface surface, double opacity, bool transform = true) { ctx.Save (); if (transform) ctx.Transform (Transform); ctx.BlendSurface (surface, BlendMode, opacity); ctx.Restore (); }
public void DrawWithOperator(Context ctx, ImageSurface surface, Operator op, double opacity = 1.0, bool transform = true) { ctx.Save (); if (transform) ctx.Transform (Transform); ctx.Operator = op; ctx.SetSourceSurface (surface, 0, 0); if (opacity >= 1.0) ctx.Paint (); else ctx.PaintWithAlpha (opacity); ctx.Restore (); }
public virtual void ApplyTransform(Matrix xform, Size new_size) { var old_size = PintaCore.Workspace.ImageSize; var dest = new ImageSurface (Format.ARGB32, new_size.Width, new_size.Height); using (var g = new Context (dest)) { g.Transform (xform); g.SetSource (Surface); g.Paint (); } Surface old = Surface; Surface = dest; old.Dispose (); }
protected override bool OnDrawn(Cairo.Context cr) { if (!CairoHelper.ShouldDrawWindow(cr, Window)) { return(base.OnDrawn(cr)); } if (reflect) { cr.PushGroup(); } cr.Operator = Operator.Over; cr.Translate(h_padding, 0); cr.Rectangle(0, 0, Allocation.Width - h_padding, Math.Max(2 * bar_height, bar_height + bar_label_spacing + layout_height)); cr.Clip(); using (var bar = RenderBar(Allocation.Width - 2 * h_padding, bar_height)) { cr.Save(); cr.SetSource(bar); cr.Paint(); cr.Restore(); if (reflect) { cr.Save(); cr.Rectangle(0, bar_height, Allocation.Width - h_padding, bar_height); cr.Clip(); Matrix matrix = new Matrix(); matrix.InitScale(1, -1); matrix.Translate(0, -(2 * bar_height) + 1); cr.Transform(matrix); cr.SetSource(bar); using (var mask = new LinearGradient(0, 0, 0, bar_height)) { mask.AddColorStop(0.25, new Color(0, 0, 0, 0)); mask.AddColorStop(0.5, new Color(0, 0, 0, 0.125)); mask.AddColorStop(0.75, new Color(0, 0, 0, 0.4)); mask.AddColorStop(1.0, new Color(0, 0, 0, 0.7)); cr.Mask(mask); } cr.Restore(); cr.PopGroupToSource(); cr.Paint(); } if (show_labels) { cr.Translate((reflect ? 0 : -h_padding) + (Allocation.Width - layout_width) / 2, bar_height + bar_label_spacing); RenderLabels(cr); } } return(true); }
private Surface CreateScene(Cairo.Context window_cr, ImageSurface image, int reflect) { var target = window_cr.GetTarget (); Surface surface = target.CreateSimilar (target.Content, image.Width, image.Height + reflect); using (var cr = new Context (surface)) { cr.Save (); cr.SetSource (image); cr.Paint (); cr.Rectangle (0, image.Height, image.Width, reflect); cr.Clip (); Matrix matrix = new Matrix (); matrix.InitScale (1, -1); matrix.Translate (0, -(2 * image.Height) + 1); cr.Transform (matrix); cr.SetSource (image); cr.Paint (); cr.Restore (); Color bg_transparent = BackgroundColor; bg_transparent.A = 0.65; using (var mask = new LinearGradient (0, image.Height, 0, image.Height + reflect)) { mask.AddColorStop (0, bg_transparent); mask.AddColorStop (1, BackgroundColor); cr.Rectangle (0, image.Height, image.Width, reflect); cr.SetSource (mask); cr.Fill (); } } return surface; }
void RenderNode(Node current, Context context) { if (current.Renderer == null) AssignRenderers (current); var cairoRenderer = current.Renderer as ICairoRenderer; if (cairoRenderer == null) return; context.Save (); context.Transform (current.GetTransform ()); cairoRenderer.Render (current, context); context.Save (); if (cairoRenderer.Clip) cairoRenderer.ClipChildren (current, context); if (current.Children != null) current.Children.ForEach (n => RenderNode (n, context)); context.Restore (); if (cairoRenderer.Post) cairoRenderer.PostRender (current, context); context.Restore (); }
public void Draw(Context ctx, ImageSurface surface, double opacity) { ctx.Save(); ctx.Transform(Transform); ctx.SetSourceSurface(surface, 0, 0); ctx.PaintWithAlpha(opacity); ctx.Restore(); }