Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Japanese characters looking like Chinese on Android

PREAMBLE: since API 17 (Android 4.2), there's a method TextView.setTextLocale() that explicitly solves this problem for TextViews and derived classes. Assign a Japanese locale (Locale.JAPAN), and Unihan characters will look Japanese.


I have an application on Android that displays Japanese text in WebViews and TextViews. There are some Chinese characters (kanji) that look, by convention, differently in China and in Japan, but share the same Unicode codepoint. Normally, the browser would rely upon the lang tag to choose the correct glyph. On Android, they all default to their Chinese shapes, and I want Japanese shapes.

The problem is well explained in this article. This article also serves as a perfect illustration of the problem - when watched on Android (up to 2.2), the characters in the "Examples of language-dependent characters" all look the same, and Chinese.

Using the lang="ja" attribute does not help. Switching the whole system locale to Japanese does not help either.

I'm wondering about Android phones that are sold in Japan. Do characters like 直, 今, 化 look Chinese-style on those, too? I'm assuming not.

So the questions are: are there official localized images of Android out there? Can I get one to run on the emulator? Is the DroidSansFallback font still the only CJK-enabled font on those? And if it is, is it the same as on the vanilla USA Android?

I'm kind of hoping that the Japanese glyphs are hidden somewhere deep in the font (Unicode private area or something). If so, I could leverage them...

EDIT: located DroidSansJapanese.ttf, installed it on the emulator by copying into /system/fonts, restarted. It made no difference on the look of the Unihan article. Even the hint area of the Japanese text input (which should know better) displays as if Chinese.

How do I know the typeface name of the DroidSansJapanese.ttf? I have a feeling it's still Droid Sans, same as in the built-in DroidSansFallback font. But if they contain the same typeface, what governs which one should take precedence? One would think - system locale, but apparently not. Fonts in Android are installed just by copying, right?

like image 700
Seva Alekseyev Avatar asked Sep 21 '11 16:09

Seva Alekseyev


People also ask

Why do Chinese characters appear on my Android phone?

Some users reported that, upon power up, their device is showing a black screen with Chinese characters and appears to be stuck at that screen. If you are seeing this screen you may have accidentally triggered MTK test mode, by pressing the Volume Down and Power Keys together.

Do Chinese and Japanese characters look the same?

If you're not familiar with Asian scripts, the written form of Korean, Japanese, and Chinese may look the same to you. It is true that Chinese characters are sometimes used in both Korean and Japanese writing. However, the 3 scripts used for these 3 different languages are quite different.

Does Japan use Chinese characters?

Unlike English, both languages incorporate symbols rather than just an alphabet. To be sure, Japanese does have a phonetic alphabet, two in fact. It also uses Chinese characters called kanji. Kanji, as well as Japan's two phonetic alphabets (hiragana and katakana) were derived from Chinese characters.

Do Chinese characters have different fonts?

Chinese has two main styles, called Mingti and Heiti, akin to the serif and sans-serif of Latin. Heiti is a bit like sans-serif: clean, straight lines without extra ornamentation at the ends, common on the web. Mingti is similar to serif, with extra embellishment at the end of strokes that give it a more bookish feel.


2 Answers

There are fonts with full Japanese support. I've heard some people talking about DroidSansJapanese.tff and TakaoPGothic.

like image 186
Mister Smith Avatar answered Sep 21 '22 00:09

Mister Smith


Found a somewhat cludgey solution.

The DroidSansJapanese.ttf font exists and is available for download, for example, here. I downloaded it, renamed it to DroidSansJapanese.mp3 to avoid the 1MB compressed asset limit, and placed it under assets/web. I then introduced the following CSS statement:

@font-face { font-family: "DroidJP"; src:url('DroidSansJapanese.mp3') } 

Then I added 'DroidJP' to the font-family of every relevant CSS style. The way I load my HTML, the assets/web folder is already designated as the base for loading linked content.

Upon careful examination, I found several places in the app where Japanese was in TextViews. For those, I've loaded the typeface like this:

Typeface s_JFont =     Typeface.createFromAsset(Ctxt.getAssets(), "web/DroidSansJapanese.mp3"); 

and called setTypeface() on every relevant TextView. Now for PROFIT!

This expanded my APK by about 1 MB. There was an alternative way, where I'd store the font in the assets in compressed form - that'd save me about 500 KB of APK size, but then I'd have to expand it to phone memory on the first run, worry about data folder path, and lose compatibility with Android 1.5.

Some credit is due: here and here. Does not work on Android 2.1 (the WebViews, not the TextViews) - that's a known bug.

Now, the question remains - how do I identify devices where the default font already contains the Japanese shapes?

EDIT re: the mp3 hack. I've implemented the chunked solution at first, but then decided to go with font in the assets. The chunked approach has one upside - smaller APK size - and the following downsides:

  • Consumes more phone memory - you end up storing both compressed font in assets and uncompressed in the data directory
  • Is incompatible with Android 1.5 on the TextView side - the method Typeface.createFromFile() was introduced in API level 4
  • Complicates HTML generation - the CSS with the @font-face declaration needs to be parametrised, since the data path is a variable
  • Slows down the first app startup - you spend time combining the chunks

Storing the font as a compressed asset is not an option either - the font then doesn't show up in WebView, and you can clearly see in LogCat the message about "Data exceeds UNCOMPRESS_DATA_MAX".

like image 36
Seva Alekseyev Avatar answered Sep 20 '22 00:09

Seva Alekseyev