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

Side by Side Diff: third_party/WebKit/Source/platform/LayoutLocale.cpp

Issue 2192703002: More LayoutLocale refactor with additional Chinese support (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Comment updated as per drott review Created 4 years, 4 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 unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "platform/LayoutLocale.h" 5 #include "platform/LayoutLocale.h"
6 6
7 #include "platform/Language.h" 7 #include "platform/Language.h"
8 #include "platform/text/LocaleToScriptMapping.h" 8 #include "platform/text/LocaleToScriptMapping.h"
9 #include "wtf/HashMap.h" 9 #include "wtf/HashMap.h"
10 #include "wtf/text/AtomicStringHash.h" 10 #include "wtf/text/AtomicStringHash.h"
11 #include "wtf/text/StringHash.h" 11 #include "wtf/text/StringHash.h"
12 12
13 #include <hb.h> 13 #include <hb.h>
14 #include <unicode/locid.h>
14 15
15 namespace blink { 16 namespace blink {
16 17
17 const LayoutLocale* LayoutLocale::s_default = nullptr; 18 const LayoutLocale* LayoutLocale::s_default = nullptr;
19 const LayoutLocale* LayoutLocale::s_system = nullptr;
20 const LayoutLocale* LayoutLocale::s_defaultForHan = nullptr;
21 bool LayoutLocale::s_defaultForHanComputed = false;
18 22
19 static hb_language_t toHarfbuzLanguage(const AtomicString& locale) 23 static hb_language_t toHarfbuzLanguage(const AtomicString& locale)
20 { 24 {
21 CString localeAsLatin1 = locale.latin1(); 25 CString localeAsLatin1 = locale.latin1();
22 return hb_language_from_string(localeAsLatin1.data(), localeAsLatin1.length( )); 26 return hb_language_from_string(localeAsLatin1.data(), localeAsLatin1.length( ));
23 } 27 }
24 28
25 // SkFontMgr requires script-based locale names, like "zh-Hant" and "zh-Hans", 29 // SkFontMgr requires script-based locale names, like "zh-Hant" and "zh-Hans",
26 // instead of "zh-CN" and "zh-TW". 30 // instead of "zh-CN" and "zh-TW".
27 static CString toSkFontMgrLocale(const String& locale) 31 static const char* toSkFontMgrLocale(UScriptCode script)
28 { 32 {
29 if (!locale.startsWith("zh", TextCaseInsensitive)) 33 switch (script) {
30 return locale.ascii(); 34 case USCRIPT_KATAKANA_OR_HIRAGANA:
31 35 return "ja-JP";
32 switch (localeToScriptCodeForFontSelection(locale)) { 36 case USCRIPT_HANGUL:
37 return "ko-KR";
33 case USCRIPT_SIMPLIFIED_HAN: 38 case USCRIPT_SIMPLIFIED_HAN:
34 return "zh-Hans"; 39 return "zh-Hans";
35 case USCRIPT_TRADITIONAL_HAN: 40 case USCRIPT_TRADITIONAL_HAN:
36 return "zh-Hant"; 41 return "zh-Hant";
37 default: 42 default:
38 return locale.ascii(); 43 return nullptr;
39 } 44 }
40 } 45 }
41 46
42 const CString& LayoutLocale::localeForSkFontMgr() const 47 const char* LayoutLocale::localeForSkFontMgr() const
43 { 48 {
44 if (m_stringForSkFontMgr.isNull()) 49 if (m_stringForSkFontMgr.isNull()) {
45 m_stringForSkFontMgr = toSkFontMgrLocale(m_string); 50 m_stringForSkFontMgr = toSkFontMgrLocale(m_script);
46 return m_stringForSkFontMgr; 51 if (m_stringForSkFontMgr.isNull())
52 m_stringForSkFontMgr = m_string.ascii();
53 }
54 return m_stringForSkFontMgr.data();
55 }
56
57 static bool isUnambiguousHanScript(UScriptCode script)
58 {
59 // localeToScriptCodeForFontSelection() does not return these values.
60 DCHECK(script != USCRIPT_HIRAGANA && script != USCRIPT_KATAKANA);
61 return script == USCRIPT_KATAKANA_OR_HIRAGANA
62 || script == USCRIPT_SIMPLIFIED_HAN
63 || script == USCRIPT_TRADITIONAL_HAN
64 || script == USCRIPT_HANGUL;
65 }
66
67 void LayoutLocale::computeScriptForHan() const
68 {
69 if (isUnambiguousHanScript(m_script)) {
70 m_scriptForHan = m_script;
71 m_hasScriptForHan = true;
72 return;
73 }
74
75 m_scriptForHan = scriptCodeForHanFromSubtags(m_string);
76 if (m_scriptForHan == USCRIPT_COMMON)
77 m_scriptForHan = USCRIPT_SIMPLIFIED_HAN;
78 else
79 m_hasScriptForHan = true;
80 DCHECK(isUnambiguousHanScript(m_scriptForHan));
47 } 81 }
48 82
49 UScriptCode LayoutLocale::scriptForHan() const 83 UScriptCode LayoutLocale::scriptForHan() const
50 { 84 {
51 if (m_scriptForHan != USCRIPT_COMMON) 85 if (m_scriptForHan == USCRIPT_COMMON)
52 return m_scriptForHan; 86 computeScriptForHan();
87 return m_scriptForHan;
88 }
53 89
54 m_scriptForHan = scriptCodeForHanFromLocale(script(), localeString()); 90 bool LayoutLocale::hasScriptForHan() const
91 {
55 if (m_scriptForHan == USCRIPT_COMMON) 92 if (m_scriptForHan == USCRIPT_COMMON)
56 m_scriptForHan = USCRIPT_HAN; 93 computeScriptForHan();
57 return m_scriptForHan; 94 return m_hasScriptForHan;
95 }
96
97 const LayoutLocale* LayoutLocale::localeForHan(const LayoutLocale* contentLocale )
98 {
99 if (contentLocale && contentLocale->hasScriptForHan())
100 return contentLocale;
101 if (!s_defaultForHanComputed)
102 setLocaleForHan(nullptr);
103 return s_defaultForHan;
104 }
105
106 void LayoutLocale::setLocaleForHan(const LayoutLocale* locale)
107 {
108 if (locale)
109 s_defaultForHan = locale;
110 else if (getDefault().hasScriptForHan())
111 s_defaultForHan = &getDefault();
112 else if (getSystem().hasScriptForHan())
113 s_defaultForHan = &getSystem();
114 else
115 s_defaultForHan = nullptr;
116 s_defaultForHanComputed = true;
117 }
118
119 const char* LayoutLocale::localeForHanForSkFontMgr() const
120 {
121 const char* locale = toSkFontMgrLocale(scriptForHan());
122 DCHECK(locale);
123 return locale;
58 } 124 }
59 125
60 LayoutLocale::LayoutLocale(const AtomicString& locale) 126 LayoutLocale::LayoutLocale(const AtomicString& locale)
61 : m_string(locale) 127 : m_string(locale)
62 , m_harfbuzzLanguage(toHarfbuzLanguage(locale)) 128 , m_harfbuzzLanguage(toHarfbuzLanguage(locale))
63 , m_script(localeToScriptCodeForFontSelection(locale)) 129 , m_script(localeToScriptCodeForFontSelection(locale))
64 , m_scriptForHan(USCRIPT_COMMON) 130 , m_scriptForHan(USCRIPT_COMMON)
131 , m_hasScriptForHan(false)
65 , m_hyphenationComputed(false) 132 , m_hyphenationComputed(false)
66 { 133 {
67 } 134 }
68 135
69 using LayoutLocaleMap = HashMap<AtomicString, RefPtr<LayoutLocale>, CaseFoldingH ash>; 136 using LayoutLocaleMap = HashMap<AtomicString, RefPtr<LayoutLocale>, CaseFoldingH ash>;
70 137
71 static LayoutLocaleMap& getLocaleMap() 138 static LayoutLocaleMap& getLocaleMap()
72 { 139 {
73 DEFINE_STATIC_LOCAL(LayoutLocaleMap, localeMap, ()); 140 DEFINE_STATIC_LOCAL(LayoutLocaleMap, localeMap, ());
74 return localeMap; 141 return localeMap;
75 } 142 }
76 143
77 const LayoutLocale* LayoutLocale::get(const AtomicString& locale) 144 const LayoutLocale* LayoutLocale::get(const AtomicString& locale)
78 { 145 {
79 if (locale.isNull()) 146 if (locale.isNull())
80 return nullptr; 147 return nullptr;
81 148
82 auto result = getLocaleMap().add(locale, nullptr); 149 auto result = getLocaleMap().add(locale, nullptr);
83 if (result.isNewEntry) 150 if (result.isNewEntry)
84 result.storedValue->value = adoptRef(new LayoutLocale(locale)); 151 result.storedValue->value = adoptRef(new LayoutLocale(locale));
85 return result.storedValue->value.get(); 152 return result.storedValue->value.get();
86 } 153 }
87 154
88 static const LayoutLocale* computeDefaultLocale()
89 {
90 AtomicString locale = defaultLanguage();
91 if (!locale.isEmpty())
92 return LayoutLocale::get(locale);
93 return LayoutLocale::get("en");
94 }
95
96 const LayoutLocale& LayoutLocale::getDefault() 155 const LayoutLocale& LayoutLocale::getDefault()
97 { 156 {
98 if (!s_default) 157 if (s_default)
99 s_default = computeDefaultLocale(); 158 return *s_default;
159
160 AtomicString locale = defaultLanguage();
161 s_default = get(!locale.isEmpty() ? locale : "en");
100 return *s_default; 162 return *s_default;
101 } 163 }
102 164
165 const LayoutLocale& LayoutLocale::getSystem()
166 {
167 if (s_system)
168 return *s_system;
169
170 // Platforms such as Windows can give more information than the default
171 // locale, such as "en-JP" for English speakers in Japan.
172 String name = icu::Locale::getDefault().getName();
173 s_system = get(AtomicString(name.replace('_', '-')));
174 return *s_system;
175 }
176
177 PassRefPtr<LayoutLocale> LayoutLocale::createForTesting(const AtomicString& loca le)
178 {
179 return adoptRef(new LayoutLocale(locale));
180 }
181
103 void LayoutLocale::clearForTesting() 182 void LayoutLocale::clearForTesting()
104 { 183 {
105 s_default = nullptr; 184 s_default = nullptr;
185 s_system = nullptr;
186 s_defaultForHan = nullptr;
187 s_defaultForHanComputed = false;
106 getLocaleMap().clear(); 188 getLocaleMap().clear();
107 } 189 }
108 190
109 Hyphenation* LayoutLocale::getHyphenation() const 191 Hyphenation* LayoutLocale::getHyphenation() const
110 { 192 {
111 if (m_hyphenationComputed) 193 if (m_hyphenationComputed)
112 return m_hyphenation.get(); 194 return m_hyphenation.get();
113 195
114 m_hyphenationComputed = true; 196 m_hyphenationComputed = true;
115 m_hyphenation = Hyphenation::platformGetHyphenation(localeString()); 197 m_hyphenation = Hyphenation::platformGetHyphenation(localeString());
116 return m_hyphenation.get(); 198 return m_hyphenation.get();
117 } 199 }
118 200
119 void LayoutLocale::setHyphenationForTesting(const AtomicString& localeString, Pa ssRefPtr<Hyphenation> hyphenation) 201 void LayoutLocale::setHyphenationForTesting(const AtomicString& localeString, Pa ssRefPtr<Hyphenation> hyphenation)
120 { 202 {
121 const LayoutLocale& locale = valueOrDefault(get(localeString)); 203 const LayoutLocale& locale = valueOrDefault(get(localeString));
122 locale.m_hyphenationComputed = true; 204 locale.m_hyphenationComputed = true;
123 locale.m_hyphenation = hyphenation; 205 locale.m_hyphenation = hyphenation;
124 } 206 }
125 207
126 } // namespace blink 208 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/platform/LayoutLocale.h ('k') | third_party/WebKit/Source/platform/LayoutLocaleTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698