Fuentes: la parte difícil
De un vistazo
Sección titulada «De un vistazo»Las fuentes son el punto donde un PDF puede parecer completamente correcto y, aun así, estar silenciosamente roto. Una página puede representar los glifos correctos y, al mismo tiempo, ser imposible de buscar, imposible de copiar como texto y no conforme con un perfil de archivo. Todo eso puede ocurrir a la vez, sin nada visible que lo advierta. Esta página trata de las tres cosas que tienen que salir bien —incrustación, subconjuntos, codificación— y de lo que NextPDF hace con cada una.
Por qué importa
Sección titulada «Por qué importa»«Parece correcto» es la frase más peligrosa en el trabajo con PDF, y las fuentes son donde causa más daño. Tres cosas independientes deben cumplirse:
- Incrustación — el programa de fuente viaja dentro del archivo, de modo que se representa igual en una máquina que no tiene la fuente instalada.
- Subconjuntos — solo se transportan los glifos realmente usados, de modo que una fuente CJK de 20 MB no infla cada documento.
- Codificación — existe una correspondencia correcta desde los códigos de carácter de la página hasta Unicode, de modo que el texto se puede buscar, copiar, indexar y leer con tecnología de asistencia.
La representación visual solo demuestra parcialmente la primera. Un documento puede mostrar glifos perfectos y, aun así, fallar por completo en la tercera: el texto es una imagen de palabras, no palabras. Ese es el fallo que supera cualquier revisión de tipo «parece correcto» y luego no supera una auditoría de cumplimiento o una solicitud de exhibición de pruebas.
La versión breve
Sección titulada «La versión breve»- Una fuente en un PDF es un diccionario más, por lo general acompañado de un flujo de programa de fuente incrustado.
- Subconjuntos reescribe ese programa para que contenga solo los glifos
usados. El nombre de una fuente subconjunto recibe una etiqueta de seis
letras mayúsculas y un
+para que los lectores la traten como distinta. - Codificación es el problema aparte de asignar códigos de carácter a
Unicode. Un CMap
/ToUnicodees lo que hace que el texto se pueda buscar y copiar, y es independiente de si los glifos se ven bien. - Un texto de aspecto correcto sin
/ToUnicode(o con uno erróneo) es el fallo silencioso clásico: perfecto en pantalla, imposible de buscar en la práctica. - NextPDF crea subconjuntos de fuentes TrueType, preserva la identidad de los
glifos para una representación correcta y emite un CMap
/ToUnicodepara que la extracción funcione, y puede imponer la regla de incrustación de PDF 2.0 en lugar de solo advertir.
Cómo lo aborda NextPDF
Sección titulada «Cómo lo aborda NextPDF»Subconjuntos. FontSubsetter (src/Typography/FontSubsetter.php) analiza
el directorio de tablas TrueType original y lee el cmap para asignar puntos de
código Unicode a identificadores de glifo. Gestiona tanto el formato 4 del BMP
como el formato 12 de Unicode completo, que CJK necesita. Después realiza el
paso que los subconjuntadores ingenuos omiten: resuelve las dependencias de
glifos compuestos por cierre transitivo. Un glifo acentuado formado por una
letra base más una marca de combinación referencia otros glifos como
componentes. Si esos componentes se descartan, el glifo se representa mal. El
subconjuntador recorre ese grafo hasta que no aparece ningún componente nuevo,
con una protección contra ciclos para que una fuente malformada no pueda quedar
en un bucle infinito.
Merece la pena destacar dos decisiones de ingeniería de ese archivo. Primera: los
identificadores de glifo se preservan, no se reasignan — las posiciones no
usadas se rellenan con ceros en glyf/loca para que los índices de glifo
originales del flujo de contenido sigan siendo válidos bajo
CIDToGIDMap /Identity. Reasignar produciría un archivo más pequeño, pero
exigiría reescribir cada referencia de glifo. Preservar la identidad es correcto
por construcción. Segunda: el recorrido está ordenado (por gid ascendente)
para que el subconjunto sea determinista a nivel de bytes — la misma fuente y
los mismos glifos usados producen los mismos bytes de subconjunto, que es lo que
exigen las compilaciones reproducibles. Si crear el subconjunto ahorrara menos
de ~10 % del archivo, se devuelve el original sin cambios. La sobrecarga no
compensa una ganancia marginal.
Incrustación. Una política explícita decide si un programa de fuente se
transporta o no — nunca por conjeturas. Pdf20FontEmbeddingPolicy
(src/Writer/Pdf20FontEmbeddingPolicy.php) tiene dos modos. Bajo el perfil
PDF 2.0, Strict rechaza una referencia a una Type 1 estándar no incrustada
(«Base14») con una excepción tipada — el comportamiento correcto para la
conformidad. AllowBase14 preserva la ruta consultiva histórica. Durante una
ventana de migración, emite el descriptor de fuente mínimo que la norma todavía
exige y genera una advertencia en lugar de lanzar una excepción. Quien invoca
toma la decisión de forma explícita en el documento; nunca se infiere a partir
de la fuente.
Codificación. Para las fuentes compuestas (Type 0),
EmbeddedTtfFontDictBuilder (src/Writer/EmbeddedTtfFontDictBuilder.php) emite
el descendiente CIDFontType2, el padre Type0 y un flujo de CMap
/ToUnicode para que los códigos de carácter se resuelvan de vuelta a Unicode.
El flujo /ToUnicode está legítimamente ausente en un único caso: cuando un
CMap CJK predefinido y autodescriptivo ya proporciona al lector la
correspondencia de carácter a Unicode. Ahí el CMap es la codificación, de modo
que el perfil simple omite un flujo /ToUnicode redundante para ahorrar bytes.
Fuera de ese caso, el flujo /ToUnicode es lo que mantiene el texto como texto.
| Aspecto | Qué garantiza | Qué no garantiza | Fallo silencioso si es incorrecto |
|---|---|---|---|
| Incrustación | La misma representación sin la fuente instalada | Que el texto sea buscable | Fuente sustituida; métricas incorrectas en otra máquina |
| Subconjuntos | Archivo pequeño; solo los glifos usados | Nada sobre la codificación | Faltan componentes compuestos → glifos acentuados rotos |
Codificación (/ToUnicode) | Texto buscable, copiable y accesible | Que los glifos se representen correctamente | Página de aspecto perfecto, imposible de buscar / ilegible al copiar |
Los tres aspectos de las fuentes son independientes. La incrustación y los subconjuntos tienen que ver con la apariencia y el tamaño; la codificación tiene que ver con el significado. Una página puede superar los dos primeros y fallar en el tercero sin nada visible que lo muestre.
Ejemplo práctico
Sección titulada «Ejemplo práctico»Aquí están las dos mitades de una fuente compuesta correctamente incrustada, con
subconjunto y buscable. La etiqueta de subconjunto sigue la regla de seis letras
de la norma; la referencia /ToUnicode mantiene el texto extraíble.
% The Type 0 (composite) font dictionary20 0 obj<< /Type /Font /Subtype /Type0 /BaseFont /ABCDEF+NotoSans % six-letter subset tag + '+' /Encoding /Identity-H /DescendantFonts [21 0 R] /ToUnicode 23 0 R >> % the map that makes text searchableendobj
% The descendant CIDFontType2 (carries the subsetted program)21 0 obj<< /Type /Font /Subtype /CIDFontType2 /BaseFont /ABCDEF+NotoSans /CIDToGIDMap /Identity % glyph IDs preserved, not remapped /FontDescriptor 22 0 R >>endobjEl /ToUnicode 23 0 R del objeto 20 es la diferencia entre un documento
buscable y una imagen de uno. Al suprimirlo (fuera del caso del CMap
predefinido), cada glifo se sigue pintando a la perfección, pero una búsqueda de
cualquier palabra de la página no encuentra nada.
Concepto erróneo habitual
Sección titulada «Concepto erróneo habitual»La trampa, dicha con claridad: que los glifos se representen correctamente no
dice nada sobre si el texto es texto. La representación sigue la ruta de
codificación a glifo. La búsqueda y la copia siguen la ruta de código a Unicode
(/ToUnicode). Son mecanismos distintos que leen partes distintas del
diccionario de fuente. Por tanto, un documento puede tener una salida visual
impecable y un /ToUnicode ausente o erróneo. El resultado es una página que
parece fiable y es funcionalmente imposible de buscar — el fallo que sobrevive a
cualquier revisión visual, porque, por definición, no hay nada que ver.
Una trampa relacionada: suponer que «la fuente está incrustada, así que vamos bien para el archivado a largo plazo». La incrustación es necesaria, pero no suficiente. Un perfil como PDF/A también espera subconjuntos nombrados según la regla de seis letras y una codificación correcta. Incrustado pero imposible de buscar sigue fallando.
Límites y fronteras
Sección titulada «Límites y fronteras»El subconjuntador de NextPDF es específicamente un subconjuntador de
TrueType. Requiere las tablas TrueType esenciales y devuelve la fuente
original sin cambios cuando faltan o cuando la ganancia queda por debajo del
umbral de ~10 %. Los subconjuntos y un CMap /ToUnicode hacen que el texto sea
extraíble, pero no pueden rescatar una fuente de origen que carece de la
información para asignar un glifo a un carácter significativo. Donde no se puede
determinar ningún valor Unicode, no hay emisión de CMap que invente
uno.
Esta página trata de producir una estructura de fuente correcta en los documentos que NextPDF escribe. No es una herramienta de reparación de fuentes para PDF entrantes arbitrarios. Y emitir un subconjunto y una codificación conformes no certifica por sí solo un documento frente a un perfil de archivo completo — esa es una comprobación aparte y más amplia.
Mini-FAQ
Sección titulada «Mini-FAQ»¿Por qué la etiqueta de seis letras y no el nombre de la fuente? Para que un lector pueda distinguir dos subconjuntos distintos de la misma fuente y fusionar documentos sin que colisionen sus conjuntos de glifos. Subconjuntos distintos, etiquetas distintas, por norma.
¿Cuándo es aceptable no tener /ToUnicode?
Cuando un CMap CJK predefinido y autodescriptivo ya proporciona la
correspondencia de carácter a Unicode. Ahí el CMap es la codificación. Un
/ToUnicode aparte sería redundante. Fuera de eso, su ausencia es un defecto.
¿Los subconjuntos perjudican alguna vez? Solo si se hacen mal. Descartar los componentes de un glifo compuesto rompe los glifos acentuados. Reasignar los identificadores de glifo sin reescribir las referencias rompe la representación. NextPDF evita ambos problemas al resolver el cierre de componentes y preservar la identidad de los glifos.
Documentos relacionados
Sección titulada «Documentos relacionados»- Flujos y filtros — los programas de fuente incrustados son objetos de flujo filtrados con su propio contrato de decodificación.
- Qué es realmente un PDF — el modelo de objetos en el que viven los diccionarios de fuente y los flujos de programa.
- PDF 2.0: qué ha cambiado — incluidas las expectativas más estrictas de incrustación de fuentes de la base de 2.0.
Glosario
Sección titulada «Glosario»- Programa de fuente incrustado — el archivo de fuente real (TrueType/CFF/Type 1) transportado dentro del PDF como un flujo, de modo que la representación no depende de las fuentes instaladas del lector.
- Subconjuntos — reescribir un programa de fuente para que contenga solo los glifos que el documento usa, con el fin de reducir el tamaño.
- Etiqueta de subconjunto — el prefijo obligatorio de seis letras mayúsculas
más
+en el nombre de una fuente subconjunto (por ejemplo,ABCDEF+NotoSans). /ToUnicode— un flujo de CMap que asigna códigos de carácter a valores Unicode; lo que hace que el texto PDF sea buscable, copiable y accesible.- Glifo compuesto — un glifo construido referenciando otros glifos como componentes; sus componentes deben conservarse al crear el subconjunto.
CIDToGIDMap /Identity— el modo en el que los índices de glifo del flujo de contenido son los propios identificadores de glifo de la fuente sin cambios; NextPDF preserva la identidad de los glifos para mantener esto válido.- Base14 — las catorce fuentes Type 1 estándar; PDF 2.0 espera que las fuentes se incrusten en lugar de referenciarse por nombre.