Browse Source

fpvectorial: Merges the implementation of pen, brush and updates the svg output to use the pen

git-svn-id: trunk@17382 -
sekelsenmat 14 years ago
parent
commit
bca76120f6

+ 6 - 3
packages/fpvectorial/examples/fpvwritetest.lpi

@@ -13,7 +13,6 @@
       <Title Value="fpvwritetest"/>
       <Title Value="fpvwritetest"/>
       <ResourceType Value="res"/>
       <ResourceType Value="res"/>
       <UseXPManifest Value="True"/>
       <UseXPManifest Value="True"/>
-      <Icon Value="0"/>
     </General>
     </General>
     <i18n>
     <i18n>
       <EnableI18N LFM="False"/>
       <EnableI18N LFM="False"/>
@@ -21,6 +20,9 @@
     <VersionInfo>
     <VersionInfo>
       <StringTable ProductVersion=""/>
       <StringTable ProductVersion=""/>
     </VersionInfo>
     </VersionInfo>
+    <BuildModes Count="1">
+      <Item1 Name="default" Default="True"/>
+    </BuildModes>
     <PublishOptions>
     <PublishOptions>
       <Version Value="2"/>
       <Version Value="2"/>
       <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
       <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
@@ -29,6 +31,7 @@
     <RunParams>
     <RunParams>
       <local>
       <local>
         <FormatVersion Value="1"/>
         <FormatVersion Value="1"/>
+        <LaunchingApplication PathPlusParams="\usr\bin\xterm -T 'Lazarus Run Output' -e $(LazarusDir)\tools\runwait.sh $(TargetCmdLine)"/>
       </local>
       </local>
     </RunParams>
     </RunParams>
     <Units Count="1">
     <Units Count="1">
@@ -40,13 +43,13 @@
     </Units>
     </Units>
   </ProjectOptions>
   </ProjectOptions>
   <CompilerOptions>
   <CompilerOptions>
-    <Version Value="9"/>
+    <Version Value="10"/>
     <PathDelim Value="\"/>
     <PathDelim Value="\"/>
     <Target>
     <Target>
       <Filename Value="fpvwritetest"/>
       <Filename Value="fpvwritetest"/>
     </Target>
     </Target>
     <SearchPaths>
     <SearchPaths>
-      <IncludeFiles Value="$(ProjOutDir)\"/>
+      <IncludeFiles Value="$(ProjOutDir)"/>
       <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
       <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
     </SearchPaths>
     </SearchPaths>
     <Other>
     <Other>

+ 46 - 1
packages/fpvectorial/examples/fpvwritetest.pas

@@ -22,7 +22,7 @@ program fpvwritetest;
 {$mode objfpc}{$H+}
 {$mode objfpc}{$H+}
 
 
 uses
 uses
-  fpvectorial, svgvectorialwriter;
+  fpvectorial, svgvectorialwriter, fpvutils;
 
 
 const
 const
   cFormat = vfSVG;
   cFormat = vfSVG;
@@ -134,6 +134,51 @@ begin
     Vec.AddText(20, 20, 0, '20, 20 Mówić, cześć, Włosku, Parabéns.');
     Vec.AddText(20, 20, 0, '20, 20 Mówić, cześć, Włosku, Parabéns.');
     Vec.AddText(30, 30, 0, '30, 30 森林,是一个高密');
     Vec.AddText(30, 30, 0, '30, 30 森林,是一个高密');
     Vec.WriteToFile('multi_test_1' + cExtension, cFormat);
     Vec.WriteToFile('multi_test_1' + cExtension, cFormat);
+
+    // pen_test_1     Tests the properties of the Pen
+    Vec.Clear;
+    Vec.StartPath(0, 20);
+    Vec.AddLineToPath(30, 30);
+    Vec.SetPenWidth(10);
+    Vec.EndPath();
+    Vec.StartPath(0, 0);
+    Vec.AddLineToPath(100, 0);
+    Vec.AddLineToPath(100, 100);
+    Vec.AddLineToPath(0, 100);
+    Vec.AddLineToPath(0, 0);
+    Vec.SetPenWidth(10);
+    Vec.EndPath();
+    Vec.StartPath(0, 0);
+    Vec.AddLineToPath(10, 10);
+    Vec.AddBezierToPath(10, 20, 20, 20, 20, 10);
+    Vec.AddLineToPath(30, 0);
+    Vec.SetPenWidth(10);
+    Vec.EndPath();
+    Vec.WriteToFile('pen_test_1' + cExtension, cFormat);
+
+    // pen_test_2     Tests the properties of the Pen
+    Vec.Clear;
+    Vec.StartPath(0, 20);
+    Vec.AddLineToPath(30, 30);
+    Vec.SetPenWidth(10);
+    Vec.SetPenColor(RGBToVColor(255, 0, 0));
+    Vec.EndPath();
+    Vec.StartPath(0, 0);
+    Vec.AddLineToPath(100, 0);
+    Vec.AddLineToPath(100, 100);
+    Vec.AddLineToPath(0, 100);
+    Vec.AddLineToPath(0, 0);
+    Vec.SetPenWidth(10);
+    Vec.SetPenColor(RGBToVColor(0, 255, 0));
+    Vec.EndPath();
+    Vec.StartPath(0, 0);
+    Vec.AddLineToPath(10, 10);
+    Vec.AddBezierToPath(10, 20, 20, 20, 20, 10);
+    Vec.AddLineToPath(30, 0);
+    Vec.SetPenWidth(10);
+    Vec.SetPenColor(RGBToVColor(0, 0, 255));
+    Vec.EndPath();
+    Vec.WriteToFile('pen_test_2' + cExtension, cFormat);
   finally
   finally
     Vec.Free;
     Vec.Free;
   end;
   end;

+ 77 - 24
packages/fpvectorial/src/fpvectorial.pas

@@ -45,6 +45,17 @@ type
     Red, Green, Blue, Alpha: Byte;
     Red, Green, Blue, Alpha: Byte;
   end;
   end;
 
 
+  TvPen = record
+    Color: TvColor;
+    Style: TFPPenStyle;
+    Width: Integer;
+  end;
+
+  TvBrush = record
+    Color: TvColor;
+    Style: TFPBrushStyle;
+  end;
+
 const
 const
   FPValphaTransparent = $00;
   FPValphaTransparent = $00;
   FPValphaOpaque = $FF;
   FPValphaOpaque = $FF;
@@ -59,7 +70,7 @@ type
   P3DPoint = ^T3DPoint;
   P3DPoint = ^T3DPoint;
 
 
   TSegmentType = (
   TSegmentType = (
-    st2DLine, st2DBezier,
+    st2DLine, st2DLineWithPen, st2DBezier,
     st3DLine, st3DBezier, stMoveTo);
     st3DLine, st3DBezier, stMoveTo);
 
 
   {@@
   {@@
@@ -75,10 +86,6 @@ type
     // Fields for linking the list
     // Fields for linking the list
     Previous: TPathSegment;
     Previous: TPathSegment;
     Next: TPathSegment;
     Next: TPathSegment;
-    // Data fields
-    PenColor: TvColor;
-    PenStyle: TFPPenStyle;
-    PenWidth: Integer;
   end;
   end;
 
 
   {@@
   {@@
@@ -93,6 +100,11 @@ type
     X, Y: Double;
     X, Y: Double;
   end;
   end;
 
 
+  T2DSegmentWithPen = class(T2DSegment)
+  public
+    Pen: TvPen;
+  end;
+
   {@@
   {@@
     In Bezier segments, we remain using the X and Y coordinates for the ending point.
     In Bezier segments, we remain using the X and Y coordinates for the ending point.
     The starting point is where the previous segment ended, so that the intermediary
     The starting point is where the previous segment ended, so that the intermediary
@@ -124,6 +136,13 @@ type
     Points: TPathSegment; // Beginning of the double-linked list
     Points: TPathSegment; // Beginning of the double-linked list
     PointsEnd: TPathSegment; // End of the double-linked list
     PointsEnd: TPathSegment; // End of the double-linked list
     CurPoint: TPathSegment; // Used in PrepareForSequentialReading and Next
     CurPoint: TPathSegment; // Used in PrepareForSequentialReading and Next
+    {@@ The global Pen for the entire path. This Pen might be overriden by
+        individual elements of the polyline. }
+    Pen: TvPen;
+    {@@ Sets a Brush to paint the inner area inside the path.
+        There is no inner area if Brush.Style = bsClear, which is the default. }
+    Brush: TvBrush;
+    constructor Create();
     procedure Assign(APath: TPath);
     procedure Assign(APath: TPath);
     function Count(): TPathSegment;
     function Count(): TPathSegment;
     procedure PrepareForSequentialReading;
     procedure PrepareForSequentialReading;
@@ -139,23 +158,18 @@ type
   TvText = class
   TvText = class
   public
   public
     X, Y, Z: Double; // Z is ignored in 2D formats
     X, Y, Z: Double; // Z is ignored in 2D formats
+    Value: utf8string;
+    FontColor: TvColor;
     FontSize: integer;
     FontSize: integer;
     FontName: utf8string;
     FontName: utf8string;
-    Value: utf8string;
-    Color: TvColor;
   end;
   end;
 
 
   {@@
   {@@
   }
   }
   TvEntity = class
   TvEntity = class
   public
   public
-    // Pen
-    PenColor: TvColor;
-    PenStyle: TFPPenStyle;
-    PenWidth: Integer;
-    // Brush
-    BrushStyle: TFPBrushStyle;
-    BrushColor: TvColor;
+    Pen: TvPen;
+    Brush: TvBrush;
   end;
   end;
 
 
   {@@
   {@@
@@ -253,6 +267,11 @@ type
     procedure AddLineToPath(AX, AY, AZ: Double); overload;
     procedure AddLineToPath(AX, AY, AZ: Double); overload;
     procedure AddBezierToPath(AX1, AY1, AX2, AY2, AX3, AY3: Double); overload;
     procedure AddBezierToPath(AX1, AY1, AX2, AY2, AX3, AY3: Double); overload;
     procedure AddBezierToPath(AX1, AY1, AZ1, AX2, AY2, AZ2, AX3, AY3, AZ3: Double); overload;
     procedure AddBezierToPath(AX1, AY1, AZ1, AX2, AY2, AZ2, AX3, AY3, AZ3: Double); overload;
+    procedure SetBrushColor(AColor: TvColor);
+    procedure SetBrushStyle(AStyle: TFPBrushStyle);
+    procedure SetPenColor(AColor: TvColor);
+    procedure SetPenStyle(AStyle: TFPPenStyle);
+    procedure SetPenWidth(AWidth: Integer);
     procedure EndPath();
     procedure EndPath();
     procedure AddText(AX, AY, AZ: Double; FontName: string; FontSize: integer; AText: utf8string); overload;
     procedure AddText(AX, AY, AZ: Double; FontName: string; FontSize: integer; AText: utf8string); overload;
     procedure AddText(AX, AY, AZ: Double; AStr: utf8string); overload;
     procedure AddText(AX, AY, AZ: Double; AStr: utf8string); overload;
@@ -550,20 +569,19 @@ begin
   segment.SegmentType := st2DLine;
   segment.SegmentType := st2DLine;
   segment.X := AX;
   segment.X := AX;
   segment.Y := AY;
   segment.Y := AY;
-  segment.PenColor := clvBlack;
 
 
   AppendSegmentToTmpPath(segment);
   AppendSegmentToTmpPath(segment);
 end;
 end;
 
 
 procedure TvVectorialDocument.AddLineToPath(AX, AY: Double; AColor: TvColor);
 procedure TvVectorialDocument.AddLineToPath(AX, AY: Double; AColor: TvColor);
 var
 var
-  segment: T2DSegment;
+  segment: T2DSegmentWithPen;
 begin
 begin
-  segment := T2DSegment.Create;
-  segment.SegmentType := st2DLine;
+  segment := T2DSegmentWithPen.Create;
+  segment.SegmentType := st2DLineWithPen;
   segment.X := AX;
   segment.X := AX;
   segment.Y := AY;
   segment.Y := AY;
-  segment.PenColor := AColor;
+  segment.Pen.Color := AColor;
 
 
   AppendSegmentToTmpPath(segment);
   AppendSegmentToTmpPath(segment);
 end;
 end;
@@ -623,6 +641,31 @@ begin
   AppendSegmentToTmpPath(segment);
   AppendSegmentToTmpPath(segment);
 end;
 end;
 
 
+procedure TvVectorialDocument.SetBrushColor(AColor: TvColor);
+begin
+  FTmPPath.Brush.Color := AColor;
+end;
+
+procedure TvVectorialDocument.SetBrushStyle(AStyle: TFPBrushStyle);
+begin
+  FTmPPath.Brush.Style := AStyle;
+end;
+
+procedure TvVectorialDocument.SetPenColor(AColor: TvColor);
+begin
+  FTmPPath.Pen.Color := AColor;
+end;
+
+procedure TvVectorialDocument.SetPenStyle(AStyle: TFPPenStyle);
+begin
+  FTmPPath.Pen.Style := AStyle;
+end;
+
+procedure TvVectorialDocument.SetPenWidth(AWidth: Integer);
+begin
+  FTmPPath.Pen.Width := AWidth;
+end;
+
 {@@
 {@@
   Finishes writing a Path, which was created in multiple
   Finishes writing a Path, which was created in multiple
   steps using StartPath and AddPointToPath,
   steps using StartPath and AddPointToPath,
@@ -683,7 +726,7 @@ begin
   lCircularArc.Radius := ARadius;
   lCircularArc.Radius := ARadius;
   lCircularArc.StartAngle := AStartAngle;
   lCircularArc.StartAngle := AStartAngle;
   lCircularArc.EndAngle := AEndAngle;
   lCircularArc.EndAngle := AEndAngle;
-  lCircularArc.PenColor := AColor;
+  lCircularArc.Pen.Color := AColor;
   FEntities.Add(lCircularArc);
   FEntities.Add(lCircularArc);
 end;
 end;
 
 
@@ -728,12 +771,13 @@ begin
   for i := 0 to Length(GvVectorialFormats) - 1 do
   for i := 0 to Length(GvVectorialFormats) - 1 do
     if GvVectorialFormats[i].Format = AFormat then
     if GvVectorialFormats[i].Format = AFormat then
     begin
     begin
-      Result := GvVectorialFormats[i].WriterClass.Create;
+      if GvVectorialFormats[i].WriterClass <> nil then
+        Result := GvVectorialFormats[i].WriterClass.Create;
 
 
       Break;
       Break;
     end;
     end;
 
 
-  if Result = nil then raise Exception.Create('Unsuported vector graphics format.');
+  if Result = nil then raise Exception.Create('Unsupported vector graphics format.');
 end;
 end;
 
 
 {@@
 {@@
@@ -749,12 +793,13 @@ begin
   for i := 0 to Length(GvVectorialFormats) - 1 do
   for i := 0 to Length(GvVectorialFormats) - 1 do
     if GvVectorialFormats[i].Format = AFormat then
     if GvVectorialFormats[i].Format = AFormat then
     begin
     begin
-      Result := GvVectorialFormats[i].ReaderClass.Create;
+      if GvVectorialFormats[i].ReaderClass <> nil then
+        Result := GvVectorialFormats[i].ReaderClass.Create;
 
 
       Break;
       Break;
     end;
     end;
 
 
-  if Result = nil then raise Exception.Create('Unsuported vector graphics format.');
+  if Result = nil then raise Exception.Create('Unsupported vector graphics format.');
 end;
 end;
 
 
 procedure TvVectorialDocument.ClearTmpPath();
 procedure TvVectorialDocument.ClearTmpPath();
@@ -1073,12 +1118,20 @@ end;
 
 
 { TPath }
 { TPath }
 
 
+constructor TPath.Create();
+begin
+  Brush.Style := bsClear;
+  inherited Create();
+end;
+
 procedure TPath.Assign(APath: TPath);
 procedure TPath.Assign(APath: TPath);
 begin
 begin
   Len := APath.Len;
   Len := APath.Len;
   Points := APath.Points;
   Points := APath.Points;
   PointsEnd := APath.PointsEnd;
   PointsEnd := APath.PointsEnd;
   CurPoint := APath.CurPoint;
   CurPoint := APath.CurPoint;
+  Pen := APath.Pen;
+  Brush := APath.Brush;
 end;
 end;
 
 
 function TPath.Count(): TPathSegment;
 function TPath.Count(): TPathSegment;

+ 12 - 5
packages/fpvectorial/src/fpvtocanvas.pas

@@ -4,7 +4,7 @@ unit fpvtocanvas;
 
 
 interface
 interface
 
 
-{.$define USE_LCL_CANVAS}
+{$define USE_LCL_CANVAS}
 
 
 uses
 uses
   Classes, SysUtils, Math,
   Classes, SysUtils, Math,
@@ -115,7 +115,7 @@ end;
 
 
   DrawFPVectorialToCanvas(ASource, ADest, 0, ASource.Height, 1.0, -1.0);
   DrawFPVectorialToCanvas(ASource, ADest, 0, ASource.Height, 1.0, -1.0);
 }
 }
-{$define FPVECTORIAL_TOCANVAS_DEBUG}
+{.$define FPVECTORIAL_TOCANVAS_DEBUG}
 procedure DrawFPVectorialToCanvas(ASource: TvVectorialDocument;
 procedure DrawFPVectorialToCanvas(ASource: TvVectorialDocument;
   {$ifdef USE_LCL_CANVAS}ADest: TCanvas;{$else}ADest: TFPCustomCanvas;{$endif}
   {$ifdef USE_LCL_CANVAS}ADest: TCanvas;{$else}ADest: TFPCustomCanvas;{$endif}
   ADestX: Integer = 0; ADestY: Integer = 0; AMulX: Double = 1.0; AMulY: Double = 1.0);
   ADestX: Integer = 0; ADestY: Integer = 0; AMulX: Double = 1.0; AMulY: Double = 1.0);
@@ -187,15 +187,22 @@ begin
         Write(Format(' M%d,%d', [CoordToCanvasX(Cur2DSegment.X), CoordToCanvasY(Cur2DSegment.Y)]));
         Write(Format(' M%d,%d', [CoordToCanvasX(Cur2DSegment.X), CoordToCanvasY(Cur2DSegment.Y)]));
         {$endif}
         {$endif}
       end;
       end;
-      st2DLine, st3DLine:
+      st2DLineWithPen:
       begin
       begin
-        {$ifdef USE_LCL_CANVAS}ADest.Pen.Color := VColorToTColor(Cur2DSegment.PenColor);{$endif}
+        {$ifdef USE_LCL_CANVAS}ADest.Pen.Color := VColorToTColor(T2DSegmentWithPen(Cur2DSegment).Pen.Color);{$endif}
         ADest.LineTo(CoordToCanvasX(Cur2DSegment.X), CoordToCanvasY(Cur2DSegment.Y));
         ADest.LineTo(CoordToCanvasX(Cur2DSegment.X), CoordToCanvasY(Cur2DSegment.Y));
         {$ifdef USE_LCL_CANVAS}ADest.Pen.Color := clBlack;{$endif}
         {$ifdef USE_LCL_CANVAS}ADest.Pen.Color := clBlack;{$endif}
         {$ifdef FPVECTORIAL_TOCANVAS_DEBUG}
         {$ifdef FPVECTORIAL_TOCANVAS_DEBUG}
         Write(Format(' L%d,%d', [CoordToCanvasX(Cur2DSegment.X), CoordToCanvasY(Cur2DSegment.Y)]));
         Write(Format(' L%d,%d', [CoordToCanvasX(Cur2DSegment.X), CoordToCanvasY(Cur2DSegment.Y)]));
         {$endif}
         {$endif}
       end;
       end;
+      st2DLine, st3DLine:
+      begin
+        ADest.LineTo(CoordToCanvasX(Cur2DSegment.X), CoordToCanvasY(Cur2DSegment.Y));
+        {$ifdef FPVECTORIAL_TOCANVAS_DEBUG}
+        Write(Format(' L%d,%d', [CoordToCanvasX(Cur2DSegment.X), CoordToCanvasY(Cur2DSegment.Y)]));
+        {$endif}
+      end;
       { To draw a bezier we need to divide the interval in parts and make
       { To draw a bezier we need to divide the interval in parts and make
         lines between this parts }
         lines between this parts }
       st2DBezier, st3DBezier:
       st2DBezier, st3DBezier:
@@ -321,7 +328,7 @@ begin
       WriteLn(Format('Drawing Arc Center=%f,%f Radius=%f StartAngle=%f AngleLength=%f',
       WriteLn(Format('Drawing Arc Center=%f,%f Radius=%f StartAngle=%f AngleLength=%f',
         [CurArc.CenterX, CurArc.CenterY, CurArc.Radius, IntStartAngle/16, IntAngleLength/16]));
         [CurArc.CenterX, CurArc.CenterY, CurArc.Radius, IntStartAngle/16, IntAngleLength/16]));
       {$endif}
       {$endif}
-      ADest.Pen.Color := {$ifdef USE_LCL_CANVAS}VColorToTColor(CurArc.PenColor);{$else}VColorToFPColor(CurArc.PenColor);{$endif}
+      ADest.Pen.Color := {$ifdef USE_LCL_CANVAS}VColorToTColor(CurArc.Pen.Color);{$else}VColorToFPColor(CurArc.Pen.Color);{$endif}
       ADest.Arc(
       ADest.Arc(
         BoundsLeft, BoundsTop, BoundsRight, BoundsBottom,
         BoundsLeft, BoundsTop, BoundsRight, BoundsBottom,
         IntStartAngle, IntAngleLength
         IntStartAngle, IntAngleLength

+ 91 - 69
packages/fpvectorial/src/svgvectorialwriter.pas

@@ -13,7 +13,7 @@ unit svgvectorialwriter;
 interface
 interface
 
 
 uses
 uses
-  Classes, SysUtils, math, fpvectorial;
+  Classes, SysUtils, math, fpvectorial, fpvutils;
 
 
 type
 type
   { TvSVGVectorialWriter }
   { TvSVGVectorialWriter }
@@ -24,6 +24,7 @@ type
     procedure WriteDocumentSize(AStrings: TStrings; AData: TvVectorialDocument);
     procedure WriteDocumentSize(AStrings: TStrings; AData: TvVectorialDocument);
     procedure WriteDocumentName(AStrings: TStrings; AData: TvVectorialDocument);
     procedure WriteDocumentName(AStrings: TStrings; AData: TvVectorialDocument);
     procedure WritePaths(AStrings: TStrings; AData: TvVectorialDocument);
     procedure WritePaths(AStrings: TStrings; AData: TvVectorialDocument);
+    procedure WritePath(AIndex: Integer; APath: TPath; AStrings: TStrings; AData: TvVectorialDocument);
     procedure WriteTexts(AStrings: TStrings; AData: TvVectorialDocument);
     procedure WriteTexts(AStrings: TStrings; AData: TvVectorialDocument);
     procedure ConvertFPVCoordinatesToSVGCoordinates(
     procedure ConvertFPVCoordinatesToSVGCoordinates(
       const AData: TvVectorialDocument;
       const AData: TvVectorialDocument;
@@ -60,6 +61,19 @@ begin
   AStrings.Add('  sodipodi:docname="New document 1">');
   AStrings.Add('  sodipodi:docname="New document 1">');
 end;
 end;
 
 
+procedure TvSVGVectorialWriter.WritePaths(AStrings: TStrings; AData: TvVectorialDocument);
+var
+  i: Integer;
+  lPath: TPath;
+begin
+  for i := 0 to AData.GetPathCount() - 1 do
+  begin
+    lPath := AData.GetPath(i);
+    lPath.PrepareForSequentialReading;
+    WritePath(i ,lPath, AStrings, AData);
+  end;
+end;
+
 {@@
 {@@
   SVG Coordinate system measures things only in pixels, so that we have to
   SVG Coordinate system measures things only in pixels, so that we have to
   hardcode a DPI value for the screen, which is usually 72.
   hardcode a DPI value for the screen, which is usually 72.
@@ -74,90 +88,98 @@ end;
   SVG uses commas "," to separate the X,Y coordinates, so it always uses points
   SVG uses commas "," to separate the X,Y coordinates, so it always uses points
   "." as decimal separators and uses no thousand separators
   "." as decimal separators and uses no thousand separators
 }
 }
-procedure TvSVGVectorialWriter.WritePaths(AStrings: TStrings; AData: TvVectorialDocument);
+procedure TvSVGVectorialWriter.WritePath(AIndex: Integer; APath: TPath; AStrings: TStrings;
+  AData: TvVectorialDocument);
 var
 var
-  i, j: Integer;
+  j: Integer;
   PathStr: string;
   PathStr: string;
-  lPath: TPath;
   PtX, PtY, OldPtX, OldPtY: double;
   PtX, PtY, OldPtX, OldPtY: double;
   BezierCP1X, BezierCP1Y, BezierCP2X, BezierCP2Y: double;
   BezierCP1X, BezierCP1Y, BezierCP2X, BezierCP2Y: double;
   segment: TPathSegment;
   segment: TPathSegment;
   l2DSegment: T2DSegment absolute segment;
   l2DSegment: T2DSegment absolute segment;
   l2DBSegment: T2DBezierSegment absolute segment;
   l2DBSegment: T2DBezierSegment absolute segment;
+  // Pen properties
+  lPenWidth: Integer;
+  lPenColor: string;
 begin
 begin
-  for i := 0 to AData.GetPathCount() - 1 do
-  begin
-    OldPtX := 0;
-    OldPtY := 0;
+  OldPtX := 0;
+  OldPtY := 0;
+  PathStr := '';
 
 
-    PathStr := '';
-    lPath := AData.GetPath(i);
-    lPath.PrepareForSequentialReading;
+  APath.PrepareForSequentialReading();
 
 
-    for j := 0 to lPath.Len - 1 do
-    begin
-      segment := TPathSegment(lPath.Next());
+  for j := 0 to APath.Len - 1 do
+  begin
+    segment := TPathSegment(APath.Next());
+
+    if (segment.SegmentType <> st2DLine)
+      and (segment.SegmentType <> stMoveTo)
+      and (segment.SegmentType <> st2DBezier)
+      then Break; // unsupported line type
 
 
-      if (segment.SegmentType <> st2DLine)
-        and (segment.SegmentType <> stMoveTo)
-        and (segment.SegmentType <> st2DBezier)
-        then Break; // unsupported line type
+    // Coordinate conversion from fpvectorial to SVG
+    ConvertFPVCoordinatesToSVGCoordinates(
+      AData, l2DSegment.X, l2DSegment.Y, PtX, PtY);
+    PtX := PtX - OldPtX;
+    PtY := PtY - OldPtY;
 
 
-      // Coordinate conversion from fpvectorial to SVG
+    if (segment.SegmentType = stMoveTo) then
+    begin
+      PathStr := PathStr + 'm '
+        + FloatToStr(PtX, FPointSeparator) + ','
+        + FloatToStr(PtY, FPointSeparator) + ' ';
+    end
+    else if (segment.SegmentType = st2DLine) then
+    begin
+      PathStr := PathStr + 'l '
+        + FloatToStr(PtX, FPointSeparator) + ','
+        + FloatToStr(PtY, FPointSeparator) + ' ';
+    end
+    else if (segment.SegmentType = st2DBezier) then
+    begin
+      // Converts all coordinates to absolute values
+      ConvertFPVCoordinatesToSVGCoordinates(
+        AData, l2DBSegment.X2, l2DBSegment.Y2, BezierCP1X, BezierCP1Y);
       ConvertFPVCoordinatesToSVGCoordinates(
       ConvertFPVCoordinatesToSVGCoordinates(
-        AData, l2DSegment.X, l2DSegment.Y, PtX, PtY);
-      PtX := PtX - OldPtX;
-      PtY := PtY - OldPtY;
-
-      if (segment.SegmentType = stMoveTo) then
-      begin
-        PathStr := PathStr + 'm '
-          + FloatToStr(PtX, FPointSeparator) + ','
-          + FloatToStr(PtY, FPointSeparator) + ' ';
-      end
-      else if (segment.SegmentType = st2DLine) then
-      begin
-        PathStr := PathStr + 'l '
-          + FloatToStr(PtX, FPointSeparator) + ','
-          + FloatToStr(PtY, FPointSeparator) + ' ';
-      end
-      else if (segment.SegmentType = st2DBezier) then
-      begin
-        // Converts all coordinates to absolute values
-        ConvertFPVCoordinatesToSVGCoordinates(
-          AData, l2DBSegment.X2, l2DBSegment.Y2, BezierCP1X, BezierCP1Y);
-        ConvertFPVCoordinatesToSVGCoordinates(
-          AData, l2DBSegment.X3, l2DBSegment.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;
-      OldPtY := OldPtY + PtY;
+        AData, l2DBSegment.X3, l2DBSegment.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;
     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) + '" />');
+    // Store the current position for future points
+    OldPtX := OldPtX + PtX;
+    OldPtY := OldPtY + PtY;
   end;
   end;
+
+  // Get the Pen Width
+  if APath.Pen.Width >= 1 then lPenWidth := APath.Pen.Width
+  else lPenWidth := 1;
+
+  // Get the Pen Color
+  lPenColor := VColorToRGBHexString(APath.Pen.Color);
+
+  AStrings.Add('  <path');
+  AStrings.Add(Format('    style="fill:none;stroke:#%s;stroke-width:%dpx;'
+   + 'stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"',
+   [lPenColor, lPenWidth]));
+  AStrings.Add('    d="' + PathStr + '"');
+  AStrings.Add('  id="path' + IntToStr(AIndex) + '" />');
 end;
 end;
 
 
 procedure TvSVGVectorialWriter.ConvertFPVCoordinatesToSVGCoordinates(
 procedure TvSVGVectorialWriter.ConvertFPVCoordinatesToSVGCoordinates(