Pular para o conteúdo

Solução de problemas: fontes, subsetting e marcação

Estas entradas tratam de falhas de resolução e análise de fontes geradas por NextPDF\Exception\FontNotFoundException e NextPDF\Exception\FontParsingException. Elas também cobrem diagnósticos de cobertura de chinês, japonês e coreano (CJK) e problemas na árvore de estrutura que afetam a saída marcada. Cada entrada indica a exceção ou o teste exato para que você possa verificar a causa.

  • Sintoma. FontNotFoundException com uma mensagem no formato Font "<name>" not found. Searched: [<paths>].
  • Causa provável. A família de fontes ou o caminho de arquivo solicitado não existe, não pode ser lido ou está em um diretório de fontes que o runtime não consegue acessar. Os dados da fonte podem ser válidos, mas, ainda assim, o engine não consegue alcançá-los.
  • Evidência / diagnóstico. getContext() retorna font_name, search_paths e fallback_attempted. Use search_paths para revisar todos os locais que o engine tentou. Use fallback_attempted para confirmar se um fallback já foi executado.
  • Resolução.
    1. Compare o font_name solicitado com o arquivo de fonte que está de fato presente.
    2. Adicione o diretório que contém a fonte à configuração de diretórios de fontes ou corrija o caminho que você informou.
    3. Verifique se o usuário do runtime consegue ler o arquivo.
    4. Execute a chamada novamente.
  • Relacionado. Referência de exceções.
  • Sintoma. FontParsingException com uma mensagem no formato Failed to parse font file "<file>": <reason>.
  • Causa provável. O engine encontrou o arquivo de fonte, mas não consegue usar seu conteúdo: o cabeçalho pode estar truncado, o diretório de tabelas pode ser inválido ou uma tabela obrigatória pode estar ausente, como head, hhea ou OS/2.
  • Evidência / diagnóstico. getContext() retorna font_file e parse_error. parse_error nomeia o problema estrutural.
  • Resolução.
    1. Leia parse_error para identificar o defeito estrutural.
    2. Substitua o arquivo de fonte por uma cópia comprovadamente íntegra da mesma face.
    3. Execute a chamada novamente.
  • Relacionado. Referência de exceções.

Entrada: o subsetting falha em uma tabela de fonte malformada

Seção intitulada “Entrada: o subsetting falha em uma tabela de fonte malformada”
  • Sintoma. FontParsingException com um valor de font_file igual a font-subset e um parse_error como Invalid head table: too short, Invalid hhea table: too short, Invalid maxp table: too short ou Failed to unpack font data.
  • Causa provável. A fonte foi carregada inicialmente, mas uma tabela necessária para o subsetting está truncada ou não pode ser descompactada. O subsetter rejeita a fonte em vez de emitir um subconjunto defeituoso.
  • Evidência / diagnóstico. Quando uma tabela head, hhea ou maxp é curta demais ou uma descompactação falha, src/Typography/FontSubsetter.php gera FontParsingException com o token literal font-subset como nome do arquivo. O token indica que a falha ocorreu durante o subsetting, e não no carregamento inicial.
  • Resolução.
    1. Substitua a fonte de origem por uma cópia completa e não truncada da mesma face.
    2. Se uma ferramenta de build gera a fonte, gere-a novamente e verifique se as tabelas head, hhea e maxp estão completas.
    3. Execute o build novamente.
  • Relacionado. Validação de PDF/A e PDF/UA.

Entrada: o texto CJK é renderizado com glifos ausentes

Seção intitulada “Entrada: o texto CJK é renderizado com glifos ausentes”
  • Sintoma. Texto em chinês, japonês ou coreano é renderizado como caixas em branco ou caracteres ausentes, e a cobertura CJK da fonte é incerta.
  • Causa provável. A fonte selecionada não cobre os blocos Unicode que o sistema de escrita exige. Cada sistema de escrita CJK exige blocos específicos, além dos blocos de ideogramas compartilhados.
  • Evidência / diagnóstico. src/Typography/CjkFontValidator.php fornece validateCoverage(FontInfo $font, CjkScript $script). O método retorna um CjkCoverageResult com o percentual de cobertura e quaisquer blocos abaixo do limite de relatório de 50%. O validador trabalha por amostragem de codepoints. Ele serve como diagnóstico e não modifica o carregamento de fontes.
  • Resolução.
    1. Execute CjkFontValidator::validateCoverage() para a fonte e o sistema de escrita de destino.
    2. Consulte o missingRanges para ver quais blocos não estão cobertos, por exemplo, Bopomofo para chinês tradicional, Hiragana e Katakana para japonês e Hangul Syllables para coreano.
    3. Selecione uma fonte que cubra esses blocos ou adicione uma fonte de fallback que os cubra.
    4. Execute a renderização novamente e verifique a cobertura de novo.
  • Relacionado. Referência de exceções.

Entrada: a CMap predefinida não corresponde ao sistema de escrita CJK

Seção intitulada “Entrada: a CMap predefinida não corresponde ao sistema de escrita CJK”
  • Sintoma. O texto CJK é mapeado para os glifos errados ou o documento usa uma CMap predefinida que não corresponde ao seu idioma.
  • Causa provável. O sistema de escrita detectado determina o nome da CMap predefinida da Adobe. Uma fonte que cobre apenas o bloco de ideogramas compartilhado, sem nenhum bloco específico do sistema de escrita, é detectada como chinês simplificado por design.
  • Evidência / diagnóstico. CjkFontValidator::detectScript() retorna o sistema de escrita detectado, e resolvePredefinedCMapName() o mapeia: chinês simplificado para UniGB-UTF16-H, chinês tradicional para UniCNS-UTF16-H, japonês para UniJIS-UTF16-H e coreano para UniKS-UTF16-H. Se nenhum bloco específico do sistema de escrita estiver presente, a detecção recorre ao chinês simplificado.
  • Resolução.
    1. Confirme que a fonte inclui o bloco específico do sistema de escrita: Bopomofo para chinês tradicional, Hiragana ou Katakana para japonês e Hangul para coreano.
    2. Se o documento estiver em chinês tradicional, mas a fonte não tiver bloco Bopomofo, selecione uma fonte que inclua esse bloco, para que a detecção resolva o sistema de escrita pretendido.
    3. Execute a renderização novamente.
  • Relacionado. Referência de exceções.

Entrada: o conteúdo marcado não produz uma árvore de estrutura utilizável

Seção intitulada “Entrada: o conteúdo marcado não produz uma árvore de estrutura utilizável”
  • Sintoma. Um build com marcação não produz estrutura, ou uma verificação de acessibilidade posterior relata uma árvore de estrutura vazia ou ausente.
  • Causa provável. O build emitiu conteúdo fora do caminho de marcação, de modo que nenhum elemento de estrutura foi criado. A árvore de estrutura permanece vazia.
  • Evidência / diagnóstico. src/Accessibility/StructureTree.php e src/Accessibility/TaggedContentEmitter.php constroem a árvore de estrutura a partir do conteúdo marcado. O teste tests/Integration/Accessibility/EmptyTaggedPdfDoesNotAdvertisePdfUa2Test.php confirma que uma árvore de estrutura vazia não anuncia PDF/UA-2.
  • Resolução.
    1. Confirme que o conteúdo é emitido pelo caminho de marcação, para que os elementos de estrutura sejam criados.
    2. Verifique se cada sequência de conteúdo marcado é mapeada para um elemento de estrutura.
    3. Execute o build novamente e inspecione a árvore de estrutura.
  • Relacionado. Validação de PDF/A e PDF/UA.

Entrada: a tag de idioma do elemento de estrutura é rejeitada

Seção intitulada “Entrada: a tag de idioma do elemento de estrutura é rejeitada”
  • Sintoma. Um build falha porque um valor de idioma em um elemento de estrutura ou no documento não é uma tag válida.
  • Causa provável. O idioma fornecido não é uma tag BCP-47 válida. O validador rejeita tags malformadas em vez de emiti-las.
  • Evidência / diagnóstico. src/Accessibility/Bcp47Validator.php valida a tag. Uma tag inválida gera src/Accessibility/InvalidBcp47TagException.php. tests/Unit/Conformance/PdfUa2Section844LangStrictTest.php exercita o requisito estrito de idioma do PDF/UA-2.
  • Resolução.
    1. Substitua o valor de idioma por uma tag BCP-47 válida, como en-US, de-DE ou zh-Hant-TW.
    2. Defina o idioma no elemento de estrutura específico quando uma passagem difere do idioma do documento.
    3. Execute o build novamente.
  • Relacionado. Validação de PDF/A e PDF/UA.
  • FontNotFoundException e FontParsingException relatam falhas diferentes. Não encontrada significa que o arquivo não pôde ser alcançado. Análise significa que o arquivo foi alcançado, mas seus bytes não são utilizáveis. Leia a classe para identificar qual falha ocorreu.
  • font-subset em font_file é um marcador deliberado para a etapa de subsetting, não um caminho real. Não procure por um arquivo chamado font-subset.
  • CjkFontValidator trabalha por amostragem de codepoints em vez de verificar cada um, de modo que seu número de cobertura é uma estimativa para seleção de fontes, não uma auditoria exata em bytes.
  • Uma árvore de estrutura vazia é relatada como não conforme com PDF/UA-2 por design. Este é o comportamento documentado do engine, não um defeito.

Glossário: subsetting de fontes · cobertura CJK · árvore de estrutura