Try last resort on no-match in platformFallbackForCharacter on Android

On Android, some locale-preferred fonts (e.g. DroidSansFallback.ttf for
Chinese locale) doesn't contain all characters that the default locale
system fonts contain.

For characters that is missing in the font, fallback to the default
locale system font, by calling getLastResortFallbackFont() in
FontCache::platformFallbackForCharacter().

Also modified getLastResortFallbackFont() to prefer Skia default font
instead of the hard-coded default font (sans) and to map also cursive
and fantasy generic families.

Combined similar code in FontCacheSkia.cpp.

BUG=347121
TEST=FontCacheAndroid.platformFallbackForCharacter (will be enabled in another CL)
R=dglazkov@chromium.org

Review URL: https://codereview.chromium.org/185863007

git-svn-id: svn://svn.chromium.org/blink/trunk@168410 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent e3434261
...@@ -106,18 +106,26 @@ inline const AtomicString& alternateFamilyName(const AtomicString& familyName) ...@@ -106,18 +106,26 @@ inline const AtomicString& alternateFamilyName(const AtomicString& familyName)
inline const AtomicString getFallbackFontFamily(const FontDescription& description) inline const AtomicString getFallbackFontFamily(const FontDescription& description)
{ {
DEFINE_STATIC_LOCAL(const AtomicString, sansStr, ("Sans", AtomicString::ConstructFromLiteral)); DEFINE_STATIC_LOCAL(const AtomicString, sansStr, ("sans-serif", AtomicString::ConstructFromLiteral));
DEFINE_STATIC_LOCAL(const AtomicString, serifStr, ("Serif", AtomicString::ConstructFromLiteral)); DEFINE_STATIC_LOCAL(const AtomicString, serifStr, ("serif", AtomicString::ConstructFromLiteral));
DEFINE_STATIC_LOCAL(const AtomicString, monospaceStr, ("Monospace", AtomicString::ConstructFromLiteral)); DEFINE_STATIC_LOCAL(const AtomicString, monospaceStr, ("monospace", AtomicString::ConstructFromLiteral));
DEFINE_STATIC_LOCAL(const AtomicString, cursiveStr, ("cursive", AtomicString::ConstructFromLiteral));
DEFINE_STATIC_LOCAL(const AtomicString, fantasyStr, ("fantasy", AtomicString::ConstructFromLiteral));
switch (description.genericFamily()) { switch (description.genericFamily()) {
case FontDescription::SansSerifFamily:
return sansStr;
case FontDescription::SerifFamily: case FontDescription::SerifFamily:
return serifStr; return serifStr;
case FontDescription::MonospaceFamily: case FontDescription::MonospaceFamily:
return monospaceStr; return monospaceStr;
case FontDescription::SansSerifFamily: case FontDescription::CursiveFamily:
return cursiveStr;
case FontDescription::FantasyFamily:
return fantasyStr;
default: default:
return sansStr; // Let the caller use the system default font.
return emptyAtom;
} }
} }
......
...@@ -64,7 +64,8 @@ static AtomicString getFamilyNameForCharacter(UChar32 c, UScriptCode script) ...@@ -64,7 +64,8 @@ static AtomicString getFamilyNameForCharacter(UChar32 c, UScriptCode script)
SkString skiaFamilyName; SkString skiaFamilyName;
if (!SkGetFallbackFamilyNameForChar(c, locale, &skiaFamilyName) || skiaFamilyName.isEmpty()) if (!SkGetFallbackFamilyNameForChar(c, locale, &skiaFamilyName) || skiaFamilyName.isEmpty())
return AtomicString(); return emptyAtom;
return skiaFamilyName.c_str(); return skiaFamilyName.c_str();
} }
...@@ -72,7 +73,7 @@ PassRefPtr<SimpleFontData> FontCache::platformFallbackForCharacter(const FontDes ...@@ -72,7 +73,7 @@ PassRefPtr<SimpleFontData> FontCache::platformFallbackForCharacter(const FontDes
{ {
AtomicString familyName = getFamilyNameForCharacter(c, fontDescription.script()); AtomicString familyName = getFamilyNameForCharacter(c, fontDescription.script());
if (familyName.isEmpty()) if (familyName.isEmpty())
return nullptr; return getLastResortFallbackFont(fontDescription, DoNotRetain);
return fontDataFromFontPlatformData(getFontPlatformData(fontDescription, familyName), DoNotRetain); return fontDataFromFontPlatformData(getFontPlatformData(fontDescription, familyName), DoNotRetain);
} }
......
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "config.h"
#include "platform/fonts/FontCache.h"
#include "platform/fonts/SimpleFontData.h"
#include <gtest/gtest.h>
namespace WebCore {
TEST(FontCacheAndroid, platformFallbackForCharacter)
{
// A Latin character in the common locale system font, but not in the
// Chinese locale-preferred font.
const UChar32 testChar = 228;
FontDescription fontDescription;
fontDescription.setScript(USCRIPT_SIMPLIFIED_HAN);
fontDescription.setGenericFamily(FontDescription::StandardFamily);
FontCache* fontCache = FontCache::fontCache();
ASSERT_TRUE(fontCache);
RefPtr<SimpleFontData> fontData = fontCache->platformFallbackForCharacter(fontDescription, testChar, 0);
EXPECT_TRUE(fontData);
}
} // namespace WebCore
...@@ -86,7 +86,7 @@ PassRefPtr<SimpleFontData> FontCache::platformFallbackForCharacter(const FontDes ...@@ -86,7 +86,7 @@ PassRefPtr<SimpleFontData> FontCache::platformFallbackForCharacter(const FontDes
return fontDataFromFontPlatformData(&platformData, DoNotRetain); return fontDataFromFontPlatformData(&platformData, DoNotRetain);
} }
#endif // !OS(WINDOWNS) && !OS(ANDROID) #endif // !OS(WIN) && !OS(ANDROID)
PassRefPtr<SimpleFontData> FontCache::getLastResortFallbackFont(const FontDescription& description, ShouldRetain shouldRetain) PassRefPtr<SimpleFontData> FontCache::getLastResortFallbackFont(const FontDescription& description, ShouldRetain shouldRetain)
{ {
...@@ -107,29 +107,10 @@ PassRefPtr<SimpleFontData> FontCache::getLastResortFallbackFont(const FontDescri ...@@ -107,29 +107,10 @@ PassRefPtr<SimpleFontData> FontCache::getLastResortFallbackFont(const FontDescri
PassRefPtr<SkTypeface> FontCache::createTypeface(const FontDescription& fontDescription, const AtomicString& family, CString& name) PassRefPtr<SkTypeface> FontCache::createTypeface(const FontDescription& fontDescription, const AtomicString& family, CString& name)
{ {
name = "";
// If we're creating a fallback font (e.g. "-webkit-monospace"), convert the name into // If we're creating a fallback font (e.g. "-webkit-monospace"), convert the name into
// the fallback name (like "monospace") that fontconfig understands. // the fallback name (like "monospace") that fontconfig understands.
if (!family.length() || family.startsWith("-webkit-")) { if (!family.length() || family.startsWith("-webkit-")) {
static const struct { name = getFallbackFontFamily(fontDescription).string().utf8();
FontDescription::GenericFamilyType mType;
const char* mName;
} fontDescriptions[] = {
{ FontDescription::SerifFamily, "serif" },
{ FontDescription::SansSerifFamily, "sans-serif" },
{ FontDescription::MonospaceFamily, "monospace" },
{ FontDescription::CursiveFamily, "cursive" },
{ FontDescription::FantasyFamily, "fantasy" }
};
FontDescription::GenericFamilyType type = fontDescription.genericFamily();
for (unsigned i = 0; i < SK_ARRAY_COUNT(fontDescriptions); i++) {
if (type == fontDescriptions[i].mType) {
name = fontDescriptions[i].mName;
break;
}
}
} else { } else {
// convert the name to utf8 // convert the name to utf8
name = family.utf8(); name = family.utf8();
...@@ -167,6 +148,6 @@ FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontD ...@@ -167,6 +148,6 @@ FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontD
fontDescription.useSubpixelPositioning()); fontDescription.useSubpixelPositioning());
return result; return result;
} }
#endif // !OS(WINDOWNS) #endif // !OS(WIN)
} // namespace WebCore } // namespace WebCore
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment