TPDFlibDynamicComponentSession
Seitenlayout, Paginierung, Datentypen
Beschreibung
Setzt eine zustandsbehaftete Komponente je eine Zielseite gleichzeitig zusammen, ohne Inhalt späterer Seiten vorab zu erzeugen
Jeder Versuch läuft auf einem Klon in einem isolierten Form-XObject und bestätigt den Klon erst, nachdem validierter Inhalt erfolgreich platziert wurde
Die erweiterte Platzierung kann Überlauf ablehnen, Inhalt in natürlicher Größe beschneiden oder ihn proportional verkleinern und dabei in einem Ziel-Slot ausrichten
Die Paginierungsrichtlinie kann normales Aufteilen erlauben, das erste Teilfragment auf eine frische Region verschieben oder verlangen, dass die gesamte Komponente sichtbar bleibt, bevor irgendetwas bestätigt wird
Fließraum-Beschränkungen können eine kurze Region ablehnen, bevor die Komponente aufgerufen wird, oder nach ihrem letzten Fragment genug Höhe für eine folgende Komponente reservieren
Ein abgelehntes Ergebnis, ein gescheiterter Zeichnenaufruf oder eine Callback-Ausnahme entfernt die temporäre Seite, stellt die vom Aufrufer gewählte Seite wieder her und lässt Zielinhalt und aktuellen Komponentenzustand unverändert
TPDFlib-Instanz bleibt im Besitz des Aufrufers und muss die Sitzung überdauern
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;
Komponentenkontrakt
CloneComponentgibt eine aufruferunabhängige Kopie des gesamten veränderlichen Paginierungszustands zurückComposezeichnet überContext.LibraryInstancein lokalen Form-Koordinaten, deren verfügbare GrößeAvailableWidthmalAvailableHeightbeträgtPageNumberidentifiziert die Zielseite, obwohl die Bibliothek während des Callbacks eine isolierte temporäre Seite auswählt- Der Callback darf Zeichen- und Inhalts-APIs verwenden, darf aber keine Dokumente, Seiten oder verschachtelte Zeichencontainer ändern
- Inhaltsergebnisse erfordern endliche positive
UsedWidth- undUsedHeight-Werte innerhalb der Inhaltsleinwand - Das verwendete Rechteck beginnt bei der lokalen Koordinate null und soll den gesamten sichtbaren Komponenteninhalt umschließen
- Ein Ergebnis ohne Inhalt ist nur gültig, wenn
HasMoreContentFalseist und beide verwendeten Abmessungen null sind - Die Rückgabe von null lehnt den Versuch ab; ausgelöste Ausnahmen breiten sich aus, nachdem der temporäre Zustand bereinigt wurde
Methoden
| Create | Hängt eine Bibliothek im Aufruferbesitz an und klont die gelieferte Komponente in unabhängige Anfangs- und aktuelle Snapshots |
|---|---|
| AttachComponent | Ersetzt beide Snapshots atomar durch Klone einer Komponente im Aufruferbesitz und löscht den Abschlusszustand |
| Reset | Stellt aus dem Anfangs-Snapshot einen neuen aktuellen Klon wieder her und setzt die Zähler erfolgreicher Kompositionen zurück |
| CloneCurrentComponent | Gibt einen Klon im Aufruferbesitz zurück, um den aktuellen übernommenen Komponentenzustand zu inspizieren |
| CreateLayoutOptions | Erstellt typisierte Einstellungen für natürliche Leinwand, Überlauf, Ausrichtung, Paginierung und Flussraum für die erweiterte Platzierung |
| ComposeNext | Komponiert einen Seitenslot, validiert und platziert dessen Form-XObject, gibt das Aufnahme-Handle frei und übernimmt den Arbeitszustand |
| ComposeNextLayout | Komponiert auf der konfigurierten natürlichen Leinwand, wendet Überlauf- und Ausrichtungsrichtlinie an und liefert Quell-, Slot- und finale Transformationsdaten |
Überlauf und Platzierung
dopReject | Lehnt Inhalte ab, die breiter oder höher als der Slot sind, ohne Zielinhalt oder übernommenen Komponentenzustand zu ändern |
|---|---|
dopClip | Belässt den Maßstab 1 und verschneidet den Seiten-Clipping-Pfad mit dem Ziel-Slot, bevor das Form-XObject aufgerufen wird |
dopScaleDown | Verwendet das kleinere Breiten- oder Höhenverhältnis nur bei Bedarf und vergrößert Inhalte nie |
Die Ausrichtung wird aus dem transformierten verwendeten Rechteck abgeleitet, sodass zentrierte oder nachlaufende abgeschnittene Inhalte den entsprechenden sichtbaren Teil auswählen
Transform[M11 M12 M21 M22 MDX MDY]
SlotLeft meldet die logische Layoutmatrix SlotTop von komponentenlokalen Koordinaten zu den finalen von oben nach unten orientierten Dokumentkoordinaten
SlotWidth, SlotHeight,
Paginierungsrichtlinien
dppAllowSplit | Bewahrt das Standardverhalten und übernimmt jedes gültige Fragment, dessen Callback weiteren Inhalt meldet |
|---|---|
dppKeepTogether | Gibt PDF_DYNAMIC_COMPONENT_RETRY für den ersten teilweisen oder nicht sichtbaren Versuch zurück und erlaubt dann beim nächsten gültigen Versuch desselben nicht übernommenen Fragments das Aufteilen oder den gewählten Clipping-Fallback |
dppRequireComplete | Gibt PDF_DYNAMIC_COMPONENT_RETRY zurück, bis der Callback keinen verbleibenden Inhalt meldet und das vollständige verwendete Rechteck entweder in den Slot passt oder durch proportionale Verkleinerung sichtbar bleibt |
Placement
KeepTogetherRetryPending-Datensatz zurück
Reset kennzeichnet den Einmal-Fallback-Zustand und wird nach einer erfolgreichen Übernahme, AttachComponent oder
Fließraum-Beschränkungen
MinimumSlotHeight | Gibt PDF_DYNAMIC_COMPONENT_RETRY zurück, bevor die Komponente geklont oder aufgerufen wird, wenn der Ziel-Slot kürzer als die konfigurierte Höhe ist |
|---|---|
MinimumFollowingHeight | Gilt nur für ein letztes Inhaltsfragment und verlangt, dass seine aufgelöste Höhe zuzüglich der reservierten Folgehöhe in den Slot passt |
Ein Folgehöhen-Wiederholungsversuch verwirft den isolierten Testlauf, während bereits übernommene Fragmente erhalten bleiben, sodass eine Überschrift, ein Label oder ein kurzer Einleitungstext mit der ersten nutzbaren Region der nächsten Komponente wandern kann
LastRetryReason unterscheidet Gesamt-, strikte Abschluss-, Mindest-Slot- und Folgraum-Wiederholungen, während LastRequiredSlotHeight die bekannte erforderliche Höhe für Fließraum-Beschränkungen meldet
Die Minimum-Slot-Prüfung läuft vor Komponentenklonung und Form-Erfassung, sodass wiederholt abgelehnte kurze Regionen keine Komponenten-Callback- oder temporäre Seitenkosten verursachen
Rückgabewerte
PDF_DYNAMIC_COMPONENT_ERROR | Anforderung, Komponenten-Callback, Ergebnisgeometrie oder Form-Platzierung schlugen fehl, und es wurde kein Zustand übernommen |
|---|---|
PDF_DYNAMIC_COMPONENT_MORE | Inhalt wurde übernommen, und die Komponente forderte einen weiteren Seitenslot an |
PDF_DYNAMIC_COMPONENT_COMPLETE | Die Komponente wurde abgeschlossen, oder die Sitzung war bereits vollständig, und es wurde kein Callback ausgeführt |
PDF_DYNAMIC_COMPONENT_RETRY | Die gewählte Paginierungs- oder Flussraum-Richtlinie hat die Platzierung zurückgestellt, ohne Inhalt oder Zustand zu übernehmen |
Beispiel
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;
Siehe auch
BeginFormXObject, ReleaseCapturedPage, ApplyRepeatedPageFragment