mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-12-16 03:00:30 +01:00
fpvectorial: Improves the custom shape support for ODG
git-svn-id: trunk@43826 -
This commit is contained in:
parent
ad229fa25c
commit
e9fb146556
@ -112,6 +112,11 @@ type
|
||||
PageWidth, PageHeight: Double;
|
||||
end;
|
||||
|
||||
TCustomShapeInfo = packed record
|
||||
Width, Height: Double; // in milimiters
|
||||
ViewBox_Left, ViewBox_Top, ViewBox_Width, ViewBox_Height: Double; // unitless
|
||||
end;
|
||||
|
||||
{ TvODGVectorialReader }
|
||||
|
||||
TvODGVectorialReader = class(TvCustomVectorialReader)
|
||||
@ -131,8 +136,8 @@ type
|
||||
//
|
||||
procedure ReadStyleNode(ANode: TDOMNode; AData: TvVectorialPage; ADoc: TvVectorialDocument);
|
||||
procedure ReadStyleStyleNode(ANode: TDOMNode; AData: TvVectorialPage; ADoc: TvVectorialDocument);
|
||||
procedure ReadEnhancedGeometryNodeToTPath(ANode: TDOMNode; AData: TvVectorialPage; ADest: TPath; ADeltaX, ADeltaY: Double);
|
||||
procedure ConvertPathStringToTPath(AStr: string; AData: TvVectorialPage; ADest: TPath; ADeltaX, ADeltaY: Double);
|
||||
procedure ReadEnhancedGeometryNodeToTPath(ANode: TDOMNode; AData: TvVectorialPage; ADest: TPath; ADeltaX, ADeltaY: Double; var AInfo: TCustomShapeInfo);
|
||||
procedure ConvertPathStringToTPath(AStr: string; AData: TvVectorialPage; ADest: TPath; ADeltaX, ADeltaY: Double; AInfo: TCustomShapeInfo);
|
||||
//
|
||||
procedure ReadElement(ANode: TDOMNode; AData: TvVectorialPage; ADoc: TvVectorialDocument);
|
||||
procedure ReadCustomShapeNode(ANode: TDOMNode; AData: TvVectorialPage; ADoc: TvVectorialDocument);
|
||||
@ -155,6 +160,12 @@ type
|
||||
procedure ConvertODGDeltaToFPVDelta(
|
||||
const AData: TvVectorialPage;
|
||||
const ASrcX, ASrcY: Double; var ADestX, ADestY: Double);
|
||||
procedure ConvertViewBoxCoordinatesToODGCoordinates(
|
||||
const AInfo: TCustomShapeInfo;
|
||||
const ASrcX, ASrcY: Double; var ADestX, ADestY: Double);
|
||||
procedure ConvertViewBoxDeltaToODGDelta(
|
||||
const AInfo: TCustomShapeInfo;
|
||||
const ASrcX, ASrcY: Double; var ADestX, ADestY: Double);
|
||||
public
|
||||
{ General reading methods }
|
||||
constructor Create; override;
|
||||
@ -670,13 +681,36 @@ end;
|
||||
<draw:enhanced-geometry svg:viewBox="0 0 21600 21600" draw:type="rectangle"
|
||||
draw:enhanced-path="M 0 0 L 21600 0 21600 21600 0 21600 0 0 Z N"/>
|
||||
</draw:custom-shape>
|
||||
|
||||
For the drawing units see http://stackoverflow.com/questions/15335926/svg-viewbox-attribute
|
||||
}
|
||||
procedure TvODGVectorialReader.ReadEnhancedGeometryNodeToTPath(ANode: TDOMNode;
|
||||
AData: TvVectorialPage; ADest: TPath; ADeltaX, ADeltaY: Double);
|
||||
AData: TvVectorialPage; ADest: TPath; ADeltaX, ADeltaY: Double; var AInfo: TCustomShapeInfo);
|
||||
var
|
||||
i: Integer;
|
||||
lNodeName, lNodeValue: string;
|
||||
l10Strings: T10Strings;
|
||||
begin
|
||||
// First of all we need the viewBox, or else we can't map the coordinates
|
||||
for i := 0 to ANode.Attributes.Length - 1 do
|
||||
begin
|
||||
lNodeName := ANode.Attributes.Item[i].NodeName;
|
||||
lNodeValue := ANode.Attributes.Item[i].NodeValue;
|
||||
if lNodeName = 'draw:viewBox' then
|
||||
begin
|
||||
// From OpenDocument 1.1 specs page 300
|
||||
// The syntax for using this attribute is the same as the [SVG] syntax.
|
||||
// The value of the attribute are four numbers separated by white spaces,
|
||||
// which define the left, top, right, and bottom dimensions of the user
|
||||
// coordinate system.
|
||||
l10Strings := SeparateString(lNodeValue, ' ');
|
||||
AInfo.ViewBox_Left := StringWithUnitToFloat(l10Strings[0]);
|
||||
AInfo.ViewBox_Top := StringWithUnitToFloat(l10Strings[1]);
|
||||
AInfo.ViewBox_Width := StringWithUnitToFloat(l10Strings[2]) - AInfo.ViewBox_Left;
|
||||
AInfo.ViewBox_Height := StringWithUnitToFloat(l10Strings[3]) - AInfo.ViewBox_Top;
|
||||
end;
|
||||
end;
|
||||
|
||||
// read the attributes
|
||||
for i := 0 to ANode.Attributes.Length - 1 do
|
||||
begin
|
||||
@ -684,13 +718,13 @@ begin
|
||||
lNodeValue := ANode.Attributes.Item[i].NodeValue;
|
||||
if lNodeName = 'draw:enhanced-path' then
|
||||
begin
|
||||
ConvertPathStringToTPath(lNodeValue, AData, ADest, ADeltaX, ADeltaY);
|
||||
ConvertPathStringToTPath(lNodeValue, AData, ADest, ADeltaX, ADeltaY, AInfo);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TvODGVectorialReader.ConvertPathStringToTPath(AStr: string;
|
||||
AData: TvVectorialPage; ADest: TPath; ADeltaX, ADeltaY: Double);
|
||||
AData: TvVectorialPage; ADest: TPath; ADeltaX, ADeltaY: Double; AInfo: TCustomShapeInfo);
|
||||
var
|
||||
x1, y1, x2, y2, lCurX, lCurY: double;
|
||||
t1, t2, lSrcX, lSrcY, lDestX, lDestY: Double;
|
||||
@ -784,7 +818,10 @@ begin
|
||||
t2 := CurToken.Value;
|
||||
t2 := t2 / Pi;
|
||||
|
||||
ConvertViewBoxCoordinatesToODGCoordinates(AInfo, x1, y1, x1, y1);
|
||||
ConvertODGCoordinatesToFPVCoordinates(AData, x1, y1, x1, y1);
|
||||
|
||||
ConvertViewBoxDeltaToODGDelta(AInfo, x2, y2, x2, y2);
|
||||
ConvertODGDeltaToFPVDelta(AData, x2, y2, x2, y2);
|
||||
|
||||
// Parametrized Ellipse equation
|
||||
@ -846,6 +883,7 @@ var
|
||||
lGroup: TvEntityWithSubEntities;
|
||||
lPath: TPath;
|
||||
lText: TvText;
|
||||
lInfo: TCustomShapeInfo;
|
||||
begin
|
||||
x1 := 0.0;
|
||||
y1 := 0.0;
|
||||
@ -905,7 +943,9 @@ begin
|
||||
end;
|
||||
'draw:enhanced-geometry':
|
||||
begin
|
||||
ReadEnhancedGeometryNodeToTPath(lCurNode, AData, lPath, x1, y1);
|
||||
lInfo.Width := lWidth;
|
||||
lInfo.Height := lHeight;
|
||||
ReadEnhancedGeometryNodeToTPath(lCurNode, AData, lPath, x1, y1, lInfo);
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -1631,6 +1671,32 @@ begin
|
||||
ADestY := - ASrcY * FLOAT_MILIMETERS_PER_PIXEL;
|
||||
end;
|
||||
|
||||
{
|
||||
For the drawing units see http://stackoverflow.com/questions/15335926/svg-viewbox-attribute
|
||||
|
||||
We should use these formulas to obtain the X, Y position from something in the drawing:
|
||||
|
||||
Xreal = Xenhanced-path * (draw:custom-shape_svg:width / svg:viewBox_Width) + svg:viewBox_Xo;
|
||||
And the same for Y
|
||||
|
||||
For sizes just use without Xo
|
||||
}
|
||||
procedure TvODGVectorialReader.ConvertViewBoxCoordinatesToODGCoordinates(
|
||||
const AInfo: TCustomShapeInfo; const ASrcX, ASrcY: Double; var ADestX,
|
||||
ADestY: Double);
|
||||
begin
|
||||
ADestX := ASrcX * (AInfo.Width / AInfo.ViewBox_Width) + AInfo.ViewBox_Left;
|
||||
ADestY := ASrcY * (AInfo.Height / AInfo.ViewBox_Height) + AInfo.ViewBox_Top;
|
||||
end;
|
||||
|
||||
procedure TvODGVectorialReader.ConvertViewBoxDeltaToODGDelta(
|
||||
const AInfo: TCustomShapeInfo; const ASrcX, ASrcY: Double; var ADestX,
|
||||
ADestY: Double);
|
||||
begin
|
||||
ADestX := ASrcX * (AInfo.Width / AInfo.ViewBox_Width);
|
||||
ADestY := ASrcY * (AInfo.Height / AInfo.ViewBox_Height);
|
||||
end;
|
||||
|
||||
constructor TvODGVectorialReader.Create;
|
||||
begin
|
||||
inherited Create;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user