TPDFlibDynamicComponentSession
Mise en page, pagination, types de données
Description
Compose un composant avec état une page de destination à la fois sans construire à l'avance le contenu des pages suivantes
Chaque tentative s'exécute sur un clone dans un Form XObject isolé et ne valide le clone qu'après que le contenu validé a été placé avec succès
Le placement étendu peut rejeter le débordement, rogner le contenu à taille naturelle ou le réduire proportionnellement en l'alignant dans un emplacement de destination
La politique de pagination peut autoriser la division normale, différer le premier fragment partiel vers une région fraîche ou exiger que le composant entier reste visible avant de valider quoi que ce soit
Les contraintes d'espace de flux peuvent rejeter une région courte avant d'invoquer le composant ou réserver assez de hauteur après son dernier fragment pour un composant suivant
Un résultat rejeté, un appel de dessin échoué ou une exception de callback supprime la page temporaire, restaure la page sélectionnée par l'appelant et laisse le contenu de destination et l'état du composant actuel inchangés
TPDFlib attachée reste la propriété de l'appelant et doit survivre à la session
Déclaration
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;
Contrat du composant
CloneComponentretourne une copie indépendante de l'appelant de tout l'état de pagination mutableComposedessine au travers deContext.LibraryInstanceen coordonnées locales du Form dont la taille disponible estAvailableWidthparAvailableHeightPageNumberidentifie la page de destination même si la bibliothèque sélectionne une page temporaire isolée pendant l'exécution du callback- Le callback peut utiliser les API de dessin et de contenu mais ne doit pas changer de documents, de pages ni de conteneurs de dessin imbriqués
- Les résultats avec contenu exigent des valeurs
UsedWidthetUsedHeightfinies et positives au sein du canevas de contenu - Le rectangle utilisé démarre à la coordonnée locale zéro et doit englober tout le contenu visible du composant
- Un résultat sans contenu n'est valide que lorsque
HasMoreContentvautFalseet que les deux dimensions utilisées sont nulles - Le retour de zéro rejette la tentative ; les exceptions levées se propagent après le nettoyage de l'état temporaire
Méthodes
| Create | Attache une bibliothèque propriété de l'appelant et clone le composant fourni en instantanés initial et courant indépendants |
|---|---|
| AttachComponent | Remplace atomiquement les deux instantanés par des clones d'un composant propriété de l'appelant et efface l'état d'achèvement |
| Reset | Restaure un nouveau clone courant à partir de l'instantané initial et réinitialise le compteur de compositions réussies |
| CloneCurrentComponent | Retourne un clone propriété de l'appelant pour inspecter l'état du composant courant validé |
| CreateLayoutOptions | Construit des réglages typés de canevas naturel, de débordement, d'alignement, de pagination et d'espace de flux pour le placement étendu |
| ComposeNext | Compose un emplacement de page, valide et place son Form XObject, libère le handle de capture et valide l'état de travail |
| ComposeNextLayout | Compose sur le canevas naturel configuré, applique la politique de débordement et d'alignement et retourne les données de source, d'emplacement et de transformation finale |
Débordement et placement
dopReject | Rejette un contenu plus large ou plus haut que l'emplacement sans changer le contenu de destination ni l'état validé du composant |
|---|---|
dopClip | Conserve l'échelle 1 et intersecte le chemin de détourage de la page avec l'emplacement de destination avant d'invoquer le Form XObject |
dopScaleDown | Utilise le plus petit rapport de largeur ou de hauteur uniquement si nécessaire et n'agrandit jamais le contenu |
L'alignement est résolu à partir du rectangle utilisé transformé, de sorte qu'un contenu centré ou tronqué en queue sélectionne la portion visible correspondante
Transform[M11 M12 M21 M22 MDX MDY]
SlotLeft signale la matrice logique de mise en page SlotTop des coordonnées locales du composant vers les coordonnées finales du document vertical descendant
SlotWidth, SlotHeight,
Règles de pagination
dppAllowSplit | Préserve le comportement par défaut et valide tout fragment valide dont le callback signale du contenu supplémentaire |
|---|---|
dppKeepTogether | Retourne PDF_DYNAMIC_COMPONENT_RETRY pour la première tentative partielle ou non visible, puis autorise la scission ou le repli de rognage sélectionné à la prochaine tentative valide pour le même fragment non validé |
dppRequireComplete | Retourne PDF_DYNAMIC_COMPONENT_RETRY jusqu'à ce que le callback signale qu'il ne reste aucun contenu et que le rectangle utilisé complet tienne dans l'emplacement ou reste visible après réduction proportionnelle |
Placement
KeepTogetherRetryPending vide
Reset identifie l'état de repli à usage unique et est effacé après une validation réussie, AttachComponent ou
Contraintes d'espace de flux
MinimumSlotHeight | Retourne PDF_DYNAMIC_COMPONENT_RETRY avant le clonage ou l'invocation du composant lorsque l'emplacement de destination est plus court que la hauteur configurée |
|---|---|
MinimumFollowingHeight | Ne s'applique qu'à un fragment de contenu final et exige que sa hauteur résolue plus la hauteur de suite réservée tiennent dans l'emplacement |
Une nouvelle tentative pour la hauteur de suite abandonne l'essai isolé tout en préservant les fragments antérieurs validés, permettant à un titre, une étiquette ou une courte amorce de suivre la première région utilisable du composant suivant
LastRetryReason distingue les réessais de composant entier, d'achèvement strict, de slot minimum et d'espace suivant, tandis que LastRequiredSlotHeight signale la hauteur requise connue pour les contraintes d'espace de flux
La vérification de slot minimum s'exécute avant le clonage du composant et la capture du Form, si bien les régions courtes rejetées à répétition n'encourent aucun coût de callback de composant ni de page temporaire
Valeurs de retour
PDF_DYNAMIC_COMPONENT_ERROR | La requête, le callback du composant, la géométrie du résultat ou le placement du Form a échoué et aucun état n'a été validé |
|---|---|
PDF_DYNAMIC_COMPONENT_MORE | Le contenu a été validé et le composant a demandé un autre emplacement de page |
PDF_DYNAMIC_COMPONENT_COMPLETE | Le composant est achevé, ou la session était déjà achevée et aucun callback n'a été effectué |
PDF_DYNAMIC_COMPONENT_RETRY | La politique de pagination ou d'espace de flux sélectionnée a reporté le placement sans valider de contenu ni d'état |
Exemple
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;
Voir aussi
BeginFormXObject, ReleaseCapturedPage, ApplyRepeatedPageFragment