mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-17 04:29:28 +02:00
Merged revision(s) 50768 #0f4cc7840e, 50807-50810 #478a6d00a4-#478a6d00a4, 50818-50819 #5fe2efae86-#5fe2efae86, 50875 #506bdbde54 from trunk:
fpvectorial: Fix text positioning issue when reading svg files. ........ fpvectorial: Fix calculation of bounding rectangle of all entities on a page ........ fpvectorial: Fix memory leak of svg tokenizer. Add ReadDefsFromNode to TvSVGVectorialReader.ReadEntityFromNode. Prepare reading of line styles for svg. ........ fpvectorial: Fix memory leak of TvEntityWithSubEntities due to not releasing items in FElements list. ........ fpvectorial: Fix bounding box of circle. Fix page bounding box in case of several top-level entities. ........ fpvectorial: Add parameter to Render method for calculation of bounding box without drawing. Fix svgreader crashing due to incorrect decimal separator in "stroke-opacity". ........ fpvectorial: Fix runtime error with fpc trunk due to duplicate application of ExtractFileExt returning no extension any more. ........ fpvectorial: svg reader detects pen styles & patterns now. Fix rendering of lines with the specified pen styles & patterns. ........ git-svn-id: branches/fixes_1_6@50877 -
This commit is contained in:
parent
0ea790b8d3
commit
0f4ab685b0
@ -117,6 +117,7 @@ type
|
|||||||
Color: TFPColor;
|
Color: TFPColor;
|
||||||
Style: TFPPenStyle;
|
Style: TFPPenStyle;
|
||||||
Width: Integer;
|
Width: Integer;
|
||||||
|
Pattern: array of LongWord;
|
||||||
end;
|
end;
|
||||||
PvPen = ^TvPen;
|
PvPen = ^TvPen;
|
||||||
|
|
||||||
@ -642,6 +643,7 @@ type
|
|||||||
TvCircle = class(TvEntityWithPenAndBrush)
|
TvCircle = class(TvEntityWithPenAndBrush)
|
||||||
public
|
public
|
||||||
Radius: Double;
|
Radius: Double;
|
||||||
|
procedure CalculateBoundingBox(ADest: TFPCustomCanvas; var ALeft, ATop, ARight, ABottom: Double); override;
|
||||||
procedure Render(ADest: TFPCustomCanvas; var ARenderInfo: TvRenderInfo; ADestX: Integer = 0;
|
procedure Render(ADest: TFPCustomCanvas; var ARenderInfo: TvRenderInfo; ADestX: Integer = 0;
|
||||||
ADestY: Integer = 0; AMulX: Double = 1.0; AMulY: Double = 1.0; ADoDraw: Boolean = True); override;
|
ADestY: Integer = 0; AMulX: Double = 1.0; AMulY: Double = 1.0; ADoDraw: Boolean = True); override;
|
||||||
end;
|
end;
|
||||||
@ -1373,6 +1375,7 @@ type
|
|||||||
MinX, MinY, MinZ, MaxX, MaxY, MaxZ: Double;
|
MinX, MinY, MinZ, MaxX, MaxY, MaxZ: Double;
|
||||||
// Other basic document information
|
// Other basic document information
|
||||||
BackgroundColor: TFPColor;
|
BackgroundColor: TFPColor;
|
||||||
|
AdjustPenColorToBackground: Boolean;
|
||||||
RenderInfo: TvRenderInfo; // Prepared by the reader with info on how to draw the page
|
RenderInfo: TvRenderInfo; // Prepared by the reader with info on how to draw the page
|
||||||
{ Base methods }
|
{ Base methods }
|
||||||
constructor Create(AOwner: TvVectorialDocument); virtual;
|
constructor Create(AOwner: TvVectorialDocument); virtual;
|
||||||
@ -1398,7 +1401,8 @@ type
|
|||||||
procedure RenderPageBorder(ADest: TFPCustomCanvas;
|
procedure RenderPageBorder(ADest: TFPCustomCanvas;
|
||||||
ADestX: Integer = 0; ADestY: Integer = 0; AMulX: Double = 1.0; AMulY: Double = 1.0); virtual; abstract;
|
ADestX: Integer = 0; ADestY: Integer = 0; AMulX: Double = 1.0; AMulY: Double = 1.0); virtual; abstract;
|
||||||
procedure Render(ADest: TFPCustomCanvas;
|
procedure Render(ADest: TFPCustomCanvas;
|
||||||
ADestX: Integer = 0; ADestY: Integer = 0; AMulX: Double = 1.0; AMulY: Double = 1.0); virtual; abstract;
|
ADestX: Integer = 0; ADestY: Integer = 0; AMulX: Double = 1.0; AMulY: Double = 1.0;
|
||||||
|
ADoDraw: Boolean = true); virtual; abstract;
|
||||||
procedure AutoFit(ADest: TFPCustomCanvas; AWidth, AHeight: Integer; out ADeltaX, ADeltaY: Integer; out AZoom: Double); virtual; abstract;
|
procedure AutoFit(ADest: TFPCustomCanvas; AWidth, AHeight: Integer; out ADeltaX, ADeltaY: Integer; out AZoom: Double); virtual; abstract;
|
||||||
{ Debug methods }
|
{ Debug methods }
|
||||||
procedure GenerateDebugTree(ADestRoutine: TvDebugAddItemProc; APageItem: Pointer); virtual; abstract;
|
procedure GenerateDebugTree(ADestRoutine: TvDebugAddItemProc; APageItem: Pointer); virtual; abstract;
|
||||||
@ -1479,8 +1483,8 @@ type
|
|||||||
procedure DrawBackground(ADest: TFPCustomCanvas); override;
|
procedure DrawBackground(ADest: TFPCustomCanvas); override;
|
||||||
procedure RenderPageBorder(ADest: TFPCustomCanvas;
|
procedure RenderPageBorder(ADest: TFPCustomCanvas;
|
||||||
ADestX: Integer = 0; ADestY: Integer = 0; AMulX: Double = 1.0; AMulY: Double = 1.0); override;
|
ADestX: Integer = 0; ADestY: Integer = 0; AMulX: Double = 1.0; AMulY: Double = 1.0); override;
|
||||||
procedure Render(ADest: TFPCustomCanvas;
|
procedure Render(ADest: TFPCustomCanvas; ADestX: Integer = 0; ADestY: Integer = 0;
|
||||||
ADestX: Integer = 0; ADestY: Integer = 0; AMulX: Double = 1.0; AMulY: Double = 1.0); override;
|
AMulX: Double = 1.0; AMulY: Double = 1.0; ADoDraw: Boolean = true); override;
|
||||||
procedure AutoFit(ADest: TFPCustomCanvas; AWidth, AHeight: Integer; out ADeltaX, ADeltaY: Integer; out AZoom: Double); override;
|
procedure AutoFit(ADest: TFPCustomCanvas; AWidth, AHeight: Integer; out ADeltaX, ADeltaY: Integer; out AZoom: Double); override;
|
||||||
{ Debug methods }
|
{ Debug methods }
|
||||||
procedure GenerateDebugTree(ADestRoutine: TvDebugAddItemProc; APageItem: Pointer); override;
|
procedure GenerateDebugTree(ADestRoutine: TvDebugAddItemProc; APageItem: Pointer); override;
|
||||||
@ -1523,8 +1527,8 @@ type
|
|||||||
procedure DrawBackground(ADest: TFPCustomCanvas); override;
|
procedure DrawBackground(ADest: TFPCustomCanvas); override;
|
||||||
procedure RenderPageBorder(ADest: TFPCustomCanvas;
|
procedure RenderPageBorder(ADest: TFPCustomCanvas;
|
||||||
ADestX: Integer = 0; ADestY: Integer = 0; AMulX: Double = 1.0; AMulY: Double = 1.0); override;
|
ADestX: Integer = 0; ADestY: Integer = 0; AMulX: Double = 1.0; AMulY: Double = 1.0); override;
|
||||||
procedure Render(ADest: TFPCustomCanvas;
|
procedure Render(ADest: TFPCustomCanvas; ADestX: Integer = 0; ADestY: Integer = 0;
|
||||||
ADestX: Integer = 0; ADestY: Integer = 0; AMulX: Double = 1.0; AMulY: Double = 1.0); override;
|
AMulX: Double = 1.0; AMulY: Double = 1.0; ADoDraw: Boolean = true); override;
|
||||||
procedure AutoFit(ADest: TFPCustomCanvas; AWidth, AHeight: Integer; out ADeltaX, ADeltaY: Integer; out AZoom: Double); override;
|
procedure AutoFit(ADest: TFPCustomCanvas; AWidth, AHeight: Integer; out ADeltaX, ADeltaY: Integer; out AZoom: Double); override;
|
||||||
{ Debug methods }
|
{ Debug methods }
|
||||||
procedure GenerateDebugTree(ADestRoutine: TvDebugAddItemProc; APageItem: Pointer); override;
|
procedure GenerateDebugTree(ADestRoutine: TvDebugAddItemProc; APageItem: Pointer); override;
|
||||||
@ -3168,7 +3172,7 @@ begin
|
|||||||
ARenderInfo.EntityCanvasMinXY := Point(INVALID_RENDERINFO_CANVAS_XY, INVALID_RENDERINFO_CANVAS_XY);
|
ARenderInfo.EntityCanvasMinXY := Point(INVALID_RENDERINFO_CANVAS_XY, INVALID_RENDERINFO_CANVAS_XY);
|
||||||
ARenderInfo.EntityCanvasMaxXY := Point(INVALID_RENDERINFO_CANVAS_XY, INVALID_RENDERINFO_CANVAS_XY);
|
ARenderInfo.EntityCanvasMaxXY := Point(INVALID_RENDERINFO_CANVAS_XY, INVALID_RENDERINFO_CANVAS_XY);
|
||||||
//ARenderInfo.BackgroundColor := colBlack; Don't change this because otherwise we lose the value set by the page
|
//ARenderInfo.BackgroundColor := colBlack; Don't change this because otherwise we lose the value set by the page
|
||||||
ARenderInfo.AdjustPenColorToBackground := True;
|
//ARenderInfo.AdjustPenColorToBackground := True; dto.
|
||||||
ARenderInfo.Selected := False;
|
ARenderInfo.Selected := False;
|
||||||
ARenderInfo.ForceRenderBlock := False;
|
ARenderInfo.ForceRenderBlock := False;
|
||||||
end;
|
end;
|
||||||
@ -3340,8 +3344,15 @@ procedure TvEntityWithPen.ApplyPenToCanvas(ADest: TFPCustomCanvas;
|
|||||||
ARenderInfo: TvRenderInfo; APen: TvPen);
|
ARenderInfo: TvRenderInfo; APen: TvPen);
|
||||||
begin
|
begin
|
||||||
ADest.Pen.FPColor := AdjustColorToBackground(APen.Color, ARenderInfo);
|
ADest.Pen.FPColor := AdjustColorToBackground(APen.Color, ARenderInfo);
|
||||||
ADest.Pen.Width := 1;//APen.Width;
|
ADest.Pen.Width := Max(1, APen.Width); // wp: why was here "1;//APen.Width;" ???
|
||||||
ADest.Pen.Style := APen.Style;
|
ADest.Pen.Style := APen.Style;
|
||||||
|
{$ifdef USE_LCL_CANVAS}
|
||||||
|
if (APen.Style = psPattern) then
|
||||||
|
begin
|
||||||
|
TCanvas(ADest).Pen.SetPattern(APen.Pattern);
|
||||||
|
if APen.Width = 1 then TCanvas(ADest).Pen.Cosmetic := false;
|
||||||
|
end;
|
||||||
|
{$endif}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TvEntityWithPen.AssignPen(APen: TvPen);
|
procedure TvEntityWithPen.AssignPen(APen: TvPen);
|
||||||
@ -3543,7 +3554,7 @@ procedure TvEntityWithPenBrushAndFont.Render(ADest: TFPCustomCanvas;
|
|||||||
AMulY: Double; ADoDraw: Boolean);
|
AMulY: Double; ADoDraw: Boolean);
|
||||||
begin
|
begin
|
||||||
inherited Render(ADest, ARenderInfo, ADestX, ADestY, AMulX, AMulY, ADoDraw);
|
inherited Render(ADest, ARenderInfo, ADestX, ADestY, AMulX, AMulY, ADoDraw);
|
||||||
ApplyFontToCanvas(ADest, ARenderInfo, AMulX);
|
ApplyFontToCanvas(ADest, ARenderInfo, AMulX); // wp: why not AMulY ?
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TvEntityWithPenBrushAndFont.GenerateDebugTree(
|
function TvEntityWithPenBrushAndFont.GenerateDebugTree(
|
||||||
@ -3939,12 +3950,14 @@ var
|
|||||||
ACanvas: TCanvas absolute ADest;
|
ACanvas: TCanvas absolute ADest;
|
||||||
{$endif}
|
{$endif}
|
||||||
begin
|
begin
|
||||||
|
inherited Render(ADest, ARenderInfo, ADestX, ADestY, AMulX, AMulY, ADoDraw);
|
||||||
|
|
||||||
PosX := 0;
|
PosX := 0;
|
||||||
PosY := 0;
|
PosY := 0;
|
||||||
ADest.Brush.Style := bsClear;
|
ADest.Brush.Style := bsClear;
|
||||||
|
|
||||||
ADest.MoveTo(ADestX, ADestY);
|
ADest.MoveTo(ADestX, ADestY);
|
||||||
|
{
|
||||||
// Set the path Pen and Brush options
|
// Set the path Pen and Brush options
|
||||||
ADest.Pen.Style := Pen.Style;
|
ADest.Pen.Style := Pen.Style;
|
||||||
ADest.Pen.Width := Round(Pen.Width * AMulX);
|
ADest.Pen.Width := Round(Pen.Width * AMulX);
|
||||||
@ -3952,8 +3965,12 @@ begin
|
|||||||
if (Pen.Width <= 2) and (ADest.Pen.Width > 2) then ADest.Pen.Width := 2;
|
if (Pen.Width <= 2) and (ADest.Pen.Width > 2) then ADest.Pen.Width := 2;
|
||||||
if (Pen.Width <= 5) and (ADest.Pen.Width > 5) then ADest.Pen.Width := 5;
|
if (Pen.Width <= 5) and (ADest.Pen.Width > 5) then ADest.Pen.Width := 5;
|
||||||
ADest.Pen.FPColor := AdjustColorToBackground(Pen.Color, ARenderInfo);
|
ADest.Pen.FPColor := AdjustColorToBackground(Pen.Color, ARenderInfo);
|
||||||
|
{$ifdef USE_LCL_CANVAS}
|
||||||
|
if (Pen.Style = psPattern) then
|
||||||
|
ACanvas.Pen.SetPattern(Pen.Pattern);
|
||||||
|
{$endif}
|
||||||
ADest.Brush.FPColor := Brush.Color;
|
ADest.Brush.FPColor := Brush.Color;
|
||||||
|
}
|
||||||
// Prepare the Clipping Region, if any
|
// Prepare the Clipping Region, if any
|
||||||
{$ifdef USE_CANVAS_CLIP_REGION}
|
{$ifdef USE_CANVAS_CLIP_REGION}
|
||||||
if ClipPath <> nil then
|
if ClipPath <> nil then
|
||||||
@ -3972,6 +3989,7 @@ begin
|
|||||||
{$endif}
|
{$endif}
|
||||||
|
|
||||||
// useful in some paths, like stars!
|
// useful in some paths, like stars!
|
||||||
|
if ADoDraw then
|
||||||
RenderInternalPolygon(ADest, ARenderInfo, ADestX, ADestY, AMulX, AMulY);
|
RenderInternalPolygon(ADest, ARenderInfo, ADestX, ADestY, AMulX, AMulY);
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -3990,7 +4008,9 @@ begin
|
|||||||
begin
|
begin
|
||||||
CoordX := CoordToCanvasX(Cur2DSegment.X);
|
CoordX := CoordToCanvasX(Cur2DSegment.X);
|
||||||
CoordY := CoordToCanvasY(Cur2DSegment.Y);
|
CoordY := CoordToCanvasY(Cur2DSegment.Y);
|
||||||
|
if ADoDraw then
|
||||||
ADest.MoveTo(CoordX, CoordY);
|
ADest.MoveTo(CoordX, CoordY);
|
||||||
|
CalcEntityCanvasMinMaxXY(ARenderInfo, CoordX, CoordY);
|
||||||
PosX := Cur2DSegment.X;
|
PosX := Cur2DSegment.X;
|
||||||
PosY := Cur2DSegment.Y;
|
PosY := Cur2DSegment.Y;
|
||||||
{$ifdef FPVECTORIAL_TOCANVAS_DEBUG}
|
{$ifdef FPVECTORIAL_TOCANVAS_DEBUG}
|
||||||
@ -4118,20 +4138,21 @@ begin
|
|||||||
ADest.Brush.Style := Brush.Style;
|
ADest.Brush.Style := Brush.Style;
|
||||||
CalcEntityCanvasMinMaxXY_With2Points(ARenderInfo, CoordX, CoordY, CoordX4, CoordY4);
|
CalcEntityCanvasMinMaxXY_With2Points(ARenderInfo, CoordX, CoordY, CoordX4, CoordY4);
|
||||||
|
|
||||||
|
if ADoDraw then
|
||||||
|
begin
|
||||||
// Arc draws counterclockwise
|
// Arc draws counterclockwise
|
||||||
if ADoDraw and Cur2DArcSegment.ClockwiseArcFlag then
|
if Cur2DArcSegment.ClockwiseArcFlag then
|
||||||
begin
|
begin
|
||||||
ACanvas.Arc(
|
ACanvas.Arc(
|
||||||
EllipseRect.Left, EllipseRect.Top, EllipseRect.Right, EllipseRect.Bottom,
|
EllipseRect.Left, EllipseRect.Top, EllipseRect.Right, EllipseRect.Bottom,
|
||||||
CoordX4, CoordY4, CoordX, CoordY);
|
CoordX4, CoordY4, CoordX, CoordY);
|
||||||
end
|
end else
|
||||||
else if ADoDraw then
|
|
||||||
begin
|
begin
|
||||||
ACanvas.Arc(
|
ACanvas.Arc(
|
||||||
EllipseRect.Left, EllipseRect.Top, EllipseRect.Right, EllipseRect.Bottom,
|
EllipseRect.Left, EllipseRect.Top, EllipseRect.Right, EllipseRect.Bottom,
|
||||||
CoordX, CoordY, CoordX4, CoordY4);
|
CoordX, CoordY, CoordX4, CoordY4);
|
||||||
end;
|
end;
|
||||||
|
end;
|
||||||
PosX := Cur2DArcSegment.X;
|
PosX := Cur2DArcSegment.X;
|
||||||
PosY := Cur2DArcSegment.Y;
|
PosY := Cur2DArcSegment.Y;
|
||||||
|
|
||||||
@ -4346,12 +4367,14 @@ procedure TvText.Render(ADest: TFPCustomCanvas; var ARenderInfo: TvRenderInfo; A
|
|||||||
Result := Round(ADestY + AmulY * ACoord);
|
Result := Round(ADestY + AmulY * ACoord);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
const
|
||||||
|
LINE_SPACING = 0.2; // fraction of font height for line spacing
|
||||||
var
|
var
|
||||||
i: Integer;
|
i: Integer;
|
||||||
//
|
//
|
||||||
LowerDim: T3DPoint;
|
LowerDim: T3DPoint;
|
||||||
XAnchorAdjustment: Integer;
|
XAnchorAdjustment: Integer;
|
||||||
lLongestLine, lLineWidth, lFontSizePx: Integer;
|
lLongestLine, lLineWidth, lFontSizePx, lFontDescenderPx: Integer;
|
||||||
lText: string;
|
lText: string;
|
||||||
{$ifdef USE_LCL_CANVAS}
|
{$ifdef USE_LCL_CANVAS}
|
||||||
ACanvas: TCanvas absolute ADest;
|
ACanvas: TCanvas absolute ADest;
|
||||||
@ -4372,7 +4395,7 @@ begin
|
|||||||
lLongestLine := 0;
|
lLongestLine := 0;
|
||||||
for i := 0 to Value.Count - 1 do
|
for i := 0 to Value.Count - 1 do
|
||||||
begin
|
begin
|
||||||
lLineWidth := ACanvas.TextWidth(Value.Strings[i]);
|
lLineWidth := ACanvas.TextWidth(Value.Strings[i]); // contains multiplier
|
||||||
if lLineWidth > lLongestLine then
|
if lLineWidth > lLongestLine then
|
||||||
lLongestLine := lLineWidth;
|
lLongestLine := lLineWidth;
|
||||||
end;
|
end;
|
||||||
@ -4386,15 +4409,15 @@ begin
|
|||||||
// TvText supports multiple lines
|
// TvText supports multiple lines
|
||||||
for i := 0 to Value.Count - 1 do
|
for i := 0 to Value.Count - 1 do
|
||||||
begin
|
begin
|
||||||
lFontSizePx := Font.Size;
|
lFontSizePx := Font.Size; // is without multiplier!
|
||||||
if lFontSizePx = 0 then lFontSizePx := 10;
|
if lFontSizePx = 0 then lFontSizePx := 10;
|
||||||
|
|
||||||
// We need to keep the order of lines drawing correct regardless of
|
// We need to keep the order of lines drawing correct regardless of
|
||||||
// the drawing direction
|
// the drawing direction
|
||||||
if AMulY < 0 then
|
if AMulY < 0 then
|
||||||
LowerDim.Y := CoordToCanvasY(Y) + lFontSizePx * 1.2 * (Value.Count - i)
|
lowerDim.Y := CoordToCanvasY(Y) + lFontSizePx * (1 + LINE_SPACING) * (Value.Count - i) * AMulY
|
||||||
else
|
else
|
||||||
LowerDim.Y := CoordToCanvasY(Y) + lFontSizePx * 1.2 * i;
|
LowerDim.Y := CoordToCanvasY(Y) + lFontSizePx * (1 + LINE_SPACING) * i * AMulY;
|
||||||
|
|
||||||
ADest.Font.FPColor := AdjustColorToBackground(Font.Color, ARenderInfo);
|
ADest.Font.FPColor := AdjustColorToBackground(Font.Color, ARenderInfo);
|
||||||
lText := Value.Strings[i];
|
lText := Value.Strings[i];
|
||||||
@ -4540,6 +4563,15 @@ end;
|
|||||||
|
|
||||||
{ TvCircle }
|
{ TvCircle }
|
||||||
|
|
||||||
|
procedure TvCircle.CalculateBoundingBox(ADest: TFPCustomCanvas;
|
||||||
|
var ALeft, ATop, ARight, ABottom: Double);
|
||||||
|
begin
|
||||||
|
ALeft := X - Radius;
|
||||||
|
ARight := X + Radius;
|
||||||
|
ATop := Y + Radius;
|
||||||
|
ABottom := Y - Radius;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TvCircle.Render(ADest: TFPCustomCanvas; var ARenderInfo: TvRenderInfo; ADestX: Integer;
|
procedure TvCircle.Render(ADest: TFPCustomCanvas; var ARenderInfo: TvRenderInfo; ADestX: Integer;
|
||||||
ADestY: Integer; AMulX: Double; AMulY: Double; ADoDraw: Boolean);
|
ADestY: Integer; AMulX: Double; AMulY: Double; ADoDraw: Boolean);
|
||||||
|
|
||||||
@ -4553,14 +4585,18 @@ procedure TvCircle.Render(ADest: TFPCustomCanvas; var ARenderInfo: TvRenderInfo;
|
|||||||
Result := Round(ADestY + AmulY * ACoord);
|
Result := Round(ADestY + AmulY * ACoord);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
x1, y1, x2, y2: Integer;
|
||||||
begin
|
begin
|
||||||
inherited Render(ADest, ARenderInfo, ADestX, ADestY, AMulX, AMulY, ADoDraw);
|
inherited Render(ADest, ARenderInfo, ADestX, ADestY, AMulX, AMulY, ADoDraw);
|
||||||
ADest.Ellipse(
|
|
||||||
CoordToCanvasX(X - Radius),
|
x1 := CoordToCanvasX(X - Radius);
|
||||||
CoordToCanvasY(Y - Radius),
|
y1 := CoordToCanvasY(Y - Radius);
|
||||||
CoordToCanvasX(X + Radius),
|
x2 := CoordToCanvasX(X + Radius);
|
||||||
CoordToCanvasY(Y + Radius)
|
y2 := CoordToCanvasY(Y + Radius);
|
||||||
);
|
ADest.Ellipse(x1, y1, x2, y2);
|
||||||
|
|
||||||
|
CalcEntityCanvasMinMaxXY_With2Points(ARenderInfo, x1, y1, x2, y2);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TvCircularArc }
|
{ TvCircularArc }
|
||||||
@ -4691,8 +4727,8 @@ begin
|
|||||||
// First do the trivial
|
// First do the trivial
|
||||||
ALeft := X - HorzHalfAxis;
|
ALeft := X - HorzHalfAxis;
|
||||||
ARight := X + HorzHalfAxis;
|
ARight := X + HorzHalfAxis;
|
||||||
ATop := Y - VertHalfAxis;
|
ATop := Y - VertHalfAxis; // wp: shouldn't this be "+" ...
|
||||||
ABottom := Y + VertHalfAxis;
|
ABottom := Y + VertHalfAxis; // ... and this "-" ?
|
||||||
{
|
{
|
||||||
To calculate the bounding rectangle we can do this:
|
To calculate the bounding rectangle we can do this:
|
||||||
|
|
||||||
@ -4771,12 +4807,13 @@ begin
|
|||||||
// Conrollpoint of secondpart endpoint
|
// Conrollpoint of secondpart endpoint
|
||||||
PointList[6] := PointList[0]; // Endpoint of
|
PointList[6] := PointList[0]; // Endpoint of
|
||||||
// Back to the startpoint
|
// Back to the startpoint
|
||||||
|
if ADoDraw then
|
||||||
ALCLDest.PolyBezier(Pointlist[0]);
|
ALCLDest.PolyBezier(Pointlist[0]);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
{$endif}
|
{$endif}
|
||||||
begin
|
begin
|
||||||
ADest.Ellipse(x1, y1, x2, y2);
|
if ADoDraw then ADest.Ellipse(x1, y1, x2, y2);
|
||||||
end;
|
end;
|
||||||
// Apply brush gradient
|
// Apply brush gradient
|
||||||
if x1 > x2 then
|
if x1 > x2 then
|
||||||
@ -4792,6 +4829,8 @@ begin
|
|||||||
y2 := dk;
|
y2 := dk;
|
||||||
end;
|
end;
|
||||||
DrawBrushGradient(ADest, ARenderInfo, x1, y1, x2, y2, ADestX, ADestY, AMulX, AMulY);
|
DrawBrushGradient(ADest, ARenderInfo, x1, y1, x2, y2, ADestX, ADestY, AMulX, AMulY);
|
||||||
|
|
||||||
|
CalcEntityCanvasMinMaxXY_With2Points(ARenderInfo, x1, y1, x2, y2);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TvRectangle }
|
{ TvRectangle }
|
||||||
@ -4830,6 +4869,8 @@ begin
|
|||||||
y1 := CoordToCanvasY(fy1);
|
y1 := CoordToCanvasY(fy1);
|
||||||
y2 := CoordToCanvasY(fy2);
|
y2 := CoordToCanvasY(fy2);
|
||||||
|
|
||||||
|
if ADoDraw then
|
||||||
|
begin
|
||||||
{$ifdef USE_LCL_CANVAS}
|
{$ifdef USE_LCL_CANVAS}
|
||||||
if (RX = 0) and (RY = 0) then
|
if (RX = 0) and (RY = 0) then
|
||||||
ADest.Rectangle(x1, y1, x2, y2)
|
ADest.Rectangle(x1, y1, x2, y2)
|
||||||
@ -4840,6 +4881,9 @@ begin
|
|||||||
{$endif}
|
{$endif}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
CalcEntityCanvasMinMaxXY_With2Points(ARenderInfo, x1, y1, x2, y2);
|
||||||
|
end;
|
||||||
|
|
||||||
function TvRectangle.GenerateDebugTree(ADestRoutine: TvDebugAddItemProc;
|
function TvRectangle.GenerateDebugTree(ADestRoutine: TvDebugAddItemProc;
|
||||||
APageItem: Pointer): Pointer;
|
APageItem: Pointer): Pointer;
|
||||||
var
|
var
|
||||||
@ -4896,8 +4940,10 @@ begin
|
|||||||
begin
|
begin
|
||||||
lPoints[i].X := CoordToCanvasX(Points[i].X);
|
lPoints[i].X := CoordToCanvasX(Points[i].X);
|
||||||
lPoints[i].Y := CoordToCanvasY(Points[i].Y);
|
lPoints[i].Y := CoordToCanvasY(Points[i].Y);
|
||||||
|
CalcEntityCanvasMinMaxXY(ARenderInfo, lPoints[i].X, lPoints[i].Y);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
if ADoDraw then
|
||||||
ADest.Polygon(lPoints);
|
ADest.Polygon(lPoints);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -4922,6 +4968,7 @@ var
|
|||||||
{$ifdef USE_LCL_CANVAS}
|
{$ifdef USE_LCL_CANVAS}
|
||||||
ALCLDest: TCanvas absolute ADest;
|
ALCLDest: TCanvas absolute ADest;
|
||||||
{$endif}
|
{$endif}
|
||||||
|
txt: String;
|
||||||
begin
|
begin
|
||||||
ADest.Pen.FPColor := AdjustColorToBackground(colBlack, ARenderInfo);
|
ADest.Pen.FPColor := AdjustColorToBackground(colBlack, ARenderInfo);
|
||||||
ADest.Pen.Width := 1;
|
ADest.Pen.Width := 1;
|
||||||
@ -4948,12 +4995,14 @@ begin
|
|||||||
Points[0] := Point(CoordToCanvasX(DimensionLeft.X), CoordToCanvasY(DimensionLeft.Y));
|
Points[0] := Point(CoordToCanvasX(DimensionLeft.X), CoordToCanvasY(DimensionLeft.Y));
|
||||||
Points[1] := Point(Points[0].X + 7, Points[0].Y - 3);
|
Points[1] := Point(Points[0].X + 7, Points[0].Y - 3);
|
||||||
Points[2] := Point(Points[0].X + 7, Points[0].Y + 3);
|
Points[2] := Point(Points[0].X + 7, Points[0].Y + 3);
|
||||||
ADest.Polygon(Points);
|
CalcEntityCanvasMinMaxXY(ARenderInfo, Points[0].X, Points[1].Y);
|
||||||
|
if ADoDraw then ADest.Polygon(Points);
|
||||||
// Right arrow
|
// Right arrow
|
||||||
Points[0] := Point(CoordToCanvasX(DimensionRight.X), CoordToCanvasY(DimensionRight.Y));
|
Points[0] := Point(CoordToCanvasX(DimensionRight.X), CoordToCanvasY(DimensionRight.Y));
|
||||||
Points[1] := Point(Points[0].X - 7, Points[0].Y - 3);
|
Points[1] := Point(Points[0].X - 7, Points[0].Y - 3);
|
||||||
Points[2] := Point(Points[0].X - 7, Points[0].Y + 3);
|
Points[2] := Point(Points[0].X - 7, Points[0].Y + 3);
|
||||||
ADest.Polygon(Points);
|
CalcEntityCanvasMinMaxXY(ARenderInfo, Points[0].X, Points[2].Y);
|
||||||
|
if ADoDraw then ADest.Polygon(Points);
|
||||||
ADest.Brush.Style := bsClear;
|
ADest.Brush.Style := bsClear;
|
||||||
// Dimension text
|
// Dimension text
|
||||||
Points[0].X := CoordToCanvasX((DimensionLeft.X+DimensionRight.X)/2);
|
Points[0].X := CoordToCanvasX((DimensionLeft.X+DimensionRight.X)/2);
|
||||||
@ -4962,7 +5011,12 @@ begin
|
|||||||
ADest.Font.Size := 10;
|
ADest.Font.Size := 10;
|
||||||
ADest.Font.Orientation := 0;
|
ADest.Font.Orientation := 0;
|
||||||
ADest.Font.FPColor := AdjustColorToBackground(colBlack, ARenderInfo);
|
ADest.Font.FPColor := AdjustColorToBackground(colBlack, ARenderInfo);
|
||||||
ADest.TextOut(Points[0].X, Points[0].Y-Round(ADest.Font.Size*1.5), Format('%.1f', [LowerDim.X]));
|
txt := Format('%.1f', [LowerDim.X]);
|
||||||
|
if ADoDraw then
|
||||||
|
ADest.TextOut(Points[0].X, Points[0].Y-Round(ADest.Font.Size*1.5), txt);
|
||||||
|
CalcEntityCanvasMinMaxXY_With2Points(ARenderInfo,
|
||||||
|
Points[0].X, Points[0].Y - round(ADest.Font.Size*1.5),
|
||||||
|
Points[0].X + ADest.TextWidth(txt), Points[0].Y);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
@ -4983,12 +5037,14 @@ begin
|
|||||||
Points[0] := Point(CoordToCanvasX(UpperDim.X), CoordToCanvasY(UpperDim.Y));
|
Points[0] := Point(CoordToCanvasX(UpperDim.X), CoordToCanvasY(UpperDim.Y));
|
||||||
Points[1] := Point(Points[0].X + Round(AMulX), Points[0].Y - Round(AMulY*3));
|
Points[1] := Point(Points[0].X + Round(AMulX), Points[0].Y - Round(AMulY*3));
|
||||||
Points[2] := Point(Points[0].X - Round(AMulX), Points[0].Y - Round(AMulY*3));
|
Points[2] := Point(Points[0].X - Round(AMulX), Points[0].Y - Round(AMulY*3));
|
||||||
ADest.Polygon(Points);
|
if ADoDraw then ADest.Polygon(Points);
|
||||||
|
CalcEntityCanvasMinMaxXY(ARenderInfo, Points[1].X, Points[0].Y);
|
||||||
// Lower arrow
|
// Lower arrow
|
||||||
Points[0] := Point(CoordToCanvasX(LowerDim.X), CoordToCanvasY(LowerDim.Y));
|
Points[0] := Point(CoordToCanvasX(LowerDim.X), CoordToCanvasY(LowerDim.Y));
|
||||||
Points[1] := Point(Points[0].X + Round(AMulX), Points[0].Y + Round(AMulY*3));
|
Points[1] := Point(Points[0].X + Round(AMulX), Points[0].Y + Round(AMulY*3));
|
||||||
Points[2] := Point(Points[0].X - Round(AMulX), Points[0].Y + Round(AMulY*3));
|
Points[2] := Point(Points[0].X - Round(AMulX), Points[0].Y + Round(AMulY*3));
|
||||||
ADest.Polygon(Points);
|
if ADoDraw then ADest.Polygon(Points);
|
||||||
|
CalcEntityCanvasMinMaxXY(ARenderInfo, Points[2].X, Points[0].Y);
|
||||||
ADest.Brush.Style := bsClear;
|
ADest.Brush.Style := bsClear;
|
||||||
// Dimension text
|
// Dimension text
|
||||||
Points[0].X := CoordToCanvasX(DimensionLeft.X);
|
Points[0].X := CoordToCanvasX(DimensionLeft.X);
|
||||||
@ -4998,8 +5054,14 @@ begin
|
|||||||
ADest.Font.Size := 10;
|
ADest.Font.Size := 10;
|
||||||
ADest.Font.Orientation := 900;
|
ADest.Font.Orientation := 900;
|
||||||
ADest.Font.FPColor := AdjustColorToBackground(colBlack, ARenderInfo);
|
ADest.Font.FPColor := AdjustColorToBackground(colBlack, ARenderInfo);
|
||||||
ADest.TextOut(Points[0].X-Round(ADest.Font.Size*1.5), Points[0].Y, Format('%.1f', [LowerDim.Y]));
|
txt := Format('%.1f', [LowerDim.Y]);
|
||||||
|
if ADoDraw then
|
||||||
|
ADest.TextOut(Points[0].X-Round(ADest.Font.Size*1.5), Points[0].Y, txt);
|
||||||
ADest.Font.Orientation := 0;
|
ADest.Font.Orientation := 0;
|
||||||
|
CalcEntityCanvasMinMaxXY_With2Points(ARenderInfo,
|
||||||
|
Points[0].X - Round(ADest.Font.Size*1.5), Points[0].Y,
|
||||||
|
Points[0].X, Points[0].Y + ADest.TextWidth(txt)
|
||||||
|
);
|
||||||
end;
|
end;
|
||||||
SetLength(Points, 0);
|
SetLength(Points, 0);
|
||||||
|
|
||||||
@ -5074,6 +5136,8 @@ begin
|
|||||||
Points[1] := Rotate2DPoint(Points[1], Point(CoordToCanvasX(Center.X), CoordToCanvasY(Center.Y)), lAngle);
|
Points[1] := Rotate2DPoint(Points[1], Point(CoordToCanvasX(Center.X), CoordToCanvasY(Center.Y)), lAngle);
|
||||||
Points[2] := Rotate2DPoint(Points[2], Point(CoordToCanvasX(Center.X), CoordToCanvasY(Center.Y)), lAngle);
|
Points[2] := Rotate2DPoint(Points[2], Point(CoordToCanvasX(Center.X), CoordToCanvasY(Center.Y)), lAngle);
|
||||||
|
|
||||||
|
if ADoDraw then
|
||||||
|
begin
|
||||||
if not IsDiameter then
|
if not IsDiameter then
|
||||||
begin
|
begin
|
||||||
// Basic line
|
// Basic line
|
||||||
@ -5120,6 +5184,7 @@ begin
|
|||||||
ADest.Font.FPColor := AdjustColorToBackground(colBlack, ARenderInfo);
|
ADest.Font.FPColor := AdjustColorToBackground(colBlack, ARenderInfo);
|
||||||
ADest.TextOut(Points[0].X, Points[0].Y, Format('%.1f', [lRadius * 2]));
|
ADest.TextOut(Points[0].X, Points[0].Y, Format('%.1f', [lRadius * 2]));
|
||||||
end;
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
SetLength(Points, 0);
|
SetLength(Points, 0);
|
||||||
end;
|
end;
|
||||||
@ -5163,6 +5228,7 @@ var
|
|||||||
{$ifdef USE_LCL_CANVAS}
|
{$ifdef USE_LCL_CANVAS}
|
||||||
ALCLDest: TCanvas absolute ADest;
|
ALCLDest: TCanvas absolute ADest;
|
||||||
{$endif}
|
{$endif}
|
||||||
|
txt: String;
|
||||||
begin
|
begin
|
||||||
ADest.Pen.FPColor := colYellow;//AdjustColorToBackground(colBlack, ARenderInfo);
|
ADest.Pen.FPColor := colYellow;//AdjustColorToBackground(colBlack, ARenderInfo);
|
||||||
ADest.Pen.Width := 1;
|
ADest.Pen.Width := 1;
|
||||||
@ -5173,6 +5239,7 @@ begin
|
|||||||
//ADest.Line(CoordToCanvasX(BaseRight.X), CoordToCanvasY(BaseRight.Y), CoordToCanvasX(DimensionRight.X), CoordToCanvasY(DimensionRight.Y));
|
//ADest.Line(CoordToCanvasX(BaseRight.X), CoordToCanvasY(BaseRight.Y), CoordToCanvasX(DimensionRight.X), CoordToCanvasY(DimensionRight.Y));
|
||||||
|
|
||||||
// Now the arc
|
// Now the arc
|
||||||
|
if ADoDraw then
|
||||||
ALCLDest.Arc(
|
ALCLDest.Arc(
|
||||||
CoordToCanvasX(BaseLeft.X - ArcRadius), CoordToCanvasY(BaseLeft.Y - ArcRadius),
|
CoordToCanvasX(BaseLeft.X - ArcRadius), CoordToCanvasY(BaseLeft.Y - ArcRadius),
|
||||||
CoordToCanvasX(BaseLeft.X + ArcRadius), CoordToCanvasY(BaseLeft.Y + ArcRadius),
|
CoordToCanvasX(BaseLeft.X + ArcRadius), CoordToCanvasY(BaseLeft.Y + ArcRadius),
|
||||||
@ -5193,6 +5260,7 @@ begin
|
|||||||
Points[1] := Point(CoordToCanvasX(lTriangleCorner.X), CoordToCanvasY(lTriangleCorner.Y));
|
Points[1] := Point(CoordToCanvasX(lTriangleCorner.X), CoordToCanvasY(lTriangleCorner.Y));
|
||||||
lTriangleCorner := Rotate3DPointInXY(lTriangleCenter, ArcLeft, - Pi * 10 / 180);
|
lTriangleCorner := Rotate3DPointInXY(lTriangleCenter, ArcLeft, - Pi * 10 / 180);
|
||||||
Points[2] := Point(CoordToCanvasX(lTriangleCorner.X), CoordToCanvasY(lTriangleCorner.Y));
|
Points[2] := Point(CoordToCanvasX(lTriangleCorner.X), CoordToCanvasY(lTriangleCorner.Y));
|
||||||
|
if ADoDraw then
|
||||||
ADest.Polygon(Points);
|
ADest.Polygon(Points);
|
||||||
|
|
||||||
// Right Arrow
|
// Right Arrow
|
||||||
@ -5204,6 +5272,7 @@ begin
|
|||||||
lTriangleCorner := Rotate3DPointInXY(lTriangleCenter, ArcRight, - Pi * 10 / 180);
|
lTriangleCorner := Rotate3DPointInXY(lTriangleCenter, ArcRight, - Pi * 10 / 180);
|
||||||
Points[2] := Point(CoordToCanvasX(lTriangleCorner.X), CoordToCanvasY(lTriangleCorner.Y));
|
Points[2] := Point(CoordToCanvasX(lTriangleCorner.X), CoordToCanvasY(lTriangleCorner.Y));
|
||||||
ADest.Polygon(Points);
|
ADest.Polygon(Points);
|
||||||
|
if ADoDraw then
|
||||||
ADest.Brush.Style := bsClear;
|
ADest.Brush.Style := bsClear;
|
||||||
|
|
||||||
// Dimension text
|
// Dimension text
|
||||||
@ -5212,7 +5281,9 @@ begin
|
|||||||
ADest.Font.Size := 10;
|
ADest.Font.Size := 10;
|
||||||
ADest.Font.Orientation := 0;
|
ADest.Font.Orientation := 0;
|
||||||
ADest.Font.FPColor := colYellow;//AdjustColorToBackground(colBlack, ARenderInfo);
|
ADest.Font.FPColor := colYellow;//AdjustColorToBackground(colBlack, ARenderInfo);
|
||||||
ADest.TextOut(Points[0].X, Points[0].Y-Round(ADest.Font.Size*1.5), Format('%.1fº', [ArcValue]));
|
txt := Format('%.1fº', [ArcValue]);
|
||||||
|
if ADoDraw then
|
||||||
|
ADest.TextOut(Points[0].X, Points[0].Y-Round(ADest.Font.Size*1.5), txt);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TvArcDimension.CalculateExtraArcInfo;
|
procedure TvArcDimension.CalculateExtraArcInfo;
|
||||||
@ -5412,6 +5483,7 @@ begin
|
|||||||
if lFinalW < 0 then lFinalW := lFinalW * -1;
|
if lFinalW < 0 then lFinalW := lFinalW * -1;
|
||||||
lFinalH := Round(Height * AMulY);
|
lFinalH := Round(Height * AMulY);
|
||||||
if lFinalH < 0 then lFinalH := lFinalH * -1;
|
if lFinalH < 0 then lFinalH := lFinalH * -1;
|
||||||
|
if ADoDraw then
|
||||||
TCanvas(ADest).StretchDraw(Bounds(lFinalX, lFinalY, lFinalW, lFinalH), lBitmap);
|
TCanvas(ADest).StretchDraw(Bounds(lFinalX, lFinalY, lFinalW, lFinalH), lBitmap);
|
||||||
finally
|
finally
|
||||||
lImageWriter.Free;
|
lImageWriter.Free;
|
||||||
@ -5530,7 +5602,7 @@ begin
|
|||||||
lPoints[1].Y := CoordToCanvasY(lPointE.Y);
|
lPoints[1].Y := CoordToCanvasY(lPointE.Y);
|
||||||
lPoints[2].X := CoordToCanvasX(lPointF.X);
|
lPoints[2].X := CoordToCanvasX(lPointF.X);
|
||||||
lPoints[2].Y := CoordToCanvasY(lPointF.Y);
|
lPoints[2].Y := CoordToCanvasY(lPointF.Y);
|
||||||
ADest.Polygon(lPoints);
|
if ADoDraw then ADest.Polygon(lPoints);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TvFormulaElement }
|
{ TvFormulaElement }
|
||||||
@ -5703,6 +5775,7 @@ begin
|
|||||||
LeftC := CoordToCanvasX(Left);
|
LeftC := CoordToCanvasX(Left);
|
||||||
TopC := CoordToCanvasY(Top);
|
TopC := CoordToCanvasY(Top);
|
||||||
|
|
||||||
|
if ADoDraw then
|
||||||
case Kind of
|
case Kind of
|
||||||
fekVariable: ADest.TextOut(LeftC, TopC, Text);
|
fekVariable: ADest.TextOut(LeftC, TopC, Text);
|
||||||
fekEqual: ADest.TextOut(LeftC, TopC, '=');
|
fekEqual: ADest.TextOut(LeftC, TopC, '=');
|
||||||
@ -6271,7 +6344,11 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
destructor TvEntityWithSubEntities.Destroy;
|
destructor TvEntityWithSubEntities.Destroy;
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
begin
|
begin
|
||||||
|
for i:= FElements.Count-1 downto 0 do
|
||||||
|
TvEntity(FElements[i]).Free;
|
||||||
FElements.Free;
|
FElements.Free;
|
||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
end;
|
end;
|
||||||
@ -6359,8 +6436,12 @@ procedure TvEntityWithSubEntities.Render(ADest: TFPCustomCanvas; var ARenderInfo
|
|||||||
ADestX: Integer; ADestY: Integer; AMulX: Double; AMulY: Double; ADoDraw: Boolean);
|
ADestX: Integer; ADestY: Integer; AMulX: Double; AMulY: Double; ADoDraw: Boolean);
|
||||||
var
|
var
|
||||||
lEntity: TvEntity;
|
lEntity: TvEntity;
|
||||||
|
rinfo: TvRenderInfo;
|
||||||
|
isFirst: Boolean;
|
||||||
begin
|
begin
|
||||||
|
rinfo := ARenderInfo;
|
||||||
inherited Render(ADest, ARenderInfo, ADestX, ADestY, AMulX, AMulY, ADoDraw);
|
inherited Render(ADest, ARenderInfo, ADestX, ADestY, AMulX, AMulY, ADoDraw);
|
||||||
|
isFirst := true;
|
||||||
lEntity := GetFirstEntity();
|
lEntity := GetFirstEntity();
|
||||||
while lEntity <> nil do
|
while lEntity <> nil do
|
||||||
begin
|
begin
|
||||||
@ -6372,8 +6453,22 @@ begin
|
|||||||
// Render
|
// Render
|
||||||
lEntity.Render(ADest, ARenderInfo, ADestX, ADestY, AMulX, AMuly, ADoDraw);
|
lEntity.Render(ADest, ARenderInfo, ADestX, ADestY, AMulX, AMuly, ADoDraw);
|
||||||
|
|
||||||
|
if isFirst then
|
||||||
|
begin
|
||||||
|
rinfo := ARenderInfo;
|
||||||
|
isFirst := false;
|
||||||
|
end else
|
||||||
|
CalcEntityCanvasMinMaxXY_With2Points(rinfo,
|
||||||
|
ARenderInfo.EntityCanvasMinXY.X,
|
||||||
|
ARenderInfo.EntityCanvasMinXY.Y,
|
||||||
|
ARenderInfo.EntityCanvasMaxXY.X,
|
||||||
|
ARenderInfo.EntityCanvasMaxXY.Y
|
||||||
|
);
|
||||||
|
|
||||||
lEntity := GetNextEntity();
|
lEntity := GetNextEntity();
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
ARenderInfo := rinfo;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TvEntityWithSubEntities.GenerateDebugTree(
|
function TvEntityWithSubEntities.GenerateDebugTree(
|
||||||
@ -6694,7 +6789,7 @@ begin
|
|||||||
if Style <> nil then
|
if Style <> nil then
|
||||||
Style.ApplyIntoEntity(lText);
|
Style.ApplyIntoEntity(lText);
|
||||||
|
|
||||||
lText.Render(ADest, lEntityRenderInfo, CurX, ADestY + lHeight_px, AMulX, AMulY, ADoDraw);
|
lText.Render(ADest, lEntityRenderInfo, CurX, ADestY, AMulX, AMulY, ADoDraw);
|
||||||
lText.CalculateBoundingBox(ADest, lLeft, lTop, lRight, lBottom);
|
lText.CalculateBoundingBox(ADest, lLeft, lTop, lRight, lBottom);
|
||||||
lCurWidth := lCurWidth + Abs(lRight - lLeft);
|
lCurWidth := lCurWidth + Abs(lRight - lLeft);
|
||||||
lFirstText := False;
|
lFirstText := False;
|
||||||
@ -7043,6 +7138,7 @@ constructor TvPage.Create(AOwner: TvVectorialDocument);
|
|||||||
begin
|
begin
|
||||||
inherited Create;
|
inherited Create;
|
||||||
FOwner := AOwner;
|
FOwner := AOwner;
|
||||||
|
AdjustPenColorToBackground := true;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
destructor TvPage.Destroy;
|
destructor TvPage.Destroy;
|
||||||
@ -7770,12 +7866,17 @@ end;
|
|||||||
use this function like this:
|
use this function like this:
|
||||||
|
|
||||||
ASource.Render(ADest, 0, ASource.Height, 1.0, -1.0);
|
ASource.Render(ADest, 0, ASource.Height, 1.0, -1.0);
|
||||||
|
|
||||||
|
Set ADoDraw to falses in order to just get the bounding box of all entities
|
||||||
|
on the page in RenderInfo.EnitityCanvasMinXY/EntityCanvasMaxXY.
|
||||||
}
|
}
|
||||||
procedure TvVectorialPage.Render(ADest: TFPCustomCanvas;
|
procedure TvVectorialPage.Render(ADest: TFPCustomCanvas;
|
||||||
ADestX: Integer; ADestY: Integer; AMulX: Double; AMulY: Double);
|
ADestX: Integer; ADestY: Integer; AMulX: Double; AMulY: Double;
|
||||||
|
ADoDraw: Boolean = true);
|
||||||
var
|
var
|
||||||
i: Integer;
|
i: Integer;
|
||||||
CurEntity: TvEntity;
|
CurEntity: TvEntity;
|
||||||
|
rinfo: TvRenderInfo;
|
||||||
begin
|
begin
|
||||||
{$ifdef FPVECTORIAL_TOCANVAS_DEBUG}
|
{$ifdef FPVECTORIAL_TOCANVAS_DEBUG}
|
||||||
WriteLn(':>DrawFPVectorialToCanvas');
|
WriteLn(':>DrawFPVectorialToCanvas');
|
||||||
@ -7790,8 +7891,22 @@ begin
|
|||||||
CurEntity := GetEntity(i);
|
CurEntity := GetEntity(i);
|
||||||
|
|
||||||
RenderInfo.BackgroundColor := BackgroundColor;
|
RenderInfo.BackgroundColor := BackgroundColor;
|
||||||
CurEntity.Render(ADest, RenderInfo, ADestX, ADestY, AMulX, AMulY);
|
RenderInfo.AdjustPenColorToBackground := AdjustPenColorToBackground;
|
||||||
|
|
||||||
|
CurEntity.Render(ADest, RenderInfo, ADestX, ADestY, AMulX, AMulY, ADoDraw);
|
||||||
|
|
||||||
|
if i = 0 then
|
||||||
|
rInfo := RenderInfo
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
rInfo.EntityCanvasMinXY.X := Min(rInfo.EntityCanvasMinXY.X, RenderInfo.EntityCanvasMinXY.X);
|
||||||
|
rInfo.EntityCanvasMinXY.Y := Min(rInfo.EntityCanvasMinXY.Y, RenderInfo.EntityCanvasMinXY.Y);
|
||||||
|
rInfo.EntityCanvasMaxXY.X := Max(rInfo.EntityCanvasMaxXY.X, RenderInfo.EntityCanvasMaxXY.X);
|
||||||
|
rInfo.EntityCanvasMaxXY.Y := Max(rInfo.EntityCanvasMaxXY.Y, RenderInfo.EntityCanvasMaxXY.Y);
|
||||||
end;
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
RenderInfo := rInfo;
|
||||||
|
|
||||||
{$ifdef FPVECTORIAL_TOCANVAS_DEBUG}
|
{$ifdef FPVECTORIAL_TOCANVAS_DEBUG}
|
||||||
WriteLn(':<DrawFPVectorialToCanvas');
|
WriteLn(':<DrawFPVectorialToCanvas');
|
||||||
@ -7983,7 +8098,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TvTextPageSequence.Render(ADest: TFPCustomCanvas; ADestX: Integer;
|
procedure TvTextPageSequence.Render(ADest: TFPCustomCanvas; ADestX: Integer;
|
||||||
ADestY: Integer; AMulX: Double; AMulY: Double);
|
ADestY: Integer; AMulX: Double; AMulY: Double; ADoDraw: Boolean = true);
|
||||||
|
|
||||||
function CoordToCanvasX(ACoord: Double): Integer;
|
function CoordToCanvasX(ACoord: Double): Integer;
|
||||||
begin
|
begin
|
||||||
@ -8019,7 +8134,7 @@ begin
|
|||||||
CurEntity.Y := 0;
|
CurEntity.Y := 0;
|
||||||
lHeight_px := CurEntity.GetEntityFeatures(ADest).DrawsUpwardHeightAdjustment;
|
lHeight_px := CurEntity.GetEntityFeatures(ADest).DrawsUpwardHeightAdjustment;
|
||||||
RenderInfo.BackgroundColor := BackgroundColor;
|
RenderInfo.BackgroundColor := BackgroundColor;
|
||||||
CurEntity.Render(ADest, RenderInfo, ADestX, CurY_px + lHeight_px, AMulX, AMulY);
|
CurEntity.Render(ADest, RenderInfo, ADestX, CurY_px + lHeight_px, AMulX, AMulY, ADoDraw);
|
||||||
// Store the old position in X/Y but don't use it, we use this to debug out the position
|
// Store the old position in X/Y but don't use it, we use this to debug out the position
|
||||||
CurEntity.X := ADestX;
|
CurEntity.X := ADestX;
|
||||||
CurEntity.Y := CurY_px;
|
CurEntity.Y := CurY_px;
|
||||||
@ -8233,7 +8348,7 @@ procedure TvVectorialDocument.ReadFromFile(AFileName: string);
|
|||||||
var
|
var
|
||||||
lFormat: TvVectorialFormat;
|
lFormat: TvVectorialFormat;
|
||||||
begin
|
begin
|
||||||
lFormat := GetFormatFromExtension(ExtractFileExt(AFileName));
|
lFormat := GetFormatFromExtension(AFileName);
|
||||||
ReadFromFile(AFileName, lFormat);
|
ReadFromFile(AFileName, lFormat);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -130,9 +130,11 @@ type
|
|||||||
function ReadTextFromNode(ANode: TDOMNode; AData: TvVectorialPage; ADoc: TvVectorialDocument): TvEntity;
|
function ReadTextFromNode(ANode: TDOMNode; AData: TvVectorialPage; ADoc: TvVectorialDocument): TvEntity;
|
||||||
function ReadUseFromNode(ANode: TDOMNode; AData: TvVectorialPage; ADoc: TvVectorialDocument): TvEntity;
|
function ReadUseFromNode(ANode: TDOMNode; AData: TvVectorialPage; ADoc: TvVectorialDocument): TvEntity;
|
||||||
//
|
//
|
||||||
|
procedure StringToPenPattern(const AStr: String; var APen: TvPen);
|
||||||
function StringWithUnitToFloat(AStr: string; ACoordKind: TSVGCoordinateKind = sckUnknown;
|
function StringWithUnitToFloat(AStr: string; ACoordKind: TSVGCoordinateKind = sckUnknown;
|
||||||
ADefaultUnit: TSVGUnit = suPX; ATargetUnit: 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;
|
||||||
const ASrcX, ASrcY: Double; var ADestX, ADestY: Double;
|
const ASrcX, ASrcY: Double; var ADestX, ADestY: Double;
|
||||||
@ -147,6 +149,7 @@ type
|
|||||||
ADoViewBoxAdjust: Boolean = True);
|
ADoViewBoxAdjust: Boolean = True);
|
||||||
procedure AutoDetectDocSize(var ALeft, ATop, ARight, ABottom: Double; ABaseNode: TDOMNode);
|
procedure AutoDetectDocSize(var ALeft, ATop, ARight, ABottom: Double; ABaseNode: TDOMNode);
|
||||||
function SVGColorValueStrToWord(AStr: string): Word;
|
function SVGColorValueStrToWord(AStr: string): Word;
|
||||||
|
|
||||||
public
|
public
|
||||||
{ General reading methods }
|
{ General reading methods }
|
||||||
constructor Create; override;
|
constructor Create; override;
|
||||||
@ -205,7 +208,11 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
destructor TSVGPathTokenizer.Destroy;
|
destructor TSVGPathTokenizer.Destroy;
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
begin
|
begin
|
||||||
|
for i:=Tokens.Count-1 downto 0 do
|
||||||
|
Tokens[i].Free;
|
||||||
Tokens.Free;
|
Tokens.Free;
|
||||||
|
|
||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
@ -928,7 +935,7 @@ begin
|
|||||||
end
|
end
|
||||||
else if AKey = 'stroke-opacity' then
|
else if AKey = 'stroke-opacity' then
|
||||||
begin
|
begin
|
||||||
ADestEntity.Pen.Color.Alpha := Round(StrToFloat(AValue)*$FFFF);
|
ADestEntity.Pen.Color.Alpha := Round(StrToFloat(AValue, FPointSeparator)*$FFFF);
|
||||||
end
|
end
|
||||||
else if AKey = 'stroke-linecap' then
|
else if AKey = 'stroke-linecap' then
|
||||||
begin
|
begin
|
||||||
@ -937,7 +944,9 @@ begin
|
|||||||
'round':
|
'round':
|
||||||
'square': ADestEntity.Pen;
|
'square': ADestEntity.Pen;
|
||||||
end;}
|
end;}
|
||||||
end;
|
end
|
||||||
|
else if AKey = 'stroke-dasharray' then
|
||||||
|
StringToPenPattern(AValue, ADestEntity.Pen);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TvSVGVectorialReader.ReadSVGBrushStyleWithKeyAndValue(AKey,
|
function TvSVGVectorialReader.ReadSVGBrushStyleWithKeyAndValue(AKey,
|
||||||
@ -1458,6 +1467,7 @@ begin
|
|||||||
lEntityName := LowerCase(ANode.NodeName);
|
lEntityName := LowerCase(ANode.NodeName);
|
||||||
case lEntityName of
|
case lEntityName of
|
||||||
'circle': Result := ReadCircleFromNode(ANode, AData, ADoc);
|
'circle': Result := ReadCircleFromNode(ANode, AData, ADoc);
|
||||||
|
'defs': ReadDefsFromNode(ANode, AData, ADoc);
|
||||||
'ellipse': Result := ReadEllipseFromNode(ANode, AData, ADoc);
|
'ellipse': Result := ReadEllipseFromNode(ANode, AData, ADoc);
|
||||||
'frame': Result := ReadFrameFromNode(ANode, AData, ADoc);
|
'frame': Result := ReadFrameFromNode(ANode, AData, ADoc);
|
||||||
'g': ReadLayerFromNode(ANode, AData, ADoc);
|
'g': ReadLayerFromNode(ANode, AData, ADoc);
|
||||||
@ -2841,6 +2851,47 @@ begin
|
|||||||
Result := lInsert;
|
Result := lInsert;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TvSVGVectorialReader.StringToPenPattern(const AStr: String;
|
||||||
|
var APen: TvPen);
|
||||||
|
var
|
||||||
|
float_patt: TDoubleArray;
|
||||||
|
patt: array of LongWord;
|
||||||
|
i: Integer;
|
||||||
|
begin
|
||||||
|
float_patt := ReadSpaceSeparatedFloats(AStr, ',');
|
||||||
|
if Length(float_patt) < 2 then
|
||||||
|
exit;
|
||||||
|
|
||||||
|
SetLength(patt, Length(float_patt));
|
||||||
|
for i:=0 to High(patt) do
|
||||||
|
begin
|
||||||
|
if float_patt[i] < 0 then
|
||||||
|
raise Exception.CreateFmt('Incorrect value in stroke-dasharray "%s"', [AStr]);
|
||||||
|
patt[i] := round(float_patt[i]);
|
||||||
|
end;
|
||||||
|
|
||||||
|
case Length(patt) of
|
||||||
|
2: if patt[1] = 5 then
|
||||||
|
case patt[0] of
|
||||||
|
3: begin APen.Style := psDot; exit; end; // stroke-dasharray: 3, 5
|
||||||
|
9: begin APen.Style := psDash; exit; end; // stroke-dasharray: 9, 5
|
||||||
|
end;
|
||||||
|
4: if (patt[0] = 9) and (patt[1] = 5) and (patt[2] = 3) and (patt[3] = 5) then
|
||||||
|
begin // stroke-dasharray: 9, 5, 3, 5
|
||||||
|
APen.Style := psDashDot;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
6: if (patt[0] = 9) and (patt[1] = 5) and (patt[2] = 3) and (patt[3] = 5) and
|
||||||
|
(patt[4] = 3) and (patt[5] = 5)
|
||||||
|
then begin // stroke-dasharray: 9, 5, 3, 5, 3, 5
|
||||||
|
APen.Style := psDashDotDot;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
APen.Style := psPattern;
|
||||||
|
APen.Pattern := patt;
|
||||||
|
end;
|
||||||
|
|
||||||
function TvSVGVectorialReader.StringWithUnitToFloat(AStr: string;
|
function TvSVGVectorialReader.StringWithUnitToFloat(AStr: string;
|
||||||
ACoordKind: TSVGCoordinateKind = sckUnknown; ADefaultUnit: TSVGUnit = suPX;
|
ACoordKind: TSVGCoordinateKind = sckUnknown; ADefaultUnit: TSVGUnit = suPX;
|
||||||
ATargetUnit: TSVGUnit = suPX): Double;
|
ATargetUnit: TSVGUnit = suPX): Double;
|
||||||
|
Loading…
Reference in New Issue
Block a user