Referencia Compacta de Bytes en TTF
Referencia Compacta de Bytes en TrueType (TTF)
Una guía mínima y de referencia rápida para los desplazamientos de bytes y diseños de campos de cada tabla TTF principal. Todo es big-endian. Para estrategia de análisis y guías detalladas, consulta Analizar una Fuente.
Contenidos
Encabezado de archivo
Tabla de desplazamientos (encabezado sfnt) — 12 bytes en byte 0:
| desplazamiento | tipo | campo | notas |
|---|---|---|---|
| 0 | u32 | sfntVersion | 0x00010000 (TrueType) o 0x4F54544F (OTTO) |
| 4 | u16 | numTables | cantidad de tablas que siguen |
| 6 | u16 | searchRange | pista de búsqueda binaria; recalcular si se modifica |
| 8 | u16 | entrySelector | pista de búsqueda binaria |
| 10 | u16 | rangeShift | pista de búsqueda binaria |
Directorio de tablas — numTables registros de 16 bytes cada uno, comenzando en byte 12:
| desplazamiento | tipo | campo | notas |
|---|---|---|---|
| 0 | tag[4] | tableTag | p. ej. head, glyf (ASCII) |
| 4 | u32 | checksum | suma de verificación de tabla |
| 8 | u32 | offset | desde el inicio del archivo |
| 12 | u32 | length | longitud real; tabla rellenada a límite de 4 bytes |
El registro i comienza en byte 12 + i×16.
Tablas
head — Encabezado de fuente (54 bytes, fijo)
Métricas de fuente global y configuración.
| desplazamiento | tipo | campo | notas |
|---|---|---|---|
| 0 | u16 | majorVersion | 1 |
| 2 | u16 | minorVersion | 0 |
| 4 | i32 | fontRevision | punto fijo 16.16 |
| 8 | u32 | checksumAdjustment | suma de archivo completo |
| 12 | u32 | magicNumber | debe ser 0x5F0F3CF5 |
| 16 | u16 | flags | campo de bits |
| 18 | u16 | unitsPerEm | cuadrícula de diseño (p. ej. 1000, 2048) |
| 20 | i64 | created | segundos desde 1904-01-01 00:00 UTC |
| 28 | i64 | modified | misma época |
| 36 | i16 | xMin | caja delimitadora de fuente |
| 38 | i16 | yMin | |
| 40 | i16 | xMax | |
| 42 | i16 | yMax | |
| 44 | u16 | macStyle | campo de bits |
| 46 | u16 | lowestRecPPEM | tamaño más pequeño legible en píxeles |
| 48 | i16 | fontDirectionHint | |
| 50 | i16 | indexToLocFormat | 0 = loca corto, 1 = loca largo |
| 52 | i16 | glyphDataFormat | 0 |
maxp — Perfil máximo
Requisitos de memoria. Versión 0.5 (CFF, 6 bytes):
| desplazamiento | tipo | campo | notas |
|---|---|---|---|
| 0 | u32 | version | 0x00005000 |
| 4 | u16 | numGlyphs | crítico |
Versión 1.0 (TrueType, 32 bytes):
| desplazamiento | tipo | campo | notas |
|---|---|---|---|
| 0 | u32 | version | 0x00010000 |
| 4 | u16 | numGlyphs | cantidad de glifos |
| 6 | u16 | maxPoints | máximo en glifo simple |
| 8 | u16 | maxContours | máximo en glifo simple |
| 10 | u16 | maxCompositePoints | máximo en glifo compuesto |
| 12 | u16 | maxCompositeContours | máximo en glifo compuesto |
| 14 | u16 | maxZones | 1 o 2 |
| 16 | u16 | maxTwilightPoints | |
| 18 | u16 | maxStorage | |
| 20 | u16 | maxFunctionDefs | |
| 22 | u16 | maxInstructionDefs | |
| 24 | u16 | maxStackElements | |
| 26 | u16 | maxSizeOfInstructions | |
| 28 | u16 | maxComponentElements | |
| 30 | u16 | maxComponentDepth |
hhea — Encabezado horizontal (36 bytes, fijo)
Métricas para diseño horizontal.
| desplazamiento | tipo | campo | notas |
|---|---|---|---|
| 0 | u16 | majorVersion | 1 |
| 2 | u16 | minorVersion | 0 |
| 4 | i16 | ascender | |
| 6 | i16 | descender | generalmente negativo |
| 8 | i16 | lineGap | |
| 10 | u16 | advanceWidthMax | |
| 12 | i16 | minLeftSideBearing | |
| 14 | i16 | minRightSideBearing | |
| 16 | i16 | xMaxExtent | |
| 18 | i16 | caretSlopeRise | 1 para vertical |
| 20 | i16 | caretSlopeRun | 0 para vertical |
| 22 | i16 | caretOffset | 0 para no inclinado |
| 24 | i16 | reserved[4] | cero |
| 32 | i16 | metricDataFormat | 0 |
| 34 | u16 | numberOfHMetrics | dimensiona tabla hmtx |
hmtx — Métricas horizontales (variable)
Sin encabezado. Dos matrices consecutivas:
Parte 1: numberOfHMetrics (de hhea) entradas de:
| desplazamiento | tipo | campo | notas |
|---|---|---|---|
| 0 | u16 | advanceWidth | |
| 2 | i16 | lsb | distancia al lado izquierdo |
Parte 2: numGlyphs − numberOfHMetrics entradas de:
| desplazamiento | tipo | campo | notas |
|---|---|---|---|
| 0 | i16 | lsb | reutiliza último advance width |
loca — Índice de ubicación (variable)
Mapea índice de glifo → desplazamiento de byte en tabla glyf. numGlyphs + 1 desplazamientos (el +1 marca el final del último glifo).
Formato corto (head.indexToLocFormat == 0): desplazamientos uint16 (multiplica por 2 para obtener desplazamiento real).
Formato largo (head.indexToLocFormat == 1): desplazamientos uint32 (usa directamente).
Si loca[i] == loca[i+1], el glifo i está vacío (p. ej. carácter de espacio).
glyf — Datos de glifos (variable)
Sin encabezado. Bloques de glifos consecutivos, ubicados por loca.
Encabezado de glifo (10 bytes):
| desplazamiento | tipo | campo | notas |
|---|---|---|---|
| 0 | i16 | numberOfContours | ≥ 0 = simple; < 0 = compuesto |
| 2 | i16 | xMin | caja delimitadora de glifo |
| 4 | i16 | yMin | |
| 6 | i16 | xMax | |
| 8 | i16 | yMax |
Glifo simple (numberOfContours ≥ 0):
| desplazamiento | tipo | campo | notas |
|---|---|---|---|
| 10 | u16[numberOfContours] | endPtsOfContours | último+1 = cantidad de puntos |
| … | u16 | instructionLength | bytes de pistas |
| … | u8[instructionLength] | instructions | bytecode TrueType |
| … | u8[…] | flags | una bandera lógica por punto, comprimida |
| … | — | xCoordinates | codificado en delta |
| … | — | yCoordinates | codificado en delta |
Bits de bandera (cada punto):
| bit | nombre | significado |
|---|---|---|
| 0x01 | ON_CURVE_POINT | punto en curva (si no es punto de control Bézier) |
| 0x02 | X_SHORT_VECTOR | delta x es 1 byte |
| 0x04 | Y_SHORT_VECTOR | delta y es 1 byte |
| 0x08 | REPEAT_FLAG | siguiente byte = contar repeticiones para esta bandera |
| 0x10 | X_IS_SAME_OR_POSITIVE | (consulta especificación) |
| 0x20 | Y_IS_SAME_OR_POSITIVE | (consulta especificación) |
| 0x40 | OVERLAP_SIMPLE | los contornos pueden superponerse |
| 0x80 | reserved | 0 |
Glifo compuesto (numberOfContours < 0):
Bucle de componentes. Cada uno:
| desplazamiento | tipo | campo | notas |
|---|---|---|---|
| 0 | u16 | flags | banderas de componentes (abajo) |
| 2 | u16 | glyphIndex | qué glifo referenciar |
| 4 | — | arg1, arg2 | int8/uint8 o int16/uint16 por ARG_1_AND_2_ARE_WORDS |
| … | — | transform | 0, 1, 2, o 4 × F2Dot14 por banderas de escala |
Bits de bandera de componente:
| bit | nombre | significado |
|---|---|---|
| 0x0001 | ARG_1_AND_2_ARE_WORDS | argumentos son 16-bit |
| 0x0002 | ARGS_ARE_XY_VALUES | argumentos son desplazamientos (si no índices) |
| 0x0004 | ROUND_XY_TO_GRID | |
| 0x0008 | WE_HAVE_A_SCALE | un F2Dot14 sigue |
| 0x0020 | MORE_COMPONENTS | otro componente después de este |
| 0x0040 | WE_HAVE_AN_X_AND_Y_SCALE | dos F2Dot14 siguen |
| 0x0080 | WE_HAVE_A_TWO_BY_TWO | cuatro F2Dot14 (matriz) |
| 0x0100 | WE_HAVE_INSTRUCTIONS | después del último componente: u16 length + bytes |
| 0x0200 | USE_MY_METRICS | |
| 0x0400 | OVERLAP_COMPOUND |
cmap — Mapeo de carácter a glifo (variable)
Mapea Unicode → índice de glifo. Múltiples subtablas; elige la mejor para tu caso.
Encabezado (4 bytes):
| desplazamiento | tipo | campo |
|---|---|---|
| 0 | u16 | version |
| 2 | u16 | numTables |
Registros de codificación (numTables de 8 bytes cada uno):
| desplazamiento | tipo | campo | notas |
|---|---|---|---|
| 0 | u16 | platformID | 0=Unicode, 1=Mac, 3=Windows |
| 2 | u16 | encodingID | dependiente de plataforma |
| 4 | u32 | subtableOffset | desde inicio de tabla cmap |
Común: (3,1) → formato 4 (BMP); (3,10) → formato 12 (Unicode completo).
Formato 0 (codificación de bytes, 256 glifos):
| desplazamiento | tipo | campo |
|---|---|---|
| 0 | u16 | format |
| 2 | u16 | length |
| 4 | u16 | language |
| 6 | u8[256] | glyphIdArray |
Formato 4 (mapeo de segmentos, BMP):
| desplazamiento | tipo | campo |
|---|---|---|
| 0 | u16 | format |
| 2 | u16 | length |
| 4 | u16 | language |
| 6 | u16 | segCountX2 |
| 8 | u16 | searchRange |
| 10 | u16 | entrySelector |
| 12 | u16 | rangeShift |
| 14+ | u16[segCount] | endCode |
| … | u16 | reserved |
| … | u16[segCount] | startCode |
| … | i16[segCount] | idDelta |
| … | u16[segCount] | idRangeOffset |
| … | u16[…] | glyphIdArray |
Formato 12 (cobertura Unicode completa):
| desplazamiento | tipo | campo |
|---|---|---|
| 0 | u16 | format |
| 2 | u16 | reserved |
| 4 | u32 | length |
| 8 | u32 | language |
| 12 | u32 | numGroups |
| 16+ | — | groups (numGroups entradas, 12 bytes cada una) |
Cada grupo: { u32 startCharCode; u32 endCharCode; u32 startGlyphID }.
name — Nombres de fuente (variable)
Cadenas legibles por humanos (familia, estilo, versión, etc.). Se almacenan una vez en un grupo de bytes; los registros apuntan con metadatos.
Encabezado (6 bytes):
| desplazamiento | tipo | campo | notas |
|---|---|---|---|
| 0 | u16 | version | 0 o 1 |
| 2 | u16 | count | cantidad de registros de nombre |
| 4 | u16 | storageOffset | inicio del grupo de cadenas desde inicio de tabla |
Registros de nombre (count de 12 bytes cada uno):
| desplazamiento | tipo | campo | notas |
|---|---|---|---|
| 0 | u16 | platformID | 0=Unicode, 3=Windows |
| 2 | u16 | encodingID | dependiente de plataforma |
| 4 | u16 | languageID | etiqueta de idioma/plataforma |
| 6 | u16 | nameID | 1=familia, 2=subfamilia, 4=completo, 5=versión |
| 8 | u16 | length | longitud de cadena en bytes |
| 10 | u16 | stringOffset | desde storageOffset |
Luego bytes de cadena sin procesar por plataforma (típicamente UTF-16BE para Windows).
post — Datos PostScript (variable)
Ángulo itálico, bandera de espacio único, nombres PostScript (solo v2.0).
Encabezado fijo (32 bytes):
| desplazamiento | tipo | campo | notas |
|---|---|---|---|
| 0 | u32 | version | 0x00010000, 0x00020000, o 0x00030000 |
| 4 | i32 | italicAngle | punto fijo 16.16 |
| 8 | i16 | underlinePosition | |
| 10 | i16 | underlineThickness | |
| 12 | u32 | isFixedPitch | 0 o distinto de cero |
| 16 | u32 | minMemType42 | |
| 20 | u32 | maxMemType42 | |
| 24 | u32 | minMemType1 | |
| 28 | u32 | maxMemType1 |
Solo versión 2.0 (después del encabezado):
| desplazamiento | tipo | campo |
|---|---|---|
| 32 | u16 | numGlyphs |
| 34 | u16[numGlyphs] | glyphNameIndex |
| … | — | nombres de cadena Pascal para índices ≥ 258 |
OS/2 — Métricas OS/2 y Windows (dependiente de versión)
Clasificación de fuente, peso, ancho, cobertura, PANOSE, banderas de incrustación.
Versión 0 (78 bytes):
| desplazamiento | tipo | campo | notas |
|---|---|---|---|
| 0 | u16 | version | 0–5 |
| 2 | i16 | xAvgCharWidth | |
| 4 | u16 | usWeightClass | 100–900 |
| 6 | u16 | usWidthClass | 1–9 |
| 8 | u16 | fsType | banderas de incrustación |
| 10 | i16 | ySubscriptXSize | |
| 12 | i16 | ySubscriptYSize | |
| 14 | i16 | ySubscriptXOffset | |
| 16 | i16 | ySubscriptYOffset | |
| 18 | i16 | ySuperscriptXSize | |
| 20 | i16 | ySuperscriptYSize | |
| 22 | i16 | ySuperscriptXOffset | |
| 24 | i16 | ySuperscriptYOffset | |
| 26 | i16 | yStrikeoutSize | |
| 28 | i16 | yStrikeoutPosition | |
| 30 | i16 | sFamilyClass | |
| 32 | u8[10] | panose | |
| 42 | u32 | ulUnicodeRange1 | bits 0–31 |
| 46 | u32 | ulUnicodeRange2 | bits 32–63 |
| 50 | u32 | ulUnicodeRange3 | bits 64–95 |
| 54 | u32 | ulUnicodeRange4 | bits 96–127 |
| 58 | tag[4] | achVendID | |
| 62 | u16 | fsSelection | banderas de estilo |
| 64 | u16 | usFirstCharIndex | |
| 66 | u16 | usLastCharIndex | |
| 68 | i16 | sTypoAscender | |
| 70 | i16 | sTypoDescender | |
| 72 | i16 | sTypoLineGap | |
| 74 | u16 | usWinAscent | |
| 76 | u16 | usWinDescent |
Versión 1 añade (86 bytes):
| desplazamiento | tipo | campo |
|---|---|---|
| 78 | u32 | ulCodePageRange1 |
| 82 | u32 | ulCodePageRange2 |
Versiones 2/3/4 añaden (96 bytes):
| desplazamiento | tipo | campo |
|---|---|---|
| 86 | i16 | sxHeight |
| 88 | i16 | sCapHeight |
| 90 | u16 | usDefaultChar |
| 92 | u16 | usBreakChar |
| 94 | u16 | usMaxContext |
Versión 5 añade (100 bytes):
| desplazamiento | tipo | campo |
|---|---|---|
| 96 | u16 | usLowerOpticalPointSize |
| 98 | u16 | usUpperOpticalPointSize |
kern — Pares de kerning (opcional, variable)
Ajustes de espaciado entre pares de glifos. Opcional; las fuentes modernas usan GPOS.
Encabezado (4 bytes):
| desplazamiento | tipo | campo | notas |
|---|---|---|---|
| 0 | u16 | version | 0 |
| 2 | u16 | nTables |
Encabezado por subtabla (6 bytes):
| desplazamiento | tipo | campo | notas |
|---|---|---|---|
| 0 | u16 | version | versión de subtabla |
| 2 | u16 | length | longitud de subtabla en bytes |
| 4 | u16 | coverage | byte alto = formato; byte bajo = banderas |
Formato 0 (pares ordenados):
| desplazamiento | tipo | campo | notas |
|---|---|---|---|
| 6 | u16 | nPairs | |
| 8 | u16 | searchRange | pista de búsqueda binaria |
| 10 | u16 | entrySelector | pista de búsqueda binaria |
| 12 | u16 | rangeShift | pista de búsqueda binaria |
| 14+ | — | pairs | nPairs entradas, 6 bytes cada una |
Cada par: { u16 left; u16 right; i16 value }.
Para estrategia de análisis y guías completas, consulta Analizar una Fuente.