~ubuntu-branches/ubuntu/trusty/monodevelop/trusty-proposed

« back to all changes in this revision

Viewing changes to external/xwt/Xwt.WPF/Xwt.WPFBackend/ContextBackendHandler.cs

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2013-05-12 09:46:03 UTC
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20130512094603-mad323bzcxvmcam0
Tags: upstream-4.0.5+dfsg
ImportĀ upstreamĀ versionĀ 4.0.5+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
ļ»æ// 
 
2
// ContextBackendHandler.cs
 
3
//  
 
4
// Author:
 
5
//       Eric Maupin <ermau@xamarin.com>
 
6
//       Hywel Thomas <hywel.w.thomas@gmail.com>
 
7
//       Lytico (http://limada.sourceforge.net)
 
8
//       LuĆ­s Reis <luiscubal@gmail.com>
 
9
//
 
10
// Copyright (c) 2012 Xamarin, Inc.
 
11
// 
 
12
// Permission is hereby granted, free of charge, to any person obtaining a copy
 
13
// of this software and associated documentation files (the "Software"), to deal
 
14
// in the Software without restriction, including without limitation the rights
 
15
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 
16
// copies of the Software, and to permit persons to whom the Software is
 
17
// furnished to do so, subject to the following conditions:
 
18
// 
 
19
// The above copyright notice and this permission notice shall be included in
 
20
// all copies or substantial portions of the Software.
 
21
// 
 
22
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
23
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
24
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 
25
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
26
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 
27
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 
28
// THE SOFTWARE.
 
29
 
 
30
using System;
 
31
using System.Drawing;
 
32
using System.Drawing.Drawing2D;
 
33
using System.Drawing.Imaging;
 
34
using System.Linq;
 
35
using System.Windows;
 
36
using System.Windows.Media.Imaging;
 
37
using Xwt.Backends;
 
38
using Xwt.Drawing;
 
39
using Xwt.Engine;
 
40
using Color = Xwt.Drawing.Color;
 
41
using Font = Xwt.Drawing.Font;
 
42
 
 
43
namespace Xwt.WPFBackend
 
44
{
 
45
        public class ContextBackendHandler
 
46
                : Backend, IContextBackendHandler
 
47
        {
 
48
                public void Save (object backend)
 
49
                {
 
50
                        var c = (DrawingContext) backend;
 
51
                        c.Save();
 
52
                }
 
53
 
 
54
                public void Restore (object backend)
 
55
                {
 
56
                        var c = (DrawingContext) backend;
 
57
                        c.Restore();
 
58
                }
 
59
 
 
60
                public void SetGlobalAlpha (object backend, double alpha)
 
61
                {
 
62
                        // TODO
 
63
                }
 
64
 
 
65
                public void Arc (object backend, double xc, double yc, double radius, double angle1, double angle2)
 
66
                {
 
67
                        // ensure sweep angle is always positive
 
68
                        if (angle2 < angle1)
 
69
                                angle2 = 360 + angle2;
 
70
                        ArcInternal (backend, xc, yc, radius, angle1, angle2);
 
71
                }
 
72
 
 
73
                public void ArcNegative (object backend, double xc, double yc, double radius, double angle1, double angle2)
 
74
                {
 
75
                        // ensure sweep angle is always negative
 
76
                        if (angle1 < angle2)
 
77
                                angle1 = 360 + angle1;
 
78
                        ArcInternal (backend, xc, yc, radius, angle1, angle2);
 
79
                }
 
80
 
 
81
                void ArcInternal (object backend, double xc, double yc, double radius, double angle1, double angle2)
 
82
                {
 
83
                        var c = (DrawingContext)backend;
 
84
                        c.Path.AddArc ((float)(xc - radius), (float)(yc - radius), (float)radius * 2, (float)radius * 2, (float)angle1,
 
85
                                       (float)(angle2 - angle1));
 
86
 
 
87
                        var current = c.Path.GetLastPoint ();
 
88
                        c.CurrentX = current.X;
 
89
                        c.CurrentY = current.Y;
 
90
                }
 
91
 
 
92
                public void Clip (object backend)
 
93
                {
 
94
                        var c = (DrawingContext) backend;
 
95
                        c.Graphics.SetClip (c.Path);
 
96
                        c.Path.Reset ();
 
97
                }
 
98
 
 
99
                public void ClipPreserve (object backend)
 
100
                {
 
101
                        var c = (DrawingContext) backend;
 
102
                        c.Graphics.SetClip (c.Path);
 
103
                }
 
104
 
 
105
                public void ClosePath (object backend)
 
106
                {
 
107
                        var c = (DrawingContext) backend;
 
108
                        c.Path.CloseFigure();
 
109
                }
 
110
 
 
111
                public void CurveTo (object backend, double x1, double y1, double x2, double y2, double x3, double y3)
 
112
                {
 
113
                        var c = (DrawingContext)backend;
 
114
                        c.Path.AddBezier (c.CurrentX, c.CurrentY,
 
115
                                        (float)x1, (float)y1,
 
116
                                        (float)x2, (float)y2,
 
117
                                        (float)x3, (float)y3);
 
118
                        c.CurrentX = (float)x3;
 
119
                        c.CurrentY = (float)y3;
 
120
                }
 
121
 
 
122
                public void Fill (object backend)
 
123
                {
 
124
                        var c = (DrawingContext) backend;
 
125
                        c.Graphics.FillPath (c.Brush, c.Path);
 
126
                        c.Path.Reset();
 
127
                        c.CurrentX = 0;
 
128
                        c.CurrentY = 0;
 
129
                }
 
130
 
 
131
                public void FillPreserve (object backend)
 
132
                {
 
133
                        var c = (DrawingContext) backend;
 
134
                        c.Graphics.FillPath (c.Brush, c.Path);
 
135
                }
 
136
 
 
137
                public void LineTo (object backend, double x, double y)
 
138
                {
 
139
                        var c = (DrawingContext) backend;
 
140
 
 
141
                        c.Path.AddLine (c.CurrentX, c.CurrentY, (float) x, (float) y);
 
142
                        c.CurrentX = (float) x;
 
143
                        c.CurrentY = (float) y;
 
144
                }
 
145
 
 
146
                public void MoveTo (object backend, double x, double y)
 
147
                {
 
148
                        var c = (DrawingContext) backend;
 
149
                        if (c.CurrentX != x || c.CurrentY != y) {
 
150
                                c.Path.StartFigure ();
 
151
                                c.CurrentX = (float)x;
 
152
                                c.CurrentY = (float)y;
 
153
                        }
 
154
                }
 
155
 
 
156
                public void NewPath (object backend)
 
157
                {
 
158
                        var c = (DrawingContext) backend;
 
159
                        c.Path.Reset();
 
160
                        c.CurrentX = 0;
 
161
                        c.CurrentY = 0;
 
162
                }
 
163
 
 
164
                public void Rectangle (object backend, double x, double y, double width, double height)
 
165
                {
 
166
                        var c = (DrawingContext) backend;
 
167
                        if (c.CurrentX != x || c.CurrentY != y)
 
168
                                c.Path.StartFigure ();
 
169
                        c.Path.AddRectangle (new RectangleF ((float)x, (float)y, (float)width, (float)height));
 
170
                        c.CurrentX = (float)x;
 
171
                        c.CurrentY = (float)y;
 
172
                }
 
173
 
 
174
                public void RelCurveTo (object backend, double dx1, double dy1, double dx2, double dy2, double dx3, double dy3)
 
175
                {
 
176
                        var c = (DrawingContext)backend;
 
177
                        c.Path.AddBezier (c.CurrentX, c.CurrentY,
 
178
                                        (float)(c.CurrentX + dx1), (float)(c.CurrentY + dy1),
 
179
                                        (float)(c.CurrentX + dx2), (float)(c.CurrentY + dy2),
 
180
                                        (float)(c.CurrentX + dx3), (float)(c.CurrentY + dy3));
 
181
                        c.CurrentX = (float)(c.CurrentX + dx3);
 
182
                        c.CurrentY = (float)(c.CurrentX + dy3);
 
183
                }
 
184
 
 
185
                public void RelLineTo (object backend, double dx, double dy)
 
186
                {
 
187
                        var c = (DrawingContext) backend;
 
188
                        
 
189
                        float x = c.CurrentX;
 
190
                        float y = c.CurrentY;
 
191
                        c.CurrentX += (float)dx;
 
192
                        c.CurrentY += (float)dy;
 
193
 
 
194
                        c.Path.AddLine (x, y, c.CurrentX, c.CurrentY);
 
195
                }
 
196
 
 
197
                public void RelMoveTo (object backend, double dx, double dy)
 
198
                {
 
199
                        var c = (DrawingContext) backend;
 
200
                        c.Path.StartFigure ();
 
201
                        c.CurrentX += (float)dx;
 
202
                        c.CurrentY += (float)dy;
 
203
                }
 
204
 
 
205
                public void Stroke (object backend)
 
206
                {
 
207
                        var c = (DrawingContext) backend;
 
208
                        c.Graphics.DrawPath (c.Pen, c.Path);
 
209
                        c.Path.Reset();
 
210
                        c.CurrentX = 0;
 
211
                        c.CurrentY = 0;
 
212
                }
 
213
 
 
214
                public void StrokePreserve (object backend)
 
215
                {
 
216
                        var c = (DrawingContext) backend;
 
217
                        c.Graphics.DrawPath (c.Pen, c.Path);
 
218
                }
 
219
 
 
220
                public void SetColor (object backend, Color color)
 
221
                {
 
222
                        var c = (DrawingContext) backend;
 
223
 
 
224
                        var dc = color.ToDrawingColor ();
 
225
                        c.SetColor (dc);
 
226
                }
 
227
 
 
228
                public void SetLineWidth (object backend, double width)
 
229
                {
 
230
                        var c = (DrawingContext) backend;
 
231
                        c.SetWidth ((float) width);
 
232
                }
 
233
 
 
234
                public void SetLineDash (object backend, double offset, params double[] pattern)
 
235
                {
 
236
                        var c = (DrawingContext) backend;
 
237
 
 
238
                        if (pattern.Length != 0) {
 
239
                                c.Pen.DashOffset = (float) (offset / c.Pen.Width);
 
240
                                float[] fp = new float [pattern.Length];
 
241
                                for (int i = 0; i < fp.Length; ++i)
 
242
                                        fp [i] = (float) (pattern [i] / c.Pen.Width);
 
243
 
 
244
                                c.Pen.DashStyle = DashStyle.Custom;
 
245
                                c.Pen.DashPattern = fp;
 
246
                        } else
 
247
                                c.Pen.DashStyle = DashStyle.Solid;
 
248
                }
 
249
 
 
250
                public void SetPattern (object backend, object p)
 
251
                {
 
252
                        var c = (DrawingContext) backend;
 
253
 
 
254
                        if (p is LinearGradient) {
 
255
                                c.Brush = ((LinearGradient) p).CreateBrush ();
 
256
                        } else if (p is RadialGradient) {
 
257
                                c.Brush = ((RadialGradient) p).CreateBrush ();
 
258
                        } else if (p is Brush)
 
259
                                c.Brush = (Brush) p;
 
260
                }
 
261
 
 
262
                public void SetFont (object backend, Font font)
 
263
                {
 
264
                        var c = (DrawingContext) backend;
 
265
                        c.Font.Dispose();
 
266
                        c.Font = font.ToDrawingFont ();
 
267
                }
 
268
 
 
269
                public void DrawTextLayout (object backend, TextLayout layout, double x, double y)
 
270
                {
 
271
                        var c = (DrawingContext)backend;
 
272
                        System.Drawing.StringFormat stringFormat = TextLayoutContext.StringFormat;
 
273
                        StringTrimming trimming = layout.Trimming.ToDrawingStringTrimming ();
 
274
 
 
275
                        if (layout.Height > 0 && stringFormat.Trimming != trimming) {
 
276
                                stringFormat = (System.Drawing.StringFormat)stringFormat.Clone ();
 
277
                                stringFormat.Trimming = trimming;
 
278
                        }
 
279
 
 
280
                        var font = layout.Font.ToDrawingFont ();
 
281
 
 
282
                        if (layout.Width == -1 && layout.Height == -1) {
 
283
                                c.Graphics.DrawString (layout.Text, font, c.Brush, (float)x, (float)y, stringFormat);
 
284
                        } else {
 
285
                                Size measure = layout.GetSize ();
 
286
                                float h = layout.Height > 0 ? (float)layout.Height : (float)measure.Height;
 
287
                                c.Graphics.DrawString (layout.Text, font, c.Brush,
 
288
                                                                           new RectangleF ((float)x, (float)y, (float)measure.Width, h),
 
289
                                                                           stringFormat);
 
290
                        }
 
291
                }
 
292
 
 
293
                public void DrawImage (object backend, object img, double x, double y, double alpha)
 
294
                {
 
295
                        var c = (DrawingContext) backend;
 
296
 
 
297
                        Bitmap bmp = DataConverter.AsBitmap (img);
 
298
                        DrawImageCore (c.Graphics, bmp, (float) x, (float) y, bmp.Width, bmp.Height, (float)alpha);
 
299
                }
 
300
 
 
301
                public void DrawImage (object backend, object img, double x, double y, double width, double height, double alpha)
 
302
                {
 
303
                        var c = (DrawingContext) backend;
 
304
 
 
305
                        Bitmap bmp = DataConverter.AsBitmap (img);
 
306
                        DrawImageCore (c.Graphics, bmp, (float) x, (float) y, (float) width, (float) height, (float) alpha);
 
307
                }
 
308
 
 
309
                public void DrawImage (object backend, object img, Rectangle srcRect, Rectangle destRect, double alpha)
 
310
                {
 
311
                        var c = (DrawingContext) backend;
 
312
 
 
313
                        Bitmap bmp = DataConverter.AsBitmap (img);
 
314
 
 
315
                        DrawImageCore (c.Graphics, bmp, srcRect, destRect, (float) alpha);
 
316
                }
 
317
 
 
318
                public void Rotate (object backend, double angle)
 
319
                {
 
320
                        var c = (DrawingContext)backend;
 
321
                        c.Graphics.RotateTransform ((float)angle);
 
322
                }
 
323
 
 
324
                public void Scale (object backend, double scaleX, double scaleY)
 
325
                {
 
326
                        var c = (DrawingContext)backend;
 
327
                        c.Graphics.ScaleTransform ((float)scaleX, (float)scaleY);
 
328
                }
 
329
                
 
330
                public void Translate (object backend, double tx, double ty)
 
331
                {
 
332
                        var c = (DrawingContext)backend;
 
333
                        c.Graphics.TranslateTransform ((float)tx, (float)ty);
 
334
                }
 
335
 
 
336
                public void TransformPoint (object backend, ref double x, ref double y)
 
337
                {
 
338
                        var m = ((DrawingContext)backend).Graphics.Transform;
 
339
                        PointF p = new PointF ((float)x, (float)y);
 
340
                        PointF[] pts = new PointF[] { p };
 
341
                        m.TransformPoints (pts);
 
342
                        x = pts[0].X;
 
343
                        y = pts[0].Y;
 
344
                }
 
345
 
 
346
                public void TransformDistance (object backend, ref double dx, ref double dy)
 
347
                {
 
348
                        var m = ((DrawingContext)backend).Graphics.Transform;
 
349
                        PointF p = new PointF ((float)dx, (float)dy);
 
350
                        PointF[] pts = new PointF[] {p};
 
351
                        m.TransformVectors (pts);
 
352
                        dx = pts[0].X;
 
353
                        dy = pts[0].Y;
 
354
                }
 
355
 
 
356
                public void TransformPoints (object backend, Point[] points)
 
357
                {
 
358
                        var m = ((DrawingContext)backend).Graphics.Transform;
 
359
                        PointF[] pts = new PointF[points.Length];
 
360
                        for (int i = 0; i < points.Length; ++i) {
 
361
                                pts[i].X = (float)points[i].X;
 
362
                                pts[i].Y = (float)points[i].Y;
 
363
                        }
 
364
                        m.TransformPoints (pts);
 
365
                        for (int i = 0; i < points.Length; ++i) {
 
366
                                points[i].X = pts[i].X;
 
367
                                points[i].Y = pts[i].Y;
 
368
                        }
 
369
                }
 
370
 
 
371
                public void TransformDistances (object backend, Distance[] vectors)
 
372
                {
 
373
                        var m = ((DrawingContext)backend).Graphics.Transform;
 
374
                        PointF[] pts = new PointF[vectors.Length];
 
375
                        for (int i = 0; i < vectors.Length; ++i) {
 
376
                                pts[i].X = (float)vectors[i].Dx;
 
377
                                pts[i].Y = (float)vectors[i].Dy;
 
378
                        }
 
379
                        m.TransformVectors (pts);
 
380
                        for (int i = 0; i < vectors.Length; ++i) {
 
381
                                vectors[i].Dx = pts[i].X;
 
382
                                vectors[i].Dy = pts[i].Y;
 
383
                        }
 
384
                }
 
385
 
 
386
                public void Dispose (object backend)
 
387
                {
 
388
                        ((DrawingContext)backend).Dispose();
 
389
                }
 
390
 
 
391
                internal static void DrawImageCore (Graphics g, Bitmap bmp, float x, float y, float width, float height, float alpha)
 
392
                {
 
393
                        if (bmp == null)
 
394
                                throw new ArgumentException();
 
395
 
 
396
                        if (alpha < 1) {
 
397
                                var attr = new ImageAttributes ();
 
398
 
 
399
                                float[][] matrixItems = new[] {
 
400
                                        new float[] { 1, 0, 0, 0, 0 },
 
401
                                        new float[] { 0, 1, 0, 0, 0 },
 
402
                                        new float[] { 0, 0, 1, 0, 0 },
 
403
                                        new float[] { 0, 0, 0, alpha, 0 },
 
404
                                        new float[] { 0, 0, 0, 0, 1 },
 
405
                                };
 
406
 
 
407
                                attr.SetColorMatrix (new ColorMatrix (matrixItems), ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
 
408
 
 
409
                                PointF[] points = new PointF[3];
 
410
                                points [0] = new PointF (x, y);
 
411
                                points [1] = new PointF (x + width, y);
 
412
                                points [2] = new PointF (x, y + height);
 
413
 
 
414
                                g.DrawImage (bmp, points, new RectangleF (0, 0, bmp.Width, bmp.Height), GraphicsUnit.Pixel, attr);
 
415
                        }
 
416
                        else
 
417
                                g.DrawImage (bmp, x, y, width, height);
 
418
                }
 
419
 
 
420
                internal void DrawImageCore (Graphics g, Bitmap bmp, Rectangle srcRect, Rectangle destRect, float alpha)
 
421
                {
 
422
                        if (alpha < 1)
 
423
                        {
 
424
                                var attr = new ImageAttributes ();
 
425
 
 
426
                                float[][] matrixItems = new[] {
 
427
                                        new float[] { 1, 0, 0, 0, 0 },
 
428
                                        new float[] { 0, 1, 0, 0, 0 },
 
429
                                        new float[] { 0, 0, 1, 0, 0 },
 
430
                                        new float[] { 0, 0, 0, alpha, 0 },
 
431
                                        new float[] { 0, 0, 0, 0, 1 },
 
432
                                };
 
433
 
 
434
                                attr.SetColorMatrix (new ColorMatrix (matrixItems), ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
 
435
 
 
436
                                PointF[] points = new PointF[3];
 
437
                                points[0] = new PointF ((float) destRect.X, (float) destRect.Y);
 
438
                                points[1] = new PointF ((float) (destRect.X + destRect.Width), (float) destRect.Y);
 
439
                                points[2] = new PointF ((float) destRect.X, (float) (destRect.Y + destRect.Height));
 
440
 
 
441
                                g.DrawImage (bmp, points, srcRect.ToSDRectF (), GraphicsUnit.Pixel, attr);
 
442
                        }
 
443
                        else
 
444
                                g.DrawImage (bmp, destRect.ToSDRectF (), srcRect.ToSDRectF (), GraphicsUnit.Pixel);
 
445
                }
 
446
        }
 
447
}