diff --git a/applications/fpvviewer/fpvectorialsrc/fpvectorial.pas b/applications/fpvviewer/fpvectorialsrc/fpvectorial.pas
index b1c9cad5a..d61b28e72 100644
--- a/applications/fpvviewer/fpvectorialsrc/fpvectorial.pas
+++ b/applications/fpvviewer/fpvectorialsrc/fpvectorial.pas
@@ -1130,6 +1130,8 @@ begin
Points := APath.Points;
PointsEnd := APath.PointsEnd;
CurPoint := APath.CurPoint;
+ Pen := APath.Pen;
+ Brush := APath.Brush;
end;
function TPath.Count(): TPathSegment;
diff --git a/applications/fpvviewer/fpvectorialsrc/fpvtocanvas.pas b/applications/fpvviewer/fpvectorialsrc/fpvtocanvas.pas
index 16c3a5126..fa0c4e798 100644
--- a/applications/fpvviewer/fpvectorialsrc/fpvtocanvas.pas
+++ b/applications/fpvviewer/fpvectorialsrc/fpvtocanvas.pas
@@ -42,14 +42,6 @@ begin
end;
{$endif}
-function VColorToFPColor(AVColor: TvColor): TFPColor; inline;
-begin
- Result.Red := AVColor.Red;
- Result.Green := AVColor.Green;
- Result.Blue := AVColor.Blue;
- Result.Alpha := AVColor.Alpha;
-end;
-
function Rotate2DPoint(P,Fix :TPoint; alpha:double): TPoint;
var
sinus, cosinus : Extended;
diff --git a/applications/fpvviewer/fpvectorialsrc/fpvutils.pas b/applications/fpvviewer/fpvectorialsrc/fpvutils.pas
new file mode 100644
index 000000000..f389df7e2
--- /dev/null
+++ b/applications/fpvviewer/fpvectorialsrc/fpvutils.pas
@@ -0,0 +1,53 @@
+{
+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;
+
+// Color Conversion routines
+function VColorToFPColor(AVColor: TvColor): TFPColor; inline;
+function VColorToRGBHexString(AVColor: TvColor): string;
+function RGBToVColor(AR, AG, AB: Byte): TvColor; inline;
+
+implementation
+
+function VColorToFPColor(AVColor: TvColor): TFPColor; inline;
+begin
+ Result.Red := AVColor.Red;
+ Result.Green := AVColor.Green;
+ Result.Blue := AVColor.Blue;
+ Result.Alpha := AVColor.Alpha;
+end;
+
+function VColorToRGBHexString(AVColor: TvColor): string;
+begin
+ Result := Format('%.2x%.2x%.2x', [AVColor.Red, AVColor.Green, AVColor.Blue]);
+end;
+
+function RGBToVColor(AR, AG, AB: Byte): TvColor; inline;
+begin
+ Result.Red := AR;
+ Result.Green := AG;
+ Result.Blue := AB;
+ Result.Alpha := 255;
+end;
+
+end.
+
diff --git a/applications/fpvviewer/fpvectorialsrc/svgvectorialwriter.pas b/applications/fpvviewer/fpvectorialsrc/svgvectorialwriter.pas
index a1ae21495..65a42f5f8 100644
--- a/applications/fpvviewer/fpvectorialsrc/svgvectorialwriter.pas
+++ b/applications/fpvviewer/fpvectorialsrc/svgvectorialwriter.pas
@@ -13,7 +13,7 @@ unit svgvectorialwriter;
interface
uses
- Classes, SysUtils, math, fpvectorial;
+ Classes, SysUtils, math, fpvectorial, fpvutils;
type
{ TvSVGVectorialWriter }
@@ -24,6 +24,7 @@ type
procedure WriteDocumentSize(AStrings: TStrings; AData: TvVectorialDocument);
procedure WriteDocumentName(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 ConvertFPVCoordinatesToSVGCoordinates(
const AData: TvVectorialDocument;
@@ -60,6 +61,19 @@ begin
AStrings.Add(' sodipodi:docname="New document 1">');
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
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
"." 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;
begin
- for i := 0 to AData.GetPathCount() - 1 do
+ OldPtX := 0;
+ OldPtY := 0;
+ PathStr := '';
+
+ APath.PrepareForSequentialReading();
+
+ for j := 0 to APath.Len - 1 do
begin
- OldPtX := 0;
- OldPtY := 0;
+ segment := TPathSegment(APath.Next());
- PathStr := '';
- lPath := AData.GetPath(i);
- lPath.PrepareForSequentialReading;
+ if (segment.SegmentType <> st2DLine)
+ and (segment.SegmentType <> stMoveTo)
+ and (segment.SegmentType <> st2DBezier)
+ then Break; // unsupported line type
- for j := 0 to lPath.Len - 1 do
+ // Coordinate conversion from fpvectorial to SVG
+ ConvertFPVCoordinatesToSVGCoordinates(
+ AData, l2DSegment.X, l2DSegment.Y, PtX, PtY);
+ PtX := PtX - OldPtX;
+ PtY := PtY - OldPtY;
+
+ if (segment.SegmentType = stMoveTo) then
begin
- segment := TPathSegment(lPath.Next());
-
- if (segment.SegmentType <> st2DLine)
- and (segment.SegmentType <> stMoveTo)
- and (segment.SegmentType <> st2DBezier)
- then Break; // unsupported line type
-
- // Coordinate conversion from fpvectorial to SVG
+ 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;
+ AData, l2DBSegment.X2, l2DBSegment.Y2, BezierCP1X, BezierCP1Y);
+ ConvertFPVCoordinatesToSVGCoordinates(
+ AData, l2DBSegment.X3, l2DBSegment.Y3, BezierCP2X, BezierCP2Y);
- 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;
- // 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
- // 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;
+ // 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(' ');
+ // 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
+ lPenColor := VColorToRGBHexString(APath.Pen.Color);
+
+ AStrings.Add(' ');
end;
procedure TvSVGVectorialWriter.ConvertFPVCoordinatesToSVGCoordinates(