Update PathGeometryConverter.cs
This commit is contained in:
Родитель
69007d4f3c
Коммит
5bb6949412
|
@ -1,7 +1,6 @@
|
|||
#nullable enable
|
||||
using System;
|
||||
using Core2D.Model.Path;
|
||||
using Core2D.ViewModels.Path;
|
||||
using Core2D.ViewModels.Path.Segments;
|
||||
using Core2D.ViewModels.Shapes;
|
||||
using PDF = PdfSharp.Drawing;
|
||||
|
@ -10,22 +9,93 @@ namespace Core2D.Modules.Renderer.PdfSharp;
|
|||
|
||||
public static class PathGeometryConverter
|
||||
{
|
||||
public static PDF.XGraphicsPath ToXGraphicsPath(this PathShapeViewModel pg, Func<double, double> scale)
|
||||
public static PDF.XGraphicsPath? ToXGraphicsPath(this PathShapeViewModel pathShape, Func<double, double> scale)
|
||||
{
|
||||
var gp = new PDF.XGraphicsPath()
|
||||
var graphicsPath = new PDF.XGraphicsPath
|
||||
{
|
||||
FillMode = pg.FillRule == FillRule.EvenOdd ? PDF.XFillMode.Alternate : PDF.XFillMode.Winding
|
||||
FillMode = pathShape.FillRule == FillRule.EvenOdd ? PDF.XFillMode.Alternate : PDF.XFillMode.Winding
|
||||
};
|
||||
|
||||
foreach (var pf in pg.Figures)
|
||||
foreach (var figure in pathShape.Figures)
|
||||
{
|
||||
var startPoint = pf.StartPoint;
|
||||
|
||||
foreach (var segment in pf.Segments)
|
||||
if (figure.StartPoint is null)
|
||||
{
|
||||
if (segment is ArcSegmentViewModel arcSegment)
|
||||
return null;
|
||||
}
|
||||
|
||||
var startPoint = figure.StartPoint;
|
||||
|
||||
foreach (var segment in figure.Segments)
|
||||
{
|
||||
switch (segment)
|
||||
{
|
||||
#if WPF
|
||||
case LineSegmentViewModel lineSegment:
|
||||
{
|
||||
if (lineSegment.Point is null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
graphicsPath.AddLine(
|
||||
scale(startPoint.X),
|
||||
scale(startPoint.Y),
|
||||
scale(lineSegment.Point.X),
|
||||
scale(lineSegment.Point.Y));
|
||||
startPoint = lineSegment.Point;
|
||||
break;
|
||||
}
|
||||
case CubicBezierSegmentViewModel cubicBezierSegment:
|
||||
{
|
||||
if (cubicBezierSegment.Point1 is null || cubicBezierSegment.Point2 is null || cubicBezierSegment.Point3 is null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
graphicsPath.AddBezier(
|
||||
scale(startPoint.X),
|
||||
scale(startPoint.Y),
|
||||
scale(cubicBezierSegment.Point1.X),
|
||||
scale(cubicBezierSegment.Point1.Y),
|
||||
scale(cubicBezierSegment.Point2.X),
|
||||
scale(cubicBezierSegment.Point2.Y),
|
||||
scale(cubicBezierSegment.Point3.X),
|
||||
scale(cubicBezierSegment.Point3.Y));
|
||||
startPoint = cubicBezierSegment.Point3;
|
||||
break;
|
||||
}
|
||||
case QuadraticBezierSegmentViewModel quadraticBezierSegment:
|
||||
{
|
||||
if (quadraticBezierSegment.Point1 is null || quadraticBezierSegment.Point2 is null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var p1 = startPoint;
|
||||
var p2 = quadraticBezierSegment.Point1;
|
||||
var p3 = quadraticBezierSegment.Point2;
|
||||
var x1 = p1.X;
|
||||
var y1 = p1.Y;
|
||||
var x2 = p1.X + (2.0 * (p2.X - p1.X)) / 3.0;
|
||||
var y2 = p1.Y + (2.0 * (p2.Y - p1.Y)) / 3.0;
|
||||
var x3 = x2 + (p3.X - p1.X) / 3.0;
|
||||
var y3 = y2 + (p3.Y - p1.Y) / 3.0;
|
||||
var x4 = p3.X;
|
||||
var y4 = p3.Y;
|
||||
graphicsPath.AddBezier(
|
||||
scale(x1),
|
||||
scale(y1),
|
||||
scale(x2),
|
||||
scale(y2),
|
||||
scale(x3),
|
||||
scale(y3),
|
||||
scale(x4),
|
||||
scale(y4));
|
||||
startPoint = quadraticBezierSegment.Point2;
|
||||
break;
|
||||
}
|
||||
case ArcSegmentViewModel arcSegment:
|
||||
{
|
||||
if (arcSegment.Point is null || arcSegment.Size is null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var point1 = new PDF.XPoint(
|
||||
scale(startPoint.X),
|
||||
scale(startPoint.Y));
|
||||
|
@ -35,80 +105,29 @@ public static class PathGeometryConverter
|
|||
var size = new PDF.XSize(
|
||||
scale(arcSegment.Size.Width),
|
||||
scale(arcSegment.Size.Height));
|
||||
gp.AddArc(
|
||||
graphicsPath.AddArc(
|
||||
point1,
|
||||
point2,
|
||||
size, arcSegment.RotationAngle, arcSegment.IsLargeArc,
|
||||
arcSegment.SweepDirection == SweepDirection.Clockwise ? PDF.XSweepDirection.Clockwise : PDF.XSweepDirection.Counterclockwise);
|
||||
startPoint = arcSegment.Point;
|
||||
#else
|
||||
// TODO: Convert WPF/SVG elliptical arc segment format to GDI+ bezier curves.
|
||||
startPoint = arcSegment.Point;
|
||||
#endif
|
||||
}
|
||||
else if (segment is CubicBezierSegmentViewModel cubicBezierSegment)
|
||||
{
|
||||
gp.AddBezier(
|
||||
scale(startPoint.X),
|
||||
scale(startPoint.Y),
|
||||
scale(cubicBezierSegment.Point1.X),
|
||||
scale(cubicBezierSegment.Point1.Y),
|
||||
scale(cubicBezierSegment.Point2.X),
|
||||
scale(cubicBezierSegment.Point2.Y),
|
||||
scale(cubicBezierSegment.Point3.X),
|
||||
scale(cubicBezierSegment.Point3.Y));
|
||||
startPoint = cubicBezierSegment.Point3;
|
||||
}
|
||||
else if (segment is LineSegmentViewModel)
|
||||
{
|
||||
var lineSegment = segment as LineSegmentViewModel;
|
||||
gp.AddLine(
|
||||
scale(startPoint.X),
|
||||
scale(startPoint.Y),
|
||||
scale(lineSegment.Point.X),
|
||||
scale(lineSegment.Point.Y));
|
||||
startPoint = lineSegment.Point;
|
||||
}
|
||||
else if (segment is QuadraticBezierSegmentViewModel quadraticBezierSegment)
|
||||
{
|
||||
var p1 = startPoint;
|
||||
var p2 = quadraticBezierSegment.Point1;
|
||||
var p3 = quadraticBezierSegment.Point2;
|
||||
double x1 = p1.X;
|
||||
double y1 = p1.Y;
|
||||
double x2 = p1.X + (2.0 * (p2.X - p1.X)) / 3.0;
|
||||
double y2 = p1.Y + (2.0 * (p2.Y - p1.Y)) / 3.0;
|
||||
double x3 = x2 + (p3.X - p1.X) / 3.0;
|
||||
double y3 = y2 + (p3.Y - p1.Y) / 3.0;
|
||||
double x4 = p3.X;
|
||||
double y4 = p3.Y;
|
||||
gp.AddBezier(
|
||||
scale(x1),
|
||||
scale(y1),
|
||||
scale(x2),
|
||||
scale(y2),
|
||||
scale(x3),
|
||||
scale(y3),
|
||||
scale(x4),
|
||||
scale(y4));
|
||||
startPoint = quadraticBezierSegment.Point2;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotSupportedException("Not supported segment type: " + segment.GetType());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new NotSupportedException("Not supported segment type: " + segment.GetType());
|
||||
}
|
||||
}
|
||||
|
||||
if (pf.IsClosed)
|
||||
if (figure.IsClosed)
|
||||
{
|
||||
gp.CloseFigure();
|
||||
graphicsPath.CloseFigure();
|
||||
}
|
||||
else
|
||||
{
|
||||
gp.StartFigure();
|
||||
graphicsPath.StartFigure();
|
||||
}
|
||||
}
|
||||
|
||||
return gp;
|
||||
return graphicsPath;
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче