mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-15 20:19:24 +02:00
fpvectorial: Greatly improves the ellipse arc drawing, now it finally works in many cases =)
git-svn-id: trunk@41650 -
This commit is contained in:
parent
d23d72eca9
commit
cb7c9207bb
@ -382,11 +382,14 @@ type
|
|||||||
It has the opposite direction of text in the LCL TCanvas.
|
It has the opposite direction of text in the LCL TCanvas.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TvTextAnchor = (vtaStart, vtaMiddle, vtaEnd);
|
||||||
|
|
||||||
{ TvText }
|
{ TvText }
|
||||||
|
|
||||||
TvText = class(TvEntityWithPenBrushAndFont)
|
TvText = class(TvEntityWithPenBrushAndFont)
|
||||||
public
|
public
|
||||||
Value: TStringList;
|
Value: TStringList;
|
||||||
|
TextAnchor: TvTextAnchor;
|
||||||
constructor Create; override;
|
constructor Create; override;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
function TryToSelect(APos: TPoint; var ASubpart: Cardinal): TvFindEntityResult; override;
|
function TryToSelect(APos: TPoint; var ASubpart: Cardinal): TvFindEntityResult; override;
|
||||||
@ -1070,51 +1073,6 @@ begin
|
|||||||
XStart := T2DSegment(Previous).X;
|
XStart := T2DSegment(Previous).X;
|
||||||
YStart := T2DSegment(Previous).Y;
|
YStart := T2DSegment(Previous).Y;
|
||||||
|
|
||||||
{
|
|
||||||
solve 4 equations and 4 unknown values (CX, CY, t1, t2)
|
|
||||||
X,Y has t=t2 // Xstart,Ystart has t=t1
|
|
||||||
CX := X - RX*Cos(t2)*Cos(XRotation) + RY*Sin(t2)*Sin(XRotation);
|
|
||||||
CX := XStart - RX*Cos(t1)*Cos(XRotation) + RY*Sin(t1)*Sin(XRotation);
|
|
||||||
CY := Y - RY*Sin(t2)*Cos(XRotation) - RX*Cos(t2)*Sin(XRotation);
|
|
||||||
CY := YStart - RY*Sin(t1)*Cos(XRotation) - RX*Cos(t1)*Sin(XRotation);
|
|
||||||
|
|
||||||
Substituting we get 2 equations and 2 unknown values (t1, t2)
|
|
||||||
X - RX*Cos(t2)*Cos(XRotation) + RY*Sin(t2)*Sin(XRotation) = XStart - RX*Cos(t1)*Cos(XRotation) + RY*Sin(t1)*Sin(XRotation)
|
|
||||||
Y - RY*Sin(t2)*Cos(XRotation) - RX*Cos(t2)*Sin(XRotation) = YStart - RY*Sin(t1)*Cos(XRotation) - RX*Cos(t1)*Sin(XRotation)
|
|
||||||
|
|
||||||
Simplify:
|
|
||||||
|
|
||||||
A = RX*Cos(XRotation)
|
|
||||||
B = RY*Cos(XRotation)
|
|
||||||
C = RY*Sin(XRotation)
|
|
||||||
D = RX*Sin(XRotation)
|
|
||||||
|
|
||||||
X - A*Cos(t2) + C*Sin(t2) = XStart - A*Cos(t1) + C*Sin(t1)
|
|
||||||
Y - B*Sin(t2) - D*Cos(t2) = YStart - B*Sin(t1) - D*Cos(t1)
|
|
||||||
|
|
||||||
Attempt to corner Sin(t1):
|
|
||||||
|
|
||||||
X - A*Cos(t2) + C*Sin(t2) = XStart - A*sqrt(1-Sin(t1)^2) + C*Sin(t1)
|
|
||||||
X - A*Cos(t2) + C*Sin(t2) - XStart - C*Sin(t1) = - A*sqrt(1-Sin^2(t1))
|
|
||||||
Mega = X - A*Cos(t2) + C*Sin(t2) - XStart
|
|
||||||
Mega^2 - 2*Mega*C*Sin(t1) + C^2*Sin^2(t1) = A^2*(1-Sin^2(t1))
|
|
||||||
Mega^2 - A^2 - 2*Mega*C*Sin(t1) + (C^2+A^2)*Sin^2(t1) = 0
|
|
||||||
|
|
||||||
Baskara!!!
|
|
||||||
|
|
||||||
AB = (C^2+A^2)
|
|
||||||
BB = -2*Mega*C
|
|
||||||
CB = Mega^2
|
|
||||||
|
|
||||||
DeltaB=BB^2-4*AB*CB
|
|
||||||
Sin(t1)=(-BB+/-sqrt(DeltaB))/(2*AB)
|
|
||||||
|
|
||||||
Now roll it back!
|
|
||||||
|
|
||||||
X - A*Cos(t2) + C*Sin(t2) = XStart - A*sqrt(1-Sin(t1)^2) + C*Sin(t1)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Solve by rotating everything to align the ellipse to the axises and then rotating back again
|
// Solve by rotating everything to align the ellipse to the axises and then rotating back again
|
||||||
E1 := Rotate3DPointInXY(Make3DPoint(XStart,YStart,0), Make3DPoint(0,0,0),-1*XRotation);
|
E1 := Rotate3DPointInXY(Make3DPoint(XStart,YStart,0), Make3DPoint(0,0,0),-1*XRotation);
|
||||||
E2 := Rotate3DPointInXY(Make3DPoint(X,Y,0), Make3DPoint(0,0,0),-1*XRotation);
|
E2 := Rotate3DPointInXY(Make3DPoint(X,Y,0), Make3DPoint(0,0,0),-1*XRotation);
|
||||||
@ -1137,14 +1095,8 @@ begin
|
|||||||
|
|
||||||
lT1 := SolveNumericallyAngle(AlignedEllipseCenterEquationT1, 0.0001, 20);
|
lT1 := SolveNumericallyAngle(AlignedEllipseCenterEquationT1, 0.0001, 20);
|
||||||
|
|
||||||
//lT2 := arccos((- E1.X + RX*cos(lt1) + E2.X)/RX);
|
|
||||||
|
|
||||||
// CX = E1.X - RX*cos(t1)
|
|
||||||
// CY = E1.Y - RY*sin(t1)
|
|
||||||
CX1 := E1.X - RX*cos(lt1);
|
CX1 := E1.X - RX*cos(lt1);
|
||||||
CY1 := E1.Y - RY*sin(lt1);
|
CY1 := E1.Y - RY*sin(lt1);
|
||||||
//CX2 := E2.X - RX*cos(lt2);
|
|
||||||
//CY2 := E2.Y - RY*sin(lt2);
|
|
||||||
|
|
||||||
// Rotate back!
|
// Rotate back!
|
||||||
RotatedCenter := Rotate3DPointInXY(Make3DPoint(CX1,CY1,0), Make3DPoint(0,0,0),XRotation);
|
RotatedCenter := Rotate3DPointInXY(Make3DPoint(CX1,CY1,0), Make3DPoint(0,0,0),XRotation);
|
||||||
@ -1152,19 +1104,17 @@ begin
|
|||||||
CY1 := RotatedCenter.Y;
|
CY1 := RotatedCenter.Y;
|
||||||
|
|
||||||
// The other ellipse is simetrically positioned
|
// The other ellipse is simetrically positioned
|
||||||
// so that the line between the two ellipse center is orthogonal to the line
|
if (CX1 > Xstart) then
|
||||||
// between (X,Y) and (Xstart,Ystart)
|
CX2 := X - (CX1-Xstart)
|
||||||
CX2 := RotatedCenter.X;
|
else
|
||||||
CY2 := RotatedCenter.Y;
|
CX2 := Xstart - (CX1-X);
|
||||||
|
//
|
||||||
|
if (CY1 > Y) then
|
||||||
|
CY2 := Ystart - (CY1-Y)
|
||||||
|
else
|
||||||
|
CY2 := Y - (CY1-Ystart);
|
||||||
|
|
||||||
// errado!!!! Apagar quando achar o correto =(
|
// Achar qual é a da esquerda e qual a da direita
|
||||||
{
|
|
||||||
CX := X - RX*Cos(0)*Cos(XRotation) + RY*Sin(0)*Sin(XRotation);
|
|
||||||
CY := Y - RY*Sin(0)*Cos(XRotation) - RX*Cos(0)*Sin(XRotation);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ativar quando tiver codigo pra calcular CX1, etc
|
|
||||||
if CX1 < CX2 then
|
if CX1 < CX2 then
|
||||||
begin
|
begin
|
||||||
LeftMostX := CX1;
|
LeftMostX := CX1;
|
||||||
@ -1233,36 +1183,46 @@ begin
|
|||||||
|
|
||||||
CalculateCenter();
|
CalculateCenter();
|
||||||
|
|
||||||
// Search for the minimum and maximum X
|
if XRotation = 0 then
|
||||||
t1 := arctan(-RY*tan(XRotation)/RX) - Pi;
|
begin
|
||||||
t2 := arctan(-RY*tan(XRotation)/RX);
|
ALeft := CX-RX;
|
||||||
t3 := arctan(-RY*tan(XRotation)/RX) + Pi;
|
ARight := CX+RX;
|
||||||
|
ATop := CY-RY;
|
||||||
|
ABottom := CY+RY;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
// Search for the minimum and maximum X
|
||||||
|
t1 := arctan(-RY*tan(XRotation)/RX);
|
||||||
|
t2 := arctan(-RY*tan(XRotation)/RX) + Pi/2;
|
||||||
|
t3 := arctan(-RY*tan(XRotation)/RX) + Pi;
|
||||||
|
|
||||||
x1 := Cx + RX*Cos(t1)*Cos(XRotation)-RY*Sin(t1)*Sin(XRotation);
|
x1 := Cx + RX*Cos(t1)*Cos(XRotation)-RY*Sin(t1)*Sin(XRotation);
|
||||||
x2 := Cx + RX*Cos(t2)*Cos(XRotation)-RY*Sin(t2)*Sin(XRotation);
|
x2 := Cx + RX*Cos(t2)*Cos(XRotation)-RY*Sin(t2)*Sin(XRotation);
|
||||||
x3 := Cx + RX*Cos(t3)*Cos(XRotation)-RY*Sin(t3)*Sin(XRotation);
|
x3 := Cx + RX*Cos(t3)*Cos(XRotation)-RY*Sin(t3)*Sin(XRotation);
|
||||||
|
|
||||||
ALeft := Min(x1, x2);
|
ALeft := Min(x1, x2);
|
||||||
ALeft := Min(ALeft, x3);
|
ALeft := Min(ALeft, x3);
|
||||||
|
|
||||||
ARight := Max(x1, x2);
|
ARight := Max(x1, x2);
|
||||||
ARight := Max(ARight, x3);
|
ARight := Max(ARight, x3);
|
||||||
|
|
||||||
// Now the same for Y
|
// Now the same for Y
|
||||||
|
|
||||||
t1 := arctan(RY*cotan(XRotation)/RX) - Pi;
|
t1 := arctan(RY*cotan(XRotation)/RX);
|
||||||
t2 := arctan(RY*cotan(XRotation)/RX);
|
t2 := arctan(RY*cotan(XRotation)/RX) + Pi/2;
|
||||||
t3 := arctan(RY*cotan(XRotation)/RX) + Pi;
|
t3 := arctan(RY*cotan(XRotation)/RX) + 3*Pi/2;
|
||||||
|
|
||||||
y1 := CY + RY*Sin(t1)*Cos(XRotation)+RX*Cos(t1)*Sin(XRotation);
|
y1 := CY + RY*Sin(t1)*Cos(XRotation)+RX*Cos(t1)*Sin(XRotation);
|
||||||
y2 := CY + RY*Sin(t2)*Cos(XRotation)+RX*Cos(t2)*Sin(XRotation);
|
y2 := CY + RY*Sin(t2)*Cos(XRotation)+RX*Cos(t2)*Sin(XRotation);
|
||||||
y3 := CY + RY*Sin(t3)*Cos(XRotation)+RX*Cos(t3)*Sin(XRotation);
|
y3 := CY + RY*Sin(t3)*Cos(XRotation)+RX*Cos(t3)*Sin(XRotation);
|
||||||
|
|
||||||
ATop := Min(y1, y2);
|
ATop := Min(y1, y2);
|
||||||
ATop := Min(ATop, y3);
|
ATop := Min(ATop, y3);
|
||||||
|
|
||||||
ABottom := Max(y1, y2);
|
ABottom := Max(y1, y2);
|
||||||
ABottom := Max(ABottom, y3);
|
ABottom := Max(ABottom, y3);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TvVerticalFormulaStack }
|
{ TvVerticalFormulaStack }
|
||||||
@ -2282,12 +2242,33 @@ var
|
|||||||
i: Integer;
|
i: Integer;
|
||||||
//
|
//
|
||||||
LowerDim: T3DPoint;
|
LowerDim: T3DPoint;
|
||||||
|
XAnchorAdjustment: Integer;
|
||||||
|
lLongestLine, lLineWidth: Integer;
|
||||||
|
{$ifdef USE_LCL_CANVAS}
|
||||||
|
ACanvas: TCanvas absolute ADest;
|
||||||
|
{$endif}
|
||||||
begin
|
begin
|
||||||
inherited Render(ADest, ARenderInfo, ADestX, ADestY, AMulX, AMulY);
|
inherited Render(ADest, ARenderInfo, ADestX, ADestY, AMulX, AMulY);
|
||||||
|
|
||||||
// Don't draw anything if we have alpha=zero
|
// Don't draw anything if we have alpha=zero
|
||||||
if Font.Color.Alpha = 0 then Exit;
|
if Font.Color.Alpha = 0 then Exit;
|
||||||
|
|
||||||
|
// if an anchor is set, use it
|
||||||
|
// to do this, first search for the longest line
|
||||||
|
lLongestLine := 0;
|
||||||
|
for i := 0 to Value.Count - 1 do
|
||||||
|
begin
|
||||||
|
lLineWidth := ACanvas.TextWidth(Value.Strings[i]);
|
||||||
|
if lLineWidth > lLongestLine then
|
||||||
|
lLongestLine := lLineWidth;
|
||||||
|
end;
|
||||||
|
case TextAnchor of
|
||||||
|
vtaMiddle: XAnchorAdjustment := -1 * lLongestLine div 2;
|
||||||
|
vtaEnd: XAnchorAdjustment := -1 * lLongestLine;
|
||||||
|
else
|
||||||
|
XAnchorAdjustment := 0;
|
||||||
|
end;
|
||||||
|
|
||||||
// TvText supports multiple lines
|
// TvText supports multiple lines
|
||||||
for i := 0 to Value.Count - 1 do
|
for i := 0 to Value.Count - 1 do
|
||||||
begin
|
begin
|
||||||
@ -2300,7 +2281,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
ADest.Font.FPColor := AdjustColorToBackground(Font.Color, ARenderInfo);
|
ADest.Font.FPColor := AdjustColorToBackground(Font.Color, ARenderInfo);
|
||||||
ADest.TextOut(CoordToCanvasX(X), Round(LowerDim.Y), Value.Strings[i]);
|
ADest.TextOut(CoordToCanvasX(X)+XAnchorAdjustment, Round(LowerDim.Y), Value.Strings[i]);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -912,7 +912,7 @@ begin
|
|||||||
lNodeName := lCurNode.Attributes.Item[i].NodeName;
|
lNodeName := lCurNode.Attributes.Item[i].NodeName;
|
||||||
if lNodeName = 'id' then
|
if lNodeName = 'id' then
|
||||||
begin
|
begin
|
||||||
lLayerName := UTF16ToUTF8(lCurNode.Attributes.Item[i].NodeValue);
|
lLayerName := lCurNode.Attributes.Item[i].NodeValue;
|
||||||
lBlock.Name := lLayerName;
|
lBlock.Name := lLayerName;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -980,7 +980,7 @@ begin
|
|||||||
else if lNodeName = 'r' then
|
else if lNodeName = 'r' then
|
||||||
cr := StringWithUnitToFloat(ANode.Attributes.Item[i].NodeValue)
|
cr := StringWithUnitToFloat(ANode.Attributes.Item[i].NodeValue)
|
||||||
else if lNodeName = 'id' then
|
else if lNodeName = 'id' then
|
||||||
lCircle.Name := UTF16ToUTF8(ANode.Attributes.Item[i].NodeValue)
|
lCircle.Name := ANode.Attributes.Item[i].NodeValue
|
||||||
else if lNodeName = 'style' then
|
else if lNodeName = 'style' then
|
||||||
ReadSVGStyle(ANode.Attributes.Item[i].NodeValue, lCircle)
|
ReadSVGStyle(ANode.Attributes.Item[i].NodeValue, lCircle)
|
||||||
else if IsAttributeFromStyle(lNodeName) then
|
else if IsAttributeFromStyle(lNodeName) then
|
||||||
@ -1030,7 +1030,7 @@ begin
|
|||||||
else if lNodeName = 'ry' then
|
else if lNodeName = 'ry' then
|
||||||
cry := StringWithUnitToFloat(ANode.Attributes.Item[i].NodeValue)
|
cry := StringWithUnitToFloat(ANode.Attributes.Item[i].NodeValue)
|
||||||
else if lNodeName = 'id' then
|
else if lNodeName = 'id' then
|
||||||
lEllipse.Name := UTF16ToUTF8(ANode.Attributes.Item[i].NodeValue)
|
lEllipse.Name := ANode.Attributes.Item[i].NodeValue
|
||||||
else if lNodeName = 'style' then
|
else if lNodeName = 'style' then
|
||||||
ReadSVGStyle(ANode.Attributes.Item[i].NodeValue, lEllipse)
|
ReadSVGStyle(ANode.Attributes.Item[i].NodeValue, lEllipse)
|
||||||
else if IsAttributeFromStyle(lNodeName) then
|
else if IsAttributeFromStyle(lNodeName) then
|
||||||
@ -1075,7 +1075,7 @@ begin
|
|||||||
begin
|
begin
|
||||||
lNodeName := ANode.Attributes.Item[i].NodeName;
|
lNodeName := ANode.Attributes.Item[i].NodeName;
|
||||||
if lNodeName = 'id' then
|
if lNodeName = 'id' then
|
||||||
lLayerName := UTF16ToUTF8(ANode.Attributes.Item[i].NodeValue);
|
lLayerName := ANode.Attributes.Item[i].NodeValue;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
lParentLayer := AData.GetCurrentLayer();
|
lParentLayer := AData.GetCurrentLayer();
|
||||||
@ -1097,7 +1097,7 @@ begin
|
|||||||
begin
|
begin
|
||||||
{$ifdef SVG_MERGE_LAYER_STYLES}
|
{$ifdef SVG_MERGE_LAYER_STYLES}
|
||||||
lLayerStyleKeys.Add(lNodeName);
|
lLayerStyleKeys.Add(lNodeName);
|
||||||
lLayerStyleValues.Add(UTF16ToUTF8(ANode.Attributes.Item[i].NodeValue));
|
lLayerStyleValues.Add(ANode.Attributes.Item[i].NodeValue);
|
||||||
{$else}
|
{$else}
|
||||||
lLayer.SetPenBrushAndFontElements += ReadSVGPenStyleWithKeyAndValue(lNodeName, ANode.Attributes.Item[i].NodeValue, lLayer);
|
lLayer.SetPenBrushAndFontElements += ReadSVGPenStyleWithKeyAndValue(lNodeName, ANode.Attributes.Item[i].NodeValue, lLayer);
|
||||||
lLayer.SetPenBrushAndFontElements += ReadSVGBrushStyleWithKeyAndValue(lNodeName, ANode.Attributes.Item[i].NodeValue, lLayer);
|
lLayer.SetPenBrushAndFontElements += ReadSVGBrushStyleWithKeyAndValue(lNodeName, ANode.Attributes.Item[i].NodeValue, lLayer);
|
||||||
@ -1211,7 +1211,7 @@ begin
|
|||||||
begin
|
begin
|
||||||
lNodeName := ANode.Attributes.Item[i].NodeName;
|
lNodeName := ANode.Attributes.Item[i].NodeName;
|
||||||
if lNodeName = 'id' then
|
if lNodeName = 'id' then
|
||||||
lPath.Name := UTF16ToUTF8(ANode.Attributes.Item[i].NodeValue)
|
lPath.Name := ANode.Attributes.Item[i].NodeValue
|
||||||
else if lNodeName = 'style' then
|
else if lNodeName = 'style' then
|
||||||
ReadSVGStyle(ANode.Attributes.Item[i].NodeValue, lPath)
|
ReadSVGStyle(ANode.Attributes.Item[i].NodeValue, lPath)
|
||||||
else if IsAttributeFromStyle(lNodeName) then
|
else if IsAttributeFromStyle(lNodeName) then
|
||||||
@ -1469,7 +1469,6 @@ begin
|
|||||||
begin
|
begin
|
||||||
ConvertSVGCoordinatesToFPVCoordinates(AData, X, Y, X, Y);
|
ConvertSVGCoordinatesToFPVCoordinates(AData, X, Y, X, Y);
|
||||||
end;
|
end;
|
||||||
ConvertSVGDeltaToFPVDelta(AData, X2, Y2, X2, Y2);
|
|
||||||
|
|
||||||
// Convert SVG flags to fpvectorial flags
|
// Convert SVG flags to fpvectorial flags
|
||||||
LeftmostEllipse := (LargeArcFlag and (not SweepFlag))
|
LeftmostEllipse := (LargeArcFlag and (not SweepFlag))
|
||||||
@ -1567,7 +1566,7 @@ begin
|
|||||||
begin
|
begin
|
||||||
lNodeName := ANode.Attributes.Item[i].NodeName;
|
lNodeName := ANode.Attributes.Item[i].NodeName;
|
||||||
if lNodeName = 'id' then
|
if lNodeName = 'id' then
|
||||||
lPath.Name := UTF16ToUTF8(ANode.Attributes.Item[i].NodeValue)
|
lPath.Name := ANode.Attributes.Item[i].NodeValue
|
||||||
else if lNodeName = 'style' then
|
else if lNodeName = 'style' then
|
||||||
ReadSVGStyle(ANode.Attributes.Item[i].NodeValue, lPath)
|
ReadSVGStyle(ANode.Attributes.Item[i].NodeValue, lPath)
|
||||||
else if IsAttributeFromStyle(lNodeName) then
|
else if IsAttributeFromStyle(lNodeName) then
|
||||||
@ -1617,7 +1616,7 @@ begin
|
|||||||
else if lNodeName = 'height' then
|
else if lNodeName = 'height' then
|
||||||
cy := StringWithUnitToFloat(ANode.Attributes.Item[i].NodeValue)
|
cy := StringWithUnitToFloat(ANode.Attributes.Item[i].NodeValue)
|
||||||
else if lNodeName = 'id' then
|
else if lNodeName = 'id' then
|
||||||
lRect.Name := UTF16ToUTF8(ANode.Attributes.Item[i].NodeValue)
|
lRect.Name := ANode.Attributes.Item[i].NodeValue
|
||||||
else if lNodeName = 'style' then
|
else if lNodeName = 'style' then
|
||||||
ReadSVGStyle(ANode.Attributes.Item[i].NodeValue, lRect)
|
ReadSVGStyle(ANode.Attributes.Item[i].NodeValue, lRect)
|
||||||
else if IsAttributeFromStyle(lNodeName) then
|
else if IsAttributeFromStyle(lNodeName) then
|
||||||
@ -1648,6 +1647,7 @@ var
|
|||||||
i: Integer;
|
i: Integer;
|
||||||
lNodeName: DOMString;
|
lNodeName: DOMString;
|
||||||
lCurNode: TDOMNode;
|
lCurNode: TDOMNode;
|
||||||
|
lTextAnchor: string = '';
|
||||||
begin
|
begin
|
||||||
lx := 0.0;
|
lx := 0.0;
|
||||||
ly := 0.0;
|
ly := 0.0;
|
||||||
@ -1663,9 +1663,11 @@ begin
|
|||||||
else if lNodeName = 'y' then
|
else if lNodeName = 'y' then
|
||||||
ly := StringWithUnitToFloat(ANode.Attributes.Item[i].NodeValue)
|
ly := StringWithUnitToFloat(ANode.Attributes.Item[i].NodeValue)
|
||||||
else if lNodeName = 'id' then
|
else if lNodeName = 'id' then
|
||||||
lText.Name := UTF16ToUTF8(ANode.Attributes.Item[i].NodeValue)
|
lText.Name := ANode.Attributes.Item[i].NodeValue
|
||||||
else if lNodeName = 'style' then
|
else if lNodeName = 'style' then
|
||||||
ReadSVGStyle(ANode.Attributes.Item[i].NodeValue, lText, True)
|
ReadSVGStyle(ANode.Attributes.Item[i].NodeValue, lText)
|
||||||
|
else if lNodeName = 'text-anchor' then
|
||||||
|
lTextAnchor := ANode.Attributes.Item[i].NodeValue
|
||||||
else if IsAttributeFromStyle(lNodeName) then
|
else if IsAttributeFromStyle(lNodeName) then
|
||||||
ReadSVGFontStyleWithKeyAndValue(lNodeName, ANode.Attributes.Item[i].NodeValue, lText);
|
ReadSVGFontStyleWithKeyAndValue(lNodeName, ANode.Attributes.Item[i].NodeValue, lText);
|
||||||
end;
|
end;
|
||||||
@ -1678,9 +1680,16 @@ begin
|
|||||||
lText.Value.Add(lTextStr);
|
lText.Value.Add(lTextStr);
|
||||||
|
|
||||||
// Set the coordinates
|
// Set the coordinates
|
||||||
ConvertSVGDeltaToFPVDelta(
|
ConvertSVGCoordinatesToFPVCoordinates(
|
||||||
AData, lx, ly, lText.X, lText.Y);
|
AData, lx, ly, lText.X, lText.Y);
|
||||||
|
|
||||||
|
// Adjust according to the text-anchor, if necessary
|
||||||
|
lTextAnchor := LowerCase(lTextAnchor);
|
||||||
|
case lTextAnchor of
|
||||||
|
'middle': lText.TextAnchor := vtaMiddle;
|
||||||
|
'end': lText.TextAnchor := vtaEnd;
|
||||||
|
end;
|
||||||
|
|
||||||
// Now add other lines, which appear as <tspan ...>another line</tspan>
|
// Now add other lines, which appear as <tspan ...>another line</tspan>
|
||||||
// Example:
|
// Example:
|
||||||
// <text x="10" y="20" style="fill:red;">Several lines:
|
// <text x="10" y="20" style="fill:red;">Several lines:
|
||||||
@ -1880,7 +1889,7 @@ begin
|
|||||||
begin
|
begin
|
||||||
{$ifdef SVG_MERGE_LAYER_STYLES}
|
{$ifdef SVG_MERGE_LAYER_STYLES}
|
||||||
lLayerStyleKeys.Add(lNodeName);
|
lLayerStyleKeys.Add(lNodeName);
|
||||||
lLayerStyleValues.Add(UTF16ToUTF8(ANode.Attributes.Item[i].NodeValue));
|
lLayerStyleValues.Add(ANode.Attributes.Item[i].NodeValue);
|
||||||
{$endif}
|
{$endif}
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
Loading…
Reference in New Issue
Block a user