TPDFlibDynamicComponentSession
Макет сторінки, пагінація, типи даних
Опис
Компонує компонент зі станом по одній сторінці призначення за раз, не створюючи вміст пізніших сторінок наперед Кожна спроба виконується на клоні всередині ізольованого Form XObject і фіксує клон лише після успішного розміщення перевіреного вмісту Розширене розміщення може відхиляти переповнення, відсікати вміст природного розміру чи пропорційно зменшувати його, вирівнюючи в межах слота призначення Політика пагінації може дозволяти звичайне розщеплення, відкладати перший частковий фрагмент до свіжої області чи вимагати, щоб весь компонент лишався видимим до фіксації чогось Обмеження простору потоку можуть відхиляти коротку область до виклику компонента чи резервувати достатню висоту після його фінального фрагмента для наступного компонента Відхилений результат, невдалий виклик малювання чи виняток у зворотному виклику вилучає тимчасову сторінку, відновлює вибрану викликачем сторінку та лишає і вміст призначення, і поточний стан компонента без змін Приєднаний екземпляр
Кожна спроба виконується на клоні всередині ізольованого Form XObject і фіксує клон лише після успішного розміщення перевіреного вмісту
Кожна спроба виконується на клоні всередині ізольованого Form XObject і фіксує клон лише після успішного розміщення перевіреного вмісту
Кожна спроба виконується на клоні всередині ізольованого Form XObject і фіксує клон лише після успішного розміщення перевіреного вмісту
Політика пагінації може дозволяти звичайний поділ, відкладати перший частковий фрагмент до свіжої області чи вимагати, щоб увесь компонент залишався видимим до якогось фіксування
Обмеження простору потоку можуть відхилити низьку область до ініціації компонента чи зарезервувати достатню висоту після його останнього фрагмента для наступного компонента
TPDFlib лишається власністю викликача й мусить пережити сеанс
Оголошення
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;
Контракт компонента
CloneComponentповертає незалежну від викликача копію всього мінливого стану пагінаціїComposeмалює черезContext.LibraryInstanceу локальних координатах Form, чиї доступний розмір —AvailableWidthнаAvailableHeightPageNumberідентифікує сторінку призначення, хоча бібліотека вибирає ізольовану тимчасову сторінку, поки зворотний виклик виконується- Зворотний виклик може використовувати API малювання та вмісту, але не має змінювати документи, сторінки чи вкладені контейнери малювання
- Результати з вмістом вимагають скінченних додатних значень
UsedWidthіUsedHeightу межах полотна вмісту - Використаний прямокутник починається з локальної координати нуль і має обмежувати весь видимий вміст компонента
- Результат без вмісту чинний лише коли
HasMoreContent—Falseі обидва використані виміри нульові - Повернення нуля відхиляє спробу; кинутий виняток передається далі після очищення тимчасового стану
Методи
| Create | Приєднує бібліотеку, що належить викликачу, і клонує наданий компонент у незалежні початковий та поточний знімки |
|---|---|
| AttachComponent | Атомарно замінює обидва знімки клонами компонента, що належить викликачу, і очищає стан завершеності |
| Reset | Відновлює новий поточний клон із початкового знімка та скидає лічильник успішних компонувань |
| CloneCurrentComponent | Повертає клон у власності викликача для огляду поточного зафіксованого стану компонента |
| CreateLayoutOptions | Будує типізовані налаштування природного полотна, переповнення, вирівнювання, пагінації та простору потоку для розширеного розміщення |
| ComposeNext | Компонує один слот сторінки, перевіряє та розміщує його Form XObject, звільняє дескриптор захоплення і фіксує робочий стан |
| ComposeNextLayout | Компонує на налаштованому природному полотні, застосовує політику переповнення та вирівнювання і повертає дані джерела, слота та фінального перетворення |
Переповнення та розміщення
dopReject | Відхиляє вміст, ширший чи вищий за слот, без зміни вмісту призначення чи зафіксованого стану компонента |
|---|---|
dopClip | Тримає масштаб 1 і перетинає контур відсікання сторінки зі слотом призначення перед викликом Form XObject |
dopScaleDown | Використовує менший коефіцієнт ширини чи висоти лише за потреби й ніколи не збільшує вміст |
Вирівнювання розв'язується з перетвореного використаного прямокутника, тож відцентрований чи кінцевий відсіканий вміст вибирає відповідну видиму частину
Transform[M11 M12 M21 M22 MDX MDY]
SlotLeft повідомляє логічну матрицю розкладки SlotTop з локальних координат компонента до фінальних координат документа з вертикальною віссю вниз
SlotWidth, SlotHeight,
Політики пагінації
dppAllowSplit | Зберігає типову поведінку та фіксує будь-який чинний фрагмент, чиї зворотний виклик повідомляє більше вмісту |
|---|---|
dppKeepTogether | Повертає PDF_DYNAMIC_COMPONENT_RETRY для першої часткової чи невидимої проби, а потім дозволяє розщеплення чи вибраний резервний шлях відсікання на наступній чинній спробі того самого незафіксованого фрагмента |
dppRequireComplete | Повертає PDF_DYNAMIC_COMPONENT_RETRY, доки зворотний виклик не повідомить, що вмісту більше немає, а повний використаний прямокутник або вміщується в слот, або лишається видимим через пропорційне зменшення |
Placement
KeepTogetherRetryPending
Reset ідентифікує одноразовий резервний стан і очищається після успішної фіксації, AttachComponent чи
Обмеження простору потоку
MinimumSlotHeight | Повертає PDF_DYNAMIC_COMPONENT_RETRY до клонування чи виклику компонента, коли слот призначення коротший за налаштовану висоту |
|---|---|
MinimumFollowingHeight | Застосовується лише до фінального фрагмента вмісту та вимагає, щоб його розв'язана висота плюс зарезервована наступна висота вміщалися в слот |
Повторна спроба за наступною висотою відкидає ізольовану пробу, зберігаючи раніше зафіксовані фрагменти, дозволяючи заголовку, підпису чи короткому вступу рухатися з першою придатною областю наступного компонента
LastRetryReason розрізняє повторні спроби цілого компонента, строгого завершення, мінімального слота та наступного простору, а LastRequiredSlotHeight повідомляє відому потрібну висоту для обмежень простору потоку
Перевірка мінімального слота виконується до клонування компонента та захоплення Form, тож повторно відхилені короткі області не несуть витрат на зворотний виклик компонента чи тимчасову сторінку
Відхилений результат, невдалий виклик малювання чи виняток у зворотному виклику вилучає тимчасову сторінку, відновлює вибрану викликачем сторінку та лишає і вміст призначення, і поточний стан компонента без змін
Повернуті значення
PDF_DYNAMIC_COMPONENT_ERROR | Запит, зворотний виклик компонента, геометрія результату чи розміщення Form зазнали невдачі, і жоден стан не зафіксовано |
|---|---|
PDF_DYNAMIC_COMPONENT_MORE | Вміст зафіксовано, а компонент запросив інший слот сторінки |
PDF_DYNAMIC_COMPONENT_COMPLETE | Компонент завершився, або сеанс уже був завершений і зворотного виклику не було |
PDF_DYNAMIC_COMPONENT_RETRY | Вибрана політика пагінації чи простору потоку відклала розміщення без фіксації вмісту чи стану |
Приклад
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;
Див. також
BeginFormXObject, ReleaseCapturedPage, ApplyRepeatedPageFragment