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:
Коммит
e44e4679f6
|
@ -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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче