Fixes the svg coordinates and svg path generation

git-svn-id: trunk@15915 -
This commit is contained in:
sekelsenmat 2010-08-28 11:52:03 +00:00
parent 4cb34b50f3
commit 51f23db4bd
2 changed files with 60 additions and 11 deletions

View File

@ -29,23 +29,43 @@ const
cExtension = '.svg';
var
Vec: TvVectorialDocument;
{$R *.res}
begin
Vec := TvVectorialDocument.Create;
try
// All documents are 10cm x 10cm
Vec.Width := 100;
Vec.Height := 100;
// single_line_1 One line from (0, 20) to (30, 30)
Vec.StartPath(0, 20);
Vec.AddLineToPath(30, 30);
Vec.EndPath();
Vec.WriteToFile('single_line_1' + cExtension, cFormat);
// single_line_2 One line from (20, 30) to (30, 20)
// single_line_2 One line from (20, 30) to (30, 20)
Vec.Clear;
Vec.StartPath(20, 30);
Vec.AddLineToPath(30, 20);
Vec.EndPath();
Vec.WriteToFile('single_line_2' + cExtension, cFormat);
// polyline_1 One line from (0, 0) to (10, 10) to (20, 30) to (30, 20)
// single_line_3 One line from (0, 20) to (30, 30) + frame
Vec.Clear;
Vec.StartPath(0, 20);
Vec.AddLineToPath(30, 30);
Vec.EndPath();
Vec.StartPath(0, 0);
Vec.AddLineToPath(100, 0);
Vec.AddLineToPath(100, 100);
Vec.AddLineToPath(0, 100);
Vec.AddLineToPath(0, 0);
Vec.EndPath();
Vec.WriteToFile('single_line_3' + cExtension, cFormat);
// polyline_1 One line from (0, 0) to (10, 10) to (20, 30) to (30, 20)
Vec.Clear;
Vec.StartPath(0, 0);
Vec.AddLineToPath(10, 10);

View File

@ -25,6 +25,9 @@ type
procedure WriteDocumentSize(AStrings: TStrings; AData: TvVectorialDocument);
procedure WriteDocumentName(AStrings: TStrings; AData: TvVectorialDocument);
procedure WritePaths(AStrings: TStrings; AData: TvVectorialDocument);
procedure ConvertFPVCoordinatesToSVGCoordinates(
const AData: TvVectorialDocument;
const ASrcX, ASrcY: Double; var ADestX, ADestY: double);
public
{ General reading methods }
procedure WriteToStrings(AStrings: TStrings; AData: TvVectorialDocument); override;
@ -32,6 +35,9 @@ type
implementation
const
FLOAT_MILIMETERS_PER_PIXEL = 0.3528;
{ TvSVGVectorialWriter }
procedure TvSVGVectorialWriter.WriteDocumentSize(AStrings: TStrings; AData: TvVectorialDocument);
@ -46,11 +52,15 @@ begin
end;
{@@
SVG Coordinate system measures things in whatever unit we pass to it, so we
choose to pass in millimiters (mm), like FPVectorial uses.
SVG Coordinate system measures things only in pixels, so that we have to
hardcode a DPI value for the screen, which is usually 72.
FPVectorial uses only milimeters (mm).
The initial point is in the bottom-left corner of the document and it grows
to the top and to the right, just like in FPVectorial.
The initial point in FPVectorial is in the bottom-left corner of the document
and it grows to the top and to the right. In SVG, on the other hand, the
initial point is in the top-left corner, growing to the bottom and right.
Besides that, coordinates in SVG are also lengths in comparison to the
previous point and not absolute coordinates.
SVG uses commas "," to separate the X,Y coordinates, so it always uses points
"." as decimal separators and uses no thousand separators
@ -60,20 +70,31 @@ var
i, j: Integer;
PathStr: string;
lPath: TPath;
PtX, PtY: double;
PtX, PtY, OldPtX, OldPtY: double;
begin
for i := 0 to AData.GetPathCount() - 1 do
begin
OldPtX := 0;
OldPtY := 0;
PathStr := 'm ';
lPath := AData.GetPath(i);
for j := 0 to lPath.Len - 1 do
begin
if lPath.Points[j].SegmentType <> st2DLine then Break; // unsupported line type
PtX := lPath.Points[j].X;
PtY := lPath.Points[j].Y;
PathStr := PathStr + FloatToStr(PtX, FPointSeparator) + 'mm,'
+ FloatToStr(PtY, FPointSeparator) + 'mm ';
// Coordinate conversion from fpvectorial to SVG
ConvertFPVCoordinatesToSVGCoordinates(
AData, lPath.Points[j].X, lPath.Points[j].Y, PtX, PtY);
PtX := PtX - OldPtX;
PtY := PtY - OldPtY;
PathStr := PathStr + FloatToStr(PtX, FPointSeparator) + ','
+ FloatToStr(PtY, FPointSeparator) + ' ';
// Store the current position for future points
OldPtX := OldPtX + PtX;
OldPtY := OldPtY + PtY;
end;
AStrings.Add(' <path');
@ -83,6 +104,14 @@ begin
end;
end;
procedure TvSVGVectorialWriter.ConvertFPVCoordinatesToSVGCoordinates(
const AData: TvVectorialDocument; const ASrcX, ASrcY: Double; var ADestX,
ADestY: double);
begin
ADestX := ASrcX / FLOAT_MILIMETERS_PER_PIXEL;
ADestY := (AData.Height - ASrcY) / FLOAT_MILIMETERS_PER_PIXEL;
end;
procedure TvSVGVectorialWriter.WriteToStrings(AStrings: TStrings;
AData: TvVectorialDocument);
begin