Rewrites the bezier rendering of the svg output of fpvectorial

git-svn-id: trunk@15930 -
This commit is contained in:
sekelsenmat 2010-09-01 08:57:54 +00:00
parent 7cd0630129
commit 3f26a9795b

View File

@ -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);