summaryrefslogtreecommitdiff
path: root/src/gui/font.h
blob: b38f822a27db79b9ea08e39282ec3c847fa6ee49 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
// Tiny C shim over FreeType and HarfBuzz, so gui.zig only imports the stable
// renderer API. The implementation owns FreeType's library and face objects
// and HarfBuzz's font and buffer, and keeps the caller's font bytes borrowed
// for the face lifetime.
#ifndef UI_FONT_H
#define UI_FONT_H
#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

typedef struct UIFont UIFont;

// Parse the first face in an in-memory font. `data` must stay alive for the
// lifetime of the font. Returns NULL on failure.
UIFont *ui_font_new(const uint8_t *data, int32_t len);

// The face FreeType actually accepted. Prefer its PostScript name (the same
// identity the macOS shell reports); fall back to the family name when the
// font has no PostScript table. Borrowed for the UIFont lifetime.
const char *ui_font_name(UIFont *f);

// The glyph the selected Unicode charmap maps `cp` to. Glyph zero is the
// face's .notdef box: the codepoint is missing, which is what fallback choice
// asks.
uint32_t ui_font_glyph(UIFont *f, int32_t cp);

// `px` is the pixel height. Metrics and rasterization both configure FreeType
// at that size, so hinted advances, baseline and bitmaps stay in step.
void ui_font_cell_metrics(UIFont *f, float px, int32_t *cell_w, int32_t *cell_h,
                          int32_t *ascent);

// What one grid cell draws: `slice` of the glyph `glyph` rasterized across
// `span` cells with its own cell `lead` cells from the left. A plain cell is
// its own glyph, lead 0, span 1, slice 0.
typedef struct {
  uint32_t glyph;
  uint8_t lead;
  uint8_t span;
  uint8_t slice;
} UIShapedCell;

// The longest glyph strip a ligature may claim, in cells.
#define UI_MAX_SPAN 8

// Whether a lookup of the font's ligature features (liga, calt, clig, rlig,
// rclt) could replace `glyph`. When it cannot, shaping leaves the glyph alone
// and its cell needs no shaping at all.
int ui_font_substitutes(UIFont *f, uint32_t glyph);

// One cell per codepoint of `cps`, all in this face, shaped by HarfBuzz with
// the font's ligature features (a run with no glyph ui_font_substitutes
// reports comes back nominal without it). A substituted glyph whose ink
// reaches over neighbouring cells that draw nothing of their own (a
// ligature's spacers, or the cells a merged cluster swallowed) claims them as
// a strip. Otherwise, and for anything the grid cannot place (several glyphs
// in one cell, positioned marks), each cell is its nominal glyph.
void ui_font_shape(UIFont *f, float px, int32_t cell_w, const uint32_t *cps,
                   int32_t n, UIShapedCell *out);

// Rasterize `glyph` into `out` as a hinted grayscale mask of `width` x
// `height` (`stride` bytes per row). The glyph's advance is centered in the
// `cell_w` pixels that start at `cell_x`, and its baseline is `ascent` pixels
// from the top; ink outside the mask is clipped. `bold` emboldens the outline
// before rendering (synthetic bold, same advance). Returns 1 when the glyph
// produced coverage, 0 for blank/error.
int ui_font_raster(UIFont *f, float px, uint32_t glyph, int bold, uint8_t *out,
                   int32_t stride, int32_t width, int32_t height,
                   int32_t cell_x, int32_t cell_w, int32_t ascent);

// Center bitmap ink bounds, independent of advance and baseline bearings.
int ui_font_raster_centered(UIFont *f, float px, uint32_t glyph, int bold,
                            uint8_t *out, int32_t stride, int32_t width,
                            int32_t height);

void ui_font_free(UIFont *f);

#ifdef __cplusplus
}
#endif
#endif