Add font ligature rendering support

Add tweak.ligatures option (default: no) for OpenType liga/calt
rendering with programming fonts. Ligatures are render-only —
the grid and copy/paste are unchanged.

Uses fcft_rasterize_shaped_run() to shape full runs with
HarfBuzz and render each glyph by its shaped glyph ID,
correctly handling contextual alternates and ligatures.

Block cursor over a ligature uses a pixman gradient as composite
source for single-pass correct-color rendering.
This commit is contained in:
barsmonster 2026-02-13 11:30:56 +00:00
parent c291194a4e
commit ade745f303
4 changed files with 599 additions and 19 deletions

View file

@ -2832,6 +2832,18 @@ parse_section_tweak(struct context *ctx)
return true;
}
else if (streq(key, "ligatures")) {
if (!value_to_bool(ctx, &conf->tweak.ligatures))
return false;
if (conf->tweak.ligatures && !conf->can_shape_grapheme) {
LOG_WARN(
"fcft lacks grapheme shaping support; "
"ligatures disabled");
conf->tweak.ligatures = false;
}
return true;
}
else if (streq(key, "grapheme-width-method")) {
_Static_assert(sizeof(conf->tweak.grapheme_width_method) == sizeof(int),
"enum is not 32-bit");
@ -3578,6 +3590,7 @@ config_load(struct config *conf, const char *conf_path,
#if defined(FOOT_GRAPHEME_CLUSTERING) && FOOT_GRAPHEME_CLUSTERING
.grapheme_shaping = fcft_caps & FCFT_CAPABILITY_GRAPHEME_SHAPING,
#endif
.ligatures = false,
.grapheme_width_method = GRAPHEME_WIDTH_DOUBLE,
.delayed_render_lower_ns = 500000, /* 0.5ms */
.delayed_render_upper_ns = 16666666 / 2, /* half a frame period (60Hz) */