Ir al contenido
getnextpdf.com

Pro edición

Font Tools — Referencia detallada

Esta página es la referencia a nivel de contrato de NextPDF Pro Font Tools. La superficie es un único escáner, NextPDF\Pro\FontTools\FontDesubsetter, y dos objetos de valor inmutables, SubsetInfo y DesubsetPlan. El escáner lee bytes PDF en bruto, informa de cada entrada /BaseFont distinta y marca las entradas que siguen la convención de nomenclatura de subconjuntos de ISO 32000-2:2020 §9.9.2. Un plan agrega los subconjuntos marcados y estima el coste en bytes de restaurar los programas de fuente completos. El módulo solo analiza y estima; nunca reescribe un programa de fuente incrustado. Esta página expone la API pública, el contrato de comportamiento observable y los modos de fallo.

Esta capacidad se distribuye en NextPDF Pro (nextpdf/pro) y se activa con un sobre de licencia de nivel Pro. Un despliegue sin ese derecho no carga las clases de la capacidad. Comparar ediciones y obtener una licencia.

Ninguna marca de licencia por función restringe este módulo. Las clases de Font Tools están disponibles siempre que nextpdf/pro esté instalado.

SímboloParámetrosComportamiento por defectoDevuelveLanza o falla conNotas
FontDesubsetterningunoEscáner sin estado sobre bytes PDF en brutofinal; seguro de reutilizar entre documentos
FontDesubsetter::analyzeSubsets()string $pdfDataInforma de cada entrada /BaseFont distinta, sea o no subconjunto, marcada por isSubsetlist<SubsetInfo>InvalidArgumentException cuando una estimación de subconjunto derivada de anchuras supera la estimación de recuento completo derivada del nombreEscaneo a nivel de bytes; los flujos de objetos comprimidos no se decodifican
FontDesubsetter::isSubsetFont()string $baseFontNameCoincide con la convención de prefijo de seis letras mayúsculas más +boolAnclado al inicio del nombre
FontDesubsetter::extractSubsetPrefix()string $baseFontNameDevuelve la etiqueta de subconjunto de seis letrasstringCadena vacía para nombres que no son subconjuntos
FontDesubsetter::generateDesubsetPlan()list<SubsetInfo> $subsetsRecoge las entradas cuyo isSubset es true y suma la estimación de tamañoDesubsetPlanNo lanzaLas entradas que no son subconjuntos se omiten silenciosamente
SubsetInfoconstructor: $fontName, $baseFont, $subsetGlyphCount, $fullGlyphCount, $isSubset, $encodingDescripción inmutable de una entrada /BaseFontInvalidArgumentException con un recuento de glifos negativo, o un recuento de subconjunto superior al recuento completofinal readonly; todas las propiedades públicas
SubsetInfo::subsetPrefix()ningunoExtrae la etiqueta de seis letras de fontNamestringCadena vacía cuando no es un subconjunto o el + está fuera de la posición seis
SubsetInfo::coveragePercent()ningunoProporción del subconjunto respecto al conjunto completo de glifosfloat en [0.0, 100.0]Devuelve 0.0 cuando fullGlyphCount es 0
DesubsetPlanconstructor: list<SubsetInfo> $targets, int $estimatedSizeIncreasePlan de reconstitución inmutablefinal readonly; todas las propiedades públicas
DesubsetPlan::count()ningunoNúmero de fuentes objetivointIgual a la longitud de targets
DesubsetPlan::totalGlyphsNeeded()ningunoGlifos faltantes sumados en todos los objetivosintSuma de fullGlyphCount - subsetGlyphCount por objetivo
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() extrae los tokens de nombre /BaseFont de los bytes en bruto mediante una coincidencia de patrón a nivel de bytes. Los nombres duplicados se colapsan en una sola entrada; el orden sigue la primera aparición. Cada nombre distinto produce un SubsetInfo, sea o no un subconjunto. Un nombre es un subconjunto cuando comienza con exactamente seis letras ASCII mayúsculas seguidas de +, la convención de §9.9.2. Para los nombres de subconjunto, baseFont es el nombre con el prefijo de siete caracteres eliminado. Para los nombres ordinarios, baseFont es igual a fontName. Cada nombre de subconjunto distinto se informa como su propia entrada, en línea con la recomendación de §9.9.2 de tratar los subconjuntos como entidades independientes.

Para cada fuente, el escáner busca en una ventana de bytes acotada tras la aparición de /BaseFont. Una entrada de nombre /Encoding en la ventana prevalece. En su defecto, se informa de una subcadena Identity-H o Identity-V presente en la ventana. Si fallan ambas, la entrada informa Unknown. Los valores de codificación contenidos en diccionarios o alcanzados mediante referencias indirectas informan Unknown.

Ambos recuentos de glifos son estimaciones. subsetGlyphCount se deriva de los arreglos de anchura visibles cerca de la entrada de la fuente: un arreglo /W de CIDFont produce aproximadamente un glifo por cada terna de anchura, y un arreglo /Widths de fuente simple produce un glifo por cada entrada numérica. Cuando ninguno de los arreglos es visible en la ventana, se aplica un pequeño valor por defecto fijo. Cuando la aparición de /BaseFont no puede reubicarse para la búsqueda en la ventana, el recuento es 0. fullGlyphCount se deriva de heurísticas de nombre de familia: una tabla de familias latinas bien conocidas, un conjunto de indicadores de nombre de familia CJK y un mínimo genérico en los demás casos. El programa de fuente incrustado nunca se analiza. Las tablas, los tamaños de ventana y las constantes específicas son detalle de implementación, no se publican y pueden cambiar entre versiones.

generateDesubsetPlan() filtra la entrada a las entradas cuyo isSubset es true. Cada objetivo aporta su recuento de glifos faltantes, multiplicado por una constante fija de bytes medios por glifo, a estimatedSizeIncrease. El plan es una proyección para decisiones de capacidad, no un delta medido. Ejecutar un plan —reescribir programas de fuente— queda fuera de este módulo.

Toda la superficie es una función pura de su entrada. Bytes idénticos producen resultados idénticos. No hay aleatoriedad, ni llamada de red, ni acceso al sistema de archivos.

  • La construcción de SubsetInfo rechaza estados inválidos: un recuento de glifos negativo, o un recuento de subconjunto superior al recuento completo, lanza InvalidArgumentException.
  • analyzeSubsets() puede propagar esa excepción en un caso extremo: una fuente cuyo nombre coincide con una familia conocida pero cuyo arreglo de anchura visible produce una estimación de subconjunto mayor que la cifra de recuento completo de la familia.
  • La detección opera sobre la representación en bytes. Las entradas /BaseFont serializadas dentro de flujos de objetos comprimidos son invisibles; descomprima esos flujos antes de escanear.
  • Las entradas cuya clave y valor /BaseFont están separados por un espacio en blanco distinto de un único espacio siguen detectándose, pero la búsqueda en la ventana por fuente no logra reubicarlas. Tales entradas informan la codificación Unknown y un recuento de glifos de subconjunto de 0.
  • Los nombres PDF que usan bytes con escape # se informan en su forma escapada en bruto; los escapes no se decodifican.
  • Los nombres /BaseFont duplicados se colapsan en una sola entrada. Dos objetos de fuente distintos que comparten un mismo nombre son indistinguibles para este escáner.
  • generateDesubsetPlan() nunca falla con entradas que no son subconjuntos; las entradas con isSubset en false simplemente se excluyen de targets.
  • Todos los recuentos y estimatedSizeIncrease son heurísticas. No los trate como valores medidos; úselos solo para triaje y planificación de capacidad.
  • No ocurre ninguna operación criptográfica en este módulo, por lo que no hay comportamiento específico del modo FIPS.
AfirmaciónEstándarCláusula
La detección de subconjuntos coincide con la convención de nomenclatura de subconjuntos: una etiqueta de seis letras mayúsculas seguida de + como prefijo del valor BaseFont.ISO 32000-2:2020§9.9.2
Cada nombre de subconjunto distinto se informa de forma independiente, siguiendo la recomendación de tratar múltiples subconjuntos como entidades separadas.ISO 32000-2:2020§9.9.2

Todas las cláusulas están parafraseadas; NextPDF no reproduce texto normativo. Estas son declaraciones de capacidad, no certificaciones. NextPDF no posee ninguna certificación ni otorga ninguna. El módulo afirma la detección de la convención de nomenclatura y el informe determinista; no afirma la exactitud de las estimaciones de recuento de glifos ni de tamaño.

  • Instale con composer require nextpdf/pro:^3. Disponible desde nextpdf/pro 1.9.0; vigente en nextpdf/pro 3.1.0.
  • FontDesubsetter es sin estado. Constrúyalo una vez y reutilícelo entre documentos y hilos de trabajo.
  • Alimente analyzeSubsets() con bytes descomprimidos cuando importe la cobertura del subconjunto; de lo contrario, los diccionarios de fuente empaquetados en flujos de objetos se pasan por alto.
  • Ramifique según SubsetInfo::isSubset antes de actuar; la lista de resultados incluye intencionadamente fuentes que no son subconjuntos con fines de inventario.
  • Use DesubsetPlan::totalGlyphsNeeded() y estimatedSizeIncrease para decidir si la reconstitución merece el coste en tamaño de archivo antes de conseguir los programas de fuente completos.
  • El escaneo es lineal en la longitud de la entrada con búsquedas en ventana por fuente acotadas. El módulo no almacena nada y no emite telemetría.

Esta página documenta únicamente el comportamiento observable externamente y la superficie de la API pública admitida. Las rutas de espacio de nombres internas, las clases auxiliares, las tablas de mecanismos, los nombres de archivo de runbooks y los prefijos de tickets quedan fuera de alcance.