Skip to content

fix(danfse): incorporar Liberation Sans como tipografia livre padrão #137

Closed

Description

@vitormattos

Objetivo

Garantir que o DANFSe gerado por `nfse-php` utilize, por padrão e sem configuração do consumidor, Liberation Sans Regular e Bold efetivamente incorporadas ao PDF, com distribuição legalmente adequada e comportamento previsível em servidores Linux.

A adoção de Liberation Sans é uma decisão arquitetural de substituição livre. Não representa atendimento literal aos nomes Arial e Microsoft Sans Serif exigidos na NT008 v1.02, item 2.4.

Comportamento atual

`DanfseGenerator` configura Helvetica como fonte padrão do Dompdf. `HTMLTemplate.php` contém nomes de famílias alternativas no CSS, mas a biblioteca não distribui os arquivos Liberation Sans nem comprova sua seleção efetiva no PDF padrão.

`DanfseFonts` já permite fontes TrueType locais externas, com validação de caminhos, registro CSS e isolamento de famílias/cache. Esse comportamento e a API pública devem ser preservados.

A suíte visual já gera documentos sintéticos, incluindo um teste de fontes externas com DejaVu Sans. O teste não comprova que a configuração padrão utiliza fontes livres incorporadas.

Implementação

  • Incorporar os arquivos necessários de Liberation Sans 2.x Regular e Bold, obtidos de distribuição oficial identificável, verificando versão, integridade, autoria, SIL OFL 1.1, nomes reservados e direitos de redistribuição/incorporação.
  • Incluir licença e atribuições pertinentes no pacote e no inventário REUSE, sem reclassificar as fontes como AGPL.
  • Garantir que os arquivos estejam disponíveis tanto no checkout quanto nas distribuições Composer, sem downloads em tempo de execução.
  • Registrar uma tipografia padrão interna no Dompdf, cobrindo rótulos, valores, cabeçalhos, campos destacados e marcas de estado. Não depender de correspondências de fontes instaladas no sistema operacional.
  • Impedir fallback silencioso para Helvetica, Times ou outras famílias inesperadas. A falta de recursos obrigatórios deve produzir erro diagnóstico apropriado.
  • Preservar o suporte a `DanfseConfig(fonts: new DanfseFonts(...))`, incluindo arquivos locais externos e isolamento de cache.
  • Preservar a proteção contra colisões do cache estático de `FontMetrics` entre renderizações consecutivas, sem impor configuração administrativa adicional ao consumidor.
  • Manter o contrato de página única A4 retrato, com conteúdo fiscal obrigatório preservado e abreviações de texto livre somente onde já permitidas.
  • Atualizar apenas o contrato estável em `docs/danfse-v2-rendering.md`, distinguindo compatibilidade funcional/visual de conformidade nominal à NT008.

A abordagem interna de registro e cache deve ser escolhida após testar o comportamento real das versões Dompdf suportadas (`^2.0 || ^3.0`). Evitar novas dependências ou APIs públicas quando desnecessárias.

Critérios de aceitação

  • A geração padrão funciona em ambiente limpo, sem fontes proprietárias e sem configuração externa.
  • `pdffonts` identifica as fontes Liberation Sans efetivas, incluindo Regular e Bold quando utilizadas, com `emb=yes` e sem substituições inesperadas.
  • Um arquivo de fonte ausente, ilegível ou inválido não resulta silenciosamente em PDF com outra família.
  • Caracteres portugueses, acentuação, símbolos monetários e caracteres especiais esperados são renderizados corretamente.
  • O HTML e o PDF preservam os rótulos, conteúdos, tamanhos mínimos e pesos exigidos para a apresentação, exceto pela divergência nominal das famílias.
  • Casos sintéticos de nomes, municípios, endereços, descrições e informações complementares extensas mantêm legibilidade e uma única página A4.
  • Ausência, zero real e valores informados permanecem distintos nos campos fiscais.
  • Continuam corretos os cenários de ISSQN, retenções, IBS/CBS, regime especial ausente/0/outros códigos, produção restrita, cancelamento e substituição.
  • Renderizações padrão → personalizada → padrão e personalizada A → personalizada B, no mesmo processo PHP, não contaminam a seleção de fontes nem o cache.
  • Testes de empacotamento comprovam que binários, licença e atribuições acompanham a instalação Composer.
  • A inspeção visual de PDFs sintéticos compara os casos relevantes com a referência anterior, incluindo canhoto, margens, bordas, contraste e quebras de linha.
  • A documentação declara expressamente a divergência tipográfica nominal da NT008, sem alegar aprovação oficial da substituição.
  • A API pública de `DanfseConfig`, `DanfseFonts` e `DanfseGenerator` permanece compatível, ou eventual mudança necessária possui justificativa e testes de migração.

Verificação

Reaproveitar e ampliar:

  • `tests/Unit/Danfse/DanfseGeneratorTest.php`
  • `tests/Unit/Danfse/DanfseGoldenReferenceTest.php`
  • `tools/bin/render-danfse-visual-fixtures.php`
  • `.github/workflows/danfse-visual.yml`

Executar `composer test`, `composer cs:check`, `composer psalm`, REUSE e os checks pertinentes. Usar `pdfinfo`, `pdffonts`, extração de texto e inspeção visual. Conservar evidências sintéticas nos artefatos da CI/PR, sem exigir igualdade byte a byte dos PDFs.

Não reduzir assertions nem remover cenários anteriores para obter CI verde.

Fora de escopo

  • Redistribuir ou baixar automaticamente fontes Microsoft.
  • Criar telas de configuração, upload ou download de fontes.
  • Alterar XML fiscal, DPS, tributos, emissão, assinatura digital ou documentos históricos.
  • Implementar regras fiscais pertencentes ao emissor.
  • Produzir documentação versionada de andamento ou auditoria transitória.

Referências

Activity

  1. added theissue type on Oct 12, 2026
  2. vitormattos commented on Oct 13, 2026

    @vitormattos
    MemberAuthor

    Aceite técnico da #137 — PR #138 integrado

    Auditei a main no commit 22b71d6b1a0949197412b625759d8015d32c1b54, com a mesma árvore de código do último SHA aprovado do PR #138 (f344818c826c28773400cf75e88511ee4ac78770).

    Critérios comprovados:

    • Liberation Sans 2.1.5 Regular/Bold incorporadas como padrão, sem Helvetica/Times inesperadas; pdffonts confirma emb=yes nos dez PDFs sintéticos analisados.
    • Geração de página única A4 (pdfinfo 10/10), acentuação e símbolos monetários extraídos corretamente, rótulos e conteúdo fiscal preservados, inclusive nos cenários de regime especial ausente/0/9, imunidade, benefício zero e ISS não incidente.
    • Comparação visual e textual com a CI anterior à troca de fontes: sem perda de campos fiscais; texto livre muito longo sofre apenas abreviação adicional visível para manter A4.
    • Licença OFL-1.1, atribuições/nomes reservados no NOTICE, inventário REUSE, SHA-256 individuais e binários incluídos no composer archive; ausência/adulteração das fontes gera erro em vez de fallback silencioso.
    • Fontes personalizadas, API pública e sequência padrão → personalizada → padrão preservadas, incluindo isolamento de cache.
    • Dependência dompdf/dompdf: ^3.1.6 confirmada, sem retorno à série 2.x.

    Testes e CI: workflow visual aprovado com 145 testes / 532 assertions e artefato de dez PDFs; PHP 8.2, 8.3 e 8.4 com 464 testes / 1.784 assertions por versão. Os checks aplicáveis do SHA final registram 15 sucessos, um job automático ignorado, zero falhas; Psalm, estilo, dependências mínimas e REUSE aprovados. Referência visual anterior: run 38277928235.

    Limites registrados, sem exagerar o aceite:

    1. A origem 2.1.5, autoria e licença foram corroboradas por release oficial, checksum do arquivo distribuído registrado pelo MacPorts, licença igual à do upstream e binários idênticos aos de repositório independente anterior ao PR. Não houve comparação direta dos dois TTFs com o tarball oficial, portanto não se afirma essa equivalência byte a byte.
    2. A NT008 v1.02, item 2.4, especifica nominalmente Arial e Microsoft Sans Serif. Liberation Sans é alternativa livre, não conformidade nominal, e não há alegação de homologação ou aprovação oficial.
    3. Os testes de CI abrangem os comportamentos pertinentes; nem cada estado fiscal possui um PDF independente no artefato, nem se afirma execução de transmissão fiscal real.

    Conclusão: não há defeito reproduzível ou alteração adicional necessária no escopo da #137. Aceite técnico fundamentado e encerramento como concluída, preservadas as ressalvas acima. A atualização do pin do consumidor akaunting-nfse, se necessária, é integração separada, não consequência automática deste merge.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions