TPDFlibDynamicComponentSession

Bố cục trang, phân trang, kiểu dữ liệu

Mô tả

Ghép một thành phần có trạng thái từng trang đích một mà không dựng trước nội dung cho các trang sau Mỗi lần thử chạy trên một bản sao bên trong một Form XObject tách biệt và chỉ xác nhận bản sao sau khi nội dung đã kiểm chứng được đặt thành công Đặt mở rộng có thể từ chối tràn, cắt nội dung cỡ tự nhiên hoặc thu nhỏ nó theo tỷ lệ trong khi căn nó trong một khung đích Chính sách phân trang có thể cho phép tách bình thường, hoãn phân đoạn một phần đầu tiên sang một vùng mới hoặc yêu cầu toàn bộ thành phần vẫn hiển thị trước khi xác nhận bất cứ thứ gì Ràng buộc vùng luồng có thể từ chối một vùng ngắn trước khi gọi thành phần hoặc dành đủ chiều cao sau phân đoạn cuối của nó cho một thành phần kế tiếp Một kết quả bị từ chối, lời gọi vẽ thất bại hoặc ngoại lệ callback xóa trang tạm, khôi phục trang do caller chọn và giữ cả nội dung đích lẫn trạng thái thành phần hiện tại nguyên trạng Thực thể

Mỗi lần thử chạy trên một bản clone bên trong Form XObject tách biệt và chỉ commit clone sau khi nội dung đã kiểm được đặt thành công

Đặt mở rộng có thể từ chối overflow, clip nội dung kích thước tự nhiên hoặc thu nhỏ theo tỷ lệ trong khi canh vào slot đích

Chính sách phân trang có thể cho phép chia thường lệ, hoãn fragment một phần đầu tiên sang vùng mới, hoặc yêu cầu cả component hiển thị trọn trước khi commit bất cứ gì

Ràng buộc không gian flow có thể từ chối vùng ngắn trước khi gọi component, hoặc giữ đủ chiều cao sau fragment cuối của nó cho component kế tiếp

Kết quả bị từ chối, lời gọi vẽ thất bại hoặc exception trong callback sẽ xóa trang tạm, khôi phục trang caller đã chọn, và giữ nguyên cả nội dung đích lẫn trạng thái hiện tại của component

TPDFlib được gắn vẫn thuộc sở hữu caller và phải tồn tại lâu hơn phiên

Khai báo

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;

Hợp đồng thành phần

Phương thức

CreateGắn một thư viện sở hữu bởi caller và sao chép thành phần được cung cấp thành các bản chụp ban đầu và hiện tại độc lập
AttachComponentNguyên tử thay cả hai bản chụp bằng các bản sao của một thành phần sở hữu bởi caller và xóa trạng thái hoàn tất
ResetKhôi phục một bản sao hiện tại mới từ bản chụp ban đầu và đặt lại số lần ghép thành công
CloneCurrentComponentTrả về một bản sao sở hữu bởi caller để xem xét trạng thái thành phần hiện tại đã xác nhận
CreateLayoutOptionsDựng các cài đặt có kiểu canvas tự nhiên, tràn, căn chỉnh, phân trang và vùng luồng cho đặt mở rộng
ComposeNextGhép một khung trang, kiểm chứng và đặt Form XObject của nó, giải phóng handle chụp và xác nhận trạng thái làm việc
ComposeNextLayoutGhép trên canvas tự nhiên đã cấu hình, áp dụng chính sách tràn và căn chỉnh, và trả về dữ liệu nguồn, khung và biến đổi cuối

Tràn và vị trí đặt

dopRejectTừ chối nội dung rộng hơn hoặc cao hơn khung mà không thay đổi nội dung đích hay trạng thái thành phần đã xác nhận
dopClipGiữ tỷ lệ 1 và giao vùng cắt trang với khung đích trước khi gọi Form XObject
dopScaleDownDùng tỷ lệ rộng hay cao nhỏ hơn chỉ khi cần và không bao giờ phóng to nội dung

Căn chỉnh được suy từ hình chữ nhật đã dùng đã biến đổi, nên nội dung bị cắt ở giữa hay ở đuôi chọn phần hiển thị tương ứng

Transform[M11 M12 M21 M22 MDX MDY]

SlotLeft báo ma trận bố cục logic SlotTop từ tọa độ cục bộ thành phần sang tọa độ tài liệu từ trên xuống cuối cùng SlotWidth, SlotHeight,

Chính sách phân trang

dppAllowSplitGiữ hành vi mặc định và xác nhận mọi phân đoạn hợp lệ mà callback báo còn nội dung
dppKeepTogetherTrả về PDF_DYNAMIC_COMPONENT_RETRY cho lần thử một phần hoặc không hiển thị đầu tiên, rồi cho phép tách hoặc phương án cắt dự phòng đã chọn ở lần thử hợp lệ tiếp theo cho cùng phân đoạn chưa xác nhận
dppRequireCompleteTrả về PDF_DYNAMIC_COMPONENT_RETRY cho đến khi callback báo không còn nội dung và toàn bộ hình chữ nhật đã dùng vừa khung hoặc vẫn hiển thị qua thu nhỏ theo tỷ lệ

Placement

KeepTogetherRetryPending rỗng Reset nhận diện trạng thái dự phòng một lần và được xóa sau một lần xác nhận thành công, AttachComponent hoặc

Ràng buộc flow-space

MinimumSlotHeightTrả về PDF_DYNAMIC_COMPONENT_RETRY trước khi sao chép hay gọi thành phần khi khung đích ngắn hơn chiều cao đã cấu hình
MinimumFollowingHeightChỉ áp dụng cho một phân đoạn nội dung cuối và yêu cầu chiều cao đã suy của nó cộng chiều cao kế tiếp đã dành phải vừa khung

Một lần thử lại vì chiều cao kế tiếp bỏ lần thử tách biệt trong khi giữ các phân đoạn đã xác nhận trước đó, cho phép một đề mục, nhãn hoặc phần dẫn ngắn di chuyển cùng vùng dùng được đầu tiên của thành phần kế tiếp

LastRetryReason phân biệt các lần thử lại toàn thành phần, hoàn tất nghiêm ngặt, khung tối thiểu và không gian kế tiếp, trong khi LastRequiredSlotHeight báo chiều cao bắt buộc đã biết cho các ràng buộc vùng luồng Kiểm tra khung tối thiểu chạy trước sao chép thành phần và chụp Form, nên các vùng ngắn bị từ chối lặp lại không phát sinh chi phí callback thành phần hay trang tạm

Kiểm tra số slot tối thiểu chạy trước khi clone component và capture Form, vùng ngắn bị từ chối lặp lại vì vậy không tốn component callback hay trang tạm

Giá trị trả về

PDF_DYNAMIC_COMPONENT_ERRORYêu cầu, callback thành phần, hình học kết quả hoặc đặt Form thất bại và không có trạng thái nào được xác nhận
PDF_DYNAMIC_COMPONENT_MORENội dung đã được xác nhận và thành phần yêu cầu một khung trang khác
PDF_DYNAMIC_COMPONENT_COMPLETEThành phần đã hoàn tất, hoặc phiên đã hoàn tất từ trước và không có callback nào được gọi
PDF_DYNAMIC_COMPONENT_RETRYChính sách phân trang hoặc vùng luồng được chọn đã hoãn việc đặt mà không xác nhận nội dung hay trạng thái

Ví dụ

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;

Xem thêm

BeginFormXObject, ReleaseCapturedPage, ApplyRepeatedPageFragment