DOM de layout declarativo
HPDFLayoutDOM construye componentes de documento reutilizables sobre THPDFLayoutElement, MeasureLayoutElement, PlaceLayoutElement, fragmentos de overflow propios y ImmediateFlushLayout
Composición de documentos y secciones
Document := THPDFDOMDocument.Create;
Renderer := THPDFDOMRenderer.Create;
try
Section := Document.AddSection;
Section.PageWidth := 595.28;
Section.PageHeight := 841.89;
Section.Header := THPDFDOMText.Create('Quarterly report');
Section.Footer := THPDFDOMText.Create('Confidential');
Section.Body.Style.Padding := 12;
Section.Body.Style.Spacing := 8;
Section.Body.AddText(BodyText, 'Narrative');
PDF.OutputStream := Output;
PDF.ImmediateFlushLayout := True;
Statistics := Renderer.Render(Document, PDF);
finally
Renderer.Free;
Document.Free;
end;
THPDFDOMDocument es dueño de sus secciones, cada THPDFDOMSection es dueña de su body, header, footer y style, y cada stack o contenedor es dueño de los componentes adjuntos a él
THPDFDOMRenderer.Render inicia y cierra el documento destino, crea una página nueva para cada sección nueva, repite el furniture de la sección en las páginas de continuación y devuelve estadísticas de páginas, colocación, splits, furniture, estructura, marked-content, artifacts y continuación máxima
Configure todas las opciones de THotPDF de salida, compresión, conformance, capas e immediate-flush antes de llamar a Render
GenerateStructure es True por defecto, así que el renderer también construye un árbol de estructura lógica seguro ante continuaciones y usa THPDFDOMDocument.Language cuando el destino no tiene idioma
Componentes
THPDFDOMTextenvuelve texto Unicode, cachea los límites de línea por ancho y métricas de texto heredadas, y divide mediante rangos de caracteres del source sin copiar el texto fuenteTHPDFDOMSpacerreserva espacio vertical y puede dividirse entre páginasTHPDFDOMStackdispone verticalmente sus hijos propios con padding y spacing heredadosTHPDFDOMContainerañade una caja con estilo alrededor de un hijo propio y reenvía las continuaciones de splitTHPDFDOMTableresuelve columnas ponderadas, dibuja filas y celdas con estilo y repite las filas de header iniciales en las páginas de continuaciónTHPDFDOMListcrea elementos de lista numerados o sin numerar con componentes de label y bodyTHPDFDOMImagees dueña de un gráfico clonado, resuelve dimensiones explícitas y aporta semántica de figura y control de compresión
Todos los componentes exponen contratos estables de Name, Path, Style, Clone, Measure, Draw y Split, más rol semántico, idioma, texto alternativo, texto de reemplazo, texto de expansión y overrides de artifact
El recorrido del body de nivel superior es lineal y no clona componentes; las continuaciones de texto y de tablas conservan metadatos de rango o de porción de fila en lugar de copiar el árbol de contenido completo
Herencia de estilos
THPDFDOMStyle resuelve el nombre de fuente, el tamaño, los estilos, el color del texto, el fondo, el borde, el padding, el spacing y la altura de línea a través de su cadena de padres
El style de una sección es el padre de su body y su furniture, el style de un stack o contenedor es el padre de sus hijos, y el style de una tabla fluye a través de las filas hasta las celdas
Solo los valores asignados explícitamente sobrescriben al padre; Clear elimina las asignaciones locales y el enlace al padre, mientras que Assign copia las asignaciones locales sin copiar la propiedad ni la ascendencia
Las cadenas de padres de más de 64 niveles se rechazan como cíclicas o ilimitadas
Fábricas de componentes reutilizables
THPDFDOMComponentFactory es una función anónima que crea una instancia de THPDFDOMComponent propiedad del caller por cada invocación
Document.RegisterComponent('notice',
function: THPDFDOMComponent
begin
Result := THPDFDOMContainer.Create(
THPDFDOMText.Create('Reusable notice'));
end);
Section.Body.Add(Document.CreateComponent('notice'));
Los nombres de factories no distinguen mayúsculas y son únicos, cada llamada debe devolver una instancia de componente nueva, y el contenedor receptor toma la propiedad después de Add
Use SetHeaderClone, SetFooterClone o Clone cuando un componente declarado deba reutilizarse en varios sitios de propiedad
Tablas con header repetido
Table := THPDFDOMTable.Create('Orders');
Table.AddColumn(1);
Table.AddColumn(3);
Header := Table.AddRow(18, True);
Header[0].Text := 'ID';
Header[1].Text := 'Description';
Row := Table.AddRow(22);
Row[0].Text := '1001';
Row[1].Text := 'Bounded streaming layout';
Section.Body.Add(Table);
Las filas de header deben ser contiguas y preceder a las filas del body, los pesos positivos de columna dividen el ancho disponible, y las alturas de fila son valores positivos explícitos
Cuando RepeatHeaders es true, un split requiere espacio para todas las filas de header iniciales y al menos una fila del body, lo que impide páginas de continuación con solo header
Paginación y fronteras de fallo
El renderer primero vuelve a medir cada componente contra el rectángulo de body restante, mueve un fragmento mínimo no divisible a una página nueva cuando es posible, y delega cada split válido a PlaceLayoutElement
Un elemento que no cabe en una página de body vacía lanza una excepción con su ruta estable de elemento en lugar de descartar contenido silenciosamente
MaximumContinuationDepth es 100,000 por defecto y acota los componentes malformados que devuelven repetidamente una continuación sin progreso
Las dimensiones de página de la sección deben ser positivas, los márgenes y los huecos de furniture no pueden ser negativos, y la geometría de header más footer debe dejar un rectángulo de body positivo
C++Builder
std::unique_ptr<THPDFDOMDocument> document(new THPDFDOMDocument());
THPDFDOMSection* section = document->AddSection();
section->Header = new THPDFDOMText(L"Report", "Header");
section->Body->AddText(L"Declarative content", "BodyText");
std::unique_ptr<THPDFDOMRenderer> renderer(new THPDFDOMRenderer());
THPDFDOMRenderStatistics statistics =
renderer->Render(document.get(), pdf.get());
El HPDFLayoutDOM.hpp generado expone las mismas superficies de documento, estilo, componente, tabla, sección, renderer y estadísticas