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

Side by Side Diff: src/core/SkFontMgr.cpp

Issue 1438113002: Factor CSS3 matching rules. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Tests can use C++11. Created 5 years, 1 month 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
« no previous file with comments | « include/ports/SkFontMgr.h ('k') | src/fonts/SkFontMgr_indirect.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2015 Google Inc. 2 * Copyright 2015 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkFontDescriptor.h" 8 #include "SkFontDescriptor.h"
9 #include "SkFontMgr.h" 9 #include "SkFontMgr.h"
10 #include "SkOncePtr.h" 10 #include "SkOncePtr.h"
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 return this->onLegacyCreateTypeface(familyName, styleBits); 158 return this->onLegacyCreateTypeface(familyName, styleBits);
159 } 159 }
160 160
161 SK_DECLARE_STATIC_ONCE_PTR(SkFontMgr, singleton); 161 SK_DECLARE_STATIC_ONCE_PTR(SkFontMgr, singleton);
162 SkFontMgr* SkFontMgr::RefDefault() { 162 SkFontMgr* SkFontMgr::RefDefault() {
163 return SkRef(singleton.get([]{ 163 return SkRef(singleton.get([]{
164 SkFontMgr* fm = SkFontMgr::Factory(); 164 SkFontMgr* fm = SkFontMgr::Factory();
165 return fm ? fm : new SkEmptyFontMgr; 165 return fm ? fm : new SkEmptyFontMgr;
166 })); 166 }));
167 } 167 }
168
169 /**
170 * Width has the greatest priority.
171 * If the value of pattern.width is 5 (normal) or less,
172 * narrower width values are checked first, then wider values.
173 * If the value of pattern.width is greater than 5 (normal),
174 * wider values are checked first, followed by narrower values.
175 *
176 * Italic/Oblique has the next highest priority.
177 * If italic requested and there is some italic font, use it.
178 * If oblique requested and there is some oblique font, use it.
179 * If italic requested and there is some oblique font, use it.
180 * If oblique requested and there is some italic font, use it.
181 *
182 * Exact match.
183 * If pattern.weight < 400, weights below pattern.weight are checked
184 * in descending order followed by weights above pattern.weight
185 * in ascending order until a match is found.
186 * If pattern.weight > 500, weights above pattern.weight are checked
187 * in ascending order followed by weights below pattern.weight
188 * in descending order until a match is found.
189 * If pattern.weight is 400, 500 is checked first
190 * and then the rule for pattern.weight < 400 is used.
191 * If pattern.weight is 500, 400 is checked first
192 * and then the rule for pattern.weight < 400 is used.
193 */
194 SkTypeface* SkFontStyleSet::matchStyleCSS3(const SkFontStyle& pattern) {
195 int count = this->count();
196 if (0 == count) {
197 return nullptr;
198 }
199
200 struct Score {
201 int score;
202 int index;
203 };
204
205 Score maxScore = { 0, 0 };
206 for (int i = 0; i < count; ++i) {
207 SkFontStyle current;
208 this->getStyle(i, &current, nullptr);
209 Score currentScore = { 0, i };
210
211 // CSS stretch. (This is the width.)
212 // This has the highest priority.
213 if (pattern.width() <= SkFontStyle::kNormal_Width) {
214 if (current.width() <= pattern.width()) {
215 currentScore.score += 10 - pattern.width() + current.width();
216 } else {
217 currentScore.score += 10 - current.width();
218 }
219 } else {
220 if (current.width() > pattern.width()) {
221 currentScore.score += 10 + pattern.width() - current.width();
222 } else {
223 currentScore.score += current.width();
224 }
225 }
226 currentScore.score *= 1002;
227
228 // CSS style (italic/oblique)
229 // Being italic trumps all valid weights which are not italic.
230 // Note that newer specs differentiate between italic and oblique.
231 if (pattern.isItalic() == current.isItalic()) {
232 currentScore.score += 1001;
233 }
234
235 // Synthetics (weight/style) [no stretch synthetic?]
236
237 // The 'closer' to the target weight, the higher the score.
238 // 1000 is the 'heaviest' recognized weight
239 if (pattern.weight() == current.weight()) {
240 currentScore.score += 1000;
241 } else if (pattern.weight() <= 500) {
242 if (400 <= pattern.weight() && pattern.weight() < 450) {
243 if (450 <= current.weight() && current.weight() <= 500) {
244 // Artificially boost the 500 weight.
245 // TODO: determine correct number to use.
246 currentScore.score += 500;
247 }
248 }
249 if (current.weight() <= pattern.weight()) {
250 currentScore.score += 1000 - pattern.weight() + current.weight() ;
251 } else {
252 currentScore.score += 1000 - current.weight();
253 }
254 } else if (pattern.weight() > 500) {
255 if (current.weight() > pattern.weight()) {
256 currentScore.score += 1000 + pattern.weight() - current.weight() ;
257 } else {
258 currentScore.score += current.weight();
259 }
260 }
261
262 if (currentScore.score > maxScore.score) {
263 maxScore = currentScore;
264 }
265 }
266
267 return this->createTypeface(maxScore.index);
268 }
OLDNEW
« no previous file with comments | « include/ports/SkFontMgr.h ('k') | src/fonts/SkFontMgr_indirect.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698