기술 문서

PDFlibPas: Delphi에서 print preview and device-context output

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.

  1. read page size and rotation before asking the printer for device capabilities
  2. compute the target rectangle from paper, printable area, and scaling policy
  3. render preview using the same geometry contract as the print job
  4. record driver and device context details when output is generated
  5. 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 애플리케이션에서 엽니다
  • 제품 버전, 프로필 버전, 입력 해시, 출력 경로, 경과 시간, 경고 수를 기록합니다
  • 암호, 인증서, 임시 파일, 고객 데이터는 명확한 보존 규칙에 따라 관리합니다
  • 고객 파일이 새로운 경계 사례를 드러내면 회귀 문서를 추가합니다

제품 문서

PDFlibPas

추가 코드 예제

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;