Merge branch 'master' into xwt-next

Conflicts:
	Xwt.Gtk/Xwt.CairoBackend/CairoContextBackendHandler.cs
	Xwt.Mac/Xwt.Mac/CanvasBackend.cs
	Xwt.Mac/Xwt.Mac/ContextBackendHandler.cs
	Xwt.WPF/Xwt.WPFBackend/ContextBackendHandler.cs
	Xwt/Xwt.Backends/IContextBackendHandler.cs
	Xwt/Xwt.Drawing/Context.cs
This commit is contained in:
Alex Corrado 2012-12-24 22:48:26 -08:00
Родитель 56d1c322f3 5c9874ea4d
Коммит e44e4679f6
6 изменённых файлов: 63 добавлений и 87 удалений

Просмотреть файл

@ -91,12 +91,6 @@ namespace Xwt.CairoBackend
ctx.ClipPreserve ();
}
public override void ResetClip (object backend)
{
Cairo.Context ctx = ((CairoContextBackend) backend).Context;
ctx.ResetClip ();
}
public override void ClosePath (object backend)
{
Cairo.Context ctx = ((CairoContextBackend) backend).Context;

Просмотреть файл

@ -27,7 +27,7 @@
using System;
using Xwt.Backends;
using MonoMac.AppKit;
using MonoMac.CoreGraphics;
namespace Xwt.Mac
{
@ -113,10 +113,12 @@ namespace Xwt.Mac
public override void DrawRect (System.Drawing.RectangleF dirtyRect)
{
context.InvokeUserCode (delegate {
var ctx = new CGContextBackend {
Context = NSGraphicsContext.CurrentContext.GraphicsPort
CGContext ctx = NSGraphicsContext.CurrentContext.GraphicsPort;
var backend = new CGContextBackend {
Context = ctx,
InverseViewTransform = ctx.GetCTM ().Invert ()
};
eventSink.OnDraw (ctx, new Rectangle (dirtyRect.X, dirtyRect.Y, dirtyRect.Width, dirtyRect.Height));
eventSink.OnDraw (backend, new Rectangle (dirtyRect.X, dirtyRect.Y, dirtyRect.Width, dirtyRect.Height));
});
}

Просмотреть файл

@ -3,7 +3,8 @@
//
// Author:
// Lluis Sanchez <lluis@xamarin.com>
//
// Alex Corrado <corrado@xamarin.com>
//
// Copyright (c) 2011 Xamarin Inc
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
@ -36,20 +37,16 @@ using System.Drawing;
namespace Xwt.Mac
{
class CGContextBackend {
public CGPath ClipPath;
public CGContext Context;
public SizeF Size;
public GradientInfo Gradient;
public CGAffineTransform? InverseViewTransform;
}
public class MacContextBackendHandler: ContextBackendHandler
{
const double degrees = System.Math.PI / 180d;
public MacContextBackendHandler ()
{
}
public override void Save (object backend)
{
((CGContextBackend)backend).Context.SaveState ();
@ -79,24 +76,18 @@ namespace Xwt.Mac
public override void Clip (object backend)
{
ClipPreserve (backend);
((CGContextBackend)backend).Context.BeginPath ();
((CGContextBackend)backend).Context.Clip ();
}
public override void ClipPreserve (object backend)
{
CGContextBackend gc = (CGContextBackend)backend;
if (gc.ClipPath == null)
gc.ClipPath = gc.Context.CopyPath ();
//else
//FIXME: figure out how to intersect existing ClipPath with the current path
CGContext ctx = ((CGContextBackend)backend).Context;
using (CGPath oldPath = ctx.CopyPath ()) {
ctx.Clip ();
ctx.AddPath (oldPath);
}
}
public override void ResetClip (object backend)
{
((CGContextBackend)backend).ClipPath = null;
}
public override void ClosePath (object backend)
{
((CGContextBackend)backend).Context.ClosePath ();
@ -109,15 +100,14 @@ namespace Xwt.Mac
public override void Fill (object backend)
{
bool needsRestore;
CGContextBackend gc = (CGContextBackend)backend;
CGContext ctx = SetupContextForDrawing (gc, out needsRestore);
CGContext ctx = gc.Context;
SetupContextForDrawing (ctx);
if (gc.Gradient != null)
MacGradientBackendHandler.Draw (ctx, gc.Gradient);
else
ctx.DrawPath (CGPathDrawingMode.Fill);
if (needsRestore)
ctx.RestoreState ();
}
public override void FillPreserve (object backend)
@ -172,18 +162,17 @@ namespace Xwt.Mac
public override void Stroke (object backend)
{
bool needsRestore;
CGContext ctx = SetupContextForDrawing ((CGContextBackend)backend, out needsRestore);
CGContext ctx = ((CGContextBackend)backend).Context;
SetupContextForDrawing (ctx);
ctx.DrawPath (CGPathDrawingMode.Stroke);
if (needsRestore)
ctx.RestoreState ();
}
public override void StrokePreserve (object backend)
{
CGContext ctx = ((CGContextBackend)backend).Context;
SetupContextForDrawing (ctx);
using (CGPath oldPath = ctx.CopyPath ()) {
Stroke (backend);
ctx.DrawPath (CGPathDrawingMode.Stroke);
ctx.AddPath (oldPath);
}
}
@ -233,23 +222,23 @@ namespace Xwt.Mac
{
((CGContextBackend)backend).Context.SelectFont (font.Family, (float)font.Size, CGTextEncoding.FontSpecific);
}
public override void DrawTextLayout (object backend, TextLayout layout, double x, double y)
{
bool needsRestore;
CGContext ctx = SetupContextForDrawing ((CGContextBackend)backend, out needsRestore);
CGContext ctx = ((CGContextBackend)backend).Context;
SetupContextForDrawing (ctx);
MacTextLayoutBackendHandler.Draw (ctx, Toolkit.GetBackend (layout), x, y);
if (needsRestore)
ctx.RestoreState ();
}
public override void DrawImage (object backend, object img, double x, double y, double alpha)
{
CGContext ctx = ((CGContextBackend)backend).Context;
NSImage image = (NSImage)img;
var rect = new RectangleF (new PointF ((float)x, (float)y), image.Size);
var rect = new RectangleF (PointF.Empty, image.Size);
ctx.SaveState ();
ctx.SetAlpha ((float)alpha);
ctx.TranslateCTM ((float)x, (float)y + rect.Height);
ctx.ScaleCTM (1f, -1f);
ctx.DrawImage (rect, image.AsCGImage (RectangleF.Empty, null, null));
ctx.RestoreState ();
}
@ -265,9 +254,12 @@ namespace Xwt.Mac
{
CGContext ctx = ((CGContextBackend)backend).Context;
NSImage image = (NSImage) img;
var rect = new RectangleF (0, 0, (float)destRect.Width, (float)destRect.Height);
ctx.SaveState ();
ctx.SetAlpha ((float)alpha);
ctx.DrawImage (destRect.ToRectangleF (), image.AsCGImage (RectangleF.Empty, null, null).WithImageInRect (srcRect.ToRectangleF ()));
ctx.TranslateCTM ((float)destRect.X, (float)destRect.Y + rect.Height);
ctx.ScaleCTM (1f, -1f);
ctx.DrawImage (rect, image.AsCGImage (RectangleF.Empty, null, null).WithImageInRect (srcRect.ToRectangleF ()));
ctx.RestoreState ();
}
@ -288,7 +280,7 @@ namespace Xwt.Mac
public override void TransformPoint (object backend, ref double x, ref double y)
{
CGAffineTransform t = ((CGContextBackend)backend).Context.GetCTM();
CGAffineTransform t = GetContextTransform ((CGContextBackend)backend);
PointF p = t.TransformPoint (new PointF ((float)x, (float)y));
x = p.X;
@ -297,7 +289,7 @@ namespace Xwt.Mac
public override void TransformDistance (object backend, ref double dx, ref double dy)
{
CGAffineTransform t = ((CGContextBackend)backend).Context.GetCTM();
CGAffineTransform t = GetContextTransform ((CGContextBackend)backend);
// remove translational elements from CTM
t.x0 = 0;
t.y0 = 0;
@ -309,7 +301,7 @@ namespace Xwt.Mac
public override void TransformPoints (object backend, Point[] points)
{
CGAffineTransform t = ((CGContextBackend)backend).Context.GetCTM();
CGAffineTransform t = GetContextTransform ((CGContextBackend)backend);
PointF p;
for (int i = 0; i < points.Length; ++i) {
@ -321,7 +313,7 @@ namespace Xwt.Mac
public override void TransformDistances (object backend, Distance[] vectors)
{
CGAffineTransform t = ((CGContextBackend)backend).Context.GetCTM();
CGAffineTransform t = GetContextTransform ((CGContextBackend)backend);
t.x0 = 0;
t.y0 = 0;
PointF p;
@ -365,28 +357,29 @@ namespace Xwt.Mac
((CGContextBackend)backend).Context.Dispose ();
}
static CGContext SetupContextForDrawing (CGContextBackend gc, out bool needsRestore)
static CGAffineTransform GetContextTransform (CGContextBackend gc)
{
CGContext ctx = gc.Context;
if (!ctx.IsPathEmpty ()) {
var drawPoint = ctx.GetCTM ().TransformPoint (ctx.GetPathBoundingBox ().Location);
var patternPhase = new SizeF (drawPoint.X, drawPoint.Y);
if (patternPhase != SizeF.Empty)
ctx.SetPatternPhase (patternPhase);
}
if (gc.ClipPath == null) {
needsRestore = false;
return ctx;
}
ctx.SaveState ();
using (CGPath oldPath = ctx.CopyPath ()) {
ctx.BeginPath ();
ctx.AddPath (gc.ClipPath);
ctx.Clip ();
ctx.AddPath (oldPath);
}
needsRestore = true;
return ctx;
CGAffineTransform t = gc.Context.GetCTM ();
// The CTM returned above actually includes the full view transform.
// We only want the transform that is applied to the context, so concat
// the inverse of the view transform to nullify that part.
if (gc.InverseViewTransform.HasValue)
t.Multiply (gc.InverseViewTransform.Value);
return t;
}
static void SetupContextForDrawing (CGContext ctx)
{
if (ctx.IsPathEmpty ())
return;
// setup pattern drawing to better match the behavior of Cairo
var drawPoint = ctx.GetCTM ().TransformPoint (ctx.GetPathBoundingBox ().Location);
var patternPhase = new SizeF (drawPoint.X, drawPoint.Y);
if (patternPhase != SizeF.Empty)
ctx.SetPatternPhase (patternPhase);
}
}
}

Просмотреть файл

@ -102,12 +102,6 @@ namespace Xwt.WPFBackend
c.Graphics.SetClip (c.Path);
}
public override void ResetClip (object backend)
{
var c = (DrawingContext) backend;
c.Graphics.ResetClip ();
}
public override void ClosePath (object backend)
{
var c = (DrawingContext) backend;
@ -335,7 +329,7 @@ namespace Xwt.WPFBackend
public override void TransformPoint (object backend, ref double x, ref double y)
{
Matrix m = ((DrawingContext)backend).Graphics.Transform;
var m = ((DrawingContext)backend).Graphics.Transform;
PointF p = new PointF ((float)x, (float)y);
PointF[] pts = new PointF[] { p };
m.TransformPoints (pts);
@ -345,7 +339,7 @@ namespace Xwt.WPFBackend
public override void TransformDistance (object backend, ref double dx, ref double dy)
{
Matrix m = ((DrawingContext)backend).Graphics.Transform;
var m = ((DrawingContext)backend).Graphics.Transform;
PointF p = new PointF ((float)dx, (float)dy);
PointF[] pts = new PointF[] {p};
m.TransformVectors (pts);
@ -355,7 +349,7 @@ namespace Xwt.WPFBackend
public override void TransformPoints (object backend, Point[] points)
{
Matrix m = ((DrawingContext)backend).Graphics.Transform;
var m = ((DrawingContext)backend).Graphics.Transform;
PointF[] pts = new PointF[points.Length];
for (int i = 0; i < points.Length; ++i) {
pts[i].X = (float)points[i].X;
@ -370,7 +364,7 @@ namespace Xwt.WPFBackend
public override void TransformDistances (object backend, Distance[] vectors)
{
Matrix m = ((DrawingContext)backend).Graphics.Transform;
var m = ((DrawingContext)backend).Graphics.Transform;
PointF[] pts = new PointF[vectors.Length];
for (int i = 0; i < vectors.Length; ++i) {
pts[i].X = (float)vectors[i].Dx;

Просмотреть файл

@ -40,8 +40,6 @@ namespace Xwt.Backends
public abstract void ClipPreserve(object backend);
public abstract void ResetClip (object backend);
public abstract void Fill (object backend);
public abstract void FillPreserve (object backend);

Просмотреть файл

@ -91,11 +91,6 @@ namespace Xwt.Drawing
handler.ClipPreserve (Backend);
}
public void ResetClip ()
{
handler.ResetClip (Backend);
}
public void Fill ()
{
handler.Fill (Backend);