Pular para o conteúdo
getnextpdf.com

Pro edição

Font Tools — Referência Profunda

Esta página é a referência em nível de contrato do NextPDF Pro Font Tools. A superfície é um único scanner, NextPDF\Pro\FontTools\FontDesubsetter, e dois objetos de valor imutáveis, SubsetInfo e DesubsetPlan. O scanner lê bytes brutos de PDF, reporta cada entrada /BaseFont distinta e sinaliza as entradas que seguem a convenção de nomenclatura de subconjuntos da ISO 32000-2:2020 §9.9.2. Um plano agrega os subconjuntos sinalizados e estima o custo em bytes de restaurar os programas de fonte completos. O módulo apenas analisa e estima; ele nunca reescreve um programa de fonte incorporado. Esta página descreve a API pública, o contrato de comportamento observável e os modos de falha.

Esta capacidade vem no NextPDF Pro (nextpdf/pro) e é ativada com um envelope de licença de nível Pro. Uma implantação sem essa titularidade não carrega as classes da capacidade. Compare edições e obtenha uma licença.

Nenhum sinalizador de licença por recurso restringe este módulo. As classes do Font Tools estão disponíveis sempre que nextpdf/pro estiver instalado.

SímboloParâmetrosComportamento padrãoRetornaLança ou falha comObservações
FontDesubsetternenhumScanner sem estado sobre bytes brutos de PDFfinal; seguro para reutilizar entre documentos
FontDesubsetter::analyzeSubsets()string $pdfDataReporta cada entrada /BaseFont distinta, subconjunto ou não, sinalizada por isSubsetlist<SubsetInfo>InvalidArgumentException quando uma estimativa de subconjunto derivada de larguras excede a estimativa de contagem total derivada do nomeVarredura em nível de bytes; fluxos de objetos compactados não são decodificados
FontDesubsetter::isSubsetFont()string $baseFontNameCorresponde à convenção de prefixo de seis letras maiúsculas mais +boolAncorado no início do nome
FontDesubsetter::extractSubsetPrefix()string $baseFontNameRetorna a etiqueta de subconjunto de seis letrasstringString vazia para nomes que não são de subconjunto
FontDesubsetter::generateDesubsetPlan()list<SubsetInfo> $subsetsColeta as entradas cujo isSubset é true e soma a estimativa de tamanhoDesubsetPlanNão lança exceçãoEntradas que não são de subconjunto são ignoradas silenciosamente
SubsetInfoconstrutor: $fontName, $baseFont, $subsetGlyphCount, $fullGlyphCount, $isSubset, $encodingDescrição imutável de uma entrada /BaseFontInvalidArgumentException para uma contagem de glifos negativa, ou uma contagem de subconjunto acima da contagem totalfinal readonly; todas as propriedades públicas
SubsetInfo::subsetPrefix()nenhumExtrai a etiqueta de seis letras de fontNamestringString vazia quando não é um subconjunto ou o + está afastado da sexta posição
SubsetInfo::coveragePercent()nenhumParcela do subconjunto no conjunto completo de glifosfloat em [0.0, 100.0]Retorna 0.0 quando fullGlyphCount é 0
DesubsetPlanconstrutor: list<SubsetInfo> $targets, int $estimatedSizeIncreasePlano de des-subconjunto imutávelfinal readonly; todas as propriedades públicas
DesubsetPlan::count()nenhumNúmero de fontes visadasintIgual ao comprimento de targets
DesubsetPlan::totalGlyphsNeeded()nenhumGlifos ausentes somados entre todos os alvosintSoma de fullGlyphCount - subsetGlyphCount por alvo
public function analyzeSubsets(string $pdfData): array
public function isSubsetFont(string $baseFontName): bool
public function extractSubsetPrefix(string $baseFontName): string
public function generateDesubsetPlan(array $subsets): DesubsetPlan
public function __construct(
public string $fontName,
public string $baseFont,
public int $subsetGlyphCount,
public int $fullGlyphCount,
public bool $isSubset,
public string $encoding,
)
public function subsetPrefix(): string
public function coveragePercent(): float
public function __construct(
public array $targets,
public int $estimatedSizeIncrease,
) {}
public function count(): int
public function totalGlyphsNeeded(): int

analyzeSubsets() extrai os tokens de nome /BaseFont dos bytes brutos com uma correspondência de padrão em nível de bytes. Nomes duplicados colapsam em uma única entrada; a ordem segue a primeira aparição. Cada nome distinto produz um SubsetInfo, seja ele um subconjunto ou não. Um nome é um subconjunto quando começa com exatamente seis letras ASCII maiúsculas seguidas de +, a convenção da §9.9.2. Para nomes de subconjunto, baseFont é o nome com o prefixo de sete caracteres removido. Para nomes comuns, baseFont é igual a fontName. Cada nome de subconjunto distinto é reportado como sua própria entrada, seguindo a orientação da §9.9.2 de tratar os subconjuntos como entidades independentes.

Para cada fonte, o scanner pesquisa uma janela de bytes limitada após a ocorrência de /BaseFont. Uma entrada de nome /Encoding na janela prevalece. Na falta dela, uma substring Identity-H ou Identity-V na janela é reportada. Na falta de ambas, a entrada reporta Unknown. Valores de codificação mantidos em dicionários ou alcançados por meio de referências indiretas reportam Unknown.

Ambas as contagens de glifos são estimativas. subsetGlyphCount deriva de arrays de largura visíveis próximos à entrada da fonte: um array /W de CIDFont produz aproximadamente um glifo por trio de largura, e um array /Widths de fonte simples produz um glifo por entrada numérica. Quando nenhum dos arrays está visível na janela, um pequeno valor padrão fixo é aplicado. Quando a ocorrência de /BaseFont não pode ser relocalizada para a pesquisa na janela, a contagem é 0. fullGlyphCount deriva de heurísticas de nome de família: uma tabela de famílias latinas conhecidas, um conjunto de indicadores de nome de família CJK e, caso contrário, um piso genérico. O programa de fonte incorporado nunca é analisado. As tabelas, os tamanhos de janela e as constantes específicos são detalhes de implementação, não são publicados e podem mudar entre versões.

generateDesubsetPlan() filtra a entrada para as entradas cujo isSubset é true. Cada alvo contribui com sua contagem de glifos ausentes, multiplicada por uma constante fixa de média de bytes por glifo, para estimatedSizeIncrease. O plano é uma projeção para decisões de capacidade, não um delta medido. Executar um plano — reescrever programas de fonte — está fora deste módulo.

Toda a superfície é uma função pura de sua entrada. Bytes idênticos produzem resultados idênticos. Não há aleatoriedade, nenhuma chamada de rede e nenhum acesso ao sistema de arquivos.

  • A construção de SubsetInfo rejeita estados inválidos: uma contagem de glifos negativa, ou uma contagem de subconjunto acima da contagem total, lança InvalidArgumentException.
  • analyzeSubsets() pode propagar essa exceção em um caso extremo: uma fonte cujo nome corresponde a uma família conhecida, mas cujo array de largura visível produz uma estimativa de subconjunto maior do que o valor de contagem total da família.
  • A detecção opera sobre a representação em bytes. Entradas /BaseFont serializadas dentro de fluxos de objetos compactados são invisíveis; descompacte esses fluxos antes de varrer.
  • Entradas cuja chave /BaseFont e valor estão separados por espaço em branco diferente de um único espaço ainda são detectadas, mas a pesquisa na janela por fonte não consegue relocalizá-las. Essas entradas reportam codificação Unknown e uma contagem de glifos de subconjunto igual a 0.
  • Nomes de PDF que usam bytes escapados com # são reportados na forma escapada bruta; os escapes não são decodificados.
  • Nomes /BaseFont duplicados colapsam em uma única entrada. Dois objetos de fonte distintos que compartilham um nome são indistinguíveis para este scanner.
  • generateDesubsetPlan() nunca falha com entradas que não são de subconjunto; entradas com isSubset definido como false são simplesmente excluídas de targets.
  • Todas as contagens e estimatedSizeIncrease são heurísticas. Não as trate como valores medidos; use-as apenas para triagem e planejamento de capacidade.
  • Nenhuma operação criptográfica ocorre neste módulo, portanto não há comportamento específico do modo FIPS.
AlegaçãoNormaCláusula
A detecção de subconjuntos corresponde à convenção de nomenclatura de subconjuntos: uma etiqueta de seis letras maiúsculas seguida de + prefixada ao valor BaseFont.ISO 32000-2:2020§9.9.2
Cada nome de subconjunto distinto é reportado de forma independente, seguindo a recomendação de tratar múltiplos subconjuntos como entidades separadas.ISO 32000-2:2020§9.9.2

Todas as cláusulas são parafraseadas; o NextPDF não reproduz texto normativo. Estas são declarações de capacidade, não certificações. O NextPDF não detém nenhuma certificação e não concede nenhuma. O módulo assegura a detecção da convenção de nomenclatura e o reporte determinístico; ele não assegura a exatidão das estimativas de contagem de glifos ou de tamanho.

  • Instale com composer require nextpdf/pro:^3. Disponível desde o nextpdf/pro 1.9.0; atual no nextpdf/pro 3.1.0.
  • FontDesubsetter é sem estado. Construa uma vez e reutilize-o entre documentos e fluxos de trabalho.
  • Forneça a analyzeSubsets() bytes descompactados quando a cobertura de subconjuntos importar; caso contrário, dicionários de fonte empacotados em fluxos de objetos são ignorados.
  • Ramifique com base em SubsetInfo::isSubset antes de agir; a lista de resultados inclui intencionalmente fontes que não são de subconjunto para fins de inventário.
  • Use DesubsetPlan::totalGlyphsNeeded() e estimatedSizeIncrease para decidir se o des-subconjunto vale o custo em tamanho de arquivo antes de obter os programas de fonte completos.
  • A varredura é linear no comprimento da entrada, com pesquisas em janela por fonte limitadas. O módulo não armazena nada e não emite telemetria.

Esta página documenta apenas o comportamento observável externamente e a superfície de API pública suportada. Caminhos de namespace internos, classes auxiliares, tabelas de mecanismos, nomes de arquivos de runbook e prefixos de tíquetes estão fora do escopo.