Skip to content

sugarloaf: preserve matched CoreText font faces - #1963

Open
aymanbagabas wants to merge 2 commits into
raphamorim:mainfrom
aymanbagabas:fix/macos-font-style-selection
Open

aymanbagabas wants to merge 2 commits into
raphamorim:mainfrom
aymanbagabas:fix/macos-font-style-selection

Conversation

@aymanbagabas

@aymanbagabas aymanbagabas commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Fix identical regular and bold text on macOS with named variable-font styles.

CoreText selects the requested face, but Rio keeps only its file path. The loader then reopens the file and selects its first descriptor. With JetBrains Mono, both Medium and Bold resolve to the same variable-font file and reopen as Thin.

Retain the matched CoreText handle through font loading instead. This preserves the selected style, variable axes, and collection face. Explicit weight overrides still apply. The existing path-based loader remains available for fallback fonts.

Before:

Image

After:

Image

Reproduction

With the variable version of JetBrains Mono installed, configure:

[fonts.regular]
family = "JetBrains Mono"
style = "Medium"

[fonts.bold]
family = "JetBrains Mono"
style = "Bold"

Run:

printf '\033[0mNormal: Hello\n\033[1mBold:   Hello\033[0m\n'

Before this fix, both styles use Thin and produce identical glyph pixels. After this fix, they use the requested Medium and Bold faces.

Testing

  • Added a regression test with bundled Cascadia Code variable fonts. It fails before the fix and passes afterward.
  • Covered regular, bold, italic, bold italic, distinct glyph masks, and an explicit weight override.
  • cargo test -q -p sugarloaf --lib font::: 80 tests passed on macOS.
  • cargo build -q -p rioterm: passed.
  • Confirmed distinct Medium and Bold glyph pixels through the patched Rio font library with installed JetBrains Mono fonts.
  • git diff --check: passed.

CoreText selects the requested named face, but reopening its file loads
the first descriptor. Variable fonts can therefore render regular and
bold text with the same thin face.

Retain the matched CoreText handle through font loading. Keep explicit
weight overrides and the existing path-based loader for fallback fonts.

Add a regression test with bundled Cascadia Code variable fonts. Cover
regular, bold, italic, bold italic, distinct glyph masks, and an explicit
weight override.

Signed-off-by: Ayman Bagabas <ayman.bagabas@gmail.com>
Copilot AI balanced review requested due to automatic review settings October 3, 2026 00:47

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Coverage checks and advance measurements still reopen the first face instead of using the retained rendering face.

Review effort: Balanced
Findings: 1 High severity

Open (1)
What changed in this PR

Preserves matched CoreText font faces on macOS so named variable-font styles survive loading.

Changes:

  • Loads matched font handles directly while retaining path-based fallback loading.
  • Adds regression coverage for named styles, distinct glyph masks, and explicit weight overrides.
File Description
sugarloaf/​src/​font/​mod.rs Retains matched handles and adds variable-font regression coverage.
sugarloaf/​src/​font/​macos.rs Returns the matched handle alongside its path.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread sugarloaf/src/font/mod.rs
}
}
info!("Font '{family}' matched via CoreText at {}", path.display());
FindResult::Found(FontData::from_handle_macos(handle, path, slot, &font_spec))
Prefer the retained CoreText handle for glyph coverage, advance
measurement, and primary-font cascade selection. Keep path and byte
fallbacks when no handle is stored.

Add a collection-face regression test that checks coverage and advances
against the selected face rather than descriptor zero.

Signed-off-by: Ayman Bagabas <ayman.bagabas@gmail.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants