HTML5 Paged-Media Import

THPDFHTMLImporter.RenderHTML5 converte markup HTML5 tolerante e CSS de impressão em conteúdo PDF paginado, preservando o caminho compacto legacy de RenderHTML

Os comprimentos de CSS e o Margin, BaseFontSize, ListIndent e BlockSpacing do importador estão em pontos, pelo que ambos os renderizadores produzem a mesma página, seja qual for a THotPDF.Resolution; o seu próprio desenho antes e depois da importação continua a usar 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;

Profile contract

HTML5ProfileVersion devolve 1 e HTML5ProfileMilestones reporta parser e cascade, layout paginado, tabelas e formulários e recursos delimitados

Parágrafos medidos e direção

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

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

Em Windows, as sequências de scripts bidirecionais são resolvidas com o Uniscribe e reordenadas através de fronteiras de estilo, enquanto o motor de texto PDF existente trata o shaping de glifos dentro de cada sequência; a direção do documento, as preferências do visualizador e o estado de texto da página gravada são restaurados depois da linha

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

Fragmentação de parágrafos

widows e orphans são inteiros positivos herdáveis, ambos com a predefinição 2; a paginação usa as caixas de linha medidas em vez de um número estimado de carateres

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

Quando uma página não consegue cumprir a restrição pedida, a renderização progride ao relaxar a restrição e ao registar hdkPaginationConstraint; cada fragmento de página recebe o seu próprio fundo e borda

Hifenização opcional

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

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

As posições de quebra contam unidades de código UTF-16 desde o início da palavra; posições inválidas, fora do intervalo, que partem pares substitutos ou que partem marcas combinantes básicas 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; os filhos de linha usam larguras explícitas ou partilham a largura restante, e valores positivos de flex-grow ponderam o espaço adicional

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

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

grid-column: span N e grid-column-end: span N permitem que um filho ocupe colunas consecutivas e os gaps intermédios; um item que não caiba na linha atual passa à linha seguinte, e spans maiores do que a contagem de colunas produzem um fallback de layout

flex-wrap: wrap começa outra linha quando a largura explícita e o gap do item seguinte não cabem; cada linha aplica independentemente flex-grow e justify-content, 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; as linhas paralelas ficam na mesma página e são verificadas antes de serem pintadas

Os filhos paralelos suportam blocos de texto com estilo inline, contentores de bloco ordinários recursivamente aninhados com padding, bordas e fundos, contentores flex e grid aninhados, imagens e controlos de formulário estáticos ou nativos

As imagens usam bytes fornecidos por callback ou data URI, retêm o rácio intrínseco quando não é especificada altura, e são descodificadas uma vez por nó do DOM; preflight e fallback reutilizam a mesma imagem em cache sem consumir outro pedido de recurso

Todas as caixas filhas são medidas antes de qualquer linha paralela ser pintada, pelo que conteúdo não suportado ou demasiado grande recua para o fluxo vertical de página sem repetir linhas já pintadas; o planeamento aninhado fica limitado a 64 níveis e consome o orçamento existente de operações de layout

Filhos em linha sem largura explícita ocupam uma linha completa; tabelas e listas dentro de filhos paralelos, flex basis e shrink, wrap-reverse, dimensionamento intrínseco de colunas, linhas e spans de grid, e colocação explícita de grid ficam fora deste perfil e produzem diagnósticos observáveis

Diagnósticos de CSS não suportado

Diagnostics expõe registos 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 suportados são ignorados com um diagnóstico, incluindo declarações em regras de folhas de estilo de resto não usadas; pseudo seletores são ignorados em vez de tratados como seletores de tipo ordinários

StrictCSS, desativado por predefinição, lança EHPDFHTMLUnsupportedCSS perante um diagnóstico; conteúdo anterior pode já ter sido emitido, pelo que os chamadores que exijam importação tudo-ou-nada devem usar um documento separado

MaxDiagnostics tem a predefinição 256 e limita os registos retidos; DiagnosticCount e a entrega por callback continuam observáveis depois de atingido o limite de armazenamento, e um limite não positivo desativa o armazenamento de registos

Recursos limitados

As folhas de estilo, imagens e fontes @font-face externas estão desativadas, a menos que OnResource forneça os respetivos bytes, pelo que a importação de HTML nunca abre implicitamente um ficheiro nem uma ligação de rede

@font-face suporta uma origem 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 os recursos de forma síncrona

As fontes têm de ser recursos sfnt TrueType ou OpenType incorporáveis, com um nome de família Windows ASCII de, no máximo, 31 carateres; WOFF, coleções de fontes, local(...), descritores variáveis e listas de origens produzem diagnósticos

As fontes aceites são registadas em privado na memória do processo em Windows e permanecem na posse do documento até ser destruído, pelo que libertar o importador antes de EndDoc não invalida a incorporação de fontes diferida

Os recursos data: e os resultados de callbacks partilham os limites MaxResources, MaxResourceBytes e MaxTotalResourceBytes

MaxDecodedImageBytes tem a predefinição de 128 MiB e limita independentemente a cache de imagens descodificadas a quatro bytes por píxel; as dimensões BMP e PNG são verificadas antes da descodificação, e cada imagem aceite é verificada antes de ser retida

MaxDOMNodes, MaxCSSRules e MaxLayoutOperations limitam independentemente o parsing, a construção da cascade 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 reporta a versão do perfil, os nós analisados, as regras CSS, as operações de layout, as quebras de página, as tabelas, os controlos de formulário, os pedidos de recursos, os carregamentos aceites e rejeitados, os bytes de recursos aceites, as linhas de texto medidas, as linhas hifenizadas, os diagnósticos, os contentores flex e os contentores grid

OnLineLayout recebe os índices baseados em zero de página e de linha de parágrafo da linha, a origem, a largura e a altura medidas, o texto lógico, a direção e a flag de hifenização, depois de o texto PDF real ter sido emitido

Cada chamada a RenderHTML5 repõe o record de estatísticas, e as violações de orçamento lançam 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;

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