Tipos de letra
En esta nueva entrada me apetece hablar de escritura. Pero no voy a escribir sobre escribir. O bueno, sí, pero no va de escribir historias, ni tampoco de estructuras narrativas, ni siquiera de cuál es la mejor rutina para conseguir rascar palabras a esa novela en progreso y cómo la vida adulta se interpone entre una y el proceso creativo. De hecho, voy a pasar un poquito por encima del minúsculo detalle de que llevo sin escribir una entrada en esta newsletter en los últimos dos meses. En mi defensa diré que he escrito muchas otras cosas, pero ninguna de ellas es relevante para los próximos párrafos.
Hace un par de semanas estuve en una cafetería frente al Mar Menor escribiendo en una libreta. Normalmente uso las libretas para escribir ideas sueltas, hacer esquemas, o apuntar las pistas del videojuego de puzles de turno. No hay ningún tipo de orden en estas notas, por supuesto.

Sin embargo, este año he empezado a escribir poesía y uso las libretas mucho más para este propósito: a través de esa mala letra, ese borrón, ese contar las sílabas y añadir notas al margen es como más disfruto a la hora de moldear los cimientos de un futuro poema. Pero no suelo escribir textos más largos. Para eso utilizo el teclado del ordenador, aprovechando cada céntimo de las clases de mecanografía a las que me apuntó mi madre.
Aquel día en la playa me apetecía esbozar una escena concreta y me puse a escribir mientras me bebía un café con hielo. Y volví a pensar que joder, qué mala letra tengo. Pero me corregí al instante: ¡Qué malas letras tengo!
Las primeras líneas, esas en las que me estaba esmerando un poco más, se iban derritiendo como el hielo de mi vaso a lo largo de las páginas. Me dolía la mano. Yo solo quería contar una historia, no escribir bonito. Entonces cambié de tipo de letra, un poco sin querer. Porque nunca he tenido único un tipo de letra: tengo dos que se intercambian según una serie de factores entre los que se encuentran mi estado de ánimo, el lápiz o el bolígrafo que esté utilizando, el gramaje del papel, si es completamente blanco o tiene guías, y lo inspirada que esté en ese momento.



Fotografías de algunas páginas de mis libretas escritas a mano
Por deformación profesional, el pensamiento que cruzó mi mente fue que tenía instaladas dos tipografías. Porque este es uno de esos temas que me maravillan y aterran a partes iguales. Así que, aprovechando que estoy escribiendo unos artículos técnicos para el trabajo que hablan precisamente de esto, me apetecía, nunca mejor dicho, dejarlo aquí por escrito.
Vamos al lío.
Para que un ordenador reciba, guarde y envíe información, esta tiene que estar, en última instancia, formada por valores numéricos. En concreto, simplificándolo mucho, ceros y unos. Al final, la informática consiste en transformar una cosa en otra, en guardar información aquí y luego moverla allí, intentando optimizar el espacio y que no se pierda nada por el camino. Y todo esto funciona en ambas direcciones: al leer y al escribir.
De este modo, cada vez que escribimos una letra, por ejemplo, la letra "a", esta se codifica de una determinada manera en un valor numérico, que es lo que reconoce un ordenador. Cuando sucede en sentido inverso, es decir, se transforma la información numérica a una letra que puede leer un humano, decimos que se decodifica. Parece muy simple y muy bonito, pero la realidad es que existen varias maneras de convertir estos valores, las cuales han ido evolucionando a lo largo de la historia, adaptándose a distintas necesidades y recursos. Y siempre intentando lo más difícil: que todos nos pongamos de acuerdo.
En los años 60 nació el estándar ASCII (American Standard Code for Information Interchange), cuyo código utiliza 7 bits (luego fueron 8 bits) para codificar caracteres del alfabeto latino, incluyendo mayúsculas y minúsculas y otros caracteres de puntuación. Esta limitación de bits tiene varios problemas que se evidencian muy pronto: no hay combinaciones suficientes de bits para codificar todos los caracteres que pueden necesitar otros idiomas. Por ejemplo, inicialmente no tenemos un huequito para meter nuestra representativa letra ñ. Ni hablemos de intentar codificar todos los caracteres de los distintos alfabetos que se utilizan en el idioma Japonés.
Así que en las décadas de los 80 y los 90, apareció Unicode para intentar unificar la codificiación textual y soportar multitud de alfabetos. Incluso los emoji tienen su representación en Unicode. Y, además, es compatible con ASCII, un detalle conveniente.
Lo que empezó en 1988 como un estándar para codificación de caracteres ha crecido hasta llegar a ser un potente portfolio de código, herramientas, librerías y productos de código abierto que aseguran un soporte de idiomas global, interoperable y resiliente en billones de dispositivos.
https://unicode.org/about.html
Lo que hace Unicode es definir una serie de valores numéricos o code points , y cada uno de estos referencia a un carácter. También está definido cuáles son los rangos de caracteres por idioma soportado. Además, estos code points pueden combinarse para formar a su vez otros caracteres, algo que ocurre con frecuencia en los alfabetos de algunos idiomas como el Japonés o el Coreano.
Pero si bien Unicode define el estándar, recordemos que nos queda la pieza que transforma la información: la codificación de la que hemos hablado antes. A esto se le llama encoding y en el caso de Unicode recibe el nombre de UTF (Unicode Transformation Format).


Pero no todo es tan fácil, hay varios tipos de UTF: UTF-8, UTF-16 y UTF-32. El número después de UTF define el número de bits que se utilizan para codificar cada carácter (recordemos que ASCII utilizaba solo 7 bits en sus inicios). Entonces, ¿por qué se elegiría uno u otro? Cuanto mayor sea el número, mayor información podremos guardar. Pero, al mismo tiempo, más espacio ocupa y por lo tanto será menos eficiente o más costoso. En algunos casos, sería como guardar los calcetines de verano en los cajones más grandes de tu armario. Sí, caben, pero... estás desperdiciando espacio. Pero, ¿y si uso un número demasiado pequeño? Hay caracteres que necesitan más bits cuando los codificamos.
Bueno, para esto hay maneras de utilizar una codificación de bits que use menos bits de los que necesitaría un determinado carácter, como por ejemplo, guardando su codificación por separado y juntándola a la hora de decodificarla. Lo que os decía al principio: mover cosas de un lado para otro.

Como curiosidad, muchos de los emoji más modernos suelen ser la combinación de varios emoji en Unicode. Por ejemplo, el code point del emoji del astronauta es la suma de los code points del emoji del una persona y el emoji del cohete. Lo sé, una fantasía.
const astronaut = "👩" + "\u200D" + "🚀"
console.log(astronaut)
👩🚀
Hasta ahora he hablado de "caracteres", pero sería más adecuado hablar de grafemas: la Unidad mínima e indivisible de la escritura de una lengua. Hasta aquí hemos visto que tengo un código de números que representan un código en Unicode que se refiere a un grafema, que se encuentra definido en un rango de un alfabeto de un idioma concreto. Vale, pero y eso... ¿cómo se pinta?
Es necesario que exista otra pieza que transforme la información en información gráfica. Y, además, otra pieza que utilice esta información gráfica y la pinte. Para ello, necesitamos definir lo que es un glifo. Un glifo es la representación gráfica de un carácter que utiliza una fuente tipográfica que corresponde al lenguaje escrito del alfabeto de un idioma concreto. Por ello, para que una palabra se pinte, no solo tenemos que conocer el idioma en el que está escrita, sino la fuente que queremos que utilice. Ya sabéis: ¿Fuente? Arial 12.

Ese cuadradito vacío (□) representa una información textual que no es posible representar por la fuente que se está utilizando, sencillamente porque la fuente no cuenta con ningún elemento que se identifique con ese código. En este caso, esto sucedería si quisiéramos escribir "I ❤️ unicode" pero no existiera una fuente que tuviera una representación del emoji del corazón.
Esto quiere decir que un texto puede dibujarse utilizando más de una fuente. Y estas se aplican en orden. Si un programa que, por ejemplo, tiene dos fuentes y quiere dibujar un carácter que no existe en la primera, pero sí en la segunda, entonces para ese carácter utilizará la segunda fuente. Eso asegura que el texto siempre sea legible.
Aunque también conlleva otros problemas.
Uno de ellos es precisamente la gestión de las fuentes por defecto que utilizan los distintos sistemas (programas de escritura, navegadores, apps móviles, etc). Quizá os haya pasado alguna vez que, una aplicación que usáis en distintos dispositivos, utilice fuentes diferentes, o directamente pinte emoji con un diseño diferente. En la emojipedia podemos ver que hay distintas fuentes para pintar un mismo emoji. Así que quizá te estés preguntando: ¿quién decide cuál se utiliza?

La clave aquí está precisamente en que esta decisión puede ocurrir en varias capas. Todos los dispositivos de Apple tendrán implementado en su sistema operativo que los emoji utilicen su propia fuente. Sin embargo, si estás utilizando una aplicación que específicamente decide que los emoji utilicen otra fuente concreta, entonces esta fuente tendrá preferencia. Cada navegador (Chrome, Firefox, Brave...) tienen su propia jerarquía de fuentes por defecto, de manera que la cadena aquí sería, simplificándolo mucho: 1) la configuración de la página web, 2) el navegador donde estés viendo la página web, 3) el dispositivo donde tengas abierto el navegador. Por esta razón, una misma página web que no tenga definida una fuente específica de emoji probablemente se vea distinta en diferentes navegadores y desde diferentes dispositivos.
Uno de los grandes retos del pintado de textos es precisamente que no todos los grafemas tendrán el mismo tamaño dado un tamaño de fuente determinado si hay varias fuentes implicadas (por una cuestión de diseño), o que las reglas para que los grafemas aparezcan en una posición concreta o en una dirección determinada dependerá de varios factores, que van desde lo semántico hasta lo puramente estético. Estos cálculos de posición dependerán además del idioma en el que se está escribiendo el texto. ¿Cómo es posible entonces modificar los valores del texto que estamos escribiendo y centrarlo en una página? ¿O calcular el interlineado de un párrafo?
Para este tipo de cálculos existe una pieza más en todo este engranaje: los motores de texto. Es decir, programas que se encargan de calcular valores de posición, dimensiones, alineamiento, entre otros, de los textos a través de su representación (como Unicode) y las distintas fuentes que utiliza. Existen varios motores, pero uno de los más utilizados es HarfBuzz.
Este proyecto es también de código abierto y está detrás de la mayoría de textos que vemos hoy en día en nuestras pantallas. Detrás de HarfBuzz está Behdad Esfahbod, un ingeniero software iraní cuya motivación para trabajar en el procesado de textos fue poder representar el idioma Persa, como explica en esta entrevista:
El árabe es un poco más complicado. Cada carácter puede pintarse de una a cuatro maneras distintas dependiendo de qué caracteres están a ambos lados. HarfBuzz es una implementación para darle forma al texto. Y darle forma al texto lo definimos como: aquí está mi fuente tipográfica, aquí está mi texto en unicode, solo dime qué glifos mostrar y dónde mostrarlos. Eso es lo que hace HarfBuzz.
El pasado mes de junio, Behdad dio una charla en el evento Web Engines Hackfest hablando más en detalle de la trayectoria del proyecto. Recomiendo dar una paseo por su página web personal, donde no solo habla de procesado de textos sino también de experiencias personales y algunos episodios importantes de su vida. Y también tiene publicados algunos poemas.
Llegados a este punto, según el contador de palabras, llevo escritas más de dos mil en este post, una cifra que excede el límite de atención del lector. Ninguna ha sido escrita a mano, sino directamente en el mismo navegador en el propio sistema de Ghost, y no me hago responsable del pintado de emoji según dónde lo estés leyendo.