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

Methoden

CreateHängt eine Bibliothek im Aufruferbesitz an und klont die gelieferte Komponente in unabhängige Anfangs- und aktuelle Snapshots
AttachComponentErsetzt beide Snapshots atomar durch Klone einer Komponente im Aufruferbesitz und löscht den Abschlusszustand
ResetStellt aus dem Anfangs-Snapshot einen neuen aktuellen Klon wieder her und setzt die Zähler erfolgreicher Kompositionen zurück
CloneCurrentComponentGibt einen Klon im Aufruferbesitz zurück, um den aktuellen übernommenen Komponentenzustand zu inspizieren
CreateLayoutOptionsErstellt typisierte Einstellungen für natürliche Leinwand, Überlauf, Ausrichtung, Paginierung und Flussraum für die erweiterte Platzierung
ComposeNextKomponiert einen Seitenslot, validiert und platziert dessen Form-XObject, gibt das Aufnahme-Handle frei und übernimmt den Arbeitszustand
ComposeNextLayoutKomponiert auf der konfigurierten natürlichen Leinwand, wendet Überlauf- und Ausrichtungsrichtlinie an und liefert Quell-, Slot- und finale Transformationsdaten

Überlauf und Platzierung

dopRejectLehnt Inhalte ab, die breiter oder höher als der Slot sind, ohne Zielinhalt oder übernommenen Komponentenzustand zu ändern
dopClipBelässt den Maßstab 1 und verschneidet den Seiten-Clipping-Pfad mit dem Ziel-Slot, bevor das Form-XObject aufgerufen wird
dopScaleDownVerwendet 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

dppAllowSplitBewahrt das Standardverhalten und übernimmt jedes gültige Fragment, dessen Callback weiteren Inhalt meldet
dppKeepTogetherGibt 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
dppRequireCompleteGibt 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

MinimumSlotHeightGibt 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
MinimumFollowingHeightGilt 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_ERRORAnforderung, Komponenten-Callback, Ergebnisgeometrie oder Form-Platzierung schlugen fehl, und es wurde kein Zustand übernommen
PDF_DYNAMIC_COMPONENT_MOREInhalt wurde übernommen, und die Komponente forderte einen weiteren Seitenslot an
PDF_DYNAMIC_COMPONENT_COMPLETEDie Komponente wurde abgeschlossen, oder die Sitzung war bereits vollständig, und es wurde kein Callback ausgeführt
PDF_DYNAMIC_COMPONENT_RETRYDie 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