喫茶XRAYトップページ

[スレッド全体
]

[6551] メタファイルとマッピング返信 削除
2012/12/15 (土) 20:18:49 taki
マスター教えてください。

長い複数ページにわたる文章を一度にCanvasに書き込んで、
任意の範囲(ページ)をプレビューしたり印刷したりしたいのです。

マスターのplPrevを使用すれば解決なのは分かっているのですが。

マスターのサンプル154,172とか
http://www.geocities.jp/asumaroyuumaro/program/tips/Printer.html
を参考にして考えました。

procedure TForm1.Button1Click(Sender: TObject);
var
  DocMeta :TMetafile;
  PageMeta :TMetafile;
  DocMetaCanvas :TMetafileCanvas;
  PageMetaCanvas :TMetafileCanvas;
  PrintRect :TRect;
  i,j :Integer;
  sx_dpm,sy_dpm:real;
  PageTate,PageYoko:integer;  // A4の有効範囲270mm、180mm
begin
//  スクリーンの解像度
  sx_dpm := screen.PixelsPerInch / 25.4;
  sy_dpm := screen.PixelsPerInch / 25.4;   // 1mm当りのピクセル数

// A4有効印刷範囲  210 × 297 1ページのサイズ
  PageTate := round(270 * sy_dpm);   // ピクセル
  PageYoko := round(180 * sx_dpm);

//テスト用メタファイルを作成
  DocMeta  :=TMetaFile.Create;
  PageMeta :=TMetaFile.Create;
  try
    DocMeta.Width  := PageYoko;         // Screen解像度
    DocMeta.Height := PageTate * 2;     // 2ページ分
    j := (PageTate * 2) div 20;         // 印字する数字の最大値
    label1.Caption := inttostr(j);      // 102

    DocMetaCanvas := TMetafileCanvas.Create(DocMeta, 0);
    try
      for i := 1 to j do begin
        DocMetaCanvas.TextOut(50, i * 20, inttostr(i));
      end;
    finally
      DocMetaCanvas.Free;
    end;

// ここまででDocMetaに2ページにわたる文章(数字)が書き込まれた。

    PageMetaCanvas := TMetafileCanvas.Create(PageMeta, 0);  // Dest
    try
      SetMapMode(PageMetaCanvas.Handle,MM_ANISOTROPIC);
      SetWindowExtEx(PageMetaCanvas.Handle,PageYoko,PageTate,nil);
      SetViewPortExtEx(PageMetaCanvas.Handle,PageYoko,PageTate,nil); // 倍率1

//     SetWindowOrgEx(PageMetaCanvas.Handle,0,0,nil);  ←1ページ目が出力 1,2,…
      SetWindowOrgEx(PageMetaCanvas.Handle,0,PageTate,nil);  // 2ページ目 51,52,…

      PageMetaCanvas.Draw(0,0,DocMeta);

    finally
      PageMetaCanvas.Free;
    end;

// 以上でPageMetaに1ページ分だけ切り出した

// プレビュー画面
    Image2.Canvas.Draw(0,0,PageMeta);  // 原寸大で

// プリンタへの印刷
    PrintRect :=Bounds(GetDeviceCaps(Printer.Handle, PHYSICALOFFSETX),
                       GetDeviceCaps(Printer.Handle, PHYSICALOFFSETY),
                       GetDeviceCaps(Printer.Handle, HORZRES),
                       GetDeviceCaps(Printer.Handle, VERTRES));

    Printer.Title := 'MetaTest';
    Printer.BeginDoc;
    try
      Printer.Canvas.StretchDraw(PrintRect,PageMeta);
//      Printer.Canvas.Draw(0,0,PageMeta);   ←ものすごく小さく印字される
    except
      Printer.Abort;
      raise;
    end;
    Printer.EndDoc;

  finally
    DocMeta.Free;
    PageMeta.Free;
  end;

end;

大まかな処理の説明です。
1.数字1〜102を書き出したDocMetaメタファイルを作成しています。
2.マッピングでDocMetaファイルから1ページ分をPageMetaファイルに切り取ります。
3.PageMetaファイルをプレビュー用のImage1に表示
4.同時にプリンタへ出力しています。

疑問点・問題点
1.メタファイルのサイズをスクリーンの解像度に合わせたのですが問題はないでしょうか。
2.マッピングでSetWindowExtEx,SetViewPortExtEx,SetWindowOrgExが
すべてPageMetaCanvasに対して行われているのが理解できない。
DocMetaCanvasだったらなんとなく理解できますが。
3.プリンタへの印刷がPrinter.Canvas.Draw(0,0,PageMeta);では
ものすごく小さく印字される。
仕方がないのでPrinter.Canvas.StretchDrawを使うが文字が歪んでしまう。


[6554] Re:メタファイルとマッピング返信 削除
2012/12/16 (日) 00:32:37 Mr.XRAY
▼ takiさん

今,非常に眠いので,
流し読みで気が付いたところだけ.

メタファイルを作成してから,また別のメタファイルを作成している
ようなのですが.う〜ん,必要あるのかな ?

それと,マッピングですが,TplPrev では,0.1mm単位で描画するために
使っているので,既にテキストを書き込んだメタファイルを作成している
のであれば不要かと.

>3.プリンタへの印刷がPrinter.Canvas.Draw(0,0,PageMeta);では
>ものすごく小さく印字される。


これは,そういうものですね.
基本的には,StretchDraw です.

>仕方がないのでPrinter.Canvas.StretchDrawを使うが文字が歪んでしまう。

これは,最初にテキストを書き込むメタファイルの設定ではないかと
思いますが.また....
Asuyu さんのところに,いいサンプルがあるんですね.


[▼次のスレッド]
INCM/CMT
Cyclamen v3.82