mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-18 02:59:17 +02:00
fpvectorial: Fixes setting the font info for formulas and improves SVG layer and text reading
git-svn-id: trunk@39727 -
This commit is contained in:
parent
ba73becf3e
commit
865a07f674
@ -110,6 +110,10 @@ type
|
|||||||
Zero is the normal, horizontal, orientation, directed to the right.
|
Zero is the normal, horizontal, orientation, directed to the right.
|
||||||
}
|
}
|
||||||
Orientation: Double;
|
Orientation: Double;
|
||||||
|
Bold: boolean;
|
||||||
|
Italic: boolean;
|
||||||
|
Underline: boolean;
|
||||||
|
StrikeTrough: boolean;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ Coordinates and polyline segments }
|
{ Coordinates and polyline segments }
|
||||||
@ -275,6 +279,17 @@ type
|
|||||||
ADestY: Integer = 0; AMulX: Double = 1.0; AMulY: Double = 1.0); override;
|
ADestY: Integer = 0; AMulX: Double = 1.0; AMulY: Double = 1.0); override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TvEntityWithPenBrushAndFont }
|
||||||
|
|
||||||
|
TvEntityWithPenBrushAndFont = class(TvEntityWithPenAndBrush)
|
||||||
|
public
|
||||||
|
Font: TvFont;
|
||||||
|
constructor Create; override;
|
||||||
|
procedure ApplyFontToCanvas(ADest: TFPCustomCanvas; ARenderInfo: TvRenderInfo; AMulX: Double = 1.0);
|
||||||
|
procedure Render(ADest: TFPCustomCanvas; ARenderInfo: TvRenderInfo; ADestX: Integer = 0;
|
||||||
|
ADestY: Integer = 0; AMulX: Double = 1.0; AMulY: Double = 1.0); override;
|
||||||
|
end;
|
||||||
|
|
||||||
TvClipMode = (vcmNonzeroWindingRule, vcmEvenOddRule);
|
TvClipMode = (vcmNonzeroWindingRule, vcmEvenOddRule);
|
||||||
|
|
||||||
TPath = class(TvEntityWithPenAndBrush)
|
TPath = class(TvEntityWithPenAndBrush)
|
||||||
@ -319,10 +334,9 @@ type
|
|||||||
|
|
||||||
{ TvText }
|
{ TvText }
|
||||||
|
|
||||||
TvText = class(TvEntityWithPenAndBrush)
|
TvText = class(TvEntityWithPenBrushAndFont)
|
||||||
public
|
public
|
||||||
Value: TStringList;
|
Value: TStringList;
|
||||||
Font: TvFont;
|
|
||||||
constructor Create; override;
|
constructor Create; override;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
function TryToSelect(APos: TPoint; var ASubpart: Cardinal): TvFindEntityResult; override;
|
function TryToSelect(APos: TPoint; var ASubpart: Cardinal): TvFindEntityResult; override;
|
||||||
@ -528,7 +542,7 @@ type
|
|||||||
|
|
||||||
{ TvFormula }
|
{ TvFormula }
|
||||||
|
|
||||||
TvFormula = class(TvEntityWithPenAndBrush)
|
TvFormula = class(TvEntityWithPenBrushAndFont)
|
||||||
private
|
private
|
||||||
FCurIndex: Integer;
|
FCurIndex: Integer;
|
||||||
SpacingBetweenElementsX: Integer;
|
SpacingBetweenElementsX: Integer;
|
||||||
@ -1123,6 +1137,43 @@ begin
|
|||||||
ApplyBrushToCanvas(ADest);
|
ApplyBrushToCanvas(ADest);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
{ TvEntityWithPenBrushAndFont }
|
||||||
|
|
||||||
|
constructor TvEntityWithPenBrushAndFont.Create;
|
||||||
|
begin
|
||||||
|
inherited Create;
|
||||||
|
Font.Color := colBlack;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TvEntityWithPenBrushAndFont.ApplyFontToCanvas(ADest: TFPCustomCanvas; ARenderInfo: TvRenderInfo; AMulX: Double = 1.0);
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
|
{$ifdef USE_LCL_CANVAS}
|
||||||
|
ALCLDest: TCanvas absolute ADest;
|
||||||
|
{$endif}
|
||||||
|
//
|
||||||
|
LowerDim: T3DPoint;
|
||||||
|
begin
|
||||||
|
ADest.Font.Size := Round(AmulX * Font.Size);
|
||||||
|
ADest.Font.Bold := Font.Bold;
|
||||||
|
ADest.Font.Italic := Font.Italic;
|
||||||
|
ADest.Font.Underline := Font.Underline;
|
||||||
|
ADest.Font.StrikeTrough := Font.StrikeTrough;
|
||||||
|
{$ifdef USE_LCL_CANVAS}
|
||||||
|
ALCLDest.Font.Orientation := Round(Font.Orientation * 16);
|
||||||
|
{$endif}
|
||||||
|
ADest.Font.FPColor := AdjustColorToBackground(Font.Color, ARenderInfo);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TvEntityWithPenBrushAndFont.Render(ADest: TFPCustomCanvas;
|
||||||
|
ARenderInfo: TvRenderInfo; ADestX: Integer; ADestY: Integer; AMulX: Double;
|
||||||
|
AMulY: Double);
|
||||||
|
begin
|
||||||
|
inherited Render(ADest, ARenderInfo, ADestX, ADestY, AMulX, AMulY);
|
||||||
|
ApplyFontToCanvas(ADest, ARenderInfo, AMulX);
|
||||||
|
end;
|
||||||
|
|
||||||
{ TPath }
|
{ TPath }
|
||||||
|
|
||||||
constructor TPath.Create;
|
constructor TPath.Create;
|
||||||
@ -1584,6 +1635,7 @@ constructor TvText.Create;
|
|||||||
begin
|
begin
|
||||||
inherited Create;
|
inherited Create;
|
||||||
Value := TStringList.Create;
|
Value := TStringList.Create;
|
||||||
|
Font.Color := colBlack;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
destructor TvText.Destroy;
|
destructor TvText.Destroy;
|
||||||
@ -1618,21 +1670,13 @@ procedure TvText.Render(ADest: TFPCustomCanvas; ARenderInfo: TvRenderInfo; ADest
|
|||||||
|
|
||||||
var
|
var
|
||||||
i: Integer;
|
i: Integer;
|
||||||
{$ifdef USE_LCL_CANVAS}
|
|
||||||
ALCLDest: TCanvas absolute ADest;
|
|
||||||
{$endif}
|
|
||||||
//
|
//
|
||||||
LowerDim: T3DPoint;
|
LowerDim: T3DPoint;
|
||||||
begin
|
begin
|
||||||
inherited Render(ADest, ARenderInfo, ADestX, ADestY, AMulX, AMulY);
|
inherited Render(ADest, ARenderInfo, ADestX, ADestY, AMulX, AMulY);
|
||||||
|
|
||||||
ADest.Font.Size := Round(AmulX * Font.Size);
|
// Don't draw anything if we have alpha=zero
|
||||||
{ ADest.Pen.Style := psSolid;
|
if Font.Color.Alpha = 0 then Exit;
|
||||||
ADest.Pen.FPColor := colBlack;
|
|
||||||
ADest.Brush.Style := bsClear;}
|
|
||||||
{$ifdef USE_LCL_CANVAS}
|
|
||||||
ALCLDest.Font.Orientation := Round(Font.Orientation * 16);
|
|
||||||
{$endif}
|
|
||||||
|
|
||||||
// TvText supports multiple lines
|
// TvText supports multiple lines
|
||||||
for i := 0 to Value.Count - 1 do
|
for i := 0 to Value.Count - 1 do
|
||||||
@ -2684,6 +2728,8 @@ procedure TvFormula.Render(ADest: TFPCustomCanvas; ARenderInfo: TvRenderInfo; AD
|
|||||||
var
|
var
|
||||||
lElement: TvFormulaElement;
|
lElement: TvFormulaElement;
|
||||||
begin
|
begin
|
||||||
|
inherited Render(ADest, ARenderInfo, ADestX, ADestY, AMulX, AMulY);
|
||||||
|
|
||||||
// First position all elements
|
// First position all elements
|
||||||
PositionSubparts(ADest, Left, Top);
|
PositionSubparts(ADest, Left, Top);
|
||||||
|
|
||||||
@ -3321,6 +3367,7 @@ end;
|
|||||||
function TvVectorialPage.AddLayer(AName: string): TvLayer;
|
function TvVectorialPage.AddLayer(AName: string): TvLayer;
|
||||||
begin
|
begin
|
||||||
Result := TvLayer.Create;
|
Result := TvLayer.Create;
|
||||||
|
Result.Name := AName;
|
||||||
AddEntity(Result);
|
AddEntity(Result);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -70,6 +70,7 @@ type
|
|||||||
procedure ReadEntityFromNode(ANode: TDOMNode; AData: TvVectorialPage; ADoc: TvVectorialDocument);
|
procedure ReadEntityFromNode(ANode: TDOMNode; AData: TvVectorialPage; ADoc: TvVectorialDocument);
|
||||||
procedure ReadCircleFromNode(ANode: TDOMNode; AData: TvVectorialPage; ADoc: TvVectorialDocument);
|
procedure ReadCircleFromNode(ANode: TDOMNode; AData: TvVectorialPage; ADoc: TvVectorialDocument);
|
||||||
procedure ReadEllipseFromNode(ANode: TDOMNode; AData: TvVectorialPage; ADoc: TvVectorialDocument);
|
procedure ReadEllipseFromNode(ANode: TDOMNode; AData: TvVectorialPage; ADoc: TvVectorialDocument);
|
||||||
|
procedure ReadLayerFromNode(ANode: TDOMNode; AData: TvVectorialPage; ADoc: TvVectorialDocument);
|
||||||
procedure ReadLineFromNode(ANode: TDOMNode; AData: TvVectorialPage; ADoc: TvVectorialDocument);
|
procedure ReadLineFromNode(ANode: TDOMNode; AData: TvVectorialPage; ADoc: TvVectorialDocument);
|
||||||
procedure ReadPathFromNode(ANode: TDOMNode; AData: TvVectorialPage; ADoc: TvVectorialDocument);
|
procedure ReadPathFromNode(ANode: TDOMNode; AData: TvVectorialPage; ADoc: TvVectorialDocument);
|
||||||
procedure ReadPathFromString(AStr: string; AData: TvVectorialPage; ADoc: TvVectorialDocument);
|
procedure ReadPathFromString(AStr: string; AData: TvVectorialPage; ADoc: TvVectorialDocument);
|
||||||
@ -700,7 +701,9 @@ begin
|
|||||||
|
|
||||||
if AValue = 'none' then ADestEntity.Brush.Style := fpcanvas.bsClear
|
if AValue = 'none' then ADestEntity.Brush.Style := fpcanvas.bsClear
|
||||||
else ADestEntity.Brush.Color := ReadSVGColor(AValue)
|
else ADestEntity.Brush.Color := ReadSVGColor(AValue)
|
||||||
end;
|
end
|
||||||
|
else if AKey = 'fill-opacity' then
|
||||||
|
ADestEntity.Brush.Color.Alpha := StrToInt(AValue)*$101;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TvSVGVectorialReader.ReadSVGFontStyleWithKeyAndValue(AKey,
|
procedure TvSVGVectorialReader.ReadSVGFontStyleWithKeyAndValue(AKey,
|
||||||
@ -709,23 +712,33 @@ begin
|
|||||||
// SVG text uses "fill" to indicate the pen color of the text, very unintuitive as
|
// SVG text uses "fill" to indicate the pen color of the text, very unintuitive as
|
||||||
// "fill" is usually for brush in other elements
|
// "fill" is usually for brush in other elements
|
||||||
if AKey = 'fill' then
|
if AKey = 'fill' then
|
||||||
|
ADestEntity.Font.Color := ReadSVGColor(AValue)
|
||||||
|
else if AKey = 'fill-opacity' then
|
||||||
|
ADestEntity.Font.Color.Alpha := StrToInt(AValue)*$101
|
||||||
|
else if AKey = 'font-size' then
|
||||||
|
ADestEntity.Font.Size := StrToInt(AValue)
|
||||||
|
else if AKey = 'font-family' then
|
||||||
|
ADestEntity.Font.Name := AValue
|
||||||
|
else if AKey = 'font-weight' then
|
||||||
begin
|
begin
|
||||||
ADestEntity.Font.Color := ReadSVGColor(AValue);
|
case LowerCase(AValue) of
|
||||||
|
'bold': ADestEntity.Font.Bold := True;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TvSVGVectorialReader.IsAttributeFromStyle(AStr: string): Boolean;
|
function TvSVGVectorialReader.IsAttributeFromStyle(AStr: string): Boolean;
|
||||||
begin
|
begin
|
||||||
Result := (AStr = 'stroke') or (AStr = 'stroke-width') or
|
Result := (AStr = 'stroke') or (AStr = 'stroke-width') or
|
||||||
(AStr = 'fill');
|
(AStr = 'fill') or (AStr = 'fill-opacity') or
|
||||||
|
(AStr = 'font-size') or (AStr = 'fill-family') or
|
||||||
|
(AStr = 'font-weight');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TvSVGVectorialReader.ReadEntityFromNode(ANode: TDOMNode;
|
procedure TvSVGVectorialReader.ReadEntityFromNode(ANode: TDOMNode;
|
||||||
AData: TvVectorialPage; ADoc: TvVectorialDocument);
|
AData: TvVectorialPage; ADoc: TvVectorialDocument);
|
||||||
var
|
var
|
||||||
lEntityName, lLayerName: DOMString;
|
lEntityName: DOMString;
|
||||||
lCurNode, lLayerNameNode: TDOMNode;
|
|
||||||
lLayer: TvLayer;
|
|
||||||
begin
|
begin
|
||||||
lEntityName := LowerCase(ANode.NodeName);
|
lEntityName := LowerCase(ANode.NodeName);
|
||||||
case lEntityName of
|
case lEntityName of
|
||||||
@ -736,24 +749,7 @@ begin
|
|||||||
'polygon', 'polyline': ReadPolyFromNode(ANode, AData, ADoc);
|
'polygon', 'polyline': ReadPolyFromNode(ANode, AData, ADoc);
|
||||||
'rect': ReadRectFromNode(ANode, AData, ADoc);
|
'rect': ReadRectFromNode(ANode, AData, ADoc);
|
||||||
'text': ReadTextFromNode(ANode, AData, ADoc);
|
'text': ReadTextFromNode(ANode, AData, ADoc);
|
||||||
// Layers
|
'g': ReadLayerFromNode(ANode, AData, ADoc);
|
||||||
'g':
|
|
||||||
begin
|
|
||||||
// if we are already inside a layer, something may be wrong...
|
|
||||||
//if ALayer <> nil then raise Exception.Create('[TvSVGVectorialReader.ReadEntityFromNode] A layer inside a layer was found!');
|
|
||||||
|
|
||||||
lLayerNameNode := ANode.Attributes.GetNamedItem('id');
|
|
||||||
lLayerName := '';
|
|
||||||
if lLayerNameNode <> nil then lLayerName := lLayerNameNode.NodeValue;
|
|
||||||
lLayer := AData.AddLayerAndSetAsCurrent(lLayerName);
|
|
||||||
|
|
||||||
lCurNode := ANode.FirstChild;
|
|
||||||
while Assigned(lCurNode) do
|
|
||||||
begin
|
|
||||||
ReadEntityFromNode(lCurNode, AData, ADoc);
|
|
||||||
lCurNode := lCurNode.NextSibling;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -854,6 +850,32 @@ begin
|
|||||||
AData.AddEntity(lEllipse);
|
AData.AddEntity(lEllipse);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TvSVGVectorialReader.ReadLayerFromNode(ANode: TDOMNode;
|
||||||
|
AData: TvVectorialPage; ADoc: TvVectorialDocument);
|
||||||
|
var
|
||||||
|
lNodeName: DOMString;
|
||||||
|
lLayerName: string = '';
|
||||||
|
lCurNode, lLayerNameNode: TDOMNode;
|
||||||
|
lLayer: TvLayer;
|
||||||
|
i: Integer;
|
||||||
|
begin
|
||||||
|
for i := 0 to ANode.Attributes.Length - 1 do
|
||||||
|
begin
|
||||||
|
lNodeName := ANode.Attributes.Item[i].NodeName;
|
||||||
|
if lNodeName = 'id' then
|
||||||
|
lLayerName := UTF16ToUTF8(ANode.Attributes.Item[i].NodeValue);
|
||||||
|
end;
|
||||||
|
|
||||||
|
lLayer := AData.AddLayerAndSetAsCurrent(lLayerName);
|
||||||
|
|
||||||
|
lCurNode := ANode.FirstChild;
|
||||||
|
while Assigned(lCurNode) do
|
||||||
|
begin
|
||||||
|
ReadEntityFromNode(lCurNode, AData, ADoc);
|
||||||
|
lCurNode := lCurNode.NextSibling;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TvSVGVectorialReader.ReadLineFromNode(ANode: TDOMNode;
|
procedure TvSVGVectorialReader.ReadLineFromNode(ANode: TDOMNode;
|
||||||
AData: TvVectorialPage; ADoc: TvVectorialDocument);
|
AData: TvVectorialPage; ADoc: TvVectorialDocument);
|
||||||
var
|
var
|
||||||
|
Loading…
Reference in New Issue
Block a user