TPDFlibDynamicComponentSession

Sidlayout, sidbrytning, datatyper

Beskrivning

Komponerar en tillståndsbaserad komponent en målsida i taget utan att i förväg bygga innehåll för senare sidor

Varje försök körs på en klon inuti en isolerad Form XObject och verkställer klonen först efter att validerat innehåll har placerats framgångsrikt

Utökad placering kan avvisa överlopp, klippa innehåll i naturlig storlek eller skala ner det proportionellt medan det justeras inom en målplats

Sidbrytningspolicyn kan tillåta normal uppdelning, skjuta upp det första partiella fragmentet till en ny region eller kräva att hela komponenten förblir synlig innan något verkställs

Begränsningar i flödesutrymme kan avvisa en kort region innan komponenten anropas eller reservera tillräcklig höjd efter dess sista fragment för en efterföljande komponent

Ett avvisat resultat, ett misslyckat ritningsanrop eller ett återanropsundantag tar bort den tillfälliga sidan, återställer den anroparvalda sidan och lämnar både målinnehåll och aktuellt komponenttillstånd oförändrade

Den koppladeTPDFlib-instansen förblir anroparägd och måste överleva sessionen

Deklaration

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

CreateKopplar en anroparägd biblioteksinstans och klonar den tillhandahållna komponenten till oberoende ursprungliga och aktuella ögonblicksbilder
AttachComponentErsätter atomärt båda ögonblicksbilderna med kloner av en anroparägd komponent och rensar fullbordandetillståndet
ResetÅterställer en ny aktuell klon från den ursprungliga ögonblicksbilden och nollställer räknaren för lyckade kompositioner
CloneCurrentComponentReturnerar en anroparägd klon för att granska aktuellt verkstäld komponenttillstånd
CreateLayoutOptionsBygger typade inställningar för naturlig canvas, överlopp, justering, sidbrytning och flödesutrymme för utökad placering
ComposeNextKomponerar en sidplats, validerar och placerar dess Form XObject, släpper infångningshandtaget och verkställer arbetsläget
ComposeNextLayoutKomponerar på den konfigurerade naturliga canvasen, tillämpar överlopps- och justeringspolicy och returnerar käll-, plats- och sluttransformdata

Överlopp och placering

dopRejectAvvisar innehåll som är bredare eller högre än platsen utan att ändra målinnehåll eller verkstäldt komponenttillstånd
dopClipBehåller skala 1 och snittar sidklippvägen med målplatsen innan Form XObject anropas
dopScaleDownAnvänder den mindre bredds- eller höjdskalfaktorn endast vid behov och förstorar aldrig innehåll

Justeringen bestäms från den transformerade använda rektangeln, så att centrerat eller avslutande klippt innehåll väljer motsvarande synliga del

Transform[M11 M12 M21 M22 MDX MDY]

SlotLeft rapporterar den logiska layoutmatrisen SlotTop från komponentlokala koordinater till de slutliga topp-ned dokumentkoordinaterna SlotWidth, SlotHeight,

Sidbrytningsprinciper

dppAllowSplitBevarar standardbeteendet och verkställer varje giltigt fragment vars återanrop rapporterar mer innehåll
dppKeepTogetherReturnerar PDF_DYNAMIC_COMPONENT_RETRY för det första partiella eller icke synliga försöket och tillåter sedan uppdelning eller den valda klippreserven vid nästa giltiga försök för samma icke verkstälda fragment
dppRequireCompleteReturnerar PDF_DYNAMIC_COMPONENT_RETRY tills återanropet rapporterar inget återstående innehåll och hela den använda rektangeln antingen ryms i platsen eller förblir synlig genom proportionell nedskalning

Placement

KeepTogetherRetryPending-post Reset identifierar engångsreservtillståndet och rensas efter en lyckad verkställning, AttachComponent eller

Begränsningar för flödesutrymme

MinimumSlotHeightReturnerar PDF_DYNAMIC_COMPONENT_RETRY innan komponenten klonas eller anropas när målplatsen är kortare än den konfigurerade höjden
MinimumFollowingHeightGäller endast ett slutligt innehållsfragment och kräver att dess upplösta höjd plus den reserverade följhöjden ryms i platsen

Ett försök igen för följhöjd kastar det isolerade provet medan tidigare verkstälda fragment bevaras, vilket gör att en rubrik, etikett eller kort inledning kan flytta med den första användbara regionen hos nästa komponent

LastRetryReason skiljer försök igen för hel komponent, strikt fullbordan, minsta plats och följutrymme, medan LastRequiredSlotHeight rapporterar den kända krävda höjden för flödesutrymmesbegränsningar

Kontrollen av minsta plats körs före komponentkloning och Form-infångning, så upprepade avvisade korta regioner medför ingen komponentåteranrops- eller tillfällig sidokostnad

Returvärden

PDF_DYNAMIC_COMPONENT_ERRORBegäran, komponentåteranropet, resultatgeometrin eller Form-placeringen misslyckades och inget tillstånd verkstäldes
PDF_DYNAMIC_COMPONENT_MOREInnehåll verkstäldes och komponenten begärde en annan sidplats
PDF_DYNAMIC_COMPONENT_COMPLETEKomponenten fullbordades, eller så var sessionen redan fullbordad och inget återanrop gjordes
PDF_DYNAMIC_COMPONENT_RETRYDen valda sidbrytnings- eller flödesutrymmespolicyn sköt upp placeringen utan att verkställa innehåll eller tillstånd

Exempel

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 även

BeginFormXObject, ReleaseCapturedPage, ApplyRepeatedPageFragment