Linux: skip menu fonts that have no Latin letters #1405
No reviewers
Labels
No labels
accessibility
autorelease: pending
autorelease: tagged
bug
dependencies
documentation
duplicate
enhancement
github_actions
good first issue
help wanted
invalid
question
testing wanted
wontfix
No milestone
No assignees
1 participant
Due date
No due date set.
Dependencies
No dependencies set
Reference
MagicBeanDev/Hookshot!1405
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/menu-font-latin"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What
On the native Linux build the Insert menu draws its text with stb_truetype from the first font that loads: one beside
the game (
fonts/regular.ttf,fonts/bold.ttf), then fontconfig'ssans-serif, then a few usual paths(
host/posix/gdi_posix.c). Nothing checked that the font has Latin letters. A font without them draws every letteras its empty box (.notdef, glyph 0): rows of hollow squares, while the same folder under Wine reads fine (#1279).
Ais now passed over for the next candidate.sans-serif:lang=en(andsans-serif:bold:lang=en): its choice among the fonts thathave the menu's letters.
I could not tell which font the reporter's system returns; with fonts on my machine, stb_truetype draws exactly that
box for every font without Latin letters.
Tests
tests/test_menu_font_latin.py(new, Linux only, skipped on Windows): builds two tiny TrueType fonts, one withAand one with only a Hebrew letter. The second goes beside the game, and a stand-infc-matchon PATH answerswith the first.
gdi_posix.cis compiled with a fixture that draws "A" in both weights: both must draw pixels,and
fc-matchmust be asked withlang=en. No system font is used. It fails on the current code and witheither half of the change taken out.
main(my environment); nothing new fails.Refs #1279
AI assistance
Assisted-by: Claude Opus 5.5
Assisted-by: Nemotron 3 Ultra 550B (LLM council)
Assisted-by: gpt-oss-120b (LLM council)
Assisted-by: dots-3-note-preview (LLM council)
Assisted-by: Gemini 3.5 Flash-Lite (LLM council)
Co-Authored-By: Claude Opus 5.5 [email protected]
The LLM council (several models answer the same question independently, then
rank each other's answers anonymously) was used to define the approach and the
solution: which problem to take on, how to fix it and what to avoid. It saw a
summary of the issues, not the code. The change and its test were written with
Claude Code, then reviewed and tested by me.
This landed in the v2.0.12 branch (merged there for testing; it reaches
mainwith that release), so closing. Thanks!Reopened: closing this was a mistake on my side. It was tested in the v2.0.12 branch, and it will be merged into main here, so it shows as merged. Sorry for the noise.
Looks good. The
stbtt_FindGlyphIndex(..., 'A')check inface_loadis cheap and does what the description says. On failure the buffer is freed andokstays 0, so the next candidate (fontconfig, then the fixed paths) is tried cleanly. The test is self-contained: it builds two tiny fonts, and I checked thathost/posix/windows.hdeclaresGetModuleFileNameAand thatthird_party/stbis on the include path. It is registered inrun_all.pyand skipped on Windows.Overlap with the sibling PRs (no semantic conflict, but expect textual ones):
face_loadgets anindexparameter andfc_matchbecomesface_match(face, pattern). Theface_loadandfaces_loadhunks here will conflict. After rebasing, the'A'check goes afterstbtt_InitFontwith the indexed offset, and the patterns becomeface_match(&faces[0], "sans-serif:lang=en")and"sans-serif:bold:lang=en". They combine fine: that PR picks the face inside a collection, this one rejects a face with no Latin. Whichever lands second has to rework its hunks, and therun_all.pyhunks are adjacent in both.gdi_posix.c(andvk_menu.cpp), so no conflict in code. Onlyrun_all.pyis adjacent. They are independent in behaviour. Once #1389 draws non-Latin names, a Latin-only font still shows boxes for those names. That is outside this PR.Nits:
fonts/regular.ttfbeside the game that has no'A'is now skipped silently. A one-line stderr note would help someone who drops in a CJK-only font and wonders why it is ignored.lang=enchange relies on fc-match preferring fonts that cover English. That is its documented behaviour, but the glyph check is what really protects you. The test covers both halves, which is nice.CI: the Linux-relevant jobs I could see (appimage, Windows Vulkan build, actionlint) pass. Python source checks and a few others were still pending when I looked. I did not build or run the PR.
I think #1459 completely replaces this btw