Machine readability — font comparison

Does font choice change OCR / VLM accuracy on code? (BUENA-350 · Study #3) · ← all reports

Generated against Buena Mono v1.228 · last updated 2026-07-27

Does the typeface a code screenshot is set in change how reliably a machine reads it? We render a 31-line code corpus (confusable-glyph stress lines + real code) across 6 coding fonts, matched on rendered x-height so size can't confound shape, with ligatures forced off, in light and dark themes, and score character accuracy + per-glyph-class error. Engines: apple-vision, tesseract, vlm (qwen2.5vl:7b, local).

Finding. On Tesseract, at matched x-height, Source Code Pro transcribes most accurately; Buena Mono ranks 6/6. The gap is concentrated in the 0 / O / o class — Buena's human-oriented zero disambiguation is read less reliably by a classical OCR engine trained on conventional shapes. A concrete instance of the human-vs-machine legibility tension (Frutiger's OCR-B question). And the result is robust across engine classes: a modern vision-language model (qwen2.5vl:7b) reads every font far more accurately (Buena 93% vs 87% on Tesseract) and handles the zero — yet still ranks Buena 6/6. All three engines agree on the order; the machine-readability gap narrows with a better reader but does not close.

Accuracy & Δ vs Buena Mono (all sizes/themes, bootstrap 95% CI)

FontChar accuracyΔ vs Buena (pp, 95% CI)
Buena Mono87%reference
JetBrains Mono88%+1.4 [+0.4, +2.5]
Fira Code91%+4.0 [+3.0, +5.0]
Cascadia Code90%+3.2 [+2.2, +4.2]
Source Code Pro91%+4.4 [+3.4, +5.3]
IBM Plex Mono90%+3.5 [+2.5, +4.5]

Char accuracy by size (light theme; green = better)

Font9px11px13px16px24px
Buena Mono82%86%87%89%90%
JetBrains Mono80%88%90%90%92%
Fira Code86%89%92%93%93%
Cascadia Code84%89%91%93%93%
Source Code Pro88%91%91%92%93%
IBM Plex Mono87%90%91%91%92%

Error rate by glyph-confusion class (lower = better; how often a font's char in that class is misread)

Font0 / O / o1 / l / I / |2 / Z5 / S6 / G8 / B9 / g / qbraces / parenspunct (. , : ;)quotes / ticks
Buena Mono48%31%2%8%3%11%2%22%6%21%
JetBrains Mono37%28%7%8%12%10%6%13%1%25%
Fira Code30%22%5%6%5%9%0%4%1%28%
Cascadia Code35%20%4%6%0%4%1%5%2%20%
Source Code Pro30%19%2%8%2%6%0%1%7%19%
IBM Plex Mono27%23%5%5%6%5%0%10%1%22%

Engine agreement (char accuracy by engine, hbview)

Fontapple-visiontesseractvlm
Buena Mono51%87%93%
JetBrains Mono51%88%94%
Fira Code59%91%96%
Cascadia Code55%90%95%
Source Code Pro57%91%96%
IBM Plex Mono55%90%94%

The engines disagree on the ranking — classical OCR and a modern engine fail on different glyph shapes, so no single engine should be treated as ground truth. Ranking — apple-vision: Fira Code > Source Code Pro > IBM Plex Mono > Cascadia Code > JetBrains Mono > Buena Mono; tesseract: Source Code Pro > Fira Code > IBM Plex Mono > Cascadia Code > JetBrains Mono > Buena Mono; vlm: Fira Code > Source Code Pro > Cascadia Code > JetBrains Mono > IBM Plex Mono > Buena Mono

Render fidelity (tesseract: hb-view vs headless-Chromium, Regular / light)

Fonthb-viewChromium (real AA)
Buena Mono87%83%
JetBrains Mono88%83%
Fira Code91%86%
Cascadia Code90%85%
Source Code Pro91%88%
IBM Plex Mono90%86%

The Chromium condition rasterizes with real OS anti-aliasing/hinting. The ranking shifts under real-browser AA — worth noting as a rendering-fidelity caveat.

Follow-up — which Buena Mono zero is most machine-readable? (zero-dense lines, small sizes, light+dark)

Study points at the 0/O/o class. Buena offers three zero designs — the default, ss10 (Plain zero), and ss11/the zero feature (Dotted). We rendered zero-dense code with each and re-scored:

Buena Mono zero0/O/o err · tesseractchar acc · tesseract0/O/o err · apple-visionchar acc · apple-vision
default66%64%77%35%
ss10 Plain zero ← recommended33%84%64%42%
zero Dotted64%66%79%32%
Actionable fix. The Plain zero (ss10) is far more machine-readable: on Tesseract it cuts the 0/O/o error from 66% to 33% and lifts overall accuracy 64% → 84%; Apple Vision agrees. The human-facing default (disambiguated zero) is best kept for people — but Buena's ss13 "machine-readable mode" currently only decomposes ligatures. Adding sub zero by zero.ss10; to ss13 would give machine contexts the plain zero too, with no change to the human default.

Sample stimuli (9px, light, ligatures off)

Buena Mono
JetBrains Mono
Fira Code
Cascadia Code
Source Code Pro
IBM Plex Mono

Method & caveats

Dataset (scores + raw hypotheses) and this report are reproducible via python -m scripts.fontcompare.run in the font repo. Generated 2026-07-27 10:57:32, 13020 rows.