diff --git a/components/fpvectorial/fpvectorial.pas b/components/fpvectorial/fpvectorial.pas index b8976b5bf4..6fd0f33b65 100644 --- a/components/fpvectorial/fpvectorial.pas +++ b/components/fpvectorial/fpvectorial.pas @@ -1756,21 +1756,25 @@ begin [Self.ClassName, Name, lParentName]); if spbfPenColor in SetElements then - lStr := lStr + Format('Pen.Color==%s', [TvEntity.GenerateDebugStrForFPColor(Pen.Color)]); -{ // Pen, Brush and Font - spbfPenColor, spbfPenStyle, spbfPenWidth, - spbfBrushColor, spbfBrushStyle, spbfBrushGradient, - spbfFontColor, spbfFontSize, spbfFontName, spbfFontBold, spbfFontItalic, + lStr := lStr + Format(' Pen.Color=%s', [TvEntity.GenerateDebugStrForFPColor(Pen.Color)]); +{ spbfPenStyle, spbfPenWidth, + spbfBrushColor, spbfBrushStyle, spbfBrushGradient,} + if spbfFontColor in SetElements then + lStr := lStr + Format(' Font.Color=%s', [TvEntity.GenerateDebugStrForFPColor(Pen.Color)]); + if spbfFontSize in SetElements then + lStr := lStr + Format(' Font.Size=%d', [Font.Size]); + if spbfFontName in SetElements then + lStr := lStr + ' Font.Name=' + Font.Name; + if spbfFontBold in SetElements then + if Font.Bold then lStr := lStr + Format(' Font.Bold=%s', [BoolToStr(Font.Bold)]); + if spbfFontItalic in SetElements then + if Font.Italic then lStr := lStr + Format(' Font.Bold=%s', [BoolToStr(Font.Italic)]); +{ spbfFontUnderline, spbfFontStrikeThrough, spbfAlignment, // Page style - sseMarginTop, sseMarginBottom, sseMarginLeft, sseMarginRight, - // Positioning - ssePosition + sseMarginTop, sseMarginBottom, sseMarginLeft, sseMarginRight ); -{ , - Font.Size, Font.Name, Font.Orientation, - BoolToStr(Font.Bold), - BoolToStr(Font.Italic), +{ Font.Size, Font.Name, Font.Orientation, BoolToStr(Font.Underline), BoolToStr(Font.StrikeThrough), GetEnumName(TypeInfo(TvTextAnchor), integer(TextAnchor))} @@ -5222,6 +5226,8 @@ procedure TvParagraph.Render(ADest: TFPCustomCanvas; ARenderInfo: TvRenderInfo; var lCurWidth: Double = 0.0; lLeft, lTop, lRight, lBottom: Double; + OldTextX: Double = 0.0; + OldTextY: Double = 0.0; lEntity: TvEntity; lText: TvText absolute lEntity; begin @@ -5231,11 +5237,21 @@ begin begin if lEntity is TvText then begin - lText.X := X + lCurWidth; - lText.Y := Y; + // Direct text position setting resets the auto-positioning + if (OldTextX <> lText.X) or (OldTextY <> lText.Y) then + lCurWidth := 0; + + OldTextX := lText.X; + OldTextY := lText.Y; + lText.X := lText.Y + X + lCurWidth; + lText.Y := lText.Y + Y; + lText.Render(ADest, ARenderInfo, ADestX, ADestY, AMulX, AMuly); lText.CalculateBoundingBox(ADest, lLeft, lTop, lRight, lBottom); lCurWidth := lCurWidth + Abs(lRight - lLeft); + + lText.X := OldTextX; + lText.Y := OldTextY; end; lEntity := GetNextEntity(); end; diff --git a/components/fpvectorial/svgvectorialreader.pas b/components/fpvectorial/svgvectorialreader.pas index 8588e7ac80..c04787e7c2 100644 --- a/components/fpvectorial/svgvectorialreader.pas +++ b/components/fpvectorial/svgvectorialreader.pas @@ -101,6 +101,7 @@ 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 ReadSVGFontStyleWithKeyAndValue_ToStyle(AKey, AValue: string; ADest: TvStyle): TvSetPenBrushAndFontElements; function ReadSVGGeneralStyleWithKeyAndValue(AKey, AValue: string; ADestEntity: TvEntity): TvSetPenBrushAndFontElements; function IsAttributeFromStyle(AStr: string): Boolean; procedure ApplyLayerStyles(ADestEntity: TvEntity); @@ -973,6 +974,54 @@ begin end; end; +function TvSVGVectorialReader.ReadSVGFontStyleWithKeyAndValue_ToStyle(AKey, + AValue: string; ADest: TvStyle): TvSetPenBrushAndFontElements; +var + lLowerValue: String; +begin + Result := []; + lLowerValue := LowerCase(AValue); + // SVG text uses "fill" to indicate the pen color of the text, very unintuitive as + // "fill" is usually for brush in other elements + if AKey = 'fill' then + begin + ADest.Font.Color := ReadSVGColor(AValue); + Result := Result + [spbfFontColor]; + end + // But sometimes SVG also uses stroke! Oh no... + else if AKey = 'stroke' then + begin + ADest.Font.Color := ReadSVGColor(AValue); + Result := Result + [spbfFontColor]; + end + else if AKey = 'fill-opacity' then + ADest.Font.Color.Alpha := StrToInt(AValue)*$101 + else if AKey = 'font-size' then + begin + ADest.Font.Size := Round(StringWithUnitToFloat(AValue)); + Result := Result + [spbfFontSize]; + end + else if AKey = 'font-family' then + ADest.Font.Name := AValue + else if AKey = 'font-weight' then + begin + case lLowerValue of + 'bold': ADest.Font.Bold := True; + end; + end + // Other text attributes, non-font ones + else if AKey = 'text-anchor' then + begin + // Adjust according to the text-anchor, if necessary + {case lLowerValue of + 'start': ADest.TextAnchor := vtaStart; + 'middle': ADest.TextAnchor := vtaMiddle; + 'end': ADest.TextAnchor := vtaEnd; + end;} + end; + ADest.SetElements := ADest.SetElements + Result; +end; + function TvSVGVectorialReader.ReadSVGGeneralStyleWithKeyAndValue(AKey, AValue: string; ADestEntity: TvEntity): TvSetPenBrushAndFontElements; var @@ -2391,12 +2440,12 @@ var if lNodeName = 'x' then begin lCurStyle.PositionSet := True; - lCurStyle.X := StringWithUnitToFloat(lNodeValue, sckX) + lCurStyle.X := StringWithUnitToFloat(lNodeValue, sckX); end else if lNodeName = 'y' then begin lCurStyle.PositionSet := True; - lCurStyle.Y := StringWithUnitToFloat(lNodeValue, sckY) + lCurStyle.Y := StringWithUnitToFloat(lNodeValue, sckY); end //else if lNodeName = 'id' then // lText.Name := lNodeValue @@ -2404,7 +2453,7 @@ var // ReadSVGStyle(lNodeValue, lParagraph) else if IsAttributeFromStyle(lNodeName) then begin - //ReadSVGFontStyleWithKeyAndValue(lNodeName, lNodeValue, lText); + ReadSVGFontStyleWithKeyAndValue_ToStyle(lNodeName, lNodeValue, lCurStyle); //ReadSVGGeneralStyleWithKeyAndValue(lNodeName, lNodeValue, lText); end; end; @@ -2585,7 +2634,7 @@ begin if ViewBoxAdjustment and (ACoordKind = sckX) then Result := Result * Page_Width / ViewBox_Width; if ViewBoxAdjustment and (ACoordKind = sckY) then - Result := Result * Page_Height / ViewBox_Height; + Result := Page_Height - Result * Page_Height / ViewBox_Height; end; end;