Index: third_party/WebKit/Source/platform/fonts/skia/FontCacheSkia.cpp |
diff --git a/third_party/WebKit/Source/platform/fonts/skia/FontCacheSkia.cpp b/third_party/WebKit/Source/platform/fonts/skia/FontCacheSkia.cpp |
index b0acb93ae827f9027dc7e10cd064062910bb43ba..ab4dd06b3666ebc22fc6a23ed1cd6d95b9423d1b 100644 |
--- a/third_party/WebKit/Source/platform/fonts/skia/FontCacheSkia.cpp |
+++ b/third_party/WebKit/Source/platform/fonts/skia/FontCacheSkia.cpp |
@@ -31,6 +31,8 @@ |
#include "SkFontMgr.h" |
#include "SkStream.h" |
#include "SkTypeface.h" |
+#include "platform/Language.h" |
+#include "platform/fonts/AcceptLanguagesResolver.h" |
#include "platform/fonts/AlternateFontFamily.h" |
#include "platform/fonts/FontCache.h" |
#include "platform/fonts/FontDescription.h" |
@@ -58,6 +60,64 @@ static PassRefPtr<SkTypeface> typefaceForFontconfigInterfaceIdAndTtcIndex(int fo |
namespace blink { |
+// Android special locale for retrieving the color emoji font |
+// based on the proposed changes in UTR #51 for introducing |
+// an Emoji script code: |
+// http://www.unicode.org/reports/tr51/proposed.html#Emoji_Script |
+static const char* kAndroidColorEmojiLocale = "und-Zsye"; |
+ |
+// SkFontMgr requires script-based locale names, like "zh-Hant" and "zh-Hans", |
+// instead of "zh-CN" and "zh-TW". |
+static CString toSkFontMgrLocale(const String& locale) |
+{ |
+ if (!locale.startsWith("zh", TextCaseInsensitive)) |
+ return locale.ascii(); |
+ |
+ switch (localeToScriptCodeForFontSelection(locale)) { |
+ case USCRIPT_SIMPLIFIED_HAN: |
+ return "zh-Hans"; |
+ case USCRIPT_TRADITIONAL_HAN: |
+ return "zh-Hant"; |
+ default: |
+ return locale.ascii(); |
+ } |
+} |
+ |
+#if OS(ANDROID) || OS(LINUX) |
+// This function is called on android or when we are emulating android fonts on linux and the |
+// embedder has overriden the default fontManager with WebFontRendering::setSkiaFontMgr. |
+// static |
+AtomicString FontCache::getFamilyNameForCharacter(SkFontMgr* fm, UChar32 c, const FontDescription& fontDescription, FontFallbackPriority fallbackPriority) |
+{ |
+ ASSERT(fm); |
+ |
+ const size_t kMaxLocales = 4; |
+ const char* bcp47Locales[kMaxLocales]; |
+ size_t localeCount = 0; |
+ |
+ if (fallbackPriority == FontFallbackPriority::EmojiEmoji) { |
+ bcp47Locales[localeCount++] = kAndroidColorEmojiLocale; |
+ } |
+ if (const char* hanLocale = AcceptLanguagesResolver::preferredHanSkFontMgrLocale()) |
+ bcp47Locales[localeCount++] = hanLocale; |
+ CString defaultLocale = toSkFontMgrLocale(defaultLanguage()); |
+ bcp47Locales[localeCount++] = defaultLocale.data(); |
+ CString fontLocale; |
+ if (!fontDescription.locale().isEmpty()) { |
+ fontLocale = toSkFontMgrLocale(fontDescription.locale()); |
+ bcp47Locales[localeCount++] = fontLocale.data(); |
+ } |
+ ASSERT_WITH_SECURITY_IMPLICATION(localeCount < kMaxLocales); |
+ RefPtr<SkTypeface> typeface = adoptRef(fm->matchFamilyStyleCharacter(0, SkFontStyle(), bcp47Locales, localeCount, c)); |
+ if (!typeface) |
+ return emptyAtom; |
+ |
+ SkString skiaFamilyName; |
+ typeface->getFamilyName(&skiaFamilyName); |
+ return skiaFamilyName.c_str(); |
+} |
+#endif |
+ |
void FontCache::platformInit() |
{ |
} |
@@ -111,7 +171,7 @@ PassRefPtr<SimpleFontData> FontCache::getLastResortFallbackFont(const FontDescri |
return fontDataFromFontPlatformData(fontPlatformData, shouldRetain); |
} |
-#if OS(WIN) |
+#if OS(WIN) || OS(LINUX) |
static inline SkFontStyle fontStyle(const FontDescription& fontDescription) |
{ |
int width = static_cast<int>(fontDescription.stretch()); |
@@ -172,6 +232,14 @@ PassRefPtr<SkTypeface> FontCache::createTypeface(const FontDescription& fontDesc |
} |
#endif |
+#if OS(LINUX) |
+ // On linux if the fontManager has been overridden then we should be calling the embedder |
+ // provided font Manager rather than calling SkTypeface::CreateFromName which may redirect the |
+ // call to the default font Manager. |
+ if (m_fontManager) |
+ return adoptRef(m_fontManager->matchFamilyStyle(name.data(), fontStyle(fontDescription))); |
+#endif |
+ |
// FIXME: Use m_fontManager, SkFontStyle and matchFamilyStyle instead of |
// CreateFromName on all platforms. |
return adoptRef(SkTypeface::CreateFromName(name.data(), static_cast<SkTypeface::Style>(style))); |