在我的印象中,Truetype的字体是可以缩放的,非truetype的,
如 System好像小不到哪里去。
我做过一个打印预览,因为想做的通用,所以针对不同的打印要求,
抽象出来一个接口如下,需要打印的类实现这个接口后,作为参数传给我的打印预览窗口。
IPrintable = interface
// 打印纸的方向
function GetOrient: TPrinterOrientation;
procedure SetOrient(const Value: TPrinterOrientation);
// 在纸上的打印原点
function GetOrigin: TPoint;
procedure SetOrigin(const Value: TPoint);
// 纸张大小(相对于A4,B5等预定义的纸张,只是一个整数)
function GetPaperSize: Integer;
procedure SetpaperSize(const Value: Integer);
// 自定义纸张的大小
function GetPaperLength: Integer;
function GetPaperWidth: Integer;
procedure SetPaperLength(const Value: Integer);
procedure SetPaperWidth(const Value: Integer);
// 要打印的总页数
function GetTotalPage: Integer;
// 缩放比例
function GetZoomRatio: Integer;
procedure SetZoomRatio(const Value: Integer);
// 要打印的每页实际的大小
function GetPageWidth: Integer;
function GetPageHeight: Integer;
// 打印
procedure PrintPage(Canvas: TCanvas; PageIndex: Integer; Scale: double = 1);
// 保存打印的配置,包括纸张,纸的方向,绘图原点,缩放比例等
procedure SavePrintConfig;
property ZoomRatio: Integer read GetZoomRatio write SetZoomRatio;
property PrintOrient: TPrinterOrientation read GetOrient write SetOrient;
property PaperSize: Integer read GetPaperSize write SetPaperSize;
property PaperLength: Integer read GetPaperLength write SetPaperLength;
property PaperWidth: Integer read GetPaperWidth write SetPaperWidth;
property Origin: TPoint read GetOrigin write SetOrigin;
property TotalPage: Integer read GetTotalPage;
property Caption: string read GetCaption;
property PageWidth: Integer read GetPageWidth;
property PageHeight: Integer read GetPageHeight;
end;
在我的打印预览窗口中,我用PaintBox模拟一张纸。要注意,打印函数
procedure PrintPage(Canvas: TCanvas; PageIndex: Integer; Scale: double = 1);
是一个,也就是说在屏幕上显示、在模拟纸上的显示、在打印机上实际打印,用的都是这个函数。
不同的是Canvas,为了能保持一致,要注意不同的Canvas是有不同的分辨率的。所以,打印函数中
要对所有的坐标进行 * Scale 的处理。比如字体,如果你用的是TrueType字体,我的经验保证
可以这样写: Font.Height := Round(Font.Height * Scale);
下面是在PaintBox上的 OnPaint函数:
procedure TFormPreview.PaintBoxPaint(Sender: TObject);
begin
with PaintBox.Canvas do
begin
Pen.Color := clBlack;
Brush.Color := clWhite;
rectangle(PaintBox.ClientRect);
...
//画当前页
MoveWindowOrg(handle, R(offSetL), R(offSetT));
FPrintable.PrintPage(PaintBox.Canvas, CurPage, Scale);
MoveWindowOrg(handle,-R(offSetL), -R(offSetT));
end;
...
end;
要做一个好的打印预览,需要考虑的东西挺多,我的实现也有很多毛病,比如我用的是像素,没有
用毫米这样设备无关的长度单位,接口抽象的也不是很好,但是对我来说够用了,也就懒得改了。
我是为一个报表写的打印预览,也许你的要求不是那么高,你可以去DSP找一些现成的PrintPreview
控件来参考一下,这会让你对Windows下的打印有更深层次的认识。