chore(tools): warn about unsupported characters
What changed, and why it matters
This is a routine font-generation tooling update. It adds a warning when a character is not supported by a font and specifically falls back the Spanish/Portuguese masculine ordinal indicator 'º' to a plain 'o' glyph. The generated font files are updated accordingly. There is no security issue here.
No security action required. Treat as a normal localization/tooling improvement.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The commit modifies core/tools/codegen/gen_font.py to add a _char_supported() helper using FreeType’s get_char_index() and prints warnings when a character lacks a glyph. For the ‘º’ character it substitutes ‘o’ as a fallback and regenerates JSON font metrics for Spanish and Portuguese font variants. Other unsupported characters continue to use an unknown glyph placeholder. This is a build-time localization/typography fix.
Changed components
core/tools/codegen/gen_font.pycore/translations/fonts/font_pixeloperator_bold_8_es.jsoncore/translations/fonts/font_pixeloperator_bold_8_pt.jsoncore/translations/fonts/font_pixeloperator_bold_8_upper_es.jsoncore/translations/fonts/font_pixeloperator_bold_8_upper_pt.jsoncore/translations/fonts/font_pixeloperator_regular_8_es.jsoncore/translations/fonts/font_pixeloperator_regular_8_pt.jsoncore/translations/fonts/font_pixeloperator_regular_8_upper_es.jsoncore/translations/fonts/font_pixeloperator_regular_8_upper_pt.jsoncore/translations/fonts/font_pixeloperatormono_regular_8_es.jsoncore/translations/fonts/font_pixeloperatormono_regular_8_pt.jsoncore/translations/fonts/font_unifont_bold_16_es.jsoncore/translations/fonts/font_unifont_bold_16_pt.jsonInspect captured patch +26 / −12
diff --git a/core/tools/codegen/gen_font.py b/core/tools/codegen/gen_font.py
index 077214f92..88415a00c 100755
--- a/core/tools/codegen/gen_font.py
+++ b/core/tools/codegen/gen_font.py
@@ -309,6 +309,17 @@ class FaceProcessor:
c = c.upper()
assert len(c) == 1
assert len(map_from) == 1
+
+ if not self._char_supported(c):
+ if c == "º":
+ c = "o"
+ print(
+ f"Character 'º' not supported ⚠️ in font {self.name} {self.style}, using fallback glyph {c}"
+ )
+ else:
+ print(
+ f"Character '{c}' not supported ❌ in font {self.name} {self.style}, using unknown glyph"
+ )
self._load_char(c)
glyph = Glyph.from_face(self.face, c, self.shaveX)
glyph.print_metrics()
@@ -343,6 +354,9 @@ class FaceProcessor:
json_content = json.dumps(widths, indent=2, ensure_ascii=False)
f.write(json_content + "\n")
+ def _char_supported(self, c: str) -> bool:
+ return self.face.get_char_index(ord(c)) != 0
+
def _load_char(self, c: str) -> None:
self.face.load_char(c, freetype.FT_LOAD_RENDER | freetype.FT_LOAD_TARGET_NORMAL) # type: ignore
diff --git a/core/translations/fonts/font_pixeloperator_bold_8_es.json b/core/translations/fonts/font_pixeloperator_bold_8_es.json
index 02a435520..2ef3ab008 100644
--- a/core/translations/fonts/font_pixeloperator_bold_8_es.json
+++ b/core/translations/fonts/font_pixeloperator_bold_8_es.json
@@ -1,5 +1,5 @@
{
- "º": "0507080107fc6318c7e0",
+ "º": "06050700057b3cf378",
"Á": "060707000718c7b3cffcc0",
"É": "060707000718cff0f30fc0",
"Í": "0307050107786db0",
diff --git a/core/translations/fonts/font_pixeloperator_bold_8_pt.json b/core/translations/fonts/font_pixeloperator_bold_8_pt.json
index 7cef54a2e..bf0600d05 100644
--- a/core/translations/fonts/font_pixeloperator_bold_8_pt.json
+++ b/core/translations/fonts/font_pixeloperator_bold_8_pt.json
@@ -1,5 +1,5 @@
{
- "º": "0507080107fc6318c7e0",
+ "º": "06050700057b3cf378",
"Á": "060707000718c7b3cffcc0",
"Ã": "070707000777b9e66cdfb300",
"Ç": "06080700077b3c30cde19c",
diff --git a/core/translations/fonts/font_pixeloperator_bold_8_upper_es.json b/core/translations/fonts/font_pixeloperator_bold_8_upper_es.json
index 074ff13d4..4f653a355 100644
--- a/core/translations/fonts/font_pixeloperator_bold_8_upper_es.json
+++ b/core/translations/fonts/font_pixeloperator_bold_8_upper_es.json
@@ -1,5 +1,5 @@
{
- "º": "0507080107fc6318c7e0",
+ "º": "06050700057b3cf378",
"Á": "060707000718c7b3cffcc0",
"É": "060707000718cff0f30fc0",
"Í": "0307050107786db0",
diff --git a/core/translations/fonts/font_pixeloperator_bold_8_upper_pt.json b/core/translations/fonts/font_pixeloperator_bold_8_upper_pt.json
index 078bec8fe..8ad963b04 100644
--- a/core/translations/fonts/font_pixeloperator_bold_8_upper_pt.json
+++ b/core/translations/fonts/font_pixeloperator_bold_8_upper_pt.json
@@ -1,5 +1,5 @@
{
- "º": "0507080107fc6318c7e0",
+ "º": "06050700057b3cf378",
"Á": "060707000718c7b3cffcc0",
"Ã": "070707000777b9e66cdfb300",
"Ç": "06080700077b3c30cde19c",
diff --git a/core/translations/fonts/font_pixeloperator_regular_8_es.json b/core/translations/fonts/font_pixeloperator_regular_8_es.json
index 7d023af27..f4b0068ed 100644
--- a/core/translations/fonts/font_pixeloperator_regular_8_es.json
+++ b/core/translations/fonts/font_pixeloperator_regular_8_es.json
@@ -1,5 +1,5 @@
{
- "º": "0507080107fc6318c7e0",
+ "º": "050506000574631700",
"Á": "0507060007111d18fe20",
"É": "0507060007113f0e43e0",
"Í": "020704010762a8",
diff --git a/core/translations/fonts/font_pixeloperator_regular_8_pt.json b/core/translations/fonts/font_pixeloperator_regular_8_pt.json
index f88d1d7ac..016d3a6f8 100644
--- a/core/translations/fonts/font_pixeloperator_regular_8_pt.json
+++ b/core/translations/fonts/font_pixeloperator_regular_8_pt.json
@@ -1,5 +1,5 @@
{
- "º": "0507080107fc6318c7e0",
+ "º": "050506000574631700",
"Á": "0507060007111d18fe20",
"Ã": "06070600076667228be880",
"Ç": "0508060007746108b84c",
diff --git a/core/translations/fonts/font_pixeloperator_regular_8_upper_es.json b/core/translations/fonts/font_pixeloperator_regular_8_upper_es.json
index 651352c38..6e18d8931 100644
--- a/core/translations/fonts/font_pixeloperator_regular_8_upper_es.json
+++ b/core/translations/fonts/font_pixeloperator_regular_8_upper_es.json
@@ -1,5 +1,5 @@
{
- "º": "0507080107fc6318c7e0",
+ "º": "050506000574631700",
"Á": "0507060007111d18fe20",
"É": "0507060007113f0e43e0",
"Í": "020704010762a8",
diff --git a/core/translations/fonts/font_pixeloperator_regular_8_upper_pt.json b/core/translations/fonts/font_pixeloperator_regular_8_upper_pt.json
index 276854956..bf2840212 100644
--- a/core/translations/fonts/font_pixeloperator_regular_8_upper_pt.json
+++ b/core/translations/fonts/font_pixeloperator_regular_8_upper_pt.json
@@ -1,5 +1,5 @@
{
- "º": "0507080107fc6318c7e0",
+ "º": "050506000574631700",
"Á": "0507060007111d18fe20",
"Ã": "06070600076667228be880",
"Ç": "0508060007746108b84c",
diff --git a/core/translations/fonts/font_pixeloperatormono_regular_8_es.json b/core/translations/fonts/font_pixeloperatormono_regular_8_es.json
index 6907ff45b..986c585ef 100644
--- a/core/translations/fonts/font_pixeloperatormono_regular_8_es.json
+++ b/core/translations/fonts/font_pixeloperatormono_regular_8_es.json
@@ -1,5 +1,5 @@
{
- "º": "0507070007fc6318c7e0",
+ "º": "050507000574631700",
"Á": "0507070007111d18fe20",
"É": "0507070007113f0e43e0",
"Í": "0507070007113e4213e0",
diff --git a/core/translations/fonts/font_pixeloperatormono_regular_8_pt.json b/core/translations/fonts/font_pixeloperatormono_regular_8_pt.json
index ea7babe8f..4a7c5aaf4 100644
--- a/core/translations/fonts/font_pixeloperatormono_regular_8_pt.json
+++ b/core/translations/fonts/font_pixeloperatormono_regular_8_pt.json
@@ -1,5 +1,5 @@
{
- "º": "0507070007fc6318c7e0",
+ "º": "050507000574631700",
"Á": "0507070007111d18fe20",
"Ã": "06070700076667228be880",
"Ç": "0508070007746108b84c",
diff --git a/core/translations/fonts/font_unifont_bold_16_es.json b/core/translations/fonts/font_unifont_bold_16_es.json
index f18dc1607..71fa3561f 100644
--- a/core/translations/fonts/font_unifont_bold_16_es.json
+++ b/core/translations/fonts/font_unifont_bold_16_es.json
@@ -1,5 +1,5 @@
{
- "º": "0000080000",
+ "º": "0608070008fa38e38e38fe",
"Á": "0000080000",
"É": "0000080000",
"Í": "0000080000",
diff --git a/core/translations/fonts/font_unifont_bold_16_pt.json b/core/translations/fonts/font_unifont_bold_16_pt.json
index 990f29460..7c271a360 100644
--- a/core/translations/fonts/font_unifont_bold_16_pt.json
+++ b/core/translations/fonts/font_unifont_bold_16_pt.json
@@ -1,5 +1,5 @@
{
- "º": "0000080000",
+ "º": "0608070008fa38e38e38fe",
"Á": "0000080000",
"Ã": "0000080000",
"Ç": "0000080000",
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.