TPDFlibDynamicComponentSession
Układ strony, paginacja, typy danych
Opis
Komponuje komponent ze stanem po jednej stronie docelowej naraz, bez wcześniejszego budowania treści dla późniejszych stron
Każda próba biegnie na klonie wewnątrz izolowanego Form XObject i zatwierdza klon dopiero po pomyślnym umieszczeniu zwalidowanej treści
Rozszerzone umieszczanie może odrzucić przepełnienie, przyciąć treść o naturalnym rozmiarze albo przeskalować ją proporcjonalnie w dół, wyrównując ją w gnieździe docelowym
Polityka paginacji może pozwolić na normalny podział, odroczyć pierwszy fragment częściowy do świeżego regionu albo wymagać, by cały komponent pozostał widoczny przed zatwierdzeniem czegokolwiek
Ograniczenia przestrzeni przepływu mogą odrzucić krótki region przed wywołaniem komponentu albo zarezerwować dość wysokości po jego ostatnim fragmencie dla komponentu następnego
Odrzucony wynik, nieudane wywołanie rysowania albo wyjątek wywołania zwrotnego usuwa stronę tymczasową, przywraca stronę wybraną przez wywołującego i zostawia i treść celu, i bieżący stan komponentu bez zmian
Dołączona instancja TPDFlib pozostaje własnością wywołującego i musi przeżyć sesję
Deklaracja
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 komponentu
CloneComponentzwraca kopię całego mutowalnego stanu paginacji niezależną od wywołującegoComposerysuje przezContext.LibraryInstancewe współrzędnych lokalnych Form, których dostępny rozmiar toAvailableWidthnaAvailableHeightPageNumberidentyfikuje stronę docelową, mimo że biblioteka wybiera izolowaną stronę tymczasową na czas działania procedury zwrotnej- Procedura zwrotna może używać API rysowania i treści, ale nie wolno jej zmieniać dokumentów, stron ani zagnieżdżonych kontenerów rysowania
- Wyniki z treścią wymagają skończonych dodatnich wartości
UsedWidthiUsedHeightw obrębie płótna treści - Użyty prostokąt zaczyna się od lokalnej współrzędnej zero i ma obejmować całą widoczną treść komponentu
- Wynik bez treści jest prawidłowy tylko wtedy, gdy
HasMoreContentma wartośćFalse, a oba użyte wymiary wynoszą zero - Zwrot zera odrzuca próbę; zgłoszone wyjątki propagują się po posprzątaniu stanu tymczasowego
Metody
| Create | Podłącza bibliotekę należącą do wywołującego i klonuje podany komponent do niezależnych migawek początkowej i bieżącej |
|---|---|
| AttachComponent | Atomowo zastępuje obie migawki klonami komponentu należącego do wywołującego i czyści stan ukończenia |
| Reset | Odtwarza nowy bieżący klon z migawki początkowej i resetuje licznik udanych kompozycji |
| CloneCurrentComponent | Zwraca klon należący do wywołującego do przeglądania bieżącego zatwierdzonego stanu komponentu |
| CreateLayoutOptions | Buduje typowane ustawienia naturalnego płótna, przepełnienia, wyrównania, paginacji i przestrzeni przepływu dla rozszerzonego rozmieszczania |
| ComposeNext | Komponuje jedno gniazdo strony, waliduje i rozmieszcza jego Form XObject, zwalnia uchwyt przechwycenia i zatwierdza stan roboczy |
| ComposeNextLayout | Komponuje na skonfigurowanym naturalnym płótnie, stosuje politykę przepełnienia i wyrównania oraz zwraca dane źródła, gniazda i przekształcenia końcowego |
Przepełnienie i rozmieszczanie
dopReject | Odrzuca treść szerszą albo wyższą niż gniazdo bez zmiany treści docelowej ani zatwierdzonego stanu komponentu |
|---|---|
dopClip | Zachowuje skalę 1 i przecina ścieżkę przycinania strony z gniazdem docelowym przed wywołaniem Form XObject |
dopScaleDown | Używa mniejszego stosunku szerokości albo wysokości tylko w razie potrzeby i nigdy nie powiększa treści |
Wyrównanie jest rozstrzygane z przekształconego użytego prostokąta, więc wyśrodkowana albo końcowa przycięta treść wybiera odpowiadającą widoczną część
Transform[M11 M12 M21 M22 MDX MDY]
SlotLeft raportuje logiczną macierz układu SlotTop ze współrzędnych lokalnych komponentu do końcowych współrzędnych dokumentu od góry w dół
SlotWidth, SlotHeight,
Zasady paginacji
dppAllowSplit | Zachowuje domyślne zachowanie i zatwierdza każdy prawidłowy fragment, którego procedura zwrotna raportuje więcej treści |
|---|---|
dppKeepTogether | Zwraca PDF_DYNAMIC_COMPONENT_RETRY dla pierwszej częściowej albo niewidocznej próby, a przy następnej prawidłowej próbie tego samego niezatwierdzonego fragmentu dopuszcza dzielenie albo wybrane rozwiązanie zapasowe przycinania |
dppRequireComplete | Zwraca PDF_DYNAMIC_COMPONENT_RETRY, dopóki procedura zwrotna nie raportuje braku pozostałej treści, a cały użyty prostokąt zmieści się w gnieździe albo pozostanie widoczny dzięki proporcjonalnemu pomniejszeniu |
Placement
KeepTogetherRetryPending
Reset identyfikuje jednorazowy stan rozwiązania zapasowego i jest czyszczony po udanym zatwierdzeniu, AttachComponent albo
Ograniczenia przestrzeni przepływu
MinimumSlotHeight | Zwraca PDF_DYNAMIC_COMPONENT_RETRY przed klonowaniem albo wywołaniem komponentu, gdy gniazdo docelowe jest krótsze niż skonfigurowana wysokość |
|---|---|
MinimumFollowingHeight | Dotyczy wyłącznie ostatniego fragmentu treści i wymaga, by jego rozwiązana wysokość plus zarezerwowana wysokość następnika zmieściły się w gnieździe |
Ponowienie z powodu wysokości następnika porzuca izolowaną próbę, zachowując wcześniej zatwierdzone fragmenty, więc nagłówek, etykieta albo krótki wstęp mogą przenieść się z pierwszym użytecznym regionem następnego komponentu
LastRetryReason rozróżnia ponowienia całego komponentu, ścisłego ukończenia, minimalnego gniazda i przestrzeni następnika, a LastRequiredSlotHeight raportuje znaną wymaganą wysokość dla ograniczeń przestrzeni przepływu
Kontrola minimalnego gniazda biegnie przed klonowaniem komponentu i przechwyceniem Form, więc wielokrotnie odrzucane krótkie regiony nie ponoszą kosztu wywołania zwrotnego komponentu ani strony tymczasowej
Wartości zwracane
PDF_DYNAMIC_COMPONENT_ERROR | Żądanie, procedura zwrotna komponentu, geometria wyniku albo rozmieszczenie Form zawiodły i nie zatwierdzono żadnego stanu |
|---|---|
PDF_DYNAMIC_COMPONENT_MORE | Treść została zatwierdzona, a komponent zażądał kolejnego gniazda strony |
PDF_DYNAMIC_COMPONENT_COMPLETE | Komponent został ukończony albo sesja była już ukończona i procedura zwrotna nie została wywołana |
PDF_DYNAMIC_COMPONENT_RETRY | Wybrana polityka paginacji albo przestrzeni przepływu odroczyła rozmieszczenie bez zatwierdzania treści ani stanu |
Przykład
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;
Zobacz również
BeginFormXObject, ReleaseCapturedPage, ApplyRepeatedPageFragment