TPDFlibDynamicComponentSession

Sideoppsett, paginering, datatyper

Beskrivelse

Komponerer en tilstandsfull komponent én måleside om gangen uten å konstruere innhold for senere sider på forhånd

Hvert forsøk kjører på en klone inne i et isolert Form XObject og commiter kloneen bare etter at validert innhold er plassert

Utvidet plassering kan avvise overflyt, klippe innhold i naturlig størrelse eller skalere det ned proporsjonalt mens det justeres innenfor en målplass

Pagineringspolicy kan tillate normal splitting, utsette det første delvise fragmentet til en fersk region eller kreve at hele komponenten forblir synlig før noe commites

Flytrom-begrensninger kan avvise en kort region før komponenten invokeres, eller reservere nok høyde etter dens siste fragment til en følgende komponent

Et avvist resultat, mislykket tegnekall eller callback-unntak fjerner den midlertidige siden, gjenoppretter siden valgt av kalleren og lar både målinnhold og nåværende komponenttilstand være uendret

Den tilkoblede TPDFlib-instansen forblir eid av kalleren og må leve lenger enn økten

Deklarasjon

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;

Komponentkontrakt

Metoder

CreateFester et bibliotek eid av kalleren og kloner den oppgitte komponenten inn i uavhengige opprinnelige og gjeldende øyeblikksbilder
AttachComponentErstatter atomært begge øyeblikksbildene med kloner av en komponent eid av kalleren og tømmer fullførelsestilstanden
ResetGjenoppretter en ny gjeldende klone fra det opprinnelige øyeblikksbildet og nullstiller antallet vellykkede sammensetninger
CloneCurrentComponentReturnerer en klone eid av kalleren for å inspisere gjeldende bekreftet komponenttilstand
CreateLayoutOptionsBygger typede innstillinger for naturlig panel, overflyt, justering, sideinndeling og flytrom for utvidet plassering
ComposeNextSammensetter én sidespor, validerer og plasserer dets Form XObject, frigir fangsthåndtaket og bekrefter arbeidstilstanden
ComposeNextLayoutSammensetter på det konfigurerte naturlige panelet, anvender overflyt- og justeringspolitikk og returnerer kilde-, spor- og endelige transformdata

Overflyt og plassering

dopRejectAvviser innhold bredere eller høyere enn plassen uten å endre målinnhold eller commitet komponenttilstand
dopClipBeholder skala 1 og gjennomsnitter sideklippepathen med målplassen før Form XObject-en invokeres
dopScaleDownBruker den mindre bredde- eller høydeforholdet bare når det trengs og forstørrer aldri innhold

Justering løses fra det transformerte brukte rektangelet, så sentrert eller etterfølgende beskåret innhold velger den tilsvarende synlige delen

Transform rapporterer den logiske layoutrmatrisen [M11 M12 M21 M22 MDX MDY] fra komponent-lokale koordinater til de endelige top-down dokumentkoordinatene

SlotLeft, SlotTop, SlotWidth og SlotHeight bevarer regionen levert av kalleren selv når det endelige innholdsorigo ligger utenfor under klipping

Pagineringsregler

dppAllowSplitBevarer standardatferden og commiter ethvert gyldig fragment hvis callback rapporterer mer innhold
dppKeepTogetherReturnerer PDF_DYNAMIC_COMPONENT_RETRY for det første delvise eller usynlige utkastet, og tillater så splitting eller den valgte klippe-fallbacken ved neste gyldige forsøk for samme ucommitete fragment
dppRequireCompleteReturnerer PDF_DYNAMIC_COMPONENT_RETRY til callback-en rapporterer intet gjenværende innhold, og det fullstendige brukte rektangelet enten får plass i plassen eller forblir synlig gjennom proporsjonal nedskalering

Et forsøk på nytt forkaster Form XObject-utkastet, bevarer målsiden, komponent-øyeblikksbildet, fullføringsflagget og sammensetningstellingen, og returnerer en tom Placement-post

KeepTogetherRetryPending identifiserer engangs-fallback-tilstanden og ryddes etter en vellykket commit, Reset eller AttachComponent

Begrensninger for flytplass

MinimumSlotHeightReturnerer PDF_DYNAMIC_COMPONENT_RETRY før komponenten kloner eller invokeres når målplassen er kortere enn den konfigurerte høyden
MinimumFollowingHeightGjelder bare et endelig innholdsfragment og krever at dets løste høyde pluss den reserverte følgehøyden får plass i plassen

Et forsøk på nytt med følgehøyde forkaster det isolerte utkastet mens tidligere commitete fragmenter bevares, slik at en overskrift, etikett eller kort innledning kan flytte seg med den første brukbare regionen til neste komponent

LastRetryReason skiller nye forsøk for hel komponent, streng fullføring, minimumsplass og påfølgende plass, mens LastRequiredSlotHeight rapporterer den kjente påkrevde høyden for flytrom-begrensninger

Minimumsplass-kontrollen kjører før komponentkloning og Form-fangst, så gjentatte avviste korte regioner medfører ingen komponent-callback- eller midlertidig side-kostnad

Returverdier

PDF_DYNAMIC_COMPONENT_ERRORForespørselen, komponenttilbakeringingen, resultatgeometrien eller Form-plasseringen mislyktes, og ingen tilstand ble bekreftet
PDF_DYNAMIC_COMPONENT_MOREInnhold ble bekreftet, og komponenten ba om en ny sidespor
PDF_DYNAMIC_COMPONENT_COMPLETEKomponenten fullførte, eller økten var allerede fullført, og ingen tilbakeringing ble gjort
PDF_DYNAMIC_COMPONENT_RETRYDen valgte sideinndelings- eller flytromspolitikken utsatte plassering uten å bekrefte innhold eller tilstand

Eksempel

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;

Se også

BeginFormXObject, ReleaseCapturedPage, ApplyRepeatedPageFragment