Unreviewed manual rollout of r239100-r239102 and r239114
authormcatanzaro@igalia.com <mcatanzaro@igalia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 12 Dec 2018 19:02:53 +0000 (19:02 +0000)
committermcatanzaro@igalia.com <mcatanzaro@igalia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 12 Dec 2018 19:02:53 +0000 (19:02 +0000)
https://bugs.webkit.org/show_bug.cgi?id=192151
<rdar://problem/46655586>

.:

* Source/cmake/OptionsGTK.cmake:

Source/WebCore:

* css/CSSFontFaceSource.cpp:
(WebCore::CSSFontFaceSource::font):
* loader/cache/CachedFont.cpp:
(WebCore::CachedFont::platformDataFromCustomData):
* platform/FreeType.cmake:
* platform/graphics/FontPlatformData.h:
(WebCore::FontPlatformData::isFixedWidth const): Deleted.
* platform/graphics/cairo/FontCustomPlatformData.h:
* platform/graphics/freetype/FontCacheFreeType.cpp:
(WebCore::FontCache::systemFallbackForCharacters):
(WebCore::FontCache::createFontPlatformData):
(WebCore::getFontPropertiesFromPattern): Deleted.
(WebCore::defaultVariationValues): Deleted.
(WebCore::buildVariationSettings): Deleted.
* platform/graphics/freetype/FontCacheFreeType.h: Removed.
* platform/graphics/freetype/FontCustomPlatformDataFreeType.cpp:
(WebCore::FontCustomPlatformData::FontCustomPlatformData):
(WebCore::FontCustomPlatformData::~FontCustomPlatformData):
(WebCore::FontCustomPlatformData::fontPlatformData):
(WebCore::FontCustomPlatformData::supportsFormat):
(WebCore::defaultFontconfigOptions): Deleted.
* platform/graphics/freetype/FontPlatformDataFreeType.cpp:
(WebCore::setCairoFontOptionsFromFontConfigPattern):
(WebCore::getDefaultFontconfigOptions):
(WebCore::FontPlatformData::FontPlatformData):
(WebCore::FontPlatformData::operator=):
(WebCore::FontPlatformData::harfBuzzFace const):
(WebCore::FontPlatformData::platformIsEqual const):
(WebCore::FontPlatformData::buildScaledFont):
(WebCore::FontPlatformData::fcPattern const): Deleted.
(WebCore::FontPlatformData::createOpenTypeMathHarfBuzzFont const): Deleted.
* platform/graphics/freetype/SimpleFontDataFreeType.cpp:
(WebCore::Font::platformCreateScaledFont const):
* platform/graphics/harfbuzz/ComplexTextControllerHarfBuzz.cpp:
(WebCore::fontFeatures):
(WebCore::ComplexTextController::collectComplexTextRunsForCharacters):
(WebCore::floatToHarfBuzzPosition): Deleted.
(WebCore::doubleToHarfBuzzPosition): Deleted.
(WebCore::harfBuzzFontFunctions): Deleted.
(WebCore::findScriptForVerticalGlyphSubstitution): Deleted.
* platform/graphics/harfbuzz/HarfBuzzFace.cpp: Added.
(WebCore::HarfBuzzFace::CacheEntry::CacheEntry):
(WebCore::HarfBuzzFace::CacheEntry::~CacheEntry):
(WebCore::HarfBuzzFace::cache):
(WebCore::HarfBuzzFace::HarfBuzzFace):
(WebCore::HarfBuzzFace::~HarfBuzzFace):
(WebCore::findScriptForVerticalGlyphSubstitution):
(WebCore::HarfBuzzFace::setScriptForVerticalGlyphSubstitution):
* platform/graphics/harfbuzz/HarfBuzzFace.h: Added.
(WebCore::HarfBuzzFace::CacheEntry::create):
(WebCore::HarfBuzzFace::CacheEntry::face):
(WebCore::HarfBuzzFace::CacheEntry::glyphCache):
* platform/graphics/harfbuzz/HarfBuzzFaceCairo.cpp: Added.
(WebCore::floatToHarfBuzzPosition):
(WebCore::doubleToHarfBuzzPosition):
(WebCore::CairoGetGlyphWidthAndExtents):
(WebCore::harfBuzzGetGlyph):
(WebCore::harfBuzzGetGlyphHorizontalAdvance):
(WebCore::harfBuzzGetGlyphHorizontalOrigin):
(WebCore::harfBuzzGetGlyphExtents):
(WebCore::harfBuzzCairoTextGetFontFuncs):
(WebCore::harfBuzzCairoGetTable):
(WebCore::HarfBuzzFace::createFace):
(WebCore::HarfBuzzFace::createFont):
* platform/graphics/harfbuzz/HbUniquePtr.h:
(WebCore::HbPtrDeleter<hb_face_t>::operator() const): Deleted.
* platform/graphics/opentype/OpenTypeMathData.cpp:
(WebCore::OpenTypeMathData::OpenTypeMathData):
* platform/graphics/win/FontCustomPlatformData.cpp:
(WebCore::FontCustomPlatformData::fontPlatformData):
* platform/graphics/win/FontCustomPlatformData.h:
* platform/graphics/win/FontCustomPlatformDataCairo.cpp:
(WebCore::FontCustomPlatformData::fontPlatformData):

Tools:

* gtk/jhbuild.modules:
* gtk/patches/cairo-ft-Use-FT_Done_MM_Var-instead-of-free-when-available.patch: Removed.

LayoutTests:

* platform/gtk/TestExpectations:
* platform/gtk/mathml/opentype/opentype-stretchy-expected.png:
* platform/gtk/mathml/opentype/opentype-stretchy-expected.txt:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@239122 268f45cc-cd09-0410-ab3c-d52691b4dbfc

29 files changed:
ChangeLog
LayoutTests/ChangeLog
LayoutTests/platform/gtk/TestExpectations
LayoutTests/platform/gtk/mathml/opentype/opentype-stretchy-expected.png
LayoutTests/platform/gtk/mathml/opentype/opentype-stretchy-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/css/CSSFontFaceSource.cpp
Source/WebCore/loader/cache/CachedFont.cpp
Source/WebCore/platform/FreeType.cmake
Source/WebCore/platform/graphics/FontPlatformData.h
Source/WebCore/platform/graphics/cairo/FontCustomPlatformData.h
Source/WebCore/platform/graphics/freetype/FontCacheFreeType.cpp
Source/WebCore/platform/graphics/freetype/FontCacheFreeType.h [deleted file]
Source/WebCore/platform/graphics/freetype/FontCustomPlatformDataFreeType.cpp
Source/WebCore/platform/graphics/freetype/FontPlatformDataFreeType.cpp
Source/WebCore/platform/graphics/freetype/SimpleFontDataFreeType.cpp
Source/WebCore/platform/graphics/harfbuzz/ComplexTextControllerHarfBuzz.cpp
Source/WebCore/platform/graphics/harfbuzz/HarfBuzzFace.cpp [new file with mode: 0644]
Source/WebCore/platform/graphics/harfbuzz/HarfBuzzFace.h [new file with mode: 0644]
Source/WebCore/platform/graphics/harfbuzz/HarfBuzzFaceCairo.cpp [new file with mode: 0644]
Source/WebCore/platform/graphics/harfbuzz/HbUniquePtr.h
Source/WebCore/platform/graphics/opentype/OpenTypeMathData.cpp
Source/WebCore/platform/graphics/win/FontCustomPlatformData.cpp
Source/WebCore/platform/graphics/win/FontCustomPlatformData.h
Source/WebCore/platform/graphics/win/FontCustomPlatformDataCairo.cpp
Source/cmake/OptionsGTK.cmake
Tools/ChangeLog
Tools/gtk/jhbuild.modules
Tools/gtk/patches/cairo-ft-Use-FT_Done_MM_Var-instead-of-free-when-available.patch [deleted file]

index 4b999e3..dc37fad 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2018-12-12  Michael Catanzaro  <mcatanzaro@igalia.com>
+
+        Unreviewed manual rollout of r239100-r239102 and r239114
+        https://bugs.webkit.org/show_bug.cgi?id=192151
+        <rdar://problem/46655586>
+
+        * Source/cmake/OptionsGTK.cmake:
+
 2018-12-12  Carlos Garcia Campos  <cgarcia@igalia.com>
 
         [FreeType] Add initial implementation of variation fonts
index a94e754..da117fc 100644 (file)
@@ -1,3 +1,13 @@
+2018-12-12  Michael Catanzaro  <mcatanzaro@igalia.com>
+
+        Unreviewed manual rollout of r239100-r239102 and r239114
+        https://bugs.webkit.org/show_bug.cgi?id=192151
+        <rdar://problem/46655586>
+
+        * platform/gtk/TestExpectations:
+        * platform/gtk/mathml/opentype/opentype-stretchy-expected.png:
+        * platform/gtk/mathml/opentype/opentype-stretchy-expected.txt:
+
 2018-12-12  Carlos Garcia Campos  <cgarcia@igalia.com>
 
         [FreeType] Remove HarfBuzzFace
index 2aad6a7..46aede2 100644 (file)
@@ -1046,6 +1046,11 @@ webkit.org/b/161586 css3/font-feature-settings-font-face-rendering.html [ ImageO
 
 webkit.org/b/161962 fast/forms/implicit-submission.html [ Failure ]
 
+# Font variations build flag is turned off
+webkit.org/b/162815 fast/text/variations/ [ Skip ]
+webkit.org/b/162815 animations/font-variations/ [ Skip ]
+webkit.org/b/162815 legacy-animation-engine/animations/font-variations/ [ Skip ]
+
 webkit.org/b/169531 fast/text/font-selection-font-face-parse.html [ Skip ]
 
 # CSS image-orientation is not yet enabled.
@@ -3637,10 +3642,6 @@ webkit.org/b/192434 fast/inline/inline-content-with-float-and-margin.html [ Fail
 webkit.org/b/166536 fast/canvas/webgl/hide-some-renderer-info.html [ Failure ]
 webkit.org/b/192435 fast/css-custom-paint/leaks.html [ Failure ]
 
-webkit.org/b/162815 fast/text/variations/font-face-clamp.html [ ImageOnlyFailure ]
-webkit.org/b/162815 fast/text/variations/font-selection-properties.html [ ImageOnlyFailure ]
-webkit.org/b/162815 fast/text/variations/skia-postscript-name.html [ ImageOnlyFailure ]
-
 #////////////////////////////////////////////////////////////////////////////////////////
 # End of non-crashing, non-flaky tests failing
 #////////////////////////////////////////////////////////////////////////////////////////
index 0585a0e..35ebe73 100644 (file)
Binary files a/LayoutTests/platform/gtk/mathml/opentype/opentype-stretchy-expected.png and b/LayoutTests/platform/gtk/mathml/opentype/opentype-stretchy-expected.png differ
index 2591cf3..892e925 100644 (file)
@@ -1,8 +1,8 @@
 layer at (0,0) size 800x600
   RenderView at (0,0) size 800x600
-layer at (0,0) size 800x350
-  RenderBlock {HTML} at (0,0) size 800x350
-    RenderBody {BODY} at (8,16) size 784x318
+layer at (0,0) size 800x339
+  RenderBlock {HTML} at (0,0) size 800x339
+    RenderBody {BODY} at (8,16) size 784x307
       RenderBlock {P} at (0,0) size 784x35
         RenderMathMLMath {math} at (0,20) size 26x11
           RenderMathMLRow {mrow} at (0,0) size 26x11
@@ -35,10 +35,10 @@ layer at (0,0) size 800x350
                 RenderText {#text} at (0,-3) size 2x0
                   text run at (0,-3) width 2: "\x{219F}"
         RenderText {#text} at (0,0) size 0x0
-      RenderBlock {P} at (0,221) size 784x97
-        RenderMathMLMath {math} at (0,0) size 94x93
-          RenderMathMLRow {mrow} at (0,0) size 94x93
-            RenderMathMLOperator {mo} at (0,0) size 94x93
+      RenderBlock {P} at (0,221) size 784x86
+        RenderMathMLMath {math} at (0,0) size 84x82
+          RenderMathMLRow {mrow} at (0,0) size 84x82
+            RenderMathMLOperator {mo} at (0,0) size 84x82
               RenderBlock (anonymous) at (0,0) size 10x12
                 RenderText {#text} at (0,6) size 10x0
                   text run at (0,6) width 10: "\x{2A1B}"
index f1f419e..f959421 100644 (file)
@@ -1,3 +1,83 @@
+2018-12-12  Michael Catanzaro  <mcatanzaro@igalia.com>
+
+        Unreviewed manual rollout of r239100-r239102 and r239114
+        https://bugs.webkit.org/show_bug.cgi?id=192151
+        <rdar://problem/46655586>
+
+        * css/CSSFontFaceSource.cpp:
+        (WebCore::CSSFontFaceSource::font):
+        * loader/cache/CachedFont.cpp:
+        (WebCore::CachedFont::platformDataFromCustomData):
+        * platform/FreeType.cmake:
+        * platform/graphics/FontPlatformData.h:
+        (WebCore::FontPlatformData::isFixedWidth const): Deleted.
+        * platform/graphics/cairo/FontCustomPlatformData.h:
+        * platform/graphics/freetype/FontCacheFreeType.cpp:
+        (WebCore::FontCache::systemFallbackForCharacters):
+        (WebCore::FontCache::createFontPlatformData):
+        (WebCore::getFontPropertiesFromPattern): Deleted.
+        (WebCore::defaultVariationValues): Deleted.
+        (WebCore::buildVariationSettings): Deleted.
+        * platform/graphics/freetype/FontCacheFreeType.h: Removed.
+        * platform/graphics/freetype/FontCustomPlatformDataFreeType.cpp:
+        (WebCore::FontCustomPlatformData::FontCustomPlatformData):
+        (WebCore::FontCustomPlatformData::~FontCustomPlatformData):
+        (WebCore::FontCustomPlatformData::fontPlatformData):
+        (WebCore::FontCustomPlatformData::supportsFormat):
+        (WebCore::defaultFontconfigOptions): Deleted.
+        * platform/graphics/freetype/FontPlatformDataFreeType.cpp:
+        (WebCore::setCairoFontOptionsFromFontConfigPattern):
+        (WebCore::getDefaultFontconfigOptions):
+        (WebCore::FontPlatformData::FontPlatformData):
+        (WebCore::FontPlatformData::operator=):
+        (WebCore::FontPlatformData::harfBuzzFace const):
+        (WebCore::FontPlatformData::platformIsEqual const):
+        (WebCore::FontPlatformData::buildScaledFont):
+        (WebCore::FontPlatformData::fcPattern const): Deleted.
+        (WebCore::FontPlatformData::createOpenTypeMathHarfBuzzFont const): Deleted.
+        * platform/graphics/freetype/SimpleFontDataFreeType.cpp:
+        (WebCore::Font::platformCreateScaledFont const):
+        * platform/graphics/harfbuzz/ComplexTextControllerHarfBuzz.cpp:
+        (WebCore::fontFeatures):
+        (WebCore::ComplexTextController::collectComplexTextRunsForCharacters):
+        (WebCore::floatToHarfBuzzPosition): Deleted.
+        (WebCore::doubleToHarfBuzzPosition): Deleted.
+        (WebCore::harfBuzzFontFunctions): Deleted.
+        (WebCore::findScriptForVerticalGlyphSubstitution): Deleted.
+        * platform/graphics/harfbuzz/HarfBuzzFace.cpp: Added.
+        (WebCore::HarfBuzzFace::CacheEntry::CacheEntry):
+        (WebCore::HarfBuzzFace::CacheEntry::~CacheEntry):
+        (WebCore::HarfBuzzFace::cache):
+        (WebCore::HarfBuzzFace::HarfBuzzFace):
+        (WebCore::HarfBuzzFace::~HarfBuzzFace):
+        (WebCore::findScriptForVerticalGlyphSubstitution):
+        (WebCore::HarfBuzzFace::setScriptForVerticalGlyphSubstitution):
+        * platform/graphics/harfbuzz/HarfBuzzFace.h: Added.
+        (WebCore::HarfBuzzFace::CacheEntry::create):
+        (WebCore::HarfBuzzFace::CacheEntry::face):
+        (WebCore::HarfBuzzFace::CacheEntry::glyphCache):
+        * platform/graphics/harfbuzz/HarfBuzzFaceCairo.cpp: Added.
+        (WebCore::floatToHarfBuzzPosition):
+        (WebCore::doubleToHarfBuzzPosition):
+        (WebCore::CairoGetGlyphWidthAndExtents):
+        (WebCore::harfBuzzGetGlyph):
+        (WebCore::harfBuzzGetGlyphHorizontalAdvance):
+        (WebCore::harfBuzzGetGlyphHorizontalOrigin):
+        (WebCore::harfBuzzGetGlyphExtents):
+        (WebCore::harfBuzzCairoTextGetFontFuncs):
+        (WebCore::harfBuzzCairoGetTable):
+        (WebCore::HarfBuzzFace::createFace):
+        (WebCore::HarfBuzzFace::createFont):
+        * platform/graphics/harfbuzz/HbUniquePtr.h:
+        (WebCore::HbPtrDeleter<hb_face_t>::operator() const): Deleted.
+        * platform/graphics/opentype/OpenTypeMathData.cpp:
+        (WebCore::OpenTypeMathData::OpenTypeMathData):
+        * platform/graphics/win/FontCustomPlatformData.cpp:
+        (WebCore::FontCustomPlatformData::fontPlatformData):
+        * platform/graphics/win/FontCustomPlatformData.h:
+        * platform/graphics/win/FontCustomPlatformDataCairo.cpp:
+        (WebCore::FontCustomPlatformData::fontPlatformData):
+
 2018-12-12  Chris Dumez  <cdumez@apple.com>
 
         Unreviewed attempt to fix Windows Cairo build after r239100.
index 33a8589..dc2bd7e 100644 (file)
@@ -232,7 +232,11 @@ RefPtr<Font> CSSFontFaceSource::font(const FontDescription& fontDescription, boo
         return nullptr;
     if (!m_inDocumentCustomPlatformData)
         return nullptr;
+#if PLATFORM(COCOA)
     return Font::create(m_inDocumentCustomPlatformData->fontPlatformData(fontDescription, syntheticBold, syntheticItalic, fontFaceFeatures, fontFaceVariantSettings, fontFaceCapabilities), Font::Origin::Remote);
+#else
+    return Font::create(m_inDocumentCustomPlatformData->fontPlatformData(fontDescription, syntheticBold, syntheticItalic), Font::Origin::Remote);
+#endif
 #endif
 
     ASSERT_NOT_REACHED();
index 8d47754..f60a38c 100644 (file)
@@ -141,7 +141,14 @@ FontPlatformData CachedFont::platformDataFromCustomData(const FontDescription& f
 
 FontPlatformData CachedFont::platformDataFromCustomData(FontCustomPlatformData& fontCustomPlatformData, const FontDescription& fontDescription, bool bold, bool italic, const FontFeatureSettings& fontFaceFeatures, const FontVariantSettings& fontFaceVariantSettings, FontSelectionSpecifiedCapabilities fontFaceCapabilities)
 {
+#if PLATFORM(COCOA)
     return fontCustomPlatformData.fontPlatformData(fontDescription, bold, italic, fontFaceFeatures, fontFaceVariantSettings, fontFaceCapabilities);
+#else
+    UNUSED_PARAM(fontFaceFeatures);
+    UNUSED_PARAM(fontFaceVariantSettings);
+    UNUSED_PARAM(fontFaceCapabilities);
+    return fontCustomPlatformData.fontPlatformData(fontDescription, bold, italic);
+#endif
 }
 
 void CachedFont::allClientsRemoved()
index c16977f..98f3ee1 100644 (file)
@@ -11,6 +11,7 @@ list(APPEND WebCore_SOURCES
     platform/graphics/freetype/SimpleFontDataFreeType.cpp
 
     platform/graphics/harfbuzz/ComplexTextControllerHarfBuzz.cpp
+    platform/graphics/harfbuzz/HarfBuzzFace.cpp
 )
 
 if (PORT STREQUAL "GTK")
@@ -26,6 +27,8 @@ endif ()
 if (USE_CAIRO)
     list(APPEND WebCore_SOURCES
         platform/graphics/cairo/FontCairoHarfbuzzNG.cpp
+
+        platform/graphics/harfbuzz/HarfBuzzFaceCairo.cpp
     )
 endif ()
 
index 8a17c8b..0ecf886 100644 (file)
@@ -40,7 +40,7 @@
 
 #if USE(FREETYPE)
 #include "FcUniquePtr.h"
-#include "HbUniquePtr.h"
+#include "HarfBuzzFace.h"
 #include "RefPtrFontconfig.h"
 #include <memory>
 #endif
@@ -112,7 +112,8 @@ public:
 #endif
 
 #if USE(FREETYPE)
-    FontPlatformData(cairo_font_face_t*, FcPattern*, float size, bool fixedWidth, bool syntheticBold, bool syntheticOblique, FontOrientation);
+    FontPlatformData(FcPattern*, const FontDescription&);
+    FontPlatformData(cairo_font_face_t*, const FontDescription&, bool syntheticBold, bool syntheticOblique);
     FontPlatformData(const FontPlatformData&);
     FontPlatformData(FontPlatformData&&) = default;
     FontPlatformData& operator=(const FontPlatformData&);
@@ -168,10 +169,8 @@ public:
 #endif
 
 #if USE(FREETYPE)
-    HbUniquePtr<hb_font_t> createOpenTypeMathHarfBuzzFont() const;
+    HarfBuzzFace& harfBuzzFace() const;
     bool hasCompatibleCharmap() const;
-    FcPattern* fcPattern() const;
-    bool isFixedWidth() const { return m_fixedWidth; }
 #endif
 
     unsigned hash() const;
@@ -249,6 +248,7 @@ private:
 
 #if USE(FREETYPE)
     RefPtr<FcPattern> m_pattern;
+    mutable std::unique_ptr<HarfBuzzFace> m_harfBuzzFace;
 #endif
 
     // The values below are common to all ports
index c31cc6e..c0d72ec 100644 (file)
  *
  */
 
-#pragma once
+#ifndef FontCustomPlatformData_h
+#define FontCustomPlatformData_h
 
 #if USE(CAIRO)
 
-#include "RefPtrCairo.h"
 #include <wtf/Forward.h>
 #include <wtf/Noncopyable.h>
 
 typedef struct FT_FaceRec_*  FT_Face;
+typedef struct _cairo_font_face cairo_font_face_t;
 
 namespace WebCore {
 
 class FontDescription;
 class FontPlatformData;
 class SharedBuffer;
-struct FontSelectionSpecifiedCapabilities;
-struct FontVariantSettings;
-
-template <typename T> class FontTaggedSettings;
-typedef FontTaggedSettings<int> FontFeatureSettings;
 
 struct FontCustomPlatformData {
     WTF_MAKE_NONCOPYABLE(FontCustomPlatformData);
 public:
     FontCustomPlatformData(FT_Face, SharedBuffer&);
-    ~FontCustomPlatformData() = default;
-    FontPlatformData fontPlatformData(const FontDescription&, bool bold, bool italic, const FontFeatureSettings&, const FontVariantSettings&, FontSelectionSpecifiedCapabilities);
+    ~FontCustomPlatformData();
+    FontPlatformData fontPlatformData(const FontDescription&, bool bold, bool italic);
     static bool supportsFormat(const String&);
 
 private:
-    RefPtr<cairo_font_face_t> m_fontFace;
+    cairo_font_face_t* m_fontFace;
 };
 
 std::unique_ptr<FontCustomPlatformData> createFontCustomPlatformData(SharedBuffer&, const String&);
@@ -57,3 +53,5 @@ std::unique_ptr<FontCustomPlatformData> createFontCustomPlatformData(SharedBuffe
 } // namespace WebCore
 
 #endif // USE(CAIRO)
+
+#endif // FontCustomPlatformData_h
index c446edb..860fc6b 100644 (file)
 #include "config.h"
 #include "FontCache.h"
 
-#include "CairoUniquePtr.h"
 #include "CairoUtilities.h"
 #include "FcUniquePtr.h"
-#include "FloatConversion.h"
 #include "Font.h"
-#include "FontDescription.h"
-#include "FontCacheFreeType.h"
 #include "RefPtrCairo.h"
 #include "RefPtrFontconfig.h"
 #include "UTF16UChar32Iterator.h"
 #include "GtkUtilities.h"
 #endif
 
-#if ENABLE(VARIATION_FONTS)
-#include FT_MULTIPLE_MASTERS_H
-#endif
-
 namespace WebCore {
 
 void FontCache::platformInit()
@@ -87,37 +79,6 @@ static bool configurePatternForFontDescription(FcPattern* pattern, const FontDes
     return true;
 }
 
-static void getFontPropertiesFromPattern(FcPattern* pattern, const FontDescription& fontDescription, bool& fixedWidth, bool& syntheticBold, bool& syntheticOblique)
-{
-    fixedWidth = false;
-    int spacing;
-    if (FcPatternGetInteger(pattern, FC_SPACING, 0, &spacing) == FcResultMatch && spacing == FC_MONO)
-        fixedWidth = true;
-
-    syntheticBold = false;
-    bool descriptionAllowsSyntheticBold = fontDescription.fontSynthesis() & FontSynthesisWeight;
-    if (descriptionAllowsSyntheticBold && isFontWeightBold(fontDescription.weight())) {
-        // The FC_EMBOLDEN property instructs us to fake the boldness of the font.
-        FcBool fontConfigEmbolden = FcFalse;
-        if (FcPatternGetBool(pattern, FC_EMBOLDEN, 0, &fontConfigEmbolden) == FcResultMatch)
-            syntheticBold = fontConfigEmbolden;
-
-        // Fallback fonts may not have FC_EMBOLDEN activated even though it's necessary.
-        int weight = 0;
-        if (!syntheticBold && FcPatternGetInteger(pattern, FC_WEIGHT, 0, &weight) == FcResultMatch)
-            syntheticBold = syntheticBold || weight < FC_WEIGHT_DEMIBOLD;
-    }
-
-    // We requested an italic font, but Fontconfig gave us one that was neither oblique nor italic.
-    syntheticOblique = false;
-    int actualFontSlant;
-    bool descriptionAllowsSyntheticOblique = fontDescription.fontSynthesis() & FontSynthesisStyle;
-    if (descriptionAllowsSyntheticOblique && fontDescription.italic()
-        && FcPatternGetInteger(pattern, FC_SLANT, 0, &actualFontSlant) == FcResultMatch) {
-        syntheticOblique = actualFontSlant == FC_SLANT_ROMAN;
-    }
-}
-
 RefPtr<Font> FontCache::systemFallbackForCharacters(const FontDescription& description, const Font*, bool, const UChar* characters, unsigned length)
 {
     FcUniquePtr<FcCharSet> fontConfigCharSet(FcCharSetCreate());
@@ -145,11 +106,7 @@ RefPtr<Font> FontCache::systemFallbackForCharacters(const FontDescription& descr
     if (!resultPattern)
         return nullptr;
 
-    bool fixedWidth, syntheticBold, syntheticOblique;
-    getFontPropertiesFromPattern(resultPattern.get(), description, fixedWidth, syntheticBold, syntheticOblique);
-
-    RefPtr<cairo_font_face_t> fontFace = adoptRef(cairo_ft_font_face_create_for_pattern(resultPattern.get()));
-    FontPlatformData alternateFontData(fontFace.get(), resultPattern.get(), description.computedPixelSize(), fixedWidth, syntheticBold, syntheticOblique, description.orientation());
+    FontPlatformData alternateFontData(resultPattern.get(), description);
     return fontForPlatformData(alternateFontData);
 }
 
@@ -375,9 +332,6 @@ std::unique_ptr<FontPlatformData> FontCache::createFontPlatformData(const FontDe
     RefPtr<FcPattern> pattern = adoptRef(FcPatternCreate());
     // Never choose unscalable fonts, as they pixelate when displayed at different sizes.
     FcPatternAddBool(pattern.get(), FC_SCALABLE, FcTrue);
-#if ENABLE(VARIATION_FONTS)
-    FcPatternAddBool(pattern.get(), FC_VARIABLE, FcDontCare);
-#endif
     String familyNameString(getFamilyNameStringFromFamily(family));
     if (!FcPatternAddString(pattern.get(), FC_FAMILY, reinterpret_cast<const FcChar8*>(familyNameString.utf8().data())))
         return nullptr;
@@ -428,28 +382,10 @@ std::unique_ptr<FontPlatformData> FontCache::createFontPlatformData(const FontDe
     if (!matchedFontFamily)
         return nullptr;
 
-    bool fixedWidth, syntheticBold, syntheticOblique;
-    getFontPropertiesFromPattern(pattern.get(), fontDescription, fixedWidth, syntheticBold, syntheticOblique);
-
-    RefPtr<cairo_font_face_t> fontFace = adoptRef(cairo_ft_font_face_create_for_pattern(resultPattern.get()));
-#if ENABLE(VARIATION_FONTS)
-    // Cairo doesn't have API to get the FT_Face of an unscaled font, so we need to
-    // create a temporary scaled font to get the FT_Face.
-    CairoUniquePtr<cairo_font_options_t> options(cairo_font_options_copy(getDefaultCairoFontOptions()));
-    cairo_matrix_t matrix;
-    cairo_matrix_init_identity(&matrix);
-    RefPtr<cairo_scaled_font_t> scaledFont = adoptRef(cairo_scaled_font_create(fontFace.get(), &matrix, &matrix, options.get()));
-    CairoFtFaceLocker cairoFtFaceLocker(scaledFont.get());
-    if (FT_Face freeTypeFace = cairoFtFaceLocker.ftFace()) {
-        auto variants = buildVariationSettings(freeTypeFace, fontDescription);
-        if (!variants.isEmpty())
-            FcPatternAddString(resultPattern.get(), FC_FONT_VARIATIONS, reinterpret_cast<const FcChar8*>(variants.utf8().data()));
-    }
-#endif
-    auto platformData = std::make_unique<FontPlatformData>(fontFace.get(), resultPattern.get(), fontDescription.computedPixelSize(), fixedWidth, syntheticBold, syntheticOblique, fontDescription.orientation());
     // Verify that this font has an encoding compatible with Fontconfig. Fontconfig currently
     // supports three encodings in FcFreeTypeCharIndex: Unicode, Symbol and AppleRoman.
     // If this font doesn't have one of these three encodings, don't select it.
+    auto platformData = std::make_unique<FontPlatformData>(resultPattern.get(), fontDescription);
     if (!platformData->hasCompatibleCharmap())
         return nullptr;
 
@@ -461,67 +397,4 @@ const AtomicString& FontCache::platformAlternateFamilyName(const AtomicString&)
     return nullAtom();
 }
 
-#if ENABLE(VARIATION_FONTS)
-struct VariationDefaults {
-    float defaultValue;
-    float minimumValue;
-    float maximumValue;
-};
-
-typedef HashMap<FontTag, VariationDefaults, FourCharacterTagHash, FourCharacterTagHashTraits> VariationDefaultsMap;
-typedef HashMap<FontTag, float, FourCharacterTagHash, FourCharacterTagHashTraits> VariationsMap;
-
-static VariationDefaultsMap defaultVariationValues(FT_Face face)
-{
-    VariationDefaultsMap result;
-    FT_MM_Var* ftMMVar;
-    if (FT_Get_MM_Var(face, &ftMMVar))
-        return result;
-
-    for (unsigned i = 0; i < ftMMVar->num_axis; ++i) {
-        auto tag = ftMMVar->axis[i].tag;
-        auto b1 = 0xFF & (tag >> 24);
-        auto b2 = 0xFF & (tag >> 16);
-        auto b3 = 0xFF & (tag >> 8);
-        auto b4 = 0xFF & (tag >> 0);
-        FontTag resultKey = {{ static_cast<char>(b1), static_cast<char>(b2), static_cast<char>(b3), static_cast<char>(b4) }};
-        VariationDefaults resultValues = { narrowPrecisionToFloat(ftMMVar->axis[i].def / 65536.), narrowPrecisionToFloat(ftMMVar->axis[i].minimum / 65536.), narrowPrecisionToFloat(ftMMVar->axis[i].maximum / 65536.) };
-        result.set(resultKey, resultValues);
-    }
-    FT_Done_MM_Var(face->glyph->library, ftMMVar);
-    return result;
-}
-
-String buildVariationSettings(FT_Face face, const FontDescription& fontDescription)
-{
-    auto defaultValues = defaultVariationValues(face);
-    const auto& variations = fontDescription.variationSettings();
-
-    VariationsMap variationsToBeApplied;
-    auto applyVariation = [&](const FontTag& tag, float value) {
-        auto iterator = defaultValues.find(tag);
-        if (iterator == defaultValues.end())
-            return;
-        float valueToApply = clampTo(value, iterator->value.minimumValue, iterator->value.maximumValue);
-        variationsToBeApplied.set(tag, valueToApply);
-    };
-
-    for (auto& variation : variations)
-        applyVariation(variation.tag(), variation.value());
-
-    StringBuilder builder;
-    for (auto& variation : variationsToBeApplied) {
-        if (!builder.isEmpty())
-            builder.append(',');
-        builder.append(variation.key[0]);
-        builder.append(variation.key[1]);
-        builder.append(variation.key[2]);
-        builder.append(variation.key[3]);
-        builder.append('=');
-        builder.appendNumber(variation.value);
-    }
-    return builder.toString();
-}
-#endif // ENABLE(VARIATION_FONTS)
-
 }
diff --git a/Source/WebCore/platform/graphics/freetype/FontCacheFreeType.h b/Source/WebCore/platform/graphics/freetype/FontCacheFreeType.h
deleted file mode 100644 (file)
index 81e823c..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2018 Igalia S.L.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#pragma once
-
-typedef struct FT_FaceRec_* FT_Face;
-
-namespace WebCore {
-class FontDescription;
-
-#if ENABLE(VARIATION_FONTS)
-String buildVariationSettings(FT_Face, const FontDescription&);
-#endif
-};
index 13765f4..53625df 100644 (file)
 #include "config.h"
 #include "FontCustomPlatformData.h"
 
-#include "CairoUtilities.h"
-#include "FontCacheFreeType.h"
-#include "FontDescription.h"
 #include "FontPlatformData.h"
 #include "SharedBuffer.h"
 #include <cairo-ft.h>
 #include <cairo.h>
 #include <ft2build.h>
 #include FT_MODULE_H
-#include <mutex>
 
 namespace WebCore {
 
@@ -40,54 +36,29 @@ static void releaseCustomFontData(void* data)
     static_cast<SharedBuffer*>(data)->deref();
 }
 
-static cairo_user_data_key_t freeTypeFaceKey;
-
 FontCustomPlatformData::FontCustomPlatformData(FT_Face freeTypeFace, SharedBuffer& buffer)
-    : m_fontFace(adoptRef(cairo_ft_font_face_create_for_ft_face(freeTypeFace, FT_LOAD_DEFAULT)))
+    : m_fontFace(cairo_ft_font_face_create_for_ft_face(freeTypeFace, FT_LOAD_DEFAULT))
 {
     buffer.ref(); // This is balanced by the buffer->deref() in releaseCustomFontData.
     static cairo_user_data_key_t bufferKey;
-    cairo_font_face_set_user_data(m_fontFace.get(), &bufferKey, &buffer,
+    cairo_font_face_set_user_data(m_fontFace, &bufferKey, &buffer,
          static_cast<cairo_destroy_func_t>(releaseCustomFontData));
 
     // Cairo doesn't do FreeType reference counting, so we need to ensure that when
     // this cairo_font_face_t is destroyed, it cleans up the FreeType face as well.
-    cairo_font_face_set_user_data(m_fontFace.get(), &freeTypeFaceKey, freeTypeFace,
+    static cairo_user_data_key_t freeTypeFaceKey;
+    cairo_font_face_set_user_data(m_fontFace, &freeTypeFaceKey, freeTypeFace,
         reinterpret_cast<cairo_destroy_func_t>(reinterpret_cast<void(*)(void)>(FT_Done_Face)));
 }
 
-static FcPattern* defaultFontconfigOptions()
+FontCustomPlatformData::~FontCustomPlatformData()
 {
-    // Get some generic default settings from fontconfig for web fonts. Strategy
-    // from Behdad Esfahbod in https://code.google.com/p/chromium/issues/detail?id=173207#c35
-    // For web fonts, the hint style is overridden in FontCustomPlatformData::FontCustomPlatformData
-    // so Fontconfig will not affect the hint style, but it may disable hinting completely.
-    static FcPattern* pattern = nullptr;
-    static std::once_flag flag;
-    std::call_once(flag, [](FcPattern*) {
-        pattern = FcPatternCreate();
-        FcConfigSubstitute(nullptr, pattern, FcMatchPattern);
-        cairo_ft_font_options_substitute(getDefaultCairoFontOptions(), pattern);
-        FcDefaultSubstitute(pattern);
-        FcPatternDel(pattern, FC_FAMILY);
-        FcConfigSubstitute(nullptr, pattern, FcMatchFont);
-    }, pattern);
-    return pattern;
+    cairo_font_face_destroy(m_fontFace);
 }
 
-FontPlatformData FontCustomPlatformData::fontPlatformData(const FontDescription& description, bool bold, bool italic, const FontFeatureSettings&, const FontVariantSettings&, FontSelectionSpecifiedCapabilities)
+FontPlatformData FontCustomPlatformData::fontPlatformData(const FontDescription& description, bool bold, bool italic)
 {
-    auto* freeTypeFace = static_cast<FT_Face>(cairo_font_face_get_user_data(m_fontFace.get(), &freeTypeFaceKey));
-    ASSERT(freeTypeFace);
-    RefPtr<FcPattern> pattern = defaultFontconfigOptions();
-#if ENABLE(VARIATION_FONTS)
-    auto variants = buildVariationSettings(freeTypeFace, description);
-    if (!variants.isEmpty()) {
-        pattern = adoptRef(FcPatternDuplicate(pattern.get()));
-        FcPatternAddString(pattern.get(), FC_FONT_VARIATIONS, reinterpret_cast<const FcChar8*>(variants.utf8().data()));
-    }
-#endif
-    return FontPlatformData(m_fontFace.get(), pattern.get(), description.computedPixelSize(), freeTypeFace->face_flags & FT_FACE_FLAG_FIXED_WIDTH, bold, italic, description.orientation());
+    return FontPlatformData(m_fontFace, description, bold, italic);
 }
 
 static bool initializeFreeTypeLibrary(FT_Library& library)
@@ -139,14 +110,6 @@ bool FontCustomPlatformData::supportsFormat(const String& format)
         || equalLettersIgnoringASCIICase(format, "opentype")
 #if USE(WOFF2)
         || equalLettersIgnoringASCIICase(format, "woff2")
-#if ENABLE(VARIATION_FONTS)
-        || equalLettersIgnoringASCIICase(format, "woff2-variations")
-#endif
-#endif
-#if ENABLE(VARIATION_FONTS)
-        || equalLettersIgnoringASCIICase(format, "woff-variations")
-        || equalLettersIgnoringASCIICase(format, "truetype-variations")
-        || equalLettersIgnoringASCIICase(format, "opentype-variations")
 #endif
         || equalLettersIgnoringASCIICase(format, "woff");
 }
index 6162281..f77d6a4 100644 (file)
 #include "CairoUniquePtr.h"
 #include "CairoUtilities.h"
 #include "FontCache.h"
+#include "FontDescription.h"
 #include "SharedBuffer.h"
 #include <cairo-ft.h>
 #include <fontconfig/fcfreetype.h>
 #include <ft2build.h>
 #include FT_TRUETYPE_TABLES_H
-#include <hb-ft.h>
-#include <hb-ot.h>
 #include <wtf/MathExtras.h>
 #include <wtf/text/WTFString.h>
 
@@ -101,22 +100,74 @@ static void setCairoFontOptionsFromFontConfigPattern(cairo_font_options_t* optio
         cairo_font_options_set_hint_style(options, convertFontConfigHintStyle(integerResult));
     if (FcPatternGetBool(pattern, FC_HINTING, 0, &booleanResult) == FcResultMatch && !booleanResult)
         cairo_font_options_set_hint_style(options, CAIRO_HINT_STYLE_NONE);
+}
 
-#if ENABLE(VARIATION_FONTS)
-    FcChar8* variations;
-    if (FcPatternGetString(pattern, FC_FONT_VARIATIONS, 0, &variations) == FcResultMatch) {
-        cairo_font_options_set_variations(options, reinterpret_cast<char*>(variations));
-    }
-#endif
+static FcPattern* getDefaultFontconfigOptions()
+{
+    // Get some generic default settings from fontconfig for web fonts. Strategy
+    // from Behdad Esfahbod in https://code.google.com/p/chromium/issues/detail?id=173207#c35
+    // For web fonts, the hint style is overridden in FontCustomPlatformData::FontCustomPlatformData
+    // so Fontconfig will not affect the hint style, but it may disable hinting completely.
+    static FcPattern* pattern = nullptr;
+    static std::once_flag flag;
+    std::call_once(flag, [](FcPattern*) {
+        pattern = FcPatternCreate();
+        FcConfigSubstitute(nullptr, pattern, FcMatchPattern);
+        cairo_ft_font_options_substitute(getDefaultCairoFontOptions(), pattern);
+        FcDefaultSubstitute(pattern);
+        FcPatternDel(pattern, FC_FAMILY);
+        FcConfigSubstitute(nullptr, pattern, FcMatchFont);
+    }, pattern);
+    return pattern;
 }
 
-FontPlatformData::FontPlatformData(cairo_font_face_t* fontFace, FcPattern* pattern, float size, bool fixedWidth, bool syntheticBold, bool syntheticOblique, FontOrientation orientation)
-    : FontPlatformData(size, syntheticBold, syntheticOblique, orientation)
+FontPlatformData::FontPlatformData(FcPattern* pattern, const FontDescription& fontDescription)
+    : m_pattern(pattern)
+    , m_size(fontDescription.computedPixelSize())
+    , m_orientation(fontDescription.orientation())
 {
-    m_pattern = pattern;
-    m_fixedWidth = fixedWidth;
+    ASSERT(m_pattern);
+    RefPtr<cairo_font_face_t> fontFace = adoptRef(cairo_ft_font_face_create_for_pattern(m_pattern.get()));
+
+    int spacing;
+    if (FcPatternGetInteger(pattern, FC_SPACING, 0, &spacing) == FcResultMatch && spacing == FC_MONO)
+        m_fixedWidth = true;
+
+    bool descriptionAllowsSyntheticBold = fontDescription.fontSynthesis() & FontSynthesisWeight;
+    if (descriptionAllowsSyntheticBold && isFontWeightBold(fontDescription.weight())) {
+        // The FC_EMBOLDEN property instructs us to fake the boldness of the font.
+        FcBool fontConfigEmbolden = FcFalse;
+        if (FcPatternGetBool(pattern, FC_EMBOLDEN, 0, &fontConfigEmbolden) == FcResultMatch)
+            m_syntheticBold = fontConfigEmbolden;
+
+        // Fallback fonts may not have FC_EMBOLDEN activated even though it's necessary.
+        int weight = 0;
+        if (!m_syntheticBold && FcPatternGetInteger(pattern, FC_WEIGHT, 0, &weight) == FcResultMatch)
+            m_syntheticBold = m_syntheticBold || weight < FC_WEIGHT_DEMIBOLD;
+    }
 
+    // We requested an italic font, but Fontconfig gave us one that was neither oblique nor italic.
+    int actualFontSlant;
+    bool descriptionAllowsSyntheticOblique = fontDescription.fontSynthesis() & FontSynthesisStyle;
+    if (descriptionAllowsSyntheticOblique && fontDescription.italic()
+        && FcPatternGetInteger(pattern, FC_SLANT, 0, &actualFontSlant) == FcResultMatch) {
+        m_syntheticOblique = actualFontSlant == FC_SLANT_ROMAN;
+    }
+
+    buildScaledFont(fontFace.get());
+}
+
+FontPlatformData::FontPlatformData(cairo_font_face_t* fontFace, const FontDescription& description, bool bold, bool italic)
+    : m_size(description.computedPixelSize())
+    , m_orientation(description.orientation())
+    , m_syntheticBold(bold)
+    , m_syntheticOblique(italic)
+{
     buildScaledFont(fontFace);
+
+    CairoFtFaceLocker cairoFtFaceLocker(m_scaledFont.get());
+    if (FT_Face fontConfigFace = cairoFtFaceLocker.ftFace())
+        m_fixedWidth = fontConfigFace->face_flags & FT_FACE_FLAG_FIXED_WIDTH;
 }
 
 FontPlatformData::FontPlatformData(const FontPlatformData& other)
@@ -146,6 +197,9 @@ FontPlatformData& FontPlatformData::operator=(const FontPlatformData& other)
 
     m_scaledFont = other.m_scaledFont;
 
+    // This will be re-created on demand.
+    m_harfBuzzFace = nullptr;
+
     return *this;
 }
 
@@ -183,9 +237,11 @@ FontPlatformData FontPlatformData::cloneWithSize(const FontPlatformData& source,
     return copy;
 }
 
-FcPattern* FontPlatformData::fcPattern() const
+HarfBuzzFace& FontPlatformData::harfBuzzFace() const
 {
-    return m_pattern.get();
+    if (!m_harfBuzzFace)
+        m_harfBuzzFace = std::make_unique<HarfBuzzFace>(const_cast<FontPlatformData&>(*this), hash());
+    return *m_harfBuzzFace;
 }
 
 bool FontPlatformData::isFixedPitch() const
@@ -200,7 +256,10 @@ unsigned FontPlatformData::hash() const
 
 bool FontPlatformData::platformIsEqual(const FontPlatformData& other) const
 {
-    if (m_pattern != other.m_pattern && !FcPatternEqual(m_pattern.get(), other.m_pattern.get()))
+    // FcPatternEqual does not support null pointers as arguments.
+    if ((m_pattern && !other.m_pattern)
+        || (!m_pattern && other.m_pattern)
+        || (m_pattern != other.m_pattern && !FcPatternEqual(m_pattern.get(), other.m_pattern.get())))
         return false;
 
     return m_scaledFont == other.m_scaledFont;
@@ -215,9 +274,9 @@ String FontPlatformData::description() const
 
 void FontPlatformData::buildScaledFont(cairo_font_face_t* fontFace)
 {
-    ASSERT(m_pattern);
     CairoUniquePtr<cairo_font_options_t> options(cairo_font_options_copy(getDefaultCairoFontOptions()));
-    setCairoFontOptionsFromFontConfigPattern(options.get(), m_pattern.get());
+    FcPattern* optionsPattern = m_pattern ? m_pattern.get() : getDefaultFontconfigOptions();
+    setCairoFontOptionsFromFontConfigPattern(options.get(), optionsPattern);
 
     cairo_matrix_t ctm;
     cairo_matrix_init_identity(&ctm);
@@ -229,7 +288,7 @@ void FontPlatformData::buildScaledFont(cairo_font_face_t* fontFace)
     FcMatrixInit(&fontConfigMatrix);
 
     // These matrices may be stacked in the pattern, so it's our job to get them all and multiply them.
-    for (int i = 0; FcPatternGetMatrix(m_pattern.get(), FC_MATRIX, i, &tempFontConfigMatrix) == FcResultMatch; i++)
+    for (int i = 0; FcPatternGetMatrix(optionsPattern, FC_MATRIX, i, &tempFontConfigMatrix) == FcResultMatch; i++)
         FcMatrixMultiply(&fontConfigMatrix, &fontConfigMatrix, tempFontConfigMatrix);
 
     cairo_matrix_init(&fontMatrix, 1, -fontConfigMatrix.yx, -fontConfigMatrix.xy, 1, 0, 0);
@@ -293,18 +352,4 @@ RefPtr<SharedBuffer> FontPlatformData::openTypeTable(uint32_t table) const
     return SharedBuffer::create(WTFMove(data));
 }
 
-HbUniquePtr<hb_font_t> FontPlatformData::createOpenTypeMathHarfBuzzFont() const
-{
-    CairoFtFaceLocker cairoFtFaceLocker(m_scaledFont.get());
-    FT_Face ftFace = cairoFtFaceLocker.ftFace();
-    if (!ftFace)
-        return nullptr;
-
-    HbUniquePtr<hb_face_t> face(hb_ft_face_create_cached(ftFace));
-    if (!hb_ot_math_has_data(face.get()))
-        return nullptr;
-
-    return HbUniquePtr<hb_font_t>(hb_font_create(face.get()));
-}
-
 } // namespace WebCore
index 4bff7cc..622a3e6 100644 (file)
@@ -143,13 +143,12 @@ void Font::platformCharWidthInit()
 RefPtr<Font> Font::platformCreateScaledFont(const FontDescription& fontDescription, float scaleFactor) const
 {
     ASSERT(m_platformData.scaledFont());
+    FontDescription scaledFontDescription = fontDescription;
+    scaledFontDescription.setComputedSize(scaleFactor * fontDescription.computedSize());
     return Font::create(FontPlatformData(cairo_scaled_font_get_font_face(m_platformData.scaledFont()),
-        m_platformData.fcPattern(),
-        scaleFactor * fontDescription.computedSize(),
-        m_platformData.isFixedWidth(),
+        scaledFontDescription,
         m_platformData.syntheticBold(),
-        m_platformData.syntheticOblique(),
-        fontDescription.orientation()),
+        m_platformData.syntheticOblique()),
         origin(), Interstitial::No);
 }
 
index 4422697..27123d3 100644 (file)
 #include "config.h"
 #include "ComplexTextController.h"
 
-#include "CairoUtilities.h"
 #include "FontCascade.h"
 #include "HbUniquePtr.h"
 #include "SurrogatePairAwareTextIterator.h"
-#include <hb-ft.h>
 #include <hb-icu.h>
-#include <hb-ot.h>
-
-#if ENABLE(VARIATION_FONTS)
-#include FT_MULTIPLE_MASTERS_H
-#endif
 
 namespace WebCore {
 
@@ -45,90 +38,6 @@ static inline float harfBuzzPositionToFloat(hb_position_t value)
     return static_cast<float>(value) / (1 << 16);
 }
 
-static inline hb_position_t floatToHarfBuzzPosition(float value)
-{
-    return static_cast<hb_position_t>(value * (1 << 16));
-}
-
-static inline hb_position_t doubleToHarfBuzzPosition(double value)
-{
-    return static_cast<hb_position_t>(value * (1 << 16));
-}
-
-static hb_font_funcs_t* harfBuzzFontFunctions()
-{
-    static hb_font_funcs_t* fontFunctions = nullptr;
-
-    // We don't set callback functions which we can't support.
-    // Harfbuzz will use the fallback implementation if they aren't set.
-    if (!fontFunctions) {
-        fontFunctions = hb_font_funcs_create();
-#if HB_VERSION_ATLEAST(1, 2, 3)
-        hb_font_funcs_set_nominal_glyph_func(fontFunctions, [](hb_font_t*, void* context, hb_codepoint_t unicode, hb_codepoint_t* glyph, void*) -> hb_bool_t {
-            auto& font = *static_cast<Font*>(context);
-            *glyph = font.glyphForCharacter(unicode);
-            return !!*glyph;
-        }, nullptr, nullptr);
-
-        hb_font_funcs_set_variation_glyph_func(fontFunctions, [](hb_font_t*, void* context, hb_codepoint_t unicode, hb_codepoint_t variation, hb_codepoint_t* glyph, void*) -> hb_bool_t {
-            auto& font = *static_cast<Font*>(context);
-            auto* scaledFont = font.platformData().scaledFont();
-            ASSERT(scaledFont);
-
-            CairoFtFaceLocker cairoFtFaceLocker(scaledFont);
-            if (FT_Face ftFace = cairoFtFaceLocker.ftFace()) {
-                *glyph = FT_Face_GetCharVariantIndex(ftFace, unicode, variation);
-                return true;
-            }
-            return false;
-            }, nullptr, nullptr);
-#else
-        hb_font_funcs_set_glyph_func(fontFunctions, [](hb_font_t*, void* context, hb_codepoint_t unicode, hb_codepoint_t, hb_codepoint_t* glyph, void*) -> hb_bool_t {
-            auto& font = *static_cast<Font*>(context);
-            *glyph = font.glyphForCharacter(unicode);
-            return !!*glyph;
-        }, nullptr, nullptr);
-#endif
-        hb_font_funcs_set_glyph_h_advance_func(fontFunctions, [](hb_font_t*, void* context, hb_codepoint_t point, void*) -> hb_bool_t {
-            auto& font = *static_cast<Font*>(context);
-            auto* scaledFont = font.platformData().scaledFont();
-            ASSERT(scaledFont);
-
-            cairo_text_extents_t glyphExtents;
-            cairo_glyph_t glyph = { point, 0, 0 };
-            cairo_scaled_font_glyph_extents(scaledFont, &glyph, 1, &glyphExtents);
-
-            bool hasVerticalGlyphs = glyphExtents.y_advance;
-            return doubleToHarfBuzzPosition(hasVerticalGlyphs ? -glyphExtents.y_advance : glyphExtents.x_advance);
-        }, nullptr, nullptr);
-
-        hb_font_funcs_set_glyph_h_origin_func(fontFunctions, [](hb_font_t*, void*, hb_codepoint_t, hb_position_t*, hb_position_t*, void*) -> hb_bool_t {
-            // Just return true, following the way that Harfbuzz-FreeType implementation does.
-            return true;
-        }, nullptr, nullptr);
-
-        hb_font_funcs_set_glyph_extents_func(fontFunctions, [](hb_font_t*, void* context, hb_codepoint_t point, hb_glyph_extents_t* extents, void*) -> hb_bool_t {
-            auto& font = *static_cast<Font*>(context);
-            auto* scaledFont = font.platformData().scaledFont();
-            ASSERT(scaledFont);
-
-            cairo_text_extents_t glyphExtents;
-            cairo_glyph_t glyph = { point, 0, 0 };
-            cairo_scaled_font_glyph_extents(scaledFont, &glyph, 1, &glyphExtents);
-
-            bool hasVerticalGlyphs = glyphExtents.y_advance;
-            extents->x_bearing = doubleToHarfBuzzPosition(glyphExtents.x_bearing);
-            extents->y_bearing = doubleToHarfBuzzPosition(hasVerticalGlyphs ? -glyphExtents.y_bearing : glyphExtents.y_bearing);
-            extents->width = doubleToHarfBuzzPosition(hasVerticalGlyphs ? -glyphExtents.height : glyphExtents.width);
-            extents->height = doubleToHarfBuzzPosition(hasVerticalGlyphs ? glyphExtents.width : glyphExtents.height);
-            return true;
-        }, nullptr, nullptr);
-
-        hb_font_funcs_make_immutable(fontFunctions);
-    }
-    return fontFunctions;
-}
-
 ComplexTextController::ComplexTextRun::ComplexTextRun(hb_buffer_t* buffer, const Font& font, const UChar* characters, unsigned stringLocation, unsigned stringLength, unsigned indexBegin, unsigned indexEnd)
     : m_initialAdvance(0, 0)
     , m_font(font)
@@ -174,28 +83,25 @@ ComplexTextController::ComplexTextRun::ComplexTextRun(hb_buffer_t* buffer, const
     }
 }
 
-static const hb_tag_t s_vertTag = HB_TAG('v', 'e', 'r', 't');
-static const hb_tag_t s_vrt2Tag = HB_TAG('v', 'r', 't', '2');
-static const hb_tag_t s_kernTag = HB_TAG('k', 'e', 'r', 'n');
-static const unsigned s_hbEnd = static_cast<unsigned>(-1);
+static const unsigned hbEnd = static_cast<unsigned>(-1);
 
 static Vector<hb_feature_t, 4> fontFeatures(const FontCascade& font, FontOrientation orientation)
 {
     Vector<hb_feature_t, 4> features;
 
     if (orientation == FontOrientation::Vertical) {
-        features.append({ s_vertTag, 1, 0, s_hbEnd });
-        features.append({ s_vrt2Tag, 1, 0, s_hbEnd });
+        features.append({ HarfBuzzFace::vertTag, 1, 0, hbEnd });
+        features.append({ HarfBuzzFace::vrt2Tag, 1, 0, hbEnd });
     }
 
-    hb_feature_t kerning = { s_kernTag, 0, 0, s_hbEnd };
+    hb_feature_t kerning = { HarfBuzzFace::kernTag, 0, 0, hbEnd };
     if (font.enableKerning())
         kerning.value = 1;
     features.append(WTFMove(kerning));
 
     for (auto& feature : font.fontDescription().featureSettings()) {
         auto& tag = feature.tag();
-        features.append({ HB_TAG(tag[0], tag[1], tag[2], tag[3]), static_cast<uint32_t>(feature.value()), 0, s_hbEnd });
+        features.append({ HB_TAG(tag[0], tag[1], tag[2], tag[3]), static_cast<uint32_t>(feature.value()), 0, hbEnd });
     }
 
     return features;
@@ -262,27 +168,6 @@ static std::optional<HBRun> findNextRun(const UChar* characters, unsigned length
     return std::optional<HBRun>({ startIndex, textIterator.currentIndex(), currentScript.value() });
 }
 
-static hb_script_t findScriptForVerticalGlyphSubstitution(hb_face_t* face)
-{
-    static const unsigned maxCount = 32;
-
-    unsigned scriptCount = maxCount;
-    hb_tag_t scriptTags[maxCount];
-    hb_ot_layout_table_get_script_tags(face, HB_OT_TAG_GSUB, 0, &scriptCount, scriptTags);
-    for (unsigned scriptIndex = 0; scriptIndex < scriptCount; ++scriptIndex) {
-        unsigned languageCount = maxCount;
-        hb_tag_t languageTags[maxCount];
-        hb_ot_layout_script_get_language_tags(face, HB_OT_TAG_GSUB, scriptIndex, 0, &languageCount, languageTags);
-        for (unsigned languageIndex = 0; languageIndex < languageCount; ++languageIndex) {
-            unsigned featureIndex;
-            if (hb_ot_layout_language_find_feature(face, HB_OT_TAG_GSUB, scriptIndex, languageIndex, s_vertTag, &featureIndex)
-                || hb_ot_layout_language_find_feature(face, HB_OT_TAG_GSUB, scriptIndex, languageIndex, s_vrt2Tag, &featureIndex))
-                return hb_ot_tag_to_script(scriptTags[scriptIndex]);
-        }
-    }
-    return HB_SCRIPT_INVALID;
-}
-
 void ComplexTextController::collectComplexTextRunsForCharacters(const UChar* characters, unsigned length, unsigned stringLocation, const Font* font)
 {
     if (!font) {
@@ -306,50 +191,13 @@ void ComplexTextController::collectComplexTextRunsForCharacters(const UChar* cha
         return;
 
     const auto& fontPlatformData = font->platformData();
-    auto* scaledFont = fontPlatformData.scaledFont();
-    CairoFtFaceLocker cairoFtFaceLocker(scaledFont);
-    FT_Face ftFace = cairoFtFaceLocker.ftFace();
-    if (!ftFace)
-        return;
-
-    HbUniquePtr<hb_face_t> face(hb_ft_face_create_cached(ftFace));
-    HbUniquePtr<hb_font_t> harfBuzzFont(hb_font_create(face.get()));
-    hb_font_set_funcs(harfBuzzFont.get(), harfBuzzFontFunctions(), const_cast<Font*>(font), nullptr);
-    const float size = fontPlatformData.size();
-    if (floorf(size) == size)
-        hb_font_set_ppem(harfBuzzFont.get(), size, size);
-    int scale = floatToHarfBuzzPosition(size);
-    hb_font_set_scale(harfBuzzFont.get(), scale, scale);
-
-#if ENABLE(VARIATION_FONTS)
-    FT_MM_Var* ftMMVar;
-    if (!FT_Get_MM_Var(ftFace, &ftMMVar)) {
-        Vector<FT_Fixed, 4> coords;
-        coords.resize(ftMMVar->num_axis);
-        if (!FT_Get_Var_Design_Coordinates(ftFace, coords.size(), coords.data())) {
-            Vector<hb_variation_t, 4> variations(coords.size());
-            for (FT_UInt i = 0; i < ftMMVar->num_axis; ++i) {
-                variations[i].tag = ftMMVar->axis[i].tag;
-                variations[i].value = coords[i] / 65536.0;
-            }
-            hb_font_set_variations(harfBuzzFont.get(), variations.data(), variations.size());
-        }
-        FT_Done_MM_Var(ftFace->glyph->library, ftMMVar);
-    }
-#endif
-
-    hb_font_make_immutable(harfBuzzFont.get());
-
     auto features = fontFeatures(m_font, fontPlatformData.orientation());
     HbUniquePtr<hb_buffer_t> buffer(hb_buffer_create());
-    if (fontPlatformData.orientation() == FontOrientation::Vertical)
-        hb_buffer_set_script(buffer.get(), findScriptForVerticalGlyphSubstitution(face.get()));
 
     for (unsigned i = 0; i < runCount; ++i) {
         auto& run = runList[m_run.rtl() ? runCount - i - 1 : i];
 
-        if (fontPlatformData.orientation() != FontOrientation::Vertical)
-            hb_buffer_set_script(buffer.get(), hb_icu_script_to_script(run.script));
+        hb_buffer_set_script(buffer.get(), hb_icu_script_to_script(run.script));
         if (!m_mayUseNaturalWritingDirection || m_run.directionalOverride())
             hb_buffer_set_direction(buffer.get(), m_run.rtl() ? HB_DIRECTION_RTL : HB_DIRECTION_LTR);
         else {
@@ -358,6 +206,11 @@ void ComplexTextController::collectComplexTextRunsForCharacters(const UChar* cha
         }
         hb_buffer_add_utf16(buffer.get(), reinterpret_cast<const uint16_t*>(characters), length, run.startIndex, run.endIndex - run.startIndex);
 
+        auto& face = fontPlatformData.harfBuzzFace();
+        if (fontPlatformData.orientation() == FontOrientation::Vertical)
+            face.setScriptForVerticalGlyphSubstitution(buffer.get());
+
+        HbUniquePtr<hb_font_t> harfBuzzFont(face.createFont());
         hb_shape(harfBuzzFont.get(), buffer.get(), features.isEmpty() ? nullptr : features.data(), features.size());
         m_complexTextRuns.append(ComplexTextRun::create(buffer.get(), *font, characters, stringLocation, length, run.startIndex, run.endIndex));
         hb_buffer_reset(buffer.get());
diff --git a/Source/WebCore/platform/graphics/harfbuzz/HarfBuzzFace.cpp b/Source/WebCore/platform/graphics/harfbuzz/HarfBuzzFace.cpp
new file mode 100644 (file)
index 0000000..45691d8
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2012 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.
+ */
+
+#include "config.h"
+#include "HarfBuzzFace.h"
+
+#include "FontPlatformData.h"
+#include <hb-ot.h>
+#include <hb.h>
+#include <wtf/NeverDestroyed.h>
+
+namespace WebCore {
+
+const hb_tag_t HarfBuzzFace::vertTag = HB_TAG('v', 'e', 'r', 't');
+const hb_tag_t HarfBuzzFace::vrt2Tag = HB_TAG('v', 'r', 't', '2');
+const hb_tag_t HarfBuzzFace::kernTag = HB_TAG('k', 'e', 'r', 'n');
+
+// Though we have FontCache class, which provides the cache mechanism for
+// WebKit's font objects, we also need additional caching layer for HarfBuzz
+// to reduce the memory consumption because hb_face_t should be associated with
+// underling font data (e.g. CTFontRef, FTFace).
+
+HarfBuzzFace::CacheEntry::CacheEntry(hb_face_t* face)
+    : m_face(face)
+{
+    ASSERT(m_face);
+}
+
+HarfBuzzFace::CacheEntry::~CacheEntry()
+{
+    hb_face_destroy(m_face);
+}
+
+HarfBuzzFace::Cache& HarfBuzzFace::cache()
+{
+    static NeverDestroyed<Cache> s_cache;
+    return s_cache;
+}
+
+HarfBuzzFace::HarfBuzzFace(FontPlatformData& platformData, uint64_t uniqueID)
+    : m_platformData(platformData)
+    , m_uniqueID(uniqueID)
+    , m_scriptForVerticalText(HB_SCRIPT_INVALID)
+{
+    auto result = cache().add(m_uniqueID, nullptr);
+    if (result.isNewEntry)
+        result.iterator->value = CacheEntry::create(createFace());
+    m_cacheEntry = result.iterator->value;
+}
+
+HarfBuzzFace::~HarfBuzzFace()
+{
+    auto it = cache().find(m_uniqueID);
+    ASSERT(it != cache().end());
+    ASSERT(it->value == m_cacheEntry);
+    ASSERT(it->value->refCount() > 1);
+
+    m_cacheEntry = nullptr;
+    if (it->value->refCount() == 1)
+        cache().remove(it);
+}
+
+static hb_script_t findScriptForVerticalGlyphSubstitution(hb_face_t* face)
+{
+    static const unsigned maxCount = 32;
+
+    unsigned scriptCount = maxCount;
+    hb_tag_t scriptTags[maxCount];
+    hb_ot_layout_table_get_script_tags(face, HB_OT_TAG_GSUB, 0, &scriptCount, scriptTags);
+    for (unsigned scriptIndex = 0; scriptIndex < scriptCount; ++scriptIndex) {
+        unsigned languageCount = maxCount;
+        hb_tag_t languageTags[maxCount];
+        hb_ot_layout_script_get_language_tags(face, HB_OT_TAG_GSUB, scriptIndex, 0, &languageCount, languageTags);
+        for (unsigned languageIndex = 0; languageIndex < languageCount; ++languageIndex) {
+            unsigned featureIndex;
+            if (hb_ot_layout_language_find_feature(face, HB_OT_TAG_GSUB, scriptIndex, languageIndex, HarfBuzzFace::vertTag, &featureIndex)
+                || hb_ot_layout_language_find_feature(face, HB_OT_TAG_GSUB, scriptIndex, languageIndex, HarfBuzzFace::vrt2Tag, &featureIndex))
+                return hb_ot_tag_to_script(scriptTags[scriptIndex]);
+        }
+    }
+    return HB_SCRIPT_INVALID;
+}
+
+void HarfBuzzFace::setScriptForVerticalGlyphSubstitution(hb_buffer_t* buffer)
+{
+    if (m_scriptForVerticalText == HB_SCRIPT_INVALID)
+        m_scriptForVerticalText = findScriptForVerticalGlyphSubstitution(m_cacheEntry->face());
+    hb_buffer_set_script(buffer, m_scriptForVerticalText);
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/harfbuzz/HarfBuzzFace.h b/Source/WebCore/platform/graphics/harfbuzz/HarfBuzzFace.h
new file mode 100644 (file)
index 0000000..006d5f7
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2012 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 HarfBuzzFace_h
+#define HarfBuzzFace_h
+
+#include <hb.h>
+
+#include <memory>
+#include <wtf/FastMalloc.h>
+#include <wtf/HashMap.h>
+#include <wtf/Ref.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class FontPlatformData;
+
+class HarfBuzzFace {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    static const hb_tag_t vertTag;
+    static const hb_tag_t vrt2Tag;
+    static const hb_tag_t kernTag;
+
+    HarfBuzzFace(FontPlatformData&, uint64_t);
+    ~HarfBuzzFace();
+
+    hb_font_t* createFont();
+
+    void setScriptForVerticalGlyphSubstitution(hb_buffer_t*);
+
+    using GlyphCache = HashMap<uint32_t, uint32_t, DefaultHash<uint32_t>::Hash, WTF::UnsignedWithZeroKeyHashTraits<uint32_t>>;
+private:
+    class CacheEntry : public RefCounted<CacheEntry> {
+    public:
+        static Ref<CacheEntry> create(hb_face_t* face)
+        {
+            return adoptRef(*new CacheEntry(face));
+        }
+        ~CacheEntry();
+
+        hb_face_t* face() { return m_face; }
+        GlyphCache& glyphCache() { return m_glyphCache; }
+
+    private:
+        CacheEntry(hb_face_t*);
+
+        hb_face_t* m_face;
+        GlyphCache m_glyphCache;
+    };
+
+    using Cache = HashMap<uint64_t, RefPtr<CacheEntry>, WTF::IntHash<uint64_t>, WTF::UnsignedWithZeroKeyHashTraits<uint64_t>>;
+    static Cache& cache();
+
+    hb_face_t* createFace();
+
+    FontPlatformData& m_platformData;
+    uint64_t m_uniqueID;
+    RefPtr<CacheEntry> m_cacheEntry;
+
+    hb_script_t m_scriptForVerticalText;
+};
+
+}
+
+#endif // HarfBuzzFace_h
diff --git a/Source/WebCore/platform/graphics/harfbuzz/HarfBuzzFaceCairo.cpp b/Source/WebCore/platform/graphics/harfbuzz/HarfBuzzFaceCairo.cpp
new file mode 100644 (file)
index 0000000..b3fd8c0
--- /dev/null
@@ -0,0 +1,220 @@
+/*
+ * Copyright (c) 2012 Google Inc. All rights reserved.
+ * Copyright (c) 2012 Intel Corporation
+ *
+ * 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.
+ */
+
+#include "config.h"
+#include "HarfBuzzFace.h"
+
+#include "CairoUtilities.h"
+#include "Font.h"
+#include "FontCascade.h"
+#include "FontPlatformData.h"
+#include "GlyphBuffer.h"
+#include "TextEncoding.h"
+#include <cairo-ft.h>
+#include <cairo.h>
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include FT_TRUETYPE_TABLES_H
+#include <hb.h>
+#include <wtf/text/CString.h>
+#include <wtf/text/StringView.h>
+
+namespace WebCore {
+
+struct HarfBuzzFontData {
+    HarfBuzzFace::GlyphCache& glyphCacheForFaceCacheEntry;
+    RefPtr<cairo_scaled_font_t> cairoScaledFont;
+};
+
+static hb_position_t floatToHarfBuzzPosition(float value)
+{
+    return static_cast<hb_position_t>(value * (1 << 16));
+}
+
+static hb_position_t doubleToHarfBuzzPosition(double value)
+{
+    return static_cast<hb_position_t>(value * (1 << 16));
+}
+
+static void CairoGetGlyphWidthAndExtents(cairo_scaled_font_t* scaledFont, hb_codepoint_t codepoint, hb_position_t* advance, hb_glyph_extents_t* extents)
+{
+    cairo_text_extents_t glyphExtents;
+    cairo_glyph_t glyph;
+    glyph.index = codepoint;
+    glyph.x = 0;
+    glyph.y = 0;
+    cairo_scaled_font_glyph_extents(scaledFont, &glyph, 1, &glyphExtents);
+
+    bool hasVerticalGlyphs = glyphExtents.y_advance;
+    if (advance)
+        *advance = doubleToHarfBuzzPosition(hasVerticalGlyphs ? -glyphExtents.y_advance : glyphExtents.x_advance);
+
+    if (extents) {
+        extents->x_bearing = doubleToHarfBuzzPosition(glyphExtents.x_bearing);
+        extents->y_bearing = doubleToHarfBuzzPosition(hasVerticalGlyphs ? -glyphExtents.y_bearing : glyphExtents.y_bearing);
+        extents->width = doubleToHarfBuzzPosition(hasVerticalGlyphs ? -glyphExtents.height : glyphExtents.width);
+        extents->height = doubleToHarfBuzzPosition(hasVerticalGlyphs ? glyphExtents.width : glyphExtents.height);
+    }
+}
+
+static hb_bool_t harfBuzzGetGlyph(hb_font_t*, void* fontData, hb_codepoint_t unicode, hb_codepoint_t, hb_codepoint_t* glyph, void*)
+{
+    auto& hbFontData = *static_cast<HarfBuzzFontData*>(fontData);
+    auto* scaledFont = hbFontData.cairoScaledFont.get();
+    ASSERT(scaledFont);
+
+    auto result = hbFontData.glyphCacheForFaceCacheEntry.add(unicode, 0);
+    if (result.isNewEntry) {
+        cairo_glyph_t* glyphs = 0;
+        int numGlyphs = 0;
+        char buffer[U8_MAX_LENGTH];
+        size_t bufferLength = 0;
+        if (FontCascade::treatAsSpace(unicode) && unicode != '\t')
+            unicode = ' ';
+        else if (FontCascade::treatAsZeroWidthSpaceInComplexScript(unicode))
+            unicode = zeroWidthSpace;
+        U8_APPEND_UNSAFE(buffer, bufferLength, unicode);
+        if (cairo_scaled_font_text_to_glyphs(scaledFont, 0, 0, buffer, bufferLength, &glyphs, &numGlyphs, nullptr, nullptr, nullptr) != CAIRO_STATUS_SUCCESS || !numGlyphs)
+            return false;
+        result.iterator->value = glyphs[0].index;
+        cairo_glyph_free(glyphs);
+    }
+    *glyph = result.iterator->value;
+    return !!*glyph;
+}
+
+static hb_position_t harfBuzzGetGlyphHorizontalAdvance(hb_font_t*, void* fontData, hb_codepoint_t glyph, void*)
+{
+    auto& hbFontData = *static_cast<HarfBuzzFontData*>(fontData);
+    auto* scaledFont = hbFontData.cairoScaledFont.get();
+    ASSERT(scaledFont);
+
+    hb_position_t advance = 0;
+    CairoGetGlyphWidthAndExtents(scaledFont, glyph, &advance, 0);
+    return advance;
+}
+
+static hb_bool_t harfBuzzGetGlyphHorizontalOrigin(hb_font_t*, void*, hb_codepoint_t, hb_position_t*, hb_position_t*, void*)
+{
+    // Just return true, following the way that Harfbuzz-FreeType
+    // implementation does.
+    return true;
+}
+
+static hb_bool_t harfBuzzGetGlyphExtents(hb_font_t*, void* fontData, hb_codepoint_t glyph, hb_glyph_extents_t* extents, void*)
+{
+    auto& hbFontData = *static_cast<HarfBuzzFontData*>(fontData);
+    auto* scaledFont = hbFontData.cairoScaledFont.get();
+    ASSERT(scaledFont);
+
+    CairoGetGlyphWidthAndExtents(scaledFont, glyph, 0, extents);
+    return true;
+}
+
+static hb_font_funcs_t* harfBuzzCairoTextGetFontFuncs()
+{
+    static hb_font_funcs_t* harfBuzzCairoFontFuncs = 0;
+
+    // We don't set callback functions which we can't support.
+    // Harfbuzz will use the fallback implementation if they aren't set.
+    if (!harfBuzzCairoFontFuncs) {
+        harfBuzzCairoFontFuncs = hb_font_funcs_create();
+        hb_font_funcs_set_glyph_func(harfBuzzCairoFontFuncs, harfBuzzGetGlyph, 0, 0);
+        hb_font_funcs_set_glyph_h_advance_func(harfBuzzCairoFontFuncs, harfBuzzGetGlyphHorizontalAdvance, 0, 0);
+        hb_font_funcs_set_glyph_h_origin_func(harfBuzzCairoFontFuncs, harfBuzzGetGlyphHorizontalOrigin, 0, 0);
+        hb_font_funcs_set_glyph_extents_func(harfBuzzCairoFontFuncs, harfBuzzGetGlyphExtents, 0, 0);
+        hb_font_funcs_make_immutable(harfBuzzCairoFontFuncs);
+    }
+    return harfBuzzCairoFontFuncs;
+}
+
+static hb_blob_t* harfBuzzCairoGetTable(hb_face_t*, hb_tag_t tag, void* userData)
+{
+    auto* scaledFont = static_cast<cairo_scaled_font_t*>(userData);
+    if (!scaledFont)
+        return 0;
+
+    CairoFtFaceLocker cairoFtFaceLocker(scaledFont);
+    FT_Face ftFont = cairoFtFaceLocker.ftFace();
+    if (!ftFont)
+        return nullptr;
+
+    FT_ULong tableSize = 0;
+    FT_Error error = FT_Load_Sfnt_Table(ftFont, tag, 0, 0, &tableSize);
+    if (error)
+        return 0;
+
+    FT_Byte* buffer = reinterpret_cast<FT_Byte*>(fastMalloc(tableSize));
+    if (!buffer)
+        return 0;
+    FT_ULong expectedTableSize = tableSize;
+    error = FT_Load_Sfnt_Table(ftFont, tag, 0, buffer, &tableSize);
+    if (error || tableSize != expectedTableSize) {
+        fastFree(buffer);
+        return 0;
+    }
+
+    return hb_blob_create(reinterpret_cast<const char*>(buffer), tableSize, HB_MEMORY_MODE_WRITABLE, buffer, fastFree);
+}
+
+hb_face_t* HarfBuzzFace::createFace()
+{
+    auto* scaledFont = m_platformData.scaledFont();
+    cairo_scaled_font_reference(scaledFont);
+
+    hb_face_t* face = hb_face_create_for_tables(harfBuzzCairoGetTable, scaledFont,
+        [](void* data)
+        {
+            cairo_scaled_font_destroy(static_cast<cairo_scaled_font_t*>(data));
+        });
+    ASSERT(face);
+    return face;
+}
+
+hb_font_t* HarfBuzzFace::createFont()
+{
+    hb_font_t* font = hb_font_create(m_cacheEntry->face());
+    hb_font_set_funcs(font, harfBuzzCairoTextGetFontFuncs(), new HarfBuzzFontData { m_cacheEntry->glyphCache(), m_platformData.scaledFont() },
+        [](void* data)
+        {
+            delete static_cast<HarfBuzzFontData*>(data);
+        });
+
+    const float size = m_platformData.size();
+    if (floorf(size) == size)
+        hb_font_set_ppem(font, size, size);
+    int scale = floatToHarfBuzzPosition(size);
+    hb_font_set_scale(font, scale, scale);
+    hb_font_make_immutable(font);
+    return font;
+}
+
+} // namespace WebCore
index 0d6f293..eab95c6 100644 (file)
@@ -52,13 +52,6 @@ template<> struct HbPtrDeleter<hb_buffer_t> {
     }
 };
 
-template<> struct HbPtrDeleter<hb_face_t> {
-    void operator()(hb_face_t* ptr) const
-    {
-        hb_face_destroy(ptr);
-    }
-};
-
 } // namespace WebCore
 
 using WebCore::HbUniquePtr;
index 5d88cd7..766d246 100644 (file)
@@ -34,6 +34,7 @@
 #endif
 #include "SharedBuffer.h"
 
+
 namespace WebCore {
 using namespace std;
 
@@ -256,8 +257,10 @@ OpenTypeMathData::OpenTypeMathData(const FontPlatformData& font)
 }
 #elif USE(HARFBUZZ)
 OpenTypeMathData::OpenTypeMathData(const FontPlatformData& font)
-    : m_mathFont(font.createOpenTypeMathHarfBuzzFont())
+    : m_mathFont(font.harfBuzzFace().createFont())
 {
+    if (!hb_ot_math_has_data(hb_font_get_face(m_mathFont.get())))
+        m_mathFont = nullptr;
 }
 #elif USE(DIRECT2D)
 OpenTypeMathData::OpenTypeMathData(const FontPlatformData& font)
@@ -293,13 +296,13 @@ float OpenTypeMathData::getMathConstant(const Font& font, MathConstant constant)
 
     return value * font.sizePerUnit();
 #elif USE(HARFBUZZ)
-float OpenTypeMathData::getMathConstant(const Font& font, MathConstant constant) const
+float OpenTypeMathData::getMathConstant(const Font&, MathConstant constant) const
 {
     hb_position_t value = hb_ot_math_get_constant(m_mathFont.get(), static_cast<hb_ot_math_constant_t>(constant));
     if (constant == ScriptPercentScaleDown || constant == ScriptScriptPercentScaleDown || constant == RadicalDegreeBottomRaisePercent)
         return value / 100.0;
 
-    return value * font.sizePerUnit();
+    return value / 65536.0;
 #else
 float OpenTypeMathData::getMathConstant(const Font&, MathConstant) const
 {
@@ -323,9 +326,9 @@ float OpenTypeMathData::getItalicCorrection(const Font& font, Glyph glyph) const
 
     return mathItalicsCorrectionInfo->getItalicCorrection(*m_mathBuffer, glyph) * font.sizePerUnit();
 #elif USE(HARFBUZZ)
-float OpenTypeMathData::getItalicCorrection(const Font& font, Glyph glyph) const
+float OpenTypeMathData::getItalicCorrection(const Font&, Glyph glyph) const
 {
-    return hb_ot_math_get_glyph_italics_correction(m_mathFont.get(), glyph) * font.sizePerUnit();
+    return hb_ot_math_get_glyph_italics_correction(m_mathFont.get(), glyph) / 65536.0;
 #else
 float OpenTypeMathData::getItalicCorrection(const Font&, Glyph) const
 {
index 387a239..1a62d33 100644 (file)
@@ -46,7 +46,7 @@ FontCustomPlatformData::~FontCustomPlatformData()
         RemoveFontMemResourceEx(m_fontReference);
 }
 
-FontPlatformData FontCustomPlatformData::fontPlatformData(const FontDescription& fontDescription, bool bold, bool italic, const FontFeatureSettings&, const FontVariantSettings&, FontSelectionSpecifiedCapabilities)
+FontPlatformData FontCustomPlatformData::fontPlatformData(const FontDescription& fontDescription, bool bold, bool italic)
 {
     int size = fontDescription.computedPixelSize();
     FontRenderingMode renderingMode = fontDescription.renderingMode();
index 1904490..28aaaad 100644 (file)
@@ -34,11 +34,6 @@ namespace WebCore {
 class FontDescription;
 class FontPlatformData;
 class SharedBuffer;
-struct FontSelectionSpecifiedCapabilities;
-struct FontVariantSettings;
-
-template <typename T> class FontTaggedSettings;
-typedef FontTaggedSettings<int> FontFeatureSettings;
 
 struct FontCustomPlatformData {
     WTF_MAKE_NONCOPYABLE(FontCustomPlatformData);
@@ -51,7 +46,7 @@ public:
 
     ~FontCustomPlatformData();
 
-    FontPlatformData fontPlatformData(const FontDescription&, bool bold, bool italic, const FontFeatureSettings&, const FontVariantSettings&, FontSelectionSpecifiedCapabilities);
+    FontPlatformData fontPlatformData(const FontDescription&, bool bold, bool italic);
 
     static bool supportsFormat(const String&);
 
index a57e69b..a3400f1 100644 (file)
@@ -40,7 +40,7 @@ FontCustomPlatformData::~FontCustomPlatformData()
         RemoveFontMemResourceEx(m_fontReference);
 }
 
-FontPlatformData FontCustomPlatformData::fontPlatformData(const FontDescription& fontDescription, bool bold, bool italic, const FontFeatureSettings&, const FontVariantSettings&, FontSelectionSpecifiedCapabilities)
+FontPlatformData FontCustomPlatformData::fontPlatformData(const FontDescription& fontDescription, bool bold, bool italic)
 {
     int size = fontDescription.computedPixelSize();
     FontRenderingMode renderingMode = fontDescription.renderingMode();
index 91b0936..58d00a0 100644 (file)
@@ -125,14 +125,6 @@ else ()
     WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_BUBBLEWRAP_SANDBOX PRIVATE OFF)
 endif ()
 
-# Enable variation fonts when cairo >= 1.16, fontconfig >= 2.13.0, freetype >= 2.9.0 and harfbuzz >= 1.4.2.
-if ("${PC_CAIRO_VERSION}" VERSION_GREATER_EQUAL "1.16.0"
-    AND "${PC_FONTCONFIG_VERSION}" VERSION_GREATER_EQUAL "2.13.0"
-    AND "${FREETYPE_VERSION_STRING}" VERSION_GREATER_EQUAL "2.9.0"
-    AND "${PC_HARFBUZZ_VERSION}" VERSION_GREATER_EQUAL "1.4.2")
-    WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_VARIATION_FONTS PRIVATE ON)
-endif ()
-
 # Public options shared with other WebKit ports. Do not add any options here
 # without approval from a GTK+ reviewer. There must be strong reason to support
 # changing the value of the option.
index b2bfc80..d9bb427 100644 (file)
@@ -1,3 +1,12 @@
+2018-12-12  Michael Catanzaro  <mcatanzaro@igalia.com>
+
+        Unreviewed manual rollout of r239100-r239102 and r239114
+        https://bugs.webkit.org/show_bug.cgi?id=192151
+        <rdar://problem/46655586>
+
+        * gtk/jhbuild.modules:
+        * gtk/patches/cairo-ft-Use-FT_Done_MM_Var-instead-of-free-when-available.patch: Removed.
+
 2018-12-12  Commit Queue  <commit-queue@webkit.org>
 
         Unreviewed, rolling out r239103.
index d6a5a81..05746c2 100644 (file)
     </dependencies>
     <branch module="releases/cairo-1.16.0.tar.xz" version="1.16.0"
             repo="cairographics.org"
-           hash="sha1:00e81842ae5e81bb0343108884eb5205be0eac14">
-      <!-- See https://gitlab.freedesktop.org/cairo/cairo/merge_requests/5 -->
-      <patch file="cairo-ft-Use-FT_Done_MM_Var-instead-of-free-when-available.patch" strip="1"/>
-    </branch>
+           hash="sha1:00e81842ae5e81bb0343108884eb5205be0eac14"/>
   </autotools>
 
   <!-- FIXME: Pixman 0.32.6 ARM iwMMXt fast path isn't buildable with GCC 4.9 and
diff --git a/Tools/gtk/patches/cairo-ft-Use-FT_Done_MM_Var-instead-of-free-when-available.patch b/Tools/gtk/patches/cairo-ft-Use-FT_Done_MM_Var-instead-of-free-when-available.patch
deleted file mode 100644 (file)
index 210d7d1..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-From b84d0cfd25f82eb25e0b3a708005a9d5502069c7 Mon Sep 17 00:00:00 2001
-From: Carlos Garcia Campos <cgarcia@igalia.com>
-Date: Mon, 19 Nov 2018 12:33:07 +0100
-Subject: [PATCH 1/2] ft: Use FT_Done_MM_Var instead of free when available in
- cairo_ft_apply_variations
-
-Fixes a crash when using freetype >= 2.9
----
- src/cairo-ft-font.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
-diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c
-index 325dd61b4..981973f78 100644
---- a/src/cairo-ft-font.c
-+++ b/src/cairo-ft-font.c
-@@ -2393,7 +2393,11 @@ skip:
- done:
-         free (coords);
-         free (current_coords);
-+#if HAVE_FT_DONE_MM_VAR
-+        FT_Done_MM_Var (face->glyph->library, ft_mm_var);
-+#else
-         free (ft_mm_var);
-+#endif
-     }
- }
--- 
-2.19.2
-