As I finished the implementing the design on Windows, a localization issue became apparent. By replacing an integer based style (Font::bold) with a string based one (“Bold”) I was not sure the implications of this running on non English versions of Windows.
Windows
I don’t have access to localized versions of Windows 7 so testing that way was out of the question. Thankfully, Microsoft has implemented a system known as the Multilingual User Interface which allows Windows users to change their display language through the use of Language Packs. I installed French and Japanese and fired up the font dialog box in Notepad. As you can see the font styles are all localized to the current display language.
I then fired up a copy of JuceFont. Even thought my display language is clearly set to Japanese, JuceFont displays all the styles in English.
This is not that surprising, since the DirectWrite code always gets strings using the “en-us” locale (it tells FindLocaleName to use “en-us” when retrieving strings from IDWriteLocalizedStrings).
While this is great for English speakers, I’m sure non-English speakers would probably prefer localized font style names. Unfortunately, I have not found a way to obtain these strings. As far as I can see, there is no way to do this from DirectWrite. Although DirectWrite returns IDWriteLocalizedStrings for both font families and font styles, these localized strings are the ones embedded in the font themselves. It is up to the font author to embed these strings and only few authors embed more than an English name. Even the few authors, like Microsoft, that do embed multiple languages, don’t add a string for every language other there.
The font style names shown in the Windows 7 CHOOSEFONT dialog box definitely are not coming from the font itself. When viewing the font table of Segoe UI, you can see that all though there are two French localized strings, there is no Japanese localized string.
This is confirmed by enumerating the fonts in DirectWrite and looking at the IDWriteLocalizedStrings of the font faces. The results of this enumeration can be seen in the text below. The results also show the reason there are two French strings in the image above is because one is for French (Canada) and the other is for French (France).
Segoe UI
face count: 10
locale count: 1
en-us
Light
locale count: 25
ca-es
cs-cz
da-dk
de-de
el-gr
en-us
es-es
es-es_tradnl
es-mx
eu-es
fi-fi
fr-ca
fr-fr
hu-hu
it-it
nb-no
nl-nl
pl-pl
pt-br
pt-pt
ru-ru
sk-sk
sl-si
sv-se
tr-tr
Regular
locale count: 25
ca-es
cs-cz
da-dk
de-de
el-gr
en-us
es-es
es-es_tradnl
es-mx
eu-es
fi-fi
fr-ca
fr-fr
hu-hu
it-it
nb-no
nl-nl
pl-pl
pt-br
pt-pt
ru-ru
sk-sk
sl-si
sv-se
tr-tr
Italic
locale count: 1
en-us
Semibold
locale count: 25
ca-es
cs-cz
da-dk
de-de
el-gr
en-us
es-es
es-es_tradnl
es-mx
eu-es
fi-fi
fr-ca
fr-fr
hu-hu
it-it
nb-no
nl-nl
pl-pl
pt-br
pt-pt
ru-ru
sk-sk
sl-si
sv-se
tr-tr
Bold
locale count: 25
ca-es
cs-cz
da-dk
de-de
el-gr
en-us
es-es
es-es_tradnl
es-mx
eu-es
fi-fi
fr-ca
fr-fr
hu-hu
it-it
nb-no
nl-nl
pl-pl
pt-br
pt-pt
ru-ru
sk-sk
sl-si
sv-se
tr-tr
Bold Italic
locale count: 1
en-us
Light Oblique
locale count: 1
en-us
Oblique
locale count: 1
en-us
Semibold Oblique
locale count: 1
en-us
Bold Oblique
So there is clearly no Japanese localized font style names in the font table or obtainable via DirectWrite. Then where are those string in the CHOOSEFONT dialog coming from? My best guess is from the language packs themselves. I certainly haven’t come across any Win32 APIs that will let me access these strings. I tried using Spy++ to see what was going on in Notepad but the Windows Messages were pretty useless. The last thing I can think of is to use a x86 assembly level debugger on it but I don’t have the time to do that.
Mac
Unlike Windows, I don’t think localized versions of Mac OS X exist. Mac OS X lets you change the display language without requiring you to download any additional language packs. I switched to French and Japanese and fired up the font dialog box in TextEdit. As you can see the font styles are all localized to the current display language.
I am quite puzzled by the results. I’m not sure why some fonts don’t have localized names in certain langauges like the Menlo example. I also find it really odd that Arial wouldn’t have localized font styles in Japanese considering how universal it is.
I then fired up a copy of JuceFont. Even thought my display language is clearly set to Japanese, JuceFont displays all the styles in English.
This confirms that when using CTFontDescriptorCopyAttribute and kFontStyleNameAttribute you will always get the font style in English regardless of the user language.
Changing the call to use CTFontDescriptorCopyLocalizedAttribute and kFontStyleNameAttribute instead gives you the font style in the user’s language.
The following font enumeration was obtained by through Core Text. The results are exactly like the results seen when using the Font dialog with TextEdit.
family: Arial
cfsLocalizedFontStyle: Regular
cfsLocalizedFontStyle: Italic
cfsLocalizedFontStyle: Bold
cfsLocalizedFontStyle: Bold Italic
family: Helvetica
cfsLocalizedFontStyle: レギュラー
cfsLocalizedFontStyle: ライト
cfsLocalizedFontStyle: イタリック
cfsLocalizedFontStyle: ライト・オブリーク
cfsLocalizedFontStyle: ボールド
cfsLocalizedFontStyle: ボールド・イタリック
family: Menlo
cfsLocalizedFontStyle: Regular
cfsLocalizedFontStyle: Italic
cfsLocalizedFontStyle: Bold
cfsLocalizedFontStyle: Bold Italic
So unlike Windows, on Mac OS X and iOS we are able to get the localized font style string via API. However, we are not able to obtain a font using its localized font style string. The only way to obtain a font with a specific font style is to use an English font style string when creating the CTFontDescriptor. According to Apple this is “expected behavior”. So the only way to make it work is create string pairs between localized font styles and English font styles, display the localized font style and finally when a user selects a style, get it’s English counterpart and use that to get the correct font face.
Summary
There is no way to get localized font style names on Windows via API.
We can get localized font style names on Mac OS X and iOS via API.
We cannot used a localized font style name to get a font face on Mac OS X and iOS, we must use an English font style name.
With the updated Juce Font System, all font styles will be displayed in English.
With the updated Juce Font System, font styles which were set in English at compile time will always work at runtime regardless of the user language.
Recommendations
The only way to get localized font styles working on both platforms is to create local files containing font style translation pairs and then use these pairs when displaying font styles (as localized strings) and creating fonts via API (with English strings).