Browse Source

Simplified geometry rendering by using Cairo.Path and caching StreamGeometryContextImpl

pull/114/head
Nelson Carrillo 11 years ago
parent
commit
06a99e6d88
  1. 27
      src/Gtk/Perspex.Cairo/Media/DrawingContext.cs
  2. 40
      src/Gtk/Perspex.Cairo/Media/StreamGeometryContextImpl.cs
  3. 55
      src/Gtk/Perspex.Cairo/Media/StreamGeometryImpl.cs

27
src/Gtk/Perspex.Cairo/Media/DrawingContext.cs

@ -119,35 +119,10 @@ namespace Perspex.Cairo.Media
public void DrawGeometry(Perspex.Media.Brush brush, Perspex.Media.Pen pen, Perspex.Media.Geometry geometry) public void DrawGeometry(Perspex.Media.Brush brush, Perspex.Media.Pen pen, Perspex.Media.Geometry geometry)
{ {
var impl = geometry.PlatformImpl as StreamGeometryImpl; var impl = geometry.PlatformImpl as StreamGeometryImpl;
var clone = new Queue<GeometryOp>(impl.Operations);
using (var pop = this.PushTransform(impl.Transform)) using (var pop = this.PushTransform(impl.Transform))
{ {
while (clone.Count > 0) this.context.AppendPath(impl.Path);
{
var current = clone.Dequeue();
if (current is BeginOp)
{
var bo = current as BeginOp;
this.context.MoveTo(bo.Point.ToCairo());
}
else if (current is LineToOp)
{
var lto = current as LineToOp;
this.context.LineTo(lto.Point.ToCairo());
}
else if (current is EndOp)
{
if (((EndOp)current).IsClosed)
this.context.ClosePath();
}
else if (current is CurveToOp)
{
var cto = current as CurveToOp;
this.context.CurveTo(cto.Point.ToCairo(), cto.Point2.ToCairo(), cto.Point3.ToCairo());
}
}
if (brush != null) if (brush != null)
{ {

40
src/Gtk/Perspex.Cairo/Media/StreamGeometryContextImpl.cs

@ -28,17 +28,17 @@ namespace Perspex.Cairo.Media
public void BeginFigure(Point startPoint, bool isFilled) public void BeginFigure(Point startPoint, bool isFilled)
{ {
this.impl.Operations.Enqueue(new BeginOp { Point = startPoint, IsFilled = isFilled }); this.context.MoveTo(startPoint.ToCairo());
} }
public void BezierTo(Point point1, Point point2, Point point3) public void BezierTo(Point point1, Point point2, Point point3)
{ {
this.impl.Operations.Enqueue(new CurveToOp { Point = point1, Point2 = point2, Point3 = point3 }); this.context.CurveTo(point1.ToCairo(), point2.ToCairo(), point3.ToCairo());
} }
public void LineTo(Point point) public void LineTo(Point point)
{ {
this.impl.Operations.Enqueue(new LineToOp { Point = point }); this.context.LineTo(point.ToCairo());
} }
private Cairo.Context context; private Cairo.Context context;
@ -46,38 +46,12 @@ namespace Perspex.Cairo.Media
public void EndFigure(bool isClosed) public void EndFigure(bool isClosed)
{ {
this.impl.Operations.Enqueue(new EndOp { IsClosed = isClosed }); if (isClosed)
this.context.ClosePath();
var clone = new Queue<GeometryOp>(this.impl.Operations);
while (clone.Count > 0)
{
var current = clone.Dequeue();
if (current is BeginOp) var extents = this.context.StrokeExtents();
{
var bo = current as BeginOp;
context.MoveTo(bo.Point.ToCairo());
}
else if (current is LineToOp)
{
var lto = current as LineToOp;
context.LineTo(lto.Point.ToCairo());
}
else if (current is EndOp)
{
if (((EndOp)current).IsClosed)
context.ClosePath();
}
else if (current is CurveToOp)
{
var cto = current as CurveToOp;
context.CurveTo(cto.Point.ToCairo(), cto.Point2.ToCairo(), cto.Point3.ToCairo());
}
}
var extents = context.StrokeExtents();
this.impl.Bounds = new Rect(extents.X, extents.Y, extents.Width, extents.Height); this.impl.Bounds = new Rect(extents.X, extents.Y, extents.Width, extents.Height);
this.impl.Path = this.context.CopyPath();
} }
public void Dispose() public void Dispose()

55
src/Gtk/Perspex.Cairo/Media/StreamGeometryImpl.cs

@ -13,57 +13,23 @@ namespace Perspex.Cairo.Media
using Splat; using Splat;
using System.Collections.Generic; using System.Collections.Generic;
public enum CairoGeometryType
{
Begin,
ArcTo,
LineTo,
End
}
public class BeginOp : GeometryOp
{
public Point Point { get; set; }
public bool IsFilled { get; set; }
}
public class EndOp : GeometryOp
{
public bool IsClosed { get; set; }
}
public class LineToOp : GeometryOp
{
public Point Point { get; set; }
}
public class CurveToOp : GeometryOp
{
public Point Point { get; set; }
public Point Point2 { get; set; }
public Point Point3 { get; set; }
}
public abstract class GeometryOp
{
}
public class StreamGeometryImpl : IStreamGeometryImpl public class StreamGeometryImpl : IStreamGeometryImpl
{ {
public StreamGeometryImpl() public StreamGeometryImpl()
{ {
this.Operations = new Queue<GeometryOp>(); this.impl = new StreamGeometryContextImpl(this);
} }
public StreamGeometryImpl(Queue<GeometryOp> ops) public StreamGeometryImpl(Cairo.Path path)
{ {
this.Operations = ops; this.impl = new StreamGeometryContextImpl(this);
this.Path = path;
} }
public Queue<GeometryOp> Operations public Cairo.Path Path
{ {
get; get;
private set; set;
} }
public Rect Bounds public Rect Bounds
@ -72,7 +38,8 @@ namespace Perspex.Cairo.Media
set; set;
} }
// TODO: Implement private StreamGeometryContextImpl impl;
private Matrix transform = Matrix.Identity; private Matrix transform = Matrix.Identity;
public Matrix Transform public Matrix Transform
{ {
@ -91,7 +58,7 @@ namespace Perspex.Cairo.Media
public IStreamGeometryImpl Clone() public IStreamGeometryImpl Clone()
{ {
return new StreamGeometryImpl(this.Operations); return new StreamGeometryImpl(this.Path);
} }
public Rect GetRenderBounds(double strokeThickness) public Rect GetRenderBounds(double strokeThickness)
@ -101,7 +68,7 @@ namespace Perspex.Cairo.Media
public IStreamGeometryContextImpl Open() public IStreamGeometryContextImpl Open()
{ {
return new StreamGeometryContextImpl(this); return this.impl;
} }
} }
} }

Loading…
Cancel
Save