DOM de layout declarativo

HPDFLayoutDOM constrói componentes de documento reutilizáveis sobre THPDFLayoutElement, MeasureLayoutElement, PlaceLayoutElement, fragmentos de estouro de propriedade e ImmediateFlushLayout

Composição de documento e seção

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 possui suas seções, cada THPDFDOMSection possui seu corpo, cabeçalho, rodapé e estilo, e cada pilha ou contêiner possui os componentes anexados a ele

THPDFDOMRenderer.Render inicia e encerra o documento de destino, cria uma nova página para cada nova seção, repete a mobília da seção em páginas de continuação e retorna estatísticas de página, posicionamento, divisão, mobília, estrutura, conteúdo marcado, artefato e continuação máxima

Defina todas as opções de saída, compressão, conformidade, camadas e flush imediato de THotPDF antes de chamar Render

GenerateStructure assume o padrão True, de modo que o renderizador também constrói uma árvore de estrutura lógica segura para continuação e usa THPDFDOMDocument.Language quando o destino não tem idioma

Componentes

Todos os componentes expõem contratos estáveis de Name, Path, Style, Clone, Measure, Draw e Split mais papel semântico, idioma, texto alternativo, texto de substituição, texto de expansão e substituições de artefato

A travessia de corpo de nível superior é linear e não clona componentes; continuações de texto e tabela retêm metadados de intervalo ou fatia de linha em vez de copiar a árvore de conteúdo completa

Herança de estilo

THPDFDOMStyle resolve nome de fonte, tamanho, estilos, cor de texto, fundo, borda, preenchimento, espaçamento e altura de linha por meio de sua cadeia pai

Um estilo de seção é o pai de seu corpo e mobília, um estilo de pilha ou contêiner é o pai de seus filhos, e o estilo de tabela flui por linhas até células

Apenas valores explicitamente atribuídos substituem o pai; Clear remove atribuições locais e o vínculo pai, enquanto Assign copia atribuições locais sem copiar propriedade ou ancestralidade

Cadeias pai mais profundas que 64 níveis são rejeitadas como cíclicas ou ilimitadas

Fábricas de componentes reutilizáveis

THPDFDOMComponentFactory é uma função anônima que cria uma instância de THPDFDOMComponent de propriedade do chamador por invocação

Document.RegisterComponent('notice',
  function: THPDFDOMComponent
  begin
    Result := THPDFDOMContainer.Create(
      THPDFDOMText.Create('Reusable notice'));
  end);

Section.Body.Add(Document.CreateComponent('notice'));

Nomes de fábrica não diferenciam maiúsculas e minúsculas e são únicos, cada chamada deve retornar uma nova instância de componente e o contêiner receptor assume a propriedade após Add

Use SetHeaderClone, SetFooterClone ou Clone quando um componente declarado deve ser reutilizado em vários locais de propriedade

Tabelas com cabeçalho 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);

Linhas de cabeçalho devem ser contíguas e preceder as linhas de corpo, pesos de coluna positivos dividem a largura disponível e alturas de linha são valores positivos explícitos

Quando RepeatHeaders é verdadeiro, uma divisão exige espaço para todas as linhas de cabeçalho iniciais e pelo menos uma linha de corpo, impedindo páginas de continuação apenas com cabeçalho

Paginação e limites de falha

O renderizador primeiro remede cada componente contra o retângulo de corpo restante, move um fragmento mínimo indivisível para uma nova página quando possível e delega toda divisão válida a PlaceLayoutElement

Um elemento que não cabe em uma página de corpo vazia gera uma exceção com seu caminho de elemento estável em vez de descartar conteúdo silenciosamente

MaximumContinuationDepth assume o padrão de 100.000 e limita componentes malformados que retornam repetidamente uma continuação sem progresso

Dimensões de página de seção devem ser positivas, margens e lacunas de mobília não podem ser negativas, e a geometria de cabeçalho mais rodapé deve deixar um retângulo de corpo 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());

O HPDFLayoutDOM.hpp gerado exporta as mesmas superfícies de documento, estilo, componente, tabela, seção, renderizador e estatísticas

APIs relacionadas