From 9689b229bf66f3ee6d249649b9a32d9e4081f895 Mon Sep 17 00:00:00 2001 From: "bashi@chromium.org" Date: Thu, 17 Nov 2011 12:16:57 +0000 Subject: [PATCH] [chromium] don't call fontconfig twice in complex text path https://bugs.webkit.org/show_bug.cgi?id=38701 Source/WebCore: Adds a new API for getting font family. For now, FontCacheLinux calls the new API, but don't use additional properties for compatibility. The old API will be removed when Chromium is ready to use new API. Reviewed by Tony Chang. No new tests. No behavior changes for now. * platform/chromium/PlatformSupport.h: Added FontFamily struct and changed the declaration of getFontFamilyForCharacters(). * platform/graphics/chromium/FontCacheLinux.cpp: (WebCore::FontCache::getFontDataForCharacters): Uses new PlatformSupport::getFontFamilyForCharacters(). * platform/graphics/chromium/FontPlatformDataLinux.h: (WebCore::FontPlatformData::setFakeBold): Added. (WebCore::FontPlatformData::setFakeItalic): Added. Source/WebKit/chromium: Reviewed by Tony Chang. Add new API for getFamilyForChars() so that keeping correct font mapping of the given characters. * public/linux/WebFontFamily.h: Added. * public/linux/WebFontInfo.h: Add a new API. * public/linux/WebSandboxSupport.h: (WebKit::WebSandboxSupport::getFontFamilyForCharacters): Ditto. * src/PlatformSupport.cpp: (WebCore::PlatformSupport::getFontFamilyForCharacters): Ditto. * src/linux/WebFontInfo.cpp: (WebKit::WebFontInfo::familyForChars): Modified to get weight and italic properties of the font. Old API uses new API internally. git-svn-id: http://svn.webkit.org/repository/webkit/trunk@100601 268f45cc-cd09-0410-ab3c-d52691b4dbfc --- Source/WebCore/ChangeLog | 18 +++++++ .../platform/chromium/PlatformSupport.h | 7 ++- .../graphics/chromium/FontCacheLinux.cpp | 34 ++++++++++++-- .../graphics/chromium/FontPlatformDataLinux.h | 3 +- Source/WebKit/chromium/ChangeLog | 18 +++++++ .../chromium/public/linux/WebFontFamily.h | 47 +++++++++++++++++++ .../chromium/public/linux/WebFontInfo.h | 4 ++ .../chromium/public/linux/WebSandboxSupport.h | 11 ++++- .../WebKit/chromium/src/PlatformSupport.cpp | 20 ++++---- .../WebKit/chromium/src/linux/WebFontInfo.cpp | 40 ++++++++++++---- 10 files changed, 177 insertions(+), 25 deletions(-) create mode 100644 Source/WebKit/chromium/public/linux/WebFontFamily.h diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog index a1ba313c4ce..0c189cb6095 100644 --- a/Source/WebCore/ChangeLog +++ b/Source/WebCore/ChangeLog @@ -1,3 +1,21 @@ +2011-11-17 Kenichi Ishibashi + + [chromium] don't call fontconfig twice in complex text path + https://bugs.webkit.org/show_bug.cgi?id=38701 + + Adds a new API for getting font family. For now, FontCacheLinux calls the new API, but don't use additional properties for compatibility. The old API will be removed when Chromium is ready to use new API. + + Reviewed by Tony Chang. + + No new tests. No behavior changes for now. + + * platform/chromium/PlatformSupport.h: Added FontFamily struct and changed the declaration of getFontFamilyForCharacters(). + * platform/graphics/chromium/FontCacheLinux.cpp: + (WebCore::FontCache::getFontDataForCharacters): Uses new PlatformSupport::getFontFamilyForCharacters(). + * platform/graphics/chromium/FontPlatformDataLinux.h: + (WebCore::FontPlatformData::setFakeBold): Added. + (WebCore::FontPlatformData::setFakeItalic): Added. + 2011-11-17 Mario Sanchez Prada [GTK] Consider parent AtkObject in webkit_accessible_get_parent(), if already set diff --git a/Source/WebCore/platform/chromium/PlatformSupport.h b/Source/WebCore/platform/chromium/PlatformSupport.h index 413edfcca55..68ba794be10 100644 --- a/Source/WebCore/platform/chromium/PlatformSupport.h +++ b/Source/WebCore/platform/chromium/PlatformSupport.h @@ -152,7 +152,12 @@ public: static bool loadFont(NSFont* srcFont, CGFontRef*, uint32_t* fontID); #elif OS(UNIX) static void getRenderStyleForStrike(const char* family, int sizeAndStyle, FontRenderStyle* result); - static String getFontFamilyForCharacters(const UChar*, size_t numCharacters, const char* preferredLocale); + struct FontFamily { + String name; + bool isBold; + bool isItalic; + }; + static void getFontFamilyForCharacters(const UChar*, size_t numCharacters, const char* preferredLocale, FontFamily*); #endif // Forms -------------------------------------------------------------- diff --git a/Source/WebCore/platform/graphics/chromium/FontCacheLinux.cpp b/Source/WebCore/platform/graphics/chromium/FontCacheLinux.cpp index 4dd660daf2d..eca7b03319d 100644 --- a/Source/WebCore/platform/graphics/chromium/FontCacheLinux.cpp +++ b/Source/WebCore/platform/graphics/chromium/FontCacheLinux.cpp @@ -59,12 +59,40 @@ const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font, int length) { icu::Locale locale = icu::Locale::getDefault(); - String family = PlatformSupport::getFontFamilyForCharacters(characters, length, locale.getLanguage()); - if (family.isEmpty()) + PlatformSupport::FontFamily family; + PlatformSupport::getFontFamilyForCharacters(characters, length, locale.getLanguage(), &family); + if (family.name.isEmpty()) return 0; - AtomicString atomicFamily(family); + AtomicString atomicFamily(family.name); + // FIXME: Remove this #if after API transition complete. +#if 0 + // Changes weight and/or italic of given FontDescription depends on + // the result of fontconfig so that keeping the correct font mapping + // of the given characters. See http://crbug.com/32109 for details. + bool shouldSetFakeBold = false; + bool shouldSetFakeItalic = false; + FontDescription description(font.fontDescription()); + if (family.isBold && description.weight() < FontWeightBold) + description.setWeight(FontWeightBold); + if (!family.isBold && description.weight() >= FontWeightBold) { + shouldSetFakeBold = true; + description.setWeight(FontWeightNormal); + } + if (family.isItalic && description.italic() == FontItalicOff) + description.setItalic(FontItalicOn); + if (!family.isItalic && description.italic() == FontItalicOn) { + shouldSetFakeItalic = true; + description.setItalic(FontItalicOff); + } + + FontPlatformData platformData = FontPlatformData(*getCachedFontPlatformData(description, atomicFamily, DoNotRetain)); + platformData.setFakeBold(shouldSetFakeBold); + platformData.setFakeItalic(shouldSetFakeItalic); + return getCachedFontData(&platformData, DoNotRetain); +#else return getCachedFontData(getCachedFontPlatformData(font.fontDescription(), atomicFamily, DoNotRetain), DoNotRetain); +#endif } SimpleFontData* FontCache::getSimilarFontPlatformData(const Font& font) diff --git a/Source/WebCore/platform/graphics/chromium/FontPlatformDataLinux.h b/Source/WebCore/platform/graphics/chromium/FontPlatformDataLinux.h index 86b941cae40..10dce905045 100644 --- a/Source/WebCore/platform/graphics/chromium/FontPlatformDataLinux.h +++ b/Source/WebCore/platform/graphics/chromium/FontPlatformDataLinux.h @@ -118,7 +118,8 @@ public: FontOrientation orientation() const { return m_orientation; } void setOrientation(FontOrientation orientation) { m_orientation = orientation; } - + void setFakeBold(bool fakeBold) { m_fakeBold = fakeBold; } + void setFakeItalic(bool fakeItalic) { m_fakeItalic = fakeItalic; } bool operator==(const FontPlatformData&) const; FontPlatformData& operator=(const FontPlatformData&); bool isHashTableDeletedValue() const { return m_typeface == hashTableDeletedFontValue(); } diff --git a/Source/WebKit/chromium/ChangeLog b/Source/WebKit/chromium/ChangeLog index 632b07f0fac..578cf3c4937 100644 --- a/Source/WebKit/chromium/ChangeLog +++ b/Source/WebKit/chromium/ChangeLog @@ -1,3 +1,21 @@ +2011-11-17 Kenichi Ishibashi + + [chromium] don't call fontconfig twice in complex text path + https://bugs.webkit.org/show_bug.cgi?id=38701 + + Reviewed by Tony Chang. + + Add new API for getFamilyForChars() so that keeping correct font mapping of the given characters. + + * public/linux/WebFontFamily.h: Added. + * public/linux/WebFontInfo.h: Add a new API. + * public/linux/WebSandboxSupport.h: + (WebKit::WebSandboxSupport::getFontFamilyForCharacters): Ditto. + * src/PlatformSupport.cpp: + (WebCore::PlatformSupport::getFontFamilyForCharacters): Ditto. + * src/linux/WebFontInfo.cpp: + (WebKit::WebFontInfo::familyForChars): Modified to get weight and italic properties of the font. Old API uses new API internally. + 2011-11-17 Adam Barth [Chromium] Introduce WebSecurityOrigin::isUnique in preparation for removing WebSecurityOrigin::isEmpty diff --git a/Source/WebKit/chromium/public/linux/WebFontFamily.h b/Source/WebKit/chromium/public/linux/WebFontFamily.h new file mode 100644 index 00000000000..47f03788222 --- /dev/null +++ b/Source/WebKit/chromium/public/linux/WebFontFamily.h @@ -0,0 +1,47 @@ +/* + * 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 WebFontFamily_h +#define WebFontFamily_h + +#include "../WebCString.h" +#include "../WebCommon.h" + +namespace WebKit { + +struct WebFontFamily { + WebCString name; + bool isBold; + bool isItalic; +}; + +} // namespace WebKit + +#endif // WebFontFamily_h diff --git a/Source/WebKit/chromium/public/linux/WebFontInfo.h b/Source/WebKit/chromium/public/linux/WebFontInfo.h index 5d525844ae7..9b3472b6cfc 100644 --- a/Source/WebKit/chromium/public/linux/WebFontInfo.h +++ b/Source/WebKit/chromium/public/linux/WebFontInfo.h @@ -32,6 +32,7 @@ #define WebFontInfo_h #include "../WebCString.h" +#include "../linux/WebFontFamily.h" #include "../linux/WebFontRenderStyle.h" #include @@ -50,7 +51,10 @@ public: // // Returns: the font family or an empty string if the request could not be // satisfied. + // FIXME: Depreciated API. Remove later. WEBKIT_EXPORT static WebCString familyForChars(const WebUChar* characters, size_t numCharacters, const char* preferredLocale); + // Returns: the font family instance. The instance has an empty font name if the request could not be satisfied. + WEBKIT_EXPORT static void familyForChars(const WebUChar* characters, size_t numCharacters, const char* preferredLocale, WebFontFamily*); // Fill out the given WebFontRenderStyle with the user's preferences for // rendering the given font at the given size. diff --git a/Source/WebKit/chromium/public/linux/WebSandboxSupport.h b/Source/WebKit/chromium/public/linux/WebSandboxSupport.h index 2f5792988b6..4283df371c6 100644 --- a/Source/WebKit/chromium/public/linux/WebSandboxSupport.h +++ b/Source/WebKit/chromium/public/linux/WebSandboxSupport.h @@ -33,6 +33,7 @@ #include "../WebCommon.h" #include "../WebString.h" +#include "WebFontFamily.h" namespace WebKit { @@ -52,7 +53,15 @@ public: // // Returns a string with the font family on an empty string if the // request cannot be satisfied. - virtual WebString getFontFamilyForCharacters(const WebUChar* characters, size_t numCharacters, const char* preferredLocale) = 0; + // FIXME: Depreciated API. Remove later. + virtual WebString getFontFamilyForCharacters(const WebUChar* characters, size_t numCharacters, const char* preferredLocale) { return WebString(); } + // Returns a WebFontFamily instance with the font name. The instance has empty font name if the request cannot be satisfied. + // FIXME: Make this to be a pure virtual function after transition. + virtual void getFontFamilyForCharacters(const WebUChar* characters, size_t numCharacters, const char* preferredLocale, WebFontFamily* family) + { + family->name = getFontFamilyForCharacters(characters, numCharacters, preferredLocale).utf8(); + } + virtual void getRenderStyleForStrike(const char* family, int sizeAndStyle, WebFontRenderStyle* style) = 0; }; diff --git a/Source/WebKit/chromium/src/PlatformSupport.cpp b/Source/WebKit/chromium/src/PlatformSupport.cpp index f1f6686101f..7ed75ccc927 100644 --- a/Source/WebKit/chromium/src/PlatformSupport.cpp +++ b/Source/WebKit/chromium/src/PlatformSupport.cpp @@ -437,21 +437,23 @@ bool PlatformSupport::loadFont(NSFont* srcFont, CGFontRef* out, uint32_t* fontID return false; } #elif OS(UNIX) -String PlatformSupport::getFontFamilyForCharacters(const UChar* characters, size_t numCharacters, const char* preferredLocale) +void PlatformSupport::getFontFamilyForCharacters(const UChar* characters, size_t numCharacters, const char* preferredLocale, FontFamily* family) { #if OS(ANDROID) // FIXME: We do not use fontconfig on Android, so use simple logic for now. // https://bugs.webkit.org/show_bug.cgi?id=67587 - return WebString("Arial"); + family->name = "Arial"; + family->isBold = false; + family->isItalic = false; #else + WebFontFamily webFamily; if (webKitPlatformSupport()->sandboxSupport()) - return webKitPlatformSupport()->sandboxSupport()->getFontFamilyForCharacters(characters, numCharacters, preferredLocale); - - WebCString family = WebFontInfo::familyForChars(characters, numCharacters, preferredLocale); - if (family.data()) - return WebString::fromUTF8(family.data()); - - return WebString(); + webKitPlatformSupport()->sandboxSupport()->getFontFamilyForCharacters(characters, numCharacters, preferredLocale, &webFamily); + else + WebFontInfo::familyForChars(characters, numCharacters, preferredLocale, &webFamily); + family->name = String::fromUTF8(webFamily.name.data(), webFamily.name.length()); + family->isBold = webFamily.isBold; + family->isItalic = webFamily.isItalic; #endif } diff --git a/Source/WebKit/chromium/src/linux/WebFontInfo.cpp b/Source/WebKit/chromium/src/linux/WebFontInfo.cpp index 49182d47ea7..4d303d24cc1 100644 --- a/Source/WebKit/chromium/src/linux/WebFontInfo.cpp +++ b/Source/WebKit/chromium/src/linux/WebFontInfo.cpp @@ -31,6 +31,7 @@ #include "config.h" #include "WebFontInfo.h" +#include "WebFontFamily.h" #include "WebFontRenderStyle.h" #include @@ -39,7 +40,15 @@ namespace WebKit { +// FIXME: Depreciated API. Remove later. WebCString WebFontInfo::familyForChars(const WebUChar* characters, size_t numCharacters, const char* preferredLocale) +{ + WebFontFamily family; + familyForChars(characters, numCharacters, preferredLocale, &family); + return family.name; +} + +void WebFontInfo::familyForChars(const WebUChar* characters, size_t numCharacters, const char* preferredLocale, WebFontFamily* family) { FcCharSet* cset = FcCharSetCreate(); for (size_t i = 0; i < numCharacters; ++i) { @@ -78,9 +87,12 @@ WebCString WebFontInfo::familyForChars(const WebUChar* characters, size_t numCha FcPatternDestroy(pattern); FcCharSetDestroy(cset); - if (!fontSet) - return WebCString(); - + if (!fontSet) { + family->name = WebCString(); + family->isBold = false; + family->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) { @@ -99,18 +111,26 @@ WebCString WebFontInfo::familyForChars(const WebUChar* characters, size_t numCha if (access(reinterpret_cast(cFilename), R_OK)) continue; - FcChar8* family; - WebCString result; - if (FcPatternGetString(current, FC_FAMILY, 0, &family) == FcResultMatch) { - const char* charFamily = reinterpret_cast(family); - result = WebCString(charFamily, strlen(charFamily)); + FcChar8* familyName; + if (FcPatternGetString(current, FC_FAMILY, 0, &familyName) == FcResultMatch) { + const char* charFamily = reinterpret_cast(familyName); + family->name = WebCString(charFamily, strlen(charFamily)); } + int weight; + if (FcPatternGetInteger(current, FC_WEIGHT, 0, &weight) == FcResultMatch) + family->isBold = weight >= FC_WEIGHT_BOLD; + else + family->isBold = false; + int slant; + if (FcPatternGetInteger(current, FC_SLANT, 0, &slant) == FcResultMatch) + family->isItalic = slant != FC_SLANT_ROMAN; + else + family->isItalic = false; FcFontSetDestroy(fontSet); - return result; + return; } FcFontSetDestroy(fontSet); - return WebCString(); } void WebFontInfo::renderStyleForStrike(const char* family, int sizeAndStyle, WebFontRenderStyle* out) -- GitLab