OLD | NEW |
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 Loading... |
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, ¤t, 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 } |
OLD | NEW |