aboutsummaryrefslogtreecommitdiffstats
path: root/graphics
diff options
context:
space:
mode:
authoracm <acm@FreeBSD.org>2011-06-23 13:05:29 +0800
committeracm <acm@FreeBSD.org>2011-06-23 13:05:29 +0800
commite653c12f05cecbd3f005e4932d0567676b33fa8a (patch)
tree96770da54e02db768a7ef438e1edf946656e7e5d /graphics
parentde375a1f7c1bc77ebae7016bd8bc0643072affd5 (diff)
downloadfreebsd-ports-gnome-e653c12f05cecbd3f005e4932d0567676b33fa8a.tar.gz
freebsd-ports-gnome-e653c12f05cecbd3f005e4932d0567676b33fa8a.tar.zst
freebsd-ports-gnome-e653c12f05cecbd3f005e4932d0567676b33fa8a.zip
- Update to 2.4.4
Diffstat (limited to 'graphics')
-rw-r--r--graphics/fpc-fpvectorial/files/fpvutils.pas114
-rw-r--r--graphics/fpc-fpvectorial/files/patch-packages-fpvectorial-src_avisocncgcodewriter.pas66
-rw-r--r--graphics/fpc-fpvectorial/files/patch-packages-fpvectorial-src_fpvectorial.pas703
-rw-r--r--graphics/fpc-fpvectorial/files/patch-packages-fpvectorial-src_fpvtocanvas.pas540
-rw-r--r--graphics/fpc-fpvectorial/files/patch-packages-fpvectorial-src_svgvectorialwriter.pas273
-rw-r--r--graphics/fpc-fpvectorial/pkg-plist6
-rw-r--r--graphics/fpc-opengl/pkg-plist3
7 files changed, 1705 insertions, 0 deletions
diff --git a/graphics/fpc-fpvectorial/files/fpvutils.pas b/graphics/fpc-fpvectorial/files/fpvutils.pas
new file mode 100644
index 000000000000..d88393ad8eff
--- /dev/null
+++ b/graphics/fpc-fpvectorial/files/fpvutils.pas
@@ -0,0 +1,114 @@
+{
+fpvutils.pas
+
+Vector graphics document
+
+License: The same modified LGPL as the Free Pascal RTL
+ See the file COPYING.modifiedLGPL for more details
+
+AUTHORS: Felipe Monteiro de Carvalho
+ Pedro Sol Pegorini L de Lima
+}
+unit fpvutils;
+
+{$ifdef fpc}
+ {$mode delphi}
+{$endif}
+
+interface
+
+uses
+ Classes, SysUtils, Math,
+ fpvectorial, fpimage;
+
+type
+ T10Strings = array[0..9] of shortstring;
+
+// Color Conversion routines
+function FPColorToRGBHexString(AColor: TFPColor): string;
+function RGBToFPColor(AR, AG, AB: byte): TFPColor; inline;
+// Other routine
+function CanvasCoordsToFPVectorial(AY: Integer; AHeight: Integer): Integer; inline;
+function CanvasTextPosToFPVectorial(AY: Integer; ACanvasHeight, ATextHeight: Integer): Integer;
+function SeparateString(AString: string; ASeparator: char): T10Strings;
+
+implementation
+
+{@@ This function is utilized by the SVG writer and some other places, so
+ it shouldn't be changed.
+}
+function FPColorToRGBHexString(AColor: TFPColor): string;
+begin
+ Result := Format('%.2x%.2x%.2x', [AColor.Red shr 8, AColor.Green shr 8, AColor.Blue shr 8]);
+end;
+
+function RGBToFPColor(AR, AG, AB: byte): TFPColor; inline;
+begin
+ Result.Red := (AR shl 8) + AR;
+ Result.Green := (AG shl 8) + AG;
+ Result.Blue := (AB shl 8) + AB;
+ Result.Alpha := $FFFF;
+end;
+
+{@@ Converts the coordinate system from a TCanvas to FPVectorial
+ The basic difference is that the Y axis is positioned differently and
+ points upwards in FPVectorial and downwards in TCanvas.
+ The X axis doesn't change. The fix is trivial and requires only the Height of
+ the Canvas as extra info.
+
+ @param AHeight Should receive TCanvas.Height
+}
+function CanvasCoordsToFPVectorial(AY: Integer; AHeight: Integer): Integer; inline;
+begin
+ Result := AHeight - AY;
+end;
+
+{@@
+ LCL Text is positioned based on the top-left corner of the text.
+ Besides that, one also needs to take the general coordinate change into account too.
+
+ @param ACanvasHeight Should receive TCanvas.Height
+ @param ATextHeight Should receive TFont.Size
+}
+function CanvasTextPosToFPVectorial(AY: Integer; ACanvasHeight, ATextHeight: Integer): Integer;
+begin
+ Result := CanvasCoordsToFPVectorial(AY, ACanvasHeight) - ATextHeight;
+end;
+
+{@@
+ Reads a string and separates it in substring
+ using ASeparator to delimite them.
+
+ Limits:
+
+ Number of substrings: 10 (indexed 0 to 9)
+ Length of each substring: 255 (they are shortstrings)
+}
+function SeparateString(AString: string; ASeparator: char): T10Strings;
+var
+ i, CurrentPart: integer;
+begin
+ CurrentPart := 0;
+
+ { Clears the result }
+ for i := 0 to 9 do
+ Result[i] := '';
+
+ { Iterates througth the string, filling strings }
+ for i := 1 to Length(AString) do
+ begin
+ if Copy(AString, i, 1) = ASeparator then
+ begin
+ Inc(CurrentPart);
+
+ { Verifies if the string capacity wasn't exceeded }
+ if CurrentPart > 9 then
+ Exit;
+ end
+ else
+ Result[CurrentPart] := Result[CurrentPart] + Copy(AString, i, 1);
+ end;
+end;
+
+end.
+
diff --git a/graphics/fpc-fpvectorial/files/patch-packages-fpvectorial-src_avisocncgcodewriter.pas b/graphics/fpc-fpvectorial/files/patch-packages-fpvectorial-src_avisocncgcodewriter.pas
new file mode 100644
index 000000000000..04207c012f34
--- /dev/null
+++ b/graphics/fpc-fpvectorial/files/patch-packages-fpvectorial-src_avisocncgcodewriter.pas
@@ -0,0 +1,66 @@
+--- packages/fpvectorial/src/avisocncgcodewriter.pas 2011/01/14 14:45:03 16765
++++ packages/fpvectorial/src/avisocncgcodewriter.pas 2011/03/08 14:28:26 17092
+@@ -36,6 +36,10 @@
+ i, j: Integer;
+ Str: string;
+ APath: TPath;
++ CurSegment: T2DSegment;
++ Cur3DSegment: T3DSegment;
++ Cur2DBezierSegment: T2DBezierSegment;
++ Cur3DBezierSegment: T3DBezierSegment;
+ begin
+ AStrings.Clear;
+
+@@ -51,25 +55,39 @@
+ // levanta a broca
+ AStrings.Add('P01 // Sobe a cabeça de gravação');
+ // vai para o ponto inicial
++ CurSegment := T2DSegment(APath.Points);
+ AStrings.Add(Format('G01 X%f Y%f',
+- [APath.Points[0].X, APath.Points[0].Y]));
++ [CurSegment.X, CurSegment.Y]));
+ AStrings.Add('P02 // Abaixa a cabeça de gravação');
+
+ for j := 1 to APath.Len - 1 do
+ begin
+- case APath.Points[j].SegmentType of
++ CurSegment := T2DSegment(CurSegment.Next);
++ case CurSegment.SegmentType of
+ st2DLine: AStrings.Add(Format('G01 X%f Y%f',
+- [APath.Points[j].X, APath.Points[j].Y]));
+- st3DLine: AStrings.Add(Format('G01 X%f Y%f Z%f',
+- [APath.Points[j].X, APath.Points[j].Y, APath.Points[j].Z]));
+- st2DBezier: AStrings.Add(Format('B02 X%f Y%f X%f Y%f X%f Y%f',
+- [APath.Points[j].X2, APath.Points[j].Y2,
+- APath.Points[j].X3, APath.Points[j].Y3,
+- APath.Points[j].X, APath.Points[j].Y]));
+- st3DBezier: AStrings.Add(Format('B03 X%f Y%f Z%f X%f Y%f Z%f X%f Y%f Z%f',
+- [APath.Points[j].X2, APath.Points[j].Y2, APath.Points[j].Z2,
+- APath.Points[j].X3, APath.Points[j].Y3, APath.Points[j].Z3,
+- APath.Points[j].X, APath.Points[j].Y, APath.Points[j].Z]));
++ [CurSegment.X, CurSegment.Y]));
++ st3DLine:
++ begin
++ Cur3DSegment := T3DSegment(CurSegment);
++ AStrings.Add(Format('G01 X%f Y%f Z%f',
++ [Cur3DSegment.X, Cur3DSegment.Y, Cur3DSegment.Z]));
++ end;
++ st2DBezier:
++ begin
++ Cur2DBezierSegment := T2DBezierSegment(CurSegment);
++ AStrings.Add(Format('B02 X%f Y%f X%f Y%f X%f Y%f',
++ [Cur2DBezierSegment.X2, Cur2DBezierSegment.Y2,
++ Cur2DBezierSegment.X3, Cur2DBezierSegment.Y3,
++ Cur2DBezierSegment.X, Cur2DBezierSegment.Y]));
++ end;
++ st3DBezier:
++ begin
++ Cur3DBezierSegment := T3DBezierSegment(CurSegment);
++ AStrings.Add(Format('B03 X%f Y%f Z%f X%f Y%f Z%f X%f Y%f Z%f',
++ [Cur3DBezierSegment.X2, Cur3DBezierSegment.Y2, Cur3DBezierSegment.Z2,
++ Cur3DBezierSegment.X3, Cur3DBezierSegment.Y3, Cur3DBezierSegment.Z3,
++ Cur3DBezierSegment.X, Cur3DBezierSegment.Y, Cur3DBezierSegment.Z]));
++ end;
+ end;
+ end;
+ end;
diff --git a/graphics/fpc-fpvectorial/files/patch-packages-fpvectorial-src_fpvectorial.pas b/graphics/fpc-fpvectorial/files/patch-packages-fpvectorial-src_fpvectorial.pas
new file mode 100644
index 000000000000..c95a9aca78fa
--- /dev/null
+++ b/graphics/fpc-fpvectorial/files/patch-packages-fpvectorial-src_fpvectorial.pas
@@ -0,0 +1,703 @@
+--- packages/fpvectorial/src/fpvectorial.pas 2011/01/30 15:51:36 16850
++++ packages/fpvectorial/src/fpvectorial.pas 2011/06/17 09:52:19 17765
+@@ -18,14 +18,17 @@
+ interface
+
+ uses
+- Classes, SysUtils, Math;
++ Classes, SysUtils, Math,
++ fpcanvas, fpimage;
+
+ type
+ TvVectorialFormat = (
+ { Multi-purpose document formats }
+- vfPDF, vfPostScript, vfSVG, vfCorelDrawCDR, vfWindowsMetafileWMF,
++ vfPDF, vfSVG, vfCorelDrawCDR, vfWindowsMetafileWMF,
+ { CAD formats }
+ vfDXF,
++ { Printing formats }
++ vfPostScript, vfEncapsulatedPostScript,
+ { GCode formats }
+ vfGCodeAvisoCNCPrototipoV5, vfGCodeAvisoCNCPrototipoV6);
+
+@@ -37,10 +40,45 @@
+ STR_SVG_EXTENSION = '.svg';
+ STR_CORELDRAW_EXTENSION = '.cdr';
+ STR_WINMETAFILE_EXTENSION = '.wmf';
++ STR_AUTOCAD_EXCHANGE_EXTENSION = '.dxf';
++ STR_ENCAPSULATEDPOSTSCRIPT_EXTENSION = '.eps';
+
+ type
++ { Pen, Brush and Font }
++
++ TvPen = record
++ Color: TFPColor;
++ Style: TFPPenStyle;
++ Width: Integer;
++ end;
++
++ TvBrush = record
++ Color: TFPColor;
++ Style: TFPBrushStyle;
++ end;
++
++ TvFont = record
++ Color: TFPColor;
++ Size: integer;
++ Name: utf8string;
++ {@@
++ Font orientation is measured in degrees and uses the
++ same direction as the LCL TFont.orientation, which is counter-clockwise.
++ Zero is the normal, horizontal, orientation.
++ }
++ Orientation: Double;
++ end;
++
++ { Coordinates and polyline segments }
++
++ T3DPoint = record
++ X, Y, Z: Double;
++ end;
++
++ P3DPoint = ^T3DPoint;
++
+ TSegmentType = (
+- st2DLine, st2DBezier,
++ st2DLine, st2DLineWithPen, st2DBezier,
+ st3DLine, st3DBezier, stMoveTo);
+
+ {@@
+@@ -70,6 +108,11 @@
+ X, Y: Double;
+ end;
+
++ T2DSegmentWithPen = class(T2DSegment)
++ public
++ Pen: TvPen;
++ end;
++
+ {@@
+ 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
+@@ -96,13 +139,30 @@
+ X3, Y3, Z3: Double;
+ end;
+
+- TPath = class
++ { Now all elements }
++
++ {@@
++ All elements should derive from TvEntity, regardless of whatever properties
++ they might contain.
++ }
++
++ TvEntity = class
++ public
++ {@@ The global Pen for the entire entity. In the case of paths, individual
++ elements might be able to override this setting. }
++ Pen: TvPen;
++ {@@ The global Brush for the entire entity. In the case of paths, individual
++ elements might be able to override this setting. }
++ Brush: TvBrush;
++ constructor Create; virtual;
++ end;
++
++ TPath = class(TvEntity)
+ Len: Integer;
+ Points: TPathSegment; // Beginning of the double-linked list
+ PointsEnd: TPathSegment; // End of the double-linked list
+ CurPoint: TPathSegment; // Used in PrepareForSequentialReading and Next
+- procedure Assign(APath: TPath);
+- function Count(): TPathSegment;
++ procedure Assign(ASource: TPath);
+ procedure PrepareForSequentialReading;
+ function Next(): TPathSegment;
+ end;
+@@ -113,18 +173,11 @@
+ At the moment fonts are unsupported, only simple texts
+ up to 255 chars are supported.
+ }
+- TvText = class
++ TvText = class(TvEntity)
+ public
+ X, Y, Z: Double; // Z is ignored in 2D formats
+- FontSize: integer;
+- FontName: utf8string;
+ Value: utf8string;
+- end;
+-
+- {@@
+- }
+- TvEntity = class
+- public
++ Font: TvFont;
+ end;
+
+ {@@
+@@ -145,9 +198,6 @@
+
+ {@@
+ }
+-
+- { TvEllipse }
+-
+ TvEllipse = class(TvEntity)
+ public
+ // Mandatory fields
+@@ -159,6 +209,24 @@
+ procedure CalculateBoundingRectangle;
+ end;
+
++ {@@
++ The brush has no effect in this class
++
++ DimensionLeft ---text--- DimensionRight
++ | |
++ | | BaseRight
++ |
++ | BaseLeft
++ }
++
++ { TvAlignedDimension }
++
++ TvAlignedDimension = class(TvEntity)
++ public
++ // Mandatory fields
++ BaseLeft, BaseRight, DimensionLeft, DimensionRight: T3DPoint;
++ end;
++
+ type
+
+ TvCustomVectorialWriter = class;
+@@ -168,8 +236,6 @@
+
+ TvVectorialDocument = class
+ private
+- FPaths: TFPList;
+- FTexts: TFPList;
+ FEntities: TFPList;
+ FTmpPath: TPath;
+ FTmpText: TvText;
+@@ -184,10 +250,14 @@
+ { Base methods }
+ constructor Create;
+ destructor Destroy; override;
+- procedure WriteToFile(AFileName: string; AFormat: TvVectorialFormat);
++ procedure Assign(ASource: TvVectorialDocument);
++ procedure AssignTo(ADest: TvVectorialDocument);
++ procedure WriteToFile(AFileName: string; AFormat: TvVectorialFormat); overload;
++ procedure WriteToFile(AFileName: string); overload;
+ procedure WriteToStream(AStream: TStream; AFormat: TvVectorialFormat);
+ procedure WriteToStrings(AStrings: TStrings; AFormat: TvVectorialFormat);
+- procedure ReadFromFile(AFileName: string; AFormat: TvVectorialFormat);
++ procedure ReadFromFile(AFileName: string; AFormat: TvVectorialFormat); overload;
++ procedure ReadFromFile(AFileName: string); overload;
+ procedure ReadFromStream(AStream: TStream; AFormat: TvVectorialFormat);
+ procedure ReadFromStrings(AStrings: TStrings; AFormat: TvVectorialFormat);
+ class function GetFormatFromExtension(AFileName: string): TvVectorialFormat;
+@@ -195,27 +265,35 @@
+ { Data reading methods }
+ function GetPath(ANum: Cardinal): TPath;
+ function GetPathCount: Integer;
+- function GetText(ANum: Cardinal): TvText;
+- function GetTextCount: Integer;
+ function GetEntity(ANum: Cardinal): TvEntity;
+- function GetEntityCount: Integer;
++ function GetEntitiesCount: Integer;
+ { Data removing methods }
+ procedure Clear;
+- procedure RemoveAllPaths;
+- procedure RemoveAllTexts;
+ { Data writing methods }
+- procedure AddPath(APath: TPath);
+- procedure StartPath(AX, AY: Double);
++ procedure AddEntity(AEntity: TvEntity);
++ procedure AddPathCopyMem(APath: TPath);
++ procedure StartPath(AX, AY: Double); overload;
++ procedure StartPath(); overload;
++ procedure AddMoveToPath(AX, AY: Double);
+ procedure AddLineToPath(AX, AY: Double); overload;
++ procedure AddLineToPath(AX, AY: Double; AColor: TFPColor); overload;
+ procedure AddLineToPath(AX, AY, AZ: Double); overload;
++ procedure GetCurrenPathPenPos(var AX, AY: Double);
+ procedure AddBezierToPath(AX1, AY1, AX2, AY2, AX3, AY3: Double); overload;
+ procedure AddBezierToPath(AX1, AY1, AZ1, AX2, AY2, AZ2, AX3, AY3, AZ3: Double); overload;
++ procedure SetBrushColor(AColor: TFPColor);
++ procedure SetBrushStyle(AStyle: TFPBrushStyle);
++ procedure SetPenColor(AColor: TFPColor);
++ procedure SetPenStyle(AStyle: TFPPenStyle);
++ procedure SetPenWidth(AWidth: Integer);
+ procedure EndPath();
+ procedure AddText(AX, AY, AZ: Double; FontName: string; FontSize: integer; AText: utf8string); overload;
+ procedure AddText(AX, AY, AZ: Double; AStr: utf8string); overload;
+ procedure AddCircle(ACenterX, ACenterY, ACenterZ, ARadius: Double);
+- procedure AddCircularArc(ACenterX, ACenterY, ACenterZ, ARadius, AStartAngle, AEndAngle: Double);
++ procedure AddCircularArc(ACenterX, ACenterY, ACenterZ, ARadius, AStartAngle, AEndAngle: Double; AColor: TFPColor);
+ procedure AddEllipse(CenterX, CenterY, CenterZ, MajorHalfAxis, MinorHalfAxis, Angle: Double);
++ // Dimensions
++ procedure AddAlignedDimension(BaseLeft, BaseRight, DimLeft, DimRight: T3DPoint);
+ { properties }
+ property PathCount: Integer read GetPathCount;
+ property Paths[Index: Cardinal]: TPath read GetPath;
+@@ -272,6 +350,7 @@
+ procedure RegisterVectorialWriter(
+ AWriterClass: TvVectorialWriterClass;
+ AFormat: TvVectorialFormat);
++function Make2DPoint(AX, AY: Double): T3DPoint;
+
+ implementation
+
+@@ -362,6 +441,23 @@
+ end;
+ end;
+
++function Make2DPoint(AX, AY: Double): T3DPoint;
++begin
++ Result.X := AX;
++ Result.Y := AY;
++ Result.Z := 0;
++end;
++
++{ TvEntity }
++
++constructor TvEntity.Create;
++begin
++ Pen.Style := psSolid;
++ Pen.Color := colBlack;
++ Brush.Style := bsClear;
++ Brush.Color := colBlue;
++end;
++
+ { TvEllipse }
+
+ procedure TvEllipse.CalculateBoundingRectangle;
+@@ -415,8 +511,6 @@
+ begin
+ inherited Create;
+
+- FPaths := TFPList.Create;
+- FTexts := TFPList.Create;
+ FEntities := TFPList.Create;
+ FTmpPath := TPath.Create;
+ end;
+@@ -428,40 +522,35 @@
+ begin
+ Clear;
+
+- FPaths.Free;
+- FTexts.Free;
+ FEntities.Free;
+
+ inherited Destroy;
+ end;
+
+-{@@
+- Clears the list of Vectors and releases their memory.
+-}
+-procedure TvVectorialDocument.RemoveAllPaths;
++procedure TvVectorialDocument.Assign(ASource: TvVectorialDocument);
++var
++ i: Integer;
+ begin
+-// FPaths.ForEachCall(RemoveCallback, nil);
+- FPaths.Clear;
++ Clear;
++
++ for i := 0 to ASource.GetEntitiesCount - 1 do
++ Self.AddEntity(ASource.GetEntity(i));
+ end;
+
+-procedure TvVectorialDocument.RemoveAllTexts;
++procedure TvVectorialDocument.AssignTo(ADest: TvVectorialDocument);
+ begin
+-// FTexts.ForEachCall(RemoveCallback, nil);
+- FTexts.Clear;
++ ADest.Assign(Self);
+ end;
+
+-procedure TvVectorialDocument.AddPath(APath: TPath);
++procedure TvVectorialDocument.AddPathCopyMem(APath: TPath);
+ var
+ lPath: TPath;
+ Len: Integer;
+ begin
+ lPath := TPath.Create;
+ lPath.Assign(APath);
+- FPaths.Add(Pointer(lPath));
++ AddEntity(lPath);
+ //WriteLn(':>TvVectorialDocument.AddPath 1 Len = ', Len);
+- //WriteLn(':>TvVectorialDocument.AddPath 2');
+- //WriteLn(':>TvVectorialDocument.AddPath 3');
+- //WriteLn(':>TvVectorialDocument.AddPath 4');
+ end;
+
+ {@@
+@@ -487,6 +576,23 @@
+ FTmpPath.PointsEnd := segment;
+ end;
+
++procedure TvVectorialDocument.StartPath();
++begin
++ ClearTmpPath();
++end;
++
++procedure TvVectorialDocument.AddMoveToPath(AX, AY: Double);
++var
++ segment: T2DSegment;
++begin
++ segment := T2DSegment.Create;
++ segment.SegmentType := stMoveTo;
++ segment.X := AX;
++ segment.Y := AY;
++
++ AppendSegmentToTmpPath(segment);
++end;
++
+ {@@
+ Adds one more point to the end of a Path being
+ writing in multiple steps.
+@@ -509,6 +615,19 @@
+ AppendSegmentToTmpPath(segment);
+ end;
+
++procedure TvVectorialDocument.AddLineToPath(AX, AY: Double; AColor: TFPColor);
++var
++ segment: T2DSegmentWithPen;
++begin
++ segment := T2DSegmentWithPen.Create;
++ segment.SegmentType := st2DLineWithPen;
++ segment.X := AX;
++ segment.Y := AY;
++ segment.Pen.Color := AColor;
++
++ AppendSegmentToTmpPath(segment);
++end;
++
+ procedure TvVectorialDocument.AddLineToPath(AX, AY, AZ: Double);
+ var
+ segment: T3DSegment;
+@@ -523,6 +642,18 @@
+ end;
+
+ {@@
++ Gets the current Pen Pos in the temporary path
++}
++procedure TvVectorialDocument.GetCurrenPathPenPos(var AX, AY: Double);
++begin
++ // Check if we are the first segment in the tmp path
++ if FTmpPath.PointsEnd = nil then raise Exception.Create('[TvVectorialDocument.GetCurrenPathPenPos] One cannot obtain the Pen Pos if there are no segments in the temporary path');
++
++ AX := T2DSegment(FTmpPath.PointsEnd).X;
++ AY := T2DSegment(FTmpPath.PointsEnd).Y;
++end;
++
++{@@
+ Adds a bezier element to the path. It starts where the previous element ended
+ and it goes throw the control points [AX1, AY1] and [AX2, AY2] and ends
+ in [AX3, AY3].
+@@ -564,6 +695,31 @@
+ AppendSegmentToTmpPath(segment);
+ end;
+
++procedure TvVectorialDocument.SetBrushColor(AColor: TFPColor);
++begin
++ FTmPPath.Brush.Color := AColor;
++end;
++
++procedure TvVectorialDocument.SetBrushStyle(AStyle: TFPBrushStyle);
++begin
++ FTmPPath.Brush.Style := AStyle;
++end;
++
++procedure TvVectorialDocument.SetPenColor(AColor: TFPColor);
++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
+ steps using StartPath and AddPointToPath,
+@@ -577,7 +733,7 @@
+ procedure TvVectorialDocument.EndPath();
+ begin
+ if FTmPPath.Len = 0 then Exit;
+- AddPath(FTmPPath);
++ AddPathCopyMem(FTmPPath);
+ ClearTmpPath();
+ end;
+
+@@ -590,9 +746,9 @@
+ lText.X := AX;
+ lText.Y := AY;
+ lText.Z := AZ;
+- lText.FontName := FontName;
+- lText.FontSize := FontSize;
+- FTexts.Add(lText);
++ lText.Font.Name := FontName;
++ lText.Font.Size := FontSize;
++ AddEntity(lText);
+ end;
+
+ procedure TvVectorialDocument.AddText(AX, AY, AZ: Double; AStr: utf8string);
+@@ -609,11 +765,11 @@
+ lCircle.CenterY := ACenterY;
+ lCircle.CenterZ := ACenterZ;
+ lCircle.Radius := ARadius;
+- FEntities.Add(lCircle);
++ AddEntity(lCircle);
+ end;
+
+ procedure TvVectorialDocument.AddCircularArc(ACenterX, ACenterY, ACenterZ,
+- ARadius, AStartAngle, AEndAngle: Double);
++ ARadius, AStartAngle, AEndAngle: Double; AColor: TFPColor);
+ var
+ lCircularArc: TvCircularArc;
+ begin
+@@ -624,7 +780,8 @@
+ lCircularArc.Radius := ARadius;
+ lCircularArc.StartAngle := AStartAngle;
+ lCircularArc.EndAngle := AEndAngle;
+- FEntities.Add(lCircularArc);
++ lCircularArc.Pen.Color := AColor;
++ AddEntity(lCircularArc);
+ end;
+
+ procedure TvVectorialDocument.AddEllipse(CenterX, CenterY, CenterZ,
+@@ -639,7 +796,28 @@
+ lEllipse.MajorHalfAxis := MajorHalfAxis;
+ lEllipse.MinorHalfAxis := MinorHalfAxis;
+ lEllipse.Angle := Angle;
+- FEntities.Add(lEllipse);
++ AddEntity(lEllipse);
++end;
++
++{@@
++ Don't free the passed TvText because it will be added directly to the list
++}
++procedure TvVectorialDocument.AddEntity(AEntity: TvEntity);
++begin
++ FEntities.Add(Pointer(AEntity));
++end;
++
++procedure TvVectorialDocument.AddAlignedDimension(BaseLeft, BaseRight,
++ DimLeft, DimRight: T3DPoint);
++var
++ lDim: TvAlignedDimension;
++begin
++ lDim := TvAlignedDimension.Create;
++ lDim.BaseLeft := BaseLeft;
++ lDim.BaseRight := BaseRight;
++ lDim.DimensionLeft := DimLeft;
++ lDim.DimensionRight := DimRight;
++ AddEntity(lDim);
+ end;
+
+ {@@
+@@ -655,12 +833,13 @@
+ for i := 0 to Length(GvVectorialFormats) - 1 do
+ if GvVectorialFormats[i].Format = AFormat then
+ begin
+- Result := GvVectorialFormats[i].WriterClass.Create;
++ if GvVectorialFormats[i].WriterClass <> nil then
++ Result := GvVectorialFormats[i].WriterClass.Create;
+
+ Break;
+ end;
+
+- if Result = nil then raise Exception.Create('Unsuported vector graphics format.');
++ if Result = nil then raise Exception.Create('Unsupported vector graphics format.');
+ end;
+
+ {@@
+@@ -676,12 +855,13 @@
+ for i := 0 to Length(GvVectorialFormats) - 1 do
+ if GvVectorialFormats[i].Format = AFormat then
+ begin
+- Result := GvVectorialFormats[i].ReaderClass.Create;
++ if GvVectorialFormats[i].ReaderClass <> nil then
++ Result := GvVectorialFormats[i].ReaderClass.Create;
+
+ Break;
+ end;
+
+- if Result = nil then raise Exception.Create('Unsuported vector graphics format.');
++ if Result = nil then raise Exception.Create('Unsupported vector graphics format.');
+ end;
+
+ procedure TvVectorialDocument.ClearTmpPath();
+@@ -700,14 +880,28 @@
+ FTmpPath.Points := nil;
+ FTmpPath.PointsEnd := nil;
+ FTmpPath.Len := 0;
++ FTmpPath.Brush.Color := colBlue;
++ FTmpPath.Brush.Style := bsClear;
++ FTmpPath.Pen.Color := colBlack;
++ FTmpPath.Pen.Style := psSolid;
++ FTmpPath.Pen.Width := 1;
+ end;
+
+ procedure TvVectorialDocument.AppendSegmentToTmpPath(ASegment: TPathSegment);
+ var
+ L: Integer;
+ begin
++ // Check if we are the first segment in the tmp path
+ if FTmpPath.PointsEnd = nil then
+- Exception.Create('[TvVectorialDocument.AppendSegmentToTmpPath]' + Str_Error_Nil_Path);
++ begin
++ if FTmpPath.Len <> 0 then
++ Exception.Create('[TvVectorialDocument.AppendSegmentToTmpPath]' + Str_Error_Nil_Path);
++
++ FTmpPath.Points := ASegment;
++ FTmpPath.PointsEnd := ASegment;
++ FTmpPath.Len := 1;
++ Exit;
++ end;
+
+ L := FTmpPath.Len;
+ Inc(FTmpPath.Len);
+@@ -736,6 +930,14 @@
+ end;
+ end;
+
++procedure TvVectorialDocument.WriteToFile(AFileName: string);
++var
++ lFormat: TvVectorialFormat;
++begin
++ lFormat := GetFormatFromExtension(ExtractFileExt(AFileName));
++ WriteToFile(AFileName, lFormat);
++end;
++
+ {@@
+ Writes the document to a stream
+ }
+@@ -787,6 +989,17 @@
+ end;
+
+ {@@
++ Reads the document from a file. A variant that auto-detects the format from the extension.
++}
++procedure TvVectorialDocument.ReadFromFile(AFileName: string);
++var
++ lFormat: TvVectorialFormat;
++begin
++ lFormat := GetFormatFromExtension(ExtractFileExt(AFileName));
++ ReadFromFile(AFileName, lFormat);
++end;
++
++{@@
+ Reads the document from a stream.
+
+ Any current contents will be removed.
+@@ -832,6 +1045,8 @@
+ else if AnsiCompareText(lExt, STR_SVG_EXTENSION) = 0 then Result := vfSVG
+ else if AnsiCompareText(lExt, STR_CORELDRAW_EXTENSION) = 0 then Result := vfCorelDrawCDR
+ else if AnsiCompareText(lExt, STR_WINMETAFILE_EXTENSION) = 0 then Result := vfWindowsMetafileWMF
++ else if AnsiCompareText(lExt, STR_AUTOCAD_EXCHANGE_EXTENSION) = 0 then Result := vfDXF
++ else if AnsiCompareText(lExt, STR_ENCAPSULATEDPOSTSCRIPT_EXTENSION) = 0 then Result := vfEncapsulatedPostScript
+ else
+ raise Exception.Create('TvVectorialDocument.GetFormatFromExtension: The extension (' + lExt + ') doesn''t match any supported formats.');
+ end;
+@@ -842,31 +1057,32 @@
+ end;
+
+ function TvVectorialDocument.GetPath(ANum: Cardinal): TPath;
++var
++ i: Integer;
++ Index: Integer = - 1;
+ begin
+- if ANum >= FPaths.Count then raise Exception.Create('TvVectorialDocument.GetPath: Path number out of bounds');
++ Result := nil;
+
+- if FPaths.Items[ANum] = nil then raise Exception.Create('TvVectorialDocument.GetPath: Invalid Path number');
++ if ANum >= FEntities.Count then raise Exception.Create('TvVectorialDocument.GetPath: Path number out of bounds');
+
+- Result := TPath(FPaths.Items[ANum]);
++ for i := 0 to FEntities.Count - 1 do
++ begin
++ if TvEntity(FEntities.Items[i]) is TPath then
++ begin
++ Inc(Index);
++ if Index = ANum then Result := TPath(FEntities.Items[i]);
++ end;
++ end;
+ end;
+
+ function TvVectorialDocument.GetPathCount: Integer;
++var
++ i: Integer;
+ begin
+- Result := FPaths.Count;
+-end;
+-
+-function TvVectorialDocument.GetText(ANum: Cardinal): TvText;
+-begin
+- if ANum >= FTexts.Count then raise Exception.Create('TvVectorialDocument.GetText: Text number out of bounds');
++ Result := 0;
+
+- if FTexts.Items[ANum] = nil then raise Exception.Create('TvVectorialDocument.GetText: Invalid Text number');
+-
+- Result := TvText(FTexts.Items[ANum]);
+-end;
+-
+-function TvVectorialDocument.GetTextCount: Integer;
+-begin
+- Result := FTexts.Count;
++ for i := 0 to FEntities.Count - 1 do
++ if TvEntity(FEntities.Items[i]) is TPath then Inc(Result);
+ end;
+
+ function TvVectorialDocument.GetEntity(ANum: Cardinal): TvEntity;
+@@ -878,7 +1094,7 @@
+ Result := TvEntity(FEntities.Items[ANum]);
+ end;
+
+-function TvVectorialDocument.GetEntityCount: Integer;
++function TvVectorialDocument.GetEntitiesCount: Integer;
+ begin
+ Result := FEntities.Count;
+ end;
+@@ -888,8 +1104,7 @@
+ }
+ procedure TvVectorialDocument.Clear;
+ begin
+- RemoveAllPaths();
+- RemoveAllTexts();
++ FEntities.Clear();
+ end;
+
+ { TvCustomVectorialReader }
+@@ -1000,17 +1215,14 @@
+
+ { TPath }
+
+-procedure TPath.Assign(APath: TPath);
++procedure TPath.Assign(ASource: TPath);
+ begin
+- Len := APath.Len;
+- Points := APath.Points;
+- PointsEnd := APath.PointsEnd;
+- CurPoint := APath.CurPoint;
+-end;
+-
+-function TPath.Count(): TPathSegment;
+-begin
+-
++ Len := ASource.Len;
++ Points := ASource.Points;
++ PointsEnd := ASource.PointsEnd;
++ CurPoint := ASource.CurPoint;
++ Pen := ASource.Pen;
++ Brush := ASource.Brush;
+ end;
+
+ procedure TPath.PrepareForSequentialReading;
diff --git a/graphics/fpc-fpvectorial/files/patch-packages-fpvectorial-src_fpvtocanvas.pas b/graphics/fpc-fpvectorial/files/patch-packages-fpvectorial-src_fpvtocanvas.pas
new file mode 100644
index 000000000000..4d89d2c45735
--- /dev/null
+++ b/graphics/fpc-fpvectorial/files/patch-packages-fpvectorial-src_fpvtocanvas.pas
@@ -0,0 +1,540 @@
+--- packages/fpvectorial/src/fpvtocanvas.pas 2011/01/30 15:51:36 16850
++++ packages/fpvectorial/src/fpvtocanvas.pas 2011/06/17 09:52:19 17765
+@@ -10,21 +10,30 @@
+ Classes, SysUtils, Math,
+ {$ifdef USE_LCL_CANVAS}
+ Graphics, LCLIntf,
+- {$else}
+- fpcanvas,
+ {$endif}
++ fpcanvas,
++ fpimage,
+ fpvectorial;
+
+ 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);
++procedure DrawFPVPathToCanvas(ASource: TvVectorialDocument; CurPath: TPath;
++ ADest: TFPCustomCanvas;
++ ADestX: Integer = 0; ADestY: Integer = 0; AMulX: Double = 1.0; AMulY: Double = 1.0);
++procedure DrawFPVEntityToCanvas(ASource: TvVectorialDocument; CurEntity: TvEntity;
++ ADest: TFPCustomCanvas;
++ ADestX: Integer = 0; ADestY: Integer = 0; AMulX: Double = 1.0; AMulY: Double = 1.0);
++procedure DrawFPVTextToCanvas(ASource: TvVectorialDocument; CurText: TvText;
++ ADest: TFPCustomCanvas;
+ ADestX: Integer = 0; ADestY: Integer = 0; AMulX: Double = 1.0; AMulY: Double = 1.0);
+
+ implementation
+
++{$ifndef Windows}
++{$define FPVECTORIALDEBUG}
++{$endif}
++
+ function Rotate2DPoint(P,Fix :TPoint; alpha:double): TPoint;
+ var
+ sinus, cosinus : Extended;
+@@ -37,17 +46,16 @@
+ end;
+
+ 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;
+ f: TPoint;
+ dk, x1, x2, y1, y2: Integer;
++ {$ifdef USE_LCL_CANVAS}
++ ALCLDest: TCanvas absolute ADest;
++ {$endif}
+ begin
+ {$ifdef USE_LCL_CANVAS}
+ CurEllipse.CalculateBoundingRectangle();
+@@ -72,7 +80,7 @@
+ // Conrollpoint of secondpart endpoint
+ PointList[6] := PointList[0]; // Endpoint of
+ // Back to the startpoint
+- ADest.PolyBezier(Pointlist[0]);
++ ALCLDest.PolyBezier(Pointlist[0]);
+ {$endif}
+ end;
+
+@@ -90,15 +98,48 @@
+
+ DrawFPVectorialToCanvas(ASource, ADest, 0, ASource.Height, 1.0, -1.0);
+ }
++{.$define FPVECTORIAL_TOCANVAS_DEBUG}
+ procedure DrawFPVectorialToCanvas(ASource: TvVectorialDocument;
+- {$ifdef USE_LCL_CANVAS}
+- ADest: TCanvas;
+- {$else}
+ ADest: TFPCustomCanvas;
++ ADestX: Integer = 0; ADestY: Integer = 0; AMulX: Double = 1.0; AMulY: Double = 1.0);
++var
++ i: Integer;
++ CurEntity: TvEntity;
++begin
++ {$ifdef FPVECTORIAL_TOCANVAS_DEBUG}
++ WriteLn(':>DrawFPVectorialToCanvas');
++ {$endif}
++
++ for i := 0 to ASource.GetEntitiesCount - 1 do
++ begin
++ CurEntity := ASource.GetEntity(i);
++
++ if CurEntity is TPath then DrawFPVPathToCanvas(ASource, TPath(CurEntity), ADest, ADestX, ADestY, AMulX, AMulY)
++ else if CurEntity is TvText then DrawFPVTextToCanvas(ASource, TvText(CurEntity), ADest, ADestX, ADestY, AMulX, AMulY)
++ else DrawFPVEntityToCanvas(ASource, CurEntity, ADest, ADestX, ADestY, AMulX, AMulY);
++ end;
++
++ {$ifdef FPVECTORIALDEBUG}
++ WriteLn(':<DrawFPVectorialToCanvas');
+ {$endif}
++end;
++
++procedure DrawFPVPathToCanvas(ASource: TvVectorialDocument; CurPath: TPath;
++ ADest: TFPCustomCanvas;
+ ADestX: Integer = 0; ADestY: Integer = 0; AMulX: Double = 1.0; AMulY: Double = 1.0);
++
++ function CoordToCanvasX(ACoord: Double): Integer;
++ begin
++ Result := Round(ADestX + AmulX * ACoord);
++ end;
++
++ function CoordToCanvasY(ACoord: Double): Integer;
++ begin
++ Result := Round(ADestY + AmulY * ACoord);
++ end;
++
+ var
+- i, j, k: Integer;
++ j, k: Integer;
+ PosX, PosY: Integer; // Not modified by ADestX, etc
+ CurSegment: TPathSegment;
+ Cur2DSegment: T2DSegment absolute CurSegment;
+@@ -107,123 +148,327 @@
+ CurX, CurY: Integer; // Not modified by ADestX, etc
+ CurveLength: Integer;
+ t: Double;
+- // For text
+- CurText: TvText;
+- // For entities
+- CurEntity: TvEntity;
+- CurCircle: TvCircle;
+- CurEllipse: TvEllipse;
+- CurArc: TvCircularArc;
+ begin
+- {$ifdef FPVECTORIALDEBUG}
+- WriteLn(':>DrawFPVectorialToCanvas');
+- {$endif}
+-
+ PosX := 0;
+ PosY := 0;
++ ADest.Brush.Style := bsClear;
+
+ ADest.MoveTo(ADestX, ADestY);
+
+- // Draws all paths
+- for i := 0 to ASource.PathCount - 1 do
++ CurPath.PrepareForSequentialReading;
++
++ // Set the path Pen and Brush options
++ ADest.Pen.Style := CurPath.Pen.Style;
++ ADest.Pen.Width := CurPath.Pen.Width;
++ ADest.Brush.Style := CurPath.Brush.Style;
++ ADest.Pen.FPColor := CurPath.Pen.Color;
++ ADest.Brush.FPColor := CurPath.Brush.Color;
++
++ {$ifdef FPVECTORIAL_TOCANVAS_DEBUG}
++ Write(Format('[Path] ID=%d', [i]));
++ {$endif}
++
++ for j := 0 to CurPath.Len - 1 do
+ begin
+- //WriteLn('i = ', i);
+- ASource.Paths[i].PrepareForSequentialReading;
++ //WriteLn('j = ', j);
++ CurSegment := TPathSegment(CurPath.Next());
+
+- for j := 0 to ASource.Paths[i].Len - 1 do
++ case CurSegment.SegmentType of
++ stMoveTo:
++ begin
++ ADest.MoveTo(CoordToCanvasX(Cur2DSegment.X), CoordToCanvasY(Cur2DSegment.Y));
++ {$ifdef FPVECTORIAL_TOCANVAS_DEBUG}
++ Write(Format(' M%d,%d', [CoordToCanvasX(Cur2DSegment.X), CoordToCanvasY(Cur2DSegment.Y)]));
++ {$endif}
++ end;
++ // This element can override temporarely the Pen
++ st2DLineWithPen:
+ begin
+- //WriteLn('j = ', j);
+- CurSegment := TPathSegment(ASource.Paths[i].Next());
++ ADest.Pen.FPColor := T2DSegmentWithPen(Cur2DSegment).Pen.Color;
+
+- case CurSegment.SegmentType of
+- stMoveTo:
+- begin
+- ADest.MoveTo(
+- Round(ADestX + AMulX * Cur2DSegment.X),
+- Round(ADestY + AMulY * Cur2DSegment.Y)
+- );
+- end;
+- st2DLine, st3DLine:
+- begin
+- ADest.LineTo(
+- Round(ADestX + AMulX * Cur2DSegment.X),
+- Round(ADestY + AMulY * Cur2DSegment.Y)
+- );
+- end;
+- { To draw a bezier we need to divide the interval in parts and make
+- lines between this parts }
+- st2DBezier, st3DBezier:
++ ADest.LineTo(CoordToCanvasX(Cur2DSegment.X), CoordToCanvasY(Cur2DSegment.Y));
++
++ ADest.Pen.FPColor := CurPath.Pen.Color;
++
++ {$ifdef FPVECTORIAL_TOCANVAS_DEBUG}
++ Write(Format(' L%d,%d', [CoordToCanvasX(Cur2DSegment.X), CoordToCanvasY(Cur2DSegment.Y)]));
++ {$endif}
++ 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
++ lines between this parts }
++ st2DBezier, st3DBezier:
++ begin
++ CurveLength :=
++ Round(sqrt(sqr(Cur2DBSegment.X3 - PosX) + sqr(Cur2DBSegment.Y3 - PosY))) +
++ Round(sqrt(sqr(Cur2DBSegment.X2 - Cur2DBSegment.X3) + sqr(Cur2DBSegment.Y2 - Cur2DBSegment.Y3))) +
++ Round(sqrt(sqr(Cur2DBSegment.X - Cur2DBSegment.X3) + sqr(Cur2DBSegment.Y - Cur2DBSegment.Y3)));
++
++ for k := 1 to CurveLength do
+ begin
+- CurveLength :=
+- Round(sqrt(sqr(Cur2DBSegment.X3 - PosX) + sqr(Cur2DBSegment.Y3 - PosY))) +
+- Round(sqrt(sqr(Cur2DBSegment.X2 - Cur2DBSegment.X3) + sqr(Cur2DBSegment.Y2 - Cur2DBSegment.Y3))) +
+- Round(sqrt(sqr(Cur2DBSegment.X - Cur2DBSegment.X3) + sqr(Cur2DBSegment.Y - Cur2DBSegment.Y3)));
+-
+- for k := 1 to CurveLength do
+- begin
+- t := k / CurveLength;
+- CurX := Round(sqr(1 - t) * (1 - t) * PosX + 3 * t * sqr(1 - t) * Cur2DBSegment.X2 + 3 * t * t * (1 - t) * Cur2DBSegment.X3 + t * t * t * Cur2DBSegment.X);
+- CurY := Round(sqr(1 - t) * (1 - t) * PosY + 3 * t * sqr(1 - t) * Cur2DBSegment.Y2 + 3 * t * t * (1 - t) * Cur2DBSegment.Y3 + t * t * t * Cur2DBSegment.Y);
+- ADest.LineTo(
+- Round(ADestX + AMulX * CurX),
+- Round(ADestY + AMulY * CurY));
+- end;
+- PosX := Round(Cur2DBSegment.X);
+- PosY := Round(Cur2DBSegment.Y);
+- end;
++ t := k / CurveLength;
++ CurX := Round(sqr(1 - t) * (1 - t) * PosX + 3 * t * sqr(1 - t) * Cur2DBSegment.X2 + 3 * t * t * (1 - t) * Cur2DBSegment.X3 + t * t * t * Cur2DBSegment.X);
++ CurY := Round(sqr(1 - t) * (1 - t) * PosY + 3 * t * sqr(1 - t) * Cur2DBSegment.Y2 + 3 * t * t * (1 - t) * Cur2DBSegment.Y3 + t * t * t * Cur2DBSegment.Y);
++ ADest.LineTo(CoordToCanvasX(CurX), CoordToCanvasY(CurY));
+ end;
++ PosX := Round(Cur2DBSegment.X);
++ PosY := Round(Cur2DBSegment.Y);
++ end;
+ end;
+ end;
++ {$ifdef FPVECTORIAL_TOCANVAS_DEBUG}
++ WriteLn('');
++ {$endif}
++end;
++
++procedure DrawFPVEntityToCanvas(ASource: TvVectorialDocument; CurEntity: TvEntity;
++ ADest: TFPCustomCanvas;
++ ADestX: Integer = 0; ADestY: Integer = 0; AMulX: Double = 1.0; AMulY: Double = 1.0);
+
+- // Draws all entities
+- for i := 0 to ASource.GetEntityCount - 1 do
++ function CoordToCanvasX(ACoord: Double): Integer;
+ begin
+- CurEntity := ASource.GetEntity(i);
+- if CurEntity is TvCircle then
++ Result := Round(ADestX + AmulX * ACoord);
++ end;
++
++ function CoordToCanvasY(ACoord: Double): Integer;
++ begin
++ Result := Round(ADestY + AmulY * ACoord);
++ end;
++
++var
++ i: Integer;
++ {$ifdef USE_LCL_CANVAS}
++ ALCLDest: TCanvas;
++ {$endif}
++ // For entities
++ CurCircle: TvCircle;
++ CurEllipse: TvEllipse;
++ //
++ CurArc: TvCircularArc;
++ FinalStartAngle, FinalEndAngle: double;
++ BoundsLeft, BoundsTop, BoundsRight, BoundsBottom,
++ IntStartAngle, IntAngleLength, IntTmp: Integer;
++ //
++ CurDim: TvAlignedDimension;
++ Points: array of TPoint;
++ UpperDim, LowerDim: T3DPoint;
++begin
++ {$ifdef USE_LCL_CANVAS}
++ ALCLDest := TCanvas(ADest);
++ {$endif}
++
++ ADest.Brush.Style := CurEntity.Brush.Style;
++ ADest.Pen.Style := CurEntity.Pen.Style;
++ ADest.Pen.FPColor := CurEntity.Pen.Color;
++ ADest.Brush.FPColor := CurEntity.Brush.Color;
++
++ if CurEntity is TvCircle then
++ begin
++ CurCircle := CurEntity as TvCircle;
++ ADest.Ellipse(
++ CoordToCanvasX(CurCircle.CenterX - CurCircle.Radius),
++ CoordToCanvasY(CurCircle.CenterY - CurCircle.Radius),
++ CoordToCanvasX(CurCircle.CenterX + CurCircle.Radius),
++ CoordToCanvasY(CurCircle.CenterY + CurCircle.Radius)
++ );
++ end
++ else if CurEntity is TvEllipse then
++ begin
++ CurEllipse := CurEntity as TvEllipse;
++ DrawRotatedEllipse(ADest, CurEllipse);
++ end
++ else if CurEntity is TvCircularArc then
++ begin
++ CurArc := CurEntity as TvCircularArc;
++ {$ifdef USE_LCL_CANVAS}
++ // ToDo: Consider a X axis inversion
++ // If the Y axis is inverted, then we need to mirror our angles as well
++ BoundsLeft := CoordToCanvasX(CurArc.CenterX - CurArc.Radius);
++ BoundsTop := CoordToCanvasY(CurArc.CenterY - CurArc.Radius);
++ BoundsRight := CoordToCanvasX(CurArc.CenterX + CurArc.Radius);
++ BoundsBottom := CoordToCanvasY(CurArc.CenterY + CurArc.Radius);
++ {if AMulY > 0 then
++ begin}
++ FinalStartAngle := CurArc.StartAngle;
++ FinalEndAngle := CurArc.EndAngle;
++ {end
++ else // AMulY is negative
+ begin
+- CurCircle := CurEntity as TvCircle;
+- ADest.Ellipse(
+- Round(ADestX + AmulX * (CurCircle.CenterX - CurCircle.Radius)),
+- Round(ADestY + AMulY * (CurCircle.CenterY - CurCircle.Radius)),
+- Round(ADestX + AmulX * (CurCircle.CenterX + CurCircle.Radius)),
+- Round(ADestY + AMulY * (CurCircle.CenterY + CurCircle.Radius))
+- );
+- end
+- else if CurEntity is TvEllipse then
++ // Inverting the angles generates the correct result for Y axis inversion
++ if CurArc.EndAngle = 0 then FinalStartAngle := 0
++ else FinalStartAngle := 360 - 1* CurArc.EndAngle;
++ if CurArc.StartAngle = 0 then FinalEndAngle := 0
++ else FinalEndAngle := 360 - 1* CurArc.StartAngle;
++ end;}
++ IntStartAngle := Round(16*FinalStartAngle);
++ IntAngleLength := Round(16*(FinalEndAngle - FinalStartAngle));
++ // On Gtk2 and Carbon, the Left really needs to be to the Left of the Right position
++ // The same for the Top and Bottom
++ // On Windows it works fine either way
++ // On Gtk2 if the positions are inverted then the arcs are screwed up
++ // In Carbon if the positions are inverted, then the arc is inverted
++ if BoundsLeft > BoundsRight then
++ begin
++ IntTmp := BoundsLeft;
++ BoundsLeft := BoundsRight;
++ BoundsRight := IntTmp;
++ end;
++ if BoundsTop > BoundsBottom then
++ begin
++ IntTmp := BoundsTop;
++ BoundsTop := BoundsBottom;
++ BoundsBottom := IntTmp;
++ end;
++ // Arc(ALeft, ATop, ARight, ABottom, Angle16Deg, Angle16DegLength: Integer);
++ {$ifdef FPVECTORIALDEBUG}
++ WriteLn(Format('Drawing Arc Center=%f,%f Radius=%f StartAngle=%f AngleLength=%f',
++ [CurArc.CenterX, CurArc.CenterY, CurArc.Radius, IntStartAngle/16, IntAngleLength/16]));
++ {$endif}
++ ADest.Pen.FPColor := CurArc.Pen.Color;
++ ALCLDest.Arc(
++ BoundsLeft, BoundsTop, BoundsRight, BoundsBottom,
++ IntStartAngle, IntAngleLength
++ );
++ ADest.Pen.FPColor := colBlack;
++ // Debug info
++// {$define FPVECTORIALDEBUG}
++// {$ifdef FPVECTORIALDEBUG}
++// WriteLn(Format('Drawing Arc x1y1=%d,%d x2y2=%d,%d start=%d end=%d',
++// [BoundsLeft, BoundsTop, BoundsRight, BoundsBottom, IntStartAngle, IntAngleLength]));
++// {$endif}
++{ ADest.TextOut(CoordToCanvasX(CurArc.CenterX), CoordToCanvasY(CurArc.CenterY),
++ Format('R=%d S=%d L=%d', [Round(CurArc.Radius*AMulX), Round(FinalStartAngle),
++ Abs(Round((FinalEndAngle - FinalStartAngle)))]));
++ ADest.Pen.Color := TColor($DDDDDD);
++ ADest.Rectangle(
++ BoundsLeft, BoundsTop, BoundsRight, BoundsBottom);
++ ADest.Pen.Color := clBlack;}
++ {$endif}
++ end
++ else if CurEntity is TvAlignedDimension then
++ begin
++ CurDim := CurEntity as TvAlignedDimension;
++ //
++ // Draws this shape:
++ // vertical horizontal
++ // ___
++ // | | or ---| X cm
++ // | --|
++ // Which marks the dimension
++ ADest.MoveTo(CoordToCanvasX(CurDim.BaseRight.X), CoordToCanvasY(CurDim.BaseRight.Y));
++ ADest.LineTo(CoordToCanvasX(CurDim.DimensionRight.X), CoordToCanvasY(CurDim.DimensionRight.Y));
++ ADest.LineTo(CoordToCanvasX(CurDim.DimensionLeft.X), CoordToCanvasY(CurDim.DimensionLeft.Y));
++ ADest.LineTo(CoordToCanvasX(CurDim.BaseLeft.X), CoordToCanvasY(CurDim.BaseLeft.Y));
++ // Now the arrows
++ // horizontal
++ SetLength(Points, 3);
++ if CurDim.DimensionRight.Y = CurDim.DimensionLeft.Y then
+ begin
+- CurEllipse := CurEntity as TvEllipse;
+- DrawRotatedEllipse(ADest, CurEllipse);
++ ADest.Brush.FPColor := colBlack;
++ ADest.Brush.Style := bsSolid;
++ // Left arrow
++ Points[0] := Point(CoordToCanvasX(CurDim.DimensionLeft.X), CoordToCanvasY(CurDim.DimensionLeft.Y));
++ Points[1] := Point(Points[0].X + 7, Points[0].Y - 3);
++ Points[2] := Point(Points[0].X + 7, Points[0].Y + 3);
++ ADest.Polygon(Points);
++ // Right arrow
++ Points[0] := Point(CoordToCanvasX(CurDim.DimensionRight.X), CoordToCanvasY(CurDim.DimensionRight.Y));
++ Points[1] := Point(Points[0].X - 7, Points[0].Y - 3);
++ Points[2] := Point(Points[0].X - 7, Points[0].Y + 3);
++ ADest.Polygon(Points);
++ ADest.Brush.Style := bsClear;
++ // Dimension text
++ Points[0].X := CoordToCanvasX((CurDim.DimensionLeft.X+CurDim.DimensionRight.X)/2);
++ Points[0].Y := CoordToCanvasY(CurDim.DimensionLeft.Y);
++ LowerDim.X := CurDim.DimensionRight.X-CurDim.DimensionLeft.X;
++ ADest.Font.Size := 10;
++ ADest.TextOut(Points[0].X, Points[0].Y, Format('%.1f', [LowerDim.X]));
+ end
+- else if CurEntity is TvCircularArc then
++ else
+ begin
+- 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}
++ ADest.Brush.FPColor := colBlack;
++ ADest.Brush.Style := bsSolid;
++ // There is no upper/lower preference for DimensionLeft/Right, so we need to check
++ if CurDim.DimensionLeft.Y > CurDim.DimensionRight.Y then
++ begin
++ UpperDim := CurDim.DimensionLeft;
++ LowerDim := CurDim.DimensionRight;
++ end
++ else
++ begin
++ UpperDim := CurDim.DimensionRight;
++ LowerDim := CurDim.DimensionLeft;
++ end;
++ // Upper arrow
++ Points[0] := Point(CoordToCanvasX(UpperDim.X), CoordToCanvasY(UpperDim.Y));
++ Points[1] := Point(Points[0].X + Round(AMulX), Points[0].Y - Round(AMulY*3));
++ Points[2] := Point(Points[0].X - Round(AMulX), Points[0].Y - Round(AMulY*3));
++ ADest.Polygon(Points);
++ // Lower arrow
++ Points[0] := Point(CoordToCanvasX(LowerDim.X), CoordToCanvasY(LowerDim.Y));
++ Points[1] := Point(Points[0].X + Round(AMulX), Points[0].Y + Round(AMulY*3));
++ Points[2] := Point(Points[0].X - Round(AMulX), Points[0].Y + Round(AMulY*3));
++ ADest.Polygon(Points);
++ ADest.Brush.Style := bsClear;
++ // Dimension text
++ Points[0].X := CoordToCanvasX(CurDim.DimensionLeft.X);
++ Points[0].Y := CoordToCanvasY((CurDim.DimensionLeft.Y+CurDim.DimensionRight.Y)/2);
++ LowerDim.Y := CurDim.DimensionRight.Y-CurDim.DimensionLeft.Y;
++ if LowerDim.Y < 0 then LowerDim.Y := -1 * LowerDim.Y;
++ ADest.Font.Size := 10;
++ ADest.TextOut(Points[0].X, Points[0].Y, Format('%.1f', [LowerDim.Y]));
+ end;
++ SetLength(Points, 0);
++{ // Debug info
++ ADest.TextOut(CoordToCanvasX(CurDim.BaseRight.X), CoordToCanvasY(CurDim.BaseRight.Y), 'BR');
++ ADest.TextOut(CoordToCanvasX(CurDim.DimensionRight.X), CoordToCanvasY(CurDim.DimensionRight.Y), 'DR');
++ ADest.TextOut(CoordToCanvasX(CurDim.DimensionLeft.X), CoordToCanvasY(CurDim.DimensionLeft.Y), 'DL');
++ ADest.TextOut(CoordToCanvasX(CurDim.BaseLeft.X), CoordToCanvasY(CurDim.BaseLeft.Y), 'BL');}
+ end;
++end;
+
+- // Draws all text
+- for i := 0 to ASource.GetTextCount - 1 do
++procedure DrawFPVTextToCanvas(ASource: TvVectorialDocument; CurText: TvText;
++ ADest: TFPCustomCanvas;
++ ADestX: Integer = 0; ADestY: Integer = 0; AMulX: Double = 1.0; AMulY: Double = 1.0);
++
++ function CoordToCanvasX(ACoord: Double): Integer;
+ 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);
++ Result := Round(ADestX + AmulX * ACoord);
+ end;
+
+- {$ifdef FPVECTORIALDEBUG}
+- WriteLn(':<DrawFPVectorialToCanvas');
++ function CoordToCanvasY(ACoord: Double): Integer;
++ begin
++ Result := Round(ADestY + AmulY * ACoord);
++ end;
++
++var
++ i: Integer;
++ {$ifdef USE_LCL_CANVAS}
++ ALCLDest: TCanvas;
+ {$endif}
++ //
++ LowerDim: T3DPoint;
++begin
++ {$ifdef USE_LCL_CANVAS}
++ ALCLDest := TCanvas(ADest);
++ {$endif}
++
++ ADest.Font.Size := Round(AmulX * CurText.Font.Size);
++ ADest.Pen.Style := psSolid;
++ ADest.Pen.FPColor := colBlack;
++ ADest.Brush.Style := bsClear;
++ {$ifdef USE_LCL_CANVAS}
++ ALCLDest.Font.Orientation := Round(CurText.Font.Orientation * 16);
++ {$endif}
++
++ LowerDim.Y := CurText.Y + CurText.Font.Size;
++ ADest.TextOut(CoordToCanvasX(CurText.X), CoordToCanvasY(LowerDim.Y), CurText.Value);
+ end;
+
+ end.
diff --git a/graphics/fpc-fpvectorial/files/patch-packages-fpvectorial-src_svgvectorialwriter.pas b/graphics/fpc-fpvectorial/files/patch-packages-fpvectorial-src_svgvectorialwriter.pas
new file mode 100644
index 000000000000..4aad8819a5a5
--- /dev/null
+++ b/graphics/fpc-fpvectorial/files/patch-packages-fpvectorial-src_svgvectorialwriter.pas
@@ -0,0 +1,273 @@
+--- packages/fpvectorial/src/svgvectorialwriter.pas 2011/01/14 14:45:03 16765
++++ packages/fpvectorial/src/svgvectorialwriter.pas 2011/06/17 09:52:19 17765
+@@ -13,7 +13,7 @@
+ interface
+
+ uses
+- Classes, SysUtils, math, fpvectorial;
++ Classes, SysUtils, math, fpvectorial, fpvutils, fpcanvas;
+
+ type
+ { TvSVGVectorialWriter }
+@@ -23,8 +23,9 @@
+ FPointSeparator, FCommaSeparator: TFormatSettings;
+ procedure WriteDocumentSize(AStrings: TStrings; AData: TvVectorialDocument);
+ procedure WriteDocumentName(AStrings: TStrings; AData: TvVectorialDocument);
+- procedure WritePaths(AStrings: TStrings; AData: TvVectorialDocument);
+- procedure WriteTexts(AStrings: TStrings; AData: TvVectorialDocument);
++ procedure WritePath(AIndex: Integer; APath: TPath; AStrings: TStrings; AData: TvVectorialDocument);
++ procedure WriteText(AStrings: TStrings; lText: TvText; AData: TvVectorialDocument);
++ procedure WriteEntities(AStrings: TStrings; AData: TvVectorialDocument);
+ procedure ConvertFPVCoordinatesToSVGCoordinates(
+ const AData: TvVectorialDocument;
+ const ASrcX, ASrcY: Double; var ADestX, ADestY: double);
+@@ -74,90 +75,106 @@
+ 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);
++procedure TvSVGVectorialWriter.WritePath(AIndex: Integer; APath: TPath; AStrings: TStrings;
++ AData: TvVectorialDocument);
+ var
+- i, j: Integer;
++ j: Integer;
+ PathStr: string;
+- lPath: TPath;
+ PtX, PtY, OldPtX, OldPtY: double;
+ BezierCP1X, BezierCP1Y, BezierCP2X, BezierCP2Y: double;
+ segment: TPathSegment;
+ l2DSegment: T2DSegment absolute segment;
+ l2DBSegment: T2DBezierSegment absolute segment;
++ // Pen properties
++ lPenWidth: Integer;
++ lPenColor: string;
++ // Brush properties
++ lFillColor: string;
+ 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, 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.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;
+
+- 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;
++
++ // Get the Pen Width
++ if APath.Pen.Width >= 1 then lPenWidth := APath.Pen.Width
++ else lPenWidth := 1;
++
++ // Get the Pen Color and Style
++ if APath.Pen.Style = psClear then lPenColor := 'none'
++ else lPenColor := '#' + FPColorToRGBHexString(APath.Pen.Color);
++
++ // Get the Brush color and style
++ if APath.Brush.Style = bsClear then lFillColor := 'none'
++ else lFillColor := '#' + FPColorToRGBHexString(APath.Brush.Color);
++
++ // Now effectively write the path
++ AStrings.Add(' <path');
++ AStrings.Add(Format(' style="fill:%s;stroke:%s;stroke-width:%dpx;'
++ + 'stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"',
++ [lFillColor, lPenColor, lPenWidth]));
++ AStrings.Add(' d="' + PathStr + '"');
++ AStrings.Add(' id="path' + IntToStr(AIndex) + '" />');
+ end;
+
+ procedure TvSVGVectorialWriter.ConvertFPVCoordinatesToSVGCoordinates(
+@@ -197,43 +214,52 @@
+
+ // Now data
+ AStrings.Add(' <g id="layer1">');
+- WritePaths(AStrings, AData);
+- WriteTexts(AStrings, AData);
++ WriteEntities(AStrings, AData);
+ AStrings.Add(' </g>');
+
+ // finalization
+ AStrings.Add('</svg>');
+ end;
+
+-procedure TvSVGVectorialWriter.WriteTexts(AStrings: TStrings; AData: TvVectorialDocument);
++procedure TvSVGVectorialWriter.WriteText(AStrings: TStrings; lText: TvText; AData: TvVectorialDocument);
+ var
+ i, j, FontSize: Integer;
+ TextStr, FontName, SVGFontFamily: string;
+- lText: TvText;
+ PtX, PtY: double;
+ begin
+- for i := 0 to AData.GetTextCount() - 1 do
+- begin
+- TextStr := '';
+- lText := AData.GetText(i);
++ TextStr := '';
+
+- ConvertFPVCoordinatesToSVGCoordinates(
+- AData, lText.X, lText.Y, PtX, PtY);
++ ConvertFPVCoordinatesToSVGCoordinates(
++ AData, lText.X, lText.Y, PtX, PtY);
+
+- TextStr := lText.Value;
+- FontSize:= ceil(lText.FontSize / FLOAT_MILIMETERS_PER_PIXEL);
+- SVGFontFamily := 'Arial, sans-serif';//lText.FontName;
+-
+- AStrings.Add(' <text ');
+- AStrings.Add(' x="' + FloatToStr(PtX, FPointSeparator) + '"');
+- AStrings.Add(' y="' + FloatToStr(PtY, FPointSeparator) + '"');
++ TextStr := lText.Value;
++ FontSize:= ceil(lText.Font.Size / FLOAT_MILIMETERS_PER_PIXEL);
++ SVGFontFamily := 'Arial, sans-serif';//lText.FontName;
++
++ AStrings.Add(' <text ');
++ AStrings.Add(' x="' + FloatToStr(PtX, FPointSeparator) + '"');
++ AStrings.Add(' y="' + FloatToStr(PtY, FPointSeparator) + '"');
+ // AStrings.Add(' font-size="' + IntToStr(FontSize) + '"'); Doesn't seam to work, we need to use the tspan
+- AStrings.Add(' font-family="' + SVGFontFamily + '">');
+- AStrings.Add(' <tspan ');
+- AStrings.Add(' style="font-size:' + IntToStr(FontSize) + '" ');
++ AStrings.Add(' font-family="' + SVGFontFamily + '">');
++ AStrings.Add(' <tspan ');
++ AStrings.Add(' style="font-size:' + IntToStr(FontSize) + '" ');
+ // AStrings.Add(' id="tspan2828" ');
+- AStrings.Add(' >');
+- AStrings.Add(TextStr + '</tspan></text>');
++ AStrings.Add(' >');
++ AStrings.Add(TextStr + '</tspan></text>');
++end;
++
++procedure TvSVGVectorialWriter.WriteEntities(AStrings: TStrings;
++ AData: TvVectorialDocument);
++var
++ lEntity: TvEntity;
++ i: Integer;
++begin
++ for i := 0 to AData.GetEntitiesCount() - 1 do
++ begin
++ lEntity := AData.GetEntity(i);
++
++ if lEntity is TPath then WritePath(i, TPath(lEntity), AStrings, AData)
++ else if lEntity is TvText then WriteText(AStrings, TvText(lEntity), AData);
+ end;
+ end;
+
diff --git a/graphics/fpc-fpvectorial/pkg-plist b/graphics/fpc-fpvectorial/pkg-plist
index 0d9ad7111c7a..91b02bad35ae 100644
--- a/graphics/fpc-fpvectorial/pkg-plist
+++ b/graphics/fpc-fpvectorial/pkg-plist
@@ -2,30 +2,36 @@ lib/fpc/%%PORTVERSION%%/units/%%BUILDNAME%%/fpvectorial/Package.fpc
lib/fpc/%%PORTVERSION%%/units/%%BUILDNAME%%/fpvectorial/avisocncgcodereader.ppu
lib/fpc/%%PORTVERSION%%/units/%%BUILDNAME%%/fpvectorial/avisocncgcodewriter.ppu
lib/fpc/%%PORTVERSION%%/units/%%BUILDNAME%%/fpvectorial/avisozlib.ppu
+lib/fpc/%%PORTVERSION%%/units/%%BUILDNAME%%/fpvectorial/cdrvectorialreader.ppu
lib/fpc/%%PORTVERSION%%/units/%%BUILDNAME%%/fpvectorial/fpvectorial.ppu
lib/fpc/%%PORTVERSION%%/units/%%BUILDNAME%%/fpvectorial/fpvtocanvas.ppu
lib/fpc/%%PORTVERSION%%/units/%%BUILDNAME%%/fpvectorial/pdfvectorialreader.ppu
lib/fpc/%%PORTVERSION%%/units/%%BUILDNAME%%/fpvectorial/pdfvrlexico.ppu
lib/fpc/%%PORTVERSION%%/units/%%BUILDNAME%%/fpvectorial/pdfvrsemantico.ppu
lib/fpc/%%PORTVERSION%%/units/%%BUILDNAME%%/fpvectorial/pdfvrsintatico.ppu
+lib/fpc/%%PORTVERSION%%/units/%%BUILDNAME%%/fpvectorial/svgvectorialwriter.ppu
lib/fpc/%%PORTVERSION%%/units/%%BUILDNAME%%/fpvectorial/avisocncgcodereader.o
lib/fpc/%%PORTVERSION%%/units/%%BUILDNAME%%/fpvectorial/avisocncgcodewriter.o
lib/fpc/%%PORTVERSION%%/units/%%BUILDNAME%%/fpvectorial/avisozlib.o
+lib/fpc/%%PORTVERSION%%/units/%%BUILDNAME%%/fpvectorial/cdrvectorialreader.o
lib/fpc/%%PORTVERSION%%/units/%%BUILDNAME%%/fpvectorial/fpvectorial.o
lib/fpc/%%PORTVERSION%%/units/%%BUILDNAME%%/fpvectorial/fpvtocanvas.o
lib/fpc/%%PORTVERSION%%/units/%%BUILDNAME%%/fpvectorial/pdfvectorialreader.o
lib/fpc/%%PORTVERSION%%/units/%%BUILDNAME%%/fpvectorial/pdfvrlexico.o
lib/fpc/%%PORTVERSION%%/units/%%BUILDNAME%%/fpvectorial/pdfvrsemantico.o
lib/fpc/%%PORTVERSION%%/units/%%BUILDNAME%%/fpvectorial/pdfvrsintatico.o
+lib/fpc/%%PORTVERSION%%/units/%%BUILDNAME%%/fpvectorial/svgvectorialwriter.o
lib/fpc/%%PORTVERSION%%/units/%%BUILDNAME%%/fpvectorial/libpavisocncgcodereader.a
lib/fpc/%%PORTVERSION%%/units/%%BUILDNAME%%/fpvectorial/libpavisocncgcodewriter.a
lib/fpc/%%PORTVERSION%%/units/%%BUILDNAME%%/fpvectorial/libpavisozlib.a
+lib/fpc/%%PORTVERSION%%/units/%%BUILDNAME%%/fpvectorial/libpcdrvectorialreader.a
lib/fpc/%%PORTVERSION%%/units/%%BUILDNAME%%/fpvectorial/libpfpvectorial.a
lib/fpc/%%PORTVERSION%%/units/%%BUILDNAME%%/fpvectorial/libpfpvtocanvas.a
lib/fpc/%%PORTVERSION%%/units/%%BUILDNAME%%/fpvectorial/libppdfvectorialreader.a
lib/fpc/%%PORTVERSION%%/units/%%BUILDNAME%%/fpvectorial/libppdfvrlexico.a
lib/fpc/%%PORTVERSION%%/units/%%BUILDNAME%%/fpvectorial/libppdfvrsemantico.a
lib/fpc/%%PORTVERSION%%/units/%%BUILDNAME%%/fpvectorial/libppdfvrsintatico.a
+lib/fpc/%%PORTVERSION%%/units/%%BUILDNAME%%/fpvectorial/libpsvgvectorialwriter.a
@dirrm lib/fpc/%%PORTVERSION%%/units/%%BUILDNAME%%/fpvectorial
@dirrmtry lib/fpc/%%PORTVERSION%%/units/%%BUILDNAME%%
@dirrmtry lib/fpc/%%PORTVERSION%%/units
diff --git a/graphics/fpc-opengl/pkg-plist b/graphics/fpc-opengl/pkg-plist
index 59630ac0dbb1..5626917cdc3c 100644
--- a/graphics/fpc-opengl/pkg-plist
+++ b/graphics/fpc-opengl/pkg-plist
@@ -1,4 +1,6 @@
lib/fpc/%%PORTVERSION%%/units/%%BUILDNAME%%/opengl/Package.fpc
+lib/fpc/%%PORTVERSION%%/units/%%BUILDNAME%%/opengl/freeglut.o
+lib/fpc/%%PORTVERSION%%/units/%%BUILDNAME%%/opengl/freeglut.ppu
lib/fpc/%%PORTVERSION%%/units/%%BUILDNAME%%/opengl/gl.o
lib/fpc/%%PORTVERSION%%/units/%%BUILDNAME%%/opengl/gl.ppu
lib/fpc/%%PORTVERSION%%/units/%%BUILDNAME%%/opengl/glext.o
@@ -9,6 +11,7 @@ lib/fpc/%%PORTVERSION%%/units/%%BUILDNAME%%/opengl/glut.o
lib/fpc/%%PORTVERSION%%/units/%%BUILDNAME%%/opengl/glut.ppu
lib/fpc/%%PORTVERSION%%/units/%%BUILDNAME%%/opengl/glx.o
lib/fpc/%%PORTVERSION%%/units/%%BUILDNAME%%/opengl/glx.ppu
+lib/fpc/%%PORTVERSION%%/units/%%BUILDNAME%%/opengl/libpfreeglut.a
lib/fpc/%%PORTVERSION%%/units/%%BUILDNAME%%/opengl/libpgl.a
lib/fpc/%%PORTVERSION%%/units/%%BUILDNAME%%/opengl/libpglext.a
lib/fpc/%%PORTVERSION%%/units/%%BUILDNAME%%/opengl/libpglu.a