fpvectorial-svg: Reworks the current unit code to make it match better the drawing of Chrome, this improves areaofcircle.html greatly

git-svn-id: trunk@47212 -
This commit is contained in:
sekelsenmat 2014-12-17 11:35:52 +00:00
parent 47c65faeef
commit c95dfb9e93
2 changed files with 62 additions and 28 deletions

View File

@ -2591,8 +2591,8 @@ var
lStr: string; lStr: string;
lCurPathSeg: TPathSegment; lCurPathSeg: TPathSegment;
begin begin
lStr := Format('[%s] Name=%s Pen.Color=%s Pen.Style=%s Brush.Color=%s Brush.Style=%s', lStr := Format('[%s] Name=%s X=%f Y=%f Pen.Color=%s Pen.Style=%s Brush.Color=%s Brush.Style=%s',
[Self.ClassName, Self.Name, [Self.ClassName, Self.Name, X, Y,
GenerateDebugStrForFPColor(Pen.Color), GenerateDebugStrForFPColor(Pen.Color),
GetEnumName(TypeInfo(TFPPenStyle), integer(Pen.Style)), GetEnumName(TypeInfo(TFPPenStyle), integer(Pen.Style)),
GenerateDebugStrForFPColor(Brush.Color), GenerateDebugStrForFPColor(Brush.Color),

View File

@ -81,7 +81,7 @@ type
TSVGCoordinateKind = (sckUnknown, sckX, sckY, sckXDelta, sckYDelta, sckXSize, sckYSize); TSVGCoordinateKind = (sckUnknown, sckX, sckY, sckXDelta, sckYDelta, sckXSize, sckYSize);
TSVGUnit = (suPX, suMM); TSVGUnit = (suPX, suMM, suPT {Points});
{ TvSVGVectorialReader } { TvSVGVectorialReader }
@ -131,7 +131,7 @@ type
function ReadUseFromNode(ANode: TDOMNode; AData: TvVectorialPage; ADoc: TvVectorialDocument): TvEntity; function ReadUseFromNode(ANode: TDOMNode; AData: TvVectorialPage; ADoc: TvVectorialDocument): TvEntity;
// //
function StringWithUnitToFloat(AStr: string; ACoordKind: TSVGCoordinateKind = sckUnknown; function StringWithUnitToFloat(AStr: string; ACoordKind: TSVGCoordinateKind = sckUnknown;
ADefaultUnit: TSVGUnit = suPX): Double; ADefaultUnit: TSVGUnit = suPX; ATargetUnit: TSVGUnit = suPX): Double;
function StringFloatZeroToOneToWord(AStr: string): Word; function StringFloatZeroToOneToWord(AStr: string): Word;
procedure ConvertSVGCoordinatesToFPVCoordinates( procedure ConvertSVGCoordinatesToFPVCoordinates(
const AData: TvVectorialPage; const AData: TvVectorialPage;
@ -166,9 +166,12 @@ const
// 90 inches per pixel = (1 / 90) * 25.4 = 0.2822 // 90 inches per pixel = (1 / 90) * 25.4 = 0.2822
// FLOAT_MILIMETERS_PER_PIXEL = 0.3528; // DPI 72 = 1 / 72 inches per pixel // FLOAT_MILIMETERS_PER_PIXEL = 0.3528; // DPI 72 = 1 / 72 inches per pixel
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 = 1; //0.2822; // DPI 90 = 1 / 90 inches per pixel => Actually I changed the value! 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
FLOAT_POINTS_PER_PIXEL = 0.75; // For conversion
FLOAT_PIXEL_PER_POINT = 1 / FLOAT_POINTS_PER_PIXEL; // For conversion
{ TSVGTextSpanStyle } { TSVGTextSpanStyle }
function TSVGTextSpanStyle.GenerateDebugTree(ADestRoutine: TvDebugAddItemProc; function TSVGTextSpanStyle.GenerateDebugTree(ADestRoutine: TvDebugAddItemProc;
@ -987,8 +990,8 @@ begin
end end
else if AKey = 'font-size' then else if AKey = 'font-size' then
begin begin
if ADestEntity <> nil then ADestEntity.Font.Size := Round(StringWithUnitToFloat(AValue, sckXSize, suPX)); if ADestEntity <> nil then ADestEntity.Font.Size := Round(StringWithUnitToFloat(AValue, sckXSize, suPX, suPT));
if ADestStyle <> nil then ADestStyle.Font.Size := Round(StringWithUnitToFloat(AValue, sckXSize, suPX)); if ADestStyle <> nil then ADestStyle.Font.Size := Round(StringWithUnitToFloat(AValue, sckXSize, suPX, suPT));
Result := Result + [spbfFontSize]; Result := Result + [spbfFontSize];
end end
else if AKey = 'font-family' then else if AKey = 'font-family' then
@ -1387,12 +1390,12 @@ begin
begin 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 = 'cx' then if lNodeName = 'cx' then
cx := StringWithUnitToFloat(lNodeValue) cx := StringWithUnitToFloat(lNodeValue, sckX, suPX, suMM)
else if lNodeName = 'cy' then else if lNodeName = 'cy' then
cy := StringWithUnitToFloat(lNodeValue) cy := StringWithUnitToFloat(lNodeValue, sckY, suPX, suMM)
else if lNodeName = 'r' then else if lNodeName = 'r' then
cr := StringWithUnitToFloat(lNodeValue) cr := StringWithUnitToFloat(lNodeValue, sckXSize, suPX, suMM)
else if lNodeName = 'id' then else if lNodeName = 'id' then
lCircle.Name := lNodeValue lCircle.Name := lNodeValue
else if lNodeName = 'style' then else if lNodeName = 'style' then
@ -1405,10 +1408,9 @@ begin
end; end;
end; end;
ConvertSVGCoordinatesToFPVCoordinates( lCircle.X := lCircle.X + cx;
AData, cx, cy, lCircle.X, lCircle.Y); lCircle.Y := lCircle.Y + cy;
ConvertSVGDeltaToFPVDelta( lCircle.Radius := lCircle.Radius + cr;
AData, cr, 0, lCircle.Radius, dtmp);
Result := lCircle; Result := lCircle;
end; end;
@ -2578,9 +2580,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, sckX, suPX) lx := lx + StringWithUnitToFloat(lNodeValue, sckX, suPX, suMM)
else if lNodeName = 'y' then else if lNodeName = 'y' then
ly := ly + StringWithUnitToFloat(lNodeValue, sckY, suPX) ly := ly + StringWithUnitToFloat(lNodeValue, sckY, suPX, suMM)
else if lNodeName = 'id' then else if lNodeName = 'id' then
begin begin
lName := lNodeValue; lName := lNodeValue;
@ -2688,7 +2690,8 @@ begin
end; end;
function TvSVGVectorialReader.StringWithUnitToFloat(AStr: string; function TvSVGVectorialReader.StringWithUnitToFloat(AStr: string;
ACoordKind: TSVGCoordinateKind = sckUnknown; ADefaultUnit: TSVGUnit = suPX): Double; ACoordKind: TSVGCoordinateKind = sckUnknown; ADefaultUnit: TSVGUnit = suPX;
ATargetUnit: TSVGUnit = suPX): Double;
var var
UnitStr, ValueStr: string; UnitStr, ValueStr: string;
Len: Integer; Len: Integer;
@ -2708,9 +2711,33 @@ var
sckYSize: Result := Result * Page_Height / ViewBox_Height; sckYSize: Result := Result * Page_Height / ViewBox_Height;
end; end;
ViewPortApplied := True; ViewPortApplied := True;
end
else
begin
case ACoordKind of
sckY: Result := Page_Height - Result;
sckYDelta: Result := - Result;
end;
end; end;
end; end;
procedure DoProcessMM_End();
begin
if ATargetUnit = suPX then
Result := Result / FLOAT_MILIMETERS_PER_PIXEL;
DoViewBoxAdjust();
end;
procedure DoProcessPX();
begin
Result := StrToFloat(ValueStr, FPointSeparator);
case ATargetUnit of
suMM: Result := Result * FLOAT_MILIMETERS_PER_PIXEL;
suPT: Result := Result * FLOAT_POINTS_PER_PIXEL;
end;
DoViewBoxAdjust();
end;
begin begin
if AStr = '' then Exit(0.0); if AStr = '' then Exit(0.0);
@ -2722,17 +2749,19 @@ begin
begin begin
ValueStr := Copy(AStr, 1, Len-2); ValueStr := Copy(AStr, 1, Len-2);
Result := StrToFloat(ValueStr, FPointSeparator); Result := StrToFloat(ValueStr, FPointSeparator);
DoProcessMM_End();
end end
else if UnitStr = 'cm' then else if UnitStr = 'cm' then
begin begin
ValueStr := Copy(AStr, 1, Len-2); ValueStr := Copy(AStr, 1, Len-2);
Result := StrToFloat(ValueStr, FPointSeparator) * 10; Result := StrToFloat(ValueStr, FPointSeparator);
Result := Result * 10;
DoProcessMM_End();
end end
else if UnitStr = 'px' then else if UnitStr = 'px' then
begin begin
ValueStr := Copy(AStr, 1, Len-2); ValueStr := Copy(AStr, 1, Len-2);
Result := StrToFloat(ValueStr, FPointSeparator); DoProcessPX();
DoViewBoxAdjust();
end end
else if LastChar = '%' then else if LastChar = '%' then
begin begin
@ -2744,18 +2773,23 @@ begin
ValueStr := Copy(AStr, 1, Len-2); ValueStr := Copy(AStr, 1, Len-2);
Result := StrToFloat(ValueStr, FPointSeparator); Result := StrToFloat(ValueStr, FPointSeparator);
end end
// Now process default values
else if ADefaultUnit = suMM then else if ADefaultUnit = suMM then
begin begin
Result := StringWithUnitToFloat(AStr+'mm', ACoordKind); ValueStr := AStr;
Result := StrToFloat(ValueStr, FPointSeparator);
DoProcessMM_End();
end end
else // If there is no unit, just use StrToFloat else if ADefaultUnit = suPX then
begin
ValueStr := AStr;
DoProcessPX();
end
else // If there is no unit and no matching default, just use StrToFloat
begin begin
Result := StrToFloat(AStr, FPointSeparator); Result := StrToFloat(AStr, FPointSeparator);
DoViewBoxAdjust(); DoViewBoxAdjust();
end; end;
// Finish the adjustment for some cases where this is substituting ConvertSVGCoordinatesToFPVCoordinates
if (not ViewPortApplied) and (ACoordKind = sckY) then
Result := Page_Height - Result;
end; end;
function TvSVGVectorialReader.StringFloatZeroToOneToWord(AStr: string): Word; function TvSVGVectorialReader.StringFloatZeroToOneToWord(AStr: string): Word;
@ -2924,12 +2958,12 @@ begin
// ---------------- // ----------------
// Read the properties of the <svg> tag // Read the properties of the <svg> tag
// ---------------- // ----------------
AData.Width := StringWithUnitToFloat(Doc.DocumentElement.GetAttribute('width')); AData.Width := StringWithUnitToFloat(Doc.DocumentElement.GetAttribute('width'), sckX, suPX, suMM);
lStr := Doc.DocumentElement.GetAttribute('height'); lStr := Doc.DocumentElement.GetAttribute('height');
if lStr <> '' then if lStr <> '' then
begin begin
lDocNeedsSizeAutoDetection := False; lDocNeedsSizeAutoDetection := False;
AData.Height := StringWithUnitToFloat(lStr); AData.Height := StringWithUnitToFloat(lStr, sckX, suPX, suMM);
end; end;
Page_Width := AData.Width; Page_Width := AData.Width;
Page_Height := AData.Height; Page_Height := AData.Height;