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 @@ ...@@ -31,6 +31,7 @@
#include "config.h" #include "config.h"
#include "public/platform/linux/WebFontInfo.h" #include "public/platform/linux/WebFontInfo.h"
#include "public/platform/linux/WebFallbackFont.h"
#include "public/platform/linux/WebFontFamily.h" #include "public/platform/linux/WebFontFamily.h"
#include "public/platform/linux/WebFontRenderStyle.h" #include "public/platform/linux/WebFontRenderStyle.h"
#include <fontconfig/fontconfig.h> #include <fontconfig/fontconfig.h>
...@@ -46,6 +47,7 @@ void WebFontInfo::setSubpixelPositioning(bool subpixelPositioning) ...@@ -46,6 +47,7 @@ void WebFontInfo::setSubpixelPositioning(bool subpixelPositioning)
useSubpixelPositioning = 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) void WebFontInfo::familyForChar(WebUChar32 c, const char* preferredLocale, WebFontFamily* family)
{ {
FcCharSet* cset = FcCharSetCreate(); FcCharSet* cset = FcCharSetCreate();
...@@ -122,6 +124,91 @@ void WebFontInfo::familyForChar(WebUChar32 c, const char* preferredLocale, WebFo ...@@ -122,6 +124,91 @@ void WebFontInfo::familyForChar(WebUChar32 c, const char* preferredLocale, WebFo
FcFontSetDestroy(fontSet); 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) void WebFontInfo::renderStyleForStrike(const char* family, int sizeAndStyle, WebFontRenderStyle* out)
{ {
bool isBold = sizeAndStyle & 1; bool isBold = sizeAndStyle & 1;
......
...@@ -511,7 +511,7 @@ std::pair<GlyphData, GlyphPage*> Font::glyphDataAndPageForCharacter(UChar32 c, b ...@@ -511,7 +511,7 @@ std::pair<GlyphData, GlyphPage*> Font::glyphDataAndPageForCharacter(UChar32 c, b
if (characterToRender <= 0xFFFF) if (characterToRender <= 0xFFFF)
characterToRender = Character::normalizeSpaces(characterToRender); characterToRender = Character::normalizeSpaces(characterToRender);
const SimpleFontData* fontDataToSubstitute = fontDataAt(0)->fontDataForCharacter(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) {
if (characterFontData->platformData().orientation() == Vertical && !characterFontData->hasVerticalGlyphs() && Character::isCJKIdeographOrSymbol(c)) if (characterFontData->platformData().orientation() == Vertical && !characterFontData->hasVerticalGlyphs() && Character::isCJKIdeographOrSymbol(c))
variant = BrokenIdeographVariant; variant = BrokenIdeographVariant;
......
...@@ -78,7 +78,7 @@ public: ...@@ -78,7 +78,7 @@ public:
// This method is implemented by the plaform and used by // This method is implemented by the plaform and used by
// FontFastPath to lookup the font for a given character. // 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. // Also implemented by the platform.
void platformInit(); void platformInit();
...@@ -118,12 +118,14 @@ public: ...@@ -118,12 +118,14 @@ public:
#if OS(ANDROID) #if OS(ANDROID)
static AtomicString getGenericFamilyNameForScript(const AtomicString& familyName, UScriptCode); static AtomicString getGenericFamilyNameForScript(const AtomicString& familyName, UScriptCode);
#else #else
struct SimpleFontFamily { struct PlatformFallbackFont {
String name; String name;
CString filename;
int ttcIndex;
bool isBold; bool isBold;
bool isItalic; bool isItalic;
}; };
static void getFontFamilyForCharacter(UChar32, const char* preferredLocale, SimpleFontFamily*); static void getFontForCharacter(UChar32, const char* preferredLocale, PlatformFallbackFont*);
#endif #endif
private: private:
......
...@@ -69,7 +69,7 @@ static AtomicString getFamilyNameForCharacter(UChar32 c, UScriptCode script) ...@@ -69,7 +69,7 @@ static AtomicString getFamilyNameForCharacter(UChar32 c, UScriptCode script)
return skiaFamilyName.c_str(); 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()); AtomicString familyName = getFamilyNameForCharacter(c, fontDescription.script());
if (familyName.isEmpty()) if (familyName.isEmpty())
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
namespace WebCore { namespace WebCore {
TEST(FontCacheAndroid, platformFallbackForCharacter) TEST(FontCacheAndroid, fallbackFontForCharacter)
{ {
// A Latin character in the common locale system font, but not in the // A Latin character in the common locale system font, but not in the
// Chinese locale-preferred font. // Chinese locale-preferred font.
...@@ -22,7 +22,7 @@ TEST(FontCacheAndroid, platformFallbackForCharacter) ...@@ -22,7 +22,7 @@ TEST(FontCacheAndroid, platformFallbackForCharacter)
FontCache* fontCache = FontCache::fontCache(); FontCache* fontCache = FontCache::fontCache();
ASSERT_TRUE(fontCache); ASSERT_TRUE(fontCache);
RefPtr<SimpleFontData> fontData = fontCache->platformFallbackForCharacter(fontDescription, testChar, 0); RefPtr<SimpleFontData> fontData = fontCache->fallbackFontForCharacter(fontDescription, testChar, 0);
EXPECT_TRUE(fontData); EXPECT_TRUE(fontData);
} }
......
...@@ -34,16 +34,26 @@ ...@@ -34,16 +34,26 @@
namespace WebCore { 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); blink::Platform::current()->sandboxSupport()->getFontFamilyForCharacter(c, preferredLocale, &webFamily);
else fallbackFont->name = String::fromUTF8(CString(webFamily.name));
blink::WebFontInfo::familyForChar(c, preferredLocale, &webFamily); fallbackFont->isBold = webFamily.isBold;
family->name = String::fromUTF8(CString(webFamily.name)); fallbackFont->isItalic = webFamily.isItalic;
family->isBold = webFamily.isBold; } else {
family->isItalic = webFamily.isItalic; 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) ...@@ -100,7 +100,7 @@ static inline bool isAppKitFontWeightBold(NSInteger appKitFontWeight)
return appKitFontWeight >= 7; 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 // FIXME: We should fix getFallbackFamily to take a UChar32
// and remove this split-to-UChar16 code. // and remove this split-to-UChar16 code.
......
...@@ -49,30 +49,30 @@ void FontCache::platformInit() ...@@ -49,30 +49,30 @@ void FontCache::platformInit()
} }
#if !OS(WIN) && !OS(ANDROID) #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(); icu::Locale locale = icu::Locale::getDefault();
FontCache::SimpleFontFamily family; FontCache::PlatformFallbackFont fallbackFont;
FontCache::getFontFamilyForCharacter(c, locale.getLanguage(), &family); FontCache::getFontForCharacter(c, locale.getLanguage(), &fallbackFont);
if (family.name.isEmpty()) if (fallbackFont.name.isEmpty())
return nullptr; return nullptr;
AtomicString atomicFamily(family.name); AtomicString atomicFamily(fallbackFont.name);
// Changes weight and/or italic of given FontDescription depends on // Changes weight and/or italic of given FontDescription depends on
// the result of fontconfig so that keeping the correct font mapping // the result of fontconfig so that keeping the correct font mapping
// of the given character. See http://crbug.com/32109 for details. // of the given character. See http://crbug.com/32109 for details.
bool shouldSetSyntheticBold = false; bool shouldSetSyntheticBold = false;
bool shouldSetSyntheticItalic = false; bool shouldSetSyntheticItalic = false;
FontDescription description(fontDescription); FontDescription description(fontDescription);
if (family.isBold && description.weight() < FontWeightBold) if (fallbackFont.isBold && description.weight() < FontWeightBold)
description.setWeight(FontWeightBold); description.setWeight(FontWeightBold);
if (!family.isBold && description.weight() >= FontWeightBold) { if (!fallbackFont.isBold && description.weight() >= FontWeightBold) {
shouldSetSyntheticBold = true; shouldSetSyntheticBold = true;
description.setWeight(FontWeightNormal); description.setWeight(FontWeightNormal);
} }
if (family.isItalic && description.style() == FontStyleNormal) if (fallbackFont.isItalic && description.style() == FontStyleNormal)
description.setStyle(FontStyleItalic); description.setStyle(FontStyleItalic);
if (!family.isItalic && description.style() == FontStyleItalic) { if (!fallbackFont.isItalic && description.style() == FontStyleItalic) {
shouldSetSyntheticItalic = true; shouldSetSyntheticItalic = true;
description.setStyle(FontStyleNormal); description.setStyle(FontStyleNormal);
} }
......
...@@ -85,7 +85,7 @@ static bool fontContainsCharacter(const FontPlatformData* fontData, const wchar_ ...@@ -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 // 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. // 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() // FIXME: Consider passing fontDescription.dominantScript()
// to GetFallbackFamily here. // 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 @@ ...@@ -32,6 +32,7 @@
#define WebFontInfo_h #define WebFontInfo_h
#include "../WebCString.h" #include "../WebCString.h"
#include "WebFallbackFont.h"
#include "WebFontFamily.h" #include "WebFontFamily.h"
#include "WebFontRenderStyle.h" #include "WebFontRenderStyle.h"
...@@ -55,6 +56,9 @@ public: ...@@ -55,6 +56,9 @@ public:
// //
// Returns: the font family or an empty string if the request could not be satisfied. // 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. // 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*); BLINK_EXPORT static void familyForChar(const WebUChar32 character, const char* preferredLocale, WebFontFamily*);
// Fill out the given WebFontRenderStyle with the user's preferences for // Fill out the given WebFontRenderStyle with the user's preferences for
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include "../WebCommon.h" #include "../WebCommon.h"
#include "../WebString.h" #include "../WebString.h"
#include "WebFallbackFont.h"
#include "WebFontFamily.h" #include "WebFontFamily.h"
namespace blink { namespace blink {
...@@ -44,16 +45,19 @@ struct WebFontRenderStyle; ...@@ -44,16 +45,19 @@ struct WebFontRenderStyle;
// https://code.google.com/p/chromium/wiki/LinuxSandboxIPC // https://code.google.com/p/chromium/wiki/LinuxSandboxIPC
class WebSandboxSupport { class WebSandboxSupport {
public: 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 // character: a UTF-32 codepoint
// preferredLocale: preferred locale identifier for the |characters| // preferredLocale: preferred locale identifier for the |characters|
// (e.g. "en", "ja", "zh-CN") // (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. // 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; 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; 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