losLab PDF Library は、Delphi/C++Builder チーム向けにソース提供の PDF エンジンを提供します。デスクトップ、サーバー、DLL、ActiveX、Dylib ワークフローで使え、PDF/A・PDF/UA チェック、PAdES 署名、複数レンダラーを外部 PDF サービスなしで利用できます。
この記事は teams building print-preview, hard-copy approval, label, or controlled-output workflows Delphi での 向けです。print preview and device-context output を単なるコンポーネント呼び出しではなく、本番向けのドキュメントエンジニアリングとして扱います。
実務上のリスクは print output can differ from preview when device margins, scaling, rotation, duplex settings, and driver behavior are not modeled explicitly です。そのため、明確な契約、観測可能な診断、実際の顧客ファイルに近い回帰サンプルが必要です。
アーキテクチャ上の判断
Separate PDF page geometry from printer geometry. fit, actual size, shrink-only, center, rotation, and crop rules / paper selection, printable margins, tray, duplex, and color mode policy
- fit, actual size, shrink-only, center, rotation, and crop rules
- paper selection, printable margins, tray, duplex, and color mode policy
- preview fidelity requirements compared with printer-driver output
- whether annotations, form fields, watermarks, and backgrounds are printed
実装フロー
Preview with the same print contract used for output. The order below keeps the workflow reviewable for Delphi and C++Builder teams.
- read page size and rotation before asking the printer for device capabilities
- compute the target rectangle from paper, printable area, and scaling policy
- render preview using the same geometry contract as the print job
- record driver and device context details when output is generated
- test high-value documents on the printer families customers actually use
検証エビデンス
Print evidence that helps support reproduce issues. Keep these fields with the output or support record.
- printer name, driver version, paper size, printable area, scaling, and rotation
- PDF page box, page number, rendered rectangle, and DPI
- annotation and form-field print policy
- operator selection and print result or driver error
A device context is a target, not a neutral canvas
A production print workflow should know the PDF page box, target paper size, printable area, scaling rule, rotation decision, and driver settings before rendering to a device context.
Operational metrics to watch
The first release should expose enough metrics to prove the workflow is healthy under real files, not only under curated samples.
- count and rate for printer name, driver version, paper size, printable area, scaling, and rotation
- warning trend for printer drivers can change printable margins after paper selection
- latency of the stage that must read page size and rotation before asking the printer for device capabilities
- profile usage for fit, actual size, shrink-only, center, rotation, and crop rules
print preview and device-context output に関する技術レビューの注意点
これらのレビュー項目を使って、機能がデモ段階を超え、リリース、サポート、顧客エスカレーションの場で説明できることを確認します
- 判断: fit, actual size, shrink-only, center, rotation, and crop rules. 実装上の焦点: compute the target rectangle from paper, printable area, and scaling policy. 受け入れ証拠: annotation and form-field print policy. 回帰の引き金: preview should disclose when it cannot match a driver-specific feature
- 判断: paper selection, printable margins, tray, duplex, and color mode policy. 実装上の焦点: render preview using the same geometry contract as the print job. 受け入れ証拠: operator selection and print result or driver error. 回帰の引き金: printer drivers can change printable margins after paper selection
- 判断: preview fidelity requirements compared with printer-driver output. 実装上の焦点: record driver and device context details when output is generated. 受け入れ証拠: printer name, driver version, paper size, printable area, scaling, and rotation. 回帰の引き金: landscape pages need a clear auto-rotation policy
- 判断: whether annotations, form fields, watermarks, and backgrounds are printed. 実装上の焦点: test high-value documents on the printer families customers actually use. 受け入れ証拠: PDF page box, page number, rendered rectangle, and DPI. 回帰の引き金: duplex output can expose odd-page and blank-page assumptions
- 判断: fit, actual size, shrink-only, center, rotation, and crop rules. 実装上の焦点: read page size and rotation before asking the printer for device capabilities. 受け入れ証拠: annotation and form-field print policy. 回帰の引き金: preview should disclose when it cannot match a driver-specific feature
境界ケース
- printer drivers can change printable margins after paper selection
- landscape pages need a clear auto-rotation policy
- duplex output can expose odd-page and blank-page assumptions
- preview should disclose when it cannot match a driver-specific feature
Delphi / C++Builder の補足
PDFlibPas should sit behind a small service boundary that receives files, streams, profiles, and credentials, then returns output paths, warnings, metrics, and validation status. 重要な用語には device context, print preview, DPI, printable area, scaling, duplex.
Delphi コード例
次の Delphi スケッチは、このテーマに対する実用的なサービス境界を示します。ポリシー確認、ログ記録、検証を製品呼び出しの狭い部分の外側に置くと、ワークフローをテストしやすくなります。
procedure PaintPreviewPage(Canvas: TCanvas; const FileName: string; PageRef: Integer; Dpi: Double);
var
Pdf: TPDFlib;
FileHandle: Integer;
begin
Pdf := TPDFlib.Create;
try
FileHandle := Pdf.DAOpenFileReadOnly(FileName, '');
try
Pdf.DARenderPageToDC(FileHandle, PageRef, Dpi, Canvas.Handle);
DrawPreviewOverlay(Canvas, PageRef, Dpi);
finally
Pdf.DACloseFile(FileHandle);
end;
finally
Pdf.Free;
end;
end;
本番チェックリスト
- ワークフローは、空のファイル、通常の顧客ファイル、最悪ケースのファイルで実行します
- 生成された PDF は、対象のビューアー、検証ツール、プリンター、または downstream アプリケーションで開きます
- 製品バージョン、プロファイルバージョン、入力ハッシュ、出力パス、経過時間、警告数を記録します
- パスワード、証明書、一時ファイル、顧客データは明確な保持ルールの下で管理します
- 顧客ファイルが新しい境界ケースを示したら、回帰用ドキュメントを追加します
製品ドキュメント
追加のコード例
var
Pdf: TPDFlib;
Virt: WideString;
Opt: Integer;
begin
Pdf := TPDFlib.Create;
try
if Pdf.LoadFromFile('report.pdf', '') <> 1 then
raise Exception.Create('load failed');
Virt := Pdf.NewCustomPrinter(Pdf.GetDefaultPrinterName);
Pdf.SetupPrinter(Virt, 1, 9); // setting 1 = paper, DMPAPER_A4
Pdf.SetupPrinter(Virt, 11, 1); // setting 11 = orientation, 1 = portrait
Opt := Pdf.PrintOptions(1, 1, 'Monthly Report'); // fit to paper, auto-rotate + center
Pdf.PrintDocument(Virt, 1, Pdf.PageCount, Opt);
finally
Pdf.Free;
end;
end;procedure ShowPrinterTruePreview(Pdf: TPDFlib; const Virt: WideString; Opt: Integer);
var
Data: AnsiString;
Strm: TMemoryStream;
Bmp: TBitmap;
begin
Data := Pdf.GetPrintPreviewBitmapToString(Virt, 1, Opt, 1200, 0);
Strm := TMemoryStream.Create;
try
Strm.WriteBuffer(PAnsiChar(Data)^, Length(Data));
Strm.Position := 0;
Bmp := TBitmap.Create;
try
Bmp.LoadFromStream(Strm);
PreviewImage.Picture.Assign(Bmp);
finally
Bmp.Free;
end;
finally
Strm.Free;
end;
end;