Browse Source

Merge pull request #67 from ncarrillo/geom-fixes

Geometry fixes for the Cairo backend
pull/69/head
Steven Kirk 11 years ago
parent
commit
e606de9184
  1. 37
      Cairo/Perspex.Cairo/Media/DrawingContext.cs
  2. 42
      Cairo/Perspex.Cairo/Media/StreamGeometryContextImpl.cs

37
Cairo/Perspex.Cairo/Media/DrawingContext.cs

@ -72,10 +72,11 @@ namespace Perspex.Cairo.Media
{ {
this.context.Dispose(); this.context.Dispose();
if (this.surface is Cairo.Win32Surface) // if (this.surface is Cairo.Win32Surface)
{ // {
if (this.surface != null)
this.surface.Dispose(); this.surface.Dispose();
} // }
} }
public void DrawImage(IBitmap bitmap, double opacity, Rect sourceRect, Rect destRect) public void DrawImage(IBitmap bitmap, double opacity, Rect sourceRect, Rect destRect)
@ -118,27 +119,17 @@ namespace Perspex.Cairo.Media
{ {
var impl = geometry.PlatformImpl as StreamGeometryImpl; var impl = geometry.PlatformImpl as StreamGeometryImpl;
var clone = new Queue<GeometryOp>(impl.Operations); var clone = new Queue<GeometryOp>(impl.Operations);
bool useFill = false;
this.SetPen(pen);
this.SetBrush(brush);
using (var pop = this.PushTransform(impl.Transform)) using (var pop = this.PushTransform(impl.Transform))
{ {
while (clone.Count > 0) while (clone.Count > 0)
{ {
var current = clone.Dequeue(); var current = clone.Dequeue();
if (current is BeginOp) if (current is BeginOp)
{ {
var bo = current as BeginOp; var bo = current as BeginOp;
this.context.MoveTo(bo.Point.ToCairo()); this.context.MoveTo(bo.Point.ToCairo());
useFill = bo.IsFilled;
System.Diagnostics.Debug.WriteLine("Start");
} }
else if (current is LineToOp) else if (current is LineToOp)
{ {
@ -147,10 +138,8 @@ namespace Perspex.Cairo.Media
} }
else if (current is EndOp) else if (current is EndOp)
{ {
if (((EndOp)current).IsClosed) if (((EndOp)current).IsClosed)
this.context.ClosePath(); this.context.ClosePath();
System.Diagnostics.Debug.WriteLine("End");
} }
else if (current is CurveToOp) else if (current is CurveToOp)
{ {
@ -159,13 +148,21 @@ namespace Perspex.Cairo.Media
} }
} }
if (useFill) if (brush != null)
{ {
this.context.FillPreserve(); this.SetBrush(brush);
if (pen != null)
this.context.FillPreserve();
else
this.context.Fill();
} }
else
if (pen != null)
{ {
this.context.StrokePreserve(); this.SetPen(pen);
this.context.Stroke();
} }
} }
} }

42
Cairo/Perspex.Cairo/Media/StreamGeometryContextImpl.cs

@ -8,6 +8,7 @@ namespace Perspex.Cairo.Media
{ {
using Perspex.Media; using Perspex.Media;
using Perspex.Platform; using Perspex.Platform;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using Cairo = global::Cairo; using Cairo = global::Cairo;
@ -17,55 +18,38 @@ namespace Perspex.Cairo.Media
public StreamGeometryContextImpl(StreamGeometryImpl imp) public StreamGeometryContextImpl(StreamGeometryImpl imp)
{ {
this.impl = imp; this.impl = imp;
points = new List<Point>(); this.surf = new Cairo.ImageSurface(Cairo.Format.Argb32, 0, 0);
this.context = new Cairo.Context(this.surf);
} }
private List<Point> points;
public void ArcTo(Point point, Size size, double rotationAngle, bool isLargeArc, SweepDirection sweepDirection) public void ArcTo(Point point, Size size, double rotationAngle, bool isLargeArc, SweepDirection sweepDirection)
{ {
points.Add(point);
} }
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.impl.Operations.Enqueue(new BeginOp { Point = startPoint, IsFilled = isFilled });
points.Add(startPoint);
} }
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.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) public void LineTo(Point point)
{ {
this.impl.Operations.Enqueue(new LineToOp { 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) public void EndFigure(bool isClosed)
{ {
this.impl.Operations.Enqueue(new EndOp { IsClosed = 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<GeometryOp>(this.impl.Operations); var clone = new Queue<GeometryOp>(this.impl.Operations);
context.LineWidth = 2;
while (clone.Count > 0) while (clone.Count > 0)
{ {
var current = clone.Dequeue(); var current = clone.Dequeue();
@ -90,20 +74,16 @@ namespace Perspex.Cairo.Media
var cto = current as CurveToOp; var cto = current as CurveToOp;
context.CurveTo(cto.Point.ToCairo(), cto.Point2.ToCairo(), cto.Point3.ToCairo()); context.CurveTo(cto.Point.ToCairo(), cto.Point2.ToCairo(), cto.Point3.ToCairo());
} }
context.StrokePreserve();
context.FillPreserve();
} }
var test = context.StrokeExtents(); var extents = context.StrokeExtents();
this.impl.Bounds = new Rect(test.X, test.Y, test.Width, test.Height); this.impl.Bounds = new Rect(extents.X, extents.Y, extents.Width, extents.Height);
context.Dispose();
} }
public void Dispose() public void Dispose()
{ {
// TODO: Implement context.Dispose();
surf.Dispose();
} }
} }
} }

Loading…
Cancel
Save