Fuentes TrueType con M5Stack

Objetivo

 

  • Mejorar la presentación en pantalla de los textos
  • Introducir las fuentes Truetype con las librerías GFX.
  • Hacer unos ejemplos de uso de Truetype.
  • Incluir un Font de números digitales en nuestro programa de reloj.
  •  

    Material requerido.

     

    MOdelo basico Un M5Stack

     

     Detalle de conectores Un cable USB C

     

    Las fuentes Truetype

     

     

    Cuando escribes algo con tu PC, con un procesador de Textos por ejemplo, usas una serie de tipos de letra o fuentes que son no solo elegantes, sino además de lo más variadas en cuanto a formas tipos y tamaños y naturalmente te parece lo normal.

    En cambio cuando usas tu Arduino o tu M5Stack te consideras afortunado si la letra es simplemente una Courier (De máquina de escribir, esos aparatos antediluvianos que aún quedan fósiles que emplean) porque aquí no se piden virguerías, basta con que se lea y lo curioso es que nadie parece querer más.

    Pero en realidad ya disponemos de microprocesadores como el ESP32 que tienen potencia de sobra para usar fuentes de paso y tipo variado y por eso vamos a aprovechar esta sesión para ver que nuestros M5stack / ESP32 pueden usar fuentes Truetype con algunas limitaciones lo que nos va a permitir imprimir textos de lo más elegantes.

    Desde que inventó la imprenta, hace ya unos añitos, los editores de libros y después periódicos, siempre buscaron que las letras que se usaban fueran no sólo agradables sino que además llamaran la atención de los lectores y les hiciera sacar la billetera del bolsillo. A lo largo del tiempo este conocimiento ancestral ha ido cristalizando en un arte que recibe el nombre de tipografía.

    Tampoco extrañará a nadie que los tipos de letra son patentables y por tanto usar los que ha producido otro supone pasar previamente por caja, algo que en los tiempos de internet y las publicaciones globales suele ser más caro que generar tus propios tipos.

    Históricamente  (En informática) el chollo estaba en manos de Adobe y cobraba lo suyo a quienes quisieran usar los tipos de letra Arial y Times entre otros y cuando Apple empezó a necesitar tipos variables para sus primeros Mac desarrolló un sistema que acabó licenciando a Microsoft (Que llegó después a los procesadores de textos gráficos) para que pudiese desarrollar tipos compatibles y por eso puedes ver correctamente en un PC textos editados en un Mac y viceversa

    Actualmente ambos sistemas operativos y por extensión Linux emplean un sistema común de fuentes escalables llamadas TrueType y si miras en tu directorio Windows\fonts encontrarás un puñado (No idea de cómo lo gestiona Apple) y aunque muchos tipos siguen siendo propietarios y si los usas te arriesgas a demandas de abogados mezquinos, también hay un suministro inagotable de fuentes Truetype de acceso libre que puedes usar a tu gusto y sin pagar un euro.

    La descripción de los tipos de letra Truetype es vectorial, eso quiere decir que se pueden escalar al tamaño que deseemos manteniendo la misma apariencia, por lo que con una descripción única de cada letra y símbolo incluido disponemos de versiones en todos los tamaños, a diferencia de lo que ocurría en los primeros procesadores de textos (O las máquinas de escribir que solo tenían uno o dos tipos de letra)

    Los siempre alabados amigos de Adafruit, desarrollaron librerías que nos permiten usar las fuentes Truetype con sus librerías GFX (Que nos hemos hartado a usar en otros tutoriales) y como las librerías de M5stack derivan de las de Adafruit tenemos el camino libre para usarlas.

    La idea de esta sesión es precisamente ver cómo podemos usar las fuentes Truetype en nuestros programas con el ESP32 y en concreto con la pantalla del M5Stack.

     

    Usando TrueType con M5Stack

     

     

    Para poder usar una fuente Truetype desde nuestro ESP32 necesitamos convertir la fuente inicial a un sistema que podamos incluir en nuestros programas C++ y gracias a Dios, hay gente amable que se lo ha trabajado y nos ofrece un modo de convertir cualquier fuente y generar un fichero que podamos incluir en nuestros programas.

    Empecemos con un ejemplo sencillo. Este esta página  https://rop.nl/truetype2gfx/, un buen samaritano nos ofrece un programa online que nos va a hacer la vida mucho más fácil:

    Programa de conversion de fonts

    Este programa nos ofrece una serie de fonts libres que podemos usar directamente y probar en pantalla del M5Stack o simplemente cargar nuestras propias fonts y probarlas de forma simulada.

    Como ves en la imagen podemos seleccionar diferentes fonts incluidos, cargar los nuestros y modificar el tamaño a usar con un texto de prueba para comprobar los resultados.

    Cuando acabes y tengas lo que quieres, pulsando en el botón “Get GFX Font file” genera un fichero .h que podemos incluir en nuestro programa C++ que representa la fuente Truetype de un tamaño determinado.

    Si por ejemplo coges la fuente FreeSerifItalic de 30 puntos y escribes en el demo text “Prometec.net” verás algo como esto:

    Ejemplo de texto

    Para generar el Font que pueda hacer esto en tu M5Stack pulsa en el botón “Get GFX Font file”  y el programa te generará un fichero llamado “FreeSerifItalic10pt7b.h”. Veamos cómo usarlo. Tenemos que empezar el programa con estas dos líneas

    #include <M5Stack.h>
    #include "FreeSerifItalic10pt7b.h"

    Llamamos al fichero .h que ha generado el Font converter como un include mas (Elegante ¿A que si?) basta con copiar el fichero generado en descargas, al directorio donde guardes el programa actual (No te olvides o no funcionará)

    void setup()
    { M5.begin();
      M5.Lcd.fillScreen(BLACK);   // Limpia la pantalla
      M5.Lcd.setTextColor(RED);
      M5.Lcd.setTextDatum(CC_DATUM);
      M5.Lcd.setFreeFont(&Digital_Numbers_40040pt7b);
      M5.Lcd.drawString("Prometec.net", 160, 120);
    }

    Aqui tienes el programa y el font incluido en fichero comprimido:  NTP_TTF_0

    Ejemplo de truetype en M5stack

     

     

    El reloj con fuentes digitales

     

    En la última sesión empezamos con el reloj que se sincronizaba con NTP y sacamos la hora en le display, pero era con las letras estándar que son bastante vulgares y como la mayoría de los relojes de mesilla usan los números digitales característicos de 7 segmentos, estaría bien poder usar este tipo de letra en la pantalla para dar la hora.

    Si haces una búsqueda por internet encontrarás que ha bastantes proveedores de digital numbers fonts por ahí, y me permito incluir aquí algunos (Sin ningún interés porque son gratis)

  • https://www.fontmirror.com/digital-numbers
  • https://www.dafont.com/ds-digital.font
  • https://www.1001fonts.com/digital-fonts.html
  •  

    He elegido una fuente de la primera página para nuestro ejemplo pero seguro que puedes usar otras fuentes, puedes descargarla de aqui: DigitalNumbers_TTF_Font.  Vamos a descargar el tipo de la susodicha página para usarla en el reloj de nuestro ejemplo anterior con el botón «Download zip»:

    Font con numeros digitales

    Al descomprimir el zip obtendrás un directorio con un fichero: Digital Numbers 400.ttf que es la fuente que vamos a usar. Ahora tenemos que convertirla al formato de M5Stack con el programa que vimos antes. Pulsa el botón “Seleccionar archivo:

    Cargar un font externo

    Se te abrirá un selector de ficheros TTF y puedes buscar en el directorio donde descomprimimos la fuente que bajamos antes:

    selector de fuentes

    Obtendrás esta pantalla para seleccionar la fuente con extensión ttf y ya solo necesitas pulsar el botón “Upload”

    Carar fuente externa truetype

    Al hacerlo te escribirá el mensaje de prueba con la fuente digital que hemos usado y ya podemos exportar esta fuente con el botón “Get GFX font file” lo que descargaría a tu directorio de Downloads el fichero “Digital_Numbers_40020pt7b.h” con el Font listo para usar en nuestro programa.

  • Pero antes de hacer esto, tienes que entender que los ficheros TTF son escalables y que si guardamos ahora el tipo de letra con el tamaño 20 puntos como en el ejemplo de arriba, esta será el tamaño 1 de nuestro tipo de letra, lo que significa que si intentamos la letra tamaño 2 no entrará en la pantalla. 
  • ¿Por qué entonces no guardar siempre el tipo de 1 punto y luego escalarlo? Aquí hay dos necesidades enfrentadas
  • Tienes que entender que las fuentes Truetype son vectoriales lo que significa que si le pidiésemos al programa de conversión hacer un Font de tamaño 1, luego podríamos escalarlo con mucha comodidad pero lamentablemente, al reducir los vectores al tamaño 1, al ampliar el resultado sería un asco ilegible (Lo he probado, pero tú ya eres mayor y puedes probarlo también)
  • Así pues la mejor opción suele ser exportar desde el programa de conversión, el tipo que vayas a usar y cuanto mayor sea este mejor, porque dibujara con más fidelidad el tamaño original. [/fancy-ul] [/three-fourth]
  •  

    Por eso te voy a recomendar que elijas, de momento, el tamaño 20 en el recuadro point antes de seguir exportando ¿Vale? Te exportará el fichero de nombre: Digital_Numbers_40020pt7b.h

    Tienes que copiar este fichero descargado al mismo directorio donde salves el programa Arduino para que puedas hacer el include y quedaría algo así:

    #include <M5Stack.h>
    #include <NTPClient.h>
    #include <WiFi.h>
    #include <WiFiUdp.h>
    #include "Digital_Numbers_40020pt7b.h".

    Es lo mismo del programa de reloj al que hemos añadido el include de tipo de letra digital. El resto del programa es todo igual con excepción de la función printclock que modificamos para usar este nuevo Font en pantalla: NTP_TTF_1

    void printClock()
    {    int H = timeClient.getHours();
         int M = timeClient.getMinutes();
         int S = timeClient.getSeconds();
    
         M5.Lcd.fillScreen(BLACK);   // Limpia la pantalla
         M5.Lcd.setCursor(0, 110);
         M5.Lcd.setTextColor(RED);
         M5.Lcd.setTextDatum(CC_DATUM);
         M5.Lcd.setTextSize(2);
         M5.Lcd.setFreeFont(&Digital_Numbers_40020pt7b); 
         M5.Lcd.printf("%02d:%02d:%02d", H, M, S ); }

    Las líneas claves son, por supuesto:

    M5.Lcd.setTextSize(2);
    M5.Lcd.setFreeFont(&Digital_Numbers_40040pt7b); 
    M5.Lcd.printf("%02d:%02d:%02d", H, M, S );

    Aunque hemos importado un font de 20 puntos, puedo escalarla usando la primera instrucción  y poner el TextSize a 2, o sea a 40 puntos (Si ponemos un 3 serán 60 puntos y las letras no entraran en la pantalla). Después con la segunda línea establecemos el tipo de letra que hemos importado y con la segunda imprimimos como siempre. Aquí tenéis el resultado:

    Ejemplo de display en pantalla

    Buenos, no cabe duda que se parece más a un reloj de verdad, pero aun tendremos que ajustar cosas. Lo primero es la mayor parte de los relojes no imprimen los segundos y nos vendría bien ese espacio para poder hacer mayor el tipo de letra en pantalla y si eliminamos los segundos y generamos una nueva fuente de 42 puntos (He hecho un montón de pruebas) podemos hacer algo así: NTP_TTF_3

    void printClock()
    {   int H = timeClient.getHours();
        int M = timeClient.getMinutes();
        int S = timeClient.getSeconds();
    
        M5.Lcd.fillScreen(BLACK);   // Limpia la pantalla
        M5.Lcd.setCursor(0, 120);
        M5.Lcd.setTextColor(RED);
        M5.Lcd.setTextSize(1); 
        M5.Lcd.setTextDatum(CC_DATUM);
        M5.Lcd.setFreeFont(&Digital_Numbers_40042pt7b);
    
        M5.Lcd.printf("%02d:%02d", H, M );
    }

    ¡Accede al contenido!

    Simplemente hemos usado el mayor font (42 puntos) que he podido encajar en el display y dibujamos la hora y minutos con ese tamaño:

    Mostrando el reloj con fuente TTF

    El resultado ya se parece mucho más a un reloj de verdad y aún nos queda sitio para poner la fecha completa y quizás alguna otra cosa que se nos ocurra.

     

    logoprometec

     

     


    Deja una respuesta