mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-11-02 03:29:34 +01:00
fpvectorial: Merges the implementation of pen, brush and updates the svg output to use the pen
git-svn-id: trunk@17382 -
This commit is contained in:
parent
576072dc17
commit
bca76120f6
@ -13,7 +13,6 @@
|
||||
<Title Value="fpvwritetest"/>
|
||||
<ResourceType Value="res"/>
|
||||
<UseXPManifest Value="True"/>
|
||||
<Icon Value="0"/>
|
||||
</General>
|
||||
<i18n>
|
||||
<EnableI18N LFM="False"/>
|
||||
@ -21,6 +20,9 @@
|
||||
<VersionInfo>
|
||||
<StringTable ProductVersion=""/>
|
||||
</VersionInfo>
|
||||
<BuildModes Count="1">
|
||||
<Item1 Name="default" Default="True"/>
|
||||
</BuildModes>
|
||||
<PublishOptions>
|
||||
<Version Value="2"/>
|
||||
<IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
|
||||
@ -29,6 +31,7 @@
|
||||
<RunParams>
|
||||
<local>
|
||||
<FormatVersion Value="1"/>
|
||||
<LaunchingApplication PathPlusParams="\usr\bin\xterm -T 'Lazarus Run Output' -e $(LazarusDir)\tools\runwait.sh $(TargetCmdLine)"/>
|
||||
</local>
|
||||
</RunParams>
|
||||
<Units Count="1">
|
||||
@ -40,13 +43,13 @@
|
||||
</Units>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
<Version Value="9"/>
|
||||
<Version Value="10"/>
|
||||
<PathDelim Value="\"/>
|
||||
<Target>
|
||||
<Filename Value="fpvwritetest"/>
|
||||
</Target>
|
||||
<SearchPaths>
|
||||
<IncludeFiles Value="$(ProjOutDir)\"/>
|
||||
<IncludeFiles Value="$(ProjOutDir)"/>
|
||||
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
|
||||
</SearchPaths>
|
||||
<Other>
|
||||
|
||||
@ -22,7 +22,7 @@ program fpvwritetest;
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
uses
|
||||
fpvectorial, svgvectorialwriter;
|
||||
fpvectorial, svgvectorialwriter, fpvutils;
|
||||
|
||||
const
|
||||
cFormat = vfSVG;
|
||||
@ -134,6 +134,51 @@ begin
|
||||
Vec.AddText(20, 20, 0, '20, 20 Mówić, cześć, Włosku, Parabéns.');
|
||||
Vec.AddText(30, 30, 0, '30, 30 森林,是一个高密');
|
||||
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
|
||||
Vec.Free;
|
||||
end;
|
||||
|
||||
@ -45,6 +45,17 @@ type
|
||||
Red, Green, Blue, Alpha: Byte;
|
||||
end;
|
||||
|
||||
TvPen = record
|
||||
Color: TvColor;
|
||||
Style: TFPPenStyle;
|
||||
Width: Integer;
|
||||
end;
|
||||
|
||||
TvBrush = record
|
||||
Color: TvColor;
|
||||
Style: TFPBrushStyle;
|
||||
end;
|
||||
|
||||
const
|
||||
FPValphaTransparent = $00;
|
||||
FPValphaOpaque = $FF;
|
||||
@ -59,7 +70,7 @@ type
|
||||
P3DPoint = ^T3DPoint;
|
||||
|
||||
TSegmentType = (
|
||||
st2DLine, st2DBezier,
|
||||
st2DLine, st2DLineWithPen, st2DBezier,
|
||||
st3DLine, st3DBezier, stMoveTo);
|
||||
|
||||
{@@
|
||||
@ -75,10 +86,6 @@ type
|
||||
// Fields for linking the list
|
||||
Previous: TPathSegment;
|
||||
Next: TPathSegment;
|
||||
// Data fields
|
||||
PenColor: TvColor;
|
||||
PenStyle: TFPPenStyle;
|
||||
PenWidth: Integer;
|
||||
end;
|
||||
|
||||
{@@
|
||||
@ -93,6 +100,11 @@ type
|
||||
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
|
||||
@ -124,6 +136,13 @@ type
|
||||
Points: TPathSegment; // Beginning of the double-linked list
|
||||
PointsEnd: TPathSegment; // End of the double-linked list
|
||||
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);
|
||||
function Count(): TPathSegment;
|
||||
procedure PrepareForSequentialReading;
|
||||
@ -139,23 +158,18 @@ type
|
||||
TvText = class
|
||||
public
|
||||
X, Y, Z: Double; // Z is ignored in 2D formats
|
||||
Value: utf8string;
|
||||
FontColor: TvColor;
|
||||
FontSize: integer;
|
||||
FontName: utf8string;
|
||||
Value: utf8string;
|
||||
Color: TvColor;
|
||||
end;
|
||||
|
||||
{@@
|
||||
}
|
||||
TvEntity = class
|
||||
public
|
||||
// Pen
|
||||
PenColor: TvColor;
|
||||
PenStyle: TFPPenStyle;
|
||||
PenWidth: Integer;
|
||||
// Brush
|
||||
BrushStyle: TFPBrushStyle;
|
||||
BrushColor: TvColor;
|
||||
Pen: TvPen;
|
||||
Brush: TvBrush;
|
||||
end;
|
||||
|
||||
{@@
|
||||
@ -253,6 +267,11 @@ type
|
||||
procedure AddLineToPath(AX, AY, AZ: 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 SetBrushColor(AColor: TvColor);
|
||||
procedure SetBrushStyle(AStyle: TFPBrushStyle);
|
||||
procedure SetPenColor(AColor: TvColor);
|
||||
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;
|
||||
@ -550,20 +569,19 @@ begin
|
||||
segment.SegmentType := st2DLine;
|
||||
segment.X := AX;
|
||||
segment.Y := AY;
|
||||
segment.PenColor := clvBlack;
|
||||
|
||||
AppendSegmentToTmpPath(segment);
|
||||
end;
|
||||
|
||||
procedure TvVectorialDocument.AddLineToPath(AX, AY: Double; AColor: TvColor);
|
||||
var
|
||||
segment: T2DSegment;
|
||||
segment: T2DSegmentWithPen;
|
||||
begin
|
||||
segment := T2DSegment.Create;
|
||||
segment.SegmentType := st2DLine;
|
||||
segment := T2DSegmentWithPen.Create;
|
||||
segment.SegmentType := st2DLineWithPen;
|
||||
segment.X := AX;
|
||||
segment.Y := AY;
|
||||
segment.PenColor := AColor;
|
||||
segment.Pen.Color := AColor;
|
||||
|
||||
AppendSegmentToTmpPath(segment);
|
||||
end;
|
||||
@ -623,6 +641,31 @@ begin
|
||||
AppendSegmentToTmpPath(segment);
|
||||
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
|
||||
steps using StartPath and AddPointToPath,
|
||||
@ -683,7 +726,7 @@ begin
|
||||
lCircularArc.Radius := ARadius;
|
||||
lCircularArc.StartAngle := AStartAngle;
|
||||
lCircularArc.EndAngle := AEndAngle;
|
||||
lCircularArc.PenColor := AColor;
|
||||
lCircularArc.Pen.Color := AColor;
|
||||
FEntities.Add(lCircularArc);
|
||||
end;
|
||||
|
||||
@ -728,12 +771,13 @@ begin
|
||||
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;
|
||||
|
||||
{@@
|
||||
@ -749,12 +793,13 @@ begin
|
||||
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();
|
||||
@ -1073,12 +1118,20 @@ end;
|
||||
|
||||
{ TPath }
|
||||
|
||||
constructor TPath.Create();
|
||||
begin
|
||||
Brush.Style := bsClear;
|
||||
inherited Create();
|
||||
end;
|
||||
|
||||
procedure TPath.Assign(APath: TPath);
|
||||
begin
|
||||
Len := APath.Len;
|
||||
Points := APath.Points;
|
||||
PointsEnd := APath.PointsEnd;
|
||||
CurPoint := APath.CurPoint;
|
||||
Pen := APath.Pen;
|
||||
Brush := APath.Brush;
|
||||
end;
|
||||
|
||||
function TPath.Count(): TPathSegment;
|
||||
|
||||
@ -4,7 +4,7 @@ unit fpvtocanvas;
|
||||
|
||||
interface
|
||||
|
||||
{.$define USE_LCL_CANVAS}
|
||||
{$define USE_LCL_CANVAS}
|
||||
|
||||
uses
|
||||
Classes, SysUtils, Math,
|
||||
@ -115,7 +115,7 @@ end;
|
||||
|
||||
DrawFPVectorialToCanvas(ASource, ADest, 0, ASource.Height, 1.0, -1.0);
|
||||
}
|
||||
{$define FPVECTORIAL_TOCANVAS_DEBUG}
|
||||
{.$define FPVECTORIAL_TOCANVAS_DEBUG}
|
||||
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);
|
||||
@ -187,15 +187,22 @@ begin
|
||||
Write(Format(' M%d,%d', [CoordToCanvasX(Cur2DSegment.X), CoordToCanvasY(Cur2DSegment.Y)]));
|
||||
{$endif}
|
||||
end;
|
||||
st2DLine, st3DLine:
|
||||
st2DLineWithPen:
|
||||
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));
|
||||
{$ifdef USE_LCL_CANVAS}ADest.Pen.Color := clBlack;{$endif}
|
||||
{$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:
|
||||
@ -321,7 +328,7 @@ begin
|
||||
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.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(
|
||||
BoundsLeft, BoundsTop, BoundsRight, BoundsBottom,
|
||||
IntStartAngle, IntAngleLength
|
||||
|
||||
@ -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(' <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
|
||||
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;
|
||||
|
||||
procedure TvSVGVectorialWriter.ConvertFPVCoordinatesToSVGCoordinates(
|
||||
|
||||
Loading…
Reference in New Issue
Block a user