mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-06-02 16:52:32 +02:00
fpvectorial-svg: Fixes the start position of secondary paths inside a path, improves file alarm.svg
git-svn-id: trunk@55389 -
This commit is contained in:
parent
41c18b95d6
commit
9b325e675c
@ -7,7 +7,6 @@ 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 fpvectorial;
|
||||
|
||||
@ -5092,7 +5091,7 @@ begin
|
||||
begin
|
||||
if (Brush.Style = bsSolid) and (Length(FPolyStarts) > 1) then
|
||||
// Non-contiguous polygon (polygon with "holes") --> use special procedure
|
||||
// Disadvantage: it can oly do solid fills!
|
||||
// Disadvantage: it can only do solid fills!
|
||||
DrawPolygon(ADest, ARenderInfo, FPolyPoints, FPolyStarts, lRect)
|
||||
else
|
||||
{$IFDEF USE_LCL_CANVAS}
|
||||
|
@ -637,39 +637,39 @@ begin
|
||||
|
||||
case curSegment.SegmentType of
|
||||
stMoveTo:
|
||||
begin
|
||||
// Store current length of points array as polygon start index
|
||||
if numPolygons >= Length(PolygonStartIndexes) then
|
||||
SetLength(PolygonstartIndexes, Length(PolygonStartIndexes) + POINT_BUFFER);
|
||||
PolygonStartIndexes[numPolygons] := numPoints;
|
||||
inc(numPolygons);
|
||||
begin
|
||||
// Store current length of points array as polygon start index
|
||||
if numPolygons >= Length(PolygonStartIndexes) then
|
||||
SetLength(PolygonstartIndexes, Length(PolygonStartIndexes) + POINT_BUFFER);
|
||||
PolygonStartIndexes[numPolygons] := numPoints;
|
||||
inc(numPolygons);
|
||||
|
||||
// Store current point as first point of a new polygon
|
||||
coordX := CoordToCanvasX(cur2DSegment.X, ADestX, AMulX);
|
||||
coordY := CoordToCanvasY(cur2DSegment.Y, ADestY, AMulY);
|
||||
if numPoints >= Length(PolygonPoints) then
|
||||
SetLength(PolygonPoints, Length(PolygonPoints) + POINT_BUFFER);
|
||||
PolygonPoints[numPoints] := Point(coordX, coordY);
|
||||
inc(numPoints);
|
||||
end;
|
||||
// Store current point as first point of a new polygon
|
||||
coordX := CoordToCanvasX(cur2DSegment.X, ADestX, AMulX);
|
||||
coordY := CoordToCanvasY(cur2DSegment.Y, ADestY, AMulY);
|
||||
if numPoints >= Length(PolygonPoints) then
|
||||
SetLength(PolygonPoints, Length(PolygonPoints) + POINT_BUFFER);
|
||||
PolygonPoints[numPoints] := Point(coordX, coordY);
|
||||
inc(numPoints);
|
||||
end;
|
||||
|
||||
st2DLine, st3DLine, st2DLineWithPen:
|
||||
begin
|
||||
// Add current point to current polygon
|
||||
coordX := CoordToCanvasX(cur2DSegment.X, ADestX, AMulX);
|
||||
coordY := CoordToCanvasY(cur2DSegment.Y, ADestY, AMulY);
|
||||
if numPoints >= Length(PolygonPoints) then
|
||||
SetLength(PolygonPoints, Length(PolygonPoints) + POINT_BUFFER);
|
||||
PolygonPoints[numPoints] := Point(coordX, coordY);
|
||||
inc(numPoints);
|
||||
end;
|
||||
begin
|
||||
// Add current point to current polygon
|
||||
coordX := CoordToCanvasX(cur2DSegment.X, ADestX, AMulX);
|
||||
coordY := CoordToCanvasY(cur2DSegment.Y, ADestY, AMulY);
|
||||
if numPoints >= Length(PolygonPoints) then
|
||||
SetLength(PolygonPoints, Length(PolygonPoints) + POINT_BUFFER);
|
||||
PolygonPoints[numPoints] := Point(coordX, coordY);
|
||||
inc(numPoints);
|
||||
end;
|
||||
|
||||
st2DBezier, st3DBezier, st2DEllipticalArc:
|
||||
begin
|
||||
SetLength(PolygonPoints, numPoints);
|
||||
curSegment.AddToPoints(ADestX, ADestY, AMulX, AMulY, PolygonPoints);
|
||||
numPoints := Length(PolygonPoints);
|
||||
end;
|
||||
begin
|
||||
SetLength(PolygonPoints, numPoints);
|
||||
curSegment.AddToPoints(ADestX, ADestY, AMulX, AMulY, PolygonPoints);
|
||||
numPoints := Length(PolygonPoints);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
SetLength(PolygonPoints, numPoints);
|
||||
@ -763,7 +763,8 @@ begin
|
||||
list := TFPList.Create;
|
||||
if ACoordIsX then
|
||||
begin
|
||||
for p := 0 to High(APolyStarts) do begin
|
||||
for p := 0 to High(APolyStarts) do
|
||||
begin
|
||||
firstj := APolyStarts[p];
|
||||
lastj := IfThen(p = High(APolyStarts), High(APoints), APolyStarts[p+1]-1);
|
||||
// Skip non-closed polygons
|
||||
|
@ -145,6 +145,8 @@ type
|
||||
CurX, CurY: Double;
|
||||
Data: TvVectorialPage;
|
||||
Doc: TvVectorialDocument;
|
||||
// Path support for multiple polygons
|
||||
LastPathStart: T2DPoint;
|
||||
function GetPath(AIndex: Integer): TPath;
|
||||
end;
|
||||
|
||||
@ -152,7 +154,7 @@ type
|
||||
|
||||
TvSVGVectorialReader = class(TvCustomVectorialReader)
|
||||
private
|
||||
FPointSeparator, FCommaSeparator: TFormatSettings;
|
||||
FPointSeparator: TFormatSettings;
|
||||
FSVGPathTokenizer: TSVGPathTokenizer;
|
||||
FLayerStylesKeys, FLayerStylesValues: TFPList; // of TStringList;
|
||||
// View box adjustment
|
||||
@ -163,8 +165,6 @@ type
|
||||
FCSSDefs: TFPList; // of TSVG_CSS_Style;
|
||||
// debug symbols
|
||||
FPathNumber: Integer;
|
||||
// Path support for multiple polygons
|
||||
FPathStart: T2DPoint;
|
||||
// BrushDefs functions
|
||||
function FindBrushDef_WithName(AName: string): TvEntityWithPenAndBrush;
|
||||
//
|
||||
@ -2309,12 +2309,18 @@ begin
|
||||
lCurPath.Brush.Style := bsClear;
|
||||
// Apply the layer style
|
||||
ApplyLayerStyles(AData, lCurPath);
|
||||
// name
|
||||
if lPaths.Count > 1 then
|
||||
lCurPath.Name := Format('[%d]', [i]);
|
||||
// Add the pen/brush/name
|
||||
for i := 0 to ANode.Attributes.Length - 1 do
|
||||
begin
|
||||
lNodeName := ANode.Attributes.Item[i].NodeName;
|
||||
if lNodeName = 'id' then
|
||||
lCurPath.Name := ANode.Attributes.Item[i].NodeValue
|
||||
begin
|
||||
if lPaths.Count = 1 then
|
||||
lCurPath.Name := ANode.Attributes.Item[i].NodeValue;
|
||||
end
|
||||
else if lNodeName = 'style' then
|
||||
ReadSVGStyle(AData, ANode.Attributes.Item[i].NodeValue, lCurPath)
|
||||
else if IsAttributeFromStyle(lNodeName) then
|
||||
@ -2333,14 +2339,23 @@ begin
|
||||
begin
|
||||
Result := lPaths.GetPath(0);
|
||||
end
|
||||
else
|
||||
else if lPaths.Count > 1 then
|
||||
begin
|
||||
Result := TvEntityWithSubEntities.Create(nil);
|
||||
|
||||
for j := 0 to lPaths.Count-1 do
|
||||
begin
|
||||
lCurPath := lPaths.GetPath(j);
|
||||
TvEntityWithSubEntities(Result).AddEntity(lCurPath);
|
||||
end;
|
||||
|
||||
// Add thename
|
||||
for i := 0 to ANode.Attributes.Length - 1 do
|
||||
begin
|
||||
lNodeName := ANode.Attributes.Item[i].NodeName;
|
||||
if lNodeName = 'id' then
|
||||
TvEntityWithSubEntities(Result).Name := ANode.Attributes.Item[i].NodeValue;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -2348,11 +2363,8 @@ end;
|
||||
function TvSVGVectorialReader.ReadPathFromString(AStr: string;
|
||||
AData: TvVectorialPage; ADoc: TvVectorialDocument): TvSVGPathList;
|
||||
var
|
||||
X, Y, X2, Y2, X3, Y3: Double;
|
||||
lCurTokenType, lLastCommandToken: TSVGTokenType;
|
||||
lDebugStr: String;
|
||||
lTmpTokenType: TSVGTokenType;
|
||||
lIsFirstPathMove, lLastPathClosed: Boolean;
|
||||
begin
|
||||
Result := TvSVGPathList.Create;
|
||||
FSVGPathTokenizer.ClearTokens;
|
||||
@ -2394,9 +2406,9 @@ procedure TvSVGVectorialReader.ReadNextPathCommand(ACurTokenType: TSVGTokenType;
|
||||
APaths: TvSVGPathList; var CurX, CurY: Double);
|
||||
var
|
||||
X, Y, X2, Y2, X3, Y3, XQ, YQ, Xnew, Ynew, cx, cy, phi, tmp: Double;
|
||||
PathEndX, PathEndY: Double;
|
||||
LargeArcFlag, SweepFlag, LeftmostEllipse, ClockwiseArc: Boolean;
|
||||
lCurTokenType: TSVGTokenType;
|
||||
lDebugStr: String;
|
||||
lToken5Before, lToken7Before: TSVGTokenType;
|
||||
lCorrectPreviousToken: Boolean;
|
||||
lPrevRelative, lCurRelative: Boolean;
|
||||
@ -2435,9 +2447,10 @@ begin
|
||||
// to close the subpolygon correctly later.
|
||||
if APaths.IsFirstPathMove then
|
||||
begin
|
||||
FPathStart.X := APaths.CurX;
|
||||
FPathStart.Y := APaths.CurY;
|
||||
APaths.IsFirstPathMove := false;
|
||||
APaths.LastPathStart.X := APaths.CurX;
|
||||
APaths.LastPathStart.Y := APaths.CurY;
|
||||
APaths.IsFirstPathMove := False;
|
||||
APaths.LastPathClosed := False;
|
||||
end;
|
||||
|
||||
Inc(APaths.CurTokenIndex, 3);
|
||||
@ -2448,10 +2461,15 @@ begin
|
||||
else if lCurTokenType = sttClosePath then
|
||||
begin
|
||||
// Repeat the first point of the subpolygon
|
||||
CurX := FPathStart.X;
|
||||
CurY := FPathStart.Y;
|
||||
APaths.Data.AddLineToPath(CurX, CurY);
|
||||
PathEndX := APaths.LastPathStart.X;
|
||||
PathEndY := APaths.LastPathStart.Y;
|
||||
CurX := PathEndX;
|
||||
CurY := PathEndY;
|
||||
APaths.LastPathStart.X := 0;
|
||||
APaths.LastPathStart.Y := 0;
|
||||
APaths.Data.AddLineToPath(PathEndX, PathEndY);
|
||||
APaths.LastPathClosed := True;
|
||||
APaths.IsFirstPathMove := True;
|
||||
APaths.Add(AData.EndPath(True));
|
||||
AData.StartPath();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user