say, I want to display a list of 10 languages in native scripts, and if the phone doesn't support the font it will fall back to english script. Is there any way we can detect which fonts are supported by particular device? In other words, I just want to check whether, say, "punjabi" can be displayed as "ਪੰਜਾਬੀ"
To be on the safe side, I would use both the English and the native name (and this is what I actually did). Please take pity on the poor guy seeing all these فارسی 贛語 ગુજરાતી Հայերեն हिन्दी বিষ্ণুপ্রিয়া মণিপুরী עברית ಕನ್ನಡ ქართული ລາວ مصرى नेपाल भाषा Олык марий ភាសាខ្មែរ Српски தமிழ் 文言 ייִדיש 中文 in native scripts only!
You also can try to draw your text into a bitmap and check whether or not the resulting bitmap is blank. E.g. http://www.skoumal.net/en/android-how-draw-text-bitmap and How to check if a Bitmap is empty (blank) on Android (of course, assuming that unsupported letters are not shown as black diamonds or something like that).
class Util {
private static final int WIDTH_PX = 200;
private static final int HEIGHT_PX = 80;
public static boolean isSupported(Context context, String text) {
int w = WIDTH_PX, h = HEIGHT_PX;
Resources resources = context.getResources();
float scale = resources.getDisplayMetrics().density;
Bitmap.Config conf = Bitmap.Config.ARGB_8888;
Bitmap bitmap = Bitmap.createBitmap(w, h, conf); // this creates a MUTABLE bitmap
Bitmap orig = bitmap.copy(conf, false);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.rgb(0, 0, 0));
paint.setTextSize((int) (14 * scale));
// draw text to the Canvas center
Rect bounds = new Rect();
paint.getTextBounds(text, 0, text.length(), bounds);
int x = (bitmap.getWidth() - bounds.width()) / 2;
int y = (bitmap.getHeight() + bounds.height()) / 2;
canvas.drawText(text, x, y, paint);
boolean res = !orig.sameAs(bitmap);
orig.recycle();
bitmap.recycle();
return res;
}
}
Testing code:
String s;
s="";Log.d("~~~","=="+s+"=="+Util.isSupported(this, s));
s="中文";Log.d("~~~","=="+s+"=="+Util.isSupported(this, s));
s="ਪੰਜਾਬੀ";Log.d("~~~","=="+s+"=="+Util.isSupported(this, s));
s="Հայերեն";Log.d("~~~","=="+s+"=="+Util.isSupported(this, s));
Output:
====false
==中文==true
==ਪੰਜਾਬੀ==false
==Հայերեն==true
PS If you want to show both English and native name in the same string, you can either check that the native name may be displayed before composing a string with both names, or remove the Latin characters:
public static String stripLatin(String s) {
String res = "";
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) > 127) {
res += s.charAt(i);
}
}
return res;
}
Testing code:
s="Punjabi(ਪੰਜਾਬੀ)";Log.d("~~~","=="+s+"=="+Util.isSupported(this, Util.stripLatin(s)));
According to this, there is no direct way to do what you want. There's a method proposed in that answer to compare drawn glyphs, but there is no programmatic, simple way to do it.
Another way would be to look at which languages are supported by preinstalled fonts. Starting from Froyo and up, the standard typefaces on Android are Roboto and Noto--Roboto for "English-like" language characters, and Noto for everything else. You can find the full list of Roboto-supported characters here. Then there's Noto, which is designed specifically to prevent those weird blocky "tofu" characters that happen when a character can't be displayed. You can find a list of supported Noto languages here. Supposedly every language has at least basic Noto font support, with the ability to support more complex fonts (serifs, etc.) upon custom installation. This is a helpful guide in seeing what kind of fonts can be supported for each language type.
According to this, besides the "English-like" Roboto, the main Noto font installed on default systems is NotoSerif-Regular. You can confirm this by going to your own system_fonts.xml
to see what's installed there. Another multi-language font is called Droid Sans
, and here is a list of the languages that it supports.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With