TPDFlibDynamicComponentSession
Rozvržení stránek, stránkování, datové typy
Popis
Skládá stavovou komponentu vždy na jednu cílovou stránku, aniž by dopředu stavěla obsah pozdějších stránek
Každý pokus běží na klonu uvnitř izolovaného Form XObject a potvrzuje klon, jen když je ověřený obsah úspěšně umístěn
Rozšířené umístění může odmítnout přetečení, oříznout obsah v přirozené velikosti nebo jej proporcionálně zmenšit, zatímco jej zarovnává uvnitř cílového slotu
Politika stránkování může dovolit normální rozdělení, odložit první částečný fragment do čerstvé oblasti nebo vyžadovat, aby celá komponenta zůstala viditelná, než se cokoli potvrdí
Omezení prostoru toku mohou odmítnout krátkou oblast před vyvoláním komponenty, nebo po jejím posledním fragmentu rezervovat dostatečnou výšku pro následující komponentu
Odmítnutý výsledek, neúspěšné kreslicí volání nebo výjimka zpětného volání odstraní dočasnou stránku, obnoví stránku vybranou volajícím a ponechá obsah cíle i aktuální stav komponenty beze změny
Připojená instance TPDFlib zůstává ve vlastnictví volajícího a musí přežít relaci
Deklarace
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;
Kontrakt komponenty
CloneComponentvrací volajícímu nezávislou kopii veškerého měnitelného stavu paginaceComposekreslí přesContext.LibraryInstancev lokálních souřadnicích Formu, jehož dostupná velikost jeAvailableWidthkrátAvailableHeightPageNumberidentifikuje cílovou stránku, i když knihovna po dobu běhu callbacku vybírá izolovanou dočasnou stránku- Callback může používat kreslicí a obsahová API, ale nesmí měnit dokumenty, stránky ani vnořené kreslicí kontejnery
- Výsledky s obsahem vyžadují konečné kladné hodnoty
UsedWidthaUsedHeightuvnitř plátna obsahu - Využitý obdélník začíná v lokální souřadnici nula a má ohraničit veškerý viditelný obsah komponenty
- Výsledek bez obsahu je platný jen tehdy, když je
HasMoreContentFalsea obě využité rozměry jsou nulové - Nulový návrat zamítne pokus; vyvolané výjimky se šíří poté, co se přechodný stav uklidí
Metody
| Create | Připojí knihovnu vlastněnou volajícím a naklonuje dodanou komponentu do nezávislých snímků počátečního a aktuálního stavu |
|---|---|
| AttachComponent | Atomicky nahradí oba snímky klony komponenty vlastněné volajícím a vymaže stav dokončení |
| Reset | Obnoví nový aktuální klon z počátečního snímku a vynuluje počet úspěšných kompozic |
| CloneCurrentComponent | Vrací klon ve vlastnictví volajícího k prohlédnutí aktuálního potvrzeného stavu komponenty |
| CreateLayoutOptions | Sestaví typovaná nastavení přirozeného plátna, přetečení, zarovnání, paginace a prostoru toku pro rozšířené umístění |
| ComposeNext | Skládá jeden slot stránky, ověří a umístí jeho Form XObject, uvolní handle zachycení a potvrdí pracovní stav |
| ComposeNextLayout | Skládá na nakonfigurovaném přirozeném plátně, aplikuje politiku přetečení a zarovnání a vrací data zdroje, slotu i finální transformace |
Přetečení a umístění
dopReject | Odmítá obsah širší nebo vyšší než slot, aniž by měnila obsah cíle nebo potvrzený stav komponenty |
|---|---|
dopClip | Drží měřítko 1 a protnout klipovou cestu stránky s cílovým slotem, než vyvolá Form XObject |
dopScaleDown | Menší poměr šířky či výšky používá jen tehdy, když je to potřeba, a nikdy nezvětšuje obsah |
Zarovnání se rozliší z transformovaného používaného obdélníku, takže vycentrovaný nebo na konci oříznutý obsah si vybere odpovídající viditelnou část
Transform hlásí logickou matici rozvržení [M11 M12 M21 M22 MDX MDY] z komponentou lokálních souřadnic na finální souřadnice dokumentu shora dolů
SlotLeft, SlotTop, SlotWidth a SlotHeight zachovávají oblast dodanou volajícím, i když původ finálního obsahu leží pod ořezem mimo ni
Zásady stránkování
dppAllowSplit | Zachovává výchozí chování a potvrdí jakýkoli platný fragment, jehož zpětné volání hlásí další obsah |
|---|---|
dppKeepTogether | Vrací PDF_DYNAMIC_COMPONENT_RETRY pro první částečnou či neviditelnou zkoušku, a pak dovolí rozdělení nebo vybranou ořezovou náhradu při dalším platném pokusu pro tentýž nepotvrzený fragment |
dppRequireComplete | Vrací PDF_DYNAMIC_COMPONENT_RETRY, dokud zpětné volání nehlásí žádný zbývající obsah a kompletní použitý obdélník se buď vejde do slotu, nebo zůstane viditelný proporcionalním zmenšením |
Opakování zahodí zkušební Form XObject, zachová cílovou stránku, snímek komponenty, příznak dokončení a počet skladeb a vrátí prázdný záznam Placement
KeepTogetherRetryPending identifikuje stav jednorázové náhrady a maže se po úspěšném potvrzení, Reset nebo AttachComponent
Omezení prostoru toku
MinimumSlotHeight | Vrací PDF_DYNAMIC_COMPONENT_RETRY před klonováním nebo vyvoláním komponenty, když je cílový slot kratší než nakonfigurovaná výška |
|---|---|
MinimumFollowingHeight | Vztahuje se jen na konečný obsahový fragment a vyžaduje, aby jeho rozlišená výška plus rezervovaná následná výška se vešly do slotu |
Opakování kvůli následné výšce zahodí izolovanou zkoušku, zatímco dříve potvrzené fragmenty zachová, takže nadpis, popisek nebo krátký úvod se mohou přemístit s první použitelnou oblastí další komponenty
LastRetryReason rozlišuje opakování celé komponenty, striktního dokončení, minimálního slotu a následného prostoru, zatímco LastRequiredSlotHeight hlásí známou požadovanou výšku pro omezení prostoru toku
Kontrola minimálního slotu běží před klonováním komponenty a zachytáváním Form, takže opakovaně odmítnuté krátké oblasti nenesou žádné náklady na zpětné volání komponenty ani dočasnou stránku
Návratové hodnoty
PDF_DYNAMIC_COMPONENT_ERROR | Požadavek, callback komponenty, výsledná geometrie nebo umístění Formu selhalo a žádný stav nebyl potvrzen |
|---|---|
PDF_DYNAMIC_COMPONENT_MORE | Obsah byl potvrzen a komponenta si vyžádala další slot stránky |
PDF_DYNAMIC_COMPONENT_COMPLETE | Komponenta dokončila, nebo už byla relace dokončená a callback se neuskutečnil |
PDF_DYNAMIC_COMPONENT_RETRY | Vybraná politika paginace nebo prostoru toku odložila umístění bez potvrzení obsahu či stavu |
Příklad
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;
Viz také
BeginFormXObject, ReleaseCapturedPage, ApplyRepeatedPageFragment