TPDFlibDynamicComponentSession
Esquema de página, paginação, tipos de dados
Descrição
Compõe um componente com estado numa página de destino de cada vez, sem construir antecipadamente conteúdo para páginas posteriores
Cada tentativa corre num clone dentro de um Form XObject isolado e só consolida o clone depois de o conteúdo validado ter sido colocado com sucesso
A colocação estendida pode recusar transbordo, recortar conteúdo de tamanho natural ou reduzi-lo proporcionalmente enquanto o alinha numa ranhura de destino
A política de paginação pode permitir a divisão normal, adiar o primeiro fragmento parcial para uma região fresca ou exigir que o componente inteiro permaneça visível antes de consolidar qualquer coisa
As restrições de espaço de fluxo podem recusar uma região baixa antes de invocar o componente ou reservar altura suficiente após o respetivo fragmento final para um componente seguinte
Um resultado recusado, uma chamada de desenho com falha ou uma exceção de chamada de retorno remove a página temporária, restaura a página selecionada pelo chamador e deixa tanto o conteúdo de destino como o estado atual do componente inalterados
A instância TPDFlib anexada permanece propriedade do chamador e tem de sobreviver à sessão
Declaraçã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;
Contrato do componente
CloneComponentdevolve uma cópia independente do chamador de todo o estado de paginação mutávelComposedesenha através deContext.LibraryInstanceem coordenadas locais do Form, cujo tamanho disponível éAvailableWidthporAvailableHeightPageNumberidentifica a página de destino, mesmo que a biblioteca selecione uma página temporária isolada enquanto a callback corre- A callback pode usar APIs de desenho e de conteúdo, mas não deve alterar documentos, páginas nem contentores de desenho aninhados
- Resultados com conteúdo exigem valores finitos e positivos de
UsedWidtheUsedHeightdentro da tela de conteúdo - O retângulo usado começa na coordenada local zero e deve delimitar todo o conteúdo visível do componente
- Um resultado sem conteúdo só é válido quando
HasMoreContentéFalsee ambas as dimensões usadas são zero - Devolver zero recusa a tentativa; exceções lançadas propagam-se depois de o estado temporário ser limpo
Métodos
| Create | Anexa uma biblioteca propriedade do chamador e clona o componente fornecido em capturas iniciais e atuais independentes |
|---|---|
| AttachComponent | Substitui atomicamente ambas as capturas por clones de um componente propriedade do chamador e limpa o estado de conclusão |
| Reset | Restaura um novo clone atual a partir da captura inicial e repõe a contagem de composições bem-sucedidas |
| CloneCurrentComponent | Devolve um clone propriedade do chamador para inspecionar o estado atual confirmado do componente |
| CreateLayoutOptions | Constrói definições tipadas de tela natural, transbordo, alinhamento, paginação e espaço de fluxo para a colocação estendida |
| ComposeNext | Compõe uma ranhura de página, valida e coloca o respetivo Form XObject, liberta o handle de captura e confirma o estado de trabalho |
| ComposeNextLayout | Compõe na tela natural configurada, aplica a política de transbordo e de alinhamento e devolve dados de origem, de ranhura e da transformação final |
Transbordo e colocação
dopReject | Recusa conteúdo mais largo ou mais alto do que a ranhura sem alterar o conteúdo de destino nem o estado consolidado do componente |
|---|---|
dopClip | Mantém a escala 1 e interseca o caminho de recorte da página com a ranhura de destino antes de invocar o Form XObject |
dopScaleDown | Utiliza o menor rácio de largura ou de altura apenas quando necessário e nunca amplia o conteúdo |
O alinhamento resolve-se a partir do retângulo usado transformado, pelo que o conteúdo centrado ou com recorte final seleciona a parte visível correspondente
Transform comunica a matriz de esquema lógico [M11 M12 M21 M22 MDX MDY] das coordenadas locais do componente para as coordenadas finais do documento, de cima para baixo
SlotLeft, SlotTop, SlotWidth e SlotHeight preservam a região fornecida pelo chamador mesmo quando a origem final do conteúdo se situa fora dela, sob recorte
Políticas de paginação
dppAllowSplit | Preserva o comportamento predefinido e consolida qualquer fragmento válido cuja chamada de retorno comunique haver mais conteúdo |
|---|---|
dppKeepTogether | Devolve PDF_DYNAMIC_COMPONENT_RETRY para a primeira tentativa parcial ou invisível e depois permite a divisão ou o recurso de recorte selecionado na próxima tentativa válida do mesmo fragmento não consolidado |
dppRequireComplete | Devolve PDF_DYNAMIC_COMPONENT_RETRY até a chamada de retorno comunicar que não resta conteúdo e o retângulo usado completo caiba na ranhura ou permaneça visível através de redução proporcional de escala |
Uma repetição descarta a tentativa de Form XObject, preserva a página de destino, o instantâneo do componente, a flag de conclusão e a contagem de composição, e devolve um registo Placement vazio
KeepTogetherRetryPending identifica o estado de recurso de uso único e é limpo depois de uma consolidação bem-sucedida, de Reset ou de AttachComponent
Restrições de espaço de fluxo
MinimumSlotHeight | Devolve PDF_DYNAMIC_COMPONENT_RETRY antes de clonar ou invocar o componente quando a ranhura de destino é mais baixa do que a altura configurada |
|---|---|
MinimumFollowingHeight | Aplica-se apenas a um fragmento de conteúdo final e exige que a respetiva altura resolvida mais a altura seguinte reservada caibam na ranhura |
Uma repetição por altura seguinte descarta a tentativa isolada preservando os fragmentos anteriormente consolidados, permitindo que um título, um rótulo ou uma introdução curta se mova com a primeira região utilizável do componente seguinte
LastRetryReason distingue repetições de componente inteiro, de conclusão estrita, de ranhura mínima e de espaço seguinte, enquanto LastRequiredSlotHeight comunica a altura exigida conhecida para restrições de espaço de fluxo
A verificação de ranhura mínima corre antes da clonagem do componente e da captura do formulário, pelo que as regiões baixas repetidamente recusadas não incorrem em custo de chamada de retorno de componente nem de página temporária
Valores devolvidos
PDF_DYNAMIC_COMPONENT_ERROR | O pedido, a callback do componente, a geometria do resultado ou a colocação do Form falhou, e nenhum estado foi confirmado |
|---|---|
PDF_DYNAMIC_COMPONENT_MORE | O conteúdo foi confirmado e o componente pediu outra ranhura de página |
PDF_DYNAMIC_COMPONENT_COMPLETE | O componente concluiu, ou a sessão já estava concluída e nenhuma callback foi feita |
PDF_DYNAMIC_COMPONENT_RETRY | A política de paginação ou de espaço de fluxo selecionada adiou a colocação sem confirmar conteúdo nem estado |
Exemplo
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;
Consulte também
BeginFormXObject, ReleaseCapturedPage, ApplyRepeatedPageFragment