Is Android Unicode Yet?
Google's Android platform has dreadful support for Unicode. Even the most recent Android versions are missing out on languages, characters, and symbols which were added to Unicode in the last decade.
Back in 2013, Google created the "Noto" project. Its aim? To include "all the world's languages". They wanted to banish "tofu" - the little white blocks □ which indicate a missing character - hence the name "No Tofu" / "Noto".
There was great flurry and excitement which has, thankfully, been sustained over the years. Noto continues to churn out regular updates to their fonts. Android began to use Noto but, for some unknown reason, it only rarely uses the latest versions. This means whole swathes of modern characters are missing from Android.
You can see all the fonts included in the Android Open Source Project. If you want to download them all, run: git clone https://android.googlesource.com/platform/external/noto-fonts
Open up the fonts in your favourite editor, and you'll see just how outdated they are.
For example, Gujarati is stuck on 2013's version (1.03) despite v2.106 being released in 2023
It's a similar story for the technical symbols block - Android is stuck on v1.09 despite a decade of advances.
A few, like Hentaigana were only created recently - and so are on the latest version. But the majority are woefully outdated.
Perhaps that's just a lack of love for AOSP? Not at all. I downloaded the latest beta version of Android 15 and went through all the fonts it included. They're exactly the same0.
How bad is it?
I decided to compare all the recently published Noto fonts and those available in AOSP.
I downloaded all the most recent Noto fonts from GitHub. It does take some time for fonts to be tested on phones so, in the spirit of fairness, I grabbed the 2024-01-01 release.
Here's what I found.
Of the 224 non-Emoji fonts in Noto, AOSP only has about 140. About a third are simply missing.
Of the fonts included with Android 15, how many were updated within the last 2 years? Ten. Not a typo.
Despite a regular publishing cadence from another Google project, Android is ignoring the vast majority of updates.
This means Android is missing entire languages, has severely outdated fonts in others, and - most importantly - doesn't include the Unicode Power Symbol.
Noto is a great effort - but Android is failing to keep up.
What now?
I've raised a bug on the AOSP bug tracker1. And I've published this ranty blog post. If you work for Google, or an Android manufacturer, please give the Android team a nudge and get them to update.
Ideally, Project Treble would allow for these fonts to be updated, so even older versions of Android could benefit from them.
Full List of Fonts, Dates, and Versions
I've generated this based on the 2024-01-01 release of Noto and the AOSP source code from 2024-09-13. I've placed the dates next to each other for ease of comparrison. Empty cells means the font doesn't exist in that release.
I've tried to transcribe all the data accurately. Corrections very much welcome.
Noto | AOSP | |||
---|---|---|---|---|
Font Name | Version | Date | Date | Version |
Noto Fangsong KSS Rotated Regular | 1 | 2022 | ||
Noto Fangsong KSS Vertical Regular | 1 | 2022 | ||
Noto Kufi Arabic Regular | 2.108 | 2022 | ||
Noto Looped Thai Regular | 1.001 | 2022 | ||
Noto Music Regular | 2.003 | 2022 | ||
Noto Naskh Arabic Regular | 2.018 | 2022 | 2014 | 1.08 |
Noto Naskh Arabic UI Regular | 2.014 | 2022 | 2013 | 1.08 |
Noto Nastaliq Urdu Regular | 3.009 | 2022 | ||
Noto Rashi Hebrew Regular | 1.006 | 2022 | ||
Noto Sans Regular | 2.013 | 2022 | ||
Noto Sans Adlam Regular | 3.001 | 2022 | 2019 | 3 |
Noto Sans Adlam Unjoined Regular | 3.001 | 2022 | ||
Noto Sans Anatolian Hieroglyphs Regular | 2.001 | 2022 | ||
Noto Sans Arabic Regular | 2.012 | 2022 | ||
Noto Sans Armenian Regular | 2.008 | 2022 | 2019 | 2.005 |
Noto Sans Avestan Regular | 2.003 | 2022 | 2013 | 1.04 |
Noto Sans Balinese Regular | 2.004 | 2022 | 2013 | 1.03 |
Noto Sans Bamum Regular | 2.002 | 2022 | 2013 | 1.03 |
Noto Sans Bassa Vah Regular | 2.002 | 2022 | ||
Noto Sans Batak Regular | 2.003 | 2022 | 2013 | 1.05 |
Noto Sans Bengali Regular | 2.003 | 2022 | 2017 | 2.001 |
Noto Sans Bengali UI Regular | 2.003 | 2022 | 2017 | 2.001 |
Noto Sans Bhaiksuki Regular | 2.002 | 2022 | ||
Noto Sans Brahmi Regular | 2.003 | 2022 | 2013 | 1.03 |
Noto Sans Buginese Regular | 2.002 | 2022 | 2013 | 1.05 |
Noto Sans Buhid Regular | 2.001 | 2022 | 2013 | 1.03 |
Noto Sans Canadian Aboriginal Regular | 2.003 | 2022 | 2022 | 2.001 |
Noto Sans Carian Regular | 2.002 | 2022 | 2012 | 1.05 |
Noto Sans Caucasian Albanian Regular | 2.005 | 2022 | ||
Noto Sans Chakma Regular | 2.003 | 2022 | ||
Noto Sans Cham Regular | 2.004 | 2022 | 2012 | 1.02 |
Noto Sans Cherokee Regular | 2.001 | 2022 | 2016 | 2 |
Noto Sans Chorasmian Regular | 1.004 | 2022 | ||
Noto Sans Coptic Regular | 2.004 | 2022 | 2013 | 1.03 |
Noto Sans Cuneiform Regular | 2.001 | 2022 | 2013 | 1.05 |
Noto Sans Cypriot Regular | 2.002 | 2022 | 2012 | 1.03 |
Noto Sans Cypro Minoan Regular | 1.503 | 2022 | ||
Noto Sans Deseret Regular | 2.001 | 2022 | 2013 | 1.02 |
Noto Sans Devanagari Regular | 2.004 | 2022 | 2015 | 2 |
Noto Sans Devanagari UI Regular | 2.004 | 2022 | 2015 | 2 |
Noto Sans Duployan Regular | 3.001 | 2019 | ||
Noto Sans Egyptian Hieroglyphs Regular | 2.001 | 2022 | 2013 | 1.04 |
Noto Sans Elbasan Regular | 2.004 | 2022 | ||
Noto Sans Elymaic Regular | 1.002 | 2022 | ||
Noto Sans Ethiopic Regular | 2.102 | 2022 | 2015 | 2 |
Noto Sans Georgian Regular | 2.003 | 2022 | 2019 | 2.001 |
Noto Sans Glagolitic Regular | 2.004 | 2022 | 2012 | 1.04 |
Noto Sans Gothic Regular | 2.001 | 2022 | 2012 | 1.03 |
Noto Sans Grantha Regular | 2.003 | 2022 | 2020 | 2.001 |
Noto Sans Gujarati Regular | 2.106 | 2022 | 2013 | 1.03 |
Noto Sans Gujarati UI Regular | 2.106 | 2022 | 2013 | 1.03 |
Noto Sans Gunjala Gondi Regular | 1.004 | 2022 | ||
Noto Sans Gurmukhi Regular | 2.004 | 2022 | 2019 | 2.001 |
Noto Sans Gurmukhi UI Regular | 2.004 | 2022 | 2019 | 2.001 |
Noto Sans Hanifi Rohingya Regular | 2.102 | 2022 | ||
Noto Sans Hanunoo Regular | 2.004 | 2022 | 2013 | 1.04 |
Noto Sans Hatran Regular | 2.001 | 2022 | ||
Noto Sans Hebrew Regular | 2.003 | 2022 | 2024 | 3.001 |
Noto Sans Imperial Aramaic Regular | 2.001 | 2022 | 2011 | 1.03 |
Noto Sans Indic Siyaq Numbers Regular | 2.002 | 2022 | ||
Noto Sans Inscriptional Pahlavi Regular | 2.003 | 2022 | 2012 | 1.02 |
Noto Sans Inscriptional Parthian Regular | 2.003 | 2022 | 2012 | 1.03 |
Noto Sans Javanese Regular | 2.005 | 2022 | ||
Noto Sans Kaithi Regular | 2.005 | 2022 | 2013 | 1.05 |
Noto Sans Kannada Regular | 2.005 | 2022 | 2018 | 2.001 |
Noto Sans Kannada UI Regular | 2.005 | 2022 | 2022 | 2.003 |
Noto Sans Kawi Regular | 1 | 2023 | ||
Noto Sans Kayah Li Regular | 2.002 | 2022 | 2013 | 1.02 |
Noto Sans Kharoshthi Regular | 2.004 | 2022 | 2013 | 1.03 |
Noto Sans Khmer Regular | 2.004 | 2022 | 2016 | 1.901 |
Noto Sans Khojki Regular | 2.005 | 2022 | ||
Noto Sans Khudawadi Regular | 2.003 | 2022 | ||
Noto Sans Lao Regular | 2.003 | 2022 | 2017 | 2.001 |
Noto Sans Lao Looped Regular | 1.002 | 2022 | ||
Noto Sans Lepcha Regular | 2.006 | 2022 | 2013 | 1.03 |
Noto Sans Limbu Regular | 2.004 | 2022 | 2013 | 1.05 |
Noto Sans Linear A Regular | 2.002 | 2022 | ||
Noto Sans Linear B Regular | 2.002 | 2022 | 2013 | 1.04 |
Noto Sans Lisu Regular | 2.102 | 2022 | 2012 | 1.03 |
Noto Sans Lycian Regular | 2.002 | 2022 | 2012 | 1.04 |
Noto Sans Lydian Regular | 2.002 | 2022 | 2012 | 1.03 |
Noto Sans Mahajani Regular | 2.003 | 2022 | ||
Noto Sans Malayalam Regular | 2.104 | 2022 | 2018 | 2.001 |
Noto Sans Malayalam UI Regular | 2.104 | 2022 | 2022 | 2.103 |
Noto Sans Mandaic Regular | 2.002 | 2022 | 2013 | 1.02 |
Noto Sans Manichaean Regular | 2.005 | 2022 | ||
Noto Sans Marchen Regular | 2.003 | 2022 | ||
Noto Sans Masaram Gondi Regular | 1.004 | 2022 | ||
Noto Sans Math Regular | 2.539 | 2022 | ||
Noto Sans Mayan Numerals Regular | 2.001 | 2022 | ||
Noto Sans Medefaidrin Regular | 1.002 | 2022 | 2020 | 1.001 |
Noto Sans Meetei Mayek Regular | 2.002 | 2022 | 2013 | 1.04 |
Noto Sans Mende Kikakui Regular | 2.003 | 2022 | ||
Noto Sans Meroitic Regular | 2.002 | 2022 | ||
Noto Sans Miao Regular | 2.003 | 2022 | ||
Noto Sans Modi Regular | 2.004 | 2022 | 2018 | 2 |
Noto Sans Mongolian Regular | 3.001 | 2023 | 2013 | 1.04 |
Noto Sans Mono Regular | 2.014 | 2022 | ||
Noto Sans Mro Regular | 2.001 | 2022 | ||
Noto Sans Multani Regular | 2.002 | 2022 | ||
Noto Sans Myanmar Regular | 2.107 | 2022 | ||
Noto Sans NKo Regular | 2.004 | 2022 | 2013 | 1.02 |
Noto Sans NKo Unjoined Regular | 2.004 | 2023 | ||
Noto Sans Nabataean Regular | 2.001 | 2022 | ||
Noto Sans Nag Mundari Regular | 1 | 2023 | ||
Noto Sans Nandinagari Regular | 1.002 | 2022 | ||
Noto Sans New Tai Lue Regular | 2.004 | 2022 | 2013 | 1.05 |
Noto Sans Newa Regular | 2.007 | 2022 | ||
Noto Sans Nushu Regular | 1.003 | 2022 | ||
Noto Sans Ogham Regular | 2.001 | 2022 | 2012 | 1.04 |
Noto Sans Ol Chiki Regular | 2.003 | 2022 | 2013 | 1.03 |
Noto Sans Old Hungarian Regular | 2.005 | 2022 | ||
Noto Sans Old Italic Regular | 2.003 | 2022 | 2012 | 1.02 |
Noto Sans Old North Arabian Regular | 2.001 | 2022 | ||
Noto Sans Old Permic Regular | 2.001 | 2022 | ||
Noto Sans Old Persian Regular | 2.001 | 2022 | 2012 | 1.04 |
Noto Sans Old Sogdian Regular | 2.002 | 2022 | ||
Noto Sans Old South Arabian Regular | 2.001 | 2022 | 2011 | 1.03 |
Noto Sans Old Turkic Regular | 2.003 | 2022 | 2013 | 1.02 |
Noto Sans Oriya Regular | 2.005 | 2022 | 2015 | 1.01 |
Noto Sans Osage Regular | 2.002 | 2022 | 2017 | 2 |
Noto Sans Osmanya Regular | 2.001 | 2022 | 2012 | 1.03 |
Noto Sans Pahawh Hmong Regular | 2.001 | 2022 | ||
Noto Sans Palmyrene Regular | 2.001 | 2022 | ||
Noto Sans Pau Cin Hau Regular | 2.002 | 2022 | ||
Noto Sans Phags-Pa Regular | 2.003 | 2022 | 2013 | 1.03 |
Noto Sans PhagsPa Regular | 2.004 | 2022 | ||
Noto Sans Phoenician Regular | 2.001 | 2022 | 2012 | 1.04 |
Noto Sans Psalter Pahlavi Regular | 2.002 | 2022 | ||
Noto Sans Rejang Regular | 2.002 | 2022 | 2013 | 1.05 |
Noto Sans Runic Regular | 2.002 | 2022 | 2012 | 1.02 |
Noto Sans Samaritan Regular | 2.001 | 2022 | 2013 | 1.03 |
Noto Sans Saurashtra Regular | 2.002 | 2022 | 2013 | 1.04 |
Noto Sans Sharada Regular | 2.006 | 2022 | ||
Noto Sans Shavian Regular | 2.001 | 2022 | 2011 | 1.03 |
Noto Sans Siddham Regular | 2.005 | 2022 | ||
Noto Sans SignWriting Regular | 2.005 | 2022 | ||
Noto Sans Sinhala Regular | 2.006 | 2022 | 2016 | 2.001 |
Noto Sans Sinhala UI Regular | 2.006 | 2022 | 2016 | 2.001 |
Noto Sans Sogdian Regular | 2.002 | 2022 | ||
Noto Sans Sora Sompeng Regular | 2.101 | 2022 | ||
Noto Sans Soyombo Regular | 2.001 | 2022 | 2019 | 2 |
Noto Sans Sundanese Regular | 2.005 | 2022 | 2013 | 1.05 |
Noto Sans Syloti Nagri Regular | 2.004 | 2022 | 2013 | 1.04 |
Noto Sans Symbols Regular | 2.003 | 2022 | 2013 | 1.09 |
Noto Sans Symbols 2 Regular | 2.008 | 2022 | ||
Noto Sans Syriac Regular | 3 | 2022 | ||
Noto Sans Syriac Eastern Regular | 3.001 | 2022 | 2014 | 1.04 |
Noto Sans Syriac Western Regular | 3 | 2022 | 2014 | 1.04 |
Noto Sans Tagalog Regular | 2.002 | 2022 | 2013 | 1.03 |
Noto Sans Tagbanwa Regular | 2.001 | 2022 | 2013 | 1.04 |
Noto Sans Tai Le Regular | 2.002 | 2022 | 2012 | 1.04 |
Noto Sans Tai Tham Regular | 2.002 | 2022 | 2013 | 1.04 |
Noto Sans Tai Viet Regular | 2.004 | 2022 | 2013 | 1.03 |
Noto Sans Takri Regular | 2.005 | 2022 | 2020 | 2.002 |
Noto Sans Tamil Regular | 2.004 | 2022 | 2017 | 2.001 |
Noto Sans Tamil UI Regular | 2.004 | 2022 | 2022 | 2.003 |
Noto Sans Tamil Supplement Regular | 2.001 | 2022 | ||
Noto Sans Tangsa Regular | 1.506 | 2022 | ||
Noto Sans Telugu Regular | 2.005 | 2022 | 2022 | 2.004 |
Noto Sans Telugu UI Regular | 2.005 | 2022 | 2022 | 2.004 |
Noto Sans Test Regular | 1 | 2022 | ||
Noto Sans Thaana Regular | 3.001 | 2022 | 2014 | 1.02 |
Noto Sans Thai Regular | 2.002 | 2022 | 2011 | 1.04 |
Noto Sans Thai Looped Regular | 1.001 | 2022 | ||
Noto Sans Tifinagh Regular | 2.006 | 2022 | ||
Noto Sans Tifinagh APT Regular | 2.006 | 2022 | ||
Noto Sans Tifinagh Adrar Regular | 2.006 | 2022 | ||
Noto Sans Tifinagh Agraw Imazighen Regular | 2.006 | 2022 | ||
Noto Sans Tifinagh Ahaggar Regular | 2.006 | 2022 | ||
Noto Sans Tifinagh Air Regular | 2.006 | 2022 | ||
Noto Sans Tifinagh Azawagh Regular | 2.006 | 2022 | ||
Noto Sans Tifinagh Ghat Regular | 2.006 | 2022 | ||
Noto Sans Tifinagh Hawad Regular | 2.006 | 2022 | ||
Noto Sans Tifinagh Rhissa Ixa Regular | 2.006 | 2022 | ||
Noto Sans Tifinagh SIL Regular | 2.006 | 2022 | ||
Noto Sans Tifinagh Tawellemmet Regular | 2.006 | 2022 | ||
Noto Sans Tirhuta Regular | 2.003 | 2022 | ||
Noto Sans Ugaritic Regular | 2.001 | 2022 | 2013 | 1.02 |
Noto Sans Vai Regular | 2.001 | 2022 | 2013 | 1.02 |
Noto Sans Vithkuqi Regular | 1.001 | 2022 | ||
Noto Sans Wancho Regular | 2.001 | 2022 | ||
Noto Sans Warang Citi Regular | 3.002 | 2022 | ||
Noto Sans Yi Regular | 2.002 | 2022 | 2013 | 1.02 |
Noto Sans Zanabazar Square Regular | 2.006 | 2022 | ||
Noto Serif Regular | 2.013 | 2022 | 2012 | 1.07 |
Noto Serif Ahom Regular | 2.007 | 2022 | ||
Noto Serif Armenian Regular | 2.008 | 2022 | 2019 | 2.005 |
Noto Serif Balinese Regular | 2.005 | 2022 | ||
Noto Serif Bengali Regular | 2.003 | 2022 | 2019 | 2.001 |
Noto Serif Devanagari Regular | 2.004 | 2022 | 2019 | 2.001 |
Noto Serif Display Regular | 2.009 | 2022 | ||
Noto Serif Dives Akuru Regular | 1.001 | 2022 | ||
Noto Serif Dogra Regular | 1.007 | 2022 | 2019 | 1.004 |
Noto Serif Ethiopic Regular | 2.102 | 2022 | 2017 | 2 |
Noto Serif Georgian Regular | 2.003 | 2022 | 2019 | 2.001 |
Noto Serif Grantha Regular | 2.004 | 2022 | ||
Noto Serif Gujarati Regular | 2.106 | 2022 | 2017 | 2.002 |
Noto Serif Gurmukhi Regular | 2.004 | 2022 | 2017 | 2.001 |
Noto Serif Hebrew Regular | 2.003 | 2022 | 2021 | 2.002 |
Noto Serif Hentaigana ExtraLight Regular | 2023 | 1 | ||
Noto Serif Kannada Regular | 2.005 | 2022 | 2017 | 2.002 |
Noto Serif Khitan Small Script Regular | 1 | 2022 | ||
Noto Serif Khmer Regular | 2.004 | 2022 | ||
Noto Serif Khojki Regular | 2.005 | 2022 | ||
Noto Serif Lao Regular | 2.003 | 2022 | 2017 | 2 |
Noto Serif Makasar Regular | 1.001 | 2022 | ||
Noto Serif Malayalam Regular | 2.104 | 2022 | 2019 | 2.001 |
Noto Serif Myanmar Regular | 2.106 | 2022 | ||
Noto Serif NP Hmong Regular | 1.001 | 2022 | 2020 | 1 |
Noto Serif Old Uyghur Regular | 1.003 | 2022 | ||
Noto Serif Oriya Regular | 1.051 | 2022 | ||
Noto Serif Ottoman Siyaq Regular | 1.006 | 2022 | ||
Noto Serif Sinhala Regular | 2.007 | 2022 | 2016 | 2.002 |
Noto Serif Tamil Regular | 2.004 | 2022 | 2017 | 2.001 |
Noto Serif Tangut Regular | 2.169 | 2022 | 2019 | 2.001 |
Noto Serif Telugu Regular | 2.005 | 2022 | 2019 | 2.001 |
Noto Serif Test Regular | 1 | 2022 | ||
Noto Serif Thai Regular | 2.002 | 2022 | 2016 | 2 |
Noto Serif Tibetan Regular | 2.103 | 2022 | 2018 | 2.001 |
Noto Serif Toto Regular | 2.001 | 2022 | ||
Noto Serif Vithkuqi Regular | 1.005 | 2022 | ||
Noto Serif Yezidi Regular | 1.001 | 2022 | 2020 | 1 |
Noto Traditional Nushu Regular | 2.003 | 2022 |
Code
This Python code will get all the TTF fonts in a directory, and its sub-directories, and then print a Markdown table of name, version, and copyright date.
Python 3import os
import glob
filelist = glob.glob('**/*.ttf', recursive=True)
for file in sorted(filelist):
filename = os.fsdecode(file)
if filename.endswith(".ttf"):
font = ttLib.TTFont(filename)
ttf_name = font["name"].getDebugName(1)
ttf_style = font["name"].getDebugName(2)
ttf_version = font["name"].getDebugName(5).split()[1].split(";")[0]
ttf_copyright = font["name"].getDebugName(0).split()[1].split("-")[-1]
print ( f"| {ttf_name} {ttf_style} | {ttf_version} | {ttf_copyright} |")