Delphi Programming / Object Pascal
[掲載 2000年05月07日] [更新 2016年04月20日] プリンタ設定コンポーネント
プリンタ設定コンポーネント
テストプログラム ScallingDraw
動作確認等
Windows 7 U64(SP1) + Delphi XE(UP1) Pro
印刷のプログラムでは,現実の用紙の寸法を用いて図形や文字列の描画印刷位置を与えたいことがあります.これにはいくつかの方法が考えられますが,その一つは,次の Windows API の関数を使用して,スケーリング (マッピング) を行う方法です.
このテストプログラムでは,これらの関数を使用して,図形および文字列を 0.1 mm 単位で指定して,プリンタのキャンバスに描画しています.
科学技術関係の計算結果をグラフにする時は,実数値 (浮動小数点値) を扱うことがあります.そのような場合は,ここで述べる方法ではなく,変換用の関数を作成して,画面のピクセル数やプリンタのドット数に換算する方法が一般的です.
SetMapMode
ページ空間単位をデバイス空間単位に変換する比率のモード
SetWindowExtEx
ウィンドウの水平と垂直方向の範囲の設定
SetViewPortExtEx
ビューポートの水平と垂直方向の設定
図1
設計時画面
図2
実行開始画面
図3
印刷のダイアログ
印刷のダイアログが現れる
出力プリンタの変更が可能
図4
実行結果
プリンタの解像度に関係なしに同じ位置に同じ寸法で印刷できる
リスト1
0.1 ミリメートル単位で図形や文字を描画
copy code
unit ScallingDrawUnit;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls, plSetPrinter, Buttons;
type
TForm1 = class (TForm)
BitBtn1: TBitBtn;
Label1: TLabel;
plSetPrinter1: TplSetPrinter;
PrintDialog1: TPrintDialog;
procedure BitBtn1Click(Sender: TObject);
procedure FormShow(Sender: TObject);
private
{ Private 宣言 }
FPaperWidth : Integer; // ドット数で表した用紙幅
FPaperHeight: Integer; // ドット数で表した用紙長さ
FPaperWmm : Integer; // 0.1mm単位で表した用紙幅
FPaperHmm : Integer; // 0.1mm単位で表した用紙長さ
FPaperLO : Integer; // 左オフセット値
FPaperTO : Integer; // 上オフセット値
procedure GetPaperScale;
procedure Scalling(ACanvas: TCanvas);
procedure DrawRoutine;
public
{ Public 宣言 }
end ;
var
Form1: TForm1;
implementation
uses
Printers;
{$R *.DFM}
// =============================================================================
// フォーム表示開始時の処理
// 確認用にプリンタ名をラベルに表示
// =============================================================================
procedure TForm1.FormShow(Sender: TObject);
var
LText: string ;
begin
LText := plSetPrinter1.PrinterName;
// 設計時のプリンタ名を表示
Label1.Caption := LText;
end ;
// =============================================================================
// プリンタに出力
// =============================================================================
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
if PrintDialog1.Execute then begin
// 印刷ダイアログで設定した内容を取得
plSetPrinter1.GetPrinterInfo;
// 用紙サイズを0.1mm単位に換算
GetPaperScale;
// Printer.Canvasに出力
DrawRoutine;
end ;
end ;
// -----------------------------------------------------------------------------
// 選択した用紙サイズ(ピクセル単位)を0.1mm単位の寸法に換算する
// (A4縦ならPaperW=2100,PaperH=2970となる)
// -----------------------------------------------------------------------------
procedure TForm1.GetPaperScale;
begin
// plSetPrinterのプロパティから横と長さ方向のドット数を取得
FPaperWidth := plSetPrinter1.PaperWidth;
FPaperHeight := plSetPrinter1.PaperHeight;
// プリンタの解像度の値から0.1mm単位の用紙の寸法を計算
FPaperWmm := Trunc(FPaperWidth * 254 / plSetPrinter1.XResolution);
FPaperHmm := Trunc(FPaperHeight * 254 /plSetPrinter1.YResolution);
// オフセット値を取得
FPaperLO := plSetPrinter1.LeftOffset;
FPaperTO := plSetPrinter1.TopOffset;
end ;
// -----------------------------------------------------------------------------
// 描画ルーチン
//
// 描画するのは幅100.0mm,縦120.0mmの四角形.線の太さは0.5mm.
// 描画は10分の1mm単位でできる.
// -----------------------------------------------------------------------------
procedure TForm1.DrawRoutine;
var
LText : string ;
begin
// 印刷する文字列
LText := '印刷テスト' ;
try
// 印刷命令開始
Printer.BeginDoc;
// スケーリング
Scalling(Printer.Canvas);
// 線の太さは0.5mm
Printer.Canvas.Pen.Width := 5 ;
// 四角形の描画開始座標は左から50.0mm,上から80.0mm
// 右は150.0mm,下は200.0mmの四角形,つまり幅100.0mm,縦120.0mm
Printer.Canvas.Rectangle(500 , 800 , 1500 , 2000 );
// 内部レディングを含めた文字の高さを10.0mmに
Printer.Canvas.Font.Height := 100 ;
// 背景は透明に
Printer.Canvas.Brush.Style := bsClear;
// 四角形の左上に文字列を描画
Printer.Canvas.TextOut(500 , 800 , LText);
// 印刷する文字列の高さ確認のための線を引く
Printer.Canvas.Pen.Width := 1 ;
Printer.Canvas.MoveTo( 500 , 900 );
Printer.Canvas.LineTo(1500 , 900 );
finally
// デフォルトのモードに戻す
SetMapMode(Printer.Canvas.Handle, MM_TEXT);
// 印刷命令終了
Printer.EndDoc;
end ;
end ;
// -----------------------------------------------------------------------------
// スケーリング
//
// このスケーリング以降,10分の1mm単位での描画が可能となる.
// -----------------------------------------------------------------------------
procedure TForm1.Scalling(ACanvas: TCanvas);
begin
// スケーリングのモード
SetMapMode (ACanvas.Handle,MM_ANISOTROPIC);
SetWindowExtEx (ACanvas.Handle,FPaperWmm, FPaperHmm, nil );
SetViewPortExtEx (ACanvas.Handle,FPaperWidth,FPaperHeight, nil );
// 描画原点を移動
SetViewPortOrgEx(ACanvas.Handle, -FPaperLO, -FPaperTO, nil );
end ;
end .
フォントの大きさは,上のコードのように,高さ (Height) で与えれば自動的にスケーリングしてくれます.一方,Font.Size で指定しても期待通りの結果とはなりません.Font.Size に相当する値で指定するには,次の様に Font.Height に換算する必要があります.この式は 1 pt が 1/72 inch であることを利用して 0.1 mm 単位の高さに換算しています.
リスト2
Font.Size の値を Font.Height の値に換算
copy code
var
LFontSize : Double;
begin
LFontSize := 12.0;
Printer.Canvas.Font.Height := -Trunc(LFontSize * 254.0 / 72.0);
end ;