技術記事

PDFium Component: Delphi での annotation review UI

Delphi/C++Builder には PDFium VCL Component のワークフローを、Lazarus/FPC には PDFium LCL Component のワークフローを組み込み、表示、レンダリング、フォーム、印刷、プリフライトレポート、標準対応の検証をソースコード付きコンポーネントで実装できます。

この記事は teams adding review, markup, approval, or quality-control panels to a Delphi PDF viewer 向けです。annotation review UI を単なるコンポーネント呼び出しではなく、本番向けのドキュメントエンジニアリングとして扱います。

実務上のリスクは annotations are easy to display but hard to trust when page rotation, authorship, replies, hidden states, or coordinate conversions are not handled consistently です。そのため、明確な契約、観測可能な診断、実際の顧客ファイルに近い回帰サンプルが必要です。

アーキテクチャ上の判断

Separate review state from page rendering. which annotation types can be viewed, filtered, replied to, exported, or locked / author identity, status labels, and whether review data is stored in the PDF

  • which annotation types can be viewed, filtered, replied to, exported, or locked
  • author identity, status labels, and whether review data is stored in the PDF
  • coordinate conversion for rotation, zoom, crop boxes, and high-DPI displays
  • read-only mode for signed, protected, or externally governed documents

実装フロー

Index annotations before showing review actions. The order below keeps the workflow reviewable for Delphi and C++Builder teams.

  1. load annotation metadata into a review index before painting page overlays
  2. normalize page coordinates and keep a stable reference for every annotation
  3. apply filters by author, status, type, page, and date without re-parsing pages
  4. tie selection in the review list to viewport navigation and highlight behavior
  5. export review summaries with enough context for non-viewer workflows

検証エビデンス

Review evidence that supports collaboration. Keep these fields with the output or support record.

  • annotation type, author, page, bounds, status, and reply count
  • coordinate transform used for the current zoom, rotation, and crop box
  • permission decision when a user attempts to edit a locked or signed document
  • exported review summary with stable page references

Coordinates and intent matter

A professional review UI treats annotations as structured data with authors, dates, page locations, appearance, replies, status, and permissions. The canvas view is only one presentation of that model.

Customer-visible behavior

Users do not see internal call order. They see whether the file opens, validates, prints, edits, imports, or gets rejected. The workflow should translate annotation review UI results into states users can act on.

  • load annotation metadata into a review index before painting page overlays
  • normalize page coordinates and keep a stable reference for every annotation
  • apply filters by author, status, type, page, and date without re-parsing pages
  • rotated pages can make highlights appear detached from the original text
  • popup annotations and replies may be missed when only visible marks are scanned

annotation review UI に関する技術レビューの注意点

これらのレビュー項目を使って、機能がデモ段階を超え、リリース、サポート、顧客エスカレーションの場で説明できることを確認します

  • 判断: which annotation types can be viewed, filtered, replied to, exported, or locked. 実装上の焦点: normalize page coordinates and keep a stable reference for every annotation. 受け入れ証拠: permission decision when a user attempts to edit a locked or signed document. 回帰の引き金: annotations on cropped pages need coordinates tied to the intended page box
  • 判断: author identity, status labels, and whether review data is stored in the PDF. 実装上の焦点: apply filters by author, status, type, page, and date without re-parsing pages. 受け入れ証拠: exported review summary with stable page references. 回帰の引き金: rotated pages can make highlights appear detached from the original text
  • 判断: coordinate conversion for rotation, zoom, crop boxes, and high-DPI displays. 実装上の焦点: tie selection in the review list to viewport navigation and highlight behavior. 受け入れ証拠: annotation type, author, page, bounds, status, and reply count. 回帰の引き金: popup annotations and replies may be missed when only visible marks are scanned
  • 判断: read-only mode for signed, protected, or externally governed documents. 実装上の焦点: export review summaries with enough context for non-viewer workflows. 受け入れ証拠: coordinate transform used for the current zoom, rotation, and crop box. 回帰の引き金: read-only review must still allow selection, navigation, filtering, and export
  • 判断: which annotation types can be viewed, filtered, replied to, exported, or locked. 実装上の焦点: load annotation metadata into a review index before painting page overlays. 受け入れ証拠: permission decision when a user attempts to edit a locked or signed document. 回帰の引き金: annotations on cropped pages need coordinates tied to the intended page box
  • 判断: author identity, status labels, and whether review data is stored in the PDF. 実装上の焦点: normalize page coordinates and keep a stable reference for every annotation. 受け入れ証拠: exported review summary with stable page references. 回帰の引き金: rotated pages can make highlights appear detached from the original text
  • 判断: coordinate conversion for rotation, zoom, crop boxes, and high-DPI displays. 実装上の焦点: apply filters by author, status, type, page, and date without re-parsing pages. 受け入れ証拠: annotation type, author, page, bounds, status, and reply count. 回帰の引き金: popup annotations and replies may be missed when only visible marks are scanned

境界ケース

  • rotated pages can make highlights appear detached from the original text
  • popup annotations and replies may be missed when only visible marks are scanned
  • read-only review must still allow selection, navigation, filtering, and export
  • annotations on cropped pages need coordinates tied to the intended page box

Delphi / C++Builder の補足

PDFium Component should sit behind a small service boundary that receives files, streams, profiles, and credentials, then returns output paths, warnings, metrics, and validation status. 重要な用語には annotation, markup, reply, page bounds, rotation, review status.

Delphi コード例

次の Delphi スケッチは、このテーマに対する実用的なサービス境界を示します。ポリシー確認、ログ記録、検証を製品呼び出しの狭い部分の外側に置くと、ワークフローをテストしやすくなります。

procedure TReviewForm.LoadAnnotationQueue(const FileName: string);
var
  PageNo: Integer;
begin
  PdfView.LoadFromFile(FileName);
  FQueue.Clear;
  for PageNo := 1 to PdfView.PageCount do
    AddPageAnnotationsToQueue(PdfView, PageNo, FQueue);
  FQueue.SortByAuthorAndDate;
  ShowNextReviewItem;
end;

本番チェックリスト

  • ワークフローは、空のファイル、通常の顧客ファイル、最悪ケースのファイルで実行します
  • 生成された PDF は、対象のビューアー、検証ツール、プリンター、または downstream アプリケーションで開きます
  • 製品バージョン、プロファイルバージョン、入力ハッシュ、出力パス、経過時間、警告数を記録します
  • パスワード、証明書、一時ファイル、顧客データは明確な保持ルールの下で管理します
  • 顧客ファイルが新しい境界ケースを示したら、回帰用ドキュメントを追加します

製品ドキュメント

PDFium Component

追加のコード例

A := Pdf.Annotation[Item.Index];
A.HasColor := True;
A.Color := $0000B0FF;       // amber
A.ColorAlpha := 160;
try
  Pdf.Annotation[Item.Index] := A;
except
  on EPdfError do
  begin
    // The annotation owns a pre-rendered /AP stream; the dictionary
    // color alone cannot change what viewers paint
    Item.AppearanceLocked := True;
    StatusBar.SimpleText := 'Color is fixed by the annotation appearance';
  end;
end;
Pdf.PageNumber := Item.PageNo;
Pdf.DeleteAnnotation(Item.Index);   // raises EPdfError on failure
Bmp := Pdf.RenderPage(0, 0, ViewWidth, ViewHeight, ro0, [reAnnotations]);
try
  PaintPageBitmap(Bmp);
finally
  Bmp.Free;  // RenderPage hands bitmap ownership to the caller
end;
RebuildPageEntries(Item.PageNo);  // indices after Item.Index shifted