mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-12-08 16:08:17 +01:00
fpvectorial: Fixes many SVG reading issues, such as text position, poligon/polyline coordinates
git-svn-id: trunk@43772 -
This commit is contained in:
parent
85d0817718
commit
0ac5918f3d
@ -112,6 +112,7 @@ type
|
|||||||
procedure ConvertSVGDeltaToFPVDelta(
|
procedure ConvertSVGDeltaToFPVDelta(
|
||||||
const AData: TvVectorialPage;
|
const AData: TvVectorialPage;
|
||||||
const ASrcX, ASrcY: Double; var ADestX, ADestY: Double);
|
const ASrcX, ASrcY: Double; var ADestX, ADestY: Double);
|
||||||
|
procedure AutoDetectDocSize(var ALeft, ATop, ARight, ABottom: Double; ABaseNode: TDOMNode);
|
||||||
public
|
public
|
||||||
{ General reading methods }
|
{ General reading methods }
|
||||||
constructor Create; override;
|
constructor Create; override;
|
||||||
@ -764,13 +765,16 @@ begin
|
|||||||
lStrings := TStringList.Create;
|
lStrings := TStringList.Create;
|
||||||
try
|
try
|
||||||
lStrings.Delimiter := ';';
|
lStrings.Delimiter := ';';
|
||||||
|
lStrings.StrictDelimiter := True;
|
||||||
lStrings.DelimitedText := LowerCase(AValue);
|
lStrings.DelimitedText := LowerCase(AValue);
|
||||||
for i := 0 to lStrings.Count-1 do
|
for i := 0 to lStrings.Count-1 do
|
||||||
begin
|
begin
|
||||||
lStr := lStrings.Strings[i];
|
lStr := lStrings.Strings[i];
|
||||||
lPosEqual := Pos(':', lStr);
|
lPosEqual := Pos(':', lStr);
|
||||||
lStyleKeyStr := Copy(lStr, 0, lPosEqual-1);
|
lStyleKeyStr := Copy(lStr, 0, lPosEqual-1);
|
||||||
|
lStyleKeyStr := Trim(lStyleKeyStr);
|
||||||
lStyleValueStr := Copy(lStr, lPosEqual+1, Length(lStr));
|
lStyleValueStr := Copy(lStr, lPosEqual+1, Length(lStr));
|
||||||
|
lStyleValueStr := Trim(lStyleValueStr);
|
||||||
ReadSVGPenStyleWithKeyAndValue(lStyleKeyStr, lStyleValueStr, ADestEntity);
|
ReadSVGPenStyleWithKeyAndValue(lStyleKeyStr, lStyleValueStr, ADestEntity);
|
||||||
ReadSVGGeneralStyleWithKeyAndValue(lStyleKeyStr, lStyleValueStr, ADestEntity);
|
ReadSVGGeneralStyleWithKeyAndValue(lStyleKeyStr, lStyleValueStr, ADestEntity);
|
||||||
if AUseFillAsPen and (lStyleKeyStr = 'fill') then
|
if AUseFillAsPen and (lStyleKeyStr = 'fill') then
|
||||||
@ -842,7 +846,7 @@ begin
|
|||||||
end
|
end
|
||||||
else if AKey = 'stroke-opacity' then
|
else if AKey = 'stroke-opacity' then
|
||||||
begin
|
begin
|
||||||
ADestEntity.Pen.Color.Alpha := StrToInt(AValue)*$101
|
ADestEntity.Pen.Color.Alpha := Round(StrToFloat(AValue)*$FFFF);
|
||||||
end
|
end
|
||||||
else if AKey = 'stroke-linecap' then
|
else if AKey = 'stroke-linecap' then
|
||||||
begin
|
begin
|
||||||
@ -1307,7 +1311,7 @@ begin
|
|||||||
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;
|
||||||
lNodeValue := ANode.Attributes.Item[i].NodeName;
|
lNodeValue := ANode.Attributes.Item[i].NodeValue;
|
||||||
if lNodeName = 'cx' then
|
if lNodeName = 'cx' then
|
||||||
cx := StringWithUnitToFloat(lNodeValue)
|
cx := StringWithUnitToFloat(lNodeValue)
|
||||||
else if lNodeName = 'cy' then
|
else if lNodeName = 'cy' then
|
||||||
@ -1987,7 +1991,7 @@ begin
|
|||||||
begin
|
begin
|
||||||
X := FSVGPathTokenizer.Tokens.Items[i].Value;
|
X := FSVGPathTokenizer.Tokens.Items[i].Value;
|
||||||
Y := FSVGPathTokenizer.Tokens.Items[i+1].Value;
|
Y := FSVGPathTokenizer.Tokens.Items[i+1].Value;
|
||||||
ConvertSVGDeltaToFPVDelta(AData, X, Y, CurX, CurY);
|
ConvertSVGCoordinatesToFPVCoordinates(AData, X, Y, CurX, CurY);
|
||||||
AData.AddLineToPath(CurX, CurY);
|
AData.AddLineToPath(CurX, CurY);
|
||||||
|
|
||||||
Inc(i, 2);
|
Inc(i, 2);
|
||||||
@ -2154,7 +2158,7 @@ begin
|
|||||||
|
|
||||||
// Recover the position if there was a transformation matrix
|
// Recover the position if there was a transformation matrix
|
||||||
lx := lx + lText.X;
|
lx := lx + lText.X;
|
||||||
ly := lx + lText.Y;
|
ly := ly + lText.Y;
|
||||||
|
|
||||||
// Set the coordinates
|
// Set the coordinates
|
||||||
ConvertSVGCoordinatesToFPVCoordinates(
|
ConvertSVGCoordinatesToFPVCoordinates(
|
||||||
@ -2304,6 +2308,51 @@ begin
|
|||||||
ADestY := - ASrcY * FLOAT_MILIMETERS_PER_PIXEL;
|
ADestY := - ASrcY * FLOAT_MILIMETERS_PER_PIXEL;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TvSVGVectorialReader.AutoDetectDocSize(var ALeft, ATop, ARight, ABottom: Double;
|
||||||
|
ABaseNode: TDOMNode);
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
|
lCurNode: TDOMNode;
|
||||||
|
lx, ly, lcx, lcy: Double;
|
||||||
|
lNodeName, lNodeValue: DomString;
|
||||||
|
begin
|
||||||
|
lx := 0;
|
||||||
|
ly := 0;
|
||||||
|
lcx := 0;
|
||||||
|
lcy := 0;
|
||||||
|
// read the attributes
|
||||||
|
if ABaseNode.Attributes <> nil then
|
||||||
|
begin
|
||||||
|
for i := 0 to ABaseNode.Attributes.Length - 1 do
|
||||||
|
begin
|
||||||
|
lNodeName := ABaseNode.Attributes.Item[i].NodeName;
|
||||||
|
lNodeValue := ABaseNode.Attributes.Item[i].NodeValue;
|
||||||
|
if (lNodeName = 'x') or (lNodeName = 'cx') then
|
||||||
|
lx := lx + StringWithUnitToFloat(lNodeValue)
|
||||||
|
else if (lNodeName = 'y') or (lNodeName = 'cy') then
|
||||||
|
ly := ly + StringWithUnitToFloat(lNodeValue)
|
||||||
|
else if lNodeName = 'width' then
|
||||||
|
lcx := StringWithUnitToFloat(lNodeValue)
|
||||||
|
else if lNodeName = 'height' then
|
||||||
|
lcy := StringWithUnitToFloat(lNodeValue);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
// Borders guessing
|
||||||
|
if lx < ALeft then ALeft := lx;
|
||||||
|
if ly < ATop then ATop := ly;
|
||||||
|
if lx + lcx > ARight then ARight := lx + lcx;
|
||||||
|
if ly + lcy > ABottom then ABottom := ly + lcy;
|
||||||
|
|
||||||
|
// iterate through children
|
||||||
|
lCurNode := ABaseNode.FirstChild;
|
||||||
|
while Assigned(lCurNode) do
|
||||||
|
begin
|
||||||
|
AutoDetectDocSize(ALeft, ATop, ARight, ABottom, lCurNode);
|
||||||
|
lCurNode := lCurNode.NextSibling;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
constructor TvSVGVectorialReader.Create;
|
constructor TvSVGVectorialReader.Create;
|
||||||
begin
|
begin
|
||||||
inherited Create;
|
inherited Create;
|
||||||
@ -2356,6 +2405,9 @@ var
|
|||||||
i: Integer;
|
i: Integer;
|
||||||
lCurEntity: TvEntity;
|
lCurEntity: TvEntity;
|
||||||
lViewBox: TDoubleArray;
|
lViewBox: TDoubleArray;
|
||||||
|
lStr: string;
|
||||||
|
lDocNeedsSizeAutoDetection: Boolean = True;
|
||||||
|
lx, ly, lx2, ly2: Double;
|
||||||
begin
|
begin
|
||||||
FPathNumber := 0;
|
FPathNumber := 0;
|
||||||
|
|
||||||
@ -2363,7 +2415,13 @@ begin
|
|||||||
// Read the properties of the <svg> tag
|
// Read the properties of the <svg> tag
|
||||||
// ----------------
|
// ----------------
|
||||||
AData.Width := StringWithUnitToFloat(Doc.DocumentElement.GetAttribute('width'));
|
AData.Width := StringWithUnitToFloat(Doc.DocumentElement.GetAttribute('width'));
|
||||||
AData.Height := StringWithUnitToFloat(Doc.DocumentElement.GetAttribute('height'));
|
lStr := Doc.DocumentElement.GetAttribute('height');
|
||||||
|
if lStr <> '' then
|
||||||
|
begin
|
||||||
|
lDocNeedsSizeAutoDetection := False;
|
||||||
|
AData.Height := StringWithUnitToFloat(lStr);
|
||||||
|
end;
|
||||||
|
|
||||||
{$ifdef SVG_MERGE_LAYER_STYLES}
|
{$ifdef SVG_MERGE_LAYER_STYLES}
|
||||||
FLayerStylesKeys.Clear;
|
FLayerStylesKeys.Clear;
|
||||||
FLayerStylesValues.Clear;
|
FLayerStylesValues.Clear;
|
||||||
@ -2380,6 +2438,7 @@ begin
|
|||||||
if lNodeName = 'viewBox' then
|
if lNodeName = 'viewBox' then
|
||||||
begin
|
begin
|
||||||
lViewBox := ReadSpaceSeparatedFloats(lNodeValue, '');
|
lViewBox := ReadSpaceSeparatedFloats(lNodeValue, '');
|
||||||
|
lDocNeedsSizeAutoDetection := False;
|
||||||
AData.Width := lViewBox[2] - lViewBox[0];
|
AData.Width := lViewBox[2] - lViewBox[0];
|
||||||
AData.Height := lViewBox[3] - lViewBox[1];
|
AData.Height := lViewBox[3] - lViewBox[1];
|
||||||
end
|
end
|
||||||
@ -2398,6 +2457,23 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
// Auto-detect the document size of necessary
|
||||||
|
if lDocNeedsSizeAutoDetection then
|
||||||
|
begin
|
||||||
|
lx := 0;
|
||||||
|
ly := 0;
|
||||||
|
lx2 := 0;
|
||||||
|
ly2 := 0;
|
||||||
|
lCurNode := Doc.DocumentElement.FirstChild;
|
||||||
|
while Assigned(lCurNode) do
|
||||||
|
begin
|
||||||
|
AutoDetectDocSize(lx, ly, lx2, ly2, lCurNode);
|
||||||
|
lCurNode := lCurNode.NextSibling;
|
||||||
|
end;
|
||||||
|
AData.Width := lx2 - lx;
|
||||||
|
AData.Height := ly2 - ly;
|
||||||
|
end;
|
||||||
|
|
||||||
// ----------------
|
// ----------------
|
||||||
// Now process the elements
|
// Now process the elements
|
||||||
// ----------------
|
// ----------------
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user