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
CloneComponentrestituisce una copia indipendente dal chiamante di tutto lo stato di paginazione mutabileComposedisegna attraversoContext.LibraryInstancein coordinate locali del Form la cui dimensione disponibile èAvailableWidthperAvailableHeightPageNumberidentifica la pagina di destinazione anche se la libreria seleziona una pagina temporanea isolata mentre il callback è in esecuzione- Il callback può usare le API di disegno e contenuto ma non deve cambiare documenti, pagine o contenitori di disegno annidati
- I risultati con contenuto richiedono valori
UsedWidtheUsedHeightfiniti e positivi all'interno della tela del contenuto - Il rettangolo usato parte dalla coordinata locale zero e deve delimitare tutto il contenuto visibile del componente
- Un risultato senza contenuto è valido solo quando
HasMoreContentèFalseed entrambe le dimensioni usate sono zero - Restituire zero rifiuta il tentativo; le eccezioni sollevate si propagano dopo la pulizia dello stato temporaneo
Metodi
| Create | Collega una libreria di proprietà del chiamante e clona il componente fornito in istantanee iniziale e corrente indipendenti |
|---|---|
| AttachComponent | Sostituisce atomicamente entrambe le istantanee con cloni di un componente di proprietà del chiamante e cancella lo stato di completamento |
| Reset | Ripristina un nuovo clone corrente dall'istantanea iniziale e azzera il conteggio delle composizioni riuscite |
| CloneCurrentComponent | Restituisce un clone di proprietà del chiamante per esaminare lo stato corrente confermato del componente |
| CreateLayoutOptions | Costruisce impostazioni tipizzate di tela naturale, overflow, allineamento, paginazione e spazio di flusso per il posizionamento esteso |
| ComposeNext | Compone uno slot di pagina, valida e posiziona il suo Form XObject, rilascia l'handle di acquisizione e conferma lo stato di lavoro |
| ComposeNextLayout | Compone sulla tela naturale configurata, applica la policy di overflow e allineamento e restituisce dati di sorgente, slot e trasformazione finale |
Overflow e posizionamento
dopReject | Rifiuta contenuto più largo o più alto dello slot senza cambiare il contenuto di destinazione né lo stato confermato del componente |
|---|---|
dopClip | Mantiene scala 1 e interseca il percorso di ritaglio della pagina con lo slot di destinazione prima di invocare il Form XObject |
dopScaleDown | Usa 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
dppAllowSplit | Preserva il comportamento predefinito e conferma qualunque frammento valido il cui callback riporta altro contenuto |
|---|---|
dppKeepTogether | Restituisce 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 |
dppRequireComplete | Restituisce 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
MinimumSlotHeight | Restituisce PDF_DYNAMIC_COMPONENT_RETRY prima di clonare o invocare il componente quando lo slot di destinazione è più corto dell'altezza configurata |
|---|---|
MinimumFollowingHeight | Si 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_ERROR | La richiesta, il callback del componente, la geometria del risultato o il posizionamento del Form è fallito e nessuno stato è stato confermato |
|---|---|
PDF_DYNAMIC_COMPONENT_MORE | Il contenuto è stato confermato e il componente ha richiesto un altro slot di pagina |
PDF_DYNAMIC_COMPONENT_COMPLETE | Il componente ha completato, oppure la sessione era già completa e nessun callback è stato effettuato |
PDF_DYNAMIC_COMPONENT_RETRY | La 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