mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-12-16 19:00:40 +01:00
fpvectorial: svg - improves text span and viewbox support, now text already shows in text_test_1.svg
git-svn-id: trunk@44392 -
This commit is contained in:
parent
91b0b4fb35
commit
68648a037f
@ -149,9 +149,7 @@ type
|
|||||||
spbfFontColor, spbfFontSize, spbfFontName, spbfFontBold, spbfFontItalic,
|
spbfFontColor, spbfFontSize, spbfFontName, spbfFontBold, spbfFontItalic,
|
||||||
spbfFontUnderline, spbfFontStrikeThrough, spbfAlignment,
|
spbfFontUnderline, spbfFontStrikeThrough, spbfAlignment,
|
||||||
// Page style
|
// Page style
|
||||||
sseMarginTop, sseMarginBottom, sseMarginLeft, sseMarginRight,
|
sseMarginTop, sseMarginBottom, sseMarginLeft, sseMarginRight
|
||||||
// Positioning
|
|
||||||
ssePosition
|
|
||||||
);
|
);
|
||||||
|
|
||||||
TvSetStyleElements = set of TvSetStyleElement;
|
TvSetStyleElements = set of TvSetStyleElement;
|
||||||
@ -170,6 +168,9 @@ type
|
|||||||
{ TvStyle }
|
{ TvStyle }
|
||||||
|
|
||||||
TvStyle = class
|
TvStyle = class
|
||||||
|
protected
|
||||||
|
FExtraDebugStr: string;
|
||||||
|
public
|
||||||
Name: string;
|
Name: string;
|
||||||
Parent: TvStyle; // Can be nil
|
Parent: TvStyle; // Can be nil
|
||||||
Kind: TvStyleKind;
|
Kind: TvStyleKind;
|
||||||
@ -182,17 +183,15 @@ type
|
|||||||
// Page style
|
// Page style
|
||||||
MarginTop, MarginBottom, MarginLeft, MarginRight: Double; // in mm
|
MarginTop, MarginBottom, MarginLeft, MarginRight: Double; // in mm
|
||||||
SuppressSpacingBetweenSameParagraphs : Boolean;
|
SuppressSpacingBetweenSameParagraphs : Boolean;
|
||||||
// Positioning
|
|
||||||
X, Y: Double;
|
|
||||||
//
|
//
|
||||||
SetElements: TvSetStyleElements;
|
SetElements: TvSetStyleElements;
|
||||||
//
|
//
|
||||||
Constructor Create;
|
Constructor Create;
|
||||||
|
|
||||||
function GetKind: TvStyleKind; // takes care of parenting
|
function GetKind: TvStyleKind; // takes care of parenting
|
||||||
procedure Clear();
|
procedure Clear(); virtual;
|
||||||
procedure CopyFrom(AFrom: TvStyle);
|
procedure CopyFrom(AFrom: TvStyle);
|
||||||
procedure ApplyOver(AFrom: TvStyle);
|
procedure ApplyOver(AFrom: TvStyle); virtual;
|
||||||
function CreateStyleCombinedWithParent: TvStyle;
|
function CreateStyleCombinedWithParent: TvStyle;
|
||||||
function GenerateDebugTree(ADestRoutine: TvDebugAddItemProc; APageItem: Pointer): Pointer; virtual;
|
function GenerateDebugTree(ADestRoutine: TvDebugAddItemProc; APageItem: Pointer): Pointer; virtual;
|
||||||
end;
|
end;
|
||||||
@ -1757,9 +1756,7 @@ begin
|
|||||||
[Self.ClassName, Name, lParentName]);
|
[Self.ClassName, Name, lParentName]);
|
||||||
|
|
||||||
if spbfPenColor in SetElements then
|
if spbfPenColor in SetElements then
|
||||||
begin
|
|
||||||
lStr := lStr + Format('Pen.Color==%s', [TvEntity.GenerateDebugStrForFPColor(Pen.Color)]);
|
lStr := lStr + Format('Pen.Color==%s', [TvEntity.GenerateDebugStrForFPColor(Pen.Color)]);
|
||||||
end;
|
|
||||||
{ // Pen, Brush and Font
|
{ // Pen, Brush and Font
|
||||||
spbfPenColor, spbfPenStyle, spbfPenWidth,
|
spbfPenColor, spbfPenStyle, spbfPenWidth,
|
||||||
spbfBrushColor, spbfBrushStyle, spbfBrushGradient,
|
spbfBrushColor, spbfBrushStyle, spbfBrushGradient,
|
||||||
@ -1777,6 +1774,7 @@ begin
|
|||||||
BoolToStr(Font.Underline),
|
BoolToStr(Font.Underline),
|
||||||
BoolToStr(Font.StrikeThrough),
|
BoolToStr(Font.StrikeThrough),
|
||||||
GetEnumName(TypeInfo(TvTextAnchor), integer(TextAnchor))}
|
GetEnumName(TypeInfo(TvTextAnchor), integer(TextAnchor))}
|
||||||
|
lStr := lStr + FExtraDebugStr;
|
||||||
Result := ADestRoutine(lStr, APageItem);
|
Result := ADestRoutine(lStr, APageItem);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|||||||
@ -55,6 +55,15 @@ type
|
|||||||
function GetList: TList;
|
function GetList: TList;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TSVGTextSpanStyle }
|
||||||
|
|
||||||
|
TSVGTextSpanStyle = class(TvStyle)
|
||||||
|
public
|
||||||
|
PositionSet: Boolean;
|
||||||
|
X, Y: Double;
|
||||||
|
function GenerateDebugTree(ADestRoutine: TvDebugAddItemProc; APageItem: Pointer): Pointer; override;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TSVGPathTokenizer }
|
{ TSVGPathTokenizer }
|
||||||
|
|
||||||
TSVGPathTokenizer = class
|
TSVGPathTokenizer = class
|
||||||
@ -70,6 +79,8 @@ type
|
|||||||
function DebugOutTokensAsString: string;
|
function DebugOutTokensAsString: string;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
TSVGCoordinateKind = (sckUnknown, sckX, sckY);
|
||||||
|
|
||||||
{ TvSVGVectorialReader }
|
{ TvSVGVectorialReader }
|
||||||
|
|
||||||
TvSVGVectorialReader = class(TvCustomVectorialReader)
|
TvSVGVectorialReader = class(TvCustomVectorialReader)
|
||||||
@ -77,6 +88,9 @@ type
|
|||||||
FPointSeparator, FCommaSeparator: TFormatSettings;
|
FPointSeparator, FCommaSeparator: TFormatSettings;
|
||||||
FSVGPathTokenizer: TSVGPathTokenizer;
|
FSVGPathTokenizer: TSVGPathTokenizer;
|
||||||
FLayerStylesKeys, FLayerStylesValues: TFPList; // of TStringList;
|
FLayerStylesKeys, FLayerStylesValues: TFPList; // of TStringList;
|
||||||
|
// View box adjustment
|
||||||
|
ViewBoxAdjustment: Boolean;
|
||||||
|
ViewBox_Width, ViewBox_Height, Page_Width, Page_Height: Double;
|
||||||
// Defs section
|
// Defs section
|
||||||
FBrushDefs: TFPList; // of TvEntityWithPenAndBrush;
|
FBrushDefs: TFPList; // of TvEntityWithPenAndBrush;
|
||||||
// debug symbols
|
// debug symbols
|
||||||
@ -113,7 +127,7 @@ type
|
|||||||
function ReadTextFromNode(ANode: TDOMNode; AData: TvVectorialPage; ADoc: TvVectorialDocument): TvEntity;
|
function ReadTextFromNode(ANode: TDOMNode; AData: TvVectorialPage; ADoc: TvVectorialDocument): TvEntity;
|
||||||
function ReadUseFromNode(ANode: TDOMNode; AData: TvVectorialPage; ADoc: TvVectorialDocument): TvEntity;
|
function ReadUseFromNode(ANode: TDOMNode; AData: TvVectorialPage; ADoc: TvVectorialDocument): TvEntity;
|
||||||
//
|
//
|
||||||
function StringWithUnitToFloat(AStr: string): Double;
|
function StringWithUnitToFloat(AStr: string; ACoordKind: TSVGCoordinateKind = sckUnknown): Double;
|
||||||
function StringFloatZeroToOneToWord(AStr: string): Word;
|
function StringFloatZeroToOneToWord(AStr: string): Word;
|
||||||
procedure ConvertSVGCoordinatesToFPVCoordinates(
|
procedure ConvertSVGCoordinatesToFPVCoordinates(
|
||||||
const AData: TvVectorialPage;
|
const AData: TvVectorialPage;
|
||||||
@ -145,6 +159,17 @@ const
|
|||||||
FLOAT_MILIMETERS_PER_PIXEL = 5*0.2822; // DPI 90 = 1 / 90 inches per pixel => Actually I changed the value by this factor! Because otherwise it looks ugly!
|
FLOAT_MILIMETERS_PER_PIXEL = 5*0.2822; // DPI 90 = 1 / 90 inches per pixel => Actually I changed the value by this factor! Because otherwise it looks ugly!
|
||||||
FLOAT_PIXELS_PER_MILIMETER = 1 / FLOAT_MILIMETERS_PER_PIXEL; // DPI 90 = 1 / 90 inches per pixel
|
FLOAT_PIXELS_PER_MILIMETER = 1 / FLOAT_MILIMETERS_PER_PIXEL; // DPI 90 = 1 / 90 inches per pixel
|
||||||
|
|
||||||
|
{ TSVGTextSpanStyle }
|
||||||
|
|
||||||
|
function TSVGTextSpanStyle.GenerateDebugTree(ADestRoutine: TvDebugAddItemProc;
|
||||||
|
APageItem: Pointer): Pointer;
|
||||||
|
begin
|
||||||
|
FExtraDebugStr := '';
|
||||||
|
if PositionSet then
|
||||||
|
FExtraDebugStr := FExtraDebugStr + Format(' X=%f Y=%f', [X, Y]);
|
||||||
|
Result:=inherited GenerateDebugTree(ADestRoutine, APageItem);
|
||||||
|
end;
|
||||||
|
|
||||||
{ TSVGObjectStack }
|
{ TSVGObjectStack }
|
||||||
|
|
||||||
function TSVGObjectStack.GetList: TList;
|
function TSVGObjectStack.GetList: TList;
|
||||||
@ -2319,8 +2344,8 @@ var
|
|||||||
lx, ly: double;
|
lx, ly: double;
|
||||||
lText: TvText;
|
lText: TvText;
|
||||||
lParagraph: TvParagraph;
|
lParagraph: TvParagraph;
|
||||||
lTextSpanStack: TSVGObjectStack;
|
lTextSpanStack: TSVGObjectStack; // of TSVGTextSpanStyle
|
||||||
lCurStyle: TvStyle;
|
lCurStyle: TSVGTextSpanStyle;
|
||||||
i: Integer;
|
i: Integer;
|
||||||
lNodeName, lNodeValue: DOMString;
|
lNodeName, lNodeValue: DOMString;
|
||||||
|
|
||||||
@ -2330,9 +2355,14 @@ var
|
|||||||
begin
|
begin
|
||||||
for j := 0 to lTextSpanStack.GetList().Count-1 do
|
for j := 0 to lTextSpanStack.GetList().Count-1 do
|
||||||
begin
|
begin
|
||||||
lCurStyle := TvStyle(lTextSpanStack.GetList().Items[j]);
|
lCurStyle := TSVGTextSpanStyle(lTextSpanStack.GetList().Items[j]);
|
||||||
if ADest.Style = nil then ADest.Style := TvStyle.Create;
|
if ADest.Style = nil then ADest.Style := TvStyle.Create;
|
||||||
ADest.Style.ApplyOver(lCurStyle);
|
ADest.Style.ApplyOver(lCurStyle);
|
||||||
|
if lCurStyle.PositionSet then
|
||||||
|
begin
|
||||||
|
ADest.X := ADest.X + lCurStyle.X; // or substitute completely ?
|
||||||
|
ADest.Y := ADest.Y + lCurStyle.Y;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -2350,7 +2380,7 @@ var
|
|||||||
|
|
||||||
if lNodeName = 'tspan' then
|
if lNodeName = 'tspan' then
|
||||||
begin
|
begin
|
||||||
lCurStyle := TvStyle.Create;
|
lCurStyle := TSVGTextSpanStyle.Create;
|
||||||
lTextSpanStack.Push(lCurStyle);
|
lTextSpanStack.Push(lCurStyle);
|
||||||
|
|
||||||
// read the attributes
|
// read the attributes
|
||||||
@ -2360,13 +2390,13 @@ var
|
|||||||
lNodeValue := lCurNode.Attributes.Item[j].NodeValue;
|
lNodeValue := lCurNode.Attributes.Item[j].NodeValue;
|
||||||
if lNodeName = 'x' then
|
if lNodeName = 'x' then
|
||||||
begin
|
begin
|
||||||
Include(lCurStyle.SetElements, ssePosition);
|
lCurStyle.PositionSet := True;
|
||||||
lCurStyle.X := StringWithUnitToFloat(lNodeValue)
|
lCurStyle.X := StringWithUnitToFloat(lNodeValue, sckX)
|
||||||
end
|
end
|
||||||
else if lNodeName = 'y' then
|
else if lNodeName = 'y' then
|
||||||
begin
|
begin
|
||||||
Include(lCurStyle.SetElements, ssePosition);
|
lCurStyle.PositionSet := True;
|
||||||
lCurStyle.Y := StringWithUnitToFloat(lNodeValue)
|
lCurStyle.Y := StringWithUnitToFloat(lNodeValue, sckY)
|
||||||
end
|
end
|
||||||
//else if lNodeName = 'id' then
|
//else if lNodeName = 'id' then
|
||||||
// lText.Name := lNodeValue
|
// lText.Name := lNodeValue
|
||||||
@ -2417,9 +2447,9 @@ begin
|
|||||||
lNodeName := ANode.Attributes.Item[i].NodeName;
|
lNodeName := ANode.Attributes.Item[i].NodeName;
|
||||||
lNodeValue := ANode.Attributes.Item[i].NodeValue;
|
lNodeValue := ANode.Attributes.Item[i].NodeValue;
|
||||||
if lNodeName = 'x' then
|
if lNodeName = 'x' then
|
||||||
lx := lx + StringWithUnitToFloat(lNodeValue)
|
lx := lx + StringWithUnitToFloat(lNodeValue, sckX)
|
||||||
else if lNodeName = 'y' then
|
else if lNodeName = 'y' then
|
||||||
ly := ly + StringWithUnitToFloat(lNodeValue)
|
ly := ly + StringWithUnitToFloat(lNodeValue, sckY)
|
||||||
else if lNodeName = 'id' then
|
else if lNodeName = 'id' then
|
||||||
lText.Name := lNodeValue
|
lText.Name := lNodeValue
|
||||||
else if lNodeName = 'style' then
|
else if lNodeName = 'style' then
|
||||||
@ -2512,7 +2542,7 @@ begin
|
|||||||
Result := lInsert;
|
Result := lInsert;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TvSVGVectorialReader.StringWithUnitToFloat(AStr: string): Double;
|
function TvSVGVectorialReader.StringWithUnitToFloat(AStr: string; ACoordKind: TSVGCoordinateKind = sckUnknown): Double;
|
||||||
var
|
var
|
||||||
UnitStr, ValueStr: string;
|
UnitStr, ValueStr: string;
|
||||||
Len: Integer;
|
Len: Integer;
|
||||||
@ -2552,6 +2582,10 @@ begin
|
|||||||
else // If there is no unit, just use StrToFloat
|
else // If there is no unit, just use StrToFloat
|
||||||
begin
|
begin
|
||||||
Result := StrToFloat(AStr, FPointSeparator);
|
Result := StrToFloat(AStr, FPointSeparator);
|
||||||
|
if ViewBoxAdjustment and (ACoordKind = sckX) then
|
||||||
|
Result := Result * Page_Width / ViewBox_Width;
|
||||||
|
if ViewBoxAdjustment and (ACoordKind = sckY) then
|
||||||
|
Result := Result * Page_Height / ViewBox_Height;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -2693,6 +2727,7 @@ var
|
|||||||
lx, ly, lx2, ly2: Double;
|
lx, ly, lx2, ly2: Double;
|
||||||
begin
|
begin
|
||||||
FPathNumber := 0;
|
FPathNumber := 0;
|
||||||
|
ViewBoxAdjustment := False;
|
||||||
|
|
||||||
// ----------------
|
// ----------------
|
||||||
// Read the properties of the <svg> tag
|
// Read the properties of the <svg> tag
|
||||||
@ -2704,6 +2739,8 @@ begin
|
|||||||
lDocNeedsSizeAutoDetection := False;
|
lDocNeedsSizeAutoDetection := False;
|
||||||
AData.Height := StringWithUnitToFloat(lStr);
|
AData.Height := StringWithUnitToFloat(lStr);
|
||||||
end;
|
end;
|
||||||
|
Page_Width := AData.Width;
|
||||||
|
Page_Height := AData.Height;
|
||||||
|
|
||||||
{$ifdef SVG_MERGE_LAYER_STYLES}
|
{$ifdef SVG_MERGE_LAYER_STYLES}
|
||||||
FLayerStylesKeys.Clear;
|
FLayerStylesKeys.Clear;
|
||||||
@ -2721,9 +2758,20 @@ begin
|
|||||||
if lNodeName = 'viewBox' then
|
if lNodeName = 'viewBox' then
|
||||||
begin
|
begin
|
||||||
lViewBox := ReadSpaceSeparatedFloats(lNodeValue, '');
|
lViewBox := ReadSpaceSeparatedFloats(lNodeValue, '');
|
||||||
|
if lDocNeedsSizeAutoDetection then // Has only ViewBox
|
||||||
|
begin
|
||||||
lDocNeedsSizeAutoDetection := False;
|
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];
|
||||||
|
ViewBox_Width := 0;
|
||||||
|
ViewBox_Height := 0;
|
||||||
|
end
|
||||||
|
else // Has both viewBox and width/height!
|
||||||
|
begin
|
||||||
|
ViewBox_Width := lViewBox[2] - lViewBox[0];
|
||||||
|
ViewBox_Height := lViewBox[3] - lViewBox[1];
|
||||||
|
ViewBoxAdjustment := True;
|
||||||
|
end;
|
||||||
end
|
end
|
||||||
else if lNodeName = 'style' then
|
else if lNodeName = 'style' then
|
||||||
begin
|
begin
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user