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

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

APIs relacionadas