{ 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(' '); 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(''); AStrings.Add(''); AStrings.Add(''); AStrings.Add(''); WritePaths(AStrings, AData); AStrings.Add(' '); // finalization AStrings.Add(''); end; initialization RegisterVectorialWriter(TvSVGVectorialWriter, vfSVG); end.