DOM de maquetación declarativa

HPDFLayoutDOM construye componentes de documento reutilizables sobre THPDFLayoutElement, MeasureLayoutElement, PlaceLayoutElement, fragmentos de desbordamiento propios y ImmediateFlushLayout

Composición de documento 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 posee sus secciones, cada THPDFDOMSection posee su cuerpo, cabecera, pie y estilo, y cada pila o contenedor posee los componentes que se le adjuntan

THPDFDOMRenderer.Render inicia y finaliza el documento de destino, crea una página nueva para cada sección, repite el mobiliario de sección en las páginas de continuación y devuelve estadísticas de página, colocación, división, mobiliario, estructura, contenido marcado, artefacto y continuación máxima

Establezca todas las opciones de THotPDF de salida, compresión, conformidad, capa y vaciado inmediato antes de llamar a Render

GenerateStructure tiene como valor predeterminado True, por lo que el renderizador también construye un árbol de estructura lógica seguro para la continuación y usa THPDFDOMDocument.Language cuando el destino no tiene idioma

Componentes

Todos los componentes exponen contratos estables de Name, Path, Style, Clone, Measure, Draw y Split, además de rol semántico, idioma, texto alternativo, texto de reemplazo, texto de expansión y anulaciones de artefacto

El recorrido del cuerpo de nivel superior es lineal y no clona componentes; las continuaciones de texto y tabla conservan metadatos de rango o de rebanada de fila en lugar de copiar el árbol de contenido completo

Herencia de estilo

THPDFDOMStyle resuelve el nombre de fuente, el tamaño, los estilos, el color de texto, el fondo, el borde, el relleno, el espaciado y la altura de línea a través de su cadena de padres

Un estilo de sección es el padre de su cuerpo y mobiliario, un estilo de pila o contenedor es el padre de sus hijos, y el estilo de tabla fluye a través de las filas hasta las celdas

Solo los valores asignados explícitamente anulan 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 llamador por 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 fábrica no distinguen mayúsculas y son únicos, cada llamada debe devolver una nueva instancia de componente y el contenedor receptor toma la propiedad después de Add

Use SetHeaderClone, SetFooterClone o Clone cuando un componente declarado deba reutilizarse en varios puntos de propiedad

Tablas con cabecera repetida

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 cabecera deben ser contiguas y preceder a las filas de cuerpo, los pesos de columna positivos dividen la anchura disponible y las alturas de fila son valores positivos explícitos

Cuando RepeatHeaders es true, una división requiere espacio para todas las filas de cabecera iniciales y al menos una fila de cuerpo, lo que evita páginas de continuación solo con cabecera

Límites de paginación y fallo

El renderizador primero vuelve a medir cada componente contra el rectángulo de cuerpo restante, mueve un fragmento mínimo indivisible a una página nueva cuando es posible y delega cada división válida en PlaceLayoutElement

Un elemento que no cabe en una página de cuerpo vacía lanza una excepción con su ruta de elemento estable en lugar de descartar contenido en silencio

MaximumContinuationDepth tiene como valor predeterminado 100 000 y limita los componentes malformados que devuelven repetidamente una continuación sin progreso

Las dimensiones de página de sección deben ser positivas, los márgenes y los huecos de mobiliario no pueden ser negativos, y la geometría de cabecera más pie debe dejar un rectángulo de cuerpo 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

APIs relacionadas