TPDFlibDynamicComponentSession

Layout di pagina, paginazione, tipi di dati

Descrizione

Compone un componente con stato una pagina di destinazione alla volta senza costruire in anticipo il contenuto delle pagine successive

Ogni tentativo gira su un clone dentro un Form XObject isolato e ne conferma il clone solo dopo che il contenuto validato è stato collocato con successo

Il collocamento esteso può rifiutare l'overflow, ritagliare il contenuto a dimensione naturale o ridurlo proporzionalmente allineandolo in uno slot di destinazione

La politica di paginazione può permettere la divisione normale, rimandare il primo frammento parziale a una regione fresca o richiedere che l'intero componente resti visibile prima di confermare qualcosa

I vincoli di flow-space possono rifiutare una regione corta prima di invocare il componente o riservare abbastanza altezza dopo il suo ultimo frammento per un componente seguente

Un risultato rifiutato, una chiamata di disegno fallita o un'eccezione di callback rimuove la pagina temporanea, ripristina la pagina selezionata dal chiamante e lascia sia il contenuto di destinazione sia lo stato del componente corrente invariati

TPDFlib collegata resta di proprietà del chiamante e deve sopravvivere alla sessione

Dichiarazione

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;

Contratto del componente

Metodi

CreateCollega una libreria di proprietà del chiamante e clona il componente fornito in istantanee iniziale e corrente indipendenti
AttachComponentSostituisce atomicamente entrambe le istantanee con cloni di un componente di proprietà del chiamante e cancella lo stato di completamento
ResetRipristina un nuovo clone corrente dall'istantanea iniziale e azzera il conteggio delle composizioni riuscite
CloneCurrentComponentRestituisce un clone di proprietà del chiamante per esaminare lo stato corrente confermato del componente
CreateLayoutOptionsCostruisce impostazioni tipizzate di tela naturale, overflow, allineamento, paginazione e spazio di flusso per il posizionamento esteso
ComposeNextCompone uno slot di pagina, valida e posiziona il suo Form XObject, rilascia l'handle di acquisizione e conferma lo stato di lavoro
ComposeNextLayoutCompone sulla tela naturale configurata, applica la policy di overflow e allineamento e restituisce dati di sorgente, slot e trasformazione finale

Overflow e posizionamento

dopRejectRifiuta contenuto più largo o più alto dello slot senza cambiare il contenuto di destinazione né lo stato confermato del componente
dopClipMantiene scala 1 e interseca il percorso di ritaglio della pagina con lo slot di destinazione prima di invocare il Form XObject
dopScaleDownUsa il rapporto minore tra larghezza o altezza solo quando necessario e non ingrandisce mai il contenuto

L'allineamento è risolto dal rettangolo usato trasformato, quindi il contenuto centrato o finale ritagliato seleziona la porzione visibile corrispondente

Transform[M11 M12 M21 M22 MDX MDY]

SlotLeft riporta la matrice di layout logica SlotTop dalle coordinate locali del componente alle coordinate finali del documento dall'alto verso il basso SlotWidth, SlotHeight,

Criteri di paginazione

dppAllowSplitPreserva il comportamento predefinito e conferma qualunque frammento valido il cui callback riporta altro contenuto
dppKeepTogetherRestituisce PDF_DYNAMIC_COMPONENT_RETRY per il primo tentativo parziale o non visibile, poi consente lo spezzamento oppure il fallback di ritaglio selezionato al successivo tentativo valido per lo stesso frammento non confermato
dppRequireCompleteRestituisce PDF_DYNAMIC_COMPONENT_RETRY finché il callback non riporta assenza di contenuto residuo e l'intero rettangolo usato entra nello slot oppure resta visibile attraverso la riduzione proporzionale

Placement

KeepTogetherRetryPending vuoto Reset identifica lo stato di fallback a uso singolo e viene cancellato dopo un commit riuscito, AttachComponent oppure

Vincoli di flow-space

MinimumSlotHeightRestituisce PDF_DYNAMIC_COMPONENT_RETRY prima di clonare o invocare il componente quando lo slot di destinazione è più corto dell'altezza configurata
MinimumFollowingHeightSi applica solo a un frammento di contenuto finale e richiede che la sua altezza risolta più l'altezza riservata successiva entrino nello slot

Un tentativo ripetuto per altezza successiva scarta la prova isolata conservando i frammenti confermati precedenti, permettendo a un'intestazione, a un'etichetta o a un breve incipit di spostarsi insieme alla prima regione utilizzabile del componente successivo

LastRetryReason distingue i tentativi di componente intero, di completamento rigoroso, di slot minimo e di spazio successivo, mentre LastRequiredSlotHeight riporta l'altezza richiesta nota per i vincoli di flow-space

Il controllo di slot minimo gira prima della clonazione del componente e dell'acquisizione del Form, così le regioni corte rifiutate ripetutamente non sostengono costi di callback del componente né di pagina temporanea

Valori restituiti

PDF_DYNAMIC_COMPONENT_ERRORLa richiesta, il callback del componente, la geometria del risultato o il posizionamento del Form è fallito e nessuno stato è stato confermato
PDF_DYNAMIC_COMPONENT_MOREIl contenuto è stato confermato e il componente ha richiesto un altro slot di pagina
PDF_DYNAMIC_COMPONENT_COMPLETEIl componente ha completato, oppure la sessione era già completa e nessun callback è stato effettuato
PDF_DYNAMIC_COMPONENT_RETRYLa policy di paginazione o di spazio di flusso selezionata ha rinviato il posizionamento senza confermare contenuto o stato

Esempio

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;

Vedere anche

BeginFormXObject, ReleaseCapturedPage, ApplyRepeatedPageFragment