Index: src/core/SkFontMgr.cpp |
diff --git a/src/core/SkFontMgr.cpp b/src/core/SkFontMgr.cpp |
index 3190825c0fd4ca9d0bcd7378c877b21649ca1104..524691646399c5716b4c6c57d4880c27d31c9529 100644 |
--- a/src/core/SkFontMgr.cpp |
+++ b/src/core/SkFontMgr.cpp |
@@ -165,3 +165,104 @@ SkFontMgr* SkFontMgr::RefDefault() { |
return fm ? fm : new SkEmptyFontMgr; |
})); |
} |
+ |
+/** |
+* Width has the greatest priority. |
+* If the value of pattern.width is 5 (normal) or less, |
+* narrower width values are checked first, then wider values. |
+* If the value of pattern.width is greater than 5 (normal), |
+* wider values are checked first, followed by narrower values. |
+* |
+* Italic/Oblique has the next highest priority. |
+* If italic requested and there is some italic font, use it. |
+* If oblique requested and there is some oblique font, use it. |
+* If italic requested and there is some oblique font, use it. |
+* If oblique requested and there is some italic font, use it. |
+* |
+* Exact match. |
+* If pattern.weight < 400, weights below pattern.weight are checked |
+* in descending order followed by weights above pattern.weight |
+* in ascending order until a match is found. |
+* If pattern.weight > 500, weights above pattern.weight are checked |
+* in ascending order followed by weights below pattern.weight |
+* in descending order until a match is found. |
+* If pattern.weight is 400, 500 is checked first |
+* and then the rule for pattern.weight < 400 is used. |
+* If pattern.weight is 500, 400 is checked first |
+* and then the rule for pattern.weight < 400 is used. |
+*/ |
+SkTypeface* SkFontStyleSet::matchStyleCSS3(const SkFontStyle& pattern) { |
+ int count = this->count(); |
+ if (0 == count) { |
+ return nullptr; |
+ } |
+ |
+ struct Score { |
+ int score; |
+ int index; |
+ }; |
+ |
+ Score maxScore = { 0, 0 }; |
+ for (int i = 0; i < count; ++i) { |
+ SkFontStyle current; |
+ this->getStyle(i, ¤t, nullptr); |
+ Score currentScore = { 0, i }; |
+ |
+ // CSS stretch. (This is the width.) |
+ // This has the highest priority. |
+ if (pattern.width() <= SkFontStyle::kNormal_Width) { |
+ if (current.width() <= pattern.width()) { |
+ currentScore.score += 10 - pattern.width() + current.width(); |
+ } else { |
+ currentScore.score += 10 - current.width(); |
+ } |
+ } else { |
+ if (current.width() > pattern.width()) { |
+ currentScore.score += 10 + pattern.width() - current.width(); |
+ } else { |
+ currentScore.score += current.width(); |
+ } |
+ } |
+ currentScore.score *= 1002; |
+ |
+ // CSS style (italic/oblique) |
+ // Being italic trumps all valid weights which are not italic. |
+ // Note that newer specs differentiate between italic and oblique. |
+ if (pattern.isItalic() == current.isItalic()) { |
+ currentScore.score += 1001; |
+ } |
+ |
+ // Synthetics (weight/style) [no stretch synthetic?] |
+ |
+ // The 'closer' to the target weight, the higher the score. |
+ // 1000 is the 'heaviest' recognized weight |
+ if (pattern.weight() == current.weight()) { |
+ currentScore.score += 1000; |
+ } else if (pattern.weight() <= 500) { |
+ if (400 <= pattern.weight() && pattern.weight() < 450) { |
+ if (450 <= current.weight() && current.weight() <= 500) { |
+ // Artificially boost the 500 weight. |
+ // TODO: determine correct number to use. |
+ currentScore.score += 500; |
+ } |
+ } |
+ if (current.weight() <= pattern.weight()) { |
+ currentScore.score += 1000 - pattern.weight() + current.weight(); |
+ } else { |
+ currentScore.score += 1000 - current.weight(); |
+ } |
+ } else if (pattern.weight() > 500) { |
+ if (current.weight() > pattern.weight()) { |
+ currentScore.score += 1000 + pattern.weight() - current.weight(); |
+ } else { |
+ currentScore.score += current.weight(); |
+ } |
+ } |
+ |
+ if (currentScore.score > maxScore.score) { |
+ maxScore = currentScore; |
+ } |
+ } |
+ |
+ return this->createTypeface(maxScore.index); |
+} |