Browse Source

Many reliability improvements to the dxf reader, adds text support for both the dxf reader and the canvas output

git-svn-id: trunk@16850 -
sekelsenmat 14 years ago
parent
commit
726339c443

+ 88 - 30
packages/fpvectorial/src/dxfvectorialreader.pas

@@ -66,8 +66,13 @@ type
 
 
   TvDXFVectorialReader = class(TvCustomVectorialReader)
   TvDXFVectorialReader = class(TvCustomVectorialReader)
   private
   private
+    FPointSeparator: TFormatSettings;
+    // HEADER data
+    ANGBASE: Double;
+    ANGDIR: Integer;
     //
     //
     function  SeparateString(AString: string; ASeparator: Char): T10Strings;
     function  SeparateString(AString: string; ASeparator: Char): T10Strings;
+    procedure ReadHEADER(ATokens: TDXFTokens; AData: TvVectorialDocument);
     procedure ReadENTITIES(ATokens: TDXFTokens; AData: TvVectorialDocument);
     procedure ReadENTITIES(ATokens: TDXFTokens; AData: TvVectorialDocument);
     procedure ReadENTITIES_LINE(ATokens: TDXFTokens; AData: TvVectorialDocument);
     procedure ReadENTITIES_LINE(ATokens: TDXFTokens; AData: TvVectorialDocument);
     procedure ReadENTITIES_ARC(ATokens: TDXFTokens; AData: TvVectorialDocument);
     procedure ReadENTITIES_ARC(ATokens: TDXFTokens; AData: TvVectorialDocument);
@@ -85,12 +90,24 @@ type
 
 
 implementation
 implementation
 
 
+{$ifndef Windows}
 {$define FPVECTORIALDEBUG}
 {$define FPVECTORIALDEBUG}
+{$endif}
 
 
 const
 const
+  // Items in the HEADER section
+
+  // $ACADVER
+  DXF_AUTOCAD_R10         = 'AC1006'; // 1988
+  DXF_AUTOCAD_R11_and_R12 = 'AC1009'; // 1990
+  DXF_AUTOCAD_R13         = 'AC1012'; // 1994
+  DXF_AUTOCAD_R14         = 'AC1009'; // 1997  http://www.autodesk.com/techpubs/autocad/acadr14/dxf/index.htm
+  DXF_AUTOCAD_2000        = 'AC1500'; // 1999  http://www.autodesk.com/techpubs/autocad/acad2000/dxf/
+
   // Group Codes for ENTITIES
   // Group Codes for ENTITIES
   DXF_ENTITIES_TYPE = 0;
   DXF_ENTITIES_TYPE = 0;
   DXF_ENTITIES_HANDLE = 5;
   DXF_ENTITIES_HANDLE = 5;
+  DXF_ENTITIES_LINETYPE_NAME = 6;
   DXF_ENTITIES_APPLICATION_GROUP = 102;
   DXF_ENTITIES_APPLICATION_GROUP = 102;
   DXF_ENTITIES_AcDbEntity = 100;
   DXF_ENTITIES_AcDbEntity = 100;
   DXF_ENTITIES_MODEL_OR_PAPER_SPACE = 67; // default=0=model, 1=paper
   DXF_ENTITIES_MODEL_OR_PAPER_SPACE = 67; // default=0=model, 1=paper
@@ -306,6 +323,33 @@ begin
   end;
   end;
 end;
 end;
 
 
+procedure TvDXFVectorialReader.ReadHEADER(ATokens: TDXFTokens;
+  AData: TvVectorialDocument);
+var
+  i: Integer;
+  CurToken: TDXFToken;
+begin
+  i := 0;
+  while i < ATokens.Count do
+  begin
+    CurToken := TDXFToken(ATokens.Items[i]);
+    if CurToken.StrValue = '$ANGBASE' then
+    begin
+      CurToken := TDXFToken(ATokens.Items[i+1]);
+      ANGBASE := StrToFloat(CurToken.StrValue, FPointSeparator);
+      Inc(i);
+    end
+    else if CurToken.StrValue = '$ANGDIR' then
+    begin
+      CurToken := TDXFToken(ATokens.Items[i+1]);
+      ANGDIR := StrToInt(CurToken.StrValue);
+      Inc(i);
+    end;
+
+    Inc(i);
+  end;
+end;
+
 procedure TvDXFVectorialReader.ReadENTITIES(ATokens: TDXFTokens; AData: TvVectorialDocument);
 procedure TvDXFVectorialReader.ReadENTITIES(ATokens: TDXFTokens; AData: TvVectorialDocument);
 var
 var
   i: Integer;
   i: Integer;
@@ -314,7 +358,8 @@ begin
   for i := 0 to ATokens.Count - 1 do
   for i := 0 to ATokens.Count - 1 do
   begin
   begin
     CurToken := TDXFToken(ATokens.Items[i]);
     CurToken := TDXFToken(ATokens.Items[i]);
-    if CurToken.StrValue = 'CIRCLE' then ReadENTITIES_CIRCLE(CurToken.Childs, AData)
+    if CurToken.StrValue = 'ARC' then ReadENTITIES_ARC(CurToken.Childs, AData)
+    else if CurToken.StrValue = 'CIRCLE' then ReadENTITIES_CIRCLE(CurToken.Childs, AData)
     else if CurToken.StrValue = 'ELLIPSE' then ReadENTITIES_ELLIPSE(CurToken.Childs, AData)
     else if CurToken.StrValue = 'ELLIPSE' then ReadENTITIES_ELLIPSE(CurToken.Childs, AData)
     else if CurToken.StrValue = 'LINE' then ReadENTITIES_LINE(CurToken.Childs, AData)
     else if CurToken.StrValue = 'LINE' then ReadENTITIES_LINE(CurToken.Childs, AData)
     else if CurToken.StrValue = 'TEXT' then
     else if CurToken.StrValue = 'TEXT' then
@@ -346,10 +391,10 @@ begin
     CurToken := TDXFToken(ATokens.Items[i]);
     CurToken := TDXFToken(ATokens.Items[i]);
 
 
     // Avoid an exception by previously checking if the conversion can be made
     // Avoid an exception by previously checking if the conversion can be made
-    if (CurToken.GroupCode = DXF_ENTITIES_HANDLE) or
-      (CurToken.GroupCode = DXF_ENTITIES_AcDbEntity) then Continue;
-
-    CurToken.FloatValue :=  StrToFloat(Trim(CurToken.StrValue));
+    if CurToken.GroupCode in [10, 20, 30, 11, 21, 31] then
+    begin
+      CurToken.FloatValue :=  StrToFloat(Trim(CurToken.StrValue), FPointSeparator);
+    end;
 
 
     case CurToken.GroupCode of
     case CurToken.GroupCode of
       10: LineStartX := CurToken.FloatValue;
       10: LineStartX := CurToken.FloatValue;
@@ -377,8 +422,8 @@ end;
 20, 30 DXF: Y and Z values of center point (in OCS)
 20, 30 DXF: Y and Z values of center point (in OCS)
 40 Radius
 40 Radius
 100 Subclass marker (AcDbArc)
 100 Subclass marker (AcDbArc)
-50 Start angle
-51 End angle
+50 Start angle (degrees)
+51 End angle (degrees)
 210 Extrusion direction. (optional; default = 0, 0, 1) DXF: X value; APP: 3D vector
 210 Extrusion direction. (optional; default = 0, 0, 1) DXF: X value; APP: 3D vector
 220, 230 DXF: Y and Z values of extrusion direction (optional)
 220, 230 DXF: Y and Z values of extrusion direction (optional)
 }
 }
@@ -402,16 +447,18 @@ begin
     CurToken := TDXFToken(ATokens.Items[i]);
     CurToken := TDXFToken(ATokens.Items[i]);
 
 
     // Avoid an exception by previously checking if the conversion can be made
     // Avoid an exception by previously checking if the conversion can be made
-    if (CurToken.GroupCode = DXF_ENTITIES_HANDLE) or
-      (CurToken.GroupCode = DXF_ENTITIES_AcDbEntity) then Continue;
-
-    CurToken.FloatValue :=  StrToFloat(Trim(CurToken.StrValue));
+    if CurToken.GroupCode in [10, 20, 30, 40, 50, 51] then
+    begin
+      CurToken.FloatValue :=  StrToFloat(Trim(CurToken.StrValue), FPointSeparator);
+    end;
 
 
     case CurToken.GroupCode of
     case CurToken.GroupCode of
       10: CenterX := CurToken.FloatValue;
       10: CenterX := CurToken.FloatValue;
       20: CenterY := CurToken.FloatValue;
       20: CenterY := CurToken.FloatValue;
       30: CenterZ := CurToken.FloatValue;
       30: CenterZ := CurToken.FloatValue;
       40: Radius := CurToken.FloatValue;
       40: Radius := CurToken.FloatValue;
+      50: StartAngle := CurToken.FloatValue;
+      51: EndAngle := CurToken.FloatValue;
     end;
     end;
   end;
   end;
 
 
@@ -446,10 +493,10 @@ begin
     CurToken := TDXFToken(ATokens.Items[i]);
     CurToken := TDXFToken(ATokens.Items[i]);
 
 
     // Avoid an exception by previously checking if the conversion can be made
     // Avoid an exception by previously checking if the conversion can be made
-    if (CurToken.GroupCode = DXF_ENTITIES_HANDLE) or
-      (CurToken.GroupCode = DXF_ENTITIES_AcDbEntity) then Continue;
-
-    CurToken.FloatValue :=  StrToFloat(Trim(CurToken.StrValue));
+    if CurToken.GroupCode in [10, 20, 30, 40] then
+    begin
+      CurToken.FloatValue :=  StrToFloat(Trim(CurToken.StrValue), FPointSeparator);
+    end;
 
 
     case CurToken.GroupCode of
     case CurToken.GroupCode of
       10: CircleCenterX := CurToken.FloatValue;
       10: CircleCenterX := CurToken.FloatValue;
@@ -488,17 +535,16 @@ begin
     CurToken := TDXFToken(ATokens.Items[i]);
     CurToken := TDXFToken(ATokens.Items[i]);
 
 
     // Avoid an exception by previously checking if the conversion can be made
     // Avoid an exception by previously checking if the conversion can be made
-    if (CurToken.GroupCode = DXF_ENTITIES_HANDLE) or
-      (CurToken.GroupCode = DXF_ENTITIES_AcDbEntity) then Continue;
-
-    CurToken.FloatValue :=  StrToFloat(Trim(CurToken.StrValue));
+    if CurToken.GroupCode in [10, 20, 30] then
+    begin
+      CurToken.FloatValue :=  StrToFloat(Trim(CurToken.StrValue), FPointSeparator);
+    end;
 
 
     case CurToken.GroupCode of
     case CurToken.GroupCode of
       10: CenterX := CurToken.FloatValue;
       10: CenterX := CurToken.FloatValue;
       20: CenterY := CurToken.FloatValue;
       20: CenterY := CurToken.FloatValue;
       30: CenterZ := CurToken.FloatValue;
       30: CenterZ := CurToken.FloatValue;
     end;
     end;
-
   end;
   end;
 
 
   //
   //
@@ -542,8 +588,11 @@ procedure TvDXFVectorialReader.ReadENTITIES_TEXT(ATokens: TDXFTokens;
 var
 var
   CurToken: TDXFToken;
   CurToken: TDXFToken;
   i: Integer;
   i: Integer;
-  PosX, PosY, PosZ: Double;
-  Str: string;
+  PosX: Double = 0.0;
+  PosY: Double = 0.0;
+  PosZ: Double = 0.0;
+  FontSize: Double = 10.0;
+  Str: string = '';
 begin
 begin
   for i := 0 to ATokens.Count - 1 do
   for i := 0 to ATokens.Count - 1 do
   begin
   begin
@@ -551,23 +600,22 @@ begin
     CurToken := TDXFToken(ATokens.Items[i]);
     CurToken := TDXFToken(ATokens.Items[i]);
 
 
     // Avoid an exception by previously checking if the conversion can be made
     // Avoid an exception by previously checking if the conversion can be made
-    if (CurToken.GroupCode = DXF_ENTITIES_HANDLE) or
-      (CurToken.GroupCode = 1) or
-      (CurToken.GroupCode = DXF_ENTITIES_AcDbEntity) then Continue;
-
-    CurToken.FloatValue :=  StrToFloat(Trim(CurToken.StrValue));
+    if CurToken.GroupCode in [10, 20, 30, 40] then
+    begin
+      CurToken.FloatValue :=  StrToFloat(Trim(CurToken.StrValue), FPointSeparator);
+    end;
 
 
     case CurToken.GroupCode of
     case CurToken.GroupCode of
       1:  Str := CurToken.StrValue;
       1:  Str := CurToken.StrValue;
       10: PosX := CurToken.FloatValue;
       10: PosX := CurToken.FloatValue;
       20: PosY := CurToken.FloatValue;
       20: PosY := CurToken.FloatValue;
       30: PosZ := CurToken.FloatValue;
       30: PosZ := CurToken.FloatValue;
+      40: FontSize := CurToken.FloatValue;
     end;
     end;
-
   end;
   end;
 
 
   //
   //
-//  AData.AddEllipse(CenterX, CenterY, CenterZ, MajorHalfAxis, MinorHalfAxis, Angle);
+  AData.AddText(PosX, PosY, PosZ, '', Round(FontSize), Str);
 end;
 end;
 
 
 function TvDXFVectorialReader.GetCoordinateValue(AStr: shortstring): Double;
 function TvDXFVectorialReader.GetCoordinateValue(AStr: shortstring): Double;
@@ -583,6 +631,14 @@ constructor TvDXFVectorialReader.Create;
 begin
 begin
   inherited Create;
   inherited Create;
 
 
+  FPointSeparator := DefaultFormatSettings;
+  FPointSeparator.DecimalSeparator := '.';
+  FPointSeparator.ThousandSeparator := '#';// disable the thousand separator
+
+  // Default HEADER data
+  ANGBASE := 0.0; // Starts pointing to the right / east
+  ANGDIR := 0; // counter-clock wise
+
   Tokenizer := TDXFTokenizer.Create;
   Tokenizer := TDXFTokenizer.Create;
 end;
 end;
 
 
@@ -610,7 +666,9 @@ begin
     CurToken := TDXFToken(Tokenizer.Tokens.Items[i]);
     CurToken := TDXFToken(Tokenizer.Tokens.Items[i]);
     CurTokenFirstChild := TDXFToken(CurToken.Childs.Items[0]);
     CurTokenFirstChild := TDXFToken(CurToken.Childs.Items[0]);
 
 
-    if CurTokenFirstChild.StrValue = 'ENTITIES' then
+    if CurTokenFirstChild.StrValue = 'HEADER' then
+      ReadHEADER(CurToken.Childs, AData)
+    else if CurTokenFirstChild.StrValue = 'ENTITIES' then
       ReadENTITIES(CurToken.Childs, AData);
       ReadENTITIES(CurToken.Childs, AData);
   end;
   end;
 end;
 end;

+ 2 - 1
packages/fpvectorial/src/fpvectorial.pas

@@ -139,6 +139,7 @@ type
   TvCircularArc = class(TvEntity)
   TvCircularArc = class(TvEntity)
   public
   public
     CenterX, CenterY, CenterZ, Radius: Double;
     CenterX, CenterY, CenterZ, Radius: Double;
+    {@@ The Angle is measured in degrees in relation to the positive X axis }
     StartAngle, EndAngle: Double;
     StartAngle, EndAngle: Double;
   end;
   end;
 
 
@@ -151,7 +152,7 @@ type
   public
   public
     // Mandatory fields
     // Mandatory fields
     CenterX, CenterY, CenterZ, MajorHalfAxis, MinorHalfAxis: Double;
     CenterX, CenterY, CenterZ, MajorHalfAxis, MinorHalfAxis: Double;
-    {@@ The Angle is measured in radians in relation to the positive X axis }
+    {@@ The Angle is measured in degrees in relation to the positive X axis }
     Angle: Double;
     Angle: Double;
     // Calculated fields
     // Calculated fields
     BoundingRect: TRect;
     BoundingRect: TRect;

+ 76 - 21
packages/fpvectorial/src/fpvtocanvas.pas

@@ -4,17 +4,28 @@ unit fpvtocanvas;
 
 
 interface
 interface
 
 
+{.$define USE_LCL_CANVAS}
+
 uses
 uses
-  Classes, SysUtils,
+  Classes, SysUtils, Math,
+  {$ifdef USE_LCL_CANVAS}
+  Graphics, LCLIntf,
+  {$else}
   fpcanvas,
   fpcanvas,
+  {$endif}
   fpvectorial;
   fpvectorial;
 
 
-procedure DrawFPVectorialToCanvas(ASource: TvVectorialDocument; ADest: TFPCustomCanvas;
+procedure DrawFPVectorialToCanvas(ASource: TvVectorialDocument;
+  {$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);
 
 
 implementation
 implementation
 
 
-{function Rotate2DPoint(P,Fix :TPoint; alpha:double): TPoint;
+function Rotate2DPoint(P,Fix :TPoint; alpha:double): TPoint;
 var
 var
   sinus, cosinus : Extended;
   sinus, cosinus : Extended;
 begin
 begin
@@ -23,31 +34,46 @@ begin
   P.y := P.y - Fix.y;
   P.y := P.y - Fix.y;
   result.x := Round(p.x*cosinus + p.y*sinus)  +  fix.x ;
   result.x := Round(p.x*cosinus + p.y*sinus)  +  fix.x ;
   result.y := Round(-p.x*sinus + p.y*cosinus) +  Fix.y;
   result.y := Round(-p.x*sinus + p.y*cosinus) +  Fix.y;
-end;}
+end;
 
 
-procedure DrawRotatedEllipse(ADest: TFPCustomCanvas; CurEllipse: TvEllipse);
-{var
+procedure DrawRotatedEllipse(
+  {$ifdef USE_LCL_CANVAS}
+  ADest: TCanvas;
+  {$else}
+  ADest: TFPCustomCanvas;
+  {$endif}
+  CurEllipse: TvEllipse;
+  ADestX: Integer = 0; ADestY: Integer = 0; AMulX: Double = 1.0; AMulY: Double = 1.0);
+var
   PointList: array[0..6] of TPoint;
   PointList: array[0..6] of TPoint;
   f: TPoint;
   f: TPoint;
-  dk: Integer;}
+  dk, x1, x2, y1, y2: Integer;
 begin
 begin
-{  dk := Round(0.654 * Abs(y2-y1));
-  f.x := CurEllipse.CenterX;
-  f.y := CurEllipse.CenterY - 1;
-  PointList[0] := Rotate2DPoint(Point(x1, f.y), f, Alpha) ;  // Startpoint
-  PointList[1] := Rotate2DPoint(Point(x1,  f.y - dk), f, Alpha);
+  {$ifdef USE_LCL_CANVAS}
+  CurEllipse.CalculateBoundingRectangle();
+  x1 := CurEllipse.BoundingRect.Left;
+  x2 := CurEllipse.BoundingRect.Right;
+  y1 := CurEllipse.BoundingRect.Top;
+  y2 := CurEllipse.BoundingRect.Bottom;
+
+  dk := Round(0.654 * Abs(y2-y1));
+  f.x := Round(CurEllipse.CenterX);
+  f.y := Round(CurEllipse.CenterY - 1);
+  PointList[0] := Rotate2DPoint(Point(x1, f.y), f, CurEllipse.Angle) ;  // Startpoint
+  PointList[1] := Rotate2DPoint(Point(x1,  f.y - dk), f, CurEllipse.Angle);
   //Controlpoint of Startpoint first part
   //Controlpoint of Startpoint first part
-  PointList[2] := Rotate2DPoint(Point(x2- 1,  f.y - dk), f, Alpha);
+  PointList[2] := Rotate2DPoint(Point(x2- 1,  f.y - dk), f, CurEllipse.Angle);
   //Controlpoint of secondpoint first part
   //Controlpoint of secondpoint first part
-  PointList[3] := Rotate2DPoint(Point(x2 -1 , f.y), f, Alpha);
+  PointList[3] := Rotate2DPoint(Point(x2 -1 , f.y), f, CurEllipse.Angle);
   // Firstpoint of secondpart
   // Firstpoint of secondpart
-  PointList[4] := Rotate2DPoint(Point(x2-1 , f.y + dk), f, Alpha);
+  PointList[4] := Rotate2DPoint(Point(x2-1 , f.y + dk), f, CurEllipse.Angle);
   // Controllpoint of secondpart firstpoint
   // Controllpoint of secondpart firstpoint
-  PointList[5] := Rotate2DPoint(Point(x1, f.y +  dk), f, Alpha);
+  PointList[5] := Rotate2DPoint(Point(x1, f.y +  dk), f, CurEllipse.Angle);
   // Conrollpoint of secondpart endpoint
   // Conrollpoint of secondpart endpoint
   PointList[6] := PointList[0];   // Endpoint of
   PointList[6] := PointList[0];   // Endpoint of
    // Back to the startpoint
    // Back to the startpoint
-  PolyBezier(canvas.handle, Pointlist[0], 7);}
+  ADest.PolyBezier(Pointlist[0]);
+  {$endif}
 end;
 end;
 
 
 {@@
 {@@
@@ -64,7 +90,12 @@ end;
 
 
   DrawFPVectorialToCanvas(ASource, ADest, 0, ASource.Height, 1.0, -1.0);
   DrawFPVectorialToCanvas(ASource, ADest, 0, ASource.Height, 1.0, -1.0);
 }
 }
-procedure DrawFPVectorialToCanvas(ASource: TvVectorialDocument; ADest: TFPCustomCanvas;
+procedure DrawFPVectorialToCanvas(ASource: TvVectorialDocument;
+  {$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);
 var
 var
   i, j, k: Integer;
   i, j, k: Integer;
@@ -76,11 +107,13 @@ var
   CurX, CurY: Integer; // Not modified by ADestX, etc
   CurX, CurY: Integer; // Not modified by ADestX, etc
   CurveLength: Integer;
   CurveLength: Integer;
   t: Double;
   t: Double;
+  // For text
+  CurText: TvText;
   // For entities
   // For entities
   CurEntity: TvEntity;
   CurEntity: TvEntity;
   CurCircle: TvCircle;
   CurCircle: TvCircle;
   CurEllipse: TvEllipse;
   CurEllipse: TvEllipse;
-  CurCircularArc: TvCircularArc;
+  CurArc: TvCircularArc;
 begin
 begin
   {$ifdef FPVECTORIALDEBUG}
   {$ifdef FPVECTORIALDEBUG}
   WriteLn(':>DrawFPVectorialToCanvas');
   WriteLn(':>DrawFPVectorialToCanvas');
@@ -91,6 +124,7 @@ begin
 
 
   ADest.MoveTo(ADestX, ADestY);
   ADest.MoveTo(ADestX, ADestY);
 
 
+  // Draws all paths
   for i := 0 to ASource.PathCount - 1 do
   for i := 0 to ASource.PathCount - 1 do
   begin
   begin
     //WriteLn('i = ', i);
     //WriteLn('i = ', i);
@@ -141,6 +175,7 @@ begin
     end;
     end;
   end;
   end;
 
 
+  // Draws all entities
   for i := 0 to ASource.GetEntityCount - 1 do
   for i := 0 to ASource.GetEntityCount - 1 do
   begin
   begin
     CurEntity := ASource.GetEntity(i);
     CurEntity := ASource.GetEntity(i);
@@ -161,11 +196,31 @@ begin
     end
     end
     else if CurEntity is TvCircularArc then
     else if CurEntity is TvCircularArc then
     begin
     begin
-      CurCircularArc := CurEntity as TvCircularArc;
-//      ADest.Arc(ADest, CurEllipse);
+      CurArc := CurEntity as TvCircularArc;
+      {$ifdef USE_LCL_CANVAS}
+      // Arc(ALeft, ATop, ARight, ABottom, Angle16Deg, Angle16DegLength: Integer);
+      ADest.Arc(
+        Round(ADestX + AmulX * (CurArc.CenterX - CurArc.Radius)),
+        Round(ADestY + AmulY * (CurArc.CenterY - CurArc.Radius)),
+        Round(ADestX + AmulX * (CurArc.CenterX + CurArc.Radius)),
+        Round(ADestY + AmulY * (CurArc.CenterY + CurArc.Radius)),
+        Round(16*CurArc.StartAngle),
+        Round(16*CurArc.EndAngle - CurArc.StartAngle)
+        );
+      {$endif}
     end;
     end;
   end;
   end;
 
 
+  // Draws all text
+  for i := 0 to ASource.GetTextCount - 1 do
+  begin
+    CurText := ASource.GetText(i);
+    ADest.Font.Height := Round(AmulY * CurText.FontSize);
+    ADest.Pen.Style := psSolid;
+    ADest.Pen.Color := clBlack;
+    ADest.TextOut(Round(CurText.X), Round(CurText.Y), CurText.Value);
+  end;
+
   {$ifdef FPVECTORIALDEBUG}
   {$ifdef FPVECTORIALDEBUG}
   WriteLn(':<DrawFPVectorialToCanvas');
   WriteLn(':<DrawFPVectorialToCanvas');
   {$endif}
   {$endif}