mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-29 20:30:33 +02:00
fpvectorial: Improves autofit
git-svn-id: trunk@51501 -
This commit is contained in:
parent
2b7967bb3f
commit
e96bbc3714
@ -471,7 +471,7 @@ type
|
|||||||
// in CalculateBoundingBox always remember to treat correctly the case of ADest=nil!!!
|
// in CalculateBoundingBox always remember to treat correctly the case of ADest=nil!!!
|
||||||
// This cased is utilized to guess the size of a document even before getting a canvas to draw at
|
// This cased is utilized to guess the size of a document even before getting a canvas to draw at
|
||||||
procedure CalculateBoundingBox(ADest: TFPCustomCanvas; out ALeft, ATop, ARight, ABottom: Double); virtual;
|
procedure CalculateBoundingBox(ADest: TFPCustomCanvas; out ALeft, ATop, ARight, ABottom: Double); virtual;
|
||||||
function CalculateSizeInCanvas(ADest: TFPCustomCanvas; AParent: TvPage; out ALeft, ATop, AWidth, AHeight: Integer): Boolean;
|
function CalculateSizeInCanvas(ADest: TFPCustomCanvas; APage: TvPage; APageHeight: Integer; AZoom: Double; out ALeft, ATop, AWidth, AHeight: Integer): Boolean;
|
||||||
procedure CalculateHeightInCanvas(ADest: TFPCustomCanvas; out AHeight: Integer);
|
procedure CalculateHeightInCanvas(ADest: TFPCustomCanvas; out AHeight: Integer);
|
||||||
// helper functions for CalculateBoundingBox & TvRenderInfo
|
// helper functions for CalculateBoundingBox & TvRenderInfo
|
||||||
procedure ExpandBoundingBox(ADest: TFPCustomCanvas; var ALeft, ATop, ARight, ABottom: Double);
|
procedure ExpandBoundingBox(ADest: TFPCustomCanvas; var ALeft, ATop, ARight, ABottom: Double);
|
||||||
@ -1475,7 +1475,7 @@ type
|
|||||||
ADestX: Integer = 0; ADestY: Integer = 0; AMulX: Double = 1.0; AMulY: Double = 1.0;
|
ADestX: Integer = 0; ADestY: Integer = 0; AMulX: Double = 1.0; AMulY: Double = 1.0;
|
||||||
ADoDraw: Boolean = true); virtual; abstract;
|
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;
|
||||||
function GetNaturalMulY(): Double; virtual; abstract;
|
procedure GetNaturalRenderPos(var APageHeight: Integer; out AMulY: Double); virtual; abstract;
|
||||||
{ Debug methods }
|
{ Debug methods }
|
||||||
procedure GenerateDebugTree(ADestRoutine: TvDebugAddItemProc; APageItem: Pointer); virtual; abstract;
|
procedure GenerateDebugTree(ADestRoutine: TvDebugAddItemProc; APageItem: Pointer); virtual; abstract;
|
||||||
end;
|
end;
|
||||||
@ -1559,7 +1559,7 @@ type
|
|||||||
procedure Render(ADest: TFPCustomCanvas; ADestX: Integer = 0; ADestY: Integer = 0;
|
procedure Render(ADest: TFPCustomCanvas; ADestX: Integer = 0; ADestY: Integer = 0;
|
||||||
AMulX: Double = 1.0; AMulY: Double = 1.0; ADoDraw: Boolean = true); 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;
|
||||||
function GetNaturalMulY(): Double; override;
|
procedure GetNaturalRenderPos(var APageHeight: Integer; out AMulY: Double); override;
|
||||||
{ Debug methods }
|
{ Debug methods }
|
||||||
procedure GenerateDebugTree(ADestRoutine: TvDebugAddItemProc; APageItem: Pointer); override;
|
procedure GenerateDebugTree(ADestRoutine: TvDebugAddItemProc; APageItem: Pointer); override;
|
||||||
//
|
//
|
||||||
@ -1604,7 +1604,7 @@ type
|
|||||||
procedure Render(ADest: TFPCustomCanvas; ADestX: Integer = 0; ADestY: Integer = 0;
|
procedure Render(ADest: TFPCustomCanvas; ADestX: Integer = 0; ADestY: Integer = 0;
|
||||||
AMulX: Double = 1.0; AMulY: Double = 1.0; ADoDraw: Boolean = true); 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;
|
||||||
function GetNaturalMulY(): Double; override;
|
procedure GetNaturalRenderPos(var APageHeight: Integer; out AMulY: Double); override;
|
||||||
{ Debug methods }
|
{ Debug methods }
|
||||||
procedure GenerateDebugTree(ADestRoutine: TvDebugAddItemProc; APageItem: Pointer); override;
|
procedure GenerateDebugTree(ADestRoutine: TvDebugAddItemProc; APageItem: Pointer); override;
|
||||||
end;
|
end;
|
||||||
@ -3427,13 +3427,17 @@ end;
|
|||||||
|
|
||||||
// returns false if the element is invisible
|
// returns false if the element is invisible
|
||||||
function TvEntity.CalculateSizeInCanvas(ADest: TFPCustomCanvas;
|
function TvEntity.CalculateSizeInCanvas(ADest: TFPCustomCanvas;
|
||||||
AParent: TvPage; out ALeft, ATop, AWidth, AHeight: Integer): Boolean;
|
APage: TvPage; APageHeight: Integer; AZoom: Double;
|
||||||
|
out ALeft, ATop, AWidth, AHeight: Integer): Boolean;
|
||||||
var
|
var
|
||||||
lRenderInfo: TvRenderInfo;
|
lRenderInfo: TvRenderInfo;
|
||||||
|
lMulY: Double;
|
||||||
begin
|
begin
|
||||||
Result := True;
|
Result := True;
|
||||||
InitializeRenderInfo(lRenderInfo);
|
InitializeRenderInfo(lRenderInfo);
|
||||||
Render(ADest, lRenderInfo, 0, 0, 1, AParent.GetNaturalMulY(), False);
|
APage.GetNaturalRenderPos(APageHeight, lMulY);
|
||||||
|
AZoom := Abs(AZoom);
|
||||||
|
Render(ADest, lRenderInfo, 0, APageHeight, AZoom, AZoom * lMulY, False);
|
||||||
ALeft := lRenderInfo.EntityCanvasMinXY.X;
|
ALeft := lRenderInfo.EntityCanvasMinXY.X;
|
||||||
ATop := lRenderInfo.EntityCanvasMinXY.Y;
|
ATop := lRenderInfo.EntityCanvasMinXY.Y;
|
||||||
AWidth := lRenderInfo.EntityCanvasMaxXY.X - lRenderInfo.EntityCanvasMinXY.X;
|
AWidth := lRenderInfo.EntityCanvasMaxXY.X - lRenderInfo.EntityCanvasMinXY.X;
|
||||||
@ -9080,11 +9084,46 @@ end;
|
|||||||
procedure TvVectorialPage.AutoFit(ADest: TFPCustomCanvas;
|
procedure TvVectorialPage.AutoFit(ADest: TFPCustomCanvas;
|
||||||
AWidth, AHeight: Integer; out ADeltaX, ADeltaY: Integer; out AZoom: Double);
|
AWidth, AHeight: Integer; out ADeltaX, ADeltaY: Integer; out AZoom: Double);
|
||||||
var
|
var
|
||||||
i: Integer;
|
|
||||||
lCurEntity: TvEntity;
|
lCurEntity: TvEntity;
|
||||||
lLeft, lTop, lWidth, lHeight: Integer;
|
lLeft, lTop, lWidth, lHeight: Integer;
|
||||||
lMinX, lMinY, lMaxX, lMaxY: Integer;
|
lMinX, lMinY, lMaxX, lMaxY, lNaturalHeightDiff: Integer;
|
||||||
lZoomFitX, lZoomFitY: Double;
|
lZoomFitX, lZoomFitY, lNaturalMulY: Double;
|
||||||
|
|
||||||
|
function CalculateAllEntitySizes(): Boolean;
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
|
begin
|
||||||
|
Result := True;
|
||||||
|
|
||||||
|
lMinX := High(Integer);
|
||||||
|
lMinY := High(Integer);
|
||||||
|
lMaxX := Low(Integer);
|
||||||
|
lMaxY := Low(Integer);
|
||||||
|
|
||||||
|
for i := 0 to FEntities.Count - 1 do
|
||||||
|
begin
|
||||||
|
lCurEntity := TvEntity(FEntities.Items[i]);
|
||||||
|
if lCurEntity.CalculateSizeInCanvas(ADest, Self, AHeight, AZoom, lLeft, lTop, lWidth, lHeight) then
|
||||||
|
begin
|
||||||
|
lMinX := Min(lMinX, lLeft);
|
||||||
|
lMinY := Min(lMinY, lTop);
|
||||||
|
lMaxX := Max(lMaxX, lLeft + lWidth);
|
||||||
|
lMaxY := Max(lMaxY, lTop + lHeight);
|
||||||
|
end;
|
||||||
|
{$ifdef FPVECTORIAL_AUTOFIT_DEBUG}
|
||||||
|
AutoFitDebug.Add(Format('[%s] MinX=%d MinY=%d MaxX=%d MaxY=%D', [lCurEntity.ClassName, lMinX, lMinY, lMaxX, lMaxY]));
|
||||||
|
{$endif}
|
||||||
|
end;
|
||||||
|
|
||||||
|
if (lMinX = High(Integer)) or (lMinY = High(Integer)) or
|
||||||
|
(lMaxX = Low(Integer)) or(lMaxY = Low(Integer)) then
|
||||||
|
Exit(False);
|
||||||
|
|
||||||
|
lWidth := lMaxX - lMinX;
|
||||||
|
lHeight := lMaxY - lMinY;
|
||||||
|
if (lWidth = 0) or (lHeight = 0) then Exit(False);
|
||||||
|
end;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
{$ifdef FPVECTORIAL_AUTOFIT_DEBUG}
|
{$ifdef FPVECTORIAL_AUTOFIT_DEBUG}
|
||||||
AutoFitDebug := TStringList.Create;
|
AutoFitDebug := TStringList.Create;
|
||||||
@ -9092,53 +9131,40 @@ begin
|
|||||||
{$endif}
|
{$endif}
|
||||||
ADeltaX := 0;
|
ADeltaX := 0;
|
||||||
ADeltaY := 0;
|
ADeltaY := 0;
|
||||||
|
GetNaturalRenderPos(lNaturalHeightDiff, lNaturalMulY);
|
||||||
|
|
||||||
|
// First Calculate the zoom
|
||||||
|
|
||||||
AZoom := 1;
|
AZoom := 1;
|
||||||
lMinX := High(Integer);
|
if not CalculateAllEntitySizes() then Exit;
|
||||||
lMinY := High(Integer);
|
|
||||||
lMaxX := Low(Integer);
|
|
||||||
lMaxY := Low(Integer);
|
|
||||||
|
|
||||||
for i := 0 to FEntities.Count - 1 do
|
|
||||||
begin
|
|
||||||
lCurEntity := TvEntity(FEntities.Items[i]);
|
|
||||||
if lCurEntity.CalculateSizeInCanvas(ADest, Self, lLeft, lTop, lWidth, lHeight) then
|
|
||||||
begin
|
|
||||||
lMinX := Min(lMinX, lLeft);
|
|
||||||
lMinY := Min(lMinY, lTop);
|
|
||||||
lMaxX := Max(lMaxX, lLeft + lWidth);
|
|
||||||
lMaxY := Max(lMaxY, lTop + lHeight);
|
|
||||||
end;
|
|
||||||
{$ifdef FPVECTORIAL_AUTOFIT_DEBUG}
|
|
||||||
AutoFitDebug.Add(Format('[%s] MinX=%d MinY=%d MaxX=%d MaxY=%D', [lCurEntity.ClassName, lMinX, lMinY, lMaxX, lMaxY]));
|
|
||||||
{$endif}
|
|
||||||
end;
|
|
||||||
|
|
||||||
if (lMinX = High(Integer)) or (lMinY = High(Integer)) or
|
|
||||||
(lMaxX = Low(Integer)) or(lMaxY = Low(Integer)) then
|
|
||||||
Exit;
|
|
||||||
|
|
||||||
lWidth := lMaxX - lMinX;
|
|
||||||
lHeight := lMaxY - lMinY;
|
|
||||||
if (lWidth = 0) or (lHeight = 0) then Exit;
|
|
||||||
|
|
||||||
lZoomFitX := AWidth / lWidth;
|
lZoomFitX := AWidth / lWidth;
|
||||||
lZoomFitY := AHeight / lHeight;
|
lZoomFitY := AHeight / lHeight;
|
||||||
AZoom := Min(lZoomFitX, lZoomFitY) * 0.9;
|
AZoom := Min(lZoomFitX, lZoomFitY) * 0.9;
|
||||||
ADeltaX := Round(-1 * AZoom * lMinX);
|
|
||||||
ADeltaY := Round(-1 * AZoom * lMinY);
|
// Now DeltaX, DeltaY
|
||||||
ADeltaY += Round(-1.05 * AZoom * lHeight);
|
|
||||||
|
if not CalculateAllEntitySizes() then Exit;
|
||||||
|
ADeltaX := Round(-1 * lMinX) + AWidth div 2 - lWidth div 2;
|
||||||
|
ADeltaY := Round(-1 * lMinY) + AHeight div 2 - lHeight div 2;
|
||||||
|
ADeltaY := Round(ADeltaY * lNaturalMulY);
|
||||||
|
|
||||||
{$ifdef FPVECTORIAL_AUTOFIT_DEBUG}
|
{$ifdef FPVECTORIAL_AUTOFIT_DEBUG}
|
||||||
finally
|
finally
|
||||||
|
{$ifdef Windows}
|
||||||
AutoFitDebug.SaveToFile('C:\Programas\autofit.txt');
|
AutoFitDebug.SaveToFile('C:\Programas\autofit.txt');
|
||||||
|
{$else}
|
||||||
|
AutoFitDebug.SaveToFile('/Users/felipe/autofit.txt');
|
||||||
|
{$endif}
|
||||||
AutoFitDebug.Free;
|
AutoFitDebug.Free;
|
||||||
AutoFitDebug := nil;
|
AutoFitDebug := nil;
|
||||||
end;
|
end;
|
||||||
{$endif}
|
{$endif}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TvVectorialPage.GetNaturalMulY: Double;
|
procedure TvVectorialPage.GetNaturalRenderPos(var APageHeight: Integer; out AMulY: Double);
|
||||||
begin
|
begin
|
||||||
Result := -1.0;
|
AMulY := -1.0;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TvVectorialPage.GenerateDebugTree(ADestRoutine: TvDebugAddItemProc;
|
procedure TvVectorialPage.GenerateDebugTree(ADestRoutine: TvDebugAddItemProc;
|
||||||
@ -9322,9 +9348,10 @@ begin
|
|||||||
AZoom := 1;
|
AZoom := 1;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TvTextPageSequence.GetNaturalMulY: Double;
|
procedure TvTextPageSequence.GetNaturalRenderPos(var APageHeight: Integer; out AMulY: Double);
|
||||||
begin
|
begin
|
||||||
Result := 1.0;
|
APageHeight := 0;
|
||||||
|
AMulY := 1.0;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TvTextPageSequence.GenerateDebugTree(
|
procedure TvTextPageSequence.GenerateDebugTree(
|
||||||
|
Loading…
Reference in New Issue
Block a user