Fixing Bangla Font Rendering on Ubuntu: Installing SolaimanLipi System-Wide
Out of the box, Ubuntu renders Bangla text with Noto Sans Bengali. It's technically correct — full Unicode coverage, proper shaping — but for anyone who grew up reading Bangla in print or on the early web, it doesn't feel right. SolaimanLipi is the font most Bangla readers actually associate with a comfortable reading experience — it's the de facto standard adopted across Bangladeshi government and publishing for years. Here's how to make it the system default, everywhere, in one pass.
Step 1: Check What's Already There
Before installing anything, check what fonts and fontconfig rules already exist — Ubuntu often has partial Bangla support pre-configured, and stepping on it blindly can cause conflicts:
# User font directories
ls -la ~/.fonts ~/.local/share/fonts
# Any Bangla-capable fonts already installed system-wide
fc-list :lang=bn
# Existing per-user fontconfig overrides
cat ~/.config/fontconfig/fonts.confOn a fresh Ubuntu 26.04 GNOME install, this usually turns up Noto Sans/Serif Bengali and Lohit Bengali already present via the fonts-beng metapackage — but no SolaimanLipi, and often an existing fonts.conf already forcing Bangla text to Noto Sans Bengali.
Step 2: Get SolaimanLipi From the Original Source
SolaimanLipi isn't packaged in the Ubuntu/Debian repositories, so it has to come from its original distributor: OmicronLab — the same team behind Avro Keyboard — who host it from the Ekushey open-font project.
curl -fL -o SolaimanLipi.ttf \
"https://www.omicronlab.com/download/fonts/SolaimanLipi_20-04-07.ttf" \
-A "Mozilla/5.0"
file SolaimanLipi.ttf
# → SolaimanLipi.ttf: TrueType Font data ... SIL Open Font LicenseAlways verify the download with file before installing — a valid TTF with an SIL OFL license string is a good sign you got the real font, not a redirect page or a bundled installer.
Step 3: Install It for Your User
No root needed — user-level font directories are picked up automatically by fontconfig:
mkdir -p ~/.local/share/fonts/bengali
cp SolaimanLipi.ttf ~/.local/share/fonts/bengali/
fc-cache -f ~/.local/share/fonts
fc-list | grep -i solaiman
# → SolaimanLipi.ttf: SolaimanLipi:style=NormalStep 4: Make It the System-Wide Default for Bangla
This is the part that actually matters — installing the font just makes it available; it doesn't make apps use it. That's fontconfig's job, via ~/.config/fontconfig/fonts.conf:
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<!-- Prefer SolaimanLipi for Bengali text system-wide; fall back to Noto
Sans Bengali for any glyphs SolaimanLipi doesn't cover. -->
<match target="pattern">
<test name="lang" compare="contains"><string>bn</string></test>
<edit name="family" mode="prepend" binding="strong">
<string>SolaimanLipi</string>
</edit>
<edit name="family" mode="append" binding="weak">
<string>Noto Sans Bengali</string>
</edit>
</match>
<!-- Cover apps that don't set a language hint (some terminals, Electron
apps) by also aliasing the generic families. -->
<alias>
<family>sans-serif</family>
<prefer><family>SolaimanLipi</family></prefer>
</alias>
<alias>
<family>serif</family>
<prefer><family>SolaimanLipi</family></prefer>
</alias>
<alias>
<family>monospace</family>
<prefer><family>SolaimanLipi</family></prefer>
</alias>
</fontconfig>Rebuild the cache and confirm it resolved correctly:
fc-cache -f
fc-match sans-serif:lang=bn
# → SolaimanLipi.ttf: "SolaimanLipi" "Normal"Why the fallback matters: binding="weak" on the Noto Sans Bengali line means it only kicks in for glyphs SolaimanLipi is missing — you get SolaimanLipi's look everywhere it has coverage, with no missing-glyph boxes (□) for anything it doesn't.
Step 5: See It Take Effect
Fontconfig changes apply immediately to new processes — already-open apps cached their font list at launch:
# Close and reopen your browser / editor / file manager, then check
# any Bangla text — news site, .odt file, chat app.No logout or reboot required, unlike XKB/keyboard-layout changes.
Other Bangla Fonts Worth Knowing
SolaimanLipi isn't the only option, and it's worth knowing the trade-offs before committing the whole system to it:
| Font | Feel | Conjunct (যুক্তাক্ষর) rendering | Best for |
|---|---|---|---|
| SolaimanLipi | Classic, nostalgic | Basic — some complex conjuncts render as stacked components rather than true ligatures | General reading, matching how most Bangla content was typeset for the last ~15 years |
| Noto Sans Bengali | Modern, UI-oriented | Excellent — full OpenType conjunct shaping | UI chrome, technical documents, guaranteed Unicode correctness |
| Kalpurush | Similar era to SolaimanLipi, slightly more refined | Better than SolaimanLipi, not as complete as Noto | A middle ground if SolaimanLipi feels dated after trying it |
Mukti (already in fonts-beng-extra) | Utilitarian, narrower | Basic | Dense text, tables |
If SolaimanLipi's conjunct rendering bothers you on certain words, swap the <string>SolaimanLipi</string> line in fonts.conf for Kalpurush — the rest of the config (weak-binding fallback, generic-family aliases) doesn't need to change.
Troubleshooting: Snap and Flatpak Apps Ignoring the Font
Ubuntu ships a lot of software as snaps, and snap-confined apps (Firefox, Chromium, etc. on default Ubuntu installs) run in a sandbox with their own font-cache view. Most snaps bind-mount ~/.local/share/fonts and ~/.config/fontconfig automatically through the desktop interface, so this setup usually works out of the box — but if a specific snap app still shows the old font after a restart:
# Confirm the snap actually has the font interface connected
snap connections <snap-name> | grep -i font
# Force that snap's font cache to rebuild
snap run --shell <snap-name> -c "fc-cache -f"Flatpak apps are stricter — by default they only see fonts under ~/.local/share/fonts if the fonts or host-fonts permission is granted:
flatpak override --user --filesystem=~/.local/share/fonts:ro <app-id>A Quick Way to Compare Fonts Side-by-Side
Before committing, it helps to see more than one candidate rendered next to each other. fc-match -a lists every font fontconfig would consider for a query, in preference order — useful for confirming your fonts.conf edit actually changed the ranking, not just added an entry:
fc-match -a :lang=bn | head -5The top result is what every unqualified Bangla-text request resolves to. If SolaimanLipi isn't first, the fonts.conf edit didn't take — usually because of a typo in the <test name="lang"> block or a stale fc-cache.
Key Takeaways
- Check before you install —
fc-list :lang=bnand the existingfontconfig/fonts.conftell you what's already fighting for the same text. - Always download fonts from their original distributor — for Bangla fonts, that's usually OmicronLab or Ekushey, not random font-aggregator sites.
- Installing ≠ defaulting — a font sitting in
~/.local/share/fontsdoes nothing until fontconfig is told to prefer it for a given language. - Use weak-binding fallbacks, not a hard single-font override — it prevents missing-glyph boxes for characters your primary font doesn't cover.
- This is entirely per-user and reversible — delete
~/.config/fontconfig/fonts.confand~/.local/share/fonts/bengali/to fully revert.
A five-minute fontconfig tweak, and Bangla text across the entire system finally reads the way it's supposed to.