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;
lCurPathSeg: TPathSegment;
begin
lStr := Format('[%s] Name=%s Pen.Color=%s Pen.Style=%s Brush.Color=%s Brush.Style=%s',
[Self.ClassName, Self.Name,
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, X, Y,
GenerateDebugStrForFPColor(Pen.Color),
GetEnumName(TypeInfo(TFPPenStyle), integer(Pen.Style)),
GenerateDebugStrForFPColor(Brush.Color),

View File

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