2289 lines
		
	
	
		
			80 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			2289 lines
		
	
	
		
			80 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| #region PDFsharp - A .NET library for processing PDF
 | ||
| //
 | ||
| // Authors:
 | ||
| //   Stefan Lange
 | ||
| //
 | ||
| // Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
 | ||
| //
 | ||
| // http://www.pdfsharp.com
 | ||
| // http://sourceforge.net/projects/pdfsharp
 | ||
| //
 | ||
| // Permission is hereby granted, free of charge, to any person obtaining a
 | ||
| // copy of this software and associated documentation files (the "Software"),
 | ||
| // to deal in the Software without restriction, including without limitation
 | ||
| // the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | ||
| // and/or sell copies of the Software, and to permit persons to whom the
 | ||
| // Software is furnished to do so, subject to the following conditions:
 | ||
| //
 | ||
| // The above copyright notice and this permission notice shall be included
 | ||
| // in all copies or substantial portions of the Software.
 | ||
| //
 | ||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | ||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | ||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | ||
| // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | ||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | ||
| // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 | ||
| // DEALINGS IN THE SOFTWARE.
 | ||
| #endregion
 | ||
| 
 | ||
| using System;
 | ||
| using System.Diagnostics;
 | ||
| #if GDI
 | ||
| using System.Drawing;
 | ||
| using System.Drawing.Drawing2D;
 | ||
| #endif
 | ||
| #if WPF
 | ||
| using System.Windows;
 | ||
| using System.Windows.Media;
 | ||
| using SysPoint = System.Windows.Point;
 | ||
| using SysSize = System.Windows.Size;
 | ||
| using SysRect = System.Windows.Rect;
 | ||
| #if !SILVERLIGHT
 | ||
| using WpfBrushes = System.Windows.Media.Brushes;
 | ||
| #endif
 | ||
| #endif
 | ||
| #if NETFX_CORE
 | ||
| using Windows.UI.Xaml.Media;
 | ||
| using SysPoint = Windows.Foundation.Point;
 | ||
| using SysSize = Windows.Foundation.Size;
 | ||
| using SysRect = Windows.Foundation.Rect;
 | ||
| #endif
 | ||
| using PdfSharp.Internal;
 | ||
| 
 | ||
| namespace PdfSharp.Drawing
 | ||
| {
 | ||
|     /// <summary>
 | ||
|     /// Represents a series of connected lines and curves.
 | ||
|     /// </summary>
 | ||
|     public sealed class XGraphicsPath
 | ||
|     {
 | ||
|         /// <summary>
 | ||
|         /// Initializes a new instance of the <see cref="XGraphicsPath"/> class.
 | ||
|         /// </summary>
 | ||
|         public XGraphicsPath()
 | ||
|         {
 | ||
| #if CORE
 | ||
|             _corePath = new CoreGraphicsPath();
 | ||
| #endif
 | ||
| #if GDI
 | ||
|             try
 | ||
|             {
 | ||
|                 Lock.EnterGdiPlus();
 | ||
|                 _gdipPath = new GraphicsPath();
 | ||
|             }
 | ||
|             finally { Lock.ExitGdiPlus(); }
 | ||
| #endif
 | ||
| #if WPF || NETFX_CORE
 | ||
|             _pathGeometry = new PathGeometry();
 | ||
| #endif
 | ||
|         }
 | ||
| 
 | ||
| #if GDI
 | ||
|         /// <summary>
 | ||
|         /// Initializes a new instance of the <see cref="XGraphicsPath"/> class.
 | ||
|         /// </summary>
 | ||
|         public XGraphicsPath(PointF[] points, byte[] types, XFillMode fillMode)
 | ||
|         {
 | ||
| #if GDI
 | ||
|             try
 | ||
|             {
 | ||
|                 Lock.EnterGdiPlus();
 | ||
|                 _gdipPath = new GraphicsPath(points, types, (FillMode)fillMode);
 | ||
|             }
 | ||
|             finally { Lock.ExitGdiPlus(); }
 | ||
| #endif
 | ||
| #if WPF  // Is true only in Hybrid build.
 | ||
|             _pathGeometry = new PathGeometry();
 | ||
|             _pathGeometry.FillRule = FillRule.EvenOdd;
 | ||
| #endif
 | ||
|         }
 | ||
| #endif
 | ||
| 
 | ||
| #if WPF || NETFX_CORE
 | ||
|         /// <summary>
 | ||
|         /// Gets the current path figure.
 | ||
|         /// </summary>
 | ||
|         PathFigure CurrentPathFigure
 | ||
|         {
 | ||
|             get
 | ||
|             {
 | ||
|                 int count = _pathGeometry.Figures.Count;
 | ||
|                 if (count == 0)
 | ||
|                 {
 | ||
|                     // Create new figure if there is none.
 | ||
|                     _pathGeometry.Figures.Add(new PathFigure());
 | ||
|                     count++;
 | ||
|                 }
 | ||
|                 else
 | ||
|                 {
 | ||
|                     PathFigure lastFigure = _pathGeometry.Figures[count - 1];
 | ||
|                     if (lastFigure.IsClosed)
 | ||
|                     {
 | ||
|                         if (lastFigure.Segments.Count > 0)
 | ||
|                         {
 | ||
|                             // Create new figure if previous one was closed.
 | ||
|                             _pathGeometry.Figures.Add(new PathFigure());
 | ||
|                             count++;
 | ||
|                         }
 | ||
|                         else
 | ||
|                         {
 | ||
|                             Debug.Assert(false);
 | ||
|                         }
 | ||
|                     }
 | ||
|                 }
 | ||
|                 // Return last figure in collection.
 | ||
|                 return _pathGeometry.Figures[count - 1];
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// Gets the current path figure, but never created a new one.
 | ||
|         /// </summary>
 | ||
|         PathFigure PeekCurrentFigure
 | ||
|         {
 | ||
|             get
 | ||
|             {
 | ||
|                 int count = _pathGeometry.Figures.Count;
 | ||
|                 return count == 0 ? null : _pathGeometry.Figures[count - 1];
 | ||
|             }
 | ||
|         }
 | ||
| #endif
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// Clones this instance.
 | ||
|         /// </summary>
 | ||
|         public XGraphicsPath Clone()
 | ||
|         {
 | ||
|             XGraphicsPath path = (XGraphicsPath)MemberwiseClone();
 | ||
| #if CORE
 | ||
|             _corePath = new CoreGraphicsPath(_corePath);
 | ||
| #endif
 | ||
| #if GDI
 | ||
|             try
 | ||
|             {
 | ||
|                 Lock.EnterGdiPlus();
 | ||
|                 path._gdipPath = _gdipPath.Clone() as GraphicsPath;
 | ||
|             }
 | ||
|             finally { Lock.ExitGdiPlus(); }
 | ||
| #endif
 | ||
| #if WPF || NETFX_CORE
 | ||
| #if !SILVERLIGHT && !NETFX_CORE
 | ||
|             path._pathGeometry = _pathGeometry.Clone();
 | ||
| #else
 | ||
|             // AG-HACK
 | ||
|             throw new InvalidOperationException("Silverlight cannot clone geometry objects.");
 | ||
|             // TODO: make it manually...
 | ||
| #pragma warning disable 0162
 | ||
| #endif
 | ||
| #endif
 | ||
|             return path;
 | ||
|         }
 | ||
| 
 | ||
|         // ----- AddLine ------------------------------------------------------------------------------
 | ||
| 
 | ||
| #if GDI
 | ||
|         /// <summary>
 | ||
|         /// Adds a line segment to current figure.
 | ||
|         /// </summary>
 | ||
|         public void AddLine(System.Drawing.Point pt1, System.Drawing.Point pt2)
 | ||
|         {
 | ||
|             AddLine(pt1.X, pt1.Y, pt2.X, pt2.Y);
 | ||
|         }
 | ||
| #endif
 | ||
| 
 | ||
| #if WPF
 | ||
|         /// <summary>
 | ||
|         /// Adds a line segment to current figure.
 | ||
|         /// </summary>
 | ||
|         public void AddLine(SysPoint pt1, SysPoint pt2)
 | ||
|         {
 | ||
|             AddLine(pt1.X, pt1.Y, pt2.X, pt2.Y);
 | ||
|         }
 | ||
| #endif
 | ||
| 
 | ||
| #if GDI
 | ||
|         /// <summary>
 | ||
|         /// Adds  a line segment to current figure.
 | ||
|         /// </summary>
 | ||
|         public void AddLine(PointF pt1, PointF pt2)
 | ||
|         {
 | ||
|             AddLine(pt1.X, pt1.Y, pt2.X, pt2.Y);
 | ||
|         }
 | ||
| #endif
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// Adds  a line segment to current figure.
 | ||
|         /// </summary>
 | ||
|         public void AddLine(XPoint pt1, XPoint pt2)
 | ||
|         {
 | ||
|             AddLine(pt1.X, pt1.Y, pt2.X, pt2.Y);
 | ||
|         }
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// Adds  a line segment to current figure.
 | ||
|         /// </summary>
 | ||
|         public void AddLine(double x1, double y1, double x2, double y2)
 | ||
|         {
 | ||
| #if CORE
 | ||
|             _corePath.MoveOrLineTo(x1, y1);
 | ||
|             _corePath.LineTo(x2, y2, false);
 | ||
| #endif
 | ||
| #if GDI
 | ||
|             try
 | ||
|             {
 | ||
|                 Lock.EnterGdiPlus();
 | ||
|                 _gdipPath.AddLine((float)x1, (float)y1, (float)x2, (float)y2);
 | ||
|             }
 | ||
|             finally { Lock.ExitGdiPlus(); }
 | ||
| #endif
 | ||
| #if WPF
 | ||
|             PathFigure figure = CurrentPathFigure;
 | ||
|             if (figure.Segments.Count == 0)
 | ||
|             {
 | ||
|                 figure.StartPoint = new SysPoint(x1, y1);
 | ||
| #if !SILVERLIGHT
 | ||
|                 var lineSegment = new LineSegment(new SysPoint(x2, y2), true);
 | ||
| #else
 | ||
|                 var lineSegment = new LineSegment { Point = new Point(x2, y2) };
 | ||
| #endif
 | ||
|                 figure.Segments.Add(lineSegment);
 | ||
|             }
 | ||
|             else
 | ||
|             {
 | ||
| #if !SILVERLIGHT
 | ||
|                 var lineSegment1 = new LineSegment(new SysPoint(x1, y1), true);
 | ||
|                 var lineSegment2 = new LineSegment(new SysPoint(x2, y2), true);
 | ||
| #else
 | ||
|                 var lineSegment1 = new LineSegment { Point = new Point(x1, y1) };
 | ||
|                 var lineSegment2 = new LineSegment { Point = new Point(x2, y2) };
 | ||
| #endif
 | ||
|                 figure.Segments.Add(lineSegment1);
 | ||
|                 figure.Segments.Add(lineSegment2);
 | ||
|             }
 | ||
| #endif
 | ||
|         }
 | ||
| 
 | ||
|         // ----- AddLines -----------------------------------------------------------------------------
 | ||
| 
 | ||
| #if GDI
 | ||
|         /// <summary>
 | ||
|         /// Adds a series of connected line segments to current figure.
 | ||
|         /// </summary>
 | ||
|         public void AddLines(System.Drawing.Point[] points)
 | ||
|         {
 | ||
|             AddLines(XGraphics.MakeXPointArray(points, 0, points.Length));
 | ||
|         }
 | ||
| #endif
 | ||
| 
 | ||
| #if WPF
 | ||
|         /// <summary>
 | ||
|         /// Adds a series of connected line segments to current figure.
 | ||
|         /// </summary>
 | ||
|         public void AddLines(SysPoint[] points)
 | ||
|         {
 | ||
|             AddLines(XGraphics.MakeXPointArray(points, 0, points.Length));
 | ||
|         }
 | ||
| #endif
 | ||
| 
 | ||
| #if GDI
 | ||
|         /// <summary>
 | ||
|         /// Adds a series of connected line segments to current figure.
 | ||
|         /// </summary>
 | ||
|         public void AddLines(PointF[] points)
 | ||
|         {
 | ||
|             AddLines(XGraphics.MakeXPointArray(points, 0, points.Length));
 | ||
|         }
 | ||
| #endif
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// Adds a series of connected line segments to current figure.
 | ||
|         /// </summary>
 | ||
|         public void AddLines(XPoint[] points)
 | ||
|         {
 | ||
|             if (points == null)
 | ||
|                 throw new ArgumentNullException("points");
 | ||
| 
 | ||
|             int count = points.Length;
 | ||
|             if (count == 0)
 | ||
|                 return;
 | ||
| #if CORE
 | ||
|             _corePath.MoveOrLineTo(points[0].X, points[0].Y);
 | ||
|             for (int idx = 1; idx < count; idx++)
 | ||
|                 _corePath.LineTo(points[idx].X, points[idx].Y, false);
 | ||
| #endif
 | ||
| #if GDI
 | ||
|             try
 | ||
|             {
 | ||
|                 Lock.EnterGdiPlus();
 | ||
|                 _gdipPath.AddLines(XGraphics.MakePointFArray(points));
 | ||
|             }
 | ||
|             finally { Lock.ExitGdiPlus(); }
 | ||
| #endif
 | ||
| #if WPF
 | ||
|             PathFigure figure = CurrentPathFigure;
 | ||
|             if (figure.Segments.Count == 0)
 | ||
|             {
 | ||
|                 figure.StartPoint = new SysPoint(points[0].X, points[0].Y);
 | ||
|                 for (int idx = 1; idx < count; idx++)
 | ||
|                 {
 | ||
| #if !SILVERLIGHT
 | ||
|                     LineSegment lineSegment = new LineSegment(new SysPoint(points[idx].X, points[idx].Y), true);
 | ||
| #else
 | ||
|                     LineSegment lineSegment = new LineSegment();
 | ||
|                     lineSegment.Point = new Point(points[idx].X, points[idx].Y); // ,true?
 | ||
| #endif
 | ||
|                     figure.Segments.Add(lineSegment);
 | ||
|                 }
 | ||
|             }
 | ||
|             else
 | ||
|             {
 | ||
|                 for (int idx = 0; idx < count; idx++)
 | ||
|                 {
 | ||
|                     // figure.Segments.Add(new LineSegment(new SysPoint(points[idx].x, points[idx].y), true));
 | ||
| #if !SILVERLIGHT
 | ||
|                     LineSegment lineSegment = new LineSegment(new SysPoint(points[idx].X, points[idx].Y), true);
 | ||
| #else
 | ||
|                     LineSegment lineSegment = new LineSegment();
 | ||
|                     lineSegment.Point = new Point(points[idx].X, points[idx].Y); // ,true?
 | ||
| #endif
 | ||
|                     figure.Segments.Add(lineSegment);
 | ||
|                 }
 | ||
|             }
 | ||
| #endif
 | ||
|         }
 | ||
| 
 | ||
|         // ----- AddBezier ----------------------------------------------------------------------------
 | ||
| 
 | ||
| #if GDI
 | ||
|         /// <summary>
 | ||
|         /// Adds a cubic B<>zier curve to the current figure.
 | ||
|         /// </summary>
 | ||
|         public void AddBezier(System.Drawing.Point pt1, System.Drawing.Point pt2, System.Drawing.Point pt3, System.Drawing.Point pt4)
 | ||
|         {
 | ||
|             AddBezier(pt1.X, pt1.Y, pt2.X, pt2.Y, pt3.X, pt3.Y, pt4.X, pt4.Y);
 | ||
|         }
 | ||
| #endif
 | ||
| 
 | ||
| #if WPF
 | ||
|         /// <summary>
 | ||
|         /// Adds a cubic B<>zier curve to the current figure.
 | ||
|         /// </summary>
 | ||
|         public void AddBezier(SysPoint pt1, SysPoint pt2, SysPoint pt3, SysPoint pt4)
 | ||
|         {
 | ||
|             AddBezier(pt1.X, pt1.Y, pt2.X, pt2.Y, pt3.X, pt3.Y, pt4.X, pt4.Y);
 | ||
|         }
 | ||
| #endif
 | ||
| 
 | ||
| #if GDI
 | ||
|         /// <summary>
 | ||
|         /// Adds a cubic B<>zier curve to the current figure.
 | ||
|         /// </summary>
 | ||
|         public void AddBezier(PointF pt1, PointF pt2, PointF pt3, PointF pt4)
 | ||
|         {
 | ||
|             AddBezier(pt1.X, pt1.Y, pt2.X, pt2.Y, pt3.X, pt3.Y, pt4.X, pt4.Y);
 | ||
|         }
 | ||
| #endif
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// Adds a cubic B<>zier curve to the current figure.
 | ||
|         /// </summary>
 | ||
|         public void AddBezier(XPoint pt1, XPoint pt2, XPoint pt3, XPoint pt4)
 | ||
|         {
 | ||
|             AddBezier(pt1.X, pt1.Y, pt2.X, pt2.Y, pt3.X, pt3.Y, pt4.X, pt4.Y);
 | ||
|         }
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// Adds a cubic B<>zier curve to the current figure.
 | ||
|         /// </summary>
 | ||
|         public void AddBezier(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4)
 | ||
|         {
 | ||
| #if CORE
 | ||
|             _corePath.MoveOrLineTo(x1, y1);
 | ||
|             _corePath.BezierTo(x2, y2, x3, y3, x4, y4, false);
 | ||
| #endif
 | ||
| #if GDI
 | ||
|             try
 | ||
|             {
 | ||
|                 Lock.EnterGdiPlus();
 | ||
|                 _gdipPath.AddBezier((float)x1, (float)y1, (float)x2, (float)y2, (float)x3, (float)y3, (float)x4, (float)y4);
 | ||
|             }
 | ||
|             finally { Lock.ExitGdiPlus(); }
 | ||
| #endif
 | ||
| #if WPF
 | ||
|             PathFigure figure = CurrentPathFigure;
 | ||
|             if (figure.Segments.Count == 0)
 | ||
|                 figure.StartPoint = new SysPoint(x1, y1);
 | ||
|             else
 | ||
|             {
 | ||
|                 // figure.Segments.Add(new LineSegment(new SysPoint(x1, y1), true));
 | ||
| #if !SILVERLIGHT
 | ||
|                 LineSegment lineSegment = new LineSegment(new SysPoint(x1, y1), true);
 | ||
| #else
 | ||
|                 LineSegment lineSegment = new LineSegment();
 | ||
|                 lineSegment.Point = new Point(x1, y1);
 | ||
| #endif
 | ||
|                 figure.Segments.Add(lineSegment);
 | ||
|             }
 | ||
|             //figure.Segments.Add(new BezierSegment(
 | ||
|             //  new SysPoint(x2, y2),
 | ||
|             //  new SysPoint(x3, y3),
 | ||
|             //  new SysPoint(x4, y4), true));
 | ||
| #if !SILVERLIGHT
 | ||
|             BezierSegment bezierSegment = new BezierSegment(
 | ||
|                 new SysPoint(x2, y2),
 | ||
|                 new SysPoint(x3, y3),
 | ||
|                 new SysPoint(x4, y4), true);
 | ||
| #else
 | ||
|             BezierSegment bezierSegment = new BezierSegment();
 | ||
|             bezierSegment.Point1 = new Point(x2, y2);
 | ||
|             bezierSegment.Point2 = new Point(x3, y3);
 | ||
|             bezierSegment.Point3 = new Point(x4, y4);
 | ||
| #endif
 | ||
|             figure.Segments.Add(bezierSegment);
 | ||
| #endif
 | ||
|         }
 | ||
| 
 | ||
|         // ----- AddBeziers ---------------------------------------------------------------------------
 | ||
| 
 | ||
| #if GDI
 | ||
|         /// <summary>
 | ||
|         /// Adds a sequence of connected cubic B<>zier curves to the current figure.
 | ||
|         /// </summary>
 | ||
|         public void AddBeziers(System.Drawing.Point[] points)
 | ||
|         {
 | ||
|             AddBeziers(XGraphics.MakeXPointArray(points, 0, points.Length));
 | ||
|         }
 | ||
| #endif
 | ||
| 
 | ||
| #if WPF
 | ||
|         /// <summary>
 | ||
|         /// Adds a sequence of connected cubic B<>zier curves to the current figure.
 | ||
|         /// </summary>
 | ||
|         public void AddBeziers(SysPoint[] points)
 | ||
|         {
 | ||
|             AddBeziers(XGraphics.MakeXPointArray(points, 0, points.Length));
 | ||
|         }
 | ||
| #endif
 | ||
| 
 | ||
| #if GDI
 | ||
|         /// <summary>
 | ||
|         /// Adds a sequence of connected cubic B<>zier curves to the current figure.
 | ||
|         /// </summary>
 | ||
|         public void AddBeziers(PointF[] points)
 | ||
|         {
 | ||
|             AddBeziers(XGraphics.MakeXPointArray(points, 0, points.Length));
 | ||
|         }
 | ||
| #endif
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// Adds a sequence of connected cubic B<>zier curves to the current figure.
 | ||
|         /// </summary>
 | ||
|         public void AddBeziers(XPoint[] points)
 | ||
|         {
 | ||
|             if (points == null)
 | ||
|                 throw new ArgumentNullException("points");
 | ||
| 
 | ||
|             int count = points.Length;
 | ||
|             if (count < 4)
 | ||
|                 throw new ArgumentException("At least four points required for bezier curve.", "points");
 | ||
| 
 | ||
|             if ((count - 1) % 3 != 0)
 | ||
|                 throw new ArgumentException("Invalid number of points for bezier curve. Number must fulfil 4+3n.",
 | ||
|                     "points");
 | ||
| 
 | ||
| #if CORE
 | ||
|             _corePath.MoveOrLineTo(points[0].X, points[0].Y);
 | ||
|             for (int idx = 1; idx < count; idx += 3)
 | ||
|             {
 | ||
|                 _corePath.BezierTo(points[idx].X, points[idx].Y, points[idx + 1].X, points[idx + 1].Y,
 | ||
|                     points[idx + 2].X, points[idx + 2].Y, false);
 | ||
|             }
 | ||
| #endif
 | ||
| #if GDI
 | ||
|             try
 | ||
|             {
 | ||
|                 Lock.EnterGdiPlus();
 | ||
|                 _gdipPath.AddBeziers(XGraphics.MakePointFArray(points));
 | ||
|             }
 | ||
|             finally { Lock.ExitGdiPlus(); }
 | ||
| #endif
 | ||
| #if WPF
 | ||
|             PathFigure figure = CurrentPathFigure;
 | ||
|             if (figure.Segments.Count == 0)
 | ||
|                 figure.StartPoint = new SysPoint(points[0].X, points[0].Y);
 | ||
|             else
 | ||
|             {
 | ||
|                 // figure.Segments.Add(new LineSegment(new SysPoint(points[0].x, points[0].y), true));
 | ||
| #if !SILVERLIGHT
 | ||
|                 LineSegment lineSegment = new LineSegment(new SysPoint(points[0].X, points[0].Y), true);
 | ||
| #else
 | ||
|                 LineSegment lineSegment = new LineSegment();
 | ||
|                 lineSegment.Point = new Point(points[0].X, points[0].Y);
 | ||
| #endif
 | ||
|                 figure.Segments.Add(lineSegment);
 | ||
|             }
 | ||
|             for (int idx = 1; idx < count; idx += 3)
 | ||
|             {
 | ||
|                 //figure.Segments.Add(new BezierSegment(
 | ||
|                 //                      new SysPoint(points[idx].x, points[idx].y),
 | ||
|                 //                      new SysPoint(points[idx + 1].x, points[idx + 1].y),
 | ||
|                 //                      new SysPoint(points[idx + 2].x, points[idx + 2].y), true));
 | ||
| #if !SILVERLIGHT
 | ||
|                 BezierSegment bezierSegment = new BezierSegment(
 | ||
|                                       new SysPoint(points[idx].X, points[idx].Y),
 | ||
|                                       new SysPoint(points[idx + 1].X, points[idx + 1].Y),
 | ||
|                                       new SysPoint(points[idx + 2].X, points[idx + 2].Y), true);
 | ||
| #else
 | ||
|                 BezierSegment bezierSegment = new BezierSegment();
 | ||
|                 bezierSegment.Point1 = new Point(points[idx].X, points[idx].Y);
 | ||
|                 bezierSegment.Point2 = new Point(points[idx + 1].X, points[idx + 1].Y);
 | ||
|                 bezierSegment.Point3 = new Point(points[idx + 2].X, points[idx + 2].Y);
 | ||
| #endif
 | ||
|                 figure.Segments.Add(bezierSegment);
 | ||
|             }
 | ||
| #endif
 | ||
|         }
 | ||
| 
 | ||
|         // ----- AddCurve -----------------------------------------------------------------------
 | ||
| 
 | ||
| #if GDI
 | ||
|         /// <summary>
 | ||
|         /// Adds a spline curve to the current figure.
 | ||
|         /// </summary>
 | ||
|         public void AddCurve(System.Drawing.Point[] points)
 | ||
|         {
 | ||
|             AddCurve(XGraphics.MakeXPointArray(points, 0, points.Length));
 | ||
|         }
 | ||
| #endif
 | ||
| 
 | ||
| #if WPF
 | ||
|         /// <summary>
 | ||
|         /// Adds a spline curve to the current figure.
 | ||
|         /// </summary>
 | ||
|         public void AddCurve(SysPoint[] points)
 | ||
|         {
 | ||
|             AddCurve(XGraphics.MakeXPointArray(points, 0, points.Length));
 | ||
|         }
 | ||
| #endif
 | ||
| 
 | ||
| #if GDI
 | ||
|         /// <summary>
 | ||
|         /// Adds a spline curve to the current figure.
 | ||
|         /// </summary>
 | ||
|         public void AddCurve(PointF[] points)
 | ||
|         {
 | ||
|             AddCurve(XGraphics.MakeXPointArray(points, 0, points.Length));
 | ||
|         }
 | ||
| #endif
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// Adds a spline curve to the current figure.
 | ||
|         /// </summary>
 | ||
|         public void AddCurve(XPoint[] points)
 | ||
|         {
 | ||
|             AddCurve(points, 0.5);
 | ||
|         }
 | ||
| 
 | ||
| #if GDI
 | ||
|         /// <summary>
 | ||
|         /// Adds a spline curve to the current figure.
 | ||
|         /// </summary>
 | ||
|         public void AddCurve(System.Drawing.Point[] points, double tension)
 | ||
|         {
 | ||
|             AddCurve(XGraphics.MakeXPointArray(points, 0, points.Length), tension);
 | ||
|         }
 | ||
| #endif
 | ||
| 
 | ||
| #if WPF
 | ||
|         /// <summary>
 | ||
|         /// Adds a spline curve to the current figure.
 | ||
|         /// </summary>
 | ||
|         public void AddCurve(SysPoint[] points, double tension)
 | ||
|         {
 | ||
|             AddCurve(XGraphics.MakeXPointArray(points, 0, points.Length), tension);
 | ||
|         }
 | ||
| #endif
 | ||
| 
 | ||
| #if GDI
 | ||
|         /// <summary>
 | ||
|         /// Adds a spline curve to the current figure.
 | ||
|         /// </summary>
 | ||
|         public void AddCurve(PointF[] points, double tension)
 | ||
|         {
 | ||
|             AddCurve(XGraphics.MakeXPointArray(points, 0, points.Length), tension);
 | ||
|         }
 | ||
| #endif
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// Adds a spline curve to the current figure.
 | ||
|         /// </summary>
 | ||
|         public void AddCurve(XPoint[] points, double tension)
 | ||
|         {
 | ||
|             int count = points.Length;
 | ||
|             if (count < 2)
 | ||
|                 throw new ArgumentException("AddCurve requires two or more points.", "points");
 | ||
| #if CORE
 | ||
|             _corePath.AddCurve(points, tension);
 | ||
| #endif
 | ||
| #if GDI
 | ||
|             try
 | ||
|             {
 | ||
|                 Lock.EnterGdiPlus();
 | ||
|                 _gdipPath.AddCurve(XGraphics.MakePointFArray(points), (float)tension);
 | ||
|             }
 | ||
|             finally { Lock.ExitGdiPlus(); }
 | ||
| #endif
 | ||
| #if WPF
 | ||
|             tension /= 3;
 | ||
| 
 | ||
|             PathFigure figure = CurrentPathFigure;
 | ||
|             if (figure.Segments.Count == 0)
 | ||
|                 figure.StartPoint = new SysPoint(points[0].X, points[0].Y);
 | ||
|             else
 | ||
|             {
 | ||
|                 // figure.Segments.Add(new LineSegment(new SysPoint(points[0].x, points[0].y), true));
 | ||
| #if !SILVERLIGHT
 | ||
|                 LineSegment lineSegment = new LineSegment(new SysPoint(points[0].X, points[0].Y), true);
 | ||
| #else
 | ||
|                 LineSegment lineSegment = new LineSegment();
 | ||
|                 lineSegment.Point = new Point(points[0].X, points[0].Y);
 | ||
| #endif
 | ||
|                 figure.Segments.Add(lineSegment);
 | ||
|             }
 | ||
| 
 | ||
|             if (count == 2)
 | ||
|             {
 | ||
|                 figure.Segments.Add(GeometryHelper.CreateCurveSegment(points[0], points[0], points[1], points[1], tension));
 | ||
|             }
 | ||
|             else
 | ||
|             {
 | ||
|                 figure.Segments.Add(GeometryHelper.CreateCurveSegment(points[0], points[0], points[1], points[2], tension));
 | ||
|                 for (int idx = 1; idx < count - 2; idx++)
 | ||
|                     figure.Segments.Add(GeometryHelper.CreateCurveSegment(points[idx - 1], points[idx], points[idx + 1], points[idx + 2], tension));
 | ||
|                 figure.Segments.Add(GeometryHelper.CreateCurveSegment(points[count - 3], points[count - 2], points[count - 1], points[count - 1], tension));
 | ||
|             }
 | ||
| #endif
 | ||
|         }
 | ||
| 
 | ||
| #if GDI
 | ||
|         /// <summary>
 | ||
|         /// Adds a spline curve to the current figure.
 | ||
|         /// </summary>
 | ||
|         public void AddCurve(System.Drawing.Point[] points, int offset, int numberOfSegments, float tension)
 | ||
|         {
 | ||
|             AddCurve(XGraphics.MakeXPointArray(points, 0, points.Length), offset, numberOfSegments, tension);
 | ||
|         }
 | ||
| #endif
 | ||
| 
 | ||
| #if WPF
 | ||
|         /// <summary>
 | ||
|         /// Adds a spline curve to the current figure.
 | ||
|         /// </summary>
 | ||
|         public void AddCurve(SysPoint[] points, int offset, int numberOfSegments, float tension)
 | ||
|         {
 | ||
|             AddCurve(XGraphics.MakeXPointArray(points, 0, points.Length), offset, numberOfSegments, tension);
 | ||
|         }
 | ||
| #endif
 | ||
| 
 | ||
| #if GDI
 | ||
|         /// <summary>
 | ||
|         /// Adds a spline curve to the current figure.
 | ||
|         /// </summary>
 | ||
|         public void AddCurve(PointF[] points, int offset, int numberOfSegments, float tension)
 | ||
|         {
 | ||
|             AddCurve(XGraphics.MakeXPointArray(points, 0, points.Length), offset, numberOfSegments, tension);
 | ||
|         }
 | ||
| #endif
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// Adds a spline curve to the current figure.
 | ||
|         /// </summary>
 | ||
|         public void AddCurve(XPoint[] points, int offset, int numberOfSegments, double tension)
 | ||
|         {
 | ||
| #if CORE
 | ||
|             throw new NotImplementedException("AddCurve not yet implemented.");
 | ||
| #endif
 | ||
| #if GDI
 | ||
|             try
 | ||
|             {
 | ||
|                 Lock.EnterGdiPlus();
 | ||
|                 _gdipPath.AddCurve(XGraphics.MakePointFArray(points), offset, numberOfSegments, (float)tension);
 | ||
|             }
 | ||
|             finally { Lock.ExitGdiPlus(); }
 | ||
| #endif
 | ||
| #if WPF
 | ||
|             throw new NotImplementedException("AddCurve not yet implemented.");
 | ||
| #endif
 | ||
|         }
 | ||
| 
 | ||
|         // ----- AddArc -------------------------------------------------------------------------------
 | ||
| 
 | ||
| #if GDI
 | ||
|         /// <summary>
 | ||
|         /// Adds an elliptical arc to the current figure.
 | ||
|         /// </summary>
 | ||
|         public void AddArc(Rectangle rect, double startAngle, double sweepAngle)
 | ||
|         {
 | ||
|             AddArc(rect.X, rect.Y, rect.Width, rect.Height, startAngle, sweepAngle);
 | ||
|         }
 | ||
| #endif
 | ||
| 
 | ||
| #if GDI
 | ||
|         /// <summary>
 | ||
|         /// Adds an elliptical arc to the current figure.
 | ||
|         /// </summary>
 | ||
|         public void AddArc(RectangleF rect, double startAngle, double sweepAngle)
 | ||
|         {
 | ||
|             AddArc(rect.X, rect.Y, rect.Width, rect.Height, startAngle, sweepAngle);
 | ||
|         }
 | ||
| #endif
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// Adds an elliptical arc to the current figure.
 | ||
|         /// </summary>
 | ||
|         public void AddArc(XRect rect, double startAngle, double sweepAngle)
 | ||
|         {
 | ||
|             AddArc(rect.X, rect.Y, rect.Width, rect.Height, startAngle, sweepAngle);
 | ||
|         }
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// Adds an elliptical arc to the current figure.
 | ||
|         /// </summary>
 | ||
|         public void AddArc(double x, double y, double width, double height, double startAngle, double sweepAngle)
 | ||
|         {
 | ||
| #if CORE
 | ||
|             _corePath.AddArc(x, y, width, height, startAngle, sweepAngle);
 | ||
| #endif
 | ||
| #if GDI
 | ||
|             try
 | ||
|             {
 | ||
|                 Lock.EnterGdiPlus();
 | ||
|                 _gdipPath.AddArc((float)x, (float)y, (float)width, (float)height, (float)startAngle, (float)sweepAngle);
 | ||
|             }
 | ||
|             finally { Lock.ExitGdiPlus(); }
 | ||
| #endif
 | ||
| #if WPF
 | ||
|             PathFigure figure = CurrentPathFigure;
 | ||
|             SysPoint startPoint;
 | ||
|             ArcSegment seg = GeometryHelper.CreateArcSegment(x, y, width, height, startAngle, sweepAngle, out startPoint);
 | ||
|             if (figure.Segments.Count == 0)
 | ||
|                 figure.StartPoint = startPoint;
 | ||
|             else
 | ||
|             {
 | ||
|                 //#if !SILVERLIGHT
 | ||
|                 //                LineSegment lineSegment = new LineSegment(startPoint, true);
 | ||
|                 //#else
 | ||
|                 LineSegment lineSegment = new LineSegment();
 | ||
|                 lineSegment.Point = startPoint;
 | ||
|                 //#endif
 | ||
|                 figure.Segments.Add(lineSegment);
 | ||
|             }
 | ||
| 
 | ||
|             figure.Segments.Add(seg);
 | ||
| 
 | ||
|             //figure.Segments.Add(
 | ||
|             //if (figure.Segments.Count == 0)
 | ||
|             //  figure.StartPoint = new SysPoint(points[0].x, points[0].y);
 | ||
|             //else
 | ||
|             //  figure.Segments.Add(new LineSegment(new SysPoint(points[0].x, points[0].y), true));
 | ||
| 
 | ||
|             //for (int idx = 1; idx < 5555; idx += 3)
 | ||
|             //  figure.Segments.Add(new BezierSegment(
 | ||
|             //    new SysPoint(points[idx].x, points[idx].y),
 | ||
|             //    new SysPoint(points[idx + 1].x, points[idx + 1].y),
 | ||
|             //    new SysPoint(points[idx + 2].x, points[idx + 2].y), true));
 | ||
| #endif
 | ||
|         }
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// Adds an elliptical arc to the current figure. The arc is specified WPF like.
 | ||
|         /// </summary>
 | ||
|         public void AddArc(XPoint point1, XPoint point2, XSize size, double rotationAngle, bool isLargeArg, XSweepDirection sweepDirection)
 | ||
|         {
 | ||
| #if CORE
 | ||
|             _corePath.AddArc(point1, point2, size, rotationAngle, isLargeArg, sweepDirection);
 | ||
| #endif
 | ||
| #if GDI
 | ||
|             DiagnosticsHelper.HandleNotImplemented("XGraphicsPath.AddArc");
 | ||
| #endif
 | ||
| #if WPF
 | ||
|             PathFigure figure = CurrentPathFigure;
 | ||
|             if (figure.Segments.Count == 0)
 | ||
|                 figure.StartPoint = point1.ToPoint();
 | ||
|             else
 | ||
|             {
 | ||
|                 // figure.Segments.Add(new LineSegment(point1.ToPoint(), true));
 | ||
| #if !SILVERLIGHT
 | ||
|                 LineSegment lineSegment = new LineSegment(point1.ToPoint(), true);
 | ||
| #else
 | ||
|                 LineSegment lineSegment = new LineSegment();
 | ||
|                 lineSegment.Point = point1.ToPoint();
 | ||
| #endif
 | ||
|                 figure.Segments.Add(lineSegment);
 | ||
|             }
 | ||
| 
 | ||
|             // figure.Segments.Add(new ArcSegment(point2.ToPoint(), size.ToSize(), rotationAngle, isLargeArg, sweepDirection, true));
 | ||
| #if !SILVERLIGHT
 | ||
|             ArcSegment arcSegment = new ArcSegment(point2.ToPoint(), size.ToSize(), rotationAngle, isLargeArg, (SweepDirection)sweepDirection, true);
 | ||
| #else
 | ||
|             ArcSegment arcSegment = new ArcSegment();
 | ||
|             arcSegment.Point = point2.ToPoint();
 | ||
|             arcSegment.Size = size.ToSize();
 | ||
|             arcSegment.RotationAngle = rotationAngle;
 | ||
|             arcSegment.IsLargeArc = isLargeArg;
 | ||
|             arcSegment.SweepDirection = (SweepDirection)sweepDirection;
 | ||
| #endif
 | ||
|             figure.Segments.Add(arcSegment);
 | ||
| #endif
 | ||
|         }
 | ||
| 
 | ||
|         // ----- AddRectangle -------------------------------------------------------------------------
 | ||
| 
 | ||
| #if GDI
 | ||
|         /// <summary>
 | ||
|         /// Adds a rectangle to this path.
 | ||
|         /// </summary>
 | ||
|         public void AddRectangle(Rectangle rect)
 | ||
|         {
 | ||
|             AddRectangle(new XRect(rect));
 | ||
|         }
 | ||
| #endif
 | ||
| 
 | ||
| #if GDI
 | ||
|         /// <summary>
 | ||
|         /// Adds a rectangle to this path.
 | ||
|         /// </summary>
 | ||
|         public void AddRectangle(RectangleF rect)
 | ||
|         {
 | ||
|             AddRectangle(new XRect(rect));
 | ||
|         }
 | ||
| #endif
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// Adds a rectangle to this path.
 | ||
|         /// </summary>
 | ||
|         public void AddRectangle(XRect rect)
 | ||
|         {
 | ||
| #if CORE
 | ||
|             _corePath.MoveTo(rect.X, rect.Y);
 | ||
|             _corePath.LineTo(rect.X + rect.Width, rect.Y, false);
 | ||
|             _corePath.LineTo(rect.X + rect.Width, rect.Y + rect.Height, false);
 | ||
|             _corePath.LineTo(rect.X, rect.Y + rect.Height, true);
 | ||
|             _corePath.CloseSubpath();
 | ||
| #endif
 | ||
| #if GDI
 | ||
|             try
 | ||
|             {
 | ||
|                 Lock.EnterGdiPlus();
 | ||
|                 // If rect is empty GDI+ removes the rect from the path.
 | ||
|                 // This is not intended if the path is used for clipping.
 | ||
|                 // See http://forum.pdfsharp.net/viewtopic.php?p=9433#p9433
 | ||
|                 // _gdipPath.AddRectangle(rect.ToRectangleF());
 | ||
| 
 | ||
|                 // Draw the rectangle manually.
 | ||
|                 _gdipPath.StartFigure();
 | ||
|                 _gdipPath.AddLines(new PointF[] { rect.TopLeft.ToPointF(), rect.TopRight.ToPointF(), rect.BottomRight.ToPointF(), rect.BottomLeft.ToPointF() });
 | ||
|                 _gdipPath.CloseFigure();
 | ||
|             }
 | ||
|             finally { Lock.ExitGdiPlus(); }
 | ||
| #endif
 | ||
| #if WPF
 | ||
|             StartFigure();
 | ||
|             PathFigure figure = CurrentPathFigure;
 | ||
|             figure.StartPoint = new SysPoint(rect.X, rect.Y);
 | ||
| 
 | ||
|             // figure.Segments.Add(new LineSegment(new SysPoint(rect.x + rect.width, rect.y), true));
 | ||
|             // figure.Segments.Add(new LineSegment(new SysPoint(rect.x + rect.width, rect.y + rect.height), true));
 | ||
|             // figure.Segments.Add(new LineSegment(new SysPoint(rect.x, rect.y + rect.height), true));
 | ||
| #if !SILVERLIGHT
 | ||
|             LineSegment lineSegment1 = new LineSegment(new SysPoint(rect.X + rect.Width, rect.Y), true);
 | ||
|             LineSegment lineSegment2 = new LineSegment(new SysPoint(rect.X + rect.Width, rect.Y + rect.Height), true);
 | ||
|             LineSegment lineSegment3 = new LineSegment(new SysPoint(rect.X, rect.Y + rect.Height), true);
 | ||
| #else
 | ||
|             LineSegment lineSegment1 = new LineSegment();
 | ||
|             lineSegment1.Point = new Point(rect.X + rect.Width, rect.Y);
 | ||
|             LineSegment lineSegment2 = new LineSegment();
 | ||
|             lineSegment2.Point = new Point(rect.X + rect.Width, rect.Y + rect.Height);
 | ||
|             LineSegment lineSegment3 = new LineSegment();
 | ||
|             lineSegment3.Point = new Point(rect.X, rect.Y + rect.Height);
 | ||
| #endif
 | ||
|             figure.Segments.Add(lineSegment1);
 | ||
|             figure.Segments.Add(lineSegment2);
 | ||
|             figure.Segments.Add(lineSegment3);
 | ||
|             CloseFigure();
 | ||
| #endif
 | ||
|         }
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// Adds a rectangle to this path.
 | ||
|         /// </summary>
 | ||
|         public void AddRectangle(double x, double y, double width, double height)
 | ||
|         {
 | ||
|             AddRectangle(new XRect(x, y, width, height));
 | ||
|         }
 | ||
| 
 | ||
|         // ----- AddRectangles ------------------------------------------------------------------------
 | ||
| 
 | ||
| #if GDI
 | ||
|         /// <summary>
 | ||
|         /// Adds a series of rectangles to this path.
 | ||
|         /// </summary>
 | ||
|         public void AddRectangles(Rectangle[] rects)
 | ||
|         {
 | ||
|             int count = rects.Length;
 | ||
|             for (int idx = 0; idx < count; idx++)
 | ||
|                 AddRectangle(rects[idx]);
 | ||
| 
 | ||
|             try
 | ||
|             {
 | ||
|                 Lock.EnterGdiPlus();
 | ||
|                 _gdipPath.AddRectangles(rects);
 | ||
|             }
 | ||
|             finally { Lock.ExitGdiPlus(); }
 | ||
|         }
 | ||
| #endif
 | ||
| 
 | ||
| #if GDI
 | ||
|         /// <summary>
 | ||
|         /// Adds a series of rectangles to this path.
 | ||
|         /// </summary>
 | ||
|         public void AddRectangles(RectangleF[] rects)
 | ||
|         {
 | ||
|             int count = rects.Length;
 | ||
|             for (int idx = 0; idx < count; idx++)
 | ||
|                 AddRectangle(rects[idx]);
 | ||
| 
 | ||
|             try
 | ||
|             {
 | ||
|                 Lock.EnterGdiPlus();
 | ||
|                 _gdipPath.AddRectangles(rects);
 | ||
|             }
 | ||
|             finally { Lock.ExitGdiPlus(); }
 | ||
|         }
 | ||
| #endif
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// Adds a series of rectangles to this path.
 | ||
|         /// </summary>
 | ||
|         public void AddRectangles(XRect[] rects)
 | ||
|         {
 | ||
|             int count = rects.Length;
 | ||
|             for (int idx = 0; idx < count; idx++)
 | ||
|             {
 | ||
| #if CORE
 | ||
|                 AddRectangle(rects[idx]);
 | ||
| #endif
 | ||
| #if GDI
 | ||
|                 try
 | ||
|                 {
 | ||
|                     Lock.EnterGdiPlus();
 | ||
|                     _gdipPath.AddRectangle(rects[idx].ToRectangleF());
 | ||
|                 }
 | ||
|                 finally { Lock.ExitGdiPlus(); }
 | ||
| #endif
 | ||
| #if WPF
 | ||
|                 StartFigure();
 | ||
|                 PathFigure figure = CurrentPathFigure;
 | ||
|                 XRect rect = rects[idx];
 | ||
|                 figure.StartPoint = new SysPoint(rect.X, rect.Y);
 | ||
| 
 | ||
|                 // figure.Segments.Add(new LineSegment(new SysPoint(rect.x + rect.width, rect.y), true));
 | ||
|                 // figure.Segments.Add(new LineSegment(new SysPoint(rect.x + rect.width, rect.y + rect.height), true));
 | ||
|                 // figure.Segments.Add(new LineSegment(new SysPoint(rect.x, rect.y + rect.height), true));
 | ||
| #if !SILVERLIGHT
 | ||
|                 LineSegment lineSegment1 = new LineSegment(new SysPoint(rect.X + rect.Width, rect.Y), true);
 | ||
|                 LineSegment lineSegment2 = new LineSegment(new SysPoint(rect.X + rect.Width, rect.Y + rect.Height), true);
 | ||
|                 LineSegment lineSegment3 = new LineSegment(new SysPoint(rect.X, rect.Y + rect.Height), true);
 | ||
| #else
 | ||
|                 LineSegment lineSegment1 = new LineSegment();
 | ||
|                 lineSegment1.Point = new Point(rect.X + rect.Width, rect.Y);
 | ||
|                 LineSegment lineSegment2 = new LineSegment();
 | ||
|                 lineSegment2.Point = new Point(rect.X + rect.Width, rect.Y + rect.Height);
 | ||
|                 LineSegment lineSegment3 = new LineSegment();
 | ||
|                 lineSegment3.Point = new Point(rect.X, rect.Y + rect.Height);
 | ||
| #endif
 | ||
|                 figure.Segments.Add(lineSegment1);
 | ||
|                 figure.Segments.Add(lineSegment2);
 | ||
|                 figure.Segments.Add(lineSegment3);
 | ||
|                 CloseFigure();
 | ||
| #endif
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         // ----- AddRoundedRectangle ------------------------------------------------------------------
 | ||
| 
 | ||
| #if GDI
 | ||
|         /// <summary>
 | ||
|         /// Adds a rectangle with rounded corners to this path.
 | ||
|         /// </summary>
 | ||
|         public void AddRoundedRectangle(Rectangle rect, System.Drawing.Size ellipseSize)
 | ||
|         {
 | ||
|             AddRoundedRectangle(rect.X, rect.Y, rect.Width, rect.Height, ellipseSize.Width, ellipseSize.Height);
 | ||
|         }
 | ||
| #endif
 | ||
| 
 | ||
| #if WPF || NETFX_CORE
 | ||
|         /// <summary>
 | ||
|         /// Adds a rectangle with rounded corners to this path.
 | ||
|         /// </summary>
 | ||
|         public void AddRoundedRectangle(SysRect rect, SysSize ellipseSize)
 | ||
|         {
 | ||
|             AddRoundedRectangle(rect.X, rect.Y, rect.Width, rect.Height, ellipseSize.Width, ellipseSize.Height);
 | ||
|         }
 | ||
| #endif
 | ||
| 
 | ||
| #if GDI
 | ||
|         /// <summary>
 | ||
|         /// Adds a rectangle with rounded corners to this path.
 | ||
|         /// </summary>
 | ||
|         public void AddRoundedRectangle(RectangleF rect, SizeF ellipseSize)
 | ||
|         {
 | ||
|             AddRoundedRectangle(rect.X, rect.Y, rect.Width, rect.Height, ellipseSize.Width, ellipseSize.Height);
 | ||
|         }
 | ||
| #endif
 | ||
| 
 | ||
| #if GDI
 | ||
|         /// <summary>
 | ||
|         /// Adds a rectangle with rounded corners to this path.
 | ||
|         /// </summary>
 | ||
|         public void AddRoundedRectangle(XRect rect, SizeF ellipseSize)
 | ||
|         {
 | ||
|             AddRoundedRectangle(rect.X, rect.Y, rect.Width, rect.Height, ellipseSize.Width, ellipseSize.Height);
 | ||
|         }
 | ||
| #endif
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// Adds a rectangle with rounded corners to this path.
 | ||
|         /// </summary>
 | ||
|         public void AddRoundedRectangle(double x, double y, double width, double height, double ellipseWidth, double ellipseHeight)
 | ||
|         {
 | ||
| #if CORE
 | ||
| #if true
 | ||
|             double arcWidth = ellipseWidth / 2;
 | ||
|             double arcHeight = ellipseHeight / 2;
 | ||
| #if true  // Clockwise
 | ||
|             _corePath.MoveTo(x + width - arcWidth, y);
 | ||
|             _corePath.QuadrantArcTo(x + width - arcWidth, y + arcHeight, arcWidth, arcHeight, 1, true);
 | ||
| 
 | ||
|             _corePath.LineTo(x + width, y + height - arcHeight, false);
 | ||
|             _corePath.QuadrantArcTo(x + width - arcWidth, y + height - arcHeight, arcWidth, arcHeight, 4, true);
 | ||
| 
 | ||
|             _corePath.LineTo(x + arcWidth, y + height, false);
 | ||
|             _corePath.QuadrantArcTo(x + arcWidth, y + height - arcHeight, arcWidth, arcHeight, 3, true);
 | ||
| 
 | ||
|             _corePath.LineTo(x, y + arcHeight, false);
 | ||
|             _corePath.QuadrantArcTo(x + arcWidth, y + arcHeight, arcWidth, arcHeight, 2, true);
 | ||
| 
 | ||
|             _corePath.CloseSubpath();
 | ||
| #else  // Counterclockwise
 | ||
|             _corePath.MoveTo(x + arcWidth, y);
 | ||
|             _corePath.QuadrantArcTo(x + arcWidth, y + arcHeight, arcWidth, arcHeight, 2, false);
 | ||
| 
 | ||
|             _corePath.LineTo(x, y + height - arcHeight, false);
 | ||
|             _corePath.QuadrantArcTo(x + arcWidth, y + height - arcHeight, arcWidth, arcHeight, 3, false);
 | ||
| 
 | ||
|             _corePath.LineTo(x + width - arcWidth, y + height, false);
 | ||
|             _corePath.QuadrantArcTo(x + width - arcWidth, y + height - arcHeight, arcWidth, arcHeight, 4, false);
 | ||
| 
 | ||
|             _corePath.LineTo(x + width, y + arcHeight, false);
 | ||
|             _corePath.QuadrantArcTo(x + width - arcWidth, y + arcHeight, arcWidth, arcHeight, 1, false);
 | ||
| 
 | ||
|             _corePath.CloseSubpath();
 | ||
| #endif
 | ||
| #else
 | ||
|             // AddArc not yet implemented
 | ||
|             AddArc((float)(x + width - ellipseWidth), (float)y, (float)ellipseWidth, (float)ellipseHeight, -90, 90);
 | ||
|             AddArc((float)(x + width - ellipseWidth), (float)(y + height - ellipseHeight), (float)ellipseWidth,
 | ||
|                 (float)ellipseHeight, 0, 90);
 | ||
|             AddArc((float)x, (float)(y + height - ellipseHeight), (float)ellipseWidth, (float)ellipseHeight, 90, 90);
 | ||
|             AddArc((float)x, (float)y, (float)ellipseWidth, (float)ellipseHeight, 180, 90);
 | ||
|             CloseFigure();
 | ||
| #endif
 | ||
| #endif
 | ||
| #if GDI
 | ||
|             try
 | ||
|             {
 | ||
|                 Lock.EnterGdiPlus();
 | ||
|                 _gdipPath.StartFigure();
 | ||
|                 _gdipPath.AddArc((float)(x + width - ellipseWidth), (float)y, (float)ellipseWidth, (float)ellipseHeight, -90, 90);
 | ||
|                 _gdipPath.AddArc((float)(x + width - ellipseWidth), (float)(y + height - ellipseHeight), (float)ellipseWidth, (float)ellipseHeight, 0, 90);
 | ||
|                 _gdipPath.AddArc((float)x, (float)(y + height - ellipseHeight), (float)ellipseWidth, (float)ellipseHeight, 90, 90);
 | ||
|                 _gdipPath.AddArc((float)x, (float)y, (float)ellipseWidth, (float)ellipseHeight, 180, 90);
 | ||
|                 _gdipPath.CloseFigure();
 | ||
|             }
 | ||
|             finally { Lock.ExitGdiPlus(); }
 | ||
| #endif
 | ||
| #if WPF || NETFX_CORE
 | ||
|             double ex = ellipseWidth / 2;
 | ||
|             double ey = ellipseHeight / 2;
 | ||
|             StartFigure();
 | ||
|             PathFigure figure = CurrentPathFigure;
 | ||
|             figure.StartPoint = new SysPoint(x + ex, y);
 | ||
| 
 | ||
|             //#if !SILVERLIGHT
 | ||
|             //      figure.Segments.Add(new LineSegment(new SysPoint(x + width - ex, y), true));
 | ||
|             //      // TODOWPF XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXx
 | ||
|             //      figure.Segments.Add(new ArcSegment(new SysPoint(x + width, y + ey), new SysSize(ex, ey), 0, false, SweepDirection.Clockwise, true));
 | ||
|             //      //figure.Segments.Add(new LineSegment(new SysPoint(x + width, y + ey), true));
 | ||
| 
 | ||
|             //      figure.Segments.Add(new LineSegment(new SysPoint(x + width, y + height - ey), true));
 | ||
|             //      // TODOWPF
 | ||
|             //      figure.Segments.Add(new ArcSegment(new SysPoint(x + width - ex, y + height), new SysSize(ex, ey), 0, false, SweepDirection.Clockwise, true));
 | ||
|             //      //figure.Segments.Add(new LineSegment(new SysPoint(x + width - ex, y + height), true));
 | ||
| 
 | ||
|             //      figure.Segments.Add(new LineSegment(new SysPoint(x + ex, y + height), true));
 | ||
|             //      // TODOWPF
 | ||
|             //      figure.Segments.Add(new ArcSegment(new SysPoint(x, y + height - ey), new SysSize(ex, ey), 0, false, SweepDirection.Clockwise, true));
 | ||
|             //      //figure.Segments.Add(new LineSegment(new SysPoint(x, y + height - ey), true));
 | ||
| 
 | ||
|             //      figure.Segments.Add(new LineSegment(new SysPoint(x, y + ey), true));
 | ||
|             //      // TODOWPF
 | ||
|             //      figure.Segments.Add(new ArcSegment(new SysPoint(x + ex, y), new SysSize(ex, ey), 0, false, SweepDirection.Clockwise, true));
 | ||
|             //      //figure.Segments.Add(new LineSegment(new SysPoint(x + ex, y), true));
 | ||
|             //#else
 | ||
| 
 | ||
| #if !SILVERLIGHT && !NETFX_CORE
 | ||
|             figure.Segments.Add(new LineSegment(new SysPoint(x + width - ex, y), true));
 | ||
| #else
 | ||
|             figure.Segments.Add(new LineSegment { Point = new SysPoint(x + width - ex, y) });
 | ||
| #endif
 | ||
| 
 | ||
|             // TODOWPF XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXx
 | ||
| #if !SILVERLIGHT && !NETFX_CORE
 | ||
|             figure.Segments.Add(new ArcSegment(new SysPoint(x + width, y + ey), new SysSize(ex, ey), 0, false, SweepDirection.Clockwise, true));
 | ||
|             //figure.Segments.Add(new LineSegment(new SysPoint(x + width, y + ey), true));
 | ||
| #else
 | ||
|             figure.Segments.Add(new ArcSegment
 | ||
|             {
 | ||
|                 Point = new SysPoint(x + width, y + ey),
 | ||
|                 Size = new SysSize(ex, ey),
 | ||
|                 //RotationAngle = 0,
 | ||
|                 //IsLargeArc = false,
 | ||
|                 SweepDirection = SweepDirection.Clockwise
 | ||
|             });
 | ||
| #endif
 | ||
| 
 | ||
| #if !SILVERLIGHT && !NETFX_CORE
 | ||
|             figure.Segments.Add(new LineSegment(new SysPoint(x + width, y + height - ey), true));
 | ||
| #else
 | ||
|             figure.Segments.Add(new LineSegment { Point = new SysPoint(x + width, y + height - ey) });
 | ||
| #endif
 | ||
| 
 | ||
|             // TODOWPF
 | ||
| #if !SILVERLIGHT && !NETFX_CORE
 | ||
|             figure.Segments.Add(new ArcSegment(new SysPoint(x + width - ex, y + height), new SysSize(ex, ey), 0, false, SweepDirection.Clockwise, true));
 | ||
|             //figure.Segments.Add(new LineSegment(new SysPoint(x + width - ex, y + height), true));
 | ||
| #else
 | ||
|             figure.Segments.Add(new ArcSegment
 | ||
|             {
 | ||
|                 Point = new SysPoint(x + width - ex, y + height),
 | ||
|                 Size = new SysSize(ex, ey),
 | ||
|                 //RotationAngle = 0,
 | ||
|                 //IsLargeArc = false,
 | ||
|                 SweepDirection = SweepDirection.Clockwise
 | ||
|             });
 | ||
| #endif
 | ||
| 
 | ||
| #if !SILVERLIGHT && !NETFX_CORE
 | ||
|             figure.Segments.Add(new LineSegment(new SysPoint(x + ex, y + height), true));
 | ||
| #else
 | ||
|             figure.Segments.Add(new LineSegment { Point = new SysPoint(x + ex, y + height) });
 | ||
| #endif
 | ||
| 
 | ||
|             // TODOWPF
 | ||
| #if !SILVERLIGHT && !NETFX_CORE
 | ||
|             figure.Segments.Add(new ArcSegment(new SysPoint(x, y + height - ey), new SysSize(ex, ey), 0, false, SweepDirection.Clockwise, true));
 | ||
|             //figure.Segments.Add(new LineSegment(new SysPoint(x, y + height - ey), true));
 | ||
| #else
 | ||
|             figure.Segments.Add(new ArcSegment
 | ||
|             {
 | ||
|                 Point = new SysPoint(x, y + height - ey),
 | ||
|                 Size = new SysSize(ex, ey),
 | ||
|                 //RotationAngle = 0,
 | ||
|                 //IsLargeArc = false,
 | ||
|                 SweepDirection = SweepDirection.Clockwise
 | ||
|             });
 | ||
| #endif
 | ||
| 
 | ||
| #if !SILVERLIGHT && !NETFX_CORE
 | ||
|             figure.Segments.Add(new LineSegment(new SysPoint(x, y + ey), true));
 | ||
| #else
 | ||
|             figure.Segments.Add(new LineSegment { Point = new SysPoint(x, y + ey) });
 | ||
| #endif
 | ||
| 
 | ||
|             // TODOWPF
 | ||
| #if !SILVERLIGHT && !NETFX_CORE
 | ||
|             figure.Segments.Add(new ArcSegment(new SysPoint(x + ex, y), new SysSize(ex, ey), 0, false, SweepDirection.Clockwise, true));
 | ||
|             //figure.Segments.Add(new LineSegment(new SysPoint(x + ex, y), true));
 | ||
| #else
 | ||
|             figure.Segments.Add(new ArcSegment
 | ||
|             {
 | ||
|                 Point = new SysPoint(x + ex, y),
 | ||
|                 Size = new SysSize(ex, ey),
 | ||
|                 //RotationAngle = 0,
 | ||
|                 //IsLargeArc = false,
 | ||
|                 SweepDirection = SweepDirection.Clockwise
 | ||
|             });
 | ||
| #endif
 | ||
|             CloseFigure();
 | ||
| #endif
 | ||
|         }
 | ||
| 
 | ||
|         // ----- AddEllipse ---------------------------------------------------------------------------
 | ||
| 
 | ||
| #if GDI
 | ||
|         /// <summary>
 | ||
|         /// Adds an ellipse to the current path.
 | ||
|         /// </summary>
 | ||
|         public void AddEllipse(Rectangle rect)
 | ||
|         {
 | ||
|             AddEllipse(rect.X, rect.Y, rect.Width, rect.Height);
 | ||
|         }
 | ||
| #endif
 | ||
| 
 | ||
| #if GDI
 | ||
|         /// <summary>
 | ||
|         /// Adds an ellipse to the current path.
 | ||
|         /// </summary>
 | ||
|         public void AddEllipse(RectangleF rect)
 | ||
|         {
 | ||
|             AddEllipse(rect.X, rect.Y, rect.Width, rect.Height);
 | ||
|         }
 | ||
| #endif
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// Adds an ellipse to the current path.
 | ||
|         /// </summary>
 | ||
|         public void AddEllipse(XRect rect)
 | ||
|         {
 | ||
|             AddEllipse(rect.X, rect.Y, rect.Width, rect.Height);
 | ||
|         }
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// Adds an ellipse to the current path.
 | ||
|         /// </summary>
 | ||
|         public void AddEllipse(double x, double y, double width, double height)
 | ||
|         {
 | ||
| #if CORE
 | ||
|             double w = width / 2;
 | ||
|             double h = height / 2;
 | ||
|             double xc = x + w;
 | ||
|             double yc = y + h;
 | ||
|             _corePath.MoveTo(x + w, y);
 | ||
|             _corePath.QuadrantArcTo(xc, yc, w, h, 1, true);
 | ||
|             _corePath.QuadrantArcTo(xc, yc, w, h, 4, true);
 | ||
|             _corePath.QuadrantArcTo(xc, yc, w, h, 3, true);
 | ||
|             _corePath.QuadrantArcTo(xc, yc, w, h, 2, true);
 | ||
|             _corePath.CloseSubpath();
 | ||
| #endif
 | ||
| #if GDI
 | ||
|             try
 | ||
|             {
 | ||
|                 Lock.EnterGdiPlus();
 | ||
|                 _gdipPath.AddEllipse((float)x, (float)y, (float)width, (float)height);
 | ||
|             }
 | ||
|             finally { Lock.ExitGdiPlus(); }
 | ||
| #endif
 | ||
| #if WPF || NETFX_CORE
 | ||
| #if !SILVERLIGHT && !NETFX_CORE
 | ||
|             _pathGeometry.AddGeometry(new EllipseGeometry(new Rect(x, y, width, height)));
 | ||
| #else
 | ||
|             var figure = new PathFigure();
 | ||
|             figure.StartPoint = new SysPoint(x, y + height / 2);
 | ||
|             var segment = new ArcSegment
 | ||
|             {
 | ||
|                 Point = new SysPoint(x + width, y + height / 2),
 | ||
|                 Size = new SysSize(width / 2, height / 2),
 | ||
|                 IsLargeArc = true,
 | ||
|                 RotationAngle = 180,
 | ||
|                 SweepDirection = SweepDirection.Clockwise,
 | ||
|             };
 | ||
|             figure.Segments.Add(segment);
 | ||
|             segment = new ArcSegment
 | ||
|             {
 | ||
|                 Point = figure.StartPoint,
 | ||
|                 Size = new SysSize(width / 2, height / 2),
 | ||
|                 IsLargeArc = true,
 | ||
|                 RotationAngle = 180,
 | ||
|                 SweepDirection = SweepDirection.Clockwise,
 | ||
|             };
 | ||
|             figure.Segments.Add(segment);
 | ||
|             _pathGeometry.Figures.Add(figure);
 | ||
| #endif
 | ||
|             // StartFigure() isn't needed because AddGeometry() implicitly starts a new figure,
 | ||
|             // but CloseFigure() is needed for the next adding not to continue this figure.
 | ||
|             CloseFigure();
 | ||
| #endif
 | ||
|         }
 | ||
| 
 | ||
|         // ----- AddPolygon ---------------------------------------------------------------------------
 | ||
| 
 | ||
| #if GDI
 | ||
|         /// <summary>
 | ||
|         /// Adds a polygon to this path.
 | ||
|         /// </summary>
 | ||
|         public void AddPolygon(System.Drawing.Point[] points)
 | ||
|         {
 | ||
|             try
 | ||
|             {
 | ||
|                 Lock.EnterGdiPlus();
 | ||
|                 _gdipPath.AddPolygon(points);
 | ||
|             }
 | ||
|             finally { Lock.ExitGdiPlus(); }
 | ||
|         }
 | ||
| #endif
 | ||
| 
 | ||
| #if WPF || NETFX_CORE
 | ||
|         /// <summary>
 | ||
|         /// Adds a polygon to this path.
 | ||
|         /// </summary>
 | ||
|         public void AddPolygon(SysPoint[] points)
 | ||
|         {
 | ||
|             // TODO: fill mode unclear here
 | ||
| #if !SILVERLIGHT && !NETFX_CORE
 | ||
|             _pathGeometry.AddGeometry(GeometryHelper.CreatePolygonGeometry(points, XFillMode.Alternate, true));
 | ||
|             CloseFigure(); // StartFigure() isn't needed because AddGeometry() implicitly starts a new figure, but CloseFigure() is needed for the next adding not to continue this figure.
 | ||
| #else
 | ||
|             AddPolygon(XGraphics.MakeXPointArray(points, 0, points.Length));
 | ||
| #endif
 | ||
|         }
 | ||
| #endif
 | ||
| 
 | ||
| #if GDI
 | ||
|         /// <summary>
 | ||
|         /// Adds a polygon to this path.
 | ||
|         /// </summary>
 | ||
|         public void AddPolygon(PointF[] points)
 | ||
|         {
 | ||
|             try
 | ||
|             {
 | ||
|                 Lock.EnterGdiPlus();
 | ||
|                 _gdipPath.AddPolygon(points);
 | ||
|             }
 | ||
|             finally { Lock.ExitGdiPlus(); }
 | ||
|         }
 | ||
| #endif
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// Adds a polygon to this path.
 | ||
|         /// </summary>
 | ||
|         public void AddPolygon(XPoint[] points)
 | ||
|         {
 | ||
| #if CORE
 | ||
|             int count = points.Length;
 | ||
|             if (count == 0)
 | ||
|                 return;
 | ||
| 
 | ||
|             _corePath.MoveTo(points[0].X, points[0].Y);
 | ||
|             for (int idx = 0; idx < count - 1; idx++)
 | ||
|                 _corePath.LineTo(points[idx].X, points[idx].Y, false);
 | ||
|             _corePath.LineTo(points[count - 1].X, points[count - 1].Y, true);
 | ||
|             _corePath.CloseSubpath();
 | ||
| #endif
 | ||
| #if GDI
 | ||
|             try
 | ||
|             {
 | ||
|                 Lock.EnterGdiPlus();
 | ||
|                 _gdipPath.AddPolygon(XGraphics.MakePointFArray(points));
 | ||
|             }
 | ||
|             finally { Lock.ExitGdiPlus(); }
 | ||
| #endif
 | ||
| #if WPF || NETFX_CORE
 | ||
| #if !SILVERLIGHT && !NETFX_CORE
 | ||
|             _pathGeometry.AddGeometry(GeometryHelper.CreatePolygonGeometry(XGraphics.MakePointArray(points), XFillMode.Alternate, true));
 | ||
| #else
 | ||
|             var figure = new PathFigure();
 | ||
|             figure.StartPoint = new SysPoint(points[0].X, points[0].Y);
 | ||
|             figure.IsClosed = true;
 | ||
| 
 | ||
|             PolyLineSegment segment = new PolyLineSegment();
 | ||
|             int count = points.Length;
 | ||
|             // For correct drawing the start point of the segment must not be the same as the first point.
 | ||
|             for (int idx = 1; idx < count; idx++)
 | ||
|                 segment.Points.Add(new SysPoint(points[idx].X, points[idx].Y));
 | ||
| #if !SILVERLIGHT && !NETFX_CORE
 | ||
|             seg.IsStroked = true;
 | ||
| #endif
 | ||
|             figure.Segments.Add(segment);
 | ||
|             _pathGeometry.Figures.Add(figure);
 | ||
| #endif
 | ||
|             // TODO: NOT NEEDED
 | ||
|             //CloseFigure(); // StartFigure() isn't needed because AddGeometry() implicitly starts a new figure, but CloseFigure() is needed for the next adding not to continue this figure.
 | ||
| #endif
 | ||
|         }
 | ||
| 
 | ||
|         // ----- AddPie -------------------------------------------------------------------------------
 | ||
| 
 | ||
| #if GDI
 | ||
|         /// <summary>
 | ||
|         /// Adds the outline of a pie shape to this path.
 | ||
|         /// </summary>
 | ||
|         public void AddPie(Rectangle rect, double startAngle, double sweepAngle)
 | ||
|         {
 | ||
|             try
 | ||
|             {
 | ||
|                 Lock.EnterGdiPlus();
 | ||
|                 _gdipPath.AddPie(rect, (float)startAngle, (float)sweepAngle);
 | ||
|             }
 | ||
|             finally { Lock.ExitGdiPlus(); }
 | ||
|         }
 | ||
| #endif
 | ||
| 
 | ||
| #if GDI
 | ||
|         /// <summary>
 | ||
|         /// Adds the outline of a pie shape to this path.
 | ||
|         /// </summary>
 | ||
|         public void AddPie(RectangleF rect, double startAngle, double sweepAngle)
 | ||
|         {
 | ||
|             AddPie(rect.X, rect.Y, rect.Width, rect.Height, startAngle, sweepAngle);
 | ||
|         }
 | ||
| #endif
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// Adds the outline of a pie shape to this path.
 | ||
|         /// </summary>
 | ||
|         public void AddPie(XRect rect, double startAngle, double sweepAngle)
 | ||
|         {
 | ||
|             AddPie(rect.X, rect.Y, rect.Width, rect.Height, startAngle, sweepAngle);
 | ||
|         }
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// Adds the outline of a pie shape to this path.
 | ||
|         /// </summary>
 | ||
|         public void AddPie(double x, double y, double width, double height, double startAngle, double sweepAngle)
 | ||
|         {
 | ||
| #if CORE
 | ||
|             DiagnosticsHelper.HandleNotImplemented("XGraphicsPath.AddPie");
 | ||
| #endif
 | ||
| #if GDI
 | ||
|             try
 | ||
|             {
 | ||
|                 Lock.EnterGdiPlus();
 | ||
|                 _gdipPath.AddPie((float)x, (float)y, (float)width, (float)height, (float)startAngle, (float)sweepAngle);
 | ||
|             }
 | ||
|             finally { Lock.ExitGdiPlus(); }
 | ||
| #endif
 | ||
| #if WPF || NETFX_CORE
 | ||
|             DiagnosticsHelper.HandleNotImplemented("XGraphicsPath.AddPie");
 | ||
| #endif
 | ||
|         }
 | ||
| 
 | ||
|         // ----- AddClosedCurve ------------------------------------------------------------------------
 | ||
| 
 | ||
| #if GDI
 | ||
|         /// <summary>
 | ||
|         /// Adds a closed curve to this path.
 | ||
|         /// </summary>
 | ||
|         public void AddClosedCurve(System.Drawing.Point[] points)
 | ||
|         {
 | ||
|             AddClosedCurve(XGraphics.MakeXPointArray(points, 0, points.Length), 0.5);
 | ||
|         }
 | ||
| #endif
 | ||
| 
 | ||
| #if WPF || NETFX_CORE
 | ||
|         /// <summary>
 | ||
|         /// Adds a closed curve to this path.
 | ||
|         /// </summary>
 | ||
|         public void AddClosedCurve(SysPoint[] points)
 | ||
|         {
 | ||
|             AddClosedCurve(XGraphics.MakeXPointArray(points, 0, points.Length), 0.5);
 | ||
|         }
 | ||
| #endif
 | ||
| 
 | ||
| #if GDI
 | ||
|         /// <summary>
 | ||
|         /// Adds a closed curve to this path.
 | ||
|         /// </summary>
 | ||
|         public void AddClosedCurve(PointF[] points)
 | ||
|         {
 | ||
|             AddClosedCurve(XGraphics.MakeXPointArray(points, 0, points.Length), 0.5);
 | ||
|         }
 | ||
| #endif
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// Adds a closed curve to this path.
 | ||
|         /// </summary>
 | ||
|         public void AddClosedCurve(XPoint[] points)
 | ||
|         {
 | ||
|             AddClosedCurve(points, 0.5);
 | ||
|         }
 | ||
| 
 | ||
| #if GDI
 | ||
|         /// <summary>
 | ||
|         /// Adds a closed curve to this path.
 | ||
|         /// </summary>
 | ||
|         public void AddClosedCurve(System.Drawing.Point[] points, double tension)
 | ||
|         {
 | ||
|             AddClosedCurve(XGraphics.MakeXPointArray(points, 0, points.Length), tension);
 | ||
|         }
 | ||
| #endif
 | ||
| 
 | ||
| #if WPF || NETFX_CORE
 | ||
|         /// <summary>
 | ||
|         /// Adds a closed curve to this path.
 | ||
|         /// </summary>
 | ||
|         public void AddClosedCurve(SysPoint[] points, double tension)
 | ||
|         {
 | ||
|             AddClosedCurve(XGraphics.MakeXPointArray(points, 0, points.Length), tension);
 | ||
|         }
 | ||
| #endif
 | ||
| 
 | ||
| #if GDI
 | ||
|         /// <summary>
 | ||
|         /// Adds a closed curve to this path.
 | ||
|         /// </summary>
 | ||
|         public void AddClosedCurve(PointF[] points, double tension)
 | ||
|         {
 | ||
|             AddClosedCurve(XGraphics.MakeXPointArray(points, 0, points.Length), tension);
 | ||
|         }
 | ||
| #endif
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// Adds a closed curve to this path.
 | ||
|         /// </summary>
 | ||
|         public void AddClosedCurve(XPoint[] points, double tension)
 | ||
|         {
 | ||
|             if (points == null)
 | ||
|                 throw new ArgumentNullException("points");
 | ||
|             int count = points.Length;
 | ||
|             if (count == 0)
 | ||
|                 return;
 | ||
|             if (count < 2)
 | ||
|                 throw new ArgumentException("Not enough points.", "points");
 | ||
| 
 | ||
| #if CORE
 | ||
|             DiagnosticsHelper.HandleNotImplemented("XGraphicsPath.AddClosedCurve");
 | ||
| #endif
 | ||
| #if GDI
 | ||
|             try
 | ||
|             {
 | ||
|                 Lock.EnterGdiPlus();
 | ||
|                 _gdipPath.AddClosedCurve(XGraphics.MakePointFArray(points), (float)tension);
 | ||
|             }
 | ||
|             finally { Lock.ExitGdiPlus(); }
 | ||
| #endif
 | ||
| #if WPF ||NETFX_CORE
 | ||
|             tension /= 3;
 | ||
| 
 | ||
|             StartFigure();
 | ||
|             PathFigure figure = CurrentPathFigure;
 | ||
|             figure.StartPoint = new SysPoint(points[0].X, points[0].Y);
 | ||
| 
 | ||
|             if (count == 2)
 | ||
|             {
 | ||
|                 figure.Segments.Add(GeometryHelper.CreateCurveSegment(points[0], points[0], points[1], points[1], tension));
 | ||
|             }
 | ||
|             else
 | ||
|             {
 | ||
|                 figure.Segments.Add(GeometryHelper.CreateCurveSegment(points[count - 1], points[0], points[1], points[2], tension));
 | ||
|                 for (int idx = 1; idx < count - 2; idx++)
 | ||
|                     figure.Segments.Add(GeometryHelper.CreateCurveSegment(points[idx - 1], points[idx], points[idx + 1], points[idx + 2], tension));
 | ||
|                 figure.Segments.Add(GeometryHelper.CreateCurveSegment(points[count - 3], points[count - 2], points[count - 1], points[0], tension));
 | ||
|                 figure.Segments.Add(GeometryHelper.CreateCurveSegment(points[count - 2], points[count - 1], points[0], points[1], tension));
 | ||
|             }
 | ||
| #endif
 | ||
|         }
 | ||
| 
 | ||
|         // ----- AddPath ------------------------------------------------------------------------------
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// Adds the specified path to this path.
 | ||
|         /// </summary>
 | ||
|         public void AddPath(XGraphicsPath path, bool connect)
 | ||
|         {
 | ||
| #if CORE
 | ||
|             DiagnosticsHelper.HandleNotImplemented("XGraphicsPath.AddPath");
 | ||
| #endif
 | ||
| #if GDI
 | ||
|             try
 | ||
|             {
 | ||
|                 Lock.EnterGdiPlus();
 | ||
|                 _gdipPath.AddPath(path._gdipPath, connect);
 | ||
|             }
 | ||
|             finally { Lock.ExitGdiPlus(); }
 | ||
| #endif
 | ||
| #if WPF || NETFX_CORE
 | ||
| #if !SILVERLIGHT && !NETFX_CORE
 | ||
|             _pathGeometry.AddGeometry(path._pathGeometry);
 | ||
| #else
 | ||
|             // AG-HACK: No AddGeometry in Silverlight version of PathGeometry
 | ||
|             throw new InvalidOperationException("Silverlight/WinRT cannot merge geometry objects.");
 | ||
|             // TODO: make it manually by using a GeometryGroup
 | ||
| #endif
 | ||
| #endif
 | ||
|         }
 | ||
| 
 | ||
|         // ----- AddString ----------------------------------------------------------------------------
 | ||
| 
 | ||
| #if GDI
 | ||
|         /// <summary>
 | ||
|         /// Adds a text string to this path.
 | ||
|         /// </summary>
 | ||
|         public void AddString(string s, XFontFamily family, XFontStyle style, double emSize, System.Drawing.Point origin, XStringFormat format)
 | ||
|         {
 | ||
|             AddString(s, family, style, emSize, new XRect(origin.X, origin.Y, 0, 0), format);
 | ||
|         }
 | ||
| #endif
 | ||
| 
 | ||
| #if WPF || NETFX_CORE
 | ||
|         /// <summary>
 | ||
|         /// Adds a text string to this path.
 | ||
|         /// </summary>
 | ||
|         public void AddString(string s, XFontFamily family, XFontStyle style, double emSize, SysPoint origin, XStringFormat format)
 | ||
|         {
 | ||
|             AddString(s, family, style, emSize, new XPoint(origin), format);
 | ||
|         }
 | ||
| #endif
 | ||
| 
 | ||
| #if GDI
 | ||
|         /// <summary>
 | ||
|         /// Adds a text string to this path.
 | ||
|         /// </summary>
 | ||
|         public void AddString(string s, XFontFamily family, XFontStyle style, double emSize, PointF origin, XStringFormat format)
 | ||
|         {
 | ||
|             AddString(s, family, style, emSize, new XRect(origin.X, origin.Y, 0, 0), format);
 | ||
|         }
 | ||
| #endif
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// Adds a text string to this path.
 | ||
|         /// </summary>
 | ||
|         public void AddString(string s, XFontFamily family, XFontStyle style, double emSize, XPoint origin,
 | ||
|             XStringFormat format)
 | ||
|         {
 | ||
|             try
 | ||
|             {
 | ||
| #if CORE
 | ||
|                 DiagnosticsHelper.HandleNotImplemented("XGraphicsPath.AddString");
 | ||
| #endif
 | ||
| #if GDI
 | ||
|                 if (family.GdiFamily == null)
 | ||
|                     throw new NotFiniteNumberException(PSSR.NotImplementedForFontsRetrievedWithFontResolver(family.Name));
 | ||
| 
 | ||
|                 PointF p = origin.ToPointF();
 | ||
|                 p.Y += SimulateBaselineOffset(family, style, emSize, format);
 | ||
| 
 | ||
|                 try
 | ||
|                 {
 | ||
|                     Lock.EnterGdiPlus();
 | ||
|                     _gdipPath.AddString(s, family.GdiFamily, (int)style, (float)emSize, p, format.RealizeGdiStringFormat());
 | ||
|                 }
 | ||
|                 finally { Lock.ExitGdiPlus(); }
 | ||
| #endif
 | ||
| #if WPF
 | ||
|                 if (family.WpfFamily == null)
 | ||
|                     throw new NotFiniteNumberException(PSSR.NotImplementedForFontsRetrievedWithFontResolver(family.Name));
 | ||
| #if !SILVERLIGHT
 | ||
|                 XFont font = new XFont(family.Name, emSize, style);
 | ||
| 
 | ||
|                 double x = origin.X;
 | ||
|                 double y = origin.Y;
 | ||
| 
 | ||
|                 double lineSpace = font.GetHeight();
 | ||
|                 double cyAscent = lineSpace * font.CellAscent / font.CellSpace;
 | ||
|                 double cyDescent = lineSpace * font.CellDescent / font.CellSpace;
 | ||
| 
 | ||
|                 Typeface typeface = FontHelper.CreateTypeface(family.WpfFamily, style);
 | ||
|                 FormattedText formattedText = FontHelper.CreateFormattedText(s, typeface, emSize, WpfBrushes.Black);
 | ||
| 
 | ||
|                 switch (format.Alignment)
 | ||
|                 {
 | ||
|                     case XStringAlignment.Near:
 | ||
|                         // nothing to do, this is the default
 | ||
|                         //formattedText.TextAlignment = TextAlignment.Left;
 | ||
|                         break;
 | ||
| 
 | ||
|                     case XStringAlignment.Center:
 | ||
|                         formattedText.TextAlignment = TextAlignment.Center;
 | ||
|                         break;
 | ||
| 
 | ||
|                     case XStringAlignment.Far:
 | ||
|                         formattedText.TextAlignment = TextAlignment.Right;
 | ||
|                         break;
 | ||
|                 }
 | ||
|                 switch (format.LineAlignment)
 | ||
|                 {
 | ||
|                     case XLineAlignment.Near:
 | ||
|                         //y += cyAscent;
 | ||
|                         break;
 | ||
| 
 | ||
|                     case XLineAlignment.Center:
 | ||
|                         // TODO use CapHeight. PDFlib also uses 3/4 of ascent
 | ||
|                         y += -lineSpace / 2; //-formattedText.Baseline + (cyAscent * 2 / 4);
 | ||
|                         break;
 | ||
| 
 | ||
|                     case XLineAlignment.Far:
 | ||
|                         y += -formattedText.Baseline - cyDescent;
 | ||
|                         break;
 | ||
| 
 | ||
|                     case XLineAlignment.BaseLine:
 | ||
|                         y -= formattedText.Baseline;
 | ||
|                         break;
 | ||
|                 }
 | ||
| 
 | ||
|                 Geometry geo = formattedText.BuildGeometry(new XPoint(x, y));
 | ||
|                 _pathGeometry.AddGeometry(geo);
 | ||
| #else
 | ||
|                 // AG-HACK
 | ||
|                 throw new InvalidOperationException("Silverlight cannot create geometry of glyphs.");
 | ||
|                 // TODO: Get the outline directly from the font.
 | ||
| #endif
 | ||
| #endif
 | ||
|             }
 | ||
|             catch
 | ||
|             {
 | ||
|                 throw;
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
| #if GDI
 | ||
|         /// <summary>
 | ||
|         /// Adds a text string to this path.
 | ||
|         /// </summary>
 | ||
|         public void AddString(string s, XFontFamily family, XFontStyle style, double emSize, Rectangle layoutRect, XStringFormat format)
 | ||
|         {
 | ||
|             if (family.GdiFamily == null)
 | ||
|                 throw new NotFiniteNumberException(PSSR.NotImplementedForFontsRetrievedWithFontResolver(family.Name));
 | ||
| 
 | ||
|             Rectangle rect = new Rectangle(layoutRect.X, layoutRect.Y, layoutRect.Width, layoutRect.Height);
 | ||
|             rect.Offset(new System.Drawing.Point(0, (int)SimulateBaselineOffset(family, style, emSize, format)));
 | ||
| 
 | ||
|             try
 | ||
|             {
 | ||
|                 Lock.EnterGdiPlus();
 | ||
|                 _gdipPath.AddString(s, family.GdiFamily, (int)style, (float)emSize, rect, format.RealizeGdiStringFormat());
 | ||
|             }
 | ||
|             finally { Lock.ExitGdiPlus(); }
 | ||
|         }
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// Adds a text string to this path.
 | ||
|         /// </summary>
 | ||
|         public void AddString(string s, XFontFamily family, XFontStyle style, double emSize, RectangleF layoutRect, XStringFormat format)
 | ||
|         {
 | ||
|             if (family.GdiFamily == null)
 | ||
|                 throw new NotFiniteNumberException(PSSR.NotImplementedForFontsRetrievedWithFontResolver(family.Name));
 | ||
| 
 | ||
|             RectangleF rect = new RectangleF(layoutRect.X, layoutRect.Y, layoutRect.Width, layoutRect.Height);
 | ||
|             rect.Offset(new PointF(0, SimulateBaselineOffset(family, style, emSize, format)));
 | ||
| 
 | ||
|             try
 | ||
|             {
 | ||
|                 Lock.EnterGdiPlus();
 | ||
|                 _gdipPath.AddString(s, family.GdiFamily, (int)style, (float)emSize, layoutRect, format.RealizeGdiStringFormat());
 | ||
|             }
 | ||
|             finally { Lock.ExitGdiPlus(); }
 | ||
|         }
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// Calculates the offset for BaseLine positioning simulation:
 | ||
|         /// In GDI we have only Near, Center and Far as LineAlignment and no BaseLine. For XLineAlignment.BaseLine StringAlignment.Near is returned.
 | ||
|         /// We now return the negative drawed ascender height.
 | ||
|         /// This has to be added to the LayoutRect/Origin before each _gdipPath.AddString().
 | ||
|         /// </summary>
 | ||
|         /// <param name="family"></param>
 | ||
|         /// <param name="style"></param>
 | ||
|         /// <param name="emSize"></param>
 | ||
|         /// <param name="format"></param>
 | ||
|         /// <returns></returns>
 | ||
|         private float SimulateBaselineOffset(XFontFamily family, XFontStyle style, double emSize, XStringFormat format)
 | ||
|         {
 | ||
|             XFont font = new XFont(family.Name, emSize, style);
 | ||
| 
 | ||
|             if (format.LineAlignment == XLineAlignment.BaseLine)
 | ||
|             {
 | ||
|                 double lineSpace = font.GetHeight();
 | ||
|                 int cellSpace = font.FontFamily.GetLineSpacing(font.Style);
 | ||
|                 int cellAscent = font.FontFamily.GetCellAscent(font.Style);
 | ||
|                 int cellDescent = font.FontFamily.GetCellDescent(font.Style);
 | ||
|                 double cyAscent = lineSpace * cellAscent / cellSpace;
 | ||
|                 cyAscent = lineSpace * font.CellAscent / font.CellSpace;
 | ||
|                 return (float)-cyAscent;
 | ||
|             }
 | ||
|             return 0;
 | ||
|         }
 | ||
| 
 | ||
| #endif
 | ||
| 
 | ||
| #if WPF
 | ||
|         /// <summary>
 | ||
|         /// Adds a text string to this path.
 | ||
|         /// </summary>
 | ||
|         public void AddString(string s, XFontFamily family, XFontStyle style, double emSize, Rect rect, XStringFormat format)
 | ||
|         {
 | ||
|             //gdip Path.AddString(s, family.gdiFamily, (int)style, (float)emSize, layoutRect, format.RealizeGdiStringFormat());
 | ||
|             AddString(s, family, style, emSize, new XRect(rect), format);
 | ||
|         }
 | ||
| #endif
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// Adds a text string to this path.
 | ||
|         /// </summary>
 | ||
|         public void AddString(string s, XFontFamily family, XFontStyle style, double emSize, XRect layoutRect,
 | ||
|             XStringFormat format)
 | ||
|         {
 | ||
|             if (s == null)
 | ||
|                 throw new ArgumentNullException("s");
 | ||
| 
 | ||
|             if (family == null)
 | ||
|                 throw new ArgumentNullException("family");
 | ||
| 
 | ||
|             if (format == null)
 | ||
|                 format = XStringFormats.Default;
 | ||
| 
 | ||
|             if (format.LineAlignment == XLineAlignment.BaseLine && layoutRect.Height != 0)
 | ||
|                 throw new InvalidOperationException(
 | ||
|                     "DrawString: With XLineAlignment.BaseLine the height of the layout rectangle must be 0.");
 | ||
| 
 | ||
|             if (s.Length == 0)
 | ||
|                 return;
 | ||
| 
 | ||
|             XFont font = new XFont(family.Name, emSize, style);
 | ||
| #if CORE
 | ||
|             DiagnosticsHelper.HandleNotImplemented("XGraphicsPath.AddString");
 | ||
| #endif
 | ||
| #if (GDI || CORE_) && !WPF
 | ||
|             //Gfx.DrawString(text, font.Realize_GdiFont(), brush.RealizeGdiBrush(), rect,
 | ||
|             //  format != null ? format.RealizeGdiStringFormat() : null);
 | ||
| 
 | ||
|             if (family.GdiFamily == null)
 | ||
|                 throw new NotFiniteNumberException(PSSR.NotImplementedForFontsRetrievedWithFontResolver(family.Name));
 | ||
| 
 | ||
|             RectangleF rect = layoutRect.ToRectangleF();
 | ||
|             rect.Offset(new PointF(0, SimulateBaselineOffset(family, style, emSize, format)));
 | ||
| 
 | ||
|             try
 | ||
|             {
 | ||
|                 Lock.EnterGdiPlus();
 | ||
|                 _gdipPath.AddString(s, family.GdiFamily, (int)style, (float)emSize, rect, format.RealizeGdiStringFormat());
 | ||
|             }
 | ||
|             finally { Lock.ExitGdiPlus(); }
 | ||
| #endif
 | ||
| #if WPF && !GDI
 | ||
|             if (family.WpfFamily == null)
 | ||
|                 throw new NotFiniteNumberException(PSSR.NotImplementedForFontsRetrievedWithFontResolver(family.Name));
 | ||
| #if !SILVERLIGHT
 | ||
|             // Just a first sketch, but currently we do not need it and there is enough to do...
 | ||
|             double x = layoutRect.X;
 | ||
|             double y = layoutRect.Y;
 | ||
| 
 | ||
|             //double lineSpace = font.GetHeight(this);
 | ||
|             //double cyAscent = lineSpace * font.cellAscent / font.cellSpace;
 | ||
|             //double cyDescent = lineSpace * font.cellDescent / font.cellSpace;
 | ||
| 
 | ||
|             //double cyAscent = family.GetCellAscent(style) * family.GetLineSpacing(style) / family.getl; //fontlineSpace * font.cellAscent / font.cellSpace;
 | ||
|             //double cyDescent =family.GetCellDescent(style); // lineSpace * font.cellDescent / font.cellSpace;
 | ||
|             double lineSpace = font.GetHeight();
 | ||
|             double cyAscent = lineSpace * font.CellAscent / font.CellSpace;
 | ||
|             double cyDescent = lineSpace * font.CellDescent / font.CellSpace;
 | ||
| 
 | ||
|             bool bold = (style & XFontStyle.Bold) != 0;
 | ||
|             bool italic = (style & XFontStyle.Italic) != 0;
 | ||
|             bool strikeout = (style & XFontStyle.Strikeout) != 0;
 | ||
|             bool underline = (style & XFontStyle.Underline) != 0;
 | ||
| 
 | ||
|             Typeface typeface = FontHelper.CreateTypeface(family.WpfFamily, style);
 | ||
|             //FormattedText formattedText = new FormattedText(s, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, typeface, emSize, WpfBrushes.Black);
 | ||
|             FormattedText formattedText = FontHelper.CreateFormattedText(s, typeface, emSize, WpfBrushes.Black);
 | ||
| 
 | ||
|             switch (format.Alignment)
 | ||
|             {
 | ||
|                 case XStringAlignment.Near:
 | ||
|                     // nothing to do, this is the default
 | ||
|                     //formattedText.TextAlignment = TextAlignment.Left;
 | ||
|                     break;
 | ||
| 
 | ||
|                 case XStringAlignment.Center:
 | ||
|                     x += layoutRect.Width / 2;
 | ||
|                     formattedText.TextAlignment = TextAlignment.Center;
 | ||
|                     break;
 | ||
| 
 | ||
|                 case XStringAlignment.Far:
 | ||
|                     x += layoutRect.Width;
 | ||
|                     formattedText.TextAlignment = TextAlignment.Right;
 | ||
|                     break;
 | ||
|             }
 | ||
|             //if (PageDirection == XPageDirection.Downwards)
 | ||
|             //{
 | ||
|             switch (format.LineAlignment)
 | ||
|             {
 | ||
|                 case XLineAlignment.Near:
 | ||
|                     //y += cyAscent;
 | ||
|                     break;
 | ||
| 
 | ||
|                 case XLineAlignment.Center:
 | ||
|                     // TO/DO use CapHeight. PDFlib also uses 3/4 of ascent
 | ||
|                     //y += -formattedText.Baseline + (cyAscent * 2 / 4) + layoutRect.Height / 2;
 | ||
| 
 | ||
|                     // GDI seems to make it this simple:
 | ||
|                     // TODO: Check WPF's vertical alignment and make all implementations fit. $MaOs
 | ||
|                     y += layoutRect.Height / 2 - lineSpace / 2;
 | ||
|                     break;
 | ||
| 
 | ||
|                 case XLineAlignment.Far:
 | ||
|                     y += -formattedText.Baseline - cyDescent + layoutRect.Height;
 | ||
|                     break;
 | ||
| 
 | ||
|                 case XLineAlignment.BaseLine:
 | ||
|                     y -= formattedText.Baseline;
 | ||
|                     break;
 | ||
|             }
 | ||
|             //}
 | ||
|             //else
 | ||
|             //{
 | ||
|             //  // TODOWPF
 | ||
|             //  switch (format.LineAlignment)
 | ||
|             //  {
 | ||
|             //    case XLineAlignment.Near:
 | ||
|             //      //y += cyDescent;
 | ||
|             //      break;
 | ||
| 
 | ||
|             //    case XLineAlignment.Center:
 | ||
|             //      // TODO use CapHeight. PDFlib also uses 3/4 of ascent
 | ||
|             //      //y += -(cyAscent * 3 / 4) / 2 + rect.Height / 2;
 | ||
|             //      break;
 | ||
| 
 | ||
|             //    case XLineAlignment.Far:
 | ||
|             //      //y += -cyAscent + rect.Height;
 | ||
|             //      break;
 | ||
| 
 | ||
|             //    case XLineAlignment.BaseLine:
 | ||
|             //      // nothing to do
 | ||
|             //      break;
 | ||
|             //  }
 | ||
|             //}
 | ||
| 
 | ||
|             //if (bold && !descriptor.IsBoldFace)
 | ||
|             //{
 | ||
|             //  // TODO: emulate bold by thicker outline
 | ||
|             //}
 | ||
| 
 | ||
|             //if (italic && !descriptor.IsItalicFace)
 | ||
|             //{
 | ||
|             //  // TODO: emulate italic by shearing transformation
 | ||
|             //}
 | ||
| 
 | ||
|             if (underline)
 | ||
|             {
 | ||
|                 //double underlinePosition = lineSpace * realizedFont.FontDescriptor.descriptor.UnderlinePosition / font.cellSpace;
 | ||
|                 //double underlineThickness = lineSpace * realizedFont.FontDescriptor.descriptor.UnderlineThickness / font.cellSpace;
 | ||
|                 //DrawRectangle(null, brush, x, y - underlinePosition, width, underlineThickness);
 | ||
|             }
 | ||
| 
 | ||
|             if (strikeout)
 | ||
|             {
 | ||
|                 //double strikeoutPosition = lineSpace * realizedFont.FontDescriptor.descriptor.StrikeoutPosition / font.cellSpace;
 | ||
|                 //double strikeoutSize = lineSpace * realizedFont.FontDescriptor.descriptor.StrikeoutSize / font.cellSpace;
 | ||
|                 //DrawRectangle(null, brush, x, y - strikeoutPosition - strikeoutSize, width, strikeoutSize);
 | ||
|             }
 | ||
| 
 | ||
|             //dc.DrawText(formattedText, layoutRectangle.Location.ToPoint());
 | ||
|             //dc.DrawText(formattedText, new SysPoint(x, y));
 | ||
| 
 | ||
|             Geometry geo = formattedText.BuildGeometry(new Point(x, y));
 | ||
|             _pathGeometry.AddGeometry(geo);
 | ||
| #else
 | ||
|             // AG-HACK
 | ||
|             throw new InvalidOperationException("Silverlight cannot create geometry of glyphs.");
 | ||
|             // TODO: no, yagni
 | ||
| #endif
 | ||
| #endif
 | ||
|         }
 | ||
| 
 | ||
|         // --------------------------------------------------------------------------------------------
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// Closes the current figure and starts a new figure.
 | ||
|         /// </summary>
 | ||
|         public void CloseFigure()
 | ||
|         {
 | ||
| #if CORE
 | ||
|             _corePath.CloseSubpath();
 | ||
| #endif
 | ||
| #if GDI
 | ||
|             try
 | ||
|             {
 | ||
|                 Lock.EnterGdiPlus();
 | ||
|                 _gdipPath.CloseFigure();
 | ||
|             }
 | ||
|             finally { Lock.ExitGdiPlus(); }
 | ||
| #endif
 | ||
| #if WPF || NETFX_CORE
 | ||
|             PathFigure figure = PeekCurrentFigure;
 | ||
|             if (figure != null && figure.Segments.Count != 0)
 | ||
|                 figure.IsClosed = true;
 | ||
| #endif
 | ||
|         }
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// Starts a new figure without closing the current figure.
 | ||
|         /// </summary>
 | ||
|         public void StartFigure()
 | ||
|         {
 | ||
| #if CORE
 | ||
|             // TODO: ???
 | ||
| #endif
 | ||
| #if GDI
 | ||
|             try
 | ||
|             {
 | ||
|                 Lock.EnterGdiPlus();
 | ||
|                 _gdipPath.StartFigure();
 | ||
|             }
 | ||
|             finally { Lock.ExitGdiPlus(); }
 | ||
| #endif
 | ||
| #if WPF || NETFX_CORE
 | ||
|             PathFigure figure = CurrentPathFigure;
 | ||
|             if (figure.Segments.Count != 0)
 | ||
|             {
 | ||
|                 figure = new PathFigure();
 | ||
|                 _pathGeometry.Figures.Add(figure);
 | ||
|             }
 | ||
| #endif
 | ||
|         }
 | ||
| 
 | ||
|         // --------------------------------------------------------------------------------------------
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// Gets or sets an XFillMode that determines how the interiors of shapes are filled.
 | ||
|         /// </summary>
 | ||
|         public XFillMode FillMode
 | ||
|         {
 | ||
|             get { return _fillMode; }
 | ||
|             set
 | ||
|             {
 | ||
|                 _fillMode = value;
 | ||
| #if CORE
 | ||
|                 // Nothing to do.
 | ||
| #endif
 | ||
| #if GDI
 | ||
|                 try
 | ||
|                 {
 | ||
|                     Lock.EnterGdiPlus();
 | ||
|                     _gdipPath.FillMode = (FillMode)value;
 | ||
|                 }
 | ||
|                 finally { Lock.ExitGdiPlus(); }
 | ||
| #endif
 | ||
| #if WPF || NETFX_CORE
 | ||
|                 _pathGeometry.FillRule = value == XFillMode.Winding ? FillRule.Nonzero : FillRule.EvenOdd;
 | ||
| #endif
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         private XFillMode _fillMode;
 | ||
| 
 | ||
|         // --------------------------------------------------------------------------------------------
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// Converts each curve in this XGraphicsPath into a sequence of connected line segments. 
 | ||
|         /// </summary>
 | ||
|         public void Flatten()
 | ||
|         {
 | ||
| #if CORE
 | ||
|             // Just do nothing.
 | ||
| #endif
 | ||
| #if GDI
 | ||
|             try
 | ||
|             {
 | ||
|                 Lock.EnterGdiPlus();
 | ||
|                 _gdipPath.Flatten();
 | ||
|             }
 | ||
|             finally { Lock.ExitGdiPlus(); }
 | ||
| #endif
 | ||
| #if WPF || NETFX_CORE
 | ||
| #if !SILVERLIGHT && !NETFX_CORE
 | ||
|             _pathGeometry = _pathGeometry.GetFlattenedPathGeometry();
 | ||
| #else
 | ||
|             // AGHACK
 | ||
|             throw new InvalidOperationException("Silverlight/WinrRT cannot flatten a geometry.");
 | ||
|             // TODO: no, yagni
 | ||
| #endif
 | ||
| #endif
 | ||
|         }
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// Converts each curve in this XGraphicsPath into a sequence of connected line segments. 
 | ||
|         /// </summary>
 | ||
|         public void Flatten(XMatrix matrix)
 | ||
|         {
 | ||
| #if CORE
 | ||
|             // Just do nothing.
 | ||
| #endif
 | ||
| #if GDI
 | ||
|             try
 | ||
|             {
 | ||
|                 Lock.EnterGdiPlus();
 | ||
|                 _gdipPath.Flatten(matrix.ToGdiMatrix());
 | ||
|             }
 | ||
|             finally { Lock.ExitGdiPlus(); }
 | ||
| #endif
 | ||
| #if WPF || NETFX_CORE
 | ||
| #if !SILVERLIGHT && !NETFX_CORE
 | ||
|             _pathGeometry = _pathGeometry.GetFlattenedPathGeometry();
 | ||
|             _pathGeometry.Transform = new MatrixTransform(matrix.ToWpfMatrix());
 | ||
| #else
 | ||
|             // AGHACK
 | ||
|             throw new InvalidOperationException("Silverlight/WinRT cannot flatten a geometry.");
 | ||
|             // TODO: no, yagni
 | ||
| #endif
 | ||
| #endif
 | ||
|         }
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// Converts each curve in this XGraphicsPath into a sequence of connected line segments. 
 | ||
|         /// </summary>
 | ||
|         public void Flatten(XMatrix matrix, double flatness)
 | ||
|         {
 | ||
| #if CORE
 | ||
|             // Just do nothing.
 | ||
| #endif
 | ||
| #if CORE___
 | ||
|             throw new NotImplementedException("XGraphicsPath.Flatten");
 | ||
| #endif
 | ||
| #if GDI
 | ||
|             try
 | ||
|             {
 | ||
|                 Lock.EnterGdiPlus();
 | ||
|                 _gdipPath.Flatten(matrix.ToGdiMatrix(), (float)flatness);
 | ||
|             }
 | ||
|             finally { Lock.ExitGdiPlus(); }
 | ||
| #endif
 | ||
| #if WPF || NETFX_CORE
 | ||
| #if !SILVERLIGHT && !NETFX_CORE
 | ||
|             _pathGeometry = _pathGeometry.GetFlattenedPathGeometry();
 | ||
|             // TODO: matrix handling not yet tested
 | ||
|             if (!matrix.IsIdentity)
 | ||
|                 _pathGeometry.Transform = new MatrixTransform(matrix.ToWpfMatrix());
 | ||
| #else
 | ||
|             // AG-HACK
 | ||
|             throw new InvalidOperationException("Silverlight/WinRT cannot flatten a geometry.");
 | ||
|             // TODO: no, yagni
 | ||
| #endif
 | ||
| #endif
 | ||
|         }
 | ||
| 
 | ||
|         // --------------------------------------------------------------------------------------------
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// Replaces this path with curves that enclose the area that is filled when this path is drawn 
 | ||
|         /// by the specified pen.
 | ||
|         /// </summary>
 | ||
|         public void Widen(XPen pen)
 | ||
|         {
 | ||
| #if CORE
 | ||
|             // Just do nothing.
 | ||
| #endif
 | ||
| #if CORE___
 | ||
|             throw new NotImplementedException("XGraphicsPath.Widen");
 | ||
| #endif
 | ||
| #if GDI
 | ||
|             try
 | ||
|             {
 | ||
|                 Lock.EnterGdiPlus();
 | ||
|                 _gdipPath.Widen(pen.RealizeGdiPen());
 | ||
|             }
 | ||
|             finally { Lock.ExitGdiPlus(); }
 | ||
| #endif
 | ||
| #if WPF || NETFX_CORE
 | ||
| #if !SILVERLIGHT && !NETFX_CORE
 | ||
|             _pathGeometry = _pathGeometry.GetWidenedPathGeometry(pen.RealizeWpfPen());
 | ||
| #else
 | ||
|             // AG-HACK
 | ||
|             throw new InvalidOperationException("Silverlight/WinRT cannot widen a geometry.");
 | ||
|             // TODO: no, yagni
 | ||
| #endif
 | ||
| #endif
 | ||
|         }
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// Replaces this path with curves that enclose the area that is filled when this path is drawn 
 | ||
|         /// by the specified pen.
 | ||
|         /// </summary>
 | ||
|         public void Widen(XPen pen, XMatrix matrix)
 | ||
|         {
 | ||
| #if CORE
 | ||
|             // Just do nothing.
 | ||
| #endif
 | ||
| #if CORE
 | ||
|             throw new NotImplementedException("XGraphicsPath.Widen");
 | ||
| #endif
 | ||
| #if GDI
 | ||
|             try
 | ||
|             {
 | ||
|                 Lock.EnterGdiPlus();
 | ||
|                 _gdipPath.Widen(pen.RealizeGdiPen(), matrix.ToGdiMatrix());
 | ||
|             }
 | ||
|             finally { Lock.ExitGdiPlus(); }
 | ||
| #endif
 | ||
| #if WPF || NETFX_CORE
 | ||
| #if !SILVERLIGHT && !NETFX_CORE
 | ||
|             _pathGeometry = _pathGeometry.GetWidenedPathGeometry(pen.RealizeWpfPen());
 | ||
| #else
 | ||
|             // AG-HACK
 | ||
|             throw new InvalidOperationException("Silverlight/WinRT cannot widen a geometry.");
 | ||
|             // TODO: no, yagni
 | ||
| #endif
 | ||
| #endif
 | ||
|         }
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// Replaces this path with curves that enclose the area that is filled when this path is drawn 
 | ||
|         /// by the specified pen.
 | ||
|         /// </summary>
 | ||
|         public void Widen(XPen pen, XMatrix matrix, double flatness)
 | ||
|         {
 | ||
| #if CORE
 | ||
|             // Just do nothing.
 | ||
| #endif
 | ||
| #if CORE__
 | ||
|             throw new NotImplementedException("XGraphicsPath.Widen");
 | ||
| #endif
 | ||
| #if GDI
 | ||
|             try
 | ||
|             {
 | ||
|                 Lock.EnterGdiPlus();
 | ||
|                 _gdipPath.Widen(pen.RealizeGdiPen(), matrix.ToGdiMatrix(), (float)flatness);
 | ||
|             }
 | ||
|             finally { Lock.ExitGdiPlus(); }
 | ||
| #endif
 | ||
| #if WPF || NETFX_CORE
 | ||
| #if !SILVERLIGHT && !NETFX_CORE
 | ||
|             _pathGeometry = _pathGeometry.GetWidenedPathGeometry(pen.RealizeWpfPen());
 | ||
| #else
 | ||
|             // AG-HACK
 | ||
|             throw new InvalidOperationException("Silverlight/WinRT cannot widen a geometry.");
 | ||
|             // TODO: no, yagni
 | ||
| #endif
 | ||
| #endif
 | ||
|         }
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// Grants access to internal objects of this class.
 | ||
|         /// </summary>
 | ||
|         public XGraphicsPathInternals Internals
 | ||
|         {
 | ||
|             get { return new XGraphicsPathInternals(this); }
 | ||
|         }
 | ||
| 
 | ||
| #if CORE
 | ||
|         /// <summary>
 | ||
|         /// Gets access to underlying Core graphics path.
 | ||
|         /// </summary>
 | ||
|         internal CoreGraphicsPath _corePath;
 | ||
| #endif
 | ||
| 
 | ||
| #if GDI
 | ||
|         /// <summary>
 | ||
|         /// Gets access to underlying GDI+ graphics path.
 | ||
|         /// </summary>
 | ||
|         internal GraphicsPath _gdipPath;
 | ||
| #endif
 | ||
| 
 | ||
| #if WPF || NETFX_CORE
 | ||
|         /// <summary>
 | ||
|         /// Gets access to underlying WPF/WinRT path geometry.
 | ||
|         /// </summary>
 | ||
|         internal PathGeometry _pathGeometry;
 | ||
| #endif
 | ||
|     }
 | ||
| } |