TPDFlibDynamicComponentSession

ページレイアウト、ページ分割、データ型

説明

ステートフルなコンポーネントを、後のページのコンテンツを先に作ることなく、一度に1つの宛先ページへ合成します

各試行は分離されたForm XObject内のクローン上で実行され、検証済みコンテンツの配置が成功した後にのみクローンをコミットします

拡張配置は、オーバーフローを拒否するか、自然サイズのコンテンツをクリップするか、宛先スロット内に整列させながら比例縮小できます

ページネーションポリシーは、通常の分割を許すこと、最初の部分フラグメントを新しい領域へ先送りすること、何かをコミットする前にコンポーネント全体を可視のまま要求することができます

フロースペースの制約は、コンポーネントを呼び出す前に短い領域を拒否することも、最終フラグメントの後ろに次のコンポーネントのための十分な高さを確保することもできます

拒否された結果、失敗した描画呼び出し、コールバック例外は一時ページを取り除き、呼び出し元が選択したページを復元し、宛先コンテンツと現在のコンポーネント状態の両方を変更しません

アタッチされたTPDFlibインスタンスは呼び出し元所有のまま残り、セッションより長く生存する必要があります

宣言

const
  PDF_DYNAMIC_COMPONENT_ERROR = 0;
  PDF_DYNAMIC_COMPONENT_MORE = 1;
  PDF_DYNAMIC_COMPONENT_COMPLETE = 2;
  PDF_DYNAMIC_COMPONENT_RETRY = 3;

type
  TPDFlibDynamicPageContext = record
    LibraryInstance: TPDFlib;
    PageNumber: Integer;
    CompositionIndex: Integer;
    DestinationLeft: Double;
    DestinationTop: Double;
    AvailableWidth: Double;
    AvailableHeight: Double;
  end;

  TPDFlibDynamicPageResult = record
    HasContent: Boolean;
    HasMoreContent: Boolean;
    UsedWidth: Double;
    UsedHeight: Double;
  end;

  TPDFlibDynamicOverflowPolicy = (dopReject, dopClip, dopScaleDown);
  TPDFlibDynamicHorizontalAlignment = (dhaLeft, dhaCenter, dhaRight);
  TPDFlibDynamicVerticalAlignment = (dvaTop, dvaCenter, dvaBottom);
  TPDFlibDynamicPaginationPolicy = (dppAllowSplit, dppKeepTogether,
    dppRequireComplete);
  TPDFlibDynamicRetryReason = (drrNone, drrKeepTogether,
    drrRequireComplete, drrMinimumSlotHeight, drrMinimumFollowingHeight);

  TPDFlibDynamicLayoutOptions = record
    ContentWidth: Double;
    ContentHeight: Double;
    OverflowPolicy: TPDFlibDynamicOverflowPolicy;
    HorizontalAlignment: TPDFlibDynamicHorizontalAlignment;
    VerticalAlignment: TPDFlibDynamicVerticalAlignment;
    PaginationPolicy: TPDFlibDynamicPaginationPolicy;
    MinimumSlotHeight: Double;
    MinimumFollowingHeight: Double;
  end;

  TPDFlibDynamicPlacementTransform = record
    M11, M12, M21, M22, MDX, MDY: Double;
  end;

  TPDFlibDynamicPagePlacement = record
    PageNumber: Integer;
    CompositionIndex: Integer;
    Left: Double;
    Top: Double;
    Width: Double;
    Height: Double;
    HasContent: Boolean;
    HasMoreContent: Boolean;
    SourceWidth: Double;
    SourceHeight: Double;
    SlotLeft: Double;
    SlotTop: Double;
    SlotWidth: Double;
    SlotHeight: Double;
    Transform: TPDFlibDynamicPlacementTransform;
    WasClipped: Boolean;
    WasScaled: Boolean;
  end;

  TPDFlibDynamicComponent = class
  public
    function CloneComponent: TPDFlibDynamicComponent; virtual; abstract;
    function Compose(const Context: TPDFlibDynamicPageContext;
      out ComposeResult: TPDFlibDynamicPageResult): Integer; virtual; abstract;
  end;

  TPDFlibDynamicComponentSession = class
  private
    FLibrary: TPDFlib;
    FCompositionCount: Integer;
    FCompleted: Boolean;
    FKeepTogetherRetryPending: Boolean;
    FLastRetryReason: TPDFlibDynamicRetryReason;
    FLastRequiredSlotHeight: Double;
  public
    constructor Create(ALibrary: TPDFlib;
      AComponent: TPDFlibDynamicComponent);
    function AttachComponent(AComponent: TPDFlibDynamicComponent): Integer;
    function Reset: Integer;
    function CloneCurrentComponent: TPDFlibDynamicComponent;
    class function CreateLayoutOptions(ContentWidth, ContentHeight: Double;
      OverflowPolicy: TPDFlibDynamicOverflowPolicy = dopReject;
      HorizontalAlignment: TPDFlibDynamicHorizontalAlignment = dhaLeft;
      VerticalAlignment: TPDFlibDynamicVerticalAlignment = dvaTop;
      PaginationPolicy: TPDFlibDynamicPaginationPolicy = dppAllowSplit;
      MinimumSlotHeight: Double = 0;
      MinimumFollowingHeight: Double = 0):
      TPDFlibDynamicLayoutOptions; static;
    function ComposeNext(Page: Integer; Left, Top, Width, Height: Double;
      out Placement: TPDFlibDynamicPagePlacement): Integer;
    function ComposeNextLayout(Page: Integer; SlotLeft, SlotTop, SlotWidth,
      SlotHeight: Double; const Options: TPDFlibDynamicLayoutOptions;
      out Placement: TPDFlibDynamicPagePlacement): Integer;
    property LibraryInstance: TPDFlib read FLibrary;
    property CompositionCount: Integer read FCompositionCount;
    property Completed: Boolean read FCompleted;
    property KeepTogetherRetryPending: Boolean
      read FKeepTogetherRetryPending;
    property LastRetryReason: TPDFlibDynamicRetryReason read FLastRetryReason;
    property LastRequiredSlotHeight: Double read FLastRequiredSlotHeight;
  end;

コンポーネント契約

メソッド

Create呼び出し側所有のライブラリを接続し、指定されたコンポーネントを独立した初期スナップショットと現在スナップショットへクローンします
AttachComponent両方のスナップショットを呼び出し側所有コンポーネントのクローンでアトミックに置き換え、完了状態をクリアします
Reset初期スナップショットから新しい現在クローンを復元し、成功した合成カウントをリセットします
CloneCurrentComponent現在確定されているコンポーネント状態を調べるための、呼び出し側所有のクローンを返します
CreateLayoutOptions拡張配置のための、型付きの自然キャンバス、オーバーフロー、整列、改ページ、フロー空間の設定を構築します
ComposeNext1 つのページスロットを合成し、その Form XObject を検証して配置し、キャプチャハンドルを解放し、作業状態を確定します
ComposeNextLayout構成された自然キャンバス上で合成し、オーバーフローと整列のポリシーを適用し、ソース、スロット、最終変換のデータを返します

オーバーフローと配置

dopReject宛先コンテンツやコミット済みコンポーネント状態を変えずに、スロットより幅広または高さの大きいコンテンツを拒否します
dopClipスケール1を保ち、Form XObjectを呼び出す前にページクリッピングパスと宛先スロットの交差を取ります
dopScaleDown幅または高さの比率の小さい方を必要なときにだけ使い、コンテンツを決して拡大しません

配置は変換された使用矩形から解決されるため、中央揃えや末尾クリップされたコンテンツは対応する可視部分を選択します

Transformは、コンポーネントローカル座標から最終的な上から下のドキュメント座標への論理レイアウト行列[M11 M12 M21 M22 MDX MDY]を報告します

SlotLeft、SlotTop、SlotWidth、SlotHeightは、クリッピングの下で最終コンテンツ原点が外にあってでも、呼び出し元が指定した領域を保持します

ページネーションポリシー

dppAllowSplit既定の動作を保持し、コールバックがさらなるコンテンツを報告する有効なフラグメントをすべてコミットします
dppKeepTogether最初の部分的または非可視の試行に対してPDF_DYNAMIC_COMPONENT_RETRYを返し、同じ未コミットフラグメントの次の有効な試行で分割または選択されたクリッピングフォールバックを許します
dppRequireCompleteコールバックが残りコンテンツなしを報告し、完全な使用矩形がスロットに収まるか比例縮小によって可視のままになるまで、PDF_DYNAMIC_COMPONENT_RETRYを返します

リトライはForm XObjectの試行を破棄し、宛先ページ、コンポーネントスナップショット、完了フラグ、合成カウントを保持し、空のPlacementレコードを返します

KeepTogetherRetryPendingは1回限りのフォールバック状態を識別し、成功したコミット、Reset、AttachComponentの後にクリアされます

フロースペースの制約

MinimumSlotHeight宛先スロットが設定された高さより短い場合、コンポーネントのクローンや呼び出しの前にPDF_DYNAMIC_COMPONENT_RETRYを返します
MinimumFollowingHeight最終コンテンツフラグメントにのみ適用され、解決された高さに予約された後続高さを加えたものがスロットに収まることを要求します

後続高さのリトライは、以前にコミットされたフラグメントを保持したまま分離された試行を破棄するため、見出し、ラベル、短いリードインが次のコンポーネントの最初の使用可能領域と共に移動できます

LastRetryReasonはコンポーネント全体、厳密完了、最小スロット、後続スペースの各リトライを区別し、LastRequiredSlotHeightはフロースペース制約に対する既知の必要高さを報告します

最小スロットのチェックはコンポーネントのクローン作成とフォームキャプチャの前に実行されるため、繰り返し拒否される短い領域がコンポーネントコールバックや一時ページのコストを生みません

戻り値

PDF_DYNAMIC_COMPONENT_ERROR要求、コンポーネントコールバック、結果のジオメトリ、または Form の配置が失敗し、状態は何も確定されませんでした
PDF_DYNAMIC_COMPONENT_MOREコンテンツが確定され、コンポーネントは別のページスロットを要求しました
PDF_DYNAMIC_COMPONENT_COMPLETEコンポーネントが完了したか、セッションは既に完了しておりコールバックは行われませんでした
PDF_DYNAMIC_COMPONENT_RETRY選択された改ページまたはフロー空間のポリシーが、コンテンツや状態を確定せずに配置を延期しました

例

type
  TNumberedPagesComponent = class(TPDFlibDynamicComponent)
  private
    FNextPage: Integer;
    FPageCount: Integer;
  public
    constructor Create(ANextPage, APageCount: Integer);
    function CloneComponent: TPDFlibDynamicComponent; override;
    function Compose(const Context: TPDFlibDynamicPageContext;
      out ComposeResult: TPDFlibDynamicPageResult): Integer; override;
  end;

constructor TNumberedPagesComponent.Create(ANextPage, APageCount: Integer);
begin
  inherited Create;
  FNextPage := ANextPage;
  FPageCount := APageCount;
end;

function TNumberedPagesComponent.CloneComponent: TPDFlibDynamicComponent;
begin
  Result := TNumberedPagesComponent.Create(FNextPage, FPageCount);
end;

function TNumberedPagesComponent.Compose(
  const Context: TPDFlibDynamicPageContext;
  out ComposeResult: TPDFlibDynamicPageResult): Integer;
begin
  Context.LibraryInstance.DrawText(0, 0, IntToStr(FNextPage));
  Inc(FNextPage);
  ComposeResult.HasContent := True;
  ComposeResult.HasMoreContent := FNextPage <= FPageCount;
  ComposeResult.UsedWidth := Context.AvailableWidth;
  ComposeResult.UsedHeight := 24;
  Result := 1;
end;

Template := TNumberedPagesComponent.Create(1, 10);
try
  Session := TPDFlibDynamicComponentSession.Create(PDF, Template);
  try
    repeat
      Status := Session.ComposeNext(PageNumber, 36, 36, 540, 720,
        Placement);
      if Status = PDF_DYNAMIC_COMPONENT_MORE then
        PageNumber := PDF.NewPage;
    until Status <> PDF_DYNAMIC_COMPONENT_MORE;
  finally
    Session.Free;
  end;
finally
  Template.Free;
end;

関連項目

BeginFormXObject, ReleaseCapturedPage, ApplyRepeatedPageFragment