From cd3dc55e54a5a29628982ac6aae19249e9bb5af5 Mon Sep 17 00:00:00 2001 From: Nelson Carrillo Date: Sun, 26 Jul 2015 00:16:01 -0400 Subject: [PATCH 1/2] Fixes RadioButton rendering Fixes CheckBox glyph rendering --- Cairo/Perspex.Cairo/Media/DrawingContext.cs | 24 +++++++-------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/Cairo/Perspex.Cairo/Media/DrawingContext.cs b/Cairo/Perspex.Cairo/Media/DrawingContext.cs index 72cf0c0340..f3ae901fb1 100644 --- a/Cairo/Perspex.Cairo/Media/DrawingContext.cs +++ b/Cairo/Perspex.Cairo/Media/DrawingContext.cs @@ -118,27 +118,17 @@ namespace Perspex.Cairo.Media { var impl = geometry.PlatformImpl as StreamGeometryImpl; var clone = new Queue(impl.Operations); - - bool useFill = false; - this.SetPen(pen); - this.SetBrush(brush); - using (var pop = this.PushTransform(impl.Transform)) { while (clone.Count > 0) { - var current = clone.Dequeue(); if (current is BeginOp) { var bo = current as BeginOp; this.context.MoveTo(bo.Point.ToCairo()); - - useFill = bo.IsFilled; - - System.Diagnostics.Debug.WriteLine("Start"); } else if (current is LineToOp) { @@ -149,8 +139,6 @@ namespace Perspex.Cairo.Media { if (((EndOp)current).IsClosed) this.context.ClosePath(); - - System.Diagnostics.Debug.WriteLine("End"); } else if (current is CurveToOp) { @@ -159,13 +147,17 @@ namespace Perspex.Cairo.Media } } - if (useFill) + if (brush != null) { - this.context.FillPreserve(); + this.SetBrush(brush); + this.context.Fill(); } - else + + + if (pen != null) { - this.context.StrokePreserve(); + this.SetPen(pen); + this.context.Stroke(); } } } From 41842b644e1c932afa3dd7edc728451b68a7ab1d Mon Sep 17 00:00:00 2001 From: Nelson Carrillo Date: Sun, 26 Jul 2015 00:38:44 -0400 Subject: [PATCH 2/2] Fixed memory leaks while drawing geometry Cached surface/context during bounds calculation --- Cairo/Perspex.Cairo/Media/DrawingContext.cs | 15 ++++--- .../Media/StreamGeometryContextImpl.cs | 42 +++++-------------- 2 files changed, 21 insertions(+), 36 deletions(-) diff --git a/Cairo/Perspex.Cairo/Media/DrawingContext.cs b/Cairo/Perspex.Cairo/Media/DrawingContext.cs index f3ae901fb1..b347c2f7b7 100644 --- a/Cairo/Perspex.Cairo/Media/DrawingContext.cs +++ b/Cairo/Perspex.Cairo/Media/DrawingContext.cs @@ -72,10 +72,11 @@ namespace Perspex.Cairo.Media { this.context.Dispose(); - if (this.surface is Cairo.Win32Surface) - { + // if (this.surface is Cairo.Win32Surface) + // { + if (this.surface != null) this.surface.Dispose(); - } + // } } public void DrawImage(IBitmap bitmap, double opacity, Rect sourceRect, Rect destRect) @@ -137,7 +138,7 @@ namespace Perspex.Cairo.Media } else if (current is EndOp) { - if (((EndOp)current).IsClosed) + if (((EndOp)current).IsClosed) this.context.ClosePath(); } else if (current is CurveToOp) @@ -150,7 +151,11 @@ namespace Perspex.Cairo.Media if (brush != null) { this.SetBrush(brush); - this.context.Fill(); + + if (pen != null) + this.context.FillPreserve(); + else + this.context.Fill(); } diff --git a/Cairo/Perspex.Cairo/Media/StreamGeometryContextImpl.cs b/Cairo/Perspex.Cairo/Media/StreamGeometryContextImpl.cs index 8e629283fa..ff9dacca08 100644 --- a/Cairo/Perspex.Cairo/Media/StreamGeometryContextImpl.cs +++ b/Cairo/Perspex.Cairo/Media/StreamGeometryContextImpl.cs @@ -8,6 +8,7 @@ namespace Perspex.Cairo.Media { using Perspex.Media; using Perspex.Platform; + using System; using System.Collections.Generic; using Cairo = global::Cairo; @@ -17,55 +18,38 @@ namespace Perspex.Cairo.Media public StreamGeometryContextImpl(StreamGeometryImpl imp) { this.impl = imp; - points = new List(); + this.surf = new Cairo.ImageSurface(Cairo.Format.Argb32, 0, 0); + this.context = new Cairo.Context(this.surf); } - private List points; - public void ArcTo(Point point, Size size, double rotationAngle, bool isLargeArc, SweepDirection sweepDirection) { - points.Add(point); } public void BeginFigure(Point startPoint, bool isFilled) { this.impl.Operations.Enqueue(new BeginOp { Point = startPoint, IsFilled = isFilled }); - points.Add(startPoint); } public void BezierTo(Point point1, Point point2, Point point3) { this.impl.Operations.Enqueue(new CurveToOp { Point = point1, Point2 = point2, Point3 = point3 }); - points.Add(point1); - points.Add(point2); - points.Add(point3); } public void LineTo(Point point) { this.impl.Operations.Enqueue(new LineToOp { Point = point }); - points.Add(point); } + private Cairo.Context context; + private Cairo.ImageSurface surf; + public void EndFigure(bool isClosed) { this.impl.Operations.Enqueue(new EndOp { IsClosed = isClosed }); - - double maxX = 0; - double maxY = 0; - - foreach (var p in this.points) - { - maxX = System.Math.Max(p.X, maxX); - maxY = System.Math.Max(p.Y, maxY); - } - - var context = new Cairo.Context(new Cairo.ImageSurface(Cairo.Format.Argb32, (int)maxX, (int)maxY)); var clone = new Queue(this.impl.Operations); - - context.LineWidth = 2; - + while (clone.Count > 0) { var current = clone.Dequeue(); @@ -90,20 +74,16 @@ namespace Perspex.Cairo.Media var cto = current as CurveToOp; context.CurveTo(cto.Point.ToCairo(), cto.Point2.ToCairo(), cto.Point3.ToCairo()); } - - context.StrokePreserve(); - context.FillPreserve(); } - var test = context.StrokeExtents(); - this.impl.Bounds = new Rect(test.X, test.Y, test.Width, test.Height); - - context.Dispose(); + var extents = context.StrokeExtents(); + this.impl.Bounds = new Rect(extents.X, extents.Y, extents.Width, extents.Height); } public void Dispose() { - // TODO: Implement + context.Dispose(); + surf.Dispose(); } } }