diff --git a/components/fpvectorial/fpvectorial.pas b/components/fpvectorial/fpvectorial.pas index 96778157a7..8cfd594de8 100644 --- a/components/fpvectorial/fpvectorial.pas +++ b/components/fpvectorial/fpvectorial.pas @@ -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), diff --git a/components/fpvectorial/svgvectorialreader.pas b/components/fpvectorial/svgvectorialreader.pas index 41e832d9fb..1ef5caf6ae 100644 --- a/components/fpvectorial/svgvectorialreader.pas +++ b/components/fpvectorial/svgvectorialreader.pas @@ -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 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;