TPDFlibDynamicComponentSession
Diseño de página, paginación, tipos de datos
Descripción
Compone un componente con estado una página de destino a la vez sin construir por adelantado contenido de páginas posteriores
Cada intento corre sobre un clon dentro de un Form XObject aislado y confirma el clon solo después de que el contenido validado se haya colocado con éxito
La colocación extendida puede rifiutare el desbordamiento, recortar el contenido de tamaño natural o reducirlo proporcionalmente alineándolo dentro de una ranura de destino
La política de paginación puede permitir la división normal, diferir el primer fragmento parcial a una región nueva o exigir que el componente completo permanezca visible antes de confirmar nada
Las restricciones de espacio de flujo pueden rechazar una región corta antes de invocar al componente o reservar altura suficiente tras su fragmento final para un componente siguiente
Un resultado rechazado, una llamada de dibujo fallida o una excepción de callback elimina la página temporal, restaura la página seleccionada por el llamador y deja tanto el contenido de destino como el estado del componente actual sin cambios
TPDFlib adjunta permanece siendo propiedad del llamador y debe sobrevivir a la sesión
Declaración
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 del componente
CloneComponentdevuelve una copia independiente del llamador de todo el estado de paginación mutableComposedibuja a través deContext.LibraryInstanceen coordenadas locales de Form cuyo tamaño disponible esAvailableWidthporAvailableHeightPageNumberidentifica la página de destino incluso aunque la biblioteca seleccione una página temporal aislada mientras el callback se ejecuta- El callback puede usar las API de dibujo y de contenido pero no debe cambiar documentos, páginas ni contenedores de dibujo anidados
- Los resultados de contenido requieren valores
UsedWidthyUsedHeightfinitos y positivos dentro del lienzo de contenido - El rectángulo usado comienza en la coordenada local cero y debe acotar todo el contenido visible del componente
- Un resultado sin contenido es válido solo cuando
HasMoreContentesFalsey ambas dimensiones usadas son cero - Devolver cero rechaza el intento; las excepciones lanzadas se propagan después de que el estado temporal se ha limpiado
Métodos
| Create | Adjunta una biblioteca propiedad del llamador y clona el componente suministrado en instantáneas inicial y actual independientes |
|---|---|
| AttachComponent | Reemplaza atómicamente ambas instantáneas con clones de un componente propiedad del llamador y limpia el estado de finalización |
| Reset | Restaura un nuevo clon actual desde la instantánea inicial y restablece el recuento de composiciones exitosas |
| CloneCurrentComponent | Devuelve un clon propiedad del llamador para inspeccionar el estado actual del componente confirmado |
| CreateLayoutOptions | Construye configuraciones tipadas de lienzo natural, desbordamiento, alineación, paginación y espacio de flujo para la colocación extendida |
| ComposeNext | Compone una ranura de página, valida y coloca su Form XObject, libera el manejador de captura y confirma el estado de trabajo |
| ComposeNextLayout | Compone sobre el lienzo natural configurado, aplica la política de desbordamiento y alineación y devuelve datos de fuente, ranura y transformación final |
Desbordamiento y colocación
dopReject | Rechaza el contenido más ancho o más alto que la ranura sin cambiar el contenido de destino ni el estado confirmado del componente |
|---|---|
dopClip | Mantiene la escala 1 e intersecta la ruta de recorte de la página con la ranura de destino antes de invocar el Form XObject |
dopScaleDown | Usa la relación menor de ancho o alto solo cuando es necesario y nunca amplía el contenido |
La alineación se resuelve a partir del rectángulo usado transformado, de modo que el contenido centrado o recortado al final selecciona la porción visible correspondiente
Transform[M11 M12 M21 M22 MDX MDY]
SlotLeft informa la matriz de disposición lógica SlotTop de las coordenadas locales del componente a las coordenadas finales del documento de arriba hacia abajo
SlotWidth, SlotHeight,
Políticas de paginación
dppAllowSplit | Preserva el comportamiento predeterminado y confirma cualquier fragmento válido cuyo callback informe más contenido |
|---|---|
dppKeepTogether | Devuelve PDF_DYNAMIC_COMPONENT_RETRY para el primer intento parcial o no visible, luego permite la división o el recorte de respaldo seleccionado en el siguiente intento válido para el mismo fragmento sin confirmar |
dppRequireComplete | Devuelve PDF_DYNAMIC_COMPONENT_RETRY hasta que el callback informe que no queda contenido y el rectángulo usado completo quepa en la ranura o permanezca visible mediante la reducción proporcional |
Placement
KeepTogetherRetryPending vacío
Reset identifica el estado de respaldo de una sola vez y se limpia después de una confirmación exitosa, AttachComponent o
Restricciones de espacio de flujo
MinimumSlotHeight | Devuelve PDF_DYNAMIC_COMPONENT_RETRY antes de clonar o invocar el componente cuando la ranura de destino es más corta que la altura configurada |
|---|---|
MinimumFollowingHeight | Se aplica solo a un fragmento de contenido final y requiere que su altura resuelta más la altura siguiente reservada quepan en la ranura |
Un reintento por altura siguiente descarta el intento aislado mientras preserva los fragmentos confirmados anteriores, permitiendo que un encabezado, una etiqueta o una entrada corta se muevan con la primera región utilizable del siguiente componente
LastRetryReason distingue i reintentos de componente completo, de finalización estricta, de ranura mínima y de espacio siguiente, mientras LastRequiredSlotHeight informa la altura requerida conocida para las restricciones de espacio de flujo
La comprobación de ranura mínima corre antes de clonar el componente y capturar el Form, así que las regiones cortas rechazadas repetidamente no incurren en coste de callback del componente ni de página temporal
Valores devueltos
PDF_DYNAMIC_COMPONENT_ERROR | La solicitud, el callback del componente, la geometría del resultado o la colocación del Form fallaron y no se confirmó ningún estado |
|---|---|
PDF_DYNAMIC_COMPONENT_MORE | El contenido se confirmó y el componente solicitó otra ranura de página |
PDF_DYNAMIC_COMPONENT_COMPLETE | El componente completó, o la sesión ya estaba completa y no se hizo ningún callback |
PDF_DYNAMIC_COMPONENT_RETRY | La política seleccionada de paginación o de espacio de flujo difirió la colocación sin confirmar contenido ni estado |
Ejemplo
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;
Véase también
BeginFormXObject, ReleaseCapturedPage, ApplyRepeatedPageFragment