mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-12-11 21:00:38 +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,
|
||||
spbfFontUnderline, spbfFontStrikeThrough, spbfAlignment,
|
||||
// Page style
|
||||
sseMarginTop, sseMarginBottom, sseMarginLeft, sseMarginRight,
|
||||
// Positioning
|
||||
ssePosition
|
||||
sseMarginTop, sseMarginBottom, sseMarginLeft, sseMarginRight
|
||||
);
|
||||
|
||||
TvSetStyleElements = set of TvSetStyleElement;
|
||||
@ -170,6 +168,9 @@ type
|
||||
{ TvStyle }
|
||||
|
||||
TvStyle = class
|
||||
protected
|
||||
FExtraDebugStr: string;
|
||||
public
|
||||
Name: string;
|
||||
Parent: TvStyle; // Can be nil
|
||||
Kind: TvStyleKind;
|
||||
@ -182,17 +183,15 @@ type
|
||||
// Page style
|
||||
MarginTop, MarginBottom, MarginLeft, MarginRight: Double; // in mm
|
||||
SuppressSpacingBetweenSameParagraphs : Boolean;
|
||||
// Positioning
|
||||
X, Y: Double;
|
||||
//
|
||||
SetElements: TvSetStyleElements;
|
||||
//
|
||||
Constructor Create;
|
||||
|
||||
function GetKind: TvStyleKind; // takes care of parenting
|
||||
procedure Clear();
|
||||
procedure Clear(); virtual;
|
||||
procedure CopyFrom(AFrom: TvStyle);
|
||||
procedure ApplyOver(AFrom: TvStyle);
|
||||
procedure ApplyOver(AFrom: TvStyle); virtual;
|
||||
function CreateStyleCombinedWithParent: TvStyle;
|
||||
function GenerateDebugTree(ADestRoutine: TvDebugAddItemProc; APageItem: Pointer): Pointer; virtual;
|
||||
end;
|
||||
@ -1757,9 +1756,7 @@ begin
|
||||
[Self.ClassName, Name, lParentName]);
|
||||
|
||||
if spbfPenColor in SetElements then
|
||||
begin
|
||||
lStr := lStr + Format('Pen.Color==%s', [TvEntity.GenerateDebugStrForFPColor(Pen.Color)]);
|
||||
end;
|
||||
{ // Pen, Brush and Font
|
||||
spbfPenColor, spbfPenStyle, spbfPenWidth,
|
||||
spbfBrushColor, spbfBrushStyle, spbfBrushGradient,
|
||||
@ -1777,6 +1774,7 @@ begin
|
||||
BoolToStr(Font.Underline),
|
||||
BoolToStr(Font.StrikeThrough),
|
||||
GetEnumName(TypeInfo(TvTextAnchor), integer(TextAnchor))}
|
||||
lStr := lStr + FExtraDebugStr;
|
||||
Result := ADestRoutine(lStr, APageItem);
|
||||
end;
|
||||
|
||||
|
||||
@ -55,6 +55,15 @@ type
|
||||
function GetList: TList;
|
||||
end;
|
||||
|
||||
{ TSVGTextSpanStyle }
|
||||
|
||||
TSVGTextSpanStyle = class(TvStyle)
|
||||
public
|
||||
PositionSet: Boolean;
|
||||
X, Y: Double;
|
||||
function GenerateDebugTree(ADestRoutine: TvDebugAddItemProc; APageItem: Pointer): Pointer; override;
|
||||
end;
|
||||
|
||||
{ TSVGPathTokenizer }
|
||||
|
||||
TSVGPathTokenizer = class
|
||||
@ -70,6 +79,8 @@ type
|
||||
function DebugOutTokensAsString: string;
|
||||
end;
|
||||
|
||||
TSVGCoordinateKind = (sckUnknown, sckX, sckY);
|
||||
|
||||
{ TvSVGVectorialReader }
|
||||
|
||||
TvSVGVectorialReader = class(TvCustomVectorialReader)
|
||||
@ -77,6 +88,9 @@ type
|
||||
FPointSeparator, FCommaSeparator: TFormatSettings;
|
||||
FSVGPathTokenizer: TSVGPathTokenizer;
|
||||
FLayerStylesKeys, FLayerStylesValues: TFPList; // of TStringList;
|
||||
// View box adjustment
|
||||
ViewBoxAdjustment: Boolean;
|
||||
ViewBox_Width, ViewBox_Height, Page_Width, Page_Height: Double;
|
||||
// Defs section
|
||||
FBrushDefs: TFPList; // of TvEntityWithPenAndBrush;
|
||||
// debug symbols
|
||||
@ -113,7 +127,7 @@ type
|
||||
function ReadTextFromNode(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;
|
||||
procedure ConvertSVGCoordinatesToFPVCoordinates(
|
||||
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_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 }
|
||||
|
||||
function TSVGObjectStack.GetList: TList;
|
||||
@ -2319,8 +2344,8 @@ var
|
||||
lx, ly: double;
|
||||
lText: TvText;
|
||||
lParagraph: TvParagraph;
|
||||
lTextSpanStack: TSVGObjectStack;
|
||||
lCurStyle: TvStyle;
|
||||
lTextSpanStack: TSVGObjectStack; // of TSVGTextSpanStyle
|
||||
lCurStyle: TSVGTextSpanStyle;
|
||||
i: Integer;
|
||||
lNodeName, lNodeValue: DOMString;
|
||||
|
||||
@ -2330,9 +2355,14 @@ var
|
||||
begin
|
||||
for j := 0 to lTextSpanStack.GetList().Count-1 do
|
||||
begin
|
||||
lCurStyle := TvStyle(lTextSpanStack.GetList().Items[j]);
|
||||
lCurStyle := TSVGTextSpanStyle(lTextSpanStack.GetList().Items[j]);
|
||||
if ADest.Style = nil then ADest.Style := TvStyle.Create;
|
||||
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;
|
||||
|
||||
@ -2350,7 +2380,7 @@ var
|
||||
|
||||
if lNodeName = 'tspan' then
|
||||
begin
|
||||
lCurStyle := TvStyle.Create;
|
||||
lCurStyle := TSVGTextSpanStyle.Create;
|
||||
lTextSpanStack.Push(lCurStyle);
|
||||
|
||||
// read the attributes
|
||||
@ -2360,13 +2390,13 @@ var
|
||||
lNodeValue := lCurNode.Attributes.Item[j].NodeValue;
|
||||
if lNodeName = 'x' then
|
||||
begin
|
||||
Include(lCurStyle.SetElements, ssePosition);
|
||||
lCurStyle.X := StringWithUnitToFloat(lNodeValue)
|
||||
lCurStyle.PositionSet := True;
|
||||
lCurStyle.X := StringWithUnitToFloat(lNodeValue, sckX)
|
||||
end
|
||||
else if lNodeName = 'y' then
|
||||
begin
|
||||
Include(lCurStyle.SetElements, ssePosition);
|
||||
lCurStyle.Y := StringWithUnitToFloat(lNodeValue)
|
||||
lCurStyle.PositionSet := True;
|
||||
lCurStyle.Y := StringWithUnitToFloat(lNodeValue, sckY)
|
||||
end
|
||||
//else if lNodeName = 'id' then
|
||||
// lText.Name := lNodeValue
|
||||
@ -2417,9 +2447,9 @@ begin
|
||||
lNodeName := ANode.Attributes.Item[i].NodeName;
|
||||
lNodeValue := ANode.Attributes.Item[i].NodeValue;
|
||||
if lNodeName = 'x' then
|
||||
lx := lx + StringWithUnitToFloat(lNodeValue)
|
||||
lx := lx + StringWithUnitToFloat(lNodeValue, sckX)
|
||||
else if lNodeName = 'y' then
|
||||
ly := ly + StringWithUnitToFloat(lNodeValue)
|
||||
ly := ly + StringWithUnitToFloat(lNodeValue, sckY)
|
||||
else if lNodeName = 'id' then
|
||||
lText.Name := lNodeValue
|
||||
else if lNodeName = 'style' then
|
||||
@ -2512,7 +2542,7 @@ begin
|
||||
Result := lInsert;
|
||||
end;
|
||||
|
||||
function TvSVGVectorialReader.StringWithUnitToFloat(AStr: string): Double;
|
||||
function TvSVGVectorialReader.StringWithUnitToFloat(AStr: string; ACoordKind: TSVGCoordinateKind = sckUnknown): Double;
|
||||
var
|
||||
UnitStr, ValueStr: string;
|
||||
Len: Integer;
|
||||
@ -2552,6 +2582,10 @@ begin
|
||||
else // If there is no unit, just use StrToFloat
|
||||
begin
|
||||
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;
|
||||
|
||||
@ -2693,6 +2727,7 @@ var
|
||||
lx, ly, lx2, ly2: Double;
|
||||
begin
|
||||
FPathNumber := 0;
|
||||
ViewBoxAdjustment := False;
|
||||
|
||||
// ----------------
|
||||
// Read the properties of the <svg> tag
|
||||
@ -2704,6 +2739,8 @@ begin
|
||||
lDocNeedsSizeAutoDetection := False;
|
||||
AData.Height := StringWithUnitToFloat(lStr);
|
||||
end;
|
||||
Page_Width := AData.Width;
|
||||
Page_Height := AData.Height;
|
||||
|
||||
{$ifdef SVG_MERGE_LAYER_STYLES}
|
||||
FLayerStylesKeys.Clear;
|
||||
@ -2721,9 +2758,20 @@ begin
|
||||
if lNodeName = 'viewBox' then
|
||||
begin
|
||||
lViewBox := ReadSpaceSeparatedFloats(lNodeValue, '');
|
||||
if lDocNeedsSizeAutoDetection then // Has only ViewBox
|
||||
begin
|
||||
lDocNeedsSizeAutoDetection := False;
|
||||
AData.Width := lViewBox[2] - lViewBox[0];
|
||||
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
|
||||
else if lNodeName = 'style' then
|
||||
begin
|
||||
|
||||
Loading…
Reference in New Issue
Block a user