Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(23)

Unified Diff: chrome/browser/ui/prefs/prefs_tab_helper.cc

Issue 10534057: Use ICU to get the script of the browser's locale. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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);
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698