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
CloneComponenttrả về một bản sao độc lập với caller của toàn bộ trạng thái phân trang có thể thay đổiComposevẽ quaContext.LibraryInstancetrong tọa độ Form cục bộ với kích thước khả dụng làAvailableWidthnhânAvailableHeightPageNumbernhận diện trang đích mặc dù thư viện chọn một trang tạm tách biệt trong khi callback chạy- Callback có thể dùng các API vẽ và nội dung nhưng không được thay đổi tài liệu, trang hay các vùng chứa vẽ lồng nhau
- Kết quả nội dung yêu cầu các giá trị
UsedWidthvàUsedHeighthữu hạn dương trong canvas nội dung - Hình chữ nhật đã dùng bắt đầu tại tọa độ cục bộ 0 và phải bao tất cả nội dung thành phần hiển thị
- Kết quả không nội dung chỉ hợp lệ khi
HasMoreContentlàFalsevà cả hai kích thước đã dùng bằng 0 - Trả về 0 từ chối lần thử; các ngoại lệ được phát tiếp sau khi trạng thái tạm đã được dọn dẹp
Phương thức
| Create | Gắ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 |
|---|---|
| AttachComponent | Nguyê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 |
| Reset | Khô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 |
| CloneCurrentComponent | Trả 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 |
| CreateLayoutOptions | Dự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 |
| ComposeNext | Ghé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 |
| ComposeNextLayout | Ghé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
dopReject | Từ 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 |
|---|---|
dopClip | Giữ tỷ lệ 1 và giao vùng cắt trang với khung đích trước khi gọi Form XObject |
dopScaleDown | Dù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
dppAllowSplit | Giữ 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 |
|---|---|
dppKeepTogether | Trả 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 |
dppRequireComplete | Trả 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
MinimumSlotHeight | Trả 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 |
|---|---|
MinimumFollowingHeight | Chỉ á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_ERROR | Yê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_MORE | Nộ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_COMPLETE | Thà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_RETRY | Chí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