[chromium] don't call fontconfig twice in complex text path
authorbashi@chromium.org <bashi@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 17 Nov 2011 12:16:57 +0000 (12:16 +0000)
committerbashi@chromium.org <bashi@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 17 Nov 2011 12:16:57 +0000 (12:16 +0000)
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: https://svn.webkit.org/repository/webkit/trunk@100601 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/platform/chromium/PlatformSupport.h
Source/WebCore/platform/graphics/chromium/FontCacheLinux.cpp
Source/WebCore/platform/graphics/chromium/FontPlatformDataLinux.h
Source/WebKit/chromium/ChangeLog
Source/WebKit/chromium/public/linux/WebFontFamily.h [new file with mode: 0644]
Source/WebKit/chromium/public/linux/WebFontInfo.h
Source/WebKit/chromium/public/linux/WebSandboxSupport.h
Source/WebKit/chromium/src/PlatformSupport.cpp
Source/WebKit/chromium/src/linux/WebFontInfo.cpp

index a1ba313..0c189cb 100644 (file)
@@ -1,3 +1,21 @@
+2011-11-17  Kenichi Ishibashi  <bashi@chromium.org>
+
+        [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  <msanchez@igalia.com>
 
         [GTK] Consider parent AtkObject in webkit_accessible_get_parent(), if already set
index 413edfc..68ba794 100644 (file)
@@ -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 --------------------------------------------------------------
index 4dd660d..eca7b03 100644 (file)
@@ -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)
index 86b941c..10dce90 100644 (file)
@@ -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(); }
index 632b07f..578cf3c 100644 (file)
@@ -1,3 +1,21 @@
+2011-11-17  Kenichi Ishibashi  <bashi@chromium.org>
+
+        [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  <abarth@webkit.org>
 
         [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 (file)
index 0000000..47f0378
--- /dev/null
@@ -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
index 5d52584..9b3472b 100644 (file)
@@ -32,6 +32,7 @@
 #define WebFontInfo_h
 
 #include "../WebCString.h"
+#include "../linux/WebFontFamily.h"
 #include "../linux/WebFontRenderStyle.h"
 
 #include <string.h>
@@ -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.
index 2f57929..4283df3 100644 (file)
@@ -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;
 };
 
index f1f6686..7ed75cc 100644 (file)
@@ -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
 }
 
index 49182d4..4d303d2 100644 (file)
@@ -31,6 +31,7 @@
 #include "config.h"
 #include "WebFontInfo.h"
 
+#include "WebFontFamily.h"
 #include "WebFontRenderStyle.h"
 
 #include <fontconfig/fontconfig.h>
 
 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) {
         if (U16_IS_SURROGATE(characters[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<char*>(cFilename), R_OK))
             continue;
 
-        FcChar8* family;
-        WebCString result;
-        if (FcPatternGetString(current, FC_FAMILY, 0, &family) == FcResultMatch) {
-            const char* charFamily = reinterpret_cast<char*>(family);
-            result = WebCString(charFamily, strlen(charFamily));
+        FcChar8* familyName;
+        if (FcPatternGetString(current, FC_FAMILY, 0, &familyName) == FcResultMatch) {
+            const char* charFamily = reinterpret_cast<char*>(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)