Index: chrome/browser/ui/prefs/prefs_tab_helper.cc |
diff --git a/chrome/browser/ui/prefs/prefs_tab_helper.cc b/chrome/browser/ui/prefs/prefs_tab_helper.cc |
index 5b76d3494b0a604b997874e7a15921aedc239451..f7033909083b34fcbe47a202e276ec0569a58eee 100644 |
--- a/chrome/browser/ui/prefs/prefs_tab_helper.cc |
+++ b/chrome/browser/ui/prefs/prefs_tab_helper.cc |
@@ -23,6 +23,8 @@ |
#include "content/public/browser/web_contents.h" |
#include "grit/locale_settings.h" |
#include "grit/platform_locale_settings.h" |
+#include "unicode/uchar.h" |
+#include "unicode/uscript.h" |
#include "webkit/glue/webpreferences.h" |
using content::WebContents; |
@@ -134,111 +136,127 @@ void RegisterFontFamilyMapObserver(PrefChangeRegistrar* registrar, |
struct FontDefault { |
const char* pref_name; |
int resource_id; |
- |
- // The locale that matches the script this default pref is for. May be a |
- // comma-separated list. For example, for a Cyrillic font pref, |
- // |native_locale| is something like "sr,ru" (Serbian and Russian). When the |
- // locale of the browser process is in |native_locale|, the default is not |
- // registered to avoid overriding the user's font pref (see comments in |
- // PrefTabsHelper::RegisterUserPrefs). When |native_locale| is the empty |
- // string, the default is registered regardless of locale. |
- const char* native_locale; |
}; |
-// Locales that match Cyrllic script, according to ICU data. Only define |
-// |kCyrllicLocales| on platforms it's used on to avoid compiler error. |
-#if defined(OS_WIN) |
-const char* kCyrllicLocales = "be,bg,kk,mk,ru,sr,uk,uz"; |
-#endif |
- |
// Font pref defaults. The prefs that have defaults vary by platform, since not |
// all platforms have fonts for all scripts for all generic families. |
// TODO(falken): add proper defaults when possible for all |
// platforms/scripts/generic families. |
const FontDefault kFontDefaults[] = { |
- { prefs::kWebKitStandardFontFamily, IDS_STANDARD_FONT_FAMILY, "" }, |
- { prefs::kWebKitFixedFontFamily, IDS_FIXED_FONT_FAMILY, "" }, |
- { prefs::kWebKitSerifFontFamily, IDS_SERIF_FONT_FAMILY, "" }, |
- { prefs::kWebKitSansSerifFontFamily, IDS_SANS_SERIF_FONT_FAMILY, "" }, |
- { prefs::kWebKitCursiveFontFamily, IDS_CURSIVE_FONT_FAMILY, "" }, |
- { prefs::kWebKitFantasyFontFamily, IDS_FANTASY_FONT_FAMILY, "" }, |
+ { prefs::kWebKitStandardFontFamily, IDS_STANDARD_FONT_FAMILY }, |
+ { prefs::kWebKitFixedFontFamily, IDS_FIXED_FONT_FAMILY }, |
+ { prefs::kWebKitSerifFontFamily, IDS_SERIF_FONT_FAMILY }, |
+ { prefs::kWebKitSansSerifFontFamily, IDS_SANS_SERIF_FONT_FAMILY }, |
+ { prefs::kWebKitCursiveFontFamily, IDS_CURSIVE_FONT_FAMILY }, |
+ { prefs::kWebKitFantasyFontFamily, IDS_FANTASY_FONT_FAMILY }, |
#if defined(OS_CHROMEOS) || defined(OS_MACOSX) || defined(OS_WIN) |
{ prefs::kWebKitStandardFontFamilyJapanese, |
- IDS_STANDARD_FONT_FAMILY_JAPANESE, "ja" }, |
- { prefs::kWebKitFixedFontFamilyJapanese, IDS_FIXED_FONT_FAMILY_JAPANESE, |
- "ja" }, |
- { prefs::kWebKitSerifFontFamilyJapanese, IDS_SERIF_FONT_FAMILY_JAPANESE, |
- "ja" }, |
+ IDS_STANDARD_FONT_FAMILY_JAPANESE }, |
+ { prefs::kWebKitFixedFontFamilyJapanese, IDS_FIXED_FONT_FAMILY_JAPANESE }, |
+ { prefs::kWebKitSerifFontFamilyJapanese, IDS_SERIF_FONT_FAMILY_JAPANESE }, |
{ prefs::kWebKitSansSerifFontFamilyJapanese, |
- IDS_SANS_SERIF_FONT_FAMILY_JAPANESE, "ja" }, |
- { prefs::kWebKitStandardFontFamilyKorean, IDS_STANDARD_FONT_FAMILY_KOREAN, |
- "ko" }, |
- { prefs::kWebKitSerifFontFamilyKorean, IDS_SERIF_FONT_FAMILY_KOREAN, "ko" }, |
+ IDS_SANS_SERIF_FONT_FAMILY_JAPANESE }, |
+ { prefs::kWebKitStandardFontFamilyKorean, IDS_STANDARD_FONT_FAMILY_KOREAN }, |
+ { prefs::kWebKitSerifFontFamilyKorean, IDS_SERIF_FONT_FAMILY_KOREAN }, |
{ prefs::kWebKitSansSerifFontFamilyKorean, |
- IDS_SANS_SERIF_FONT_FAMILY_KOREAN, "ko" }, |
+ IDS_SANS_SERIF_FONT_FAMILY_KOREAN }, |
{ prefs::kWebKitStandardFontFamilySimplifiedHan, |
- IDS_STANDARD_FONT_FAMILY_SIMPLIFIED_HAN, "zh-CN" }, |
+ IDS_STANDARD_FONT_FAMILY_SIMPLIFIED_HAN }, |
{ prefs::kWebKitSerifFontFamilySimplifiedHan, |
- IDS_SERIF_FONT_FAMILY_SIMPLIFIED_HAN, "zh-CN" }, |
+ IDS_SERIF_FONT_FAMILY_SIMPLIFIED_HAN }, |
{ prefs::kWebKitSansSerifFontFamilySimplifiedHan, |
- IDS_SANS_SERIF_FONT_FAMILY_SIMPLIFIED_HAN, "zh-CN" }, |
+ IDS_SANS_SERIF_FONT_FAMILY_SIMPLIFIED_HAN }, |
{ prefs::kWebKitStandardFontFamilyTraditionalHan, |
- IDS_STANDARD_FONT_FAMILY_TRADITIONAL_HAN, "zh-TW" }, |
+ IDS_STANDARD_FONT_FAMILY_TRADITIONAL_HAN }, |
{ prefs::kWebKitSerifFontFamilyTraditionalHan, |
- IDS_SERIF_FONT_FAMILY_TRADITIONAL_HAN, "zh-TW" }, |
+ IDS_SERIF_FONT_FAMILY_TRADITIONAL_HAN }, |
{ prefs::kWebKitSansSerifFontFamilyTraditionalHan, |
- IDS_SANS_SERIF_FONT_FAMILY_TRADITIONAL_HAN, "zh-TW" }, |
+ IDS_SANS_SERIF_FONT_FAMILY_TRADITIONAL_HAN }, |
#endif |
#if defined(OS_CHROMEOS) |
- { prefs::kWebKitStandardFontFamilyArabic, IDS_STANDARD_FONT_FAMILY_ARABIC, |
- "ar" }, |
- { prefs::kWebKitSerifFontFamilyArabic, IDS_SERIF_FONT_FAMILY_ARABIC, "ar" }, |
+ { prefs::kWebKitStandardFontFamilyArabic, IDS_STANDARD_FONT_FAMILY_ARABIC }, |
+ { prefs::kWebKitSerifFontFamilyArabic, IDS_SERIF_FONT_FAMILY_ARABIC }, |
{ prefs::kWebKitSansSerifFontFamilyArabic, |
- IDS_SANS_SERIF_FONT_FAMILY_ARABIC, "ar" }, |
- { prefs::kWebKitFixedFontFamilyKorean, IDS_FIXED_FONT_FAMILY_KOREAN, "ko" }, |
+ IDS_SANS_SERIF_FONT_FAMILY_ARABIC }, |
+ { prefs::kWebKitFixedFontFamilyKorean, IDS_FIXED_FONT_FAMILY_KOREAN }, |
{ prefs::kWebKitFixedFontFamilySimplifiedHan, |
- IDS_FIXED_FONT_FAMILY_SIMPLIFIED_HAN, "zh-CN" }, |
+ IDS_FIXED_FONT_FAMILY_SIMPLIFIED_HAN }, |
{ prefs::kWebKitFixedFontFamilyTraditionalHan, |
- IDS_FIXED_FONT_FAMILY_TRADITIONAL_HAN, "zh-TW" }, |
+ IDS_FIXED_FONT_FAMILY_TRADITIONAL_HAN }, |
#elif defined(OS_WIN) |
{ prefs::kWebKitStandardFontFamilyCyrillic, |
- IDS_STANDARD_FONT_FAMILY_CYRILLIC, kCyrllicLocales }, |
- { prefs::kWebKitFixedFontFamilyCyrillic, |
- IDS_FIXED_FONT_FAMILY_CYRILLIC, kCyrllicLocales }, |
- { prefs::kWebKitSerifFontFamilyCyrillic, |
- IDS_SERIF_FONT_FAMILY_CYRILLIC, kCyrllicLocales }, |
+ IDS_STANDARD_FONT_FAMILY_CYRILLIC }, |
+ { prefs::kWebKitFixedFontFamilyCyrillic, IDS_FIXED_FONT_FAMILY_CYRILLIC }, |
+ { prefs::kWebKitSerifFontFamilyCyrillic, IDS_SERIF_FONT_FAMILY_CYRILLIC }, |
{ prefs::kWebKitSansSerifFontFamilyCyrillic, |
- IDS_SANS_SERIF_FONT_FAMILY_CYRILLIC, kCyrllicLocales }, |
- { prefs::kWebKitStandardFontFamilyGreek, |
- IDS_STANDARD_FONT_FAMILY_GREEK, "el" }, |
- { prefs::kWebKitFixedFontFamilyGreek, IDS_FIXED_FONT_FAMILY_GREEK, "el" }, |
- { prefs::kWebKitSerifFontFamilyGreek, IDS_SERIF_FONT_FAMILY_GREEK, "el" }, |
- { prefs::kWebKitSansSerifFontFamilyGreek, |
- IDS_SANS_SERIF_FONT_FAMILY_GREEK, "el" }, |
- { prefs::kWebKitFixedFontFamilyKorean, IDS_FIXED_FONT_FAMILY_KOREAN, "ko" }, |
- { prefs::kWebKitCursiveFontFamilyKorean, IDS_CURSIVE_FONT_FAMILY_KOREAN, |
- "ko" }, |
+ IDS_SANS_SERIF_FONT_FAMILY_CYRILLIC }, |
+ { prefs::kWebKitStandardFontFamilyGreek, IDS_STANDARD_FONT_FAMILY_GREEK }, |
+ { prefs::kWebKitFixedFontFamilyGreek, IDS_FIXED_FONT_FAMILY_GREEK }, |
+ { prefs::kWebKitSerifFontFamilyGreek, IDS_SERIF_FONT_FAMILY_GREEK }, |
+ { prefs::kWebKitSansSerifFontFamilyGreek, IDS_SANS_SERIF_FONT_FAMILY_GREEK }, |
+ { prefs::kWebKitFixedFontFamilyKorean, IDS_FIXED_FONT_FAMILY_KOREAN }, |
+ { prefs::kWebKitCursiveFontFamilyKorean, IDS_CURSIVE_FONT_FAMILY_KOREAN }, |
{ prefs::kWebKitFixedFontFamilySimplifiedHan, |
- IDS_FIXED_FONT_FAMILY_SIMPLIFIED_HAN, "zh-CN" }, |
+ IDS_FIXED_FONT_FAMILY_SIMPLIFIED_HAN }, |
{ prefs::kWebKitFixedFontFamilyTraditionalHan, |
- IDS_FIXED_FONT_FAMILY_TRADITIONAL_HAN, "zh-TW" }, |
+ IDS_FIXED_FONT_FAMILY_TRADITIONAL_HAN }, |
#endif |
}; |
const size_t kFontDefaultsLength = arraysize(kFontDefaults); |
-// Returns true if |locale| matches a string in comma-separated list |
-// |locale_list|. |
-static bool MatchesLocale(const std::string& locale, |
- const std::string& locale_list) { |
- std::vector<std::string> list; |
- base::SplitString(locale_list, ',', &list); |
- for (std::vector<std::string>::const_iterator iter = list.begin(); |
- iter != list.end(); ++iter) { |
- if (StartsWithASCII(locale, *iter, false)) |
- return true; |
+// Returns the script of the font pref |pref_name|. For example, suppose |
+// |pref_name| is "webkit.webprefs.fonts.serif.Hant". Since the script code for |
+// the script name "Hant" is USCRIPT_TRADITIONAL_HAN, the function returns |
+// USCRIPT_TRADITIONAL_HAN. |pref_name| must be a valid font pref name. |
+UScriptCode GetScriptOfFontPref(const char* pref_name) { |
+ // ICU script names are four letters. |
+ static const size_t kScriptNameLength = 4; |
+ |
+ size_t len = strlen(pref_name); |
+ DCHECK(len > kScriptNameLength); |
+ const char* scriptName = &pref_name[len - kScriptNameLength]; |
+ int32 code = u_getPropertyValueEnum(UCHAR_SCRIPT, scriptName); |
+ DCHECK(code >= 0 && code < USCRIPT_CODE_LIMIT); |
+ return (UScriptCode) code; |
+} |
+ |
+// If |scriptCode| is a member of a family of "similar" script codes, returns |
+// the script code in that family that is used in font pref names. For example, |
+// USCRIPT_HANGUL and USCRIPT_KOREAN are considered equivalent for the purposes |
+// of font selection. Chrome uses the script code USCRIPT_HANGUL (script name |
+// "Hang") in Korean font pref names (for example, |
+// "webkit.webprefs.fonts.serif.Hang"). So, if |scriptCode| is USCRIPT_KOREAN, |
+// the function returns USCRIPT_HANGUL. If |scriptCode| is not a member of such |
+// a family, returns |scriptCode|. |
+UScriptCode GetScriptForFontPrefMatching(UScriptCode scriptCode) { |
+ switch (scriptCode) { |
+ case USCRIPT_HIRAGANA: |
+ case USCRIPT_KATAKANA: |
+ case USCRIPT_JAPANESE: |
+ return USCRIPT_KATAKANA_OR_HIRAGANA; |
+ case USCRIPT_KOREAN: |
+ return USCRIPT_HANGUL; |
+ default: |
+ return scriptCode; |
} |
- return false; |
+} |
+ |
+// Returns the primary script used by the browser's locale. For example, if the |
+// locale is "ru", the function returns USCRIPT_CYRILLIC, and if the locale is |
+// "en", the function returns USCRIPT_LATIN. |
+UScriptCode GetScriptOfBrowserLocale() { |
+ std::string locale = g_browser_process->GetApplicationLocale(); |
+ |
+ UScriptCode code = USCRIPT_INVALID_CODE; |
+ UErrorCode err = U_ZERO_ERROR; |
+ uscript_getCode(locale.c_str(), &code, 1, &err); |
+ |
+ // Ignore the error that multiple scripts could be returned, since we only |
+ // want one script. |
+ if (U_FAILURE(err) && err != U_BUFFER_OVERFLOW_ERROR) |
+ code = USCRIPT_INVALID_CODE; |
+ return GetScriptForFontPrefMatching(code); |
} |
const struct { |
@@ -415,17 +433,24 @@ void PrefsTabHelper::RegisterUserPrefs(PrefService* prefs) { |
PrefService::SYNCABLE_PREF); |
// Register font prefs that have defaults. |
- std::string locale = g_browser_process->GetApplicationLocale(); |
+ UScriptCode browser_script = GetScriptOfBrowserLocale(); |
for (size_t i = 0; i < kFontDefaultsLength; ++i) { |
const FontDefault& pref = kFontDefaults[i]; |
- // Suppress default per-script font when the script matches the browser's |
- // locale. Otherwise, the default would override the user's preferences |
- // when viewing pages in their native language. This would be bad |
- // particularly because there is not yet a way for users to customize |
- // their per-script font prefs. This code can possibly be removed later if |
- // users can easily access per-script font prefs (e.g., via the extensions |
- // workflow), or the problem turns out to not be really critical after all. |
- if (!MatchesLocale(locale, pref.native_locale)) { |
+ UScriptCode pref_script = GetScriptOfFontPref(pref.pref_name); |
+ |
+ // Suppress this default font pref value if the script it is for is the |
+ // primary script of the browser's locale. For example, if the pref is for |
jungshik at Google
2012/06/11 19:56:29
I think "If the script it is for .... locale" can
falken
2012/06/12 01:47:57
Done.
|
+ // the sans-serif font for the Cyrillic script, and the browser locale is |
+ // "ru" (Russian), the default is suppressed. Otherwise, the default would |
+ // override the user's font preferences when viewing pages in their native |
+ // language. This is because users have no way yet of customizing their |
+ // per-script font preferences. The font prefs accessible in the options UI |
+ // are for the default, unknown script; these prefs have less priority than |
+ // the per-script font prefs when the script of the content is known. This |
+ // code can possibly be removed later if users can easily access per-script |
+ // font prefs (e.g., via the extensions workflow), or the problem turns out |
+ // to not be really critical after all. |
+ if (browser_script != pref_script) { |
prefs->RegisterLocalizedStringPref(pref.pref_name, |
pref.resource_id, |
PrefService::UNSYNCABLE_PREF); |