Adding WebFallbackFont and renaming SimpleFontFamily

Step 1 of renames preceding the fix for family based fallback font selection.

BUG=382411
R=eae,behdad

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

git-svn-id: svn://svn.chromium.org/blink/trunk@175858 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent ffb0853a
......@@ -31,6 +31,7 @@
#include "config.h"
#include "public/platform/linux/WebFontInfo.h"
#include "public/platform/linux/WebFallbackFont.h"
#include "public/platform/linux/WebFontFamily.h"
#include "public/platform/linux/WebFontRenderStyle.h"
#include <fontconfig/fontconfig.h>
......@@ -46,6 +47,7 @@ void WebFontInfo::setSubpixelPositioning(bool subpixelPositioning)
useSubpixelPositioning = subpixelPositioning;
}
// TODO(dro): Remove this legacy version, kept until renames on the Chromium side are done. crbug.com/382411
void WebFontInfo::familyForChar(WebUChar32 c, const char* preferredLocale, WebFontFamily* family)
{
FcCharSet* cset = FcCharSetCreate();
......@@ -122,6 +124,91 @@ void WebFontInfo::familyForChar(WebUChar32 c, const char* preferredLocale, WebFo
FcFontSetDestroy(fontSet);
}
void WebFontInfo::fallbackFontForChar(WebUChar32 c, const char* preferredLocale, WebFallbackFont* fallbackFont)
{
FcCharSet* cset = FcCharSetCreate();
FcCharSetAddChar(cset, c);
FcPattern* pattern = FcPatternCreate();
FcValue fcvalue;
fcvalue.type = FcTypeCharSet;
fcvalue.u.c = cset;
FcPatternAdd(pattern, FC_CHARSET, fcvalue, FcFalse);
fcvalue.type = FcTypeBool;
fcvalue.u.b = FcTrue;
FcPatternAdd(pattern, FC_SCALABLE, fcvalue, FcFalse);
if (preferredLocale) {
FcLangSet* langset = FcLangSetCreate();
FcLangSetAdd(langset, reinterpret_cast<const FcChar8 *>(preferredLocale));
FcPatternAddLangSet(pattern, FC_LANG, langset);
FcLangSetDestroy(langset);
}
FcConfigSubstitute(0, pattern, FcMatchPattern);
FcDefaultSubstitute(pattern);
FcResult result;
FcFontSet* fontSet = FcFontSort(0, pattern, 0, 0, &result);
FcPatternDestroy(pattern);
FcCharSetDestroy(cset);
if (!fontSet) {
fallbackFont->name = WebCString();
fallbackFont->isBold = false;
fallbackFont->isItalic = false;
return;
}
// Older versions of fontconfig have a bug where they cannot select
// only scalable fonts so we have to manually filter the results.
for (int i = 0; i < fontSet->nfont; ++i) {
FcPattern* current = fontSet->fonts[i];
FcBool isScalable;
if (FcPatternGetBool(current, FC_SCALABLE, 0, &isScalable) != FcResultMatch
|| !isScalable)
continue;
// fontconfig can also return fonts which are unreadable
FcChar8* cFilename;
if (FcPatternGetString(current, FC_FILE, 0, &cFilename) != FcResultMatch)
continue;
if (access(reinterpret_cast<char*>(cFilename), R_OK))
continue;
const char* fontFilename = reinterpret_cast<char*>(cFilename);
fallbackFont->filename = WebCString(fontFilename, strlen(fontFilename));
// Index into font collection.
int ttcIndex;
if (FcPatternGetInteger(current, FC_INDEX, 0, &ttcIndex) != FcResultMatch && ttcIndex < 0)
continue;
fallbackFont->ttcIndex = ttcIndex;
FcChar8* familyName;
if (FcPatternGetString(current, FC_FAMILY, 0, &familyName) == FcResultMatch) {
const char* charFamily = reinterpret_cast<char*>(familyName);
fallbackFont->name = WebCString(charFamily, strlen(charFamily));
}
int weight;
if (FcPatternGetInteger(current, FC_WEIGHT, 0, &weight) == FcResultMatch)
fallbackFont->isBold = weight >= FC_WEIGHT_BOLD;
else
fallbackFont->isBold = false;
int slant;
if (FcPatternGetInteger(current, FC_SLANT, 0, &slant) == FcResultMatch)
fallbackFont->isItalic = slant != FC_SLANT_ROMAN;
else
fallbackFont->isItalic = false;
FcFontSetDestroy(fontSet);
return;
}
FcFontSetDestroy(fontSet);
}
void WebFontInfo::renderStyleForStrike(const char* family, int sizeAndStyle, WebFontRenderStyle* out)
{
bool isBold = sizeAndStyle & 1;
......
......@@ -511,7 +511,7 @@ std::pair<GlyphData, GlyphPage*> Font::glyphDataAndPageForCharacter(UChar32 c, b
if (characterToRender <= 0xFFFF)
characterToRender = Character::normalizeSpaces(characterToRender);
const SimpleFontData* fontDataToSubstitute = fontDataAt(0)->fontDataForCharacter(characterToRender);
RefPtr<SimpleFontData> characterFontData = FontCache::fontCache()->platformFallbackForCharacter(m_fontDescription, characterToRender, fontDataToSubstitute);
RefPtr<SimpleFontData> characterFontData = FontCache::fontCache()->fallbackFontForCharacter(m_fontDescription, characterToRender, fontDataToSubstitute);
if (characterFontData) {
if (characterFontData->platformData().orientation() == Vertical && !characterFontData->hasVerticalGlyphs() && Character::isCJKIdeographOrSymbol(c))
variant = BrokenIdeographVariant;
......
......@@ -78,7 +78,7 @@ public:
// This method is implemented by the plaform and used by
// FontFastPath to lookup the font for a given character.
PassRefPtr<SimpleFontData> platformFallbackForCharacter(const FontDescription&, UChar32, const SimpleFontData* fontDataToSubstitute);
PassRefPtr<SimpleFontData> fallbackFontForCharacter(const FontDescription&, UChar32, const SimpleFontData* fontDataToSubstitute);
// Also implemented by the platform.
void platformInit();
......@@ -118,12 +118,14 @@ public:
#if OS(ANDROID)
static AtomicString getGenericFamilyNameForScript(const AtomicString& familyName, UScriptCode);
#else
struct SimpleFontFamily {
struct PlatformFallbackFont {
String name;
CString filename;
int ttcIndex;
bool isBold;
bool isItalic;
};
static void getFontFamilyForCharacter(UChar32, const char* preferredLocale, SimpleFontFamily*);
static void getFontForCharacter(UChar32, const char* preferredLocale, PlatformFallbackFont*);
#endif
private:
......
......@@ -69,7 +69,7 @@ static AtomicString getFamilyNameForCharacter(UChar32 c, UScriptCode script)
return skiaFamilyName.c_str();
}
PassRefPtr<SimpleFontData> FontCache::platformFallbackForCharacter(const FontDescription& fontDescription, UChar32 c, const SimpleFontData*)
PassRefPtr<SimpleFontData> FontCache::fallbackFontForCharacter(const FontDescription& fontDescription, UChar32 c, const SimpleFontData*)
{
AtomicString familyName = getFamilyNameForCharacter(c, fontDescription.script());
if (familyName.isEmpty())
......
......@@ -10,7 +10,7 @@
namespace WebCore {
TEST(FontCacheAndroid, platformFallbackForCharacter)
TEST(FontCacheAndroid, fallbackFontForCharacter)
{
// A Latin character in the common locale system font, but not in the
// Chinese locale-preferred font.
......@@ -22,7 +22,7 @@ TEST(FontCacheAndroid, platformFallbackForCharacter)
FontCache* fontCache = FontCache::fontCache();
ASSERT_TRUE(fontCache);
RefPtr<SimpleFontData> fontData = fontCache->platformFallbackForCharacter(fontDescription, testChar, 0);
RefPtr<SimpleFontData> fontData = fontCache->fallbackFontForCharacter(fontDescription, testChar, 0);
EXPECT_TRUE(fontData);
}
......
......@@ -34,16 +34,26 @@
namespace WebCore {
void FontCache::getFontFamilyForCharacter(UChar32 c, const char* preferredLocale, FontCache::SimpleFontFamily* family)
void FontCache::getFontForCharacter(UChar32 c, const char* preferredLocale, FontCache::PlatformFallbackFont* fallbackFont)
{
blink::WebFontFamily webFamily;
if (blink::Platform::current()->sandboxSupport())
if (blink::Platform::current()->sandboxSupport()) {
// TODO(dro): crbug.com/382411 Change this to using new getFallbackFontForCharacter sandbox API
// and WebFallbackFont class to complete the rename, and pull WebFallbackFont out of the if statement again.
blink::WebFontFamily webFamily;
blink::Platform::current()->sandboxSupport()->getFontFamilyForCharacter(c, preferredLocale, &webFamily);
else
blink::WebFontInfo::familyForChar(c, preferredLocale, &webFamily);
family->name = String::fromUTF8(CString(webFamily.name));
family->isBold = webFamily.isBold;
family->isItalic = webFamily.isItalic;
fallbackFont->name = String::fromUTF8(CString(webFamily.name));
fallbackFont->isBold = webFamily.isBold;
fallbackFont->isItalic = webFamily.isItalic;
} else {
blink::WebFallbackFont webFallbackFont;
blink::WebFontInfo::fallbackFontForChar(c, preferredLocale, &webFallbackFont);
fallbackFont->name = String::fromUTF8(CString(webFallbackFont.name));
fallbackFont->filename = CString(webFallbackFont.filename);
fallbackFont->ttcIndex = webFallbackFont.ttcIndex;
fallbackFont->isBold = webFallbackFont.isBold;
fallbackFont->isItalic = webFallbackFont.isItalic;
}
}
}
......@@ -100,7 +100,7 @@ static inline bool isAppKitFontWeightBold(NSInteger appKitFontWeight)
return appKitFontWeight >= 7;
}
PassRefPtr<SimpleFontData> FontCache::platformFallbackForCharacter(const FontDescription& fontDescription, UChar32 character, const SimpleFontData* fontDataToSubstitute)
PassRefPtr<SimpleFontData> FontCache::fallbackFontForCharacter(const FontDescription& fontDescription, UChar32 character, const SimpleFontData* fontDataToSubstitute)
{
// FIXME: We should fix getFallbackFamily to take a UChar32
// and remove this split-to-UChar16 code.
......
......@@ -49,30 +49,30 @@ void FontCache::platformInit()
}
#if !OS(WIN) && !OS(ANDROID)
PassRefPtr<SimpleFontData> FontCache::platformFallbackForCharacter(const FontDescription& fontDescription, UChar32 c, const SimpleFontData*)
PassRefPtr<SimpleFontData> FontCache::fallbackFontForCharacter(const FontDescription& fontDescription, UChar32 c, const SimpleFontData*)
{
icu::Locale locale = icu::Locale::getDefault();
FontCache::SimpleFontFamily family;
FontCache::getFontFamilyForCharacter(c, locale.getLanguage(), &family);
if (family.name.isEmpty())
FontCache::PlatformFallbackFont fallbackFont;
FontCache::getFontForCharacter(c, locale.getLanguage(), &fallbackFont);
if (fallbackFont.name.isEmpty())
return nullptr;
AtomicString atomicFamily(family.name);
AtomicString atomicFamily(fallbackFont.name);
// Changes weight and/or italic of given FontDescription depends on
// the result of fontconfig so that keeping the correct font mapping
// of the given character. See http://crbug.com/32109 for details.
bool shouldSetSyntheticBold = false;
bool shouldSetSyntheticItalic = false;
FontDescription description(fontDescription);
if (family.isBold && description.weight() < FontWeightBold)
if (fallbackFont.isBold && description.weight() < FontWeightBold)
description.setWeight(FontWeightBold);
if (!family.isBold && description.weight() >= FontWeightBold) {
if (!fallbackFont.isBold && description.weight() >= FontWeightBold) {
shouldSetSyntheticBold = true;
description.setWeight(FontWeightNormal);
}
if (family.isItalic && description.style() == FontStyleNormal)
if (fallbackFont.isItalic && description.style() == FontStyleNormal)
description.setStyle(FontStyleItalic);
if (!family.isItalic && description.style() == FontStyleItalic) {
if (!fallbackFont.isItalic && description.style() == FontStyleItalic) {
shouldSetSyntheticItalic = true;
description.setStyle(FontStyleNormal);
}
......
......@@ -85,7 +85,7 @@ static bool fontContainsCharacter(const FontPlatformData* fontData, const wchar_
// Given the desired base font, this will create a SimpleFontData for a specific
// font that can be used to render the given range of characters.
PassRefPtr<SimpleFontData> FontCache::platformFallbackForCharacter(const FontDescription& fontDescription, UChar32 character, const SimpleFontData*)
PassRefPtr<SimpleFontData> FontCache::fallbackFontForCharacter(const FontDescription& fontDescription, UChar32 character, const SimpleFontData*)
{
// FIXME: Consider passing fontDescription.dominantScript()
// to GetFallbackFamily here.
......
/*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef WebFallbackFont_h
#define WebFallbackFont_h
#include "../WebCString.h"
#include "../WebCommon.h"
namespace blink {
struct WebFallbackFont {
WebCString name;
WebCString filename;
int ttcIndex;
bool isBold;
bool isItalic;
};
} // namespace blink
#endif // WebFallbackFont_h
......@@ -32,6 +32,7 @@
#define WebFontInfo_h
#include "../WebCString.h"
#include "WebFallbackFont.h"
#include "WebFontFamily.h"
#include "WebFontRenderStyle.h"
......@@ -55,6 +56,9 @@ public:
//
// Returns: the font family or an empty string if the request could not be satisfied.
// Returns: the font family instance. The instance has an empty font name if the request could not be satisfied.
BLINK_EXPORT static void fallbackFontForChar(const WebUChar32 character, const char* preferredLocale, WebFallbackFont*);
// TODO(dro): Remove this legacy version, kept until renames on the Chromium side are done. crbug.com/382411
BLINK_EXPORT static void familyForChar(const WebUChar32 character, const char* preferredLocale, WebFontFamily*);
// Fill out the given WebFontRenderStyle with the user's preferences for
......
......@@ -33,6 +33,7 @@
#include "../WebCommon.h"
#include "../WebString.h"
#include "WebFallbackFont.h"
#include "WebFontFamily.h"
namespace blink {
......@@ -44,16 +45,19 @@ struct WebFontRenderStyle;
// https://code.google.com/p/chromium/wiki/LinuxSandboxIPC
class WebSandboxSupport {
public:
// Get a font family which contains glyphs for the given Unicode code-point.
// Get information to instantiate a font which contains glyphs for the given Unicode code-point.
// character: a UTF-32 codepoint
// preferredLocale: preferred locale identifier for the |characters|
// (e.g. "en", "ja", "zh-CN")
//
// Returns a string with the font family on an empty string if the
// request cannot be satisfied.
// Returns a WebFontFamily instance with the font name. The instance has empty font name if the request cannot be satisfied.
virtual void getFontFamilyForCharacter(WebUChar32, const char* preferredLocale, WebFontFamily*) = 0;
// TODO(dro): crbug.com/382411 Add a new version on the Chromium side to complete
// the WebFontFamily->WebFallbackFont rename, like
// virtual void getFallbackFontForCharacter(WebUChar32, const char* preferredLocale, WebFallbackFont*) = 0;
// then add it here.
virtual void getRenderStyleForStrike(const char* family, int sizeAndStyle, WebFontRenderStyle*) = 0;
};
......
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