19 using System.Collections.Generic;
24 internal static class Utils
26 public static Point RotatePoint(Point point,
double angle)
28 return new Point(point.X * Math.Cos(angle) - point.Y * Math.Sin(angle), point.X * Math.Sin(angle) + point.Y * Math.Cos(angle));
75 void Scale(
double scaleX,
double scaleY);
86 void Transform(
double a,
double b,
double c,
double d,
double e,
double f);
186 void CubicBezierTo(
double p1X,
double p1Y,
double p2X,
double p2Y,
double p3X,
double p3Y);
195 void Rectangle(
double x0,
double y0,
double width,
double height);
240 void DrawRasterImage(
int sourceX,
int sourceY,
int sourceWidth,
int sourceHeight,
double destinationX,
double destinationY,
double destinationWidth,
double destinationHeight,
RasterImage image);
255 internal UnbalancedStackException(
int excessSave,
int excessRestore) : base(
"The graphics state stack is unbalanced!\nThere are " + excessSave +
" calls to Graphics.Save() and " + excessRestore +
" calls to Graphics.Restore() in excess!") { }
268 internal List<IGraphicsAction> Actions =
new List<IGraphicsAction>();
294 Actions.Add(
new PathAction(path,
null, strokeColour, lineWidth, lineCap, lineJoin, lineDash ??
LineDash.
SolidLine, tag,
false));
325 Actions.Add(
new PathAction(
new GraphicsPath().MoveTo(topLeft).LineTo(topLeft.
X + size.
Width, topLeft.
Y).
LineTo(topLeft.
X + size.
Width, topLeft.
Y + size.
Height).
LineTo(topLeft.
X, topLeft.
Y + size.
Height).
Close(),
null,
null, 0,
LineCaps.Butt,
LineJoins.Miter,
LineDash.
SolidLine,
null,
true));
334 Actions.Add(
new TransformAction(angle));
344 Actions.Add(
new TransformAction(pivot));
345 Actions.Add(
new TransformAction(angle));
346 Actions.Add(
new TransformAction(
new Point(-pivot.
X, -pivot.
Y)));
359 public void Transform(
double a,
double b,
double c,
double d,
double e,
double f)
361 double[,] matrix =
new double[,] { { a, c, e }, { b, d, f }, { 0, 0, 1 } };
362 Actions.Add(
new TransformAction(matrix));
372 Actions.Add(
new TransformAction(
new Point(x, y)));
381 Actions.Add(
new TransformAction(delta));
389 public void Scale(
double scaleX,
double scaleY)
391 Actions.Add(
new TransformAction(
new Size(scaleX, scaleY)));
415 public void FillRectangle(
double leftX,
double topY,
double width,
double height,
Brush fillColour,
string tag =
null)
417 Actions.Add(
new RectangleAction(
new Point(leftX, topY),
new Size(width, height), fillColour,
null, 0,
LineCaps.Butt,
LineJoins.Miter,
LineDash.
SolidLine, tag));
433 Actions.Add(
new RectangleAction(topLeft, size,
null, strokeColour, lineWidth, lineCap, lineJoin, lineDash ??
LineDash.
SolidLine, tag));
451 Actions.Add(
new RectangleAction(
new Point(leftX, topY),
new Size(width, height),
null, strokeColour, lineWidth, lineCap, lineJoin, lineDash ??
LineDash.
SolidLine, tag));
467 public void DrawRasterImage(
int sourceX,
int sourceY,
int sourceWidth,
int sourceHeight,
double destinationX,
double destinationY,
double destinationWidth,
double destinationHeight,
RasterImage image,
string tag =
null)
469 Actions.Add(
new RasterImageAction(sourceX, sourceY, sourceWidth, sourceHeight, destinationX, destinationY, destinationWidth, destinationHeight, image, tag));
526 Actions.Add(
new StateAction(StateAction.StateActionTypes.Save));
534 Actions.Add(
new StateAction(StateAction.StateActionTypes.Restore));
537 private void FixGraphicsStateStack()
545 List<int> toBeRemoved =
new List<int>();
547 for (
int i = 0; i < this.Actions.Count; i++)
549 if (this.Actions[i] is StateAction st)
551 if (st.StateActionType == StateAction.StateActionTypes.Save)
555 else if (st.StateActionType == StateAction.StateActionTypes.Restore)
571 if (count > 0 || toBeRemoved.Count > 0)
573 throw new UnbalancedStackException(count, toBeRemoved.Count);
578 if (count > 0 || toBeRemoved.Count > 0)
580 for (
int i = toBeRemoved.Count - 1; i >= 0; i--)
582 this.Actions.RemoveAt(toBeRemoved[i]);
585 for (
int i = 0; i < count; i++)
590 this.FixGraphicsStateStack();
601 this.FixGraphicsStateStack();
603 for (
int i = 0; i < this.Actions.Count; i++)
605 if (this.Actions[i] is RectangleAction)
607 RectangleAction rec = this.Actions[i] as RectangleAction;
609 destinationContext.
Tag = rec.Tag;
610 destinationContext.
Rectangle(rec.TopLeft.X, rec.TopLeft.Y, rec.Size.Width, rec.Size.Height);
612 if (rec.Fill !=
null)
614 if (destinationContext.
FillStyle != rec.Fill)
618 destinationContext.
Fill();
620 else if (rec.Stroke !=
null)
626 if (destinationContext.
LineWidth != rec.LineWidth)
628 destinationContext.
LineWidth = rec.LineWidth;
631 destinationContext.
LineCap = rec.LineCap;
632 destinationContext.
LineJoin = rec.LineJoin;
634 destinationContext.
Stroke();
637 else if (this.Actions[i] is PathAction)
639 PathAction pth = this.Actions[i] as PathAction;
641 destinationContext.
Tag = pth.Tag;
643 for (
int j = 0; j < pth.Path.Segments.Count; j++)
645 switch (pth.Path.Segments[j].Type)
648 destinationContext.
MoveTo(pth.Path.Segments[j].Point.X, pth.Path.Segments[j].Point.Y);
651 destinationContext.
LineTo(pth.Path.Segments[j].Point.X, pth.Path.Segments[j].Point.Y);
654 destinationContext.
CubicBezierTo(pth.Path.Segments[j].Points[0].X, pth.Path.Segments[j].Points[0].Y, pth.Path.Segments[j].Points[1].X, pth.Path.Segments[j].Points[1].Y, pth.Path.Segments[j].Points[2].X, pth.Path.Segments[j].Points[2].Y);
658 ArcSegment seg = pth.Path.Segments[j] as ArcSegment;
659 Segment[] segs = seg.ToBezierSegments();
660 for (
int k = 0; k < segs.Length; k++)
662 switch (segs[k].Type)
671 destinationContext.
CubicBezierTo(segs[k].Points[0].X, segs[k].Points[0].Y, segs[k].Points[1].X, segs[k].Points[1].Y, segs[k].Points[2].X, segs[k].Points[2].Y);
678 destinationContext.
Close();
689 if (pth.Fill !=
null)
691 if (destinationContext.
FillStyle != pth.Fill)
695 destinationContext.
Fill();
697 else if (pth.Stroke !=
null)
703 if (destinationContext.
LineWidth != pth.LineWidth)
705 destinationContext.
LineWidth = pth.LineWidth;
708 destinationContext.
LineCap = pth.LineCap;
709 destinationContext.
LineJoin = pth.LineJoin;
711 destinationContext.
Stroke();
715 else if (this.Actions[i] is TextAction)
717 TextAction txt = this.Actions[i] as TextAction;
719 destinationContext.
Tag = txt.Tag;
720 if (destinationContext.
TextBaseline != txt.TextBaseline)
726 if (txt.Fill !=
null)
728 if (destinationContext.
FillStyle != txt.Fill)
732 destinationContext.
FillText(txt.Text, txt.Origin.X, txt.Origin.Y);
734 else if (txt.Stroke !=
null)
740 if (destinationContext.
LineWidth != txt.LineWidth)
742 destinationContext.
LineWidth = txt.LineWidth;
745 destinationContext.
LineCap = txt.LineCap;
746 destinationContext.
LineJoin = txt.LineJoin;
748 destinationContext.
StrokeText(txt.Text, txt.Origin.X, txt.Origin.Y);
751 else if (this.Actions[i] is TransformAction)
753 TransformAction trf = this.Actions[i] as TransformAction;
755 if (trf.Delta !=
null)
759 else if (trf.Angle !=
null)
761 destinationContext.
Rotate((
double)trf.Angle);
763 else if (trf.Scale !=
null)
765 destinationContext.
Scale(((
Size)trf.Scale).Width, ((
Size)trf.Scale).Height);
767 else if (trf.Matrix !=
null)
769 destinationContext.
Transform(trf.Matrix[0, 0], trf.Matrix[1, 0], trf.Matrix[0, 1], trf.Matrix[1, 1], trf.Matrix[0, 2], trf.Matrix[1, 2]);
772 else if (this.Actions[i] is StateAction)
774 if (((StateAction)this.Actions[i]).StateActionType == StateAction.StateActionTypes.Save)
776 destinationContext.
Save();
783 else if (this.Actions[i] is RasterImageAction)
785 RasterImageAction img = this.Actions[i] as RasterImageAction;
786 destinationContext.
Tag = img.Tag;
787 destinationContext.
DrawRasterImage(img.SourceX, img.SourceY, img.SourceWidth, img.SourceHeight, img.DestinationX, img.DestinationY, img.DestinationWidth, img.DestinationHeight, img.Image);
789 else if (this.Actions[i] is FilteredGraphicsAction)
791 FilteredGraphicsAction fil = this.Actions[i] as FilteredGraphicsAction;
807 graphics.FixGraphicsStateStack();
809 this.Actions.AddRange(graphics.Actions);
837 clone.Actions.AddRange(graphics.Actions);
838 clone.FixGraphicsStateStack();
840 this.Actions.Add(
new FilteredGraphicsAction(clone, filter));
858 internal static Point Multiply(
double[,] matrix,
Point pt)
860 double x = matrix[0, 0] * pt.
X + matrix[0, 1] * pt.
Y + matrix[0, 2];
861 double y = matrix[1, 0] * pt.
X + matrix[1, 1] * pt.
Y + matrix[1, 2];
862 double z = matrix[2, 0] * pt.
X + matrix[2, 1] * pt.
Y + matrix[2, 2];
864 return new Point(x / z, y / z);
867 internal static double[,] Multiply(
double[,] m1,
double[,] m2)
869 return new double[3, 3]
871 { m1[0,0] * m2[0,0] + m1[0,1] * m2[1,0] + m1[0,2] *m2[2,0], m1[0,0] * m2[0,1] + m1[0,1] * m2[1,1] + m1[0,2] * m2[2,1], m1[0,0] * m2[0,2] + m1[0,1] * m2[1,2] + m1[0,2] * m2[2,2] },
872 { m1[1,0] * m2[0,0] + m1[1,1] * m2[1,0] + m1[1,2] *m2[2,0], m1[1,0] * m2[0,1] + m1[1,1] * m2[1,1] + m1[1,2] * m2[2,1], m1[1,0] * m2[0,2] + m1[1,1] * m2[1,2] + m1[1,2] * m2[2,2] },
873 { m1[2,0] * m2[0,0] + m1[2,1] * m2[1,0] + m1[2,2] *m2[2,0], m1[2,0] * m2[0,1] + m1[2,1] * m2[1,1] + m1[2,2] * m2[2,1], m1[2,0] * m2[0,2] + m1[2,1] * m2[1,2] + m1[2,2] * m2[2,2] }
877 internal static double[,] TranslationMatrix(
double dx,
double dy)
879 return new double[3, 3]
887 internal static double[,] ScaleMatrix(
double sx,
double sy)
889 return new double[3, 3]
897 internal static double[,] RotationMatrix(
double theta)
899 return new double[3, 3]
901 {Math.Cos(theta), -Math.Sin(theta), 0 },
902 {Math.Sin(theta), Math.Cos(theta), 0 },
907 internal static double[,] Invert(
double[,] m)
909 double[,] tbr =
new double[3, 3];
911 tbr[0, 0] = (m[1, 1] * m[2, 2] - m[1, 2] * m[2, 1]) / (m[0, 0] * m[1, 1] * m[2, 2] - m[0, 0] * m[1, 2] * m[2, 1] - m[1, 0] * m[0, 1] * m[2, 2] + m[2, 0] * m[0, 1] * m[1, 2] + m[1, 0] * m[0, 2] * m[2, 1] - m[2, 0] * m[0, 2] * m[1, 1]);
912 tbr[0, 1] = -(m[0, 1] * m[2, 2] - m[0, 2] * m[2, 1]) / (m[0, 0] * m[1, 1] * m[2, 2] - m[0, 0] * m[1, 2] * m[2, 1] - m[1, 0] * m[0, 1] * m[2, 2] + m[2, 0] * m[0, 1] * m[1, 2] + m[1, 0] * m[0, 2] * m[2, 1] - m[2, 0] * m[0, 2] * m[1, 1]);
913 tbr[0, 2] = (m[0, 1] * m[1, 2] - m[0, 2] * m[1, 1]) / (m[0, 0] * m[1, 1] * m[2, 2] - m[0, 0] * m[1, 2] * m[2, 1] - m[1, 0] * m[0, 1] * m[2, 2] + m[2, 0] * m[0, 1] * m[1, 2] + m[1, 0] * m[0, 2] * m[2, 1] - m[2, 0] * m[0, 2] * m[1, 1]);
914 tbr[1, 0] = -(m[1, 0] * m[2, 2] - m[1, 2] * m[2, 0]) / (m[0, 0] * m[1, 1] * m[2, 2] - m[0, 0] * m[1, 2] * m[2, 1] - m[1, 0] * m[0, 1] * m[2, 2] + m[2, 0] * m[0, 1] * m[1, 2] + m[1, 0] * m[0, 2] * m[2, 1] - m[2, 0] * m[0, 2] * m[1, 1]);
915 tbr[1, 1] = (m[0, 0] * m[2, 2] - m[0, 2] * m[2, 0]) / (m[0, 0] * m[1, 1] * m[2, 2] - m[0, 0] * m[1, 2] * m[2, 1] - m[1, 0] * m[0, 1] * m[2, 2] + m[2, 0] * m[0, 1] * m[1, 2] + m[1, 0] * m[0, 2] * m[2, 1] - m[2, 0] * m[0, 2] * m[1, 1]);
916 tbr[1, 2] = -(m[0, 0] * m[1, 2] - m[0, 2] * m[1, 0]) / (m[0, 0] * m[1, 1] * m[2, 2] - m[0, 0] * m[1, 2] * m[2, 1] - m[1, 0] * m[0, 1] * m[2, 2] + m[2, 0] * m[0, 1] * m[1, 2] + m[1, 0] * m[0, 2] * m[2, 1] - m[2, 0] * m[0, 2] * m[1, 1]);
917 tbr[2, 0] = (m[1, 0] * m[2, 1] - m[1, 1] * m[2, 0]) / (m[0, 0] * m[1, 1] * m[2, 2] - m[0, 0] * m[1, 2] * m[2, 1] - m[1, 0] * m[0, 1] * m[2, 2] + m[2, 0] * m[0, 1] * m[1, 2] + m[1, 0] * m[0, 2] * m[2, 1] - m[2, 0] * m[0, 2] * m[1, 1]);
918 tbr[2, 1] = -(m[0, 0] * m[2, 1] - m[0, 1] * m[2, 0]) / (m[0, 0] * m[1, 1] * m[2, 2] - m[0, 0] * m[1, 2] * m[2, 1] - m[1, 0] * m[0, 1] * m[2, 2] + m[2, 0] * m[0, 1] * m[1, 2] + m[1, 0] * m[0, 2] * m[2, 1] - m[2, 0] * m[0, 2] * m[1, 1]);
919 tbr[2, 2] = (m[0, 0] * m[1, 1] - m[0, 1] * m[1, 0]) / (m[0, 0] * m[1, 1] * m[2, 2] - m[0, 0] * m[1, 2] * m[2, 1] - m[1, 0] * m[0, 1] * m[2, 2] + m[2, 0] * m[0, 1] * m[1, 2] + m[1, 0] * m[0, 2] * m[2, 1] - m[2, 0] * m[0, 2] * m[1, 1]);
930 public Graphics Transform(Func<Point, Point> transformationFunction,
double linearisationResolution)
934 Stack<double[,]> transformMatrix =
new Stack<double[,]>();
935 double[,] currMatrix =
new double[3, 3] { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 } };
937 for (
int i = 0; i < this.Actions.Count; i++)
939 if (this.Actions[i] is RectangleAction)
941 RectangleAction rec = this.Actions[i] as RectangleAction;
945 Point pt1 = transformationFunction(Multiply(currMatrix, rec.TopLeft));
946 Point pt2 = transformationFunction(Multiply(currMatrix,
new Point(rec.TopLeft.X + rec.Size.Width, rec.TopLeft.Y)));
947 Point pt3 = transformationFunction(Multiply(currMatrix,
new Point(rec.TopLeft.X + rec.Size.Width, rec.TopLeft.Y + rec.Size.Height)));
948 Point pt4 = transformationFunction(Multiply(currMatrix,
new Point(rec.TopLeft.X, rec.TopLeft.Y + rec.Size.Height)));
952 if (rec.Fill !=
null)
954 destinationGraphics.
FillPath(rectanglePath, rec.Fill, rec.Tag);
956 else if (rec.Stroke !=
null)
958 destinationGraphics.
StrokePath(rectanglePath, rec.Stroke, rec.LineWidth, rec.LineCap, rec.LineJoin, rec.LineDash, rec.Tag);
961 else if (this.Actions[i] is PathAction)
963 PathAction pth = this.Actions[i] as PathAction;
973 if (pth.Fill !=
null)
975 destinationGraphics.
FillPath(newPath, pth.Fill, pth.Tag);
977 else if (pth.Stroke !=
null)
979 destinationGraphics.
StrokePath(newPath, pth.Stroke, pth.LineWidth, pth.LineCap, pth.LineJoin, pth.LineDash, pth.Tag);
983 else if (this.Actions[i] is TextAction)
985 TextAction txt = this.Actions[i] as TextAction;
989 if (txt.Fill !=
null)
991 destinationGraphics.
FillPath(textPath, txt.Fill, txt.Tag);
993 else if (txt.Stroke !=
null)
995 destinationGraphics.
StrokePath(textPath, txt.Stroke, txt.LineWidth, txt.LineCap, txt.LineJoin, txt.LineDash, txt.Tag);
998 else if (this.Actions[i] is TransformAction)
1000 TransformAction trf = this.Actions[i] as TransformAction;
1002 if (trf.Delta !=
null)
1004 currMatrix = Multiply(currMatrix, TranslationMatrix(trf.Delta.Value.X, trf.Delta.Value.Y));
1006 else if (trf.Angle !=
null)
1008 currMatrix = Multiply(currMatrix, RotationMatrix(trf.Angle.Value));
1010 else if (trf.Scale !=
null)
1012 currMatrix = Multiply(currMatrix, ScaleMatrix(trf.Scale.Value.Width, trf.Scale.Value.Height));
1014 else if (trf.Matrix !=
null)
1016 currMatrix = Multiply(currMatrix, trf.Matrix);
1019 else if (this.Actions[i] is StateAction)
1021 if (((StateAction)this.Actions[i]).StateActionType == StateAction.StateActionTypes.Save)
1023 transformMatrix.Push(currMatrix);
1027 currMatrix = transformMatrix.Pop();
1030 else if (this.Actions[i] is RasterImageAction)
1032 RasterImageAction img = this.Actions[i] as RasterImageAction;
1036 Point pt1 = transformationFunction(Multiply(currMatrix,
new Point(img.DestinationX, img.DestinationY)));
1037 Point pt2 = transformationFunction(Multiply(currMatrix,
new Point(img.DestinationX + img.DestinationWidth, img.DestinationY)));
1038 Point pt3 = transformationFunction(Multiply(currMatrix,
new Point(img.DestinationX + img.DestinationWidth, img.DestinationY + img.DestinationHeight)));
1039 Point pt4 = transformationFunction(Multiply(currMatrix,
new Point(img.DestinationX, img.DestinationY + img.DestinationHeight)));
1047 return destinationGraphics;
1055 double maxLengthSq = maxLength * maxLength;
1062 if (seg is MoveSegment mov)
1064 shortLinearisedPath.
MoveTo(mov.Point);
1065 startFigurePoint = mov.
Point;
1066 currPoint = mov.
Point;
1068 else if (seg is LineSegment line)
1070 double lengthSq = (line.Point.X - currPoint.
X) * (line.Point.X - currPoint.
X) +
1071 (line.Point.Y - currPoint.
Y) * (line.Point.Y - currPoint.
Y);
1073 if (lengthSq < maxLengthSq)
1075 shortLinearisedPath.
LineTo(line.Point);
1079 int segmentCount = (int)Math.Ceiling(Math.Sqrt(lengthSq / maxLengthSq));
1081 for (
int j = 0; j < segmentCount - 1; j++)
1083 Point endPoint =
new Point(currPoint.
X + (line.Point.X - currPoint.
X) * (j + 1) / segmentCount,
1084 currPoint.
Y + (line.Point.Y - currPoint.
Y) * (j + 1) / segmentCount);
1085 shortLinearisedPath.
LineTo(endPoint);
1088 shortLinearisedPath.
LineTo(line.Point);
1090 currPoint = line.
Point;
1092 else if (seg is CloseSegment close)
1094 double lengthSq = (startFigurePoint.
X - currPoint.
X) * (startFigurePoint.
X - currPoint.
X) +
1095 (startFigurePoint.
Y - currPoint.
Y) * (startFigurePoint.
Y - currPoint.
Y);
1097 if (lengthSq < maxLengthSq)
1099 shortLinearisedPath.
Close();
1103 int segmentCount = (int)Math.Ceiling(Math.Sqrt(lengthSq / maxLengthSq));
1105 for (
int j = 0; j < segmentCount - 1; j++)
1107 Point endPoint =
new Point(currPoint.
X + (startFigurePoint.
X - currPoint.
X) * (j + 1) / segmentCount,
1108 currPoint.
Y + (startFigurePoint.
Y - currPoint.
Y) * (j + 1) / segmentCount);
1109 shortLinearisedPath.
LineTo(endPoint);
1112 shortLinearisedPath.
Close();
1114 currPoint = startFigurePoint;
1118 return shortLinearisedPath;
1128 public Graphics Transform(Func<Point, Point> transformationFunction,
double linearisationResolution,
double maxSegmentLength)
1132 Stack<double[,]> transformMatrix =
new Stack<double[,]>();
1133 double[,] currMatrix =
new double[3, 3] { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 } };
1135 for (
int i = 0; i < this.Actions.Count; i++)
1137 if (this.Actions[i] is RectangleAction)
1139 RectangleAction rec = this.Actions[i] as RectangleAction;
1143 Point pt1 = rec.TopLeft;
1144 Point pt2 =
new Point(rec.TopLeft.X + rec.Size.Width, rec.TopLeft.Y);
1145 Point pt3 =
new Point(rec.TopLeft.X + rec.Size.Width, rec.TopLeft.Y + rec.Size.Height);
1146 Point pt4 =
new Point(rec.TopLeft.X, rec.TopLeft.Y + rec.Size.Height);
1150 rectanglePath = ReduceMaximumLength(rectanglePath, maxSegmentLength).
Transform(pt => transformationFunction(Multiply(currMatrix, pt)));
1152 if (rec.Fill !=
null)
1154 destinationGraphics.
FillPath(rectanglePath, rec.Fill, rec.Tag);
1156 else if (rec.Stroke !=
null)
1158 destinationGraphics.
StrokePath(rectanglePath, rec.Stroke, rec.LineWidth, rec.LineCap, rec.LineJoin, rec.LineDash, rec.Tag);
1161 else if (this.Actions[i] is PathAction)
1163 PathAction pth = this.Actions[i] as PathAction;
1165 GraphicsPath newPath = ReduceMaximumLength(pth.Path.Linearise(linearisationResolution), maxSegmentLength).
Transform(pt => transformationFunction(Multiply(currMatrix, pt)));
1173 if (pth.Fill !=
null)
1175 destinationGraphics.
FillPath(newPath, pth.Fill, pth.Tag);
1177 else if (pth.Stroke !=
null)
1179 destinationGraphics.
StrokePath(newPath, pth.Stroke, pth.LineWidth, pth.LineCap, pth.LineJoin, pth.LineDash, pth.Tag);
1183 else if (this.Actions[i] is TextAction)
1185 TextAction txt = this.Actions[i] as TextAction;
1187 GraphicsPath textPath = ReduceMaximumLength(
new GraphicsPath().AddText(txt.Origin, txt.Text, txt.Font, txt.TextBaseline).
Linearise(linearisationResolution), maxSegmentLength).
Transform(pt => transformationFunction(Multiply(currMatrix, pt)));
1189 if (txt.Fill !=
null)
1191 destinationGraphics.
FillPath(textPath, txt.Fill, txt.Tag);
1193 else if (txt.Stroke !=
null)
1195 destinationGraphics.
StrokePath(textPath, txt.Stroke, txt.LineWidth, txt.LineCap, txt.LineJoin, txt.LineDash, txt.Tag);
1198 else if (this.Actions[i] is TransformAction)
1200 TransformAction trf = this.Actions[i] as TransformAction;
1202 if (trf.Delta !=
null)
1204 currMatrix = Multiply(currMatrix, TranslationMatrix(trf.Delta.Value.X, trf.Delta.Value.Y));
1206 else if (trf.Angle !=
null)
1208 currMatrix = Multiply(currMatrix, RotationMatrix(trf.Angle.Value));
1210 else if (trf.Scale !=
null)
1212 currMatrix = Multiply(currMatrix, ScaleMatrix(trf.Scale.Value.Width, trf.Scale.Value.Height));
1214 else if (trf.Matrix !=
null)
1216 currMatrix = Multiply(currMatrix, trf.Matrix);
1219 else if (this.Actions[i] is StateAction)
1221 if (((StateAction)this.Actions[i]).StateActionType == StateAction.StateActionTypes.Save)
1223 transformMatrix.Push(currMatrix);
1227 currMatrix = transformMatrix.Pop();
1230 else if (this.Actions[i] is RasterImageAction)
1232 RasterImageAction img = this.Actions[i] as RasterImageAction;
1236 Point pt1 =
new Point(img.DestinationX, img.DestinationY);
1237 Point pt2 =
new Point(img.DestinationX + img.DestinationWidth, img.DestinationY);
1238 Point pt3 =
new Point(img.DestinationX + img.DestinationWidth, img.DestinationY + img.DestinationHeight);
1239 Point pt4 =
new Point(img.DestinationX, img.DestinationY + img.DestinationHeight);
1243 rectanglePath = ReduceMaximumLength(rectanglePath, maxSegmentLength).
Transform(pt => transformationFunction(Multiply(currMatrix, pt)));
1249 return destinationGraphics;
1261 for (
int i = 0; i < this.Actions.Count; i++)
1263 if (this.Actions[i] is RectangleAction || this.Actions[i] is TransformAction || this.Actions[i] is StateAction || this.Actions[i] is RasterImageAction)
1265 destinationGraphics.Actions.Add(this.Actions[i]);
1267 else if (this.Actions[i] is PathAction)
1269 PathAction pth = this.Actions[i] as PathAction;
1279 if (pth.Fill !=
null)
1281 destinationGraphics.
FillPath(newPath, pth.Fill, pth.Tag);
1283 else if (pth.Stroke !=
null)
1285 destinationGraphics.
StrokePath(newPath, pth.Stroke, pth.LineWidth, pth.LineCap, pth.LineJoin, pth.LineDash, pth.Tag);
1289 else if (this.Actions[i] is TextAction)
1291 TextAction txt = this.Actions[i] as TextAction;
1295 if (txt.Fill !=
null)
1297 destinationGraphics.
FillPath(textPath, txt.Fill, txt.Tag);
1299 else if (txt.Stroke !=
null)
1301 destinationGraphics.
StrokePath(textPath, txt.Stroke, txt.LineWidth, txt.LineCap, txt.LineJoin, txt.LineDash, txt.Tag);
1306 return destinationGraphics;
1316 bool initialised =
false;
1318 Stack<double[,]> transformMatrix =
new Stack<double[,]>();
1319 double[,] currMatrix =
new double[3, 3] { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 } };
1321 for (
int i = 0; i < this.Actions.Count; i++)
1323 if (this.Actions[i] is IPrintableAction act)
1327 double lineThickness =
double.IsNaN(act.LineWidth) ? 0 : act.LineWidth;
1349 else if (this.Actions[i] is TransformAction)
1351 TransformAction trf = this.Actions[i] as TransformAction;
1353 if (trf.Delta !=
null)
1355 currMatrix = Multiply(currMatrix, TranslationMatrix(trf.Delta.Value.X, trf.Delta.Value.Y));
1357 else if (trf.Angle !=
null)
1359 currMatrix = Multiply(currMatrix, RotationMatrix(trf.Angle.Value));
1361 else if (trf.Scale !=
null)
1363 currMatrix = Multiply(currMatrix, ScaleMatrix(trf.Scale.Value.Width, trf.Scale.Value.Height));
1365 else if (trf.Matrix !=
null)
1367 currMatrix = Multiply(currMatrix, trf.Matrix);
1370 else if (this.Actions[i] is StateAction)
1372 if (((StateAction)this.Actions[i]).StateActionType == StateAction.StateActionTypes.Save)
1374 transformMatrix.Push(currMatrix);
1378 currMatrix = transformMatrix.Pop();
1413 System.Reflection.Assembly raster;
1417 raster = System.Reflection.Assembly.Load(
"VectSharp.Raster");
1420 System.Reflection.MethodInfo rasteriser = raster.GetType(
"VectSharp.Raster.Raster").GetMethod(
"Rasterise", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);
1421 output = (
RasterImage)rasteriser.Invoke(
null,
new object[] {
this, region, scale, interpolate });
1429 raster = System.Reflection.Assembly.Load(
"VectSharp.Raster.ImageSharp");
1432 System.Reflection.MethodInfo rasteriser = raster.GetType(
"VectSharp.Raster.ImageSharp.ImageSharpContextInterpreter").GetMethod(
"Rasterise", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);
1433 output = (
RasterImage)rasteriser.Invoke(
null,
new object[] {
this, region, scale, interpolate });