Skip to content

LT-22854: Control the Avalonia interface font from the theme - #1196

Open
johnml1135 wants to merge 4 commits into
mainfrom
LT-22854-andika-ui-font
Open

johnml1135 wants to merge 4 commits into
mainfrom
LT-22854-andika-ui-font

Conversation

@johnml1135

@johnml1135 johnml1135 commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Start here: Src/Common/FwAvalonia/FwUiFont.cs, then the token FwUiFontFamily in Src/Common/FwAvaloniaTheme/Tokens/FwColorTokens.axaml. The decision is in Docs/architecture/adr/0004-interface-font-controlled-by-the-theme.md. Jira: https://jira.sil.org/browse/LT-22854

Ready for review. Nothing is red; one xWorksTests clipboard test failed once and passes alone (see Tests).

FieldWorks now controls the font of its Avalonia interface. One theme token, FwUiFontFamily, names it, and Semi's font resources point at that token, so all text inherits it from the root. The font is bundled in FwAvaloniaTheme, so it is the same on every machine and nothing needs installing. Five UI languages (fa, hi, ko, te, zh-CN) get fallback lists: a Windows system font first, then the SIL or Noto family. To change the font later, change the token and replace the bundled files. No code changes.

Proposed default: Andika 7.000 (OFL, five faces, about 4.1 MB). The cost is height: lines are about 21% taller (1.61 em against 1.33 em), so rows and dialogs grow by a few pixels. Font sizes (11 px, 13 px) and x-height (0.508 em against 0.500 em) are unchanged. The default is the proposal; the mechanism is the point. Alternatives are in the first accordion.

Headless captures from the dialog tests, not the running product:

DialogBefore (platform default)After (Andika)
Options
Add New Sense

All 9 before/after pairs are attached to LT-22854.

Where to look

  • Writing-system fonts must not change. A plain "Andika" family still resolves to the installed font; a test pins it.
  • Fallbacks: FwUiFontTests checks each fallback language's sample string.
  • Layout growth: AssertNoCrowding still passes for every dialog.
  • DisposeDialogResources_* tests moved to [AvaloniaTest] (accordion).

Not in this PR: the installer still ships Andika 6.101 (LT-19288); decision-register rows for #1191 (#1191).

Next: approve the token mechanism, and say whether Andika is the default you want or one of the alternatives.


Reading this a year from now -- start here

This branch had no research or working notes in the tree. The reasoning below is the record: why the font is controlled by the theme, what the default is and what else was considered. The durable decision is also in ADR 0004.

Alternatives to Andika, and why each was not the default

Andika 7.000 is the only SIL Latin sans with full Latin, Cyrillic, Greek and IPA and all the weights FieldWorks uses. It is the proposal, not a settled choice: the token can name any of these instead.

  • Platform UI font (Segoe UI). Closest to today's look. Its licence does not allow bundling, so other platforms and test machines would differ. The token can still name it.
  • Sophia Nubian 1.0. Vertical metrics closest to Segoe UI. No Cyrillic, no SemiBold, little Greek or IPA. Last release 2009.
  • Padauk 6.000. Has SemiBold, but its x-height is 0.435, so it needs a size about 15% larger. No Cyrillic, IPA or Italic.

Cost of the default: line height 1.61 em against 1.33 em (about 21% taller, about 3 px at 11 px).

Reviewer notes: two test changes

The two DisposeDialogResources_* tests moved to [AvaloniaTest]. The problem was already there. They built new Control() on the NUnit thread, outside the headless dispatcher, so they depended on which thread owned the dispatcher. Setting the font resources changed that timing and exposed it. With [Test], 1 in 3 full runs failed with "Call from invalid thread". Running them on the headless thread fixes it.

In xWorksTests, FwDragDropDataTests.TextDrag_FromAvaloniaPayload_LegacyClipboardBridgeReadsBothRichAndNeutralLanes failed once in a full filter run and passed when the class ran alone. It reads the system clipboard and does not touch fonts.

Evidence: tests and checks
  • FwAvaloniaTests: 949 passed, 1 skipped.
  • FwAvaloniaDialogsTests: 289 of 289 passed.
  • xWorksTests, Avalonia filter (FullyQualifiedName~Avalonia): 1814 passed, 2 skipped, 1 failed (the clipboard test above; 4 of 4 pass in its class alone).
  • build.ps1 -CommentHygiene -TokenHygiene is clean, and the PowerShell 5.1 and 7.0 compatibility check is clean. Re-run on this head: comment-hygiene.ps1 and token-hygiene.ps1 clean; git diff --check origin/main..HEAD clean.
  • Nine dialog baselines in Docs/migration/baseline-screenshots/ are refreshed for the new font.

🤖 Generated with Claude Code


This change is Reviewable

@github-actions

github-actions Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

NUnit Tests

    1 files  ± 0      1 suites  ±0   14m 30s ⏱️ + 5m 56s
6 834 tests +18  6 749 ✅ +18  85 💤 ±0  0 ❌ ±0 
6 843 runs  +18  6 758 ✅ +18  85 💤 ±0  0 ❌ ±0 

Results for commit 0921803. ± Comparison against base commit d0d85cb.

♻️ This comment has been updated with latest results.

@codecov-commenter

codecov-commenter commented Oct 20, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.67442% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 39.89%. Comparing base (d0d85cb) to head (0921803).

Files with missing lines Patch % Lines
Src/Common/FwAvalonia/FwUiFont.cs 97.43% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main    #1196   +/-   ##
=======================================
  Coverage   39.88%   39.89%           
=======================================
  Files        1542     1543    +1     
  Lines      355361   355403   +42     
  Branches    41320    41324    +4     
=======================================
+ Hits       141753   141784   +31     
- Misses     184253   184262    +9     
- Partials    29355    29357    +2     
Files with missing lines Coverage Δ
Src/Common/FwAvalonia/Detail/FwFieldControls.cs 87.56% <100.00%> (ø)
Src/Common/FwAvalonia/FwAvaloniaApp.cs 82.35% <100.00%> (+1.10%) ⬆️
Src/Common/FwAvalonia/FwThemeResources.cs 69.23% <100.00%> (+2.56%) ⬆️
.../Common/FwAvaloniaTheme/Tokens/FwColorTokens.axaml 100.00% <100.00%> (ø)
Src/Common/FwAvalonia/FwUiFont.cs 97.43% <97.43%> (ø)

... and 2 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

johnml1135 and others added 4 commits October 23, 2026 07:05
The five faces in use (Regular, Italic, Bold, BoldItalic, SemiBold)
ship unmodified inside FwAvaloniaTheme.dll with the OFL text and a
notice recording the SHA-256 of each file. Nothing registers or uses
them yet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The interface font is no longer left to the platform default. The
FwUiFontFamily token names it, FwUiFont registers the bundled font
collection and points Semi's DefaultFontFamily,
ContentControlThemeFontFamily and SemiFontFamilyRegular at a stack of
that font followed by the fallbacks the UI language needs. The default
is Andika; fa, hi, ko, te and zh-CN get a Windows system font first
and the SIL or Noto family second. The other UI languages are covered
by the default itself.

Data text keeps its writing-system font, and the writing-system
abbreviation column is measured in the interface font. The token
generator learns FontFamily entries. Tests cover each fallback
language's sample string. Two tests that built Avalonia controls on
the NUnit thread become AvaloniaTest, since the headless session owns
the dispatcher.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ADR 0004 records that the theme controls the interface font, Andika as
the proposed default and the alternatives, the Semi resource keys, the
five faces, the unchanged sizes and the per-language fallback fonts.
Two passages that still described the Fluent theme and its font now
name the Semi theme and the FieldWorks interface font.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The nine committed dialog snapshots are regenerated with the interface
in Andika. Lines are about 3 px taller at 11 px, so rows and dialogs
grow a little; AssertNoCrowding still passes for every dialog.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@johnml1135
johnml1135 force-pushed the LT-22854-andika-ui-font branch from f5874ae to 0921803 Compare October 23, 2026 11:29
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