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 d9af8814f20745f374402948176848edc5db9597..5d6f98beecec62d80c408c1c5298d33e68a163ee 100644 |
--- a/third_party/WebKit/Source/platform/fonts/skia/FontCacheSkia.cpp |
+++ b/third_party/WebKit/Source/platform/fonts/skia/FontCacheSkia.cpp |
@@ -31,6 +31,7 @@ |
#include "SkFontMgr.h" |
#include "SkStream.h" |
#include "SkTypeface.h" |
+#include "platform/Language.h" |
#include "platform/fonts/AlternateFontFamily.h" |
#include "platform/fonts/FontCache.h" |
#include "platform/fonts/FontDescription.h" |
@@ -87,6 +88,51 @@ static PassRefPtr<SkTypeface> typefaceForFontconfigInterfaceIdAndTtcIndex(int fo |
namespace blink { |
+// 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) |
+{ |
+ ASSERT(fm); |
+ |
+ const char* bcp47Locales[2]; |
+ int localeCount = 0; |
+ CString defaultLocale = toSkFontMgrLocale(defaultLanguage()); |
+ bcp47Locales[localeCount++] = defaultLocale.data(); |
+ CString fontLocale; |
+ if (!fontDescription.locale().isEmpty()) { |
+ fontLocale = toSkFontMgrLocale(fontDescription.locale()); |
+ bcp47Locales[localeCount++] = fontLocale.data(); |
+ } |
+ 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() |
{ |
} |
@@ -113,6 +159,19 @@ PassRefPtr<SimpleFontData> FontCache::fallbackOnStandardFontStyle( |
#if !OS(WIN) && !OS(ANDROID) |
PassRefPtr<SimpleFontData> FontCache::fallbackFontForCharacter(const FontDescription& fontDescription, UChar32 c, const SimpleFontData*) |
{ |
+#if OS(LINUX) |
+ // On linux the m_fontManager is set only if it was provided by the embedder with WebFontRendering::setSkiaFontManager. This is |
+ // used to emulate android fonts so we always request the family from the font manager and if none is found, we return |
+ // the LastResort fallback font and avoid using FontCache::getFontForCharacter which would use sandbox support to |
+ // query the underlying system for the font family. |
+ if (m_fontManager) { |
+ AtomicString familyName = getFamilyNameForCharacter(m_fontManager.get(), c, fontDescription); |
+ if (familyName.isEmpty()) |
+ return getLastResortFallbackFont(fontDescription, DoNotRetain); |
+ return fontDataFromFontPlatformData(getFontPlatformData(fontDescription, FontFaceCreationParams(familyName)), DoNotRetain); |
+ } |
+#endif |
+ |
// First try the specified font with standard style & weight. |
if (fontDescription.style() == FontStyleItalic |
|| fontDescription.weight() >= FontWeight600) { |
@@ -277,6 +336,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->legacyCreateTypeface(name.data(), style)); |
+#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))); |