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
THPDFDOMTextenvolve texto Unicode, armazena em cache limites de linha por largura e métricas de texto herdadas e divide por intervalos de caracteres de origem sem copiar o texto de origemTHPDFDOMSpacerreserva espaço vertical e pode se dividir entre páginasTHPDFDOMStackdispõe filhos de propriedade verticalmente com preenchimento e espaçamento herdadosTHPDFDOMContaineradiciona uma caixa estilizada ao redor de um filho de propriedade e encaminha continuações de divisãoTHPDFDOMTableresolve colunas ponderadas, desenha linhas e células estilizadas e repete linhas de cabeçalho iniciais em páginas de continuaçãoTHPDFDOMListcria itens de lista numerados ou não numerados com componentes de rótulo e corpoTHPDFDOMImagepossui um gráfico clonado, resolve dimensões explícitas e fornece semântica de figura e controle de compactação
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