mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-12-05 13:07:33 +01:00
128 lines
4.0 KiB
ObjectPascal
128 lines
4.0 KiB
ObjectPascal
{
|
|
Writes an SVG Document
|
|
|
|
License: The same modified LGPL as the Free Pascal RTL
|
|
See the file COPYING.modifiedLGPL for more details
|
|
|
|
AUTHORS: Felipe Monteiro de Carvalho
|
|
}
|
|
unit svgvectorialwriter;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils,
|
|
fpvectorial;
|
|
|
|
type
|
|
{ TvSVGVectorialWriter }
|
|
|
|
TvSVGVectorialWriter = class(TvCustomVectorialWriter)
|
|
private
|
|
FPointSeparator, FCommaSeparator: TFormatSettings;
|
|
procedure WriteDocumentSize(AStrings: TStrings; AData: TvVectorialDocument);
|
|
procedure WriteDocumentName(AStrings: TStrings; AData: TvVectorialDocument);
|
|
procedure WritePaths(AStrings: TStrings; AData: TvVectorialDocument);
|
|
public
|
|
{ General reading methods }
|
|
procedure WriteToStrings(AStrings: TStrings; AData: TvVectorialDocument); override;
|
|
end;
|
|
|
|
implementation
|
|
|
|
{ TvSVGVectorialWriter }
|
|
|
|
procedure TvSVGVectorialWriter.WriteDocumentSize(AStrings: TStrings; AData: TvVectorialDocument);
|
|
begin
|
|
AStrings.Add(' width="' + FloatToStr(AData.Width, FPointSeparator) + 'mm"');
|
|
AStrings.Add(' height="' + FloatToStr(AData.Height, FPointSeparator) + 'mm"');
|
|
end;
|
|
|
|
procedure TvSVGVectorialWriter.WriteDocumentName(AStrings: TStrings; AData: TvVectorialDocument);
|
|
begin
|
|
AStrings.Add(' sodipodi:docname="New document 1">');
|
|
end;
|
|
|
|
{@@
|
|
SVG Coordinate system measures things in whatever unit we pass to it, so we
|
|
choose to pass in millimiters (mm), like FPVectorial uses.
|
|
|
|
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.
|
|
|
|
SVG uses commas "," to separate the X,Y coordinates, so it always uses points
|
|
"." as decimal separators and uses no thousand separators
|
|
}
|
|
procedure TvSVGVectorialWriter.WritePaths(AStrings: TStrings; AData: TvVectorialDocument);
|
|
var
|
|
i, j: Integer;
|
|
PathStr: string;
|
|
lPath: TPath;
|
|
PtX, PtY: double;
|
|
begin
|
|
for i := 0 to AData.GetPathCount() - 1 do
|
|
begin
|
|
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 ';
|
|
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="path' + IntToStr(i) + '" />');
|
|
end;
|
|
end;
|
|
|
|
procedure TvSVGVectorialWriter.WriteToStrings(AStrings: TStrings;
|
|
AData: TvVectorialDocument);
|
|
begin
|
|
// Format seetings to convert a string to a float
|
|
FPointSeparator := DefaultFormatSettings;
|
|
FPointSeparator.DecimalSeparator := '.';
|
|
FPointSeparator.ThousandSeparator := '#';// disable the thousand separator
|
|
FCommaSeparator := DefaultFormatSettings;
|
|
FCommaSeparator.DecimalSeparator := ',';
|
|
FCommaSeparator.ThousandSeparator := '#';// disable the thousand separator
|
|
|
|
// Headers
|
|
AStrings.Add('<?xml version="1.0" encoding="UTF-8" standalone="no"?>');
|
|
AStrings.Add('<!-- Created with fpVectorial (http://wiki.lazarus.freepascal.org/fpvectorial) -->');
|
|
AStrings.Add('');
|
|
AStrings.Add('<svg');
|
|
AStrings.Add(' xmlns:dc="http://purl.org/dc/elements/1.1/"');
|
|
AStrings.Add(' xmlns:cc="http://creativecommons.org/ns#"');
|
|
AStrings.Add(' xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"');
|
|
AStrings.Add(' xmlns:svg="http://www.w3.org/2000/svg"');
|
|
AStrings.Add(' xmlns="http://www.w3.org/2000/svg"');
|
|
AStrings.Add(' xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"');
|
|
WriteDocumentSize(AStrings, AData);
|
|
AStrings.Add(' id="svg2"');
|
|
AStrings.Add(' version="1.1"');
|
|
WriteDocumentName(AStrings, AData);
|
|
|
|
// Now data
|
|
AStrings.Add(' <g id="layer1">');
|
|
WritePaths(AStrings, AData);
|
|
AStrings.Add(' </g>');
|
|
|
|
// finalization
|
|
AStrings.Add('</svg>');
|
|
end;
|
|
|
|
initialization
|
|
|
|
RegisterVectorialWriter(TvSVGVectorialWriter, vfSVG);
|
|
|
|
end.
|
|
|