Importação de mídia paginada HTML5

THPDFHTMLImporter.RenderHTML5 converte marcação HTML5 tolerante e CSS de impressão em conteúdo PDF paginado preservando o caminho legado compacto RenderHTML

Comprimentos CSS e o Margin, BaseFontSize, ListIndent e BlockSpacing do importer estão em pontos, de modo que ambos os renderers produzem a mesma página qualquer que seja a THotPDF.Resolution definida; o seu próprio desenho antes e depois da importação continua usando 1/Resolution de polegada

Declaração

function RenderHTML5(
  const HTML: WideString;
  const AuthorStyleSheet: WideString = ''
): Boolean;

function HPDFRenderHTML5Document(
  Doc: THotPDF;
  const HTML: WideString;
  const AuthorStyleSheet: WideString = '';
  MarginPt: Single = 72;
  const FontName: AnsiString = 'Arial';
  FontSize: Single = 12
): Boolean;

Contrato de perfil

HTML5ProfileVersion retorna 1 e HTML5ProfileMilestones relata análise e cascata, layout paginado, tabelas e formulários e recursos limitados

Parágrafos medidos e direção

Parágrafos quebram linha usando os avanços medidos da fonte atual, incluindo mudanças de fonte, runs bold e italic, letter spacing, word spacing, quebras de linha explícitas e fronteiras de caracteres do Leste Asiático; alinhamento e decoração se aplicam separadamente a cada linha resultante

direction: ltr, direction: rtl e o atributo dir do HTML selecionam a direção do parágrafo; dir="auto" usa a direção Unicode do primeiro caractere forte

No Windows, runs de escrita bidirecional são resolvidos com Uniscribe e reordenados através de fronteiras de estilo, enquanto o engine de texto PDF existente cuida do shaping de glifos dentro de cada run; a direção do documento, as viewer preferences e o estado de texto salvo da página são restaurados depois da linha

Overrides de direção inline, bdi e bdo atualmente usam a ordenação do parágrafo e produzem um diagnóstico hdkLayoutFallback; unicode-bidi está fora deste perfil, e o shaping de scripts ainda segue a configuração de shaping do documento

Fragmentação de parágrafos

widows e orphans são inteiros positivos herdáveis, ambos com padrão 2; a paginação usa as line boxes medidas em vez de um número estimado de caracteres

O importer move um parágrafo ou ajusta a divisão dele para deixar o número mínimo de linhas solicitado antes e depois de uma quebra de página; break-inside: avoid mantém um parágrafo junto quando ele cabe em uma página nova

Quando uma página não comporta a restrição solicitada, a renderização progride relaxando a restrição e registrando hdkPaginationConstraint; cada fragmento de página recebe o background e a border próprios

Hifenização opcional

hyphens: none suprime quebras discricionárias, e o padrão hyphens: manual usa U+00AD ou ­; um hífen visível é emitido apenas quando a quebra selecionada é usada

hyphens: auto adicionalmente chama OnHyphenate com a palavra e o valor de lang do HTML herdado; sem callback, ele mantém as quebras manuais e relata um fallback de layout, porque nenhum dicionário de idioma é embarcado

Posições de quebra contam unidades de código UTF-16 a partir do início da palavra; posições inválidas, fora do intervalo, que dividam surrogates ou quebrem combining marks básicos são ignoradas

THPDFHTMLHyphenationEvent = procedure(
  Sender: TObject;
  const WordText, Language: WideString;
  var BreakPositions: TArray<Integer>
) of object;

Caixas flex e grid limitadas

display: flex suporta row, row-reverse, column e column-reverse; filhos de linha usam widths explícitas ou dividem a largura restante, e valores positivos de flex-grow ponderam o espaço adicional

Linhas suportam justify-content start, end, center, space-between, space-around e space-evenly, mais alinhamento de eixo transversal start, end, center e stretch; o fluxo de coluna suporta layout vertical natural e emite um diagnóstico para distribuição de altura fixa ou alinhamento de eixo transversal não suportados

display: grid suporta colunas com tracks de comprimento fixo positivo e fr, incluindo repeat(n, tracks) limitado a até 64 colunas; células são colocadas na ordem de origem, preenchendo uma linha por vez

grid-column: span N e grid-column-end: span N permitem que um filho ocupe tracks consecutivos e os gaps intermediários; um item que não cabe na linha atual vai para a próxima linha, e spans maiores que a contagem de tracks produzem um fallback de layout

flex-wrap: wrap inicia outra linha quando a width explícita e o gap do próximo item não cabem; cada linha aplica flex-grow e justify-content de forma independente, enquanto row-reverse e RTL invertem posições dentro de cada linha sem mover itens entre linhas

gap aceita um ou dois comprimentos, com overrides independentes de row-gap e column-gap; linhas paralelas ficam em uma página e são verificadas antes da pintura

Filhos paralelos suportam blocos de texto com estilo inline, contêineres de bloco comuns aninhados recursivamente com padding, bordas e backgrounds, contêineres flex e grid aninhados, imagens e controles de formulário estáticos ou nativos

Imagens usam bytes fornecidos por callback ou data URI, retêm a proporção intrínseca quando nenhuma altura é especificada e são decodificadas uma vez por nó do DOM; preflight e fallback reutilizam a mesma imagem em cache sem consumir outra requisição de recurso

Todas as caixas filhas são medidas antes de qualquer linha paralela ser pintada, então conteúdo não suportado ou grande demais cai no fluxo vertical da página sem repetir linhas pintadas anteriormente; o planejamento aninhado é limitado a 64 níveis e consome o orçamento existente de operações de layout

Filhos que quebram linha sem width explícita ocupam uma linha completa; tabelas e listas dentro de filhos paralelos, flex basis e shrink, wrap-reverse, dimensionamento intrínseco de tracks, tracks de linha e row spans de grid e posicionamento explícito de grid permanecem fora deste perfil e produzem diagnósticos observáveis

Diagnósticos de CSS não suportado

Diagnostics expõe records contendo Kind, Subject, Value e MessageText; OnDiagnostic recebe a mesma informação durante a renderização

Propriedades desconhecidas, valores não suportados, seletores não suportados e at-rules não suportadas são ignorados com um diagnóstico, incluindo declarações em regras de stylesheet não usadas; pseudo seletores são pulados em vez de tratados como seletores de tipo comuns

StrictCSS, desabilitado por padrão, levanta EHPDFHTMLUnsupportedCSS a cada diagnóstico; o conteúdo anterior pode já ter sido emitido, então chamadores que exigem importação all-or-nothing devem usar um documento separado

MaxDiagnostics tem padrão 256 e limita os records retidos; DiagnosticCount e a entrega por callback continuam observáveis depois que o limite de armazenamento é atingido, e um limite não positivo desabilita o armazenamento de records

Recursos limitados

Folhas de estilo externas, imagens e fontes @font-face ficam desabilitadas a menos que OnResource forneça os bytes delas, de modo que a importação HTML nunca abre um arquivo ou conexão de rede implicitamente

@font-face suporta uma fonte url(...), format('truetype') ou format('opentype') opcional, um alias de família, estilo normal ou italic e peso normal, bold, 400 ou 700; font-display aceita as políticas padrão porque a importação offline carrega recursos de forma síncrona

Fontes precisam ser recursos sfnt TrueType ou OpenType embutíveis com nome de família Windows ASCII de no máximo 31 caracteres; WOFF, coleções de fontes, local(...), descritores de variável e listas de fontes produzem diagnósticos

Fontes aceitas são registradas privadamente na memória do processo no Windows e permanecem de propriedade do documento até que ele seja destruído, então liberar o importer antes do EndDoc não invalida o embedding de fonte diferido

Recursos data: e resultados de callback compartilham os limites MaxResources, MaxResourceBytes e MaxTotalResourceBytes

MaxDecodedImageBytes tem padrão 128 MiB e limita independentemente o cache de imagens decodificadas a quatro bytes por pixel; dimensões de BMP e PNG são checadas antes da decodificação, e toda imagem aceita é checada antes de ser retida

MaxDOMNodes, MaxCSSRules e MaxLayoutOperations limitam independentemente a análise, a construção da cascata e o trabalho de layout

THPDFHTMLResourceEvent = procedure(
  Sender: TObject;
  const URI: WideString;
  ResourceKind: THPDFHTMLResourceKind;
  var Data: TBytes;
  var ContentType: string;
  var Handled: Boolean
) of object;

Estatísticas

THPDFHTMLImportStatistics relata a versão do perfil, nós analisados, regras CSS, operações de layout, quebras de página, tabelas, controles de formulário, solicitações de recursos, cargas aceitas e rejeitadas, bytes de recursos aceitos, linhas de texto medidas, linhas hifenizadas, diagnósticos, contêineres flex e contêineres grid

OnLineLayout recebe os índices com base zero de página e de linha de parágrafo da linha, a origem, a width e a height medidas, o texto lógico, a direção e a flag de hifenização depois que o texto PDF real foi emitido

Toda chamada RenderHTML5 redefine o registro de estatísticas, e violações de orçamento geram EHPDFHTMLImportBudget

Exemplo

Importer := THPDFHTMLImporter.Create(Doc);
try
  Importer.CreateAcroForms := True;
  Importer.MaxResources := 16;
  Importer.RenderHTML5(
    '<style>@page { margin: 36pt } ' +
    'table { width: 100% }</style>' +
    '<h1>Invoice</h1>' +
    '<table><tr><td>Total</td><td>42</td></tr></table>' +
    '<input name="approved" type="checkbox">'
  );
finally
  Importer.Free;
end;

Veja também: THPDFPage.TextOutHTML, Declarative Layout DOM, AcroForm Support