hb-gpu: HarfBuzz Manual

## hb-gpu hb-gpu — GPU text rendering |

## Functions

const char * | hb_gpu_shader_source ()
const char * | hb_gpu_draw_shader_source ()
hb_gpu_draw_t * | hb_gpu_draw_create_or_fail ()
hb_gpu_draw_t * | hb_gpu_draw_reference ()
void | hb_gpu_draw_destroy ()
hb_bool_t | hb_gpu_draw_set_user_data ()
void * | hb_gpu_draw_get_user_data ()
hb_draw_funcs_t * | hb_gpu_draw_get_funcs ()
void | hb_gpu_draw_set_scale ()
void | hb_gpu_draw_get_scale ()
void | hb_gpu_draw_glyph ()
hb_bool_t | hb_gpu_draw_glyph_or_fail ()
hb_blob_t * | hb_gpu_draw_encode ()
void | hb_gpu_draw_clear ()
void | hb_gpu_draw_reset ()
void | hb_gpu_draw_recycle_blob ()
hb_gpu_paint_t * | hb_gpu_paint_create_or_fail ()
hb_gpu_paint_t * | hb_gpu_paint_reference ()
void | hb_gpu_paint_destroy ()
hb_bool_t | hb_gpu_paint_set_user_data ()
void * | hb_gpu_paint_get_user_data ()
hb_paint_funcs_t * | hb_gpu_paint_get_funcs ()
void | hb_gpu_paint_set_palette ()
unsigned | hb_gpu_paint_get_palette ()
void | hb_gpu_paint_clear_custom_palette_colors ()
hb_bool_t | hb_gpu_paint_set_custom_palette_color ()
void | hb_gpu_paint_set_scale ()
void | hb_gpu_paint_get_scale ()
void | hb_gpu_paint_glyph ()
hb_bool_t | hb_gpu_paint_glyph_or_fail ()
hb_blob_t * | hb_gpu_paint_encode ()
void | hb_gpu_paint_clear ()
void | hb_gpu_paint_reset ()
void | hb_gpu_paint_recycle_blob ()
const char * | hb_gpu_paint_shader_source ()

## Types and Values

enum | hb_gpu_shader_lang_t
enum | hb_gpu_shader_stage_t
typedef | hb_gpu_draw_t
typedef | hb_gpu_paint_t

## Includes

    #include <hb-gpu.h>

## Description

This module provides GPU-side text rendering. Glyph data is encoded on the CPU into compact blobs that the GPU decodes and rasterizes directly in the fragment shader, with no intermediate bitmap atlas.

Two renderers share the same atlas, vertex stage, and pipeline:

- Draw, an antialiased monochrome coverage mask for outline glyphs.

- Paint, a premultiplied-RGBA color accumulator for COLRv0 and COLRv1 glyphs. Paint also renders plain monochrome outlines (as a single foreground-colored layer), at some cost over the Draw path.

Applications typically pick one renderer per font, based on whether the font has a color paint table (see `hb_ot_color_has_paint()`). The Draw path is meaningfully faster than Paint on monochrome fonts, so using Paint unconditionally leaves performance on the table.

See the live web demo.

### Draw

The draw renderer implements the Slug algorithm by Eric Lengyel. It produces an antialiased coverage mask in the fragment shader, suitable for compositing over any background or multiplying with any foreground color.

#### Encoding

Each glyph is encoded independently into an opaque blob of RGBA16I texels (8 bytes each). Typical encoding flow:

    hb_gpu_draw_t *draw = hb_gpu_draw_create_or_fail ();

    hb_gpu_draw_glyph (draw, font, gid);
    hb_blob_t *blob = hb_gpu_draw_encode (draw);

    // Upload hb_blob_get_data(blob) to the atlas at some offset.
    unsigned atlas_offset = upload_to_atlas (blob);

    hb_gpu_draw_recycle_blob (draw, blob);
    // repeat for more glyphs...

    hb_gpu_draw_destroy (draw);

Create the encoder once and reuse it across glyphs. `hb_gpu_draw_encode()` auto-clears the accumulated outlines on return, so the next call to `hb_gpu_draw_glyph()` starts fresh; user configuration (font scale) is preserved. Pass the encoded blob back via `hb_gpu_draw_recycle_blob()` after upload to recycle the buffer across encodes.

#### Atlas setup

All encoded blobs are uploaded into a single GL_TEXTURE_BUFFER backed by a GL_RGBA16I format buffer. Each glyph occupies a contiguous range of texels at a known offset:

    GLuint buf, tex;
    glGenBuffers (1, &buf);
    glGenTextures (1, &tex);

    glBindBuffer (GL_TEXTURE_BUFFER, buf);
    glBufferData (GL_TEXTURE_BUFFER, capacity * 8, NULL, GL_STATIC_DRAW);

    glBindTexture (GL_TEXTURE_BUFFER, tex);
    glTexBuffer (GL_TEXTURE_BUFFER, GL_RGBA16I, buf);

    // Upload a glyph blob at 'offset' texels:
    glBufferSubData (GL_TEXTURE_BUFFER,
                     offset * 8,
                     hb_blob_get_length (blob),
                     hb_blob_get_data (blob, NULL));

#### Shader compilation

The library provides GLSL source strings for shared helpers (atlas access, vertex dilation) and for the draw-renderer stage code. Prepend a version directive, concatenate shared and draw sources in order, and append your own `main()`:

    const char *vert_sources[] = {
        "#version 330\n",
        hb_gpu_shader_source      (HB_GPU_SHADER_STAGE_VERTEX,
                                   HB_GPU_SHADER_LANG_GLSL),
        hb_gpu_draw_shader_source (HB_GPU_SHADER_STAGE_VERTEX,
                                   HB_GPU_SHADER_LANG_GLSL),
        your_vertex_main
    };
    glShaderSource (vert_shader, 4, vert_sources, NULL);
    // Same pattern for the fragment shader.

hb_gpu_draw_shader_source() returns an empty string for the vertex stage, so the assembly order above is safe.

#### Vertex shader

The vertex library provides one function:

    void hb_gpu_dilate (inout vec2 position, inout vec2 texcoord,
                        vec2 normal, vec4 jac,
                        mat4 m, vec2 viewport);

This expands each glyph quad by approximately half a pixel on screen to ensure proper antialiasing coverage at the edges. It must be called in the vertex shader before computing gl_Position.

Per-vertex attributes for each glyph quad (2 triangles, 6 vertices, 4 unique corners):

- position (vec2): object-space vertex position, computed from the glyph's bounding box. For corner (cx, cy) where cx,cy are 0 or 1:

      pos.x = pen_x + scale * lerp(extent_min_x, extent_max_x, cx)
      pos.y = pen_y - scale * lerp(extent_min_y, extent_max_y, cy)

  where scale = font_size / upem.

- texcoord (vec2): em-space texture coordinates, equal to the raw extent values: `(ex, ey)` where ex/ey are the glyph's bounding box corners in font design units. The fragment shader samples the encoded blob in this coordinate space.

- normal (vec2): outward normal at each corner. `(-1, +1)` for (0,0), `(+1, +1)` for (1,0), `(-1, -1)` for (0,1), `(+1, -1)` for (1,1). Note: y is negated relative to cx,cy because the common em-to-object transform flips y.

- jac (vec4): maps object-space displacements back to em-space after dilation, stored row-major as (j00, j01, j10, j11). For the common case of uniform scaling with y-flip:

      jac = vec4(emPerPos, 0.0, 0.0, -emPerPos)

  where emPerPos = upem / font_size. For non-trivial transforms, see the hb_gpu_dilate source.

- m (mat4): the model-view-projection matrix (uniform).

- viewport (vec2): the viewport size in pixels (uniform).

A typical vertex main:

    uniform mat4 u_matViewProjection;
    uniform vec2 u_viewport;

    in vec2 a_position;
    in vec2 a_texcoord;
    in vec2 a_normal;
    in float a_emPerPos;
    in uint a_glyphLoc;

    out vec2 v_texcoord;
    flat out uint v_glyphLoc;

    void main () {
      vec2 pos = a_position;
      vec2 tex = a_texcoord;
      vec4 jac = vec4 (a_emPerPos, 0.0, 0.0, -a_emPerPos);
      hb_gpu_dilate (pos, tex, a_normal, jac,
                     u_matViewProjection, u_viewport);
      gl_Position = u_matViewProjection * vec4 (pos, 0.0, 1.0);
      v_texcoord = tex;
      v_glyphLoc = a_glyphLoc;
    }

#### Font scale

The encoder works in font design units (upem). For best results, do not set a scale on the hb_font_t passed to `hb_gpu_draw_glyph()` — leave it at the default (upem). Scaling is applied later when computing vertex positions:

    float scale = font_size / upem;
    pos.x = pen_x + scale * extent_x;
    pos.y = pen_y - scale * extent_y;

If you do set a font scale (e.g. for hinting), the encoded blob and extents will be in the scaled coordinate space, and you must adjust emPerPos accordingly.

#### Dilation

Each glyph is rendered on a screen-aligned quad whose corners match the glyph's bounding box. Without dilation, the antialiased edges at the quad boundary get clipped — the fragment shader needs at least half a pixel of padding around the glyph to produce smooth coverage gradients.

hb_gpu_dilate computes a perspective-correct half-pixel expansion. It adjusts both the vertex position (expanding the quad) and the texcoord (so the fragment shader samples the right location in em-space after expansion).

The `jac` parameter maps object-space displacements back to em-space. For the common case of uniform scaling with y-flip (`pos.y = pen_y - scale * ey`):

    float emPerPos = upem / font_size;
    jac = vec4(emPerPos, 0.0, 0.0, -emPerPos);

For non-uniform scaling or shearing transforms, jac is the 2x2 inverse of the em-to-object linear transform, stored row-major.

### Static dilation alternative

Applications that do not need perspective correctness (e.g. strictly 2D rendering at known sizes) can skip hb_gpu_dilate and instead expand each quad vertex by a fixed amount along its normal, based on the minimum expected font size:

    float min_ppem = 10.0;  // smallest expected size in pixels
    float pad = 0.5 * upem / min_ppem;  // half-pixel in em units
    pos += normal * pad * scale;
    texcoord += normal * pad;

This over-dilates at larger sizes (wasting fill rate on transparent pixels) but is simpler to implement and avoids the need for the MVP matrix and viewport size in the vertex shader.

#### Fragment shader

The fragment library provides two functions:

    float hb_gpu_draw (vec2 renderCoord, uint glyphLoc);

It requires the `hb_gpu_atlas` uniform to be bound to the texture containing the encoded glyph data. By default this is an `isamplerBuffer` (GL_TEXTURE_BUFFER). For platforms without texture buffers (e.g. WebGL2), define `HB_GPU_ATLAS_2D` before including the shader source; the atlas then becomes an `isampler2D` and a `uniform int hb_gpu_atlas_width` must also be set to the texture width.

Parameters:

- renderCoord: the interpolated em-space coordinate from the vertex shader (v_texcoord).

- glyphLoc: the texel offset of this glyph's encoded blob in the atlas buffer. Passed as a flat varying from the vertex shader.

Returns the coverage in [0, 1]: 1.0 inside the glyph, 0.0 outside, with antialiased edges.

A typical fragment main:

    in vec2 v_texcoord;
    flat in uint v_glyphLoc;
    out vec4 fragColor;

    void main () {
      float coverage = hb_gpu_draw (v_texcoord, v_glyphLoc);
      fragColor = vec4 (0.0, 0.0, 0.0, coverage);
    }

The coverage value can be used with alpha blending (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) to composite over a background, or multiplied with any color.

#### Stem darkening

    float hb_gpu_stem_darken (float coverage, float brightness, float ppem);

Optional stem darkening adjusts coverage at small sizes so thin stems are not washed out by gamma correction.

Parameters:

- coverage: a coverage / alpha value in [0, 1]. For `hb_gpu_draw()` this is the returned coverage; for `hb_gpu_paint()` use the edge coverage out parameter.

- brightness: brightness of the color that will end up on screen for this fragment, in [0, 1], computed as `dot (straight_color.rgb, vec3 (1.0 / 3.0))`.

- ppem: pixels per em at this fragment, computed as `1.0 / max (fwidth (v_texcoord).x, fwidth (v_texcoord).y)`.

Example — draw path:

    float coverage = hb_gpu_draw (v_texcoord, v_glyphLoc);
    float brightness = dot (u_foreground.rgb, vec3 (1.0 / 3.0));
    float ppem = 1.0 / max (fwidth (v_texcoord).x,
                             fwidth (v_texcoord).y);
    coverage = hb_gpu_stem_darken (coverage, brightness, ppem);

Example — paint path: `hb_gpu_paint()` returns a separate edge coverage value that tracks the maximum antialiasing coverage across paint layers. Apply stem darkening and gamma to this edge coverage, then scale the premultiplied color to match. Interior fragments (coverage == 1) are left untouched.

    float cov;
    vec4 c = hb_gpu_paint (v_texcoord, v_glyphLoc, u_foreground, cov);
    if (cov > 0.0 && cov < 1.0) {
      float brightness = c.a > 0.0
        ? dot (c.rgb, vec3 (1.0 / 3.0)) / c.a : 0.0;
      float ppem = 1.0 / max (fwidth (v_texcoord).x,
                               fwidth (v_texcoord).y);
      float adj = hb_gpu_stem_darken (cov, brightness, ppem);
      c *= adj / cov;
    }

### Paint

The paint renderer walks the font's paint tree (COLRv0 layers or COLRv1 paint subtree) and records one layer op per solid or gradient fill, each with its own clip outline encoded as a Slug (so the paint renderer reuses the draw renderer internally for clips). Palette colors and custom overrides are resolved and baked into the blob at encode time, so the shader does not need a separate palette uniform.

Monochrome (non-color) glyphs are handled transparently: `hb_gpu_paint_glyph()` synthesizes a single foreground-colored layer from the glyph's outline, so callers can use the paint renderer uniformly for any font. This costs more per fragment than the Draw path, but the rendered result is the same.

#### Encoding

    hb_gpu_paint_t *paint = hb_gpu_paint_create_or_fail ();

    // Optional: select a palette and install any custom-palette
    // overrides before hb_gpu_paint_glyph — their values are baked
    // into the encoded blob.  (The foreground color is NOT set here:
    // it stays a shader uniform so dark-mode and color-change
    // toggles take effect without re-encoding.)
    hb_gpu_paint_set_palette (paint, 0);
    hb_gpu_paint_set_custom_palette_color (paint, 2,
                                           HB_COLOR (0xff, 0, 0, 0xff));

    hb_gpu_paint_glyph (paint, font, gid);
    hb_glyph_extents_t ext;
    hb_blob_t *blob = hb_gpu_paint_encode (paint, &ext);

    // Upload hb_blob_get_data(blob) to the same atlas used by draw.
    unsigned atlas_offset = upload_to_atlas (blob);

    hb_gpu_paint_recycle_blob (paint, blob);
    // repeat for more glyphs...

    hb_gpu_paint_destroy (paint);

As with the draw encoder, create the paint encoder once and reuse it. `hb_gpu_paint_encode()` auto-clears on return; user configuration (palette, custom-palette overrides) is preserved across encodes. Because colors are baked, changing any of that configuration afterwards requires re-encoding the affected glyphs. The encoded blob's texel format is the same RGBA16I as the draw renderer's, so both kinds of blobs can coexist in one atlas at different offsets.

#### Shader composition

Same pattern as the draw renderer but using `hb_gpu_paint_shader_source()` for the paint-specific helpers. The vertex stage is identical — `hb_gpu_paint_shader_source()` returns an empty string for HB_GPU_SHADER_STAGE_VERTEX, so the fixed assembly order still works:

    const char *frag_sources[] = {
        "#version 330\n",
        hb_gpu_shader_source       (HB_GPU_SHADER_STAGE_FRAGMENT,
                                    HB_GPU_SHADER_LANG_GLSL),
        hb_gpu_paint_shader_source (HB_GPU_SHADER_STAGE_FRAGMENT,
                                    HB_GPU_SHADER_LANG_GLSL),
        your_fragment_main
    };
    glShaderSource (frag_shader, 4, frag_sources, NULL);

The atlas setup, vertex attributes, dilation, and font scaling guidance from the Draw section all apply unchanged.

#### Fragment shader

The paint library provides one function:

    vec4 hb_gpu_paint (vec2 renderCoord, uint glyphLoc, vec4 foreground,
                       out float coverage);

Parameters:

- renderCoord: the interpolated em-space coordinate from the vertex shader (v_texcoord), as for `hb_gpu_draw()`.

- glyphLoc: the texel offset of this glyph's encoded paint blob in the atlas, passed as a flat varying from the vertex shader.

- foreground: the foreground color used to resolve palette entries that COLRv1 marks as "foreground color". The encoder only records the is-foreground flag per layer/stop; the actual color is substituted here at render time, so runtime foreground-color changes (e.g. a dark-mode toggle) take effect without re-encoding any glyphs.

- coverage (out): the maximum antialiasing coverage across all paint layers. Fractional values (between 0 and 1) indicate antialiased edge pixels; 0 means fully outside, 1 means fully inside. Stem darkening and gamma correction should be applied to this value rather than to the returned color, so that interior paint colors are unaffected. See the stem darkening notes in the Draw section.

Returns premultiplied RGBA: fully transparent outside the glyph, composited layers inside. Use (GL_ONE, GL_ONE_MINUS_SRC_ALPHA) blending to composite over a background.

A typical fragment main:

    uniform vec4 u_foreground;
    uniform float u_gamma;
    uniform float u_stem_darkening;
    in vec2 v_texcoord;
    flat in uint v_glyphLoc;
    out vec4 fragColor;

    void main () {
      float cov;
      vec4 c = hb_gpu_paint (v_texcoord, v_glyphLoc, u_foreground, cov);
      if (cov > 0.0 && cov < 1.0) {
        float adj = cov;
        if (u_stem_darkening > 0.0) {
          float brightness = c.a > 0.0
            ? dot (c.rgb, vec3 (1.0 / 3.0)) / c.a : 0.0;
          adj = hb_gpu_stem_darken (adj, brightness,
            1.0 / max (fwidth (v_texcoord).x, fwidth (v_texcoord).y));
        }
        if (u_gamma != 1.0)
          adj = pow (adj, u_gamma);
        c *= adj / cov;
      }
      fragColor = c;
    }

## Functions

### hb_gpu_shader_source ()

    const char *
    hb_gpu_shader_source (hb_gpu_shader_stage_t stage,
                          hb_gpu_shader_lang_t lang);

Returns the shared helper shader source used by the hb-gpu renderers for the specified stage and language. The returned string is static and must not be freed.

The shared source defines utilities such as the atlas sampler and the ``hb_gpu_fetch()`` accessor for the fragment stage, and the ``hb_gpu_dilate()`` helper for the vertex stage. Each renderer-specific source (for example, `hb_gpu_draw_shader_source()`) assumes these helpers are already in scope — callers should concatenate a `#version` directive, then this shared source, then the renderer-specific source, then their own ``main()``.

#### Parameters

stage | pipeline stage (vertex or fragment) |
lang | shader language variant |

#### Returns

A shader source string, or `NULL` if `stage` or `lang` is unsupported.

[transfer none]

Since: 14.2.0

### hb_gpu_draw_shader_source ()

    const char *
    hb_gpu_draw_shader_source (hb_gpu_shader_stage_t stage,
                               hb_gpu_shader_lang_t lang);

Returns the draw-renderer-specific shader source for the specified stage and language. The returned string is static and must not be freed.

This source assumes the shared helpers returned by `hb_gpu_shader_source()` are concatenated ahead of it. The caller should assemble the full shader as `#version`-directive + `hb_gpu_shader_source()` + `hb_gpu_draw_shader_source()` + caller's ``main()``.

The vertex stage currently has no draw-specific helpers; this function returns an empty string for that stage so the caller can concatenate unconditionally.

#### Parameters

stage | pipeline stage (vertex or fragment) |
lang | shader language variant |

#### Returns

A shader source string, or `NULL` if `stage` or `lang` is unsupported.

[transfer none]

Since: 14.2.0

### hb_gpu_draw_create_or_fail ()

    hb_gpu_draw_t *
    hb_gpu_draw_create_or_fail (void);

Creates a new GPU shape encoder.

#### Returns

A newly allocated hb_gpu_draw_t, or `NULL` on allocation failure.

[transfer full]

Since: 14.0.0

### hb_gpu_draw_reference ()

    hb_gpu_draw_t *
    hb_gpu_draw_reference (hb_gpu_draw_t *draw);

Increases the reference count on `draw` by one.

[skip]

#### Parameters

draw | a GPU shape encoder |

#### Returns

The referenced hb_gpu_draw_t.

[transfer full]

Since: 14.0.0

### hb_gpu_draw_destroy ()

    void
    hb_gpu_draw_destroy (hb_gpu_draw_t *draw);

Decreases the reference count on `draw` by one. When the reference count reaches zero, the encoder is freed.

[skip]

#### Parameters

draw | a GPU shape encoder |

Since: 14.0.0

### hb_gpu_draw_set_user_data ()

    hb_bool_t
    hb_gpu_draw_set_user_data (hb_gpu_draw_t *draw,
                               hb_user_data_key_t *key,
                               void *data,
                               hb_destroy_func_t destroy,
                               hb_bool_t replace);

Attaches user data to `draw` .

[skip]

#### Parameters

draw | a GPU shape encoder |
key | the user-data key |
data | a pointer to the user data |
destroy | a callback to call when `data` is not needed anymore. | [nullable]
replace | whether to replace an existing data with the same key |

#### Returns

`true` if success, `false` otherwise

Since: 14.0.0

### hb_gpu_draw_get_user_data ()

    void *
    hb_gpu_draw_get_user_data (const hb_gpu_draw_t *draw,
                               hb_user_data_key_t *key);

Fetches the user-data associated with the specified key.

[skip]

#### Parameters

draw | a GPU shape encoder |
key | the user-data key |

#### Returns

A pointer to the user data.

[transfer none]

Since: 14.0.0

### hb_gpu_draw_get_funcs ()

    hb_draw_funcs_t *
    hb_gpu_draw_get_funcs (const hb_gpu_draw_t *draw);

Fetches the hb_draw_funcs_t that feeds outline data into `draw` . Pass `draw` as the `draw_data` argument when calling the draw functions.

#### Parameters

draw | a GPU draw context. |

#### Returns

The GPU draw functions.

[transfer none]

Since: 14.2.0

### hb_gpu_draw_set_scale ()

    void
    hb_gpu_draw_set_scale (hb_gpu_draw_t *draw,
                           int x_scale,
                           int y_scale);

Sets the font scale so the encoded blob can embed it for shader use (e.g. computing pixels-per-em). Called automatically by `hb_gpu_draw_glyph()`.

#### Parameters

draw | a GPU shape encoder |
x_scale | horizontal scale (typically from `hb_font_get_scale()`) |
y_scale | vertical scale |

Since: 14.1.0

### hb_gpu_draw_get_scale ()

    void
    hb_gpu_draw_get_scale (const hb_gpu_draw_t *draw,
                           int *x_scale,
                           int *y_scale);

Gets the font scale previously set via `hb_gpu_draw_set_scale()` or `hb_gpu_draw_glyph()`.

#### Parameters

draw | a GPU shape encoder |
x_scale | horizontal scale. | [out]
y_scale | vertical scale. | [out]

Since: 14.2.0

### hb_gpu_draw_glyph ()

    void
    hb_gpu_draw_glyph (hb_gpu_draw_t *draw,
                       hb_font_t *font,
                       hb_codepoint_t glyph);

Draws a single glyph outline into the encoder. Equivalent to `hb_gpu_draw_glyph_or_fail()` with the return value ignored.

#### Parameters

draw | a GPU shape encoder |
font | font to draw from |
glyph | glyph ID to draw |

Since: 14.0.0

### hb_gpu_draw_glyph_or_fail ()

    hb_bool_t
    hb_gpu_draw_glyph_or_fail (hb_gpu_draw_t *draw,
                               hb_font_t *font,
                               hb_codepoint_t glyph);

Convenience to draw one glyph outline. Equivalent to:

    hb_gpu_draw_set_scale (draw, x_scale, y_scale);
    hb_font_draw_glyph_or_fail (font, glyph,
      hb_gpu_draw_get_funcs (draw), draw);

#### Parameters

draw | a GPU shape encoder |
font | font to draw from |
glyph | glyph ID to draw |

#### Returns

`true` if the glyph was drawn, `false` if the font has no outlines for `glyph` .

Since: 14.2.0

### hb_gpu_draw_encode ()

    hb_blob_t *
    hb_gpu_draw_encode (hb_gpu_draw_t *draw,
                        hb_glyph_extents_t *extents);

Encodes the accumulated outlines into a compact blob suitable for GPU rendering. The blob data is an array of RGBA16I texels (8 bytes each) to be uploaded to a texture buffer object.

The returned blob owns its own copy of the data. On success `draw` is auto-cleared so it can be reused for the next glyph; user configuration (font scale) is preserved.

#### Parameters

draw | a GPU shape encoder |
extents | where to store the computed glyph extents (in font units, Y-up). Pass `NULL` if not needed. | [out][nullable]

#### Returns

An hb_blob_t containing the encoded data, or `NULL` if encoding failed (allocation failure or accumulation error). When the encoder accumulated no outline (e.g. the glyph has no ink, like a space), returns the empty-blob singleton instead of `NULL`, so callers can distinguish "nothing to render" (length 0) from a real failure (`NULL`).

[transfer full]

Since: 14.0.0

### hb_gpu_draw_clear ()

    void
    hb_gpu_draw_clear (hb_gpu_draw_t *draw);

Discards accumulated outlines so `draw` can be reused for another encode. User configuration (font scale) is preserved. Call `hb_gpu_draw_reset()` to also reset user configuration to defaults.

#### Parameters

draw | a GPU shape encoder |

Since: 14.2.0

### hb_gpu_draw_reset ()

    void
    hb_gpu_draw_reset (hb_gpu_draw_t *draw);

Resets the encoder, discarding all accumulated outlines and resetting user configuration to defaults.

#### Parameters

draw | a GPU shape encoder |

Since: 14.0.0

### hb_gpu_draw_recycle_blob ()

    void
    hb_gpu_draw_recycle_blob (hb_gpu_draw_t *draw,
                              hb_blob_t *blob);

Returns a blob to the encoder for potential reuse. The caller transfers ownership of `blob` .

Currently this simply destroys the blob. A future version may reclaim the underlying buffer to avoid allocation on the next `hb_gpu_draw_encode()` call.

#### Parameters

draw | a GPU shape encoder |
blob | a blob previously returned by `hb_gpu_draw_encode()`. | [transfer full]

Since: 14.0.0

### hb_gpu_paint_create_or_fail ()

    hb_gpu_paint_t *
    hb_gpu_paint_create_or_fail (void);

Creates a new GPU color-glyph paint encoder.

#### Returns

A newly allocated hb_gpu_paint_t, or `NULL` on allocation failure.

[transfer full]

Since: 14.2.0

### hb_gpu_paint_reference ()

    hb_gpu_paint_t *
    hb_gpu_paint_reference (hb_gpu_paint_t *paint);

Increases the reference count on `paint` by one.

[skip]

#### Parameters

paint | a GPU color-glyph paint encoder |

#### Returns

The referenced hb_gpu_paint_t.

[transfer full]

Since: 14.2.0

### hb_gpu_paint_destroy ()

    void
    hb_gpu_paint_destroy (hb_gpu_paint_t *paint);

Decreases the reference count on `paint` by one. When the reference count reaches zero, the encoder is freed.

[skip]

#### Parameters

paint | a GPU color-glyph paint encoder |

Since: 14.2.0

### hb_gpu_paint_set_user_data ()

    hb_bool_t
    hb_gpu_paint_set_user_data (hb_gpu_paint_t *paint,
                                hb_user_data_key_t *key,
                                void *data,
                                hb_destroy_func_t destroy,
                                hb_bool_t replace);

Attaches user data to `paint` .

[skip]

#### Parameters

paint | a GPU color-glyph paint encoder |
key | the user-data key |
data | a pointer to the user data |
destroy | a callback to call when `data` is not needed anymore. | [nullable]
replace | whether to replace an existing data with the same key |

#### Returns

`true` if success, `false` otherwise

Since: 14.2.0

### hb_gpu_paint_get_user_data ()

    void *
    hb_gpu_paint_get_user_data (const hb_gpu_paint_t *paint,
                                hb_user_data_key_t *key);

Fetches the user data associated with the specified key.

[skip]

#### Parameters

paint | a GPU color-glyph paint encoder |
key | the user-data key |

#### Returns

A pointer to the user data.

[transfer none]

Since: 14.2.0

### hb_gpu_paint_get_funcs ()

    hb_paint_funcs_t *
    hb_gpu_paint_get_funcs (const hb_gpu_paint_t *paint);

Fetches the hb_paint_funcs_t that feeds paint data into `paint` . Pass `paint` as the `paint_data` argument when calling the paint functions.

#### Parameters

paint | a GPU paint context. |

#### Returns

The GPU paint functions.

[transfer none]

Since: 14.2.0

### hb_gpu_paint_set_palette ()

    void
    hb_gpu_paint_set_palette (hb_gpu_paint_t *paint,
                              unsigned  palette);

Selects which font palette is used when paint callbacks look up indexed colors. Default is palette 0.

#### Parameters

paint | a GPU color-glyph paint encoder |
palette | palette index |

Since: 14.2.0

### hb_gpu_paint_get_palette ()

    unsigned
    hb_gpu_paint_get_palette (const hb_gpu_paint_t *paint);

Returns the palette index previously set on `paint` , or 0 if none was set.

#### Parameters

paint | a GPU color-glyph paint encoder |

#### Returns

the palette index.

Since: 14.2.0

### hb_gpu_paint_clear_custom_palette_colors ()

    void
    hb_gpu_paint_clear_custom_palette_colors
                                   (hb_gpu_paint_t *paint);

Clears all custom palette color overrides previously set on `paint` .

#### Parameters

paint | a GPU color-glyph paint encoder |

Since: 14.2.0

### hb_gpu_paint_set_custom_palette_color ()

    hb_bool_t
    hb_gpu_paint_set_custom_palette_color (hb_gpu_paint_t *paint,
                                           unsigned int color_index,
                                           hb_color_t color);

Overrides one font palette color entry. Overrides are keyed by `color_index` and persist on `paint` until cleared (or replaced for the same index).

#### Parameters

paint | a GPU color-glyph paint encoder |
color_index | palette index to override |
color | replacement color |

#### Returns

`true` if the override was set; `false` on allocation failure.

Since: 14.2.0

### hb_gpu_paint_set_scale ()

    void
    hb_gpu_paint_set_scale (hb_gpu_paint_t *paint,
                            int x_scale,
                            int y_scale);

Sets the font scale used to dimension clip-glyph slug outlines inside the encoded blob. Called automatically by `hb_gpu_paint_glyph()`.

#### Parameters

paint | a GPU color-glyph paint encoder |
x_scale | horizontal scale (typically from `hb_font_get_scale()`) |
y_scale | vertical scale |

Since: 14.2.0

### hb_gpu_paint_get_scale ()

    void
    hb_gpu_paint_get_scale (const hb_gpu_paint_t *paint,
                            int *x_scale,
                            int *y_scale);

Fetches the font scale previously set on `paint` .

#### Parameters

paint | a GPU color-glyph paint encoder |
x_scale | horizontal scale. | [out]
y_scale | vertical scale. | [out]

Since: 14.2.0

### hb_gpu_paint_glyph ()

    void
    hb_gpu_paint_glyph (hb_gpu_paint_t *paint,
                        hb_font_t *font,
                        hb_codepoint_t glyph);

Feeds `glyph` into the encoder. Unlike `hb_gpu_paint_glyph_or_fail()`, non-color glyphs are handled transparently via a synthesized foreground-colored layer, so any glyph with an outline produces output.

#### Parameters

paint | a GPU color-glyph paint encoder |
font | font to paint from |
glyph | glyph ID to paint |

Since: 14.2.0

### hb_gpu_paint_glyph_or_fail ()

    hb_bool_t
    hb_gpu_paint_glyph_or_fail (hb_gpu_paint_t *paint,
                                hb_font_t *font,
                                hb_codepoint_t glyph);

Convenience to feed `glyph` 's paint tree into the encoder. Equivalent to:

    hb_gpu_paint_set_scale (paint, x_scale, y_scale);
    hb_font_paint_glyph_or_fail (font, glyph,
      hb_gpu_paint_get_funcs (paint), paint,
      palette, HB_COLOR (0, 0, 0, 0xff));

Encoder-level limitations (unsupported paint ops, group-stack overflow) do NOT fail here -- they surface later from `hb_gpu_paint_encode()` which returns `NULL`.

#### Parameters

paint | a GPU color-glyph paint encoder |
font | font to paint from |
glyph | glyph ID to paint |

#### Returns

`true` if the font had paint data for `glyph` , `false` otherwise.

Since: 14.2.0

### hb_gpu_paint_encode ()

    hb_blob_t *
    hb_gpu_paint_encode (hb_gpu_paint_t *paint,
                         hb_glyph_extents_t *extents);

Encodes the accumulated paint state into a GPU-renderable blob and writes the glyph's ink extents to `extents` .

On return `paint` is auto-cleared so it can be reused for the next glyph; user configuration (palette, foreground, custom palette overrides) is preserved.

#### Parameters

paint | a GPU color-glyph paint encoder |
extents | receives the glyph's ink extents in font units. | [out]

#### Returns

A newly allocated blob, or `NULL` if the paint walk hit an unsupported feature (see `hb_gpu_paint_glyph()`'s return value) or encoding failed (allocation failure). When the paint accumulated no ink (e.g. a space glyph) returns the empty-blob singleton, so callers can distinguish "nothing to render" (length 0) from a real failure (`NULL`).

[transfer full]

Since: 14.2.0

### hb_gpu_paint_clear ()

    void
    hb_gpu_paint_clear (hb_gpu_paint_t *paint);

Discards accumulated paint state so `paint` can be reused for another encode. User configuration (font scale) is preserved.

#### Parameters

paint | a GPU color-glyph paint encoder |

Since: 14.2.0

### hb_gpu_paint_reset ()

    void
    hb_gpu_paint_reset (hb_gpu_paint_t *paint);

Resets `paint` , discarding accumulated state and user configuration.

#### Parameters

paint | a GPU color-glyph paint encoder |

Since: 14.2.0

### hb_gpu_paint_recycle_blob ()

    void
    hb_gpu_paint_recycle_blob (hb_gpu_paint_t *paint,
                               hb_blob_t *blob);

Returns a blob to the encoder for potential reuse. The caller transfers ownership of `blob` .

If `blob` came from `hb_gpu_paint_encode()` its underlying buffer will be reused by the next call to `hb_gpu_paint_encode()`, avoiding a malloc / blob allocation per glyph.

#### Parameters

paint | a GPU color-glyph paint encoder |
blob | a blob previously returned by `hb_gpu_paint_encode()`. | [transfer full]

Since: 14.2.0

### hb_gpu_paint_shader_source ()

    const char *
    hb_gpu_paint_shader_source (hb_gpu_shader_stage_t stage,
                                hb_gpu_shader_lang_t lang);

Returns the paint-renderer-specific shader source for the specified stage and language. The returned string is static and must not be freed.

This source assumes both the shared helpers (`hb_gpu_shader_source()`) and the draw-renderer helpers (`hb_gpu_draw_shader_source()`) are concatenated ahead of it -- the paint interpreter invokes `hb_gpu_draw()` to compute clip-glyph coverage. Full assembly:

[version] + `hb_gpu_shader_source()`

- hb_gpu_draw_shader_source ()

  - hb_gpu_paint_shader_source ()

    - caller's `main()`

#### Parameters

stage | pipeline stage (vertex or fragment) |
lang | shader language variant |

#### Returns

A shader source string, or `NULL` if `stage` or `lang` is unsupported.

[transfer none]

Since: 14.2.0

## Types and Values

### enum hb_gpu_shader_lang_t

Shader language variant.

#### Members

HB_GPU_SHADER_LANG_INVALID | Sentinel for an invalid or unspecified language. |
HB_GPU_SHADER_LANG_GLSL | GLSL (OpenGL 3.3 / OpenGL ES 3.0 / WebGL 2.0) |
HB_GPU_SHADER_LANG_WGSL | WGSL (WebGPU) |
HB_GPU_SHADER_LANG_MSL | MSL (Metal) |
HB_GPU_SHADER_LANG_HLSL | HLSL (Direct3D) |

Since: 14.0.0

### enum hb_gpu_shader_stage_t

Shader pipeline stage.

#### Members

HB_GPU_SHADER_STAGE_VERTEX | Vertex shader stage. |
HB_GPU_SHADER_STAGE_FRAGMENT | Fragment shader stage. |

Since: 14.2.0

### hb_gpu_draw_t

    typedef struct hb_gpu_draw_t hb_gpu_draw_t;

An opaque GPU shape encoder. Accumulates outlines via draw callbacks, then encodes them into a compact blob for GPU rendering.

Since: 14.0.0

### hb_gpu_paint_t

    typedef struct hb_gpu_paint_t hb_gpu_paint_t;

An opaque GPU color-glyph encoder. Accumulates color-glyph paint state via paint callbacks, then encodes it into a compact blob for GPU rendering.

Since: 14.2.0