SDK Multiplataforma en C logo

SDK Multiplataforma en C

Fuentes

❮ Anterior
Siguiente ❯

Cabecera

#include <draw2d/font.h>


Funciones

Font*font_create (...)
Font*font_system (...)
Font*font_monospace (...)
Font*font_with_style (...)
Font*font_with_width (...)
Font*font_with_xscale (...)
Font*font_with_cell_size (...)
Font*font_copy (...)
voidfont_destroy (...)
bool_tfont_equals (...)
real32_tfont_regular_size (void)
real32_tfont_small_size (void)
real32_tfont_mini_size (void)
const char_t*font_family (...)
real32_tfont_size (...)
real32_tfont_height (...)
real32_tfont_width (...)
real32_tfont_xscale (...)
real32_tfont_ascent (...)
real32_tfont_descent (...)
real32_tfont_leading (...)
bool_tfont_is_monospace (...)
uint32_tfont_style (...)
voidfont_extents (...)
bool_tfont_exists_family (...)
ArrPt(String)*font_installed_families (void)
ArrPt(String)*font_installed_monospace (void)
void*font_native (...)
void*font_native_dpi (...)
voidfont_metrics_dpi (...)

Las fuentes tipográficas son objetos gráficos (archivos) que contienen los caracteres y símbolos que vemos en un monitor. Recordamos que una cadena Unicode únicamente almacena el código de los caracteres (codepoints) sin ningún tipo de información sobre como se dibujarán. Se conoce como glifo al gráfico asociado a un carácter y, en un fichero de fuente, hay tantos glifos como codepoints pueda representar la tipografía. El emparejamiento entre codepoints y sus correspondientes glifos lo lleva a cabo el sub-sistema gráfico del sistema operativo (Listado 1) (Figura 1).

Listado 1: Dibujo de una cadena de texto.
1
2
3
4
Font *font = font_create("Comic Sans MS" 28, 0);
draw_font(ctx, font);
draw_text(ctx, "Hello World", 200, 250);
font_destroy(&font);
Gráfico que relaciones caracteres Unicode con glifos y tipografías.
Figura 1: Representación de textos: codepoints + glifos.

1. Crear fuentes

A la hora de mostrar textos en interfaces gráficas es necesario establecer una tipografía, de lo contrario el sistema no sabría como renderizarla. Siempre existirá alguna fuente definida por defecto, pero podemos cambiarla a la hora de personalizar la apariencia de nuestros textos.

  • Utiliza font_create para crear una nueva fuente.
  • Utiliza font_family para obtener el tipo de letra de la fuente.
  • Utiliza draw_font para establecer la fuente en contextos 2D.
  • Utiliza label_font para cambiar la fuente asociada a un control Label.

La característica más representativa del diseño de una tipografía es la familia a la que pertenece (font family o typeface) (Figura 2). Cada computador tiene instaladas una serie de familias que no tienen porqué coincidir con las incorporadas en otra máquina. Este es un hecho importante a tener en cuenta ya que, en pro de la portabilidad, no debemos asumir que una determinada familia tipográfica vaya a estar presente en todas las máquinas que ejecuten el programa. Sentencias del tipo:

1
Font *font = font_create("Comic Sans MS", 28, 0);

no serán del todo portables, ya que no tenemos la certeza de que la tipografía Comic Sans MS esté instalada en todos los ordenadores.

  • Utiliza font_installed_families para obtener la lista de todas las familias instaladas en la máquina.
  • Texto Hello World escrito utilizando diferentes tipografías.
    Figura 2: Diferentes familias tipográficas.

2. Fuente del sistema

  • Utiliza font_system para crear una fuente con la familia predeterminada.
  • Utiliza font_regular_size para obtener el tamaño de fuente de la interfaz.

Siempre hay una fuente por defecto asociada al entorno de ventanas y que, en cierta manera, le otorga parte de su personalidad. Utilizar esta fuente nos garantiza la correcta integración de nuestro programa en todos los sistemas donde se ejecute, haciendo nuestro código totalmente portable (Figura 3). Controles como Button o Label tienen asociada por defecto la fuente del sistema en tamaño regular. Las más conocidas son:

  • Segoe UI: Windows Vista, 7, 8, 10, 11.
  • Tahoma: Windows XP.
  • San Francisco: Mac OSX El Capitan y posteriores.
  • Helvetica Neue: Mac OSX Yosemite.
  • Lucida Grande: Mac OSX Mavericks, Mountain Lion, Lion, Snow Leopard.
  • Ubuntu: Linux Ubuntu.
  • Piboto: Linux Raspbian.
  • Cantarell: Kali Linux.
  • Captura de la misma aplicación en diferentes sistemas, utilizando la fuente por defecto.
    Figura 3: Uso de la fuente del sistema.

3. Fuente monoespaciada

Además de la fuente del sistema tenemos disponible otra fuente monoespaciada por defecto (Figura 4). Estas tipografías imitan a las máquinas de escribir antiguas, donde todos los caracteres ocupan el mismo espacio. Suelen utilizarse para documentos técnicos o archivos de código fuente.

  • Utiliza font_monospace para crear una tipografía monoespacio genérica.
  • Utiliza font_is_monospace para comprobar si una fuente es monoespaciada.
  • Utiliza font_installed_monospace para obtener todas las fuentes monoespaciadas instaladas.
  • Comparativa de una fuente proporcional y monoespaciada.
    Figura 4: Fuente proporcional (ancho variable) y monoespaciada (ancho fijo).

En general, las APIs gráficas no ofrecen una fuente monoespaciada por defecto. NAppGUI seleccionará la más apropiada en cada caso buscando entre las fuentes instaladas:

  • Windows: Consolas, Courier New.
  • macOS: SF Mono, Menlo, Monaco, Andale Mono, Courier New.
  • Linux: Ubuntu Mono, DejaVu Sans Mono, Courier New.
A partir de macOS Catalina, Cocoa sí que ofrece una fuente de sistema monoespaciada.

No obstante, puedes registrar una familia monoespaciada por defecto para toda la aplicación mediante draw2d_preferred_monospace. Cualquier llamada a font_monospace dará prioridad a esta opción de usuario.


4. Estilo de la fuente

Además de la familia, dispondremos de ciertas propiedades (estilo) que también influirán en su apariencia. Se agrupan en el parámetro style del constructor, combinando los valores de fstyle_t (Figura 5).


5. Tamaño y métricas

  • Utiliza font_size para obtener el tamaño de la fuente.
  • Utiliza font_height para obtener el tamaño de línea.
  • Utiliza font_ascent para obtener la medida encima del baseline.
  • Utiliza font_descent para obtener la medida debajo del baseline.
  • Utiliza font_leading para obtener el margen de línea.
  • Utiliza font_extents para obtener la medida de un texto.

El tamaño de letra (size) se expresa siempre en puntos lógicos de pantalla, independientes de la resolución (DPI) del dispositivo. Existen diferentes medidas asociadas que nos pueden ser útiles a la hora de trabajar con gráficos vectoriales (Figura 6). La más utilizada será la altura de línea (height), en general, algo superior al tamaño de letra ya que incluye un pequeño margen vertical (leading). Puedes utilizar font_with_cell_size para obtener una fuente cuya altura de línea (en lugar de la altura de letra) coincida con un tamaño dado.

Gráfico con las diferentes medidas de un texto.
Figura 6: Métricas del texto con una fuente dada.

6. Ancho de fuente

En general, la anchura media del carácter viene determinada por el tamaño de la fuente y casi nunca deberíamos tener necesidad de cambiarla (Figura 7). Pero en ocasiones puede ser útil "estirar" o "contraer" el texto dejando intacta su altura. Pensemos, por ejemplo, en la emulación de terminales donde cada celda deba ocupar una determinada anchura.

Diferentes elementos GUI donde se ha cambiado la anchura de la fuente.
Figura 7: Efecto de cambiar el ancho de fuente en contextos de dibujo y elementos GUI.

Consideramos anchura media al tamaño en píxeles de la cadena [A-Z][a-z][0-9] dividido por 62. Evidentemente, en fuentes monoespaciadas, la anchura media corresponderá con la anchura de cualquier carácter. El escalado en X, es un valor relacionado con la anchura, pero más intuitivo a la hora de crear la fuente.


7. Fuentes Bitmap y Outline

En los primeros computadores las tipografías se creaban como gráficos de raster Bitmap Fonts (Figura 8). Cada carácter se ajustaba a una celda de tamaño fijo donde se marcaban aquellos píxeles que lo componían. El mayor problema es que no escalan bien. A medida que hacemos más grande el texto en pantalla más se hace patente el efecto dentado de los píxeles.

Ampliación de una fuente bitmap, donde se aprecia el efecto dentado.
Figura 8: Fuentes bitmap.

En 1982 Adobe lanza el formato PostScript que incluía las conocidas como Outline Fonts (Figura 9). Este formato contiene una descripción geométrica de cada símbolo basada en líneas y curvas de Bezier. De esta forma se evita el efecto pixelado de las bitmap, ya que al escalar el carácter se vuelven a computar los píxeles que lo componen en un proceso conocido como rasterización. A finales de los 80's Apple lanza el formato TrueType y le vende una licencia a Microsoft que lo incorpora en Windows 3.1, abriendo la puerta del mercado masivo a las fuentes vectoriales. Hoy en día todos los sistemas trabajan con fuentes escalables, teniendo en TrueType y OpenType los más claros representantes.

Escalado de una fuente outline (vectorial).
Figura 9: Fuentes outline, en las que se basan los formatos TrueType y OpenType.

8. Unicode y glifos

Unicode es una tabla muy extensa. En la versión 11 (Junio 2018) hay registrados 137.374 codepoints y este número va creciendo en cada nueva revisión del estándar. Si la aplicación necesita de símbolos especiales (por encima del BMP-Basic Multilingual Plane) debemos cerciorarnos que las tipografías seleccionadas contengan glifos para ellos. Para ver la relación entre codepoints y glifos podemos utilizar la aplicación BabelMap (Figura 10), y dentro de ella la opción Font Analysis. A partir de un bloque Unicode mostrará aquellas fuentes instaladas que incluyen glifos para dicho rango. En macOS tenemos una aplicación similar llamada Character Viewer y en Ubuntu otra denominada Character Map.

Aplicación que muestra los glifos incluidos en cada fuente tipográfica.
Figura 10: BabelMap Font Analysis nos proporciona información sobre los glifos incluidos en cada tipografía.
❮ Anterior
Siguiente ❯

font_create ()

Crea una fuente tipográfica.

Font*
font_create(const char_t *family,
            const real32_t size,
            const uint32_t style);
family

Familia tipográfica. Pe: "Arial", "Times New Roman", etc.

size

Tamaño de la fuente, en puntos lógicos de pantalla.

style

Operación OR | sobre los campos de la estructura fstyle_t. Pe: ekFBOLD | ekFITALIC.

Retorna

La fuente recién creada.


font_system ()

Crea una fuente tipográfica, con la familia por defecto del sistema.

Font*
font_system(const real32_t size,
            const uint32_t style);
size

Tamaño de la fuente, en puntos lógicos de pantalla.

style

Operación OR | sobre los campos de la estructura fstyle_t. Pe: ekFBOLD | ekFITALIC.

Retorna

La fuente recién creada.

Observaciones

Ver Fuente del sistema.


font_monospace ()

Crea una fuente tipográfica, con la familia mono-espacio por defecto del sistema.

Font*
font_monospace(const real32_t size,
               const uint32_t style);
size

Tamaño de la fuente, en puntos lógicos de pantalla.

style

Operación OR | sobre los campos de la estructura fstyle_t. Pe: ekFBOLD | ekFITALIC.

Retorna

La fuente recién creada.

Observaciones

Ver Fuente monoespaciada.


font_with_style ()

Crea una copia de una fuente existente, cambiando el estilo.

Font*
font_with_style(const Font *font,
                const uint32_t style);
font

Fuente original.

style

Operación OR | sobre los campos de la estructura fstyle_t. Pe: ekFBOLD | ekFITALIC.

Retorna

Una copia de font con otro estilo.


font_with_width ()

Crea una copia de una fuente existente, cambiando el ancho medio del carácter.

Font*
font_with_width(const Font *font,
                const real32_t width);
font

Fuente original.

width

Anchura media del carácter.

Retorna

Una copia de font cambiando el ancho del carácter.

Observaciones

Se considera anchura media el tamaño en pixels de la cadena "[A-Z][a-z][0-9]" / 62. Cambiar este valor implica cambiar el escalado en x, ya que son valores relacionados. Ver Ancho de fuente.


font_with_xscale ()

Crea una copia de una fuente existente, cambiando el escalado en x del texto.

Font*
font_with_xscale(const Font *font,
                 const real32_t scale);
font

Fuente original.

scale

Escalado. Por defecto es 1.

Retorna

Una copia de font cambiando el escalado.

Observaciones

Cambiar el escalado implica cambiar la anchura media del carácter, ya que son valores relacionados. Ver Ancho de fuente.


font_with_cell_size ()

Crea una copia de una fuente existente, ajustando su tamaño para que la altura de celda coincida con el valor indicado.

Font*
font_with_cell_size(const Font *font,
                    const real32_t size);
font

Fuente original.

size

Altura de celda deseada, en puntos lógicos de pantalla.

Retorna

Una copia de font con el tamaño ajustado.

Observaciones

Ver Tamaño y métricas.


font_copy ()

Crea una copia exacta de una fuente tipográfica.

Font*
font_copy(const Font *font);
font

Fuente original.

Retorna

La copia de font.

Observaciones

Las fuentes son objetos inmutables. Copiar realmente significa incrementar un contador interno sin llegar a clonar el objeto. No obstante, la aplicación debe destruir la copia con font_destroy al igual que las creadas con cualquier otro constructor.


font_destroy ()

Destruye la fuente.

void
font_destroy(Font **font);
font

La fuente. Será puesto a NULL tras la destrucción.


font_equals ()

Compara dos fuentes. Se consideran iguales si tienen la misma familia, tamaño y estilo.

bool_t
font_equals(const Font *font1,
            const Font *font2);
font1

Primera fuente a comparar.

font2

Segunda fuente a comparar.

Retorna

TRUE si son iguales, FALSE si no.


font_regular_size ()

Obtiene el tamaño de la fuente por defecto para los controles de interfaz.

real32_t
font_regular_size(void);

Retorna

El tamaño por defecto, en puntos lógicos de pantalla.

Observaciones

Ver Fuente del sistema.


font_small_size ()

Obtiene el tamaño pequeño de la fuente por defecto para los controles de interfaz.

real32_t
font_small_size(void);

Retorna

El tamaño, en puntos lógicos de pantalla.

Observaciones

Este tamaño es ligeramente menor que el obtenido por font_regular_size.


font_mini_size ()

Obtiene el tamaño mini de la fuente por defecto para los controles de interfaz.

real32_t
font_mini_size(void);

Retorna

El tamaño, en puntos lógicos de pantalla.

Observaciones

Este tamaño es ligeramente menor que el obtenido por font_small_size.


font_family ()

Obtiene la familia tipográfica de la fuente.

const char_t*
font_family(const Font *font);
font

La fuente.

Retorna

La familia tipográfica en UTF8.


font_size ()

Obtiene el tamaño de la fuente.

real32_t
font_size(const Font *font);
font

La fuente.

Retorna

El tamaño, en puntos lógicos de pantalla.

Observaciones

Ver Tamaño y métricas.


font_height ()

Obtiene la altura de la celda o línea de texto con esta fuente.

real32_t
font_height(const Font *font);
font

La fuente.

Retorna

Altura de línea.

Observaciones

Ver Tamaño y métricas.


font_width ()

Obtiene la anchura media del carácter.

real32_t
font_width(const Font *font);
font

La fuente.

Retorna

Anchura media.

Observaciones

Ver Ancho de fuente.


font_xscale ()

Obtiene el escalado en x del texto.

real32_t
font_xscale(const Font *font);
font

La fuente.

Retorna

Escalado.

Observaciones

Ver Ancho de fuente.


font_ascent ()

Obtiene la medida de la fuente por encima del baseline.

real32_t
font_ascent(const Font *font);
font

La fuente.

Retorna

Medida superior.

Observaciones

Ver Tamaño y métricas.


font_descent ()

Obtiene la medida de la fuente por debajo del baseline.

real32_t
font_descent(const Font *font);
font

La fuente.

Retorna

Medida inferior.

Observaciones

Ver Tamaño y métricas.


font_leading ()

Obtiene el margen entre el tamaño de carácter y la altura de línea.

real32_t
font_leading(const Font *font);
font

La fuente.

Retorna

Margen.

Observaciones

Ver Tamaño y métricas.


font_is_monospace ()

Consulta si una fuente es monoespaciada o no.

bool_t
font_is_monospace(const Font *font);
font

La fuente.

Retorna

TRUE si la fuente es monoespaciada.

Observaciones

Ver Fuente monoespaciada.


font_style ()

Obtiene el estilo de la fuente.

uint32_t
font_style(const Font *font);
font

La fuente.

Retorna

El estilo. Combinación de valores de la estructura fstyle_t. Pe: ekFBOLD | ekFITALIC.


font_extents ()

Obtiene el tamaño en píxeles de una cadena de texto, en función de la fuente.

void
font_extents(const Font *font,
             const char_t *text,
             const real32_t refwidth,
             real32_t *width,
             real32_t *height);
font

La fuente.

text

La cadena de texto a dimensionar.

refwidth

Anchura máxima del cuadro de texto o -1.

width

Ancho del cuadro de texto.

height

Alto del cuadro de texto.

Observaciones

Si se encuentran saltos de línea '\n' el cuadro de texto crecerá en altura. Si se establece refwidth > 0 se limitará la anchura del cuadro, creciendo en altura lo suficiente para albergar todo el texto. Únicamente se considerará una sola línea de texto si refwidth < 0 y no existen '\n'.


font_exists_family ()

Comprueba si una familia tipográfica está instalada en el sistema operativo.

bool_t
font_exists_family(const char_t *family);
family

Cadena UTF8 con el nombre de la familia, terminada en carácter nulo '\0'.

Retorna

TRUE si existe la familia, FALSE si no.


font_installed_families ()

Obtiene una lista con los nombres de todas las familias tipográficas instaladas en el sistema operativo.

ArrPt(String)*
font_installed_families(void);
1
2
3

Retorna

Array de String con los nombres de las familias, ordenadas alfabéticamente. Debe ser destruido con arrpt_destroy.

Observaciones

Ver Crear fuentes.


font_installed_monospace ()

Obtiene una lista con los nombres de todas las familias monoespaciadas instaladas en el sistema operativo.

ArrPt(String)*
font_installed_monospace(void);
1
2
3

Retorna

Array de String con los nombres de las familias, ordenadas alfabéticamente. Debe ser destruido con arrpt_destroy.

Observaciones

Ver Fuente monoespaciada.


font_native ()

Obtiene la fuente en el formato nativo de cada plataforma.

void*
font_native(const Font *font);
font

La fuente.

Retorna

La fuente nativa. HFONT en Windows, PangoFontDescription en Linux y NSFont en macOS.


font_native_dpi ()

Obtiene la fuente en el formato nativo de cada plataforma, resuelta para un DPI concreto.

void*
font_native_dpi(const Font *font,
                const uint32_t dpi);
font

La fuente.

dpi

El DPI para el que se resuelve la fuente nativa (96 equivale a la resolución lógica de referencia).

Retorna

La fuente nativa. HFONT en Windows, PangoFontDescription en Linux y NSFont en macOS.

Observaciones

Función de uso interno del SDK — la aplicación no debería necesitar llamarla en el uso habitual del API. En Windows, cada dpi distinto solicitado se resuelve y cachea de forma independiente, sin alterar el HFONT por defecto que devuelve font_native. En macOS y Linux equivale a font_native, ya que esas plataformas no distinguen la fuente nativa por DPI.


font_metrics_dpi ()

Establece el DPI que se utilizará internamente para medir texto (font_extents, font_height y funciones relacionadas) hasta la siguiente llamada.

void
font_metrics_dpi(const uint32_t dpi);
dpi

El DPI de referencia para las medidas (96 equivale a la resolución lógica de referencia).

Observaciones

Función de uso interno del SDK — la aplicación no debería necesitar llamarla en el uso habitual del API. Solo tiene efecto en Windows, donde el redondeo (hinting) de la fuente al medir puede variar según el DPI real de renderizado; se utiliza para sincronizar las medidas de texto con el DPI real de una ventana concreta justo antes de recalcular su layout. En macOS y Linux no tiene efecto, ya que las medidas de texto de esas plataformas ya son siempre coherentes con el DPI real.

❮ Anterior
Siguiente ❯