fpvectorial: Fixes quadratic beziers in SVG reader

git-svn-id: trunk@41860 -
This commit is contained in:
sekelsenmat 2013-06-24 09:28:15 +00:00
parent 6d49af0c96
commit d470200313

View File

@ -1280,7 +1280,7 @@ procedure TvSVGVectorialReader.ReadNextPathCommand(ACurTokenType: TSVGTokenType;
var i: Integer; var CurX, CurY: Double; AData: TvVectorialPage; var i: Integer; var CurX, CurY: Double; AData: TvVectorialPage;
ADoc: TvVectorialDocument); ADoc: TvVectorialDocument);
var var
X, Y, X2, Y2, X3, Y3: Double; X, Y, X2, Y2, X3, Y3, XQ, YQ: Double;
LargeArcFlag, SweepFlag, LeftmostEllipse, ClockwiseArc: Boolean; LargeArcFlag, SweepFlag, LeftmostEllipse, ClockwiseArc: Boolean;
lCurTokenType: TSVGTokenType; lCurTokenType: TSVGTokenType;
lDebugStr: String; lDebugStr: String;
@ -1475,35 +1475,42 @@ begin
// -------------- // --------------
else if lCurTokenType in [sttQuadraticBezierTo, sttRelativeQuadraticBezierTo] then else if lCurTokenType in [sttQuadraticBezierTo, sttRelativeQuadraticBezierTo] then
begin begin
X2 := FSVGPathTokenizer.Tokens.Items[i+1].Value; XQ := FSVGPathTokenizer.Tokens.Items[i+1].Value;
Y2 := FSVGPathTokenizer.Tokens.Items[i+2].Value; YQ := FSVGPathTokenizer.Tokens.Items[i+2].Value;
X := FSVGPathTokenizer.Tokens.Items[i+3].Value; X := FSVGPathTokenizer.Tokens.Items[i+3].Value;
Y := FSVGPathTokenizer.Tokens.Items[i+4].Value; Y := FSVGPathTokenizer.Tokens.Items[i+4].Value;
// Careful that absolute coordinates require using ConvertSVGCoordinatesToFPVCoordinates // Careful that absolute coordinates require using ConvertSVGCoordinatesToFPVCoordinates
if lCurTokenType in [sttRelativeQuadraticBezierTo] then if lCurTokenType in [sttRelativeQuadraticBezierTo] then
begin begin
ConvertSVGDeltaToFPVDelta(AData, X2, Y2, X2, Y2); ConvertSVGDeltaToFPVDelta(AData, XQ, YQ, XQ, YQ);
ConvertSVGDeltaToFPVDelta(AData, X, Y, X, Y); ConvertSVGDeltaToFPVDelta(AData, X, Y, X, Y);
XQ := XQ + CurX;
YQ := YQ + CurY;
X := X + CurX;
Y := Y + CurY;
end end
else else
begin begin
ConvertSVGCoordinatesToFPVCoordinates(AData, X2, Y2, X2, Y2); ConvertSVGCoordinatesToFPVCoordinates(AData, XQ, YQ, XQ, YQ);
ConvertSVGCoordinatesToFPVCoordinates(AData, X, Y, X, Y); ConvertSVGCoordinatesToFPVCoordinates(AData, X, Y, X, Y);
end; end;
if lCurTokenType = sttRelativeQuadraticBezierTo then // Convert quadratic to cubic bezier
begin // CP1 = QP0 + 2/3 *(QP1-QP0)
AData.AddBezierToPath(X2 + CurX, Y2 + CurY, X2 + CurX, Y2 + CurY, X + CurX, Y + CurY); // CP2 = QP2 + 2/3 *(QP1-QP2)
CurX := CurX + X; // See http://stackoverflow.com/questions/3162645/convert-a-quadratic-bezier-to-a-cubic
CurY := CurY + Y; // Just CP1=CP2=QP1 does not work! See svg/w3c/path2.svg
end X2 := CurX + (2/3) * (XQ-CurX);
else Y2 := CurY + (2/3) * (YQ-CurY);
begin //
AData.AddBezierToPath(X2, Y2, X2, Y2, X, Y); X3 := X + (2/3) * (XQ-X);
CurX := X; Y3 := Y + (2/3) * (YQ-Y);
CurY := Y;
end; AData.AddBezierToPath(X2, Y2, X3, Y3, X, Y);
CurX := X;
CurY := Y;
Inc(i, 5); Inc(i, 5);
end end