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;

Контракт компонента

Методи

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