gui_toolkit

Slug's small text

Slug draws a glyph's exact outline with a one-pixel box filter: sharp at any scale or transform, but small text has no grid fitting and only grayscale antialiasing, so next to DirectWrite's hinted bitmaps it can look softer. Three settings of font.Settings address it; each is off by default (0) and they combine.

SettingWhat it doesCost
slug_hint_ppemScreen-aligned glyphs at most this many pixels per em use an outline hinted for their size: the native backend's light auto-hinter (skrifa), vertical only, so the baseline, the x-height and horizontal stems land on whole pixels while shapes and advances stay as designed.One glyph per size (quarter pixels) instead of one per face; a hinting instance per face and size in the Rust library. Needs -define:FONT_BACKEND=native (DirectWrite's backend has no hinter: nothing happens).
slug_darkenStem darkening: every edge moves outwards by this many pixels at 12 px per em and less, fading out linearly by 36. The side is the glyph's winding (Slug_Glyph.orient: TrueType clockwise, CFF counter-clockwise).Nothing measurable: two additions per root in the shader.
slug_supersample_ppemGlyphs at most this many pixels per em take four coverage samples on a rotated grid, each over its own half-pixel box, instead of one estimated from two rays.Four times the fragment work of those glyphs.

The darkening and the samples travel in colors[1] of the glyph's instance (x: signed pixels, y: 1 for four samples); the shader takes fwidth once at the top of ps_slug and passes it to each SlugRender call.

Comparing

odin run tools/slugsmall -define:FONT_BACKEND=native -- -out build/slugsmall [-dpr 1.5] [-darken 0.15] [-hint 24] [-ss 20] renders an opencode-like dark interface and a light page (Segoe UI and Cascadia Mono, 11 to 16 px) with DirectWrite's bitmaps and with Slug in six combinations, stacked in one PNG per scene and scale, plus a 3x enlargement of the first lines. Build the Rust library first (tools/tk build_text).

Mean difference per pixel from DirectWrite (/255, green channel), with the defaults above:

Slug+ darkening+ hinting+ both+ 4 samplesall
dark interface, 100 %2.154.243.695.262.265.38
dark interface, 150 %1.992.373.323.582.053.64
light page, 100 %2.605.204.036.132.615.95
light page, 150 %2.552.933.914.132.654.17

Closer to DirectWrite is not the same as sharper: the auto-hinter does not place lines where Segoe UI's own instructions put them for DirectWrite, and darkening thickens on purpose. Judge by eye.

Edit this page on GitHub