mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-09 22:09:25 +02:00
Rewrites the bezier rendering of the svg output of fpvectorial
git-svn-id: trunk@15930 -
This commit is contained in:
parent
7cd0630129
commit
3f26a9795b
@ -25,7 +25,6 @@ type
|
||||
procedure WriteDocumentName(AStrings: TStrings; AData: TvVectorialDocument);
|
||||
procedure WritePaths(AStrings: TStrings; AData: TvVectorialDocument);
|
||||
procedure WriteTexts(AStrings: TStrings; AData: TvVectorialDocument);
|
||||
procedure WriteBeziers(AStrings: TStrings; AData: TvVectorialDocument);
|
||||
procedure ConvertFPVCoordinatesToSVGCoordinates(
|
||||
const AData: TvVectorialDocument;
|
||||
const ASrcX, ASrcY: Double; var ADestX, ADestY: double);
|
||||
@ -44,7 +43,9 @@ const
|
||||
// 1 Inch = 25.4 milimiters
|
||||
// 90 inches per pixel = (1 / 90) * 25.4 = 0.2822
|
||||
// FLOAT_MILIMETERS_PER_PIXEL = 0.3528; // DPI 72 = 1 / 72 inches per pixel
|
||||
|
||||
FLOAT_MILIMETERS_PER_PIXEL = 0.2822; // DPI 90 = 1 / 90 inches per pixel
|
||||
FLOAT_PIXELS_PER_MILIMETER = 3.5433; // DPI 90 = 1 / 90 inches per pixel
|
||||
|
||||
{ TvSVGVectorialWriter }
|
||||
|
||||
@ -79,18 +80,20 @@ var
|
||||
PathStr: string;
|
||||
lPath: TPath;
|
||||
PtX, PtY, OldPtX, OldPtY: double;
|
||||
BezierCP1X, BezierCP1Y, BezierCP2X, BezierCP2Y: double;
|
||||
begin
|
||||
for i := 0 to AData.GetPathCount() - 1 do
|
||||
begin
|
||||
OldPtX := 0;
|
||||
OldPtY := 0;
|
||||
|
||||
PathStr := 'm ';
|
||||
PathStr := '';
|
||||
lPath := AData.GetPath(i);
|
||||
for j := 0 to lPath.Len - 1 do
|
||||
begin
|
||||
if (lPath.Points[j].SegmentType <> st2DLine)
|
||||
and (lPath.Points[j].SegmentType <> stMoveTo)
|
||||
and (lPath.Points[j].SegmentType <> st2DBezier)
|
||||
then Break; // unsupported line type
|
||||
|
||||
// Coordinate conversion from fpvectorial to SVG
|
||||
@ -99,8 +102,44 @@ begin
|
||||
PtX := PtX - OldPtX;
|
||||
PtY := PtY - OldPtY;
|
||||
|
||||
PathStr := PathStr + FloatToStr(PtX, FPointSeparator) + ','
|
||||
+ FloatToStr(PtY, FPointSeparator) + ' ';
|
||||
if (lPath.Points[j].SegmentType = stMoveTo) then
|
||||
begin
|
||||
PathStr := PathStr + 'm '
|
||||
+ FloatToStr(PtX, FPointSeparator) + ','
|
||||
+ FloatToStr(PtY, FPointSeparator) + ' ';
|
||||
end
|
||||
else if (lPath.Points[j].SegmentType = st2DLine) then
|
||||
begin
|
||||
PathStr := PathStr + 'l '
|
||||
+ FloatToStr(PtX, FPointSeparator) + ','
|
||||
+ FloatToStr(PtY, FPointSeparator) + ' ';
|
||||
end
|
||||
else if (lPath.Points[j].SegmentType = st2DBezier) then
|
||||
begin
|
||||
// Converts all coordinates to absolute values
|
||||
ConvertFPVCoordinatesToSVGCoordinates(
|
||||
AData, lPath.Points[j].X2, lPath.Points[j].Y2, BezierCP1X, BezierCP1X);
|
||||
ConvertFPVCoordinatesToSVGCoordinates(
|
||||
AData, lPath.Points[j].X3, lPath.Points[j].Y3, BezierCP2X, BezierCP2Y);
|
||||
|
||||
// Transforms them into values relative to the initial point
|
||||
BezierCP1X := BezierCP1X - OldPtX;
|
||||
BezierCP1Y := BezierCP1Y - OldPtY;
|
||||
BezierCP2X := BezierCP2X - OldPtX;
|
||||
BezierCP2Y := BezierCP2Y - OldPtY;
|
||||
|
||||
// PtX and PtY already contains the destination point
|
||||
|
||||
// Now render our 2D cubic bezier
|
||||
PathStr := PathStr + 'c '
|
||||
+ FloatToStr(BezierCP1X, FPointSeparator) + ','
|
||||
+ FloatToStr(BezierCP1Y, FPointSeparator) + ' '
|
||||
+ FloatToStr(BezierCP2X, FPointSeparator) + ','
|
||||
+ FloatToStr(BezierCP2Y, FPointSeparator) + ' '
|
||||
+ FloatToStr(PtX, FPointSeparator) + ','
|
||||
+ FloatToStr(PtY, FPointSeparator) + ' '
|
||||
;
|
||||
end;
|
||||
|
||||
// Store the current position for future points
|
||||
OldPtX := OldPtX + PtX;
|
||||
@ -153,7 +192,6 @@ begin
|
||||
AStrings.Add(' <g id="layer1">');
|
||||
WritePaths(AStrings, AData);
|
||||
WriteTexts(AStrings, AData);
|
||||
WriteBeziers(AStrings, AData);
|
||||
AStrings.Add(' </g>');
|
||||
|
||||
// finalization
|
||||
@ -192,86 +230,6 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TvSVGVectorialWriter.WriteBeziers(AStrings: TStrings; AData: TvVectorialDocument);
|
||||
var
|
||||
i, j: Integer;
|
||||
PathStr: string;
|
||||
lPath: TPath;
|
||||
PtX, PtY, OldPtX, OldPtY, PtX2, PtY2, OldPtX2, OldPtY2,
|
||||
PtX3, PtY3, OldPtX3, OldPtY3: double;
|
||||
BezierType: TSegmentType;
|
||||
begin
|
||||
for i := 0 to AData.GetPathCount() - 1 do
|
||||
begin
|
||||
OldPtX := 0;
|
||||
OldPtY := 0;
|
||||
OldPtX2 := 0;
|
||||
OldPtY2 := 0;
|
||||
OldPtX3 := 0;
|
||||
OldPtY3 := 0;
|
||||
|
||||
PathStr := 'm ';
|
||||
lPath := AData.GetPath(i);
|
||||
for j := 0 to lPath.Len - 1 do
|
||||
begin
|
||||
BezierType := lPath.Points[j].SegmentType;
|
||||
if j>0 then
|
||||
if (BezierType <> st2DBezier) and (BezierType <> stMoveTo)
|
||||
and (BezierType <> st2DLine)
|
||||
then Break; // unsupported Bezier type
|
||||
|
||||
if (BezierType = st2DBezier) or (BezierType = stMoveTo) then
|
||||
begin
|
||||
ConvertFPVCoordinatesToSVGCoordinates(
|
||||
AData, lPath.Points[j].X, lPath.Points[j].Y, PtX, PtY);
|
||||
ConvertFPVCoordinatesToSVGCoordinates(
|
||||
AData, lPath.Points[j].X2, lPath.Points[j].Y2, PtX2, PtY2);
|
||||
ConvertFPVCoordinatesToSVGCoordinates(
|
||||
AData, lPath.Points[j].X3, lPath.Points[j].Y3, PtX3, PtY3);
|
||||
|
||||
PtX := PtX - OldPtX;
|
||||
PtY := PtY - OldPtY;
|
||||
PtX2 := PtX2 - OldPtX2;
|
||||
PtY2 := PtY2 - OldPtY2;
|
||||
PtX3 := PtX3 - OldPtX3;
|
||||
PtY3 := PtY3 - OldPtY3;
|
||||
|
||||
if j = 0 then
|
||||
PathStr := PathStr + FloatToStr(PtX, FPointSeparator) + ','
|
||||
+ FloatToStr(PtY, FPointSeparator) + ' ';
|
||||
|
||||
if j = 0 then
|
||||
begin
|
||||
PathStr := PathStr + 'q';
|
||||
// if BezierType = st3DBezier then
|
||||
// PathStr := PathStr + 'c';
|
||||
end;
|
||||
|
||||
if j > 0 then
|
||||
PathStr := PathStr + FloatToStr(PtX, FPointSeparator) + ','
|
||||
+ FloatToStr(PtY, FPointSeparator) + ' '
|
||||
+ FloatToStr(PtX2, FPointSeparator) + ','
|
||||
+ FloatToStr(PtY2, FPointSeparator) + ' '
|
||||
+ FloatToStr(PtX3, FPointSeparator) + ','
|
||||
+ FloatToStr(PtY3, FPointSeparator) + ' ';
|
||||
|
||||
// Store the current position for future points
|
||||
OldPtX := OldPtX + PtX;
|
||||
OldPtY := OldPtY + PtY;
|
||||
OldPtX2 := OldPtX2 + PtX2;
|
||||
OldPtY2 := OldPtY2 + PtY2;
|
||||
OldPtX3 := OldPtX3 + PtX3;
|
||||
OldPtY3 := OldPtY3 + PtY3;
|
||||
end;
|
||||
end;
|
||||
|
||||
AStrings.Add(' <path');
|
||||
AStrings.Add(' style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"');
|
||||
AStrings.Add(' d="' + PathStr + '"');
|
||||
AStrings.Add(' id="Bezier' + IntToStr(i) + '" />');
|
||||
end;
|
||||
end;
|
||||
|
||||
initialization
|
||||
|
||||
RegisterVectorialWriter(TvSVGVectorialWriter, vfSVG);
|
||||
|
Loading…
Reference in New Issue
Block a user