mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-14 23:29:12 +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 WriteDocumentName(AStrings: TStrings; AData: TvVectorialDocument);
|
||||||
procedure WritePaths(AStrings: TStrings; AData: TvVectorialDocument);
|
procedure WritePaths(AStrings: TStrings; AData: TvVectorialDocument);
|
||||||
procedure WriteTexts(AStrings: TStrings; AData: TvVectorialDocument);
|
procedure WriteTexts(AStrings: TStrings; AData: TvVectorialDocument);
|
||||||
procedure WriteBeziers(AStrings: TStrings; AData: TvVectorialDocument);
|
|
||||||
procedure ConvertFPVCoordinatesToSVGCoordinates(
|
procedure ConvertFPVCoordinatesToSVGCoordinates(
|
||||||
const AData: TvVectorialDocument;
|
const AData: TvVectorialDocument;
|
||||||
const ASrcX, ASrcY: Double; var ADestX, ADestY: double);
|
const ASrcX, ASrcY: Double; var ADestX, ADestY: double);
|
||||||
@ -44,7 +43,9 @@ const
|
|||||||
// 1 Inch = 25.4 milimiters
|
// 1 Inch = 25.4 milimiters
|
||||||
// 90 inches per pixel = (1 / 90) * 25.4 = 0.2822
|
// 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.3528; // DPI 72 = 1 / 72 inches per pixel
|
||||||
|
|
||||||
FLOAT_MILIMETERS_PER_PIXEL = 0.2822; // DPI 90 = 1 / 90 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 }
|
{ TvSVGVectorialWriter }
|
||||||
|
|
||||||
@ -79,18 +80,20 @@ var
|
|||||||
PathStr: string;
|
PathStr: string;
|
||||||
lPath: TPath;
|
lPath: TPath;
|
||||||
PtX, PtY, OldPtX, OldPtY: double;
|
PtX, PtY, OldPtX, OldPtY: double;
|
||||||
|
BezierCP1X, BezierCP1Y, BezierCP2X, BezierCP2Y: double;
|
||||||
begin
|
begin
|
||||||
for i := 0 to AData.GetPathCount() - 1 do
|
for i := 0 to AData.GetPathCount() - 1 do
|
||||||
begin
|
begin
|
||||||
OldPtX := 0;
|
OldPtX := 0;
|
||||||
OldPtY := 0;
|
OldPtY := 0;
|
||||||
|
|
||||||
PathStr := 'm ';
|
PathStr := '';
|
||||||
lPath := AData.GetPath(i);
|
lPath := AData.GetPath(i);
|
||||||
for j := 0 to lPath.Len - 1 do
|
for j := 0 to lPath.Len - 1 do
|
||||||
begin
|
begin
|
||||||
if (lPath.Points[j].SegmentType <> st2DLine)
|
if (lPath.Points[j].SegmentType <> st2DLine)
|
||||||
and (lPath.Points[j].SegmentType <> stMoveTo)
|
and (lPath.Points[j].SegmentType <> stMoveTo)
|
||||||
|
and (lPath.Points[j].SegmentType <> st2DBezier)
|
||||||
then Break; // unsupported line type
|
then Break; // unsupported line type
|
||||||
|
|
||||||
// Coordinate conversion from fpvectorial to SVG
|
// Coordinate conversion from fpvectorial to SVG
|
||||||
@ -99,8 +102,44 @@ begin
|
|||||||
PtX := PtX - OldPtX;
|
PtX := PtX - OldPtX;
|
||||||
PtY := PtY - OldPtY;
|
PtY := PtY - OldPtY;
|
||||||
|
|
||||||
PathStr := PathStr + FloatToStr(PtX, FPointSeparator) + ','
|
if (lPath.Points[j].SegmentType = stMoveTo) then
|
||||||
+ FloatToStr(PtY, FPointSeparator) + ' ';
|
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
|
// Store the current position for future points
|
||||||
OldPtX := OldPtX + PtX;
|
OldPtX := OldPtX + PtX;
|
||||||
@ -153,7 +192,6 @@ begin
|
|||||||
AStrings.Add(' <g id="layer1">');
|
AStrings.Add(' <g id="layer1">');
|
||||||
WritePaths(AStrings, AData);
|
WritePaths(AStrings, AData);
|
||||||
WriteTexts(AStrings, AData);
|
WriteTexts(AStrings, AData);
|
||||||
WriteBeziers(AStrings, AData);
|
|
||||||
AStrings.Add(' </g>');
|
AStrings.Add(' </g>');
|
||||||
|
|
||||||
// finalization
|
// finalization
|
||||||
@ -192,86 +230,6 @@ begin
|
|||||||
end;
|
end;
|
||||||
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
|
initialization
|
||||||
|
|
||||||
RegisterVectorialWriter(TvSVGVectorialWriter, vfSVG);
|
RegisterVectorialWriter(TvSVGVectorialWriter, vfSVG);
|
||||||
|
Loading…
Reference in New Issue
Block a user