mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-10-01 01:59:58 +02:00
Fixes the svg coordinates and svg path generation
git-svn-id: trunk@15915 -
This commit is contained in:
parent
4cb34b50f3
commit
51f23db4bd
@ -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);
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user