Pico Headers
Loading...
Searching...
No Matches
Classes | Typedefs | Functions
pico_font.h File Reference
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
Include dependency graph for pico_font.h:

Go to the source code of this file.

Classes

struct  pf_glyph_t
 UV coordinates and metrics for a cached glyph. More...
 
struct  pf_quad_t
 Quad emitted by pf_draw_text. More...
 
struct  pf_metrics_t
 Vertical font metrics for a face. More...
 

Typedefs

typedef struct pf_atlas_t pf_atlas_t
 
typedef struct pf_face_t pf_face_t
 
typedef bool(* pf_draw_callback_fn) (const pf_quad_t *quad, void *user)
 Callback invoked for each glyph quad during text drawing.
 
typedef bool(* pf_upload_callback_fn) (size_t page, const unsigned char *pixels, int width, int height, void *user)
 Callback invoked for each dirty atlas page during pf_upload_atlas.
 

Functions

pf_atlas_tpf_create_atlas (int page_width, int max_page_height)
 Allocates and initializes a font atlas.
 
void pf_destroy_atlas (pf_atlas_t *atlas)
 Destroys a font atlas and frees all associated pages and glyphs.
 
pf_face_tpf_create_face (pf_atlas_t *atlas, const unsigned char *ttf_data, float pixel_height)
 Create a font face at a given pixel height.
 
void pf_destroy_face (pf_face_t *face)
 Destroys a font face.
 
const pf_glyph_tpf_get_glyph (pf_face_t *face, uint32_t codepoint)
 Get (or rasterize) a single glyph.
 
void pf_draw_text (pf_face_t *face, const char *text, float *x, float *y, pf_draw_callback_fn cb, void *user)
 Lay out and emit quads for a UTF-8 string.
 
void pf_upload_atlas (pf_atlas_t *atlas, pf_upload_callback_fn cb, void *user)
 Iterate over dirty pages and invoke the callback for each one.
 
void pf_measure_text (pf_face_t *face, const char *text, float *out_width, float *out_height)
 Measure a UTF-8 string without drawing.
 
void pf_get_metrics (const pf_face_t *face, pf_metrics_t *metrics)
 Retrieve vertical font metrics for a face.
 
float pf_get_kerning (const pf_face_t *face, uint32_t cp1, uint32_t cp2)
 Get the horizontal kerning adjustment between two codepoints.
 

Typedef Documentation

◆ pf_atlas_t

typedef struct pf_atlas_t pf_atlas_t
@file pico_font.h
@brief A simple, dynamic (online) font atlas

----------------------------------------------------------------------------
Licensing information at end of header
----------------------------------------------------------------------------

Introduction:
-------------

A single-header library that rasterizes and caches glyphs on demand into a
multi-page texture atlas. Each page is a single-channel (alpha) bitmap with
a fixed width and a height that grows on demand up to a configurable maximum.
When a page is full, a new page is appended automatically. Glyph placement
uses row-based shelf packing. The library also supports basic, single line
drawing, but can be customized using the available metrics and measurement
functions.

Features:
---------
- Written in C99
- On-demand glyph rasterization via stb_truetype.h
- Multi-page atlas with automatic page growth and creation
- Hashtable glyph cache with automatic rehashing
- UTF-8 text layout with kerning (rendering API agnostic)
- Text measurement and font metrics
- Dirty-page tracking for efficient GPU uploads

Revision History:
-----------------

- 0.1 (2026/04/11):
    - On-demand glyph rasterization and storage
    - Simple text rendering

Usage:
------

    #define PICO_FONT_IMPLEMENTATION
    #include "pico_font.h"

You must also have stb_truetype.h available. Define STB_TRUETYPE_IMPLEMENTATION
exactly once in your project after including this file.

Quick Start:
------------

```c
pf_atlas_t* atlas = pf_create_atlas(512, 512);   // page width, max page height
pf_face_t*  face  = pf_create_face(atlas, ttf_data, 32.0f);  // 32px height

During rendering (call every frame for each string): float x = 10, y = 50; pf_draw_text(face, "Hello!", &x, &y, my_quad_callback, user_ptr);

The callback receives screen-space quads with atlas UVs and page index. After pf_draw_text, upload any dirty atlas pages to the GPU: pf_upload_atlas(atlas, my_upload_callback, user_ptr);

pf_destroy_face(face); pf_destroy_atlas(atlas); ```

Full Example:

A more or less complete example can be found at: examples_pico_gfx/text.c

Macro Overrides:

  • PICO_FONT_ASSERT (default: assert)
  • PICO_FONT_CALLOC (default: calloc)
  • PICO_FONT_REALLOC (default: realloc)
  • PICO_FONT_FRE (default: free)
  • PICO_FONT_MEMSET (default: memset)

Constant Overrides:

  • PICO_FONT_GLYPH_PADDING (default: 1)
  • PICO_FONT_CACHE_INIT_SIZE (default: 256)
  • PICO_FONT_INIT_PAGE_HEIGHT (default: 64)

◆ pf_face_t

typedef struct pf_face_t pf_face_t

◆ pf_draw_callback_fn

typedef bool(* pf_draw_callback_fn) (const pf_quad_t *quad, void *user)

Callback invoked for each glyph quad during text drawing.

Return false to stop iteration, true to continue.

◆ pf_upload_callback_fn

typedef bool(* pf_upload_callback_fn) (size_t page, const unsigned char *pixels, int width, int height, void *user)

Callback invoked for each dirty atlas page during pf_upload_atlas.

Parameters
pagepage index
pixelssingle-channel bitmap (width * height bytes)
width,bitmaphorizontal dimensions
heightbitmap vertical dimensions
Returns
false to stop iteration, true to continue. The dirty flag is cleared automatically after a successful (true) return.

Function Documentation

◆ pf_create_atlas()

pf_atlas_t * pf_create_atlas ( int  page_width,
int  max_page_height 
)

Allocates and initializes a font atlas.

Each atlas is composed of one or more bitmap pages that store rasterized glyphs and their associated metadata. Pages start empty and grow vertically (doubling in height) as glyphs are added, up to max_page_height. Once a page is full, a new page is appended automatically.

Parameters
page_widthWidth of each atlas page in pixels.
max_page_heightMaximum height each page may grow to in pixels.
Returns
A new atlas, or NULL on allocation failure.

◆ pf_destroy_atlas()

void pf_destroy_atlas ( pf_atlas_t atlas)

Destroys a font atlas and frees all associated pages and glyphs.

Parameters
atlasAtlas to destroy. May be NULL (no-op).

◆ pf_create_face()

pf_face_t * pf_create_face ( pf_atlas_t atlas,
const unsigned char *  ttf_data,
float  pixel_height 
)

Create a font face at a given pixel height.

Initialises an stb_truetype font from raw TrueType data and binds it to atlas for glyph caching. The face does not take ownership of ttf_data; the caller must keep it alive for the lifetime of the face.

Parameters
atlasAtlas that will store rasterized glyphs.
ttf_dataPointer to the raw TrueType font file contents.
pixel_heightDesired font height in pixels.
Returns
A new face, or NULL on failure.

◆ pf_destroy_face()

void pf_destroy_face ( pf_face_t face)

Destroys a font face.

Does not destroy the atlas it was bound to.

Parameters
faceFace to destroy. May be NULL (no-op).

◆ pf_get_glyph()

const pf_glyph_t * pf_get_glyph ( pf_face_t face,
uint32_t  codepoint 
)

Get (or rasterize) a single glyph.

If the glyph is already cached, returns it immediately. Otherwise it is rasterized into the atlas and cached for future lookups.

Parameters
faceFace to use for rasterization.
codepointUnicode codepoint.
Returns
Pointer into the atlas glyph array, or NULL on failure.

◆ pf_draw_text()

void pf_draw_text ( pf_face_t face,
const char *  text,
float *  x,
float *  y,
pf_draw_callback_fn  cb,
void *  user 
)

Lay out and emit quads for a UTF-8 string.

For each visible glyph the callback receives a screen-space quad with atlas UVs and a page index. Kerning is applied automatically between adjacent codepoints. The caller is responsible for line breaking; use pf_get_metrics() to obtain the line height for advancing *y between lines.

Parameters
faceFace to use.
textNull-terminated UTF-8 string.
xIn/out cursor X position. Updated after the last glyph.
yIn/out cursor Y position. Updated after the last glyph.
cbCallback invoked for each visible glyph quad. May be NULL.
userOpaque pointer forwarded to cb.

◆ pf_upload_atlas()

void pf_upload_atlas ( pf_atlas_t atlas,
pf_upload_callback_fn  cb,
void *  user 
)

Iterate over dirty pages and invoke the callback for each one.

A page becomes dirty whenever a new glyph is rasterized into it. The dirty flag is cleared for each page whose callback returns non-zero, so calling this after drawing ensures the GPU copy stays in sync.

Parameters
atlasThe atlas to upload.
cbCallback invoked once per dirty page.
userOpaque pointer forwarded to cb.

◆ pf_measure_text()

void pf_measure_text ( pf_face_t face,
const char *  text,
float *  out_width,
float *  out_height 
)

Measure a UTF-8 string without drawing.

Performs the same layout as pf_draw_text but does not emit quads.

Parameters
faceFace to use.
textNull-terminated UTF-8 string.
out_widthReceives the bounding-box width. May be NULL.
out_heightReceives the bounding-box height. May be NULL.

◆ pf_get_metrics()

void pf_get_metrics ( const pf_face_t face,
pf_metrics_t metrics 
)

Retrieve vertical font metrics for a face.

Parameters
faceFace to query.
metricsReceives the metrics. Must not be NULL.

◆ pf_get_kerning()

float pf_get_kerning ( const pf_face_t face,
uint32_t  cp1,
uint32_t  cp2 
)

Get the horizontal kerning adjustment between two codepoints.

Parameters
faceFace to query.
cp1Left codepoint.
cp2Right codepoint.
Returns
Kerning offset in pixels (typically negative for tighter pairs).