mirror of
				https://gitlab.com/freepascal.org/lazarus/lazarus.git
				synced 2025-11-04 09:39:43 +01:00 
			
		
		
		
	fpvectorial-svg: Implements support for reading PNG raster images inside SVG
git-svn-id: trunk@42309 -
This commit is contained in:
		
							parent
							
								
									fe0a06d109
								
							
						
					
					
						commit
						9230dae80f
					
				@ -26,6 +26,7 @@ uses
 | 
			
		||||
  {$ifdef USE_LCL_CANVAS}
 | 
			
		||||
  Graphics, LCLIntf, LCLType,
 | 
			
		||||
  {$endif}
 | 
			
		||||
  base64,
 | 
			
		||||
  fpvectorial, fpimage, zstream;
 | 
			
		||||
 | 
			
		||||
type
 | 
			
		||||
@ -65,8 +66,11 @@ function SolveNumericallyAngle(ANumericalEquation: TNumericalEquation;
 | 
			
		||||
// Compression/Decompression
 | 
			
		||||
procedure DeflateBytes(var ASource, ADest: TFPVUByteArray);
 | 
			
		||||
procedure DeflateStream(ASource, ADest: TStream);
 | 
			
		||||
// ASCII85
 | 
			
		||||
// Binary to Text encodings
 | 
			
		||||
procedure DecodeASCII85(ASource: string; var ADest: TFPVUByteArray);
 | 
			
		||||
procedure DecodeBase64(ASource: string; ADest: TStream);
 | 
			
		||||
// Byte array to stream conversion
 | 
			
		||||
procedure ByteArrayToStream(ASource: TFPVUByteArray; ADest: TStream);
 | 
			
		||||
// Debug
 | 
			
		||||
procedure FPVUDebug(AStr: string);
 | 
			
		||||
procedure FPVUDebugLn(AStr: string);
 | 
			
		||||
@ -577,6 +581,29 @@ begin
 | 
			
		||||
  end;
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
procedure DecodeBase64(ASource: string; ADest: TStream);
 | 
			
		||||
var
 | 
			
		||||
  lSourceStream: TStringStream;
 | 
			
		||||
  lDecoder: TBase64DecodingStream;
 | 
			
		||||
begin
 | 
			
		||||
  lSourceStream := TStringStream.Create(ASource);
 | 
			
		||||
  lDecoder := TBase64DecodingStream.Create(lSourceStream);
 | 
			
		||||
  try
 | 
			
		||||
    ADest.CopyFrom(lDecoder, lDecoder.Size);
 | 
			
		||||
  finally
 | 
			
		||||
    lDecoder.Free;
 | 
			
		||||
    lSourceStream.Free;
 | 
			
		||||
  end;
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
procedure ByteArrayToStream(ASource: TFPVUByteArray; ADest: TStream);
 | 
			
		||||
var
 | 
			
		||||
  i: Integer;
 | 
			
		||||
begin
 | 
			
		||||
  for i := 0 to Length(ASource)-1 do
 | 
			
		||||
    ADest.WriteByte(ASource[i]);
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
procedure FPVUDebug(AStr: string);
 | 
			
		||||
begin
 | 
			
		||||
  FPVDebugBuffer := FPVDebugBuffer + AStr;
 | 
			
		||||
 | 
			
		||||
@ -16,6 +16,8 @@ interface
 | 
			
		||||
uses
 | 
			
		||||
  Classes, SysUtils, math,
 | 
			
		||||
  fpimage, fpcanvas, laz2_xmlread, laz2_dom, fgl,
 | 
			
		||||
  // image data formats
 | 
			
		||||
  fpreadpng,
 | 
			
		||||
  fpvectorial, fpvutils, lazutf8, TypInfo;
 | 
			
		||||
 | 
			
		||||
type
 | 
			
		||||
@ -78,10 +80,11 @@ type
 | 
			
		||||
    function ReadSVGPenStyleWithKeyAndValue(AKey, AValue: string; ADestEntity: TvEntityWithPen): TvSetPenBrushAndFontElements;
 | 
			
		||||
    function ReadSVGBrushStyleWithKeyAndValue(AKey, AValue: string; ADestEntity: TvEntityWithPenAndBrush): TvSetPenBrushAndFontElements;
 | 
			
		||||
    function ReadSVGFontStyleWithKeyAndValue(AKey, AValue: string; ADestEntity: TvEntityWithPenBrushAndFont): TvSetPenBrushAndFontElements;
 | 
			
		||||
    function ReadSVGGeneralStyleWithKeyAndValue(AKey, AValue: string; ADestEntity: TvEntityWithPen): TvSetPenBrushAndFontElements;
 | 
			
		||||
    function ReadSVGGeneralStyleWithKeyAndValue(AKey, AValue: string; ADestEntity: TvEntity): TvSetPenBrushAndFontElements;
 | 
			
		||||
    function IsAttributeFromStyle(AStr: string): Boolean;
 | 
			
		||||
    procedure ApplyLayerStyles(ADestEntity: TvEntity);
 | 
			
		||||
    function ReadSpaceSeparatedFloats(AInput: string): TDoubleArray;
 | 
			
		||||
    function ReadSpaceSeparatedFloats(AInput: string; AOtherSeparators: string): TDoubleArray;
 | 
			
		||||
    function ReadSpaceSeparatedStrings(AInput: string; AOtherSeparators: string): TStringList;
 | 
			
		||||
    procedure ReadSVGTransformationMatrix(AMatrix: string; out AA, AB, AC, AD, AE, AF: Double);
 | 
			
		||||
    //
 | 
			
		||||
    procedure ReadDefsFromNode(ANode: TDOMNode; AData: TvVectorialPage; ADoc: TvVectorialDocument);
 | 
			
		||||
@ -89,6 +92,7 @@ type
 | 
			
		||||
    function ReadEntityFromNode(ANode: TDOMNode; AData: TvVectorialPage; ADoc: TvVectorialDocument): TvEntity;
 | 
			
		||||
    function ReadCircleFromNode(ANode: TDOMNode; AData: TvVectorialPage; ADoc: TvVectorialDocument): TvEntity;
 | 
			
		||||
    function ReadEllipseFromNode(ANode: TDOMNode; AData: TvVectorialPage; ADoc: TvVectorialDocument): TvEntity;
 | 
			
		||||
    function ReadImageFromNode(ANode: TDOMNode; AData: TvVectorialPage; ADoc: TvVectorialDocument): TvEntity;
 | 
			
		||||
    procedure ReadLayerFromNode(ANode: TDOMNode; AData: TvVectorialPage; ADoc: TvVectorialDocument);
 | 
			
		||||
    function ReadLineFromNode(ANode: TDOMNode; AData: TvVectorialPage; ADoc: TvVectorialDocument): TvEntity;
 | 
			
		||||
    function ReadPathFromNode(ANode: TDOMNode; AData: TvVectorialPage; ADoc: TvVectorialDocument): TvEntity;
 | 
			
		||||
@ -923,7 +927,7 @@ begin
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
function TvSVGVectorialReader.ReadSVGGeneralStyleWithKeyAndValue(AKey,
 | 
			
		||||
  AValue: string; ADestEntity: TvEntityWithPen): TvSetPenBrushAndFontElements;
 | 
			
		||||
  AValue: string; ADestEntity: TvEntity): TvSetPenBrushAndFontElements;
 | 
			
		||||
var
 | 
			
		||||
  // transform
 | 
			
		||||
  MA, MB, MC, MD, ME, MF: Double;
 | 
			
		||||
@ -949,7 +953,7 @@ begin
 | 
			
		||||
      begin
 | 
			
		||||
        lFunctionName := lTokenizer.Tokens.Items[i].StrValue;
 | 
			
		||||
        lParamStr := lTokenizer.Tokens.Items[i+1].StrValue;
 | 
			
		||||
        lMatrixElements := ReadSpaceSeparatedFloats(lParamStr);
 | 
			
		||||
        lMatrixElements := ReadSpaceSeparatedFloats(lParamStr, ',');
 | 
			
		||||
 | 
			
		||||
        if lFunctionName = 'matrix' then
 | 
			
		||||
        begin
 | 
			
		||||
@ -1024,17 +1028,25 @@ begin
 | 
			
		||||
  end;
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
function TvSVGVectorialReader.ReadSpaceSeparatedFloats(AInput: string
 | 
			
		||||
  ): TDoubleArray;
 | 
			
		||||
function TvSVGVectorialReader.ReadSpaceSeparatedFloats(AInput: string;
 | 
			
		||||
  AOtherSeparators: string): TDoubleArray;
 | 
			
		||||
var
 | 
			
		||||
  lStrings: TStringList;
 | 
			
		||||
  lInputStr: string;
 | 
			
		||||
  lMatrixElements: array of Double;
 | 
			
		||||
  i: Integer;
 | 
			
		||||
begin
 | 
			
		||||
  lStrings := TStringList.Create;
 | 
			
		||||
  try
 | 
			
		||||
    lStrings.Delimiter := ' ';
 | 
			
		||||
    lStrings.DelimitedText := AInput;
 | 
			
		||||
    // now other separator too
 | 
			
		||||
    lInputStr := AInput;
 | 
			
		||||
    for i := 1 to Length(AOtherSeparators) do
 | 
			
		||||
    begin
 | 
			
		||||
      lInputStr := StringReplace(lInputStr, AOtherSeparators[i], ' ', [rfReplaceAll]);
 | 
			
		||||
    end;
 | 
			
		||||
    //
 | 
			
		||||
    lStrings.DelimitedText := lInputStr;
 | 
			
		||||
    SetLength(lMatrixElements, lStrings.Count);
 | 
			
		||||
    for i := 0 to lStrings.Count-1 do
 | 
			
		||||
    begin
 | 
			
		||||
@ -1047,6 +1059,24 @@ begin
 | 
			
		||||
  end;
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
function TvSVGVectorialReader.ReadSpaceSeparatedStrings(AInput: string;
 | 
			
		||||
  AOtherSeparators: string): TStringList;
 | 
			
		||||
var
 | 
			
		||||
  i: Integer;
 | 
			
		||||
  lInputStr: String;
 | 
			
		||||
begin
 | 
			
		||||
  Result := TStringList.Create;
 | 
			
		||||
  Result.Delimiter := ' ';
 | 
			
		||||
  // now other separator too
 | 
			
		||||
  lInputStr := AInput;
 | 
			
		||||
  for i := 1 to Length(AOtherSeparators) do
 | 
			
		||||
  begin
 | 
			
		||||
    lInputStr := StringReplace(lInputStr, AOtherSeparators[i], ' ', [rfReplaceAll]);
 | 
			
		||||
  end;
 | 
			
		||||
  //
 | 
			
		||||
  Result.DelimitedText := lInputStr;
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
// transform="matrix(0.860815 0 -0 1.07602 354.095 482.177)"=>matrix(a, b, c, d, e, f)
 | 
			
		||||
// See http://apike.ca/prog_svg_transform.html
 | 
			
		||||
procedure TvSVGVectorialReader.ReadSVGTransformationMatrix(
 | 
			
		||||
@ -1054,7 +1084,7 @@ procedure TvSVGVectorialReader.ReadSVGTransformationMatrix(
 | 
			
		||||
var
 | 
			
		||||
  lMatrixElements: array of Double;
 | 
			
		||||
begin
 | 
			
		||||
  lMatrixElements := ReadSpaceSeparatedFloats(AMatrix);
 | 
			
		||||
  lMatrixElements := ReadSpaceSeparatedFloats(AMatrix, '');
 | 
			
		||||
 | 
			
		||||
  AA := lMatrixElements[0];
 | 
			
		||||
  AB := lMatrixElements[1];
 | 
			
		||||
@ -1177,6 +1207,7 @@ begin
 | 
			
		||||
    'circle': Result := ReadCircleFromNode(ANode, AData, ADoc);
 | 
			
		||||
    'ellipse': Result := ReadEllipseFromNode(ANode, AData, ADoc);
 | 
			
		||||
    'g': ReadLayerFromNode(ANode, AData, ADoc);
 | 
			
		||||
    'image': Result := ReadImageFromNode(ANode, AData, ADoc);
 | 
			
		||||
    'line': Result := ReadLineFromNode(ANode, AData, ADoc);
 | 
			
		||||
    'path': Result := ReadPathFromNode(ANode, AData, ADoc);
 | 
			
		||||
    'polygon', 'polyline': Result := ReadPolyFromNode(ANode, AData, ADoc);
 | 
			
		||||
@ -1192,7 +1223,7 @@ var
 | 
			
		||||
  cx, cy, cr, dtmp: double;
 | 
			
		||||
  lCircle: TvCircle;
 | 
			
		||||
  i: Integer;
 | 
			
		||||
  lNodeName: DOMString;
 | 
			
		||||
  lNodeName, lNodeValue: DOMString;
 | 
			
		||||
begin
 | 
			
		||||
  cx := 0.0;
 | 
			
		||||
  cy := 0.0;
 | 
			
		||||
@ -1210,21 +1241,22 @@ begin
 | 
			
		||||
  for i := 0 to ANode.Attributes.Length - 1 do
 | 
			
		||||
  begin
 | 
			
		||||
    lNodeName := ANode.Attributes.Item[i].NodeName;
 | 
			
		||||
    lNodeValue := ANode.Attributes.Item[i].NodeName;
 | 
			
		||||
    if  lNodeName = 'cx' then
 | 
			
		||||
      cx := StringWithUnitToFloat(ANode.Attributes.Item[i].NodeValue)
 | 
			
		||||
      cx := StringWithUnitToFloat(lNodeValue)
 | 
			
		||||
    else if lNodeName = 'cy' then
 | 
			
		||||
      cy := StringWithUnitToFloat(ANode.Attributes.Item[i].NodeValue)
 | 
			
		||||
      cy := StringWithUnitToFloat(lNodeValue)
 | 
			
		||||
    else if lNodeName = 'r' then
 | 
			
		||||
      cr := StringWithUnitToFloat(ANode.Attributes.Item[i].NodeValue)
 | 
			
		||||
      cr := StringWithUnitToFloat(lNodeValue)
 | 
			
		||||
    else if lNodeName = 'id' then
 | 
			
		||||
      lCircle.Name := ANode.Attributes.Item[i].NodeValue
 | 
			
		||||
      lCircle.Name := lNodeValue
 | 
			
		||||
    else if lNodeName = 'style' then
 | 
			
		||||
      ReadSVGStyle(ANode.Attributes.Item[i].NodeValue, lCircle)
 | 
			
		||||
      ReadSVGStyle(lNodeValue, lCircle)
 | 
			
		||||
    else if IsAttributeFromStyle(lNodeName) then
 | 
			
		||||
    begin
 | 
			
		||||
      ReadSVGPenStyleWithKeyAndValue(lNodeName, ANode.Attributes.Item[i].NodeValue, lCircle);
 | 
			
		||||
      ReadSVGBrushStyleWithKeyAndValue(lNodeName, ANode.Attributes.Item[i].NodeValue, lCircle);
 | 
			
		||||
      ReadSVGGeneralStyleWithKeyAndValue(lNodeName, ANode.Attributes.Item[i].NodeValue, lCircle);
 | 
			
		||||
      ReadSVGPenStyleWithKeyAndValue(lNodeName, lNodeValue, lCircle);
 | 
			
		||||
      ReadSVGBrushStyleWithKeyAndValue(lNodeName, lNodeValue, lCircle);
 | 
			
		||||
      ReadSVGGeneralStyleWithKeyAndValue(lNodeName, lNodeValue, lCircle);
 | 
			
		||||
    end;
 | 
			
		||||
  end;
 | 
			
		||||
 | 
			
		||||
@ -1242,7 +1274,7 @@ var
 | 
			
		||||
  cx, cy, crx, cry: double;
 | 
			
		||||
  lEllipse: TvEllipse;
 | 
			
		||||
  i: Integer;
 | 
			
		||||
  lNodeName: DOMString;
 | 
			
		||||
  lNodeName, lNodeValue: DOMString;
 | 
			
		||||
begin
 | 
			
		||||
  cx := 0.0;
 | 
			
		||||
  cy := 0.0;
 | 
			
		||||
@ -1261,23 +1293,24 @@ begin
 | 
			
		||||
  for i := 0 to ANode.Attributes.Length - 1 do
 | 
			
		||||
  begin
 | 
			
		||||
    lNodeName := ANode.Attributes.Item[i].NodeName;
 | 
			
		||||
    lNodeValue := ANode.Attributes.Item[i].NodeName;
 | 
			
		||||
    if  lNodeName = 'cx' then
 | 
			
		||||
      cx := StringWithUnitToFloat(ANode.Attributes.Item[i].NodeValue)
 | 
			
		||||
      cx := StringWithUnitToFloat(lNodeValue)
 | 
			
		||||
    else if lNodeName = 'cy' then
 | 
			
		||||
      cy := StringWithUnitToFloat(ANode.Attributes.Item[i].NodeValue)
 | 
			
		||||
      cy := StringWithUnitToFloat(lNodeValue)
 | 
			
		||||
    else if lNodeName = 'rx' then
 | 
			
		||||
      crx := StringWithUnitToFloat(ANode.Attributes.Item[i].NodeValue)
 | 
			
		||||
      crx := StringWithUnitToFloat(lNodeValue)
 | 
			
		||||
    else if lNodeName = 'ry' then
 | 
			
		||||
      cry := StringWithUnitToFloat(ANode.Attributes.Item[i].NodeValue)
 | 
			
		||||
      cry := StringWithUnitToFloat(lNodeValue)
 | 
			
		||||
    else if lNodeName = 'id' then
 | 
			
		||||
      lEllipse.Name := ANode.Attributes.Item[i].NodeValue
 | 
			
		||||
    else if lNodeName = 'style' then
 | 
			
		||||
      ReadSVGStyle(ANode.Attributes.Item[i].NodeValue, lEllipse)
 | 
			
		||||
      ReadSVGStyle(lNodeValue, lEllipse)
 | 
			
		||||
    else if IsAttributeFromStyle(lNodeName) then
 | 
			
		||||
    begin
 | 
			
		||||
      ReadSVGPenStyleWithKeyAndValue(lNodeName, ANode.Attributes.Item[i].NodeValue, lEllipse);
 | 
			
		||||
      ReadSVGBrushStyleWithKeyAndValue(lNodeName, ANode.Attributes.Item[i].NodeValue, lEllipse);
 | 
			
		||||
      ReadSVGGeneralStyleWithKeyAndValue(lNodeName, ANode.Attributes.Item[i].NodeValue, lEllipse);
 | 
			
		||||
      ReadSVGPenStyleWithKeyAndValue(lNodeName, lNodeValue, lEllipse);
 | 
			
		||||
      ReadSVGBrushStyleWithKeyAndValue(lNodeName, lNodeValue, lEllipse);
 | 
			
		||||
      ReadSVGGeneralStyleWithKeyAndValue(lNodeName, lNodeValue, lEllipse);
 | 
			
		||||
    end;
 | 
			
		||||
  end;
 | 
			
		||||
 | 
			
		||||
@ -1289,6 +1322,95 @@ begin
 | 
			
		||||
  Result := lEllipse;
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
// <image width="92.5" x="0" y="0" height="76.0429"
 | 
			
		||||
//  xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKMAAACGCAYAA
 | 
			
		||||
//  ACxDToF......" clip-path="url(#Clip0)" transform="matrix(1 0 0 1 0 0)"/>
 | 
			
		||||
function TvSVGVectorialReader.ReadImageFromNode(ANode: TDOMNode;
 | 
			
		||||
  AData: TvVectorialPage; ADoc: TvVectorialDocument): TvEntity;
 | 
			
		||||
var
 | 
			
		||||
  lImage: TvRasterImage;
 | 
			
		||||
  lx, ly, lw, lh: Double;
 | 
			
		||||
  i: Integer;
 | 
			
		||||
  lNodeName, lNodeValue: DOMString;
 | 
			
		||||
  lImageDataParts: TStringList;
 | 
			
		||||
  lImageDataBase64: string;
 | 
			
		||||
  lImageData: array of Byte;
 | 
			
		||||
  lImageDataStream: TMemoryStream;
 | 
			
		||||
  lImageReader: TFPCustomImageReader;
 | 
			
		||||
begin
 | 
			
		||||
  lImage := TvRasterImage.Create;
 | 
			
		||||
  lx := 0;
 | 
			
		||||
  ly := 0;
 | 
			
		||||
  lw := 0;
 | 
			
		||||
  lh := 0;
 | 
			
		||||
 | 
			
		||||
  // Apply the layer style
 | 
			
		||||
  //ApplyLayerStyles(lEllipse);
 | 
			
		||||
 | 
			
		||||
  // read the attributes
 | 
			
		||||
  for i := 0 to ANode.Attributes.Length - 1 do
 | 
			
		||||
  begin
 | 
			
		||||
    lNodeName := ANode.Attributes.Item[i].NodeName;
 | 
			
		||||
    lNodeValue := ANode.Attributes.Item[i].NodeValue;
 | 
			
		||||
    if  lNodeName = 'x' then
 | 
			
		||||
      lx := StringWithUnitToFloat(lNodeValue)
 | 
			
		||||
    else if lNodeName = 'y' then
 | 
			
		||||
      ly := StringWithUnitToFloat(lNodeValue)
 | 
			
		||||
    else if lNodeName = 'width' then
 | 
			
		||||
      lw := StringWithUnitToFloat(lNodeValue)
 | 
			
		||||
    else if lNodeName = 'height' then
 | 
			
		||||
      lh := StringWithUnitToFloat(lNodeValue)
 | 
			
		||||
    else if lNodeName = 'xlink:href' then
 | 
			
		||||
    begin
 | 
			
		||||
      lImageDataParts := ReadSpaceSeparatedStrings(lNodeValue, ':;,');
 | 
			
		||||
      try
 | 
			
		||||
        if (lImageDataParts.Strings[0] = 'data') and
 | 
			
		||||
           (lImageDataParts.Strings[1] = 'image/png') and
 | 
			
		||||
           (lImageDataParts.Strings[2] = 'base64') then
 | 
			
		||||
        begin
 | 
			
		||||
          lImageReader := TFPReaderPNG.Create;
 | 
			
		||||
          lImageDataStream := TMemoryStream.Create;
 | 
			
		||||
          try
 | 
			
		||||
            lImageDataBase64 := lImageDataParts.Strings[3];
 | 
			
		||||
            DecodeBase64(lImageDataBase64, lImageDataStream);
 | 
			
		||||
            lImageDataStream.Position := 0;
 | 
			
		||||
            lImage.CreateRGB888Image(10, 10);
 | 
			
		||||
            lImage.RasterImage.LoadFromStream(lImageDataStream, lImageReader);
 | 
			
		||||
          finally
 | 
			
		||||
            lImageDataStream.Free;
 | 
			
		||||
            lImageReader.Free;
 | 
			
		||||
          end;
 | 
			
		||||
        end
 | 
			
		||||
        else
 | 
			
		||||
          raise Exception.Create('[TvSVGVectorialReader.ReadImageFromNode] Unimplemented image format');
 | 
			
		||||
      finally
 | 
			
		||||
        lImageDataParts.Free;
 | 
			
		||||
      end;
 | 
			
		||||
    end
 | 
			
		||||
    else if lNodeName = 'id' then
 | 
			
		||||
      lImage.Name := lNodeValue
 | 
			
		||||
{    else if lNodeName = 'style' then
 | 
			
		||||
      ReadSVGStyle(lNodeValue, lImage)}
 | 
			
		||||
    else if IsAttributeFromStyle(lNodeName) then
 | 
			
		||||
    begin
 | 
			
		||||
      //ReadSVGPenStyleWithKeyAndValue(lNodeName, lNodeValue, lImage);
 | 
			
		||||
      //ReadSVGBrushStyleWithKeyAndValue(lNodeName, lNodeValue, lImage);
 | 
			
		||||
      ReadSVGGeneralStyleWithKeyAndValue(lNodeName, lNodeValue, lImage);
 | 
			
		||||
    end;
 | 
			
		||||
  end;
 | 
			
		||||
 | 
			
		||||
  // Record translate data
 | 
			
		||||
  lx := lx + lImage.X;
 | 
			
		||||
  ly := ly + lImage.Y;
 | 
			
		||||
 | 
			
		||||
  ConvertSVGCoordinatesToFPVCoordinates(
 | 
			
		||||
        AData, lx, ly, lImage.X, lImage.Y);
 | 
			
		||||
  ConvertSVGDeltaToFPVDelta(
 | 
			
		||||
        AData, lw, lh, lImage.Width, lImage.Height);
 | 
			
		||||
 | 
			
		||||
  Result := lImage;
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
procedure TvSVGVectorialReader.ReadLayerFromNode(ANode: TDOMNode;
 | 
			
		||||
  AData: TvVectorialPage; ADoc: TvVectorialDocument);
 | 
			
		||||
var
 | 
			
		||||
@ -2037,7 +2159,7 @@ var
 | 
			
		||||
  lXLink: DOMString = '';
 | 
			
		||||
  lInsertedEntity: TvEntity;
 | 
			
		||||
  i: Integer;
 | 
			
		||||
  lNodeName: DOMString;
 | 
			
		||||
  lNodeName, lNodeValue: DOMString;
 | 
			
		||||
begin
 | 
			
		||||
  Result := nil;
 | 
			
		||||
 | 
			
		||||
@ -2061,6 +2183,24 @@ begin
 | 
			
		||||
 | 
			
		||||
  lInsert := TvInsert.Create;
 | 
			
		||||
  lInsert.InsertEntity := lInsertedEntity;
 | 
			
		||||
 | 
			
		||||
  // Apply the styles
 | 
			
		||||
  // read the attributes
 | 
			
		||||
  for i := 0 to ANode.Attributes.Length - 1 do
 | 
			
		||||
  begin
 | 
			
		||||
    lNodeName := ANode.Attributes.Item[i].NodeName;
 | 
			
		||||
    lNodeValue := ANode.Attributes.Item[i].NodeValue;
 | 
			
		||||
    {if lNodeName = 'style' then
 | 
			
		||||
      ReadSVGStyle(lNodeValue, lText)
 | 
			
		||||
    else} if IsAttributeFromStyle(lNodeName) then
 | 
			
		||||
    begin
 | 
			
		||||
      {ReadSVGPenStyleWithKeyAndValue(lNodeName, lNodeValue, lText);
 | 
			
		||||
      ReadSVGBrushStyleWithKeyAndValue(lNodeName, lNodeValue, lText);
 | 
			
		||||
      ReadSVGFontStyleWithKeyAndValue(lNodeName, lNodeValue, lText);}
 | 
			
		||||
      ReadSVGGeneralStyleWithKeyAndValue(lNodeName, lNodeValue, lInsert);
 | 
			
		||||
    end;
 | 
			
		||||
  end;
 | 
			
		||||
 | 
			
		||||
  Result := lInsert;
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
@ -2175,7 +2315,7 @@ var
 | 
			
		||||
  {$ifdef SVG_MERGE_LAYER_STYLES}
 | 
			
		||||
  lLayerStyleKeys, lLayerStyleValues: TStringList;
 | 
			
		||||
  {$endif}
 | 
			
		||||
  lNodeName: DOMString;
 | 
			
		||||
  lNodeName, lNodeValue: DOMString;
 | 
			
		||||
  ANode: TDOMElement;
 | 
			
		||||
  i: Integer;
 | 
			
		||||
  lCurEntity: TvEntity;
 | 
			
		||||
@ -2200,23 +2340,24 @@ begin
 | 
			
		||||
  for i := 0 to ANode.Attributes.Length - 1 do
 | 
			
		||||
  begin
 | 
			
		||||
    lNodeName := ANode.Attributes.Item[i].NodeName;
 | 
			
		||||
    lNodeValue := ANode.Attributes.Item[i].NodeValue;
 | 
			
		||||
    if lNodeName = 'viewBox' then
 | 
			
		||||
    begin
 | 
			
		||||
      lViewBox := ReadSpaceSeparatedFloats(ANode.Attributes.Item[i].NodeValue);
 | 
			
		||||
      lViewBox := ReadSpaceSeparatedFloats(lNodeValue, '');
 | 
			
		||||
      AData.Width := lViewBox[2] - lViewBox[0];
 | 
			
		||||
      AData.Height := lViewBox[3] - lViewBox[1];
 | 
			
		||||
    end
 | 
			
		||||
    else if lNodeName = 'style' then
 | 
			
		||||
    begin
 | 
			
		||||
      {$ifdef SVG_MERGE_LAYER_STYLES}
 | 
			
		||||
      ReadSVGStyleToStyleLists(ANode.Attributes.Item[i].NodeValue, lLayerStyleKeys, lLayerStyleValues);
 | 
			
		||||
      ReadSVGStyleToStyleLists(lNodeValue, lLayerStyleKeys, lLayerStyleValues);
 | 
			
		||||
      {$endif}
 | 
			
		||||
    end
 | 
			
		||||
    else if IsAttributeFromStyle(lNodeName) then
 | 
			
		||||
    begin
 | 
			
		||||
      {$ifdef SVG_MERGE_LAYER_STYLES}
 | 
			
		||||
      lLayerStyleKeys.Add(lNodeName);
 | 
			
		||||
      lLayerStyleValues.Add(ANode.Attributes.Item[i].NodeValue);
 | 
			
		||||
      lLayerStyleValues.Add(lNodeValue);
 | 
			
		||||
      {$endif}
 | 
			
		||||
    end;
 | 
			
		||||
  end;
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user