Index: third_party/WebKit/Source/platform/fonts/FontFallbackList.cpp |
diff --git a/third_party/WebKit/Source/platform/fonts/FontFallbackList.cpp b/third_party/WebKit/Source/platform/fonts/FontFallbackList.cpp |
index 2840a61a4330ecf81b1610978817d38652cd573d..3de39caf2ece4bded7c0a9d3eedadfdec5590aef 100644 |
--- a/third_party/WebKit/Source/platform/fonts/FontFallbackList.cpp |
+++ b/third_party/WebKit/Source/platform/fonts/FontFallbackList.cpp |
@@ -150,12 +150,43 @@ const SimpleFontData* FontFallbackList::determinePrimarySimpleFontData(const Fon |
} |
} |
+unsigned evaluateFontMatch(const FontDescription& desiredFont, PassRefPtr<FontData> actualFont) |
+{ |
+ const SkFontStyle& actualStyle = actualFont->fontDataForCharacter(' ')->platformData().typeface()->fontStyle(); |
+ // TODO: use desiredFont.skiaFontStyle(); |
+ |
+ // Blink maps font weights into [0,8], with 3 being 'normal' (400). |
+ // Skia maps the same font weights into [100,900] with 400 being 'normal'. |
+ int fontWeightScore = abs((desiredFont.weight() + 1) - (actualStyle.weight() / 100)); |
+ if (fontWeightScore == 1) |
+ fontWeightScore = 0; // Allow for a small amount of tolerance. |
+ if (fontWeightScore > 3) |
+ fontWeightScore *= 10; // Larger weight differenecs are disproportionately bad. |
+ |
+ int fontStretchScore = abs(desiredFont.stretch() - actualStyle.width()); // Skia and Blink agree on the definition of font stretch |
+ if (fontStretchScore == 1) |
+ fontStretchScore = 0; // Allow for a small amount of tolerance. |
+ if (fontStretchScore > 3) |
+ fontStretchScore *= 3; // Larger stretch differences are bad, but not as noticeable as weight differences. |
+ |
+ // We allow italic and oblique to substitute for each other, but substituting either for upright/normal is undesirable. |
+ int fontSlantScore = 0; |
+ if ((desiredFont.style() == FontStyleNormal) != (actualStyle.slant() == SkFontStyle::kUpright_Slant)) |
+ fontSlantScore += 50; |
+ |
+ return fontWeightScore + fontStretchScore + fontSlantScore; |
+} |
+ |
PassRefPtr<FontData> FontFallbackList::getFontData(const FontDescription& fontDescription, int& familyIndex) const |
{ |
const FontFamily* currFamily = &fontDescription.family(); |
for (int i = 0; currFamily && i < familyIndex; i++) |
currFamily = currFamily->next(); |
+ int bestMatchIndex = cAllFamiliesScanned; |
+ unsigned bestMatchScore = UINT_MAX; |
+ RefPtr<FontData> bestMatch; |
+ |
for (; currFamily; currFamily = currFamily->next()) { |
familyIndex++; |
if (currFamily->family().length()) { |
@@ -164,10 +195,22 @@ PassRefPtr<FontData> FontFallbackList::getFontData(const FontDescription& fontDe |
result = m_fontSelector->getFontData(fontDescription, currFamily->family()); |
if (!result) |
result = FontCache::fontCache()->getFontData(fontDescription, currFamily->family()); |
- if (result) |
- return result.release(); |
+ if (result) { |
+ unsigned fontMatchScore = evaluateFontMatch(fontDescription, result); |
+ if (fontMatchScore == 0) |
+ return result.release(); |
+ if (fontMatchScore < bestMatchScore) { |
+ bestMatch = result; |
+ bestMatchScore = fontMatchScore; |
+ bestMatchIndex = familyIndex; |
+ } |
+ } |
} |
} |
+ if (bestMatchScore != UINT_MAX) { |
+ familyIndex = bestMatchIndex; |
+ return bestMatch.release(); |
+ } |
familyIndex = cAllFamiliesScanned; |
if (m_fontSelector) { |