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