TAChart: Fix poor resolution when printing a chart with LazReport.

git-svn-id: trunk@52205 -
This commit is contained in:
wp 2016-04-16 15:07:06 +00:00
parent 9a6c33c697
commit ada5db9ce2
11 changed files with 79 additions and 51 deletions

View File

@ -226,8 +226,6 @@ begin
end;
procedure TAggPasDrawer.SetFont(AFont: TFPCustomFont);
const
DEFAULT_FONT_SIZE = 10; // Just a random value.
var
f: TAggLCLFont;
fontSize: Integer;

View File

@ -7,7 +7,7 @@ object Form1: TForm1
ClientHeight = 331
ClientWidth = 528
OnCreate = FormCreate
LCLVersion = '1.1'
LCLVersion = '1.7'
object Chart1: TChart
Left = 0
Height = 296
@ -33,7 +33,6 @@ object Form1: TForm1
'TAChart'
)
Align = alClient
ParentColor = False
object Chart1BarSeries1: TBarSeries
BarBrush.Color = clRed
Source = ListChartSource1
@ -67,9 +66,6 @@ object Form1: TForm1
OnEnterRect = frReport1EnterRect
left = 72
top = 80
ReportForm = {
19000000
}
end
object ListChartSource1: TListChartSource
DataPoints.Strings = (

View File

@ -31,6 +31,9 @@ implementation
{$R *.lfm}
uses
Math, Printers, TADrawUtils, TADrawerCanvas;
{ TForm1 }
procedure TForm1.btnShowReportClick(Sender: TObject);
@ -47,16 +50,19 @@ procedure TForm1.frReport1EnterRect(Memo: TStringList; View: TfrView);
var
bmp: TBitmap;
pv: TfrPictureView;
factor: Double;
begin
if Memo.Count = 0 then exit;
if (Memo[0] = 'Chart1') and (View is TfrPictureView) then begin
pv := View as TfrPictureView;
factor := Max(Printer.XDpi, Printer.YDpi) / Screen.PixelsPerInch;
bmp := TBitmap.Create;
try
bmp.Width := Round(pv.Width);
bmp.Height := Round(pv.Height);
Chart1.PaintOnCanvas(
bmp.Canvas, Rect(0, 0, bmp.Width, bmp.Height));
bmp.Width := Round(pv.Width * factor);
bmp.Height := Round(pv.Height * factor);
Chart1.Draw(
TScaledCanvasDrawer.Create(bmp.Canvas, factor, [scaleFont, scalePen]),
Rect(0, 0, bmp.Width, bmp.Height));
pv.Picture.Bitmap.Assign(bmp);
finally
bmp.Free;

View File

@ -1,4 +1,4 @@
<?xml version="1.0"?>
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="9"/>
@ -44,7 +44,6 @@
<Unit0>
<Filename Value="lazreportdemo.lpr"/>
<IsPartOfProject Value="True"/>
<UnitName Value="lazreportdemo"/>
</Unit0>
<Unit1>
<Filename Value="Main.pas"/>
@ -52,7 +51,6 @@
<ComponentName Value="Form1"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="Main"/>
</Unit1>
</Units>
</ProjectOptions>
@ -78,12 +76,6 @@
</Win32>
</Options>
</Linking>
<Other>
<CompilerMessages>
<UseMsgFile Value="True"/>
</CompilerMessages>
<CompilerPath Value="$(CompPath)"/>
</Other>
</CompilerOptions>
<Debugging>
<Exceptions Count="3">

View File

@ -6,7 +6,7 @@ object Form1: TForm1
Caption = 'Form1'
ClientHeight = 310
ClientWidth = 398
LCLVersion = '0.9.31'
LCLVersion = '1.7'
object Chart1: TChart
Left = 0
Height = 272
@ -33,7 +33,6 @@ object Form1: TForm1
'TAChart'
)
Align = alClient
ParentColor = False
object Chart1LineSeries1: TLineSeries
Source = RandomChartSource1
end
@ -57,7 +56,7 @@ object Form1: TForm1
TabOrder = 0
end
object PrintCanvas: TButton
Left = 96
Left = 256
Height = 25
Top = 6
Width = 115
@ -65,6 +64,15 @@ object Form1: TForm1
OnClick = PrintClick
TabOrder = 1
end
object PrintScaledPen: TButton
Left = 88
Height = 25
Top = 6
Width = 163
Caption = 'Print w/ scaled penwidth'
OnClick = PrintClick
TabOrder = 2
end
end
object RandomChartSource1: TRandomChartSource
PointsNumber = 12

View File

@ -13,6 +13,7 @@ type
{ TForm1 }
TForm1 = class(TForm)
PrintScaledPen: TButton;
Chart1: TChart;
Chart1LineSeries1: TLineSeries;
Panel1: TPanel;
@ -55,7 +56,7 @@ begin
if Sender = PrintCanvas then
Chart1.PaintOnCanvas(Printer.Canvas, r)
else
Chart1.Draw(TPrinterDrawer.Create(Printer), r);
Chart1.Draw(TPrinterDrawer.Create(Printer, (Sender = PrintScaledPen)), r);
finally
Printer.EndDoc;
end;

View File

@ -1,4 +1,4 @@
<?xml version="1.0"?>
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="9"/>
@ -31,7 +31,7 @@
<RequiredPackages Count="5">
<Item1>
<PackageName Value="LCLBase"/>
<MinVersion Major="1" Valid="True" Release="1"/>
<MinVersion Major="1" Release="1" Valid="True"/>
</Item1>
<Item2>
<PackageName Value="LCL"/>
@ -52,14 +52,13 @@
<Unit0>
<Filename Value="printdemo.lpr"/>
<IsPartOfProject Value="True"/>
<UnitName Value="printdemo"/>
</Unit0>
<Unit1>
<Filename Value="Main.pas"/>
<IsPartOfProject Value="True"/>
<ComponentName Value="Form1"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="Main"/>
</Unit1>
<Unit2>
<Filename Value="..\..\taprint.pas"/>
@ -69,7 +68,7 @@
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="10"/>
<Version Value="11"/>
<PathDelim Value="\"/>
<Target>
<Filename Value="printdemo"/>
@ -85,12 +84,6 @@
</Win32>
</Options>
</Linking>
<Other>
<CompilerMessages>
<UseMsgFile Value="True"/>
</CompilerMessages>
<CompilerPath Value="$(CompPath)"/>
</Other>
</CompilerOptions>
<Debugging>
<Exceptions Count="3">

View File

@ -32,6 +32,7 @@ const
CHART_COMPONENT_IDE_PAGE = 'Chart';
PERCENT = 0.01;
clTAColor = $20000000; // = clDefault, but avoiding dependency on Graphics
DEFAULT_FONT_SIZE = 10;
type
EChartError = class(Exception);

View File

@ -73,13 +73,21 @@ type
procedure SetTransparency(ATransparency: TChartTransparency);
end;
TScaledCanvasDrawer = class(TCanvasDrawer)
protected
FCoeff: Double;
public
constructor Create(ACanvas: TCanvas; ACoeff: Double; AScaleItems: TScaleItems);
function Scale(ADistance: Integer): Integer; override;
end;
function CanvasGetFontOrientationFunc(AFont: TFPCustomFont): Integer;
function ChartColorSysToFPColor(AChartColor: TChartColor): TFPColor;
implementation
uses
GraphType, LCLIntf, LCLType, IntfGraphics,
GraphType, Math, LCLIntf, LCLType, IntfGraphics,
TAGeometry;
function CanvasGetFontOrientationFunc(AFont: TFPCustomFont): Integer;
@ -213,7 +221,9 @@ begin
Mode := pmXor
else
Mode := pmCopy;
Width := 1;
if (scalePen in FScaleItems) then
Width := Scale(1) else
Width := 1;
end;
end;
@ -334,12 +344,14 @@ begin
end;
if FMonochromeColor <> clTAColor then
Color := FMonochromeColor;
if scaleFont in FScaleItems then
Size := Scale(IfThen(Size = 0, DEFAULT_FONT_SIZE, Size));
end;
end;
procedure TCanvasDrawer.SetPen(APen: TFPCustomPen);
begin
with GetCanvas do
with GetCanvas do begin
if FXor then begin
Brush.Style := bsClear;
if APen = nil then
@ -366,6 +378,9 @@ begin
if FMonochromeColor <> clTAColor then
Pen.Color := FMonochromeColor;
end;
if scalePen in FScaleItems then
Pen.Width := Scale(Pen.Width);
end;
end;
procedure TCanvasDrawer.SetPenParams(AStyle: TFPPenStyle; AColor: TChartColor);
@ -481,6 +496,22 @@ begin
DrawSimpleText(GetCanvas, AX, AY, AText);
end;
{ TScaledCanvasDrawer }
constructor TScaledCanvasDrawer.Create(ACanvas: TCanvas; ACoeff: Double;
AScaleItems: TScaleItems);
begin
inherited Create(ACanvas);
FCoeff := ACoeff;
FScaleItems := AScaleItems;
end;
function TScaledCanvasDrawer.Scale(ADistance: Integer): Integer;
begin
Result := Round(FCoeff * ADistance);
end;
initialization
// Suppress incorrect "TAGeometry is unused" hint
Unused(DoublePoint(0, 0));

View File

@ -59,6 +59,9 @@ type
TChartTransparency = 0..255;
TScaleItem = (scaleFont, scalePen);
TScaleItems = set of TScaleItem;
IChartDrawer = interface
procedure AddToFontOrientation(ADelta: Integer);
procedure ClippingStart(const AClipRect: TRect);
@ -129,6 +132,7 @@ type
FRightToLeft: Boolean;
FTransparency: TChartTransparency;
FXor: Boolean;
FScaleItems: TScaleItems;
function ColorOrMono(AColor: TChartColor): TChartColor; inline;
function FPColorOrMono(const AColor: TFPColor): TFPColor; inline;
function GetFontAngle: Double; virtual; abstract;

View File

@ -20,32 +20,30 @@ type
{ TPrinterDrawer }
TPrinterDrawer = class(TCanvasDrawer)
TPrinterDrawer = class(TScaledCanvasDrawer)
private
FPrinter: TPrinter;
FCoeff: Double;
public
constructor Create(APrinter: TPrinter);
function Scale(ADistance: Integer): Integer; override;
constructor Create(APrinter: TPrinter; AScalePens: Boolean = false);
end;
implementation
uses
Forms, Math;
Forms, Math, TADrawUtils;
{ TPrinterDrawer }
constructor TPrinterDrawer.Create(APrinter: TPrinter);
constructor TPrinterDrawer.Create(APrinter: TPrinter;
AScalePens: Boolean = false);
var
f: Double;
si: TScaleItems;
begin
FPrinter := APrinter;
inherited Create(FPrinter.Canvas);
FCoeff := Max(FPrinter.XDPI, FPrinter.YDPI) / Screen.PixelsPerInch;
end;
function TPrinterDrawer.Scale(ADistance: Integer): Integer;
begin
Result := Round(ADistance * FCoeff);
f := Max(FPrinter.XDPI, FPrinter.YDPI) / Screen.PixelsPerInch;
if AScalePens then si := [scalePen] else si := [];
inherited Create(FPrinter.Canvas, f, si);
end;
end.