1
#region PDFsharp - A .NET library for processing PDF
4
// Stefan Lange (mailto:Stefan.Lange@pdfsharp.com)
6
// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
8
// http://www.pdfsharp.com
9
// http://sourceforge.net/projects/pdfsharp
11
// Permission is hereby granted, free of charge, to any person obtaining a
12
// copy of this software and associated documentation files (the "Software"),
13
// to deal in the Software without restriction, including without limitation
14
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
15
// and/or sell copies of the Software, and to permit persons to whom the
16
// Software is furnished to do so, subject to the following conditions:
18
// The above copyright notice and this permission notice shall be included
19
// in all copies or substantial portions of the Software.
21
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27
// DEALINGS IN THE SOFTWARE.
31
using System.Diagnostics;
32
using System.Collections;
33
using System.Globalization;
38
using System.Drawing.Drawing2D;
42
using System.Windows.Media;
44
using PdfSharp.Internal;
46
namespace PdfSharp.Drawing
49
/// Represents a series of connected lines and curves.
51
public sealed class XGraphicsPath
54
/// Initializes a new instance of the <see cref="XGraphicsPath"/> class.
56
public XGraphicsPath()
59
this.gdipPath = new GraphicsPath();
62
this.pathGeometry = new PathGeometry();
68
/// Initializes a new instance of the <see cref="XGraphicsPath"/> class.
70
public XGraphicsPath(PointF[] points, byte[] types, XFillMode fillMode)
73
this.gdipPath = new GraphicsPath(points, types, (FillMode)fillMode);
76
this.pathGeometry = new PathGeometry();
77
this.pathGeometry.FillRule = FillRule.EvenOdd;
84
/// Gets access to underlying GDI+ path.
86
internal GraphicsPath gdipPath;
91
/// Gets access to underlying WPF path geometry.
93
internal PathGeometry pathGeometry;
96
///// The current path figure;
101
/// Gets the current path figure.
103
PathFigure CurrentPathFigure
107
int count = this.pathGeometry.Figures.Count;
110
this.pathGeometry.Figures.Add(new PathFigure());
113
else if (this.startNewFigure && this.pathGeometry.Figures[count - 1].Segments.Count == 0)
115
this.pathGeometry.Figures.Add(new PathFigure());
118
return this.pathGeometry.Figures[count - 1];
120
//if (this.figure == null)
122
// this.figure = new PathFigure();
123
// this.pathGeometry.Figures.Add(this.figure);
125
//return this.figure;
132
/// Clones this instance.
134
public XGraphicsPath Clone()
136
XGraphicsPath path = (XGraphicsPath)MemberwiseClone();
138
path.gdipPath = this.gdipPath.Clone() as GraphicsPath;
141
path.pathGeometry = this.pathGeometry.Clone();
147
///// For internal use only.
149
//internal XGraphicsPathItem[] GetPathData()
151
// int count = this.items.Count;
152
// XGraphicsPathItem[] data = new XGraphicsPathItem[count];
153
// for (int idx = 0; idx < count; idx++)
154
// data[idx] = ((XGraphicsPathItem)this.items[idx]).Clone() as XGraphicsPathItem;
158
// ----- AddLine ------------------------------------------------------------------------------
162
/// Adds a line segment to current figure.
164
public void AddLine(System.Drawing.Point pt1, System.Drawing.Point pt2)
166
AddLine((double)pt1.X, (double)pt1.Y, (double)pt2.X, (double)pt2.Y);
172
/// Adds a line segment to current figure.
174
public void AddLine(System.Windows.Point pt1, System.Windows.Point pt2)
176
AddLine(pt1.X, pt1.Y, pt2.X, pt2.Y);
182
/// Adds a line segment to current figure.
184
public void AddLine(PointF pt1, PointF pt2)
186
AddLine((double)pt1.X, (double)pt1.Y, (double)pt2.X, (double)pt2.Y);
191
/// Adds a line segment to current figure.
193
public void AddLine(XPoint pt1, XPoint pt2)
195
AddLine(pt1.X, pt1.Y, pt2.X, pt2.Y);
199
/// Adds a line segment to current figure.
201
public void AddLine(int x1, int y1, int x2, int y2)
203
AddLine((double)x1, (double)y1, (double)x2, (double)y2);
207
/// Adds a line segment to current figure.
209
public void AddLine(double x1, double y1, double x2, double y2)
212
this.gdipPath.AddLine((float)x1, (float)y1, (float)x2, (float)y2);
215
PathFigure figure = CurrentPathFigure;
216
if (figure.Segments.Count == 0)
218
figure.StartPoint = new System.Windows.Point(x1, y1);
219
figure.Segments.Add(new LineSegment(new System.Windows.Point(x2, y2), true));
223
figure.Segments.Add(new LineSegment(new System.Windows.Point(x1, y1), true));
224
figure.Segments.Add(new LineSegment(new System.Windows.Point(x2, y2), true));
229
// ----- AddLines -----------------------------------------------------------------------------
233
/// Adds a series of connected line segments to current figure.
235
public void AddLines(System.Drawing.Point[] points)
237
AddLines(XGraphics.MakeXPointArray(points));
243
/// Adds a series of connected line segments to current figure.
245
public void AddLines(System.Windows.Point[] points)
247
AddLines(XGraphics.MakeXPointArray(points));
253
/// Adds a series of connected line segments to current figure.
255
public void AddLines(PointF[] points)
257
AddLines(XGraphics.MakeXPointArray(points));
262
/// Adds a series of connected line segments to current figure.
264
public void AddLines(XPoint[] points)
267
throw new ArgumentNullException("points");
269
int count = points.Length;
274
this.gdipPath.AddLines(XGraphics.MakePointFArray(points));
277
PathFigure figure = CurrentPathFigure;
278
if (figure.Segments.Count == 0)
280
figure.StartPoint = new System.Windows.Point(points[0].x, points[0].y);
281
for (int idx = 1; idx < count; idx++)
282
figure.Segments.Add(new LineSegment(new System.Windows.Point(points[idx].x, points[idx].y), true));
286
for (int idx = 0; idx < count; idx++)
287
figure.Segments.Add(new LineSegment(new System.Windows.Point(points[idx].x, points[idx].y), true));
292
// ----- AddBezier ----------------------------------------------------------------------------
296
/// Adds a cubic Bļæ½zier curve to the current figure.
298
public void AddBezier(System.Drawing.Point pt1, System.Drawing.Point pt2, System.Drawing.Point pt3, System.Drawing.Point pt4)
300
AddBezier((double)pt1.X, (double)pt1.Y, (double)pt2.X, (double)pt2.Y, (double)pt3.X, (double)pt3.Y, (double)pt4.X, (double)pt4.Y);
306
/// Adds a cubic Bļæ½zier curve to the current figure.
308
public void AddBezier(System.Windows.Point pt1, System.Windows.Point pt2, System.Windows.Point pt3, System.Windows.Point pt4)
310
AddBezier(pt1.X, pt1.Y, pt2.X, pt2.Y, pt3.X, pt3.Y, pt4.X, pt4.Y);
316
/// Adds a cubic Bļæ½zier curve to the current figure.
318
public void AddBezier(PointF pt1, PointF pt2, PointF pt3, PointF pt4)
320
AddBezier((double)pt1.X, (double)pt1.Y, (double)pt2.X, (double)pt2.Y, (double)pt3.X, (double)pt3.Y, (double)pt4.X, (double)pt4.Y);
325
/// Adds a cubic Bļæ½zier curve to the current figure.
327
public void AddBezier(XPoint pt1, XPoint pt2, XPoint pt3, XPoint pt4)
329
AddBezier(pt1.X, pt1.Y, pt2.X, pt2.Y, pt3.X, pt3.Y, pt4.X, pt4.Y);
333
/// Adds a cubic Bļæ½zier curve to the current figure.
335
public void AddBezier(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4)
337
AddBezier((double)x1, (double)y1, (double)x2, (double)y2, (double)x3, (double)y3, (double)x4, (double)y4);
341
/// Adds a cubic Bļæ½zier curve to the current figure.
343
public void AddBezier(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4)
346
this.gdipPath.AddBezier((float)x1, (float)y1, (float)x2, (float)y2, (float)x3, (float)y3, (float)x4, (float)y4);
349
PathFigure figure = CurrentPathFigure;
350
if (figure.Segments.Count == 0)
351
figure.StartPoint = new System.Windows.Point(x1, y1);
353
figure.Segments.Add(new LineSegment(new System.Windows.Point(x1, y1), true));
354
figure.Segments.Add(new BezierSegment(
355
new System.Windows.Point(x2, y2),
356
new System.Windows.Point(x3, y3),
357
new System.Windows.Point(x4, y4), true));
361
// ----- AddBeziers ---------------------------------------------------------------------------
365
/// Adds a sequence of connected cubic Bļæ½zier curves to the current figure.
367
public void AddBeziers(System.Drawing.Point[] points)
369
AddBeziers(XGraphics.MakeXPointArray(points));
375
/// Adds a sequence of connected cubic Bļæ½zier curves to the current figure.
377
public void AddBeziers(System.Windows.Point[] points)
379
AddBeziers(XGraphics.MakeXPointArray(points));
385
/// Adds a sequence of connected cubic Bļæ½zier curves to the current figure.
387
public void AddBeziers(PointF[] points)
389
AddBeziers(XGraphics.MakeXPointArray(points));
394
/// Adds a sequence of connected cubic Bļæ½zier curves to the current figure.
396
public void AddBeziers(XPoint[] points)
399
new ArgumentNullException("points");
401
int count = points.Length;
402
if (points.Length < 4)
403
throw new ArgumentException("At least four points required for bezier curve.", "points");
405
if ((points.Length - 1) % 3 != 0)
406
throw new ArgumentException("Invalid number of points for bezier curve. Number must fulfil 4+3n.", "points");
409
this.gdipPath.AddBeziers(XGraphics.MakePointFArray(points));
412
PathFigure figure = CurrentPathFigure;
413
if (figure.Segments.Count == 0)
414
figure.StartPoint = new System.Windows.Point(points[0].x, points[0].y);
416
figure.Segments.Add(new LineSegment(new System.Windows.Point(points[0].x, points[0].y), true));
418
for (int idx = 1; idx < count; idx += 3)
419
figure.Segments.Add(new BezierSegment(
420
new System.Windows.Point(points[idx].x, points[idx].y),
421
new System.Windows.Point(points[idx + 1].x, points[idx + 1].y),
422
new System.Windows.Point(points[idx + 2].x, points[idx + 2].y), true));
426
// ----- AddCurve -----------------------------------------------------------------------
430
/// Adds a spline curve to the current figure.
432
public void AddCurve(System.Drawing.Point[] points)
434
AddCurve(XGraphics.MakeXPointArray(points));
440
/// Adds a spline curve to the current figure.
442
public void AddCurve(System.Windows.Point[] points)
444
AddCurve(XGraphics.MakeXPointArray(points));
450
/// Adds a spline curve to the current figure.
452
public void AddCurve(PointF[] points)
454
AddCurve(XGraphics.MakeXPointArray(points));
459
/// Adds a spline curve to the current figure.
461
public void AddCurve(XPoint[] points)
463
AddCurve(points, 0.5);
468
/// Adds a spline curve to the current figure.
470
public void AddCurve(System.Drawing.Point[] points, double tension)
472
AddCurve(XGraphics.MakeXPointArray(points), tension);
478
/// Adds a spline curve to the current figure.
480
public void AddCurve(System.Windows.Point[] points, double tension)
482
AddCurve(XGraphics.MakeXPointArray(points), tension);
488
/// Adds a spline curve to the current figure.
490
public void AddCurve(PointF[] points, double tension)
492
AddCurve(XGraphics.MakeXPointArray(points), tension);
497
/// Adds a spline curve to the current figure.
499
public void AddCurve(XPoint[] points, double tension)
501
int count = points.Length;
503
throw new ArgumentException("AddCurve requires two or more points.", "points");
505
this.gdipPath.AddCurve(XGraphics.MakePointFArray(points), (float)tension);
510
PathFigure figure = CurrentPathFigure;
511
if (figure.Segments.Count == 0)
512
figure.StartPoint = new System.Windows.Point(points[0].x, points[0].y);
514
figure.Segments.Add(new LineSegment(new System.Windows.Point(points[0].x, points[0].y), true));
518
figure.Segments.Add(GeometryHelper.CreateCurveSegment(points[0], points[0], points[1], points[1], tension));
522
figure.Segments.Add(GeometryHelper.CreateCurveSegment(points[0], points[0], points[1], points[2], tension));
523
for (int idx = 1; idx < count - 2; idx++)
524
figure.Segments.Add(GeometryHelper.CreateCurveSegment(points[idx - 1], points[idx], points[idx + 1], points[idx + 2], tension));
525
figure.Segments.Add(GeometryHelper.CreateCurveSegment(points[count - 3], points[count - 2], points[count - 1], points[count - 1], tension));
532
/// Adds a spline curve to the current figure.
534
public void AddCurve(System.Drawing.Point[] points, int offset, int numberOfSegments, float tension)
536
AddCurve(XGraphics.MakeXPointArray(points), offset, numberOfSegments, tension);
542
/// Adds a spline curve to the current figure.
544
public void AddCurve(System.Windows.Point[] points, int offset, int numberOfSegments, float tension)
546
AddCurve(XGraphics.MakeXPointArray(points), offset, numberOfSegments, tension);
552
/// Adds a spline curve to the current figure.
554
public void AddCurve(PointF[] points, int offset, int numberOfSegments, float tension)
556
AddCurve(XGraphics.MakeXPointArray(points), offset, numberOfSegments, tension);
561
/// Adds a spline curve to the current figure.
563
public void AddCurve(XPoint[] points, int offset, int numberOfSegments, double tension)
566
this.gdipPath.AddCurve(XGraphics.MakePointFArray(points), offset, numberOfSegments, (float)tension);
569
throw new NotImplementedException("AddCurve not yet implemented.");
573
// ----- AddArc -------------------------------------------------------------------------------
577
/// Adds an elliptical arc to the current figure.
579
public void AddArc(Rectangle rect, double startAngle, double sweepAngle)
581
AddArc((double)rect.X, (double)rect.Y, (double)rect.Width, (double)rect.Height, startAngle, sweepAngle);
587
/// Adds an elliptical arc to the current figure.
589
public void AddArc(RectangleF rect, double startAngle, double sweepAngle)
591
AddArc((double)rect.X, (double)rect.Y, (double)rect.Width, (double)rect.Height, startAngle, sweepAngle);
596
/// Adds an elliptical arc to the current figure.
598
public void AddArc(XRect rect, double startAngle, double sweepAngle)
600
AddArc((double)rect.X, (double)rect.Y, (double)rect.Width, (double)rect.Height, startAngle, sweepAngle);
604
/// Adds an elliptical arc to the current figure.
606
public void AddArc(int x, int y, int width, int height, int startAngle, int sweepAngle)
608
AddArc((double)x, (double)y, (double)width, (double)height, (double)startAngle, (double)sweepAngle);
612
/// Adds an elliptical arc to the current figure.
614
public void AddArc(double x, double y, double width, double height, double startAngle, double sweepAngle)
617
this.gdipPath.AddArc((float)x, (float)y, (float)width, (float)height, (float)startAngle, (float)sweepAngle);
620
PathFigure figure = CurrentPathFigure;
621
System.Windows.Point startPoint;
622
ArcSegment seg = GeometryHelper.CreateArcSegment(x, y, width, height, startAngle, sweepAngle, out startPoint);
623
if (figure.Segments.Count == 0)
624
figure.StartPoint = startPoint;
625
figure.Segments.Add(seg);
627
//figure.Segments.Add(
628
//if (figure.Segments.Count == 0)
629
// figure.StartPoint = new System.Windows.Point(points[0].x, points[0].y);
631
// figure.Segments.Add(new LineSegment(new System.Windows.Point(points[0].x, points[0].y), true));
633
//for (int idx = 1; idx < 5555; idx += 3)
634
// figure.Segments.Add(new BezierSegment(
635
// new System.Windows.Point(points[idx].x, points[idx].y),
636
// new System.Windows.Point(points[idx + 1].x, points[idx + 1].y),
637
// new System.Windows.Point(points[idx + 2].x, points[idx + 2].y), true));
643
/// Adds an elliptical arc to the current figure. The arc is specified WPF like.
645
public void AddArc(XPoint point1, XPoint point2, XSize size, double rotationAngle, bool isLargeArg, SweepDirection sweepDirection)
647
PathFigure figure = CurrentPathFigure;
648
if (figure.Segments.Count == 0)
649
figure.StartPoint = point1.ToPoint();
651
figure.Segments.Add(new LineSegment(point1.ToPoint(), true));
652
figure.Segments.Add(new ArcSegment(point2.ToPoint(), size.ToSize(), rotationAngle, isLargeArg, sweepDirection, true));
656
// ----- AddRectangle -------------------------------------------------------------------------
660
/// Adds a rectangle to this path.
662
public void AddRectangle(Rectangle rect)
664
AddRectangle(new XRect(rect));
670
/// Adds a rectangle to this path.
672
public void AddRectangle(RectangleF rect)
674
AddRectangle(new XRect(rect));
679
/// Adds a rectangle to this path.
681
public void AddRectangle(XRect rect)
684
this.gdipPath.AddRectangle(rect.ToRectangleF());
688
PathFigure figure = CurrentPathFigure;
689
figure.StartPoint = new System.Windows.Point(rect.x, rect.y);
690
figure.Segments.Add(new LineSegment(new System.Windows.Point(rect.x + rect.width, rect.y), true));
691
figure.Segments.Add(new LineSegment(new System.Windows.Point(rect.x + rect.width, rect.y + rect.height), true));
692
figure.Segments.Add(new LineSegment(new System.Windows.Point(rect.x, rect.y + rect.height), true));
698
/// Adds a rectangle to this path.
700
public void AddRectangle(int x, int y, int width, int height)
702
AddRectangle(new XRect(x, y, width, height));
706
/// Adds a rectangle to this path.
708
public void AddRectangle(double x, double y, double width, double height)
710
AddRectangle(new XRect(x, y, width, height));
713
// ----- AddRectangles ------------------------------------------------------------------------
717
/// Adds a series of rectangles to this path.
719
public void AddRectangles(Rectangle[] rects)
721
int count = rects.Length;
722
for (int idx = 0; idx < count; idx++)
723
AddRectangle(rects[idx]);
724
this.gdipPath.AddRectangles(rects);
730
/// Adds a series of rectangles to this path.
732
public void AddRectangles(RectangleF[] rects)
734
int count = rects.Length;
735
for (int idx = 0; idx < count; idx++)
736
AddRectangle(rects[idx]);
737
this.gdipPath.AddRectangles(rects);
742
/// Adds a series of rectangles to this path.
744
public void AddRectangles(XRect[] rects)
746
int count = rects.Length;
747
for (int idx = 0; idx < count; idx++)
750
this.gdipPath.AddRectangle(rects[idx].ToRectangleF());
754
PathFigure figure = CurrentPathFigure;
755
XRect rect = rects[idx];
756
figure.StartPoint = new System.Windows.Point(rect.x, rect.y);
757
figure.Segments.Add(new LineSegment(new System.Windows.Point(rect.x + rect.width, rect.y), true));
758
figure.Segments.Add(new LineSegment(new System.Windows.Point(rect.x + rect.width, rect.y + rect.height), true));
759
figure.Segments.Add(new LineSegment(new System.Windows.Point(rect.x, rect.y + rect.height), true));
765
// ----- AddRoundedRectangle ------------------------------------------------------------------
769
/// Adds a rectangle with rounded cornes to this path.
771
public void AddRoundedRectangle(Rectangle rect, System.Drawing.Size ellipseSize)
773
AddRoundedRectangle((double)rect.X, (double)rect.Y, (double)rect.Width, (double)rect.Height,
774
(double)ellipseSize.Width, (double)ellipseSize.Height);
780
/// Adds a rectangle with rounded cornes to this path.
782
public void AddRoundedRectangle(Rect rect, System.Windows.Size ellipseSize)
784
AddRoundedRectangle((double)rect.X, (double)rect.Y, (double)rect.Width, (double)rect.Height,
785
(double)ellipseSize.Width, (double)ellipseSize.Height);
791
/// Adds a rectangle with rounded cornes to this path.
793
public void AddRoundedRectangle(RectangleF rect, SizeF ellipseSize)
795
AddRoundedRectangle((double)rect.X, (double)rect.Y, (double)rect.Width, (double)rect.Height,
796
(double)ellipseSize.Width, (double)ellipseSize.Height);
802
/// Adds a rectangle with rounded cornes to this path.
804
public void AddRoundedRectangle(XRect rect, SizeF ellipseSize)
806
AddRoundedRectangle((double)rect.X, (double)rect.Y, (double)rect.Width, (double)rect.Height,
807
(double)ellipseSize.Width, (double)ellipseSize.Height);
812
/// Adds a rectangle with rounded cornes to this path.
814
public void AddRoundedRectangle(int x, int y, int width, int height, int ellipseWidth, int ellipseHeight)
816
AddRoundedRectangle((double)x, (double)y, (double)width, (double)height, (double)ellipseWidth, (double)ellipseHeight);
820
/// Adds a rectangle with rounded cornes to this path.
822
public void AddRoundedRectangle(double x, double y, double width, double height, double ellipseWidth, double ellipseHeight)
825
this.gdipPath.AddArc((float)(x + width - ellipseWidth), (float)y, (float)ellipseWidth, (float)ellipseHeight, -90, 90);
826
this.gdipPath.AddArc((float)(x + width - ellipseWidth), (float)(y + height - ellipseHeight), (float)ellipseWidth, (float)ellipseHeight, 0, 90);
827
this.gdipPath.AddArc((float)x, (float)(y + height - ellipseHeight), (float)ellipseWidth, (float)ellipseHeight, 90, 90);
828
this.gdipPath.AddArc((float)x, (float)y, (float)ellipseWidth, (float)ellipseHeight, 180, 90);
829
this.gdipPath.CloseFigure();
832
double ex = ellipseWidth / 2;
833
double ey = ellipseHeight / 2;
835
PathFigure figure = CurrentPathFigure;
836
figure.StartPoint = new System.Windows.Point(x + ex, y);
837
figure.Segments.Add(new LineSegment(new System.Windows.Point(x + width - ex, y), true));
839
figure.Segments.Add(new ArcSegment(new System.Windows.Point(x + width, y + ey), new System.Windows.Size(ex, ey), 0, false, SweepDirection.Clockwise, true));
840
//figure.Segments.Add(new LineSegment(new System.Windows.Point(x + width, y + ey), true));
842
figure.Segments.Add(new LineSegment(new System.Windows.Point(x + width, y + height - ey), true));
844
figure.Segments.Add(new ArcSegment(new System.Windows.Point(x + width - ex, y + height), new System.Windows.Size(ex, ey), 0, false, SweepDirection.Clockwise, true));
845
//figure.Segments.Add(new LineSegment(new System.Windows.Point(x + width - ex, y + height), true));
847
figure.Segments.Add(new LineSegment(new System.Windows.Point(x + ex, y + height), true));
849
figure.Segments.Add(new ArcSegment(new System.Windows.Point(x, y + height - ey), new System.Windows.Size(ex, ey), 0, false, SweepDirection.Clockwise, true));
850
//figure.Segments.Add(new LineSegment(new System.Windows.Point(x, y + height - ey), true));
852
figure.Segments.Add(new LineSegment(new System.Windows.Point(x, y + ey), true));
854
figure.Segments.Add(new ArcSegment(new System.Windows.Point(x + ex, y), new System.Windows.Size(ex, ey), 0, false, SweepDirection.Clockwise, true));
855
//figure.Segments.Add(new LineSegment(new System.Windows.Point(x + ex, y), true));
861
// ----- AddEllipse ---------------------------------------------------------------------------
865
/// Adds an ellipse to the current path.
867
public void AddEllipse(Rectangle rect)
869
AddEllipse(rect.X, rect.Y, rect.Width, rect.Height);
875
/// Adds an ellipse to the current path.
877
public void AddEllipse(RectangleF rect)
879
AddEllipse(rect.X, rect.Y, rect.Width, rect.Height);
884
/// Adds an ellipse to the current path.
886
public void AddEllipse(XRect rect)
888
AddEllipse(rect.x, rect.y, rect.width, rect.height);
892
/// Adds an ellipse to the current path.
894
public void AddEllipse(int x, int y, int width, int height)
896
AddEllipse((double)x, (double)y, (double)width, (double)height);
900
/// Adds an ellipse to the current path.
902
public void AddEllipse(double x, double y, double width, double height)
905
this.gdipPath.AddEllipse((float)x, (float)y, (float)width, (float)height);
909
this.pathGeometry.AddGeometry(new EllipseGeometry(new Rect(x, y, width, height)));
913
// ----- AddPolygon ---------------------------------------------------------------------------
917
/// Adds a polygon to this path.
919
public void AddPolygon(System.Drawing.Point[] points)
921
this.gdipPath.AddPolygon(points);
927
/// Adds a polygon to this path.
929
public void AddPolygon(System.Windows.Point[] points)
937
/// Adds a polygon to this path.
939
public void AddPolygon(PointF[] points)
941
this.gdipPath.AddPolygon(points);
946
/// Adds a polygon to this path.
948
public void AddPolygon(XPoint[] points)
951
this.gdipPath.AddPolygon(XGraphics.MakePointFArray(points));
955
this.pathGeometry.AddGeometry(GeometryHelper.CreatePolygonGeometry(XGraphics.MakePointArray(points), XFillMode.Alternate, false));
959
// ----- AddPie -------------------------------------------------------------------------------
963
/// Adds the outline of a pie shape to this path.
965
public void AddPie(Rectangle rect, double startAngle, double sweepAngle)
967
this.gdipPath.AddPie(rect, (float)startAngle, (float)sweepAngle);
973
/// Adds the outline of a pie shape to this path.
975
public void AddPie(RectangleF rect, double startAngle, double sweepAngle)
977
AddPie((double)rect.X, (double)rect.Y, (double)rect.Width, (double)rect.Height, startAngle, sweepAngle);
982
/// Adds the outline of a pie shape to this path.
984
public void AddPie(XRect rect, double startAngle, double sweepAngle)
986
AddPie(rect.X, rect.Y, rect.Width, rect.Height, startAngle, sweepAngle);
990
/// Adds the outline of a pie shape to this path.
992
public void AddPie(int x, int y, int width, int height, double startAngle, double sweepAngle)
994
AddPie((double)x, (double)y, (double)width, (double)height, startAngle, sweepAngle);
998
/// Adds the outline of a pie shape to this path.
1000
public void AddPie(double x, double y, double width, double height, double startAngle, double sweepAngle)
1003
this.gdipPath.AddPie((float)x, (float)y, (float)width, (float)height, (float)startAngle, (float)sweepAngle);
1009
// ----- AddClosedCurve ------------------------------------------------------------------------
1013
/// Adds a closed curve to this path.
1015
public void AddClosedCurve(System.Drawing.Point[] points)
1017
AddClosedCurve(XGraphics.MakeXPointArray(points), 0.5);
1023
/// Adds a closed curve to this path.
1025
public void AddClosedCurve(System.Windows.Point[] points)
1027
AddClosedCurve(XGraphics.MakeXPointArray(points), 0.5);
1033
/// Adds a closed curve to this path.
1035
public void AddClosedCurve(PointF[] points)
1037
AddClosedCurve(XGraphics.MakeXPointArray(points), 0.5);
1042
/// Adds a closed curve to this path.
1044
public void AddClosedCurve(XPoint[] points)
1046
AddClosedCurve(points, 0.5);
1051
/// Adds a closed curve to this path.
1053
public void AddClosedCurve(System.Drawing.Point[] points, double tension)
1055
AddClosedCurve(XGraphics.MakeXPointArray(points), tension);
1061
/// Adds a closed curve to this path.
1063
public void AddClosedCurve(System.Windows.Point[] points, double tension)
1065
AddClosedCurve(XGraphics.MakeXPointArray(points), tension);
1071
/// Adds a closed curve to this path.
1073
public void AddClosedCurve(PointF[] points, double tension)
1075
AddClosedCurve(XGraphics.MakeXPointArray(points), tension);
1080
/// Adds a closed curve to this path.
1082
public void AddClosedCurve(XPoint[] points, double tension)
1085
throw new ArgumentNullException("points");
1086
int count = points.Length;
1090
throw new ArgumentException("Not enough points.", "points");
1092
this.gdipPath.AddClosedCurve(XGraphics.MakePointFArray(points), (float)tension);
1098
PathFigure figure = CurrentPathFigure;
1099
figure.StartPoint = new System.Windows.Point(points[0].x, points[0].y);
1103
figure.Segments.Add(GeometryHelper.CreateCurveSegment(points[0], points[0], points[1], points[1], tension));
1107
figure.Segments.Add(GeometryHelper.CreateCurveSegment(points[count - 1], points[0], points[1], points[2], tension));
1108
for (int idx = 1; idx < count - 2; idx++)
1109
figure.Segments.Add(GeometryHelper.CreateCurveSegment(points[idx - 1], points[idx], points[idx + 1], points[idx + 2], tension));
1110
figure.Segments.Add(GeometryHelper.CreateCurveSegment(points[count - 3], points[count - 2], points[count - 1], points[0], tension));
1111
figure.Segments.Add(GeometryHelper.CreateCurveSegment(points[count - 2], points[count - 1], points[0], points[1], tension));
1116
// ----- AddPath ------------------------------------------------------------------------------
1119
/// Adds the specified path to this path.
1121
public void AddPath(XGraphicsPath path, bool connect)
1124
this.gdipPath.AddPath(path.gdipPath, connect);
1127
this.pathGeometry.AddGeometry(path.pathGeometry);
1131
// ----- AddString ----------------------------------------------------------------------------
1135
/// Adds a text string to this path.
1137
public void AddString(string s, XFontFamily family, XFontStyle style, double emSize, System.Drawing.Point origin, XStringFormat format)
1139
//this.gdipPath.AddString(s, family.gdiFamily, (int)style, (float)emSize, origin, format.RealizeGdiStringFormat());
1141
AddString(s, family, style, emSize, origin, format);
1147
/// Adds a text string to this path.
1149
public void AddString(string s, XFontFamily family, XFontStyle style, double emSize, System.Windows.Point origin, XStringFormat format)
1151
AddString(s, family, style, emSize, new XPoint(origin), format);
1153
//Typeface typeface = FontHelper.CreateTypeface(family, style);
1154
//FormattedText formattedText = new FormattedText(s, null, FlowDirection.LeftToRight, typeface, emSize, System.Windows.Media.Brushes.Black);
1155
//Geometry geo = formattedText.BuildGeometry(origin);
1156
//this.pathGeometry.AddGeometry(geo);
1162
/// Adds a text string to this path.
1164
public void AddString(string s, XFontFamily family, XFontStyle style, double emSize, PointF origin, XStringFormat format)
1166
//this.gdipPath.AddString(s, family.gdiFamily, (int)style, (float)emSize, origin, format.RealizeGdiStringFormat());
1168
AddString(s, family, style, emSize, new XRect(origin.X, origin.Y, 0, 0), format);
1173
/// Adds a text string to this path.
1175
public void AddString(string s, XFontFamily family, XFontStyle style, double emSize, XPoint origin, XStringFormat format)
1181
this.gdipPath.AddString(s, family.gdiFamily, (int)style, (float)emSize, origin.ToPointF(), format.RealizeGdiStringFormat());
1184
Typeface typeface = FontHelper.CreateTypeface(family, style);
1185
FormattedText ft = new FormattedText(s, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, typeface, emSize,
1186
System.Windows.Media.Brushes.Black);
1187
Geometry geo = ft.BuildGeometry(origin);
1188
this.pathGeometry.AddGeometry(geo);
1196
/// Adds a text string to this path.
1198
public void AddString(string s, XFontFamily family, XFontStyle style, double emSize, Rectangle layoutRect, XStringFormat format)
1201
this.gdipPath.AddString(s, family.gdiFamily, (int)style, (float)emSize, layoutRect, format.RealizeGdiStringFormat());
1207
/// Adds a text string to this path.
1209
public void AddString(string s, XFontFamily family, XFontStyle style, double emSize, RectangleF layoutRect, XStringFormat format)
1212
this.gdipPath.AddString(s, family.gdiFamily, (int)style, (float)emSize, layoutRect, format.RealizeGdiStringFormat());
1218
/// Adds a text string to this path.
1220
public void AddString(string s, XFontFamily family, XFontStyle style, double emSize, Rect rect, XStringFormat format)
1222
//this.gdip Path.AddString(s, family.gdiFamily, (int)style, (float)emSize, layoutRect, format.RealizeGdiStringFormat());
1223
AddString(s, family, style, emSize, new XRect(rect), format);
1228
/// Adds a text string to this path.
1230
public void AddString(string s, XFontFamily family, XFontStyle style, double emSize, XRect layoutRect, XStringFormat format)
1233
throw new ArgumentNullException("s");
1235
throw new ArgumentNullException("family");
1237
if (format.LineAlignment == XLineAlignment.BaseLine && layoutRect.Height != 0)
1238
throw new InvalidOperationException("DrawString: With XLineAlignment.BaseLine the height of the layout rectangle must be 0.");
1244
format = XStringFormats.Default;
1246
XFont font = new XFont(family.Name, emSize, style);
1248
RectangleF rc = layoutRect.ToRectangleF();
1249
if (format.LineAlignment == XLineAlignment.BaseLine)
1251
double lineSpace = font.GetHeight();
1252
int cellSpace = font.FontFamily.GetLineSpacing(font.Style);
1253
int cellAscent = font.FontFamily.GetCellAscent(font.Style);
1254
int cellDescent = font.FontFamily.GetCellDescent(font.Style);
1255
double cyAscent = lineSpace * cellAscent / cellSpace;
1256
cyAscent = lineSpace * font.cellAscent / font.cellSpace;
1257
rc.Offset(0, (float)-cyAscent);
1259
//this.gfx.DrawString(text, font.RealizeGdiFont(), brush.RealizeGdiBrush(), rect,
1260
// format != null ? format.RealizeGdiStringFormat() : null);
1261
this.gdipPath.AddString(s, family.gdiFamily, (int)style, (float)emSize, rc, format.RealizeGdiStringFormat());
1264
// Just a first sketch, but currently we do not need it and there is enough to do...
1265
double x = layoutRect.X;
1266
double y = layoutRect.Y;
1268
//double lineSpace = font.GetHeight(this);
1269
//double cyAscent = lineSpace * font.cellAscent / font.cellSpace;
1270
//double cyDescent = lineSpace * font.cellDescent / font.cellSpace;
1272
//double cyAscent = family.GetCellAscent(style) * family.GetLineSpacing(style) / family.getl; //fontlineSpace * font.cellAscent / font.cellSpace;
1273
//double cyDescent =family.GetCellDescent(style); // lineSpace * font.cellDescent / font.cellSpace;
1274
double lineSpace = font.GetHeight();
1275
double cyAscent = lineSpace * font.cellAscent / font.cellSpace;
1276
double cyDescent = lineSpace * font.cellDescent / font.cellSpace;
1278
bool bold = (style & XFontStyle.Bold) != 0;
1279
bool italic = (style & XFontStyle.Italic) != 0;
1280
bool strikeout = (style & XFontStyle.Strikeout) != 0;
1281
bool underline = (style & XFontStyle.Underline) != 0;
1283
Typeface typeface = FontHelper.CreateTypeface(family, style);
1284
FormattedText formattedText = new FormattedText(s, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, typeface, emSize,
1285
System.Windows.Media.Brushes.Black);
1287
switch (format.Alignment)
1289
case XStringAlignment.Near:
1290
// nothing to do, this is the default
1291
//formattedText.TextAlignment = TextAlignment.Left;
1294
case XStringAlignment.Center:
1295
x += layoutRect.Width / 2;
1296
formattedText.TextAlignment = TextAlignment.Center;
1299
case XStringAlignment.Far:
1300
x += layoutRect.Width;
1301
formattedText.TextAlignment = TextAlignment.Right;
1304
//if (PageDirection == XPageDirection.Downwards)
1306
switch (format.LineAlignment)
1308
case XLineAlignment.Near:
1312
case XLineAlignment.Center:
1313
// TODO use CapHeight. PDFlib also uses 3/4 of ascent
1314
y += -formattedText.Baseline + (cyAscent * 2 / 4) + layoutRect.Height / 2;
1317
case XLineAlignment.Far:
1318
y += -formattedText.Baseline - cyDescent + layoutRect.Height;
1321
case XLineAlignment.BaseLine:
1322
y -= formattedText.Baseline;
1329
// switch (format.LineAlignment)
1331
// case XLineAlignment.Near:
1332
// //y += cyDescent;
1335
// case XLineAlignment.Center:
1336
// // TODO use CapHeight. PDFlib also uses 3/4 of ascent
1337
// //y += -(cyAscent * 3 / 4) / 2 + rect.Height / 2;
1340
// case XLineAlignment.Far:
1341
// //y += -cyAscent + rect.Height;
1344
// case XLineAlignment.BaseLine:
1350
//if (bold && !descriptor.IsBoldFace)
1352
// // TODO: emulate bold by thicker outline
1355
//if (italic && !descriptor.IsBoldFace)
1357
// // TODO: emulate italic by shearing transformation
1362
//double underlinePosition = lineSpace * realizedFont.FontDescriptor.descriptor.UnderlinePosition / font.cellSpace;
1363
//double underlineThickness = lineSpace * realizedFont.FontDescriptor.descriptor.UnderlineThickness / font.cellSpace;
1364
//DrawRectangle(null, brush, x, y - underlinePosition, width, underlineThickness);
1369
//double strikeoutPosition = lineSpace * realizedFont.FontDescriptor.descriptor.StrikeoutPosition / font.cellSpace;
1370
//double strikeoutSize = lineSpace * realizedFont.FontDescriptor.descriptor.StrikeoutSize / font.cellSpace;
1371
//DrawRectangle(null, brush, x, y - strikeoutPosition - strikeoutSize, width, strikeoutSize);
1374
//this.dc.DrawText(formattedText, layoutRectangle.Location.ToPoint());
1375
//this.dc.DrawText(formattedText, new System.Windows.Point(x, y));
1377
Geometry geo = formattedText.BuildGeometry(new Point(x, y));
1378
this.pathGeometry.AddGeometry(geo);
1382
// ----- CloseAllFigures ----------------------------------------------------------------------
1384
// TODO? CloseAllFigures
1385
//public void CloseAllFigures();
1387
// --------------------------------------------------------------------------------------------
1390
/// Closes the current figure and starts a new figure.
1392
public void CloseFigure()
1395
this.gdipPath.CloseFigure();
1398
PathFigure figure = CurrentPathFigure;
1399
if (figure.Segments.Count != 0)
1401
figure.IsClosed = true;
1402
//this.figure = null; // force start of new figure
1403
this.startNewFigure = true;
1409
/// Starts a new figure without closing the current figure.
1411
public void StartFigure()
1414
this.gdipPath.StartFigure();
1417
PathFigure figure = CurrentPathFigure;
1418
if (figure.Segments.Count != 0)
1420
figure = new PathFigure();
1421
this.pathGeometry.Figures.Add(figure);
1426
// --------------------------------------------------------------------------------------------
1429
/// Gets or sets an XFillMode that determines how the interiors of shapes are filled.
1431
public XFillMode FillMode
1433
get { return this.fillMode; }
1436
this.fillMode = value;
1438
this.gdipPath.FillMode = (FillMode)value;
1441
this.pathGeometry.FillRule = value == XFillMode.Winding ? FillRule.Nonzero : FillRule.EvenOdd;
1447
// --------------------------------------------------------------------------------------------
1450
/// Converts each curve in this XGraphicsPath into a sequence of connected line segments.
1452
public void Flatten()
1455
this.gdipPath.Flatten();
1458
this.pathGeometry = this.pathGeometry.GetFlattenedPathGeometry();
1463
/// Converts each curve in this XGraphicsPath into a sequence of connected line segments.
1465
public void Flatten(XMatrix matrix)
1468
this.gdipPath.Flatten(matrix.ToGdiMatrix());
1471
this.pathGeometry = this.pathGeometry.GetFlattenedPathGeometry();
1472
this.pathGeometry.Transform = new MatrixTransform(matrix.ToWpfMatrix());
1477
/// Converts each curve in this XGraphicsPath into a sequence of connected line segments.
1479
public void Flatten(XMatrix matrix, double flatness)
1482
this.gdipPath.Flatten(matrix.ToGdiMatrix(), (float)flatness);
1486
this.pathGeometry = this.pathGeometry.GetFlattenedPathGeometry();
1490
// --------------------------------------------------------------------------------------------
1493
/// Replaces this path with curves that enclose the area that is filled when this path is drawn
1494
/// by the specified pen.
1496
public void Widen(XPen pen)
1499
this.gdipPath.Widen(pen.RealizeGdiPen());
1502
this.pathGeometry = this.pathGeometry.GetWidenedPathGeometry(pen.RealizeWpfPen());
1507
/// Replaces this path with curves that enclose the area that is filled when this path is drawn
1508
/// by the specified pen.
1510
public void Widen(XPen pen, XMatrix matrix)
1513
this.gdipPath.Widen(pen.RealizeGdiPen(), matrix.ToGdiMatrix());
1516
this.pathGeometry = this.pathGeometry.GetWidenedPathGeometry(pen.RealizeWpfPen());
1521
/// Replaces this path with curves that enclose the area that is filled when this path is drawn
1522
/// by the specified pen.
1524
public void Widen(XPen pen, XMatrix matrix, double flatness)
1527
this.gdipPath.Widen(pen.RealizeGdiPen(), matrix.ToGdiMatrix(), (float)flatness);
1530
this.pathGeometry = this.pathGeometry.GetWidenedPathGeometry(pen.RealizeWpfPen());
1535
/// Grants access to internal objects of this class.
1537
public XGraphicsPathInternals Internals
1539
get { return new XGraphicsPathInternals(this); }
b'\\ No newline at end of file'