Diff
Modified: trunk/ChangeLog (239099 => 239100)
--- trunk/ChangeLog 2018-12-12 08:38:45 UTC (rev 239099)
+++ trunk/ChangeLog 2018-12-12 09:07:19 UTC (rev 239100)
@@ -1,3 +1,14 @@
+2018-12-12 Carlos Garcia Campos <[email protected]>
+
+ [FreeType] Add initial implementation of variation fonts
+ https://bugs.webkit.org/show_bug.cgi?id=192151
+
+ Reviewed by Michael Catanzaro.
+
+ Enable variation fonts in GTK+ port when required dependencies are available.
+
+ * Source/cmake/OptionsGTK.cmake:
+
2018-12-10 Don Olmstead <[email protected]>
[CMake] Add ENABLE_RESOURCE_LOAD_STATISTICS to WebKitFeatures.cmake
Modified: trunk/LayoutTests/ChangeLog (239099 => 239100)
--- trunk/LayoutTests/ChangeLog 2018-12-12 08:38:45 UTC (rev 239099)
+++ trunk/LayoutTests/ChangeLog 2018-12-12 09:07:19 UTC (rev 239100)
@@ -1,3 +1,14 @@
+2018-12-12 Carlos Garcia Campos <[email protected]>
+
+ [FreeType] Add initial implementation of variation fonts
+ https://bugs.webkit.org/show_bug.cgi?id=192151
+
+ Reviewed by Michael Catanzaro.
+
+ Unskip variation fonts tests that are now passing in GTK+ port.
+
+ * platform/gtk/TestExpectations:
+
2018-12-10 Ryosuke Niwa <[email protected]>
connectedCallback is invoked during the removal of the element inside another element's connectedCallback
Modified: trunk/LayoutTests/platform/gtk/TestExpectations (239099 => 239100)
--- trunk/LayoutTests/platform/gtk/TestExpectations 2018-12-12 08:38:45 UTC (rev 239099)
+++ trunk/LayoutTests/platform/gtk/TestExpectations 2018-12-12 09:07:19 UTC (rev 239100)
@@ -1046,11 +1046,6 @@
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.
@@ -3642,6 +3637,10 @@
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
#////////////////////////////////////////////////////////////////////////////////////////
Modified: trunk/Source/WebCore/ChangeLog (239099 => 239100)
--- trunk/Source/WebCore/ChangeLog 2018-12-12 08:38:45 UTC (rev 239099)
+++ trunk/Source/WebCore/ChangeLog 2018-12-12 09:07:19 UTC (rev 239100)
@@ -1,3 +1,49 @@
+2018-12-12 Carlos Garcia Campos <[email protected]>
+
+ [FreeType] Add initial implementation of variation fonts
+ https://bugs.webkit.org/show_bug.cgi?id=192151
+
+ Reviewed by Michael Catanzaro.
+
+ * css/CSSFontFaceSource.cpp:
+ (WebCore::CSSFontFaceSource::font): Remove platform ifdefs.
+ * loader/cache/CachedFont.cpp:
+ (WebCore::CachedFont::platformDataFromCustomData): Ditto.
+ * platform/graphics/FontPlatformData.h:
+ (WebCore::FontPlatformData::isFixedWidth const):
+ * platform/graphics/cairo/FontCustomPlatformData.h: Use RefPtr for cairo_font_face_t.
+ * platform/graphics/freetype/FontCacheFreeType.cpp:
+ (WebCore::getFontPropertiesFromPattern): Helper function to get several font properties from the fontconfig
+ pattern.
+ (WebCore::FontCache::systemFallbackForCharacters): Use getFontPropertiesFromPattern().
+ (WebCore::FontCache::createFontPlatformData): Pass FC_VARIABLE to the pattern and call buildVariationSettings()
+ before creating the FontPlatformData to set FC_FONT_VARIATIONS on the pattern.
+ (WebCore::defaultVariationValues): Parse font variations table.
+ (WebCore::buildVariationSettings): Build a font variations string from the settings that can be passed to cairo.
+ * platform/graphics/freetype/FontCacheFreeType.h: Added.
+ * platform/graphics/freetype/FontCustomPlatformDataFreeType.cpp:
+ (WebCore::FontCustomPlatformData::FontCustomPlatformData): Use RefPtr and make freeTypeFaceKey global.
+ (WebCore::FontCustomPlatformData::~FontCustomPlatformData): Remove explicit destroy.
+ (WebCore::defaultFontconfigOptions): Moved here from FontCacheFreeType.
+ (WebCore::FontCustomPlatformData::fontPlatformData): Call buildVariationSettings() before creating the
+ FontPlatformData to set FC_FONT_VARIATIONS on the pattern.
+ (WebCore::FontCustomPlatformData::supportsFormat): Add variation formats.
+ * platform/graphics/freetype/FontPlatformDataFreeType.cpp:
+ (WebCore::setCairoFontOptionsFromFontConfigPattern): Call cairo_font_options_set_variations() with the
+ FC_FONT_VARIATIONS value from the pattern.
+ (WebCore::FontPlatformData::FontPlatformData): Use a single constructor that always receives a valid fontconfig
+ pattern.
+ (WebCore::FontPlatformData::fcPattern const): Return the fontconfig pattern.
+ (WebCore::FontPlatformData::platformIsEqual const): Update the condition now that m_pattern can't be nullptr.
+ (WebCore::FontPlatformData::buildScaledFont): Use m_pattern unconditionally.
+ * platform/graphics/freetype/SimpleFontDataFreeType.cpp:
+ (WebCore::Font::platformCreateScaledFont const): Update it to use the new FontPlatformData constructor.
+ * platform/graphics/harfbuzz/HarfBuzzFaceCairo.cpp:
+ (WebCore::HarfBuzzFace::createFont): Pass variations to HarfBuzz.
+ * platform/graphics/win/FontCustomPlatformData.cpp:
+ (WebCore::FontCustomPlatformData::fontPlatformData):
+ * platform/graphics/win/FontCustomPlatformData.h:
+
2018-12-11 Justin Michaud <[email protected]>
Implement feature flag for CSS Typed OM
Modified: trunk/Source/WebCore/css/CSSFontFaceSource.cpp (239099 => 239100)
--- trunk/Source/WebCore/css/CSSFontFaceSource.cpp 2018-12-12 08:38:45 UTC (rev 239099)
+++ trunk/Source/WebCore/css/CSSFontFaceSource.cpp 2018-12-12 09:07:19 UTC (rev 239100)
@@ -232,12 +232,8 @@
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();
return nullptr;
Modified: trunk/Source/WebCore/loader/cache/CachedFont.cpp (239099 => 239100)
--- trunk/Source/WebCore/loader/cache/CachedFont.cpp 2018-12-12 08:38:45 UTC (rev 239099)
+++ trunk/Source/WebCore/loader/cache/CachedFont.cpp 2018-12-12 09:07:19 UTC (rev 239100)
@@ -141,14 +141,7 @@
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()
Modified: trunk/Source/WebCore/platform/graphics/FontPlatformData.h (239099 => 239100)
--- trunk/Source/WebCore/platform/graphics/FontPlatformData.h 2018-12-12 08:38:45 UTC (rev 239099)
+++ trunk/Source/WebCore/platform/graphics/FontPlatformData.h 2018-12-12 09:07:19 UTC (rev 239100)
@@ -112,8 +112,7 @@
#endif
#if USE(FREETYPE)
- FontPlatformData(FcPattern*, const FontDescription&);
- FontPlatformData(cairo_font_face_t*, const FontDescription&, bool syntheticBold, bool syntheticOblique);
+ FontPlatformData(cairo_font_face_t*, FcPattern*, float size, bool fixedWidth, bool syntheticBold, bool syntheticOblique, FontOrientation);
FontPlatformData(const FontPlatformData&);
FontPlatformData(FontPlatformData&&) = default;
FontPlatformData& operator=(const FontPlatformData&);
@@ -171,6 +170,8 @@
#if USE(FREETYPE)
HarfBuzzFace& harfBuzzFace() const;
bool hasCompatibleCharmap() const;
+ FcPattern* fcPattern() const;
+ bool isFixedWidth() const { return m_fixedWidth; }
#endif
unsigned hash() const;
Modified: trunk/Source/WebCore/platform/graphics/cairo/FontCustomPlatformData.h (239099 => 239100)
--- trunk/Source/WebCore/platform/graphics/cairo/FontCustomPlatformData.h 2018-12-12 08:38:45 UTC (rev 239099)
+++ trunk/Source/WebCore/platform/graphics/cairo/FontCustomPlatformData.h 2018-12-12 09:07:19 UTC (rev 239100)
@@ -19,16 +19,15 @@
*
*/
-#ifndef FontCustomPlatformData_h
-#define FontCustomPlatformData_h
+#pragma once
#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 {
@@ -35,17 +34,22 @@
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();
- FontPlatformData fontPlatformData(const FontDescription&, bool bold, bool italic);
+ ~FontCustomPlatformData() = default;
+ FontPlatformData fontPlatformData(const FontDescription&, bool bold, bool italic, const FontFeatureSettings&, const FontVariantSettings&, FontSelectionSpecifiedCapabilities);
static bool supportsFormat(const String&);
private:
- cairo_font_face_t* m_fontFace;
+ RefPtr<cairo_font_face_t> m_fontFace;
};
std::unique_ptr<FontCustomPlatformData> createFontCustomPlatformData(SharedBuffer&, const String&);
@@ -53,5 +57,3 @@
} // namespace WebCore
#endif // USE(CAIRO)
-
-#endif // FontCustomPlatformData_h
Modified: trunk/Source/WebCore/platform/graphics/freetype/FontCacheFreeType.cpp (239099 => 239100)
--- trunk/Source/WebCore/platform/graphics/freetype/FontCacheFreeType.cpp 2018-12-12 08:38:45 UTC (rev 239099)
+++ trunk/Source/WebCore/platform/graphics/freetype/FontCacheFreeType.cpp 2018-12-12 09:07:19 UTC (rev 239100)
@@ -22,9 +22,13 @@
#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"
@@ -38,6 +42,10 @@
#include "GtkUtilities.h"
#endif
+#if ENABLE(VARIATION_FONTS)
+#include FT_MULTIPLE_MASTERS_H
+#endif
+
namespace WebCore {
void FontCache::platformInit()
@@ -79,6 +87,37 @@
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());
@@ -106,7 +145,11 @@
if (!resultPattern)
return nullptr;
- FontPlatformData alternateFontData(resultPattern.get(), description);
+ 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());
return fontForPlatformData(alternateFontData);
}
@@ -332,6 +375,9 @@
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;
@@ -382,10 +428,28 @@
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;
@@ -397,4 +461,67 @@
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)
+
+}
Added: trunk/Source/WebCore/platform/graphics/freetype/FontCacheFreeType.h (0 => 239100)
--- trunk/Source/WebCore/platform/graphics/freetype/FontCacheFreeType.h (rev 0)
+++ trunk/Source/WebCore/platform/graphics/freetype/FontCacheFreeType.h 2018-12-12 09:07:19 UTC (rev 239100)
@@ -0,0 +1,30 @@
+/*
+ * 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
+};
Modified: trunk/Source/WebCore/platform/graphics/freetype/FontCustomPlatformDataFreeType.cpp (239099 => 239100)
--- trunk/Source/WebCore/platform/graphics/freetype/FontCustomPlatformDataFreeType.cpp 2018-12-12 08:38:45 UTC (rev 239099)
+++ trunk/Source/WebCore/platform/graphics/freetype/FontCustomPlatformDataFreeType.cpp 2018-12-12 09:07:19 UTC (rev 239100)
@@ -22,6 +22,9 @@
#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>
@@ -36,29 +39,54 @@
static_cast<SharedBuffer*>(data)->deref();
}
+static cairo_user_data_key_t freeTypeFaceKey;
+
FontCustomPlatformData::FontCustomPlatformData(FT_Face freeTypeFace, SharedBuffer& buffer)
- : m_fontFace(cairo_ft_font_face_create_for_ft_face(freeTypeFace, FT_LOAD_DEFAULT))
+ : m_fontFace(adoptRef(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, &bufferKey, &buffer,
+ cairo_font_face_set_user_data(m_fontFace.get(), &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.
- static cairo_user_data_key_t freeTypeFaceKey;
- cairo_font_face_set_user_data(m_fontFace, &freeTypeFaceKey, freeTypeFace,
+ cairo_font_face_set_user_data(m_fontFace.get(), &freeTypeFaceKey, freeTypeFace,
reinterpret_cast<cairo_destroy_func_t>(reinterpret_cast<void(*)(void)>(FT_Done_Face)));
}
-FontCustomPlatformData::~FontCustomPlatformData()
+static FcPattern* defaultFontconfigOptions()
{
- cairo_font_face_destroy(m_fontFace);
+ // 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 FontCustomPlatformData::fontPlatformData(const FontDescription& description, bool bold, bool italic)
+FontPlatformData FontCustomPlatformData::fontPlatformData(const FontDescription& description, bool bold, bool italic, const FontFeatureSettings&, const FontVariantSettings&, FontSelectionSpecifiedCapabilities)
{
- return FontPlatformData(m_fontFace, description, bold, 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());
}
static bool initializeFreeTypeLibrary(FT_Library& library)
@@ -110,7 +138,15 @@
|| 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");
}
Modified: trunk/Source/WebCore/platform/graphics/freetype/FontPlatformDataFreeType.cpp (239099 => 239100)
--- trunk/Source/WebCore/platform/graphics/freetype/FontPlatformDataFreeType.cpp 2018-12-12 08:38:45 UTC (rev 239099)
+++ trunk/Source/WebCore/platform/graphics/freetype/FontPlatformDataFreeType.cpp 2018-12-12 09:07:19 UTC (rev 239100)
@@ -28,7 +28,6 @@
#include "CairoUniquePtr.h"
#include "CairoUtilities.h"
#include "FontCache.h"
-#include "FontDescription.h"
#include "SharedBuffer.h"
#include <cairo-ft.h>
#include <fontconfig/fcfreetype.h>
@@ -100,74 +99,22 @@
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);
-}
-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;
+#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
}
-FontPlatformData::FontPlatformData(FcPattern* pattern, const FontDescription& fontDescription)
- : m_pattern(pattern)
- , m_size(fontDescription.computedPixelSize())
- , m_orientation(fontDescription.orientation())
+FontPlatformData::FontPlatformData(cairo_font_face_t* fontFace, FcPattern* pattern, float size, bool fixedWidth, bool syntheticBold, bool syntheticOblique, FontOrientation orientation)
+ : FontPlatformData(size, syntheticBold, syntheticOblique, orientation)
{
- ASSERT(m_pattern);
- RefPtr<cairo_font_face_t> fontFace = adoptRef(cairo_ft_font_face_create_for_pattern(m_pattern.get()));
+ m_pattern = pattern;
+ m_fixedWidth = fixedWidth;
- 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)
@@ -244,6 +191,11 @@
return *m_harfBuzzFace;
}
+FcPattern* FontPlatformData::fcPattern() const
+{
+ return m_pattern.get();
+}
+
bool FontPlatformData::isFixedPitch() const
{
return m_fixedWidth;
@@ -256,10 +208,7 @@
bool FontPlatformData::platformIsEqual(const FontPlatformData& other) const
{
- // 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())))
+ if (m_pattern != other.m_pattern && !FcPatternEqual(m_pattern.get(), other.m_pattern.get()))
return false;
return m_scaledFont == other.m_scaledFont;
@@ -274,9 +223,9 @@
void FontPlatformData::buildScaledFont(cairo_font_face_t* fontFace)
{
+ ASSERT(m_pattern);
CairoUniquePtr<cairo_font_options_t> options(cairo_font_options_copy(getDefaultCairoFontOptions()));
- FcPattern* optionsPattern = m_pattern ? m_pattern.get() : getDefaultFontconfigOptions();
- setCairoFontOptionsFromFontConfigPattern(options.get(), optionsPattern);
+ setCairoFontOptionsFromFontConfigPattern(options.get(), m_pattern.get());
cairo_matrix_t ctm;
cairo_matrix_init_identity(&ctm);
@@ -288,7 +237,7 @@
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(optionsPattern, FC_MATRIX, i, &tempFontConfigMatrix) == FcResultMatch; i++)
+ for (int i = 0; FcPatternGetMatrix(m_pattern.get(), FC_MATRIX, i, &tempFontConfigMatrix) == FcResultMatch; i++)
FcMatrixMultiply(&fontConfigMatrix, &fontConfigMatrix, tempFontConfigMatrix);
cairo_matrix_init(&fontMatrix, 1, -fontConfigMatrix.yx, -fontConfigMatrix.xy, 1, 0, 0);
Modified: trunk/Source/WebCore/platform/graphics/freetype/SimpleFontDataFreeType.cpp (239099 => 239100)
--- trunk/Source/WebCore/platform/graphics/freetype/SimpleFontDataFreeType.cpp 2018-12-12 08:38:45 UTC (rev 239099)
+++ trunk/Source/WebCore/platform/graphics/freetype/SimpleFontDataFreeType.cpp 2018-12-12 09:07:19 UTC (rev 239100)
@@ -143,12 +143,13 @@
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()),
- scaledFontDescription,
+ m_platformData.fcPattern(),
+ scaleFactor * fontDescription.computedSize(),
+ m_platformData.isFixedWidth(),
m_platformData.syntheticBold(),
- m_platformData.syntheticOblique()),
+ m_platformData.syntheticOblique(),
+ fontDescription.orientation()),
origin(), Interstitial::No);
}
Modified: trunk/Source/WebCore/platform/graphics/harfbuzz/HarfBuzzFaceCairo.cpp (239099 => 239100)
--- trunk/Source/WebCore/platform/graphics/harfbuzz/HarfBuzzFaceCairo.cpp 2018-12-12 08:38:45 UTC (rev 239099)
+++ trunk/Source/WebCore/platform/graphics/harfbuzz/HarfBuzzFaceCairo.cpp 2018-12-12 09:07:19 UTC (rev 239100)
@@ -47,6 +47,10 @@
#include <wtf/text/CString.h>
#include <wtf/text/StringView.h>
+#if ENABLE(VARIATION_FONTS)
+#include FT_MULTIPLE_MASTERS_H
+#endif
+
namespace WebCore {
struct HarfBuzzFontData {
@@ -213,6 +217,29 @@
hb_font_set_ppem(font, size, size);
int scale = floatToHarfBuzzPosition(size);
hb_font_set_scale(font, scale, scale);
+
+#if ENABLE(VARIATION_FONTS)
+ {
+ CairoFtFaceLocker cairoFtFaceLocker(m_platformData.scaledFont());
+ if (FT_Face face = cairoFtFaceLocker.ftFace()) {
+ FT_MM_Var* ftMMVar;
+ if (!FT_Get_MM_Var(face, &ftMMVar)) {
+ Vector<FT_Fixed, 4> coords;
+ coords.resize(ftMMVar->num_axis);
+ if (!FT_Get_Var_Design_Coordinates(face, 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(font, variations.data(), variations.size());
+ }
+ FT_Done_MM_Var(face->glyph->library, ftMMVar);
+ }
+ }
+ }
+#endif
+
hb_font_make_immutable(font);
return font;
}
Modified: trunk/Source/WebCore/platform/graphics/win/FontCustomPlatformData.cpp (239099 => 239100)
--- trunk/Source/WebCore/platform/graphics/win/FontCustomPlatformData.cpp 2018-12-12 08:38:45 UTC (rev 239099)
+++ trunk/Source/WebCore/platform/graphics/win/FontCustomPlatformData.cpp 2018-12-12 09:07:19 UTC (rev 239100)
@@ -46,7 +46,7 @@
RemoveFontMemResourceEx(m_fontReference);
}
-FontPlatformData FontCustomPlatformData::fontPlatformData(const FontDescription& fontDescription, bool bold, bool italic)
+FontPlatformData FontCustomPlatformData::fontPlatformData(const FontDescription& fontDescription, bool bold, bool italic, const FontFeatureSettings&, const FontVariantSettings&, FontSelectionSpecifiedCapabilities)
{
int size = fontDescription.computedPixelSize();
FontRenderingMode renderingMode = fontDescription.renderingMode();
Modified: trunk/Source/WebCore/platform/graphics/win/FontCustomPlatformData.h (239099 => 239100)
--- trunk/Source/WebCore/platform/graphics/win/FontCustomPlatformData.h 2018-12-12 08:38:45 UTC (rev 239099)
+++ trunk/Source/WebCore/platform/graphics/win/FontCustomPlatformData.h 2018-12-12 09:07:19 UTC (rev 239100)
@@ -34,7 +34,12 @@
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:
@@ -46,7 +51,7 @@
~FontCustomPlatformData();
- FontPlatformData fontPlatformData(const FontDescription&, bool bold, bool italic);
+ FontPlatformData fontPlatformData(const FontDescription&, bool bold, bool italic, const FontFeatureSettings&, const FontVariantSettings&, FontSelectionSpecifiedCapabilities);
static bool supportsFormat(const String&);
Modified: trunk/Source/cmake/OptionsGTK.cmake (239099 => 239100)
--- trunk/Source/cmake/OptionsGTK.cmake 2018-12-12 08:38:45 UTC (rev 239099)
+++ trunk/Source/cmake/OptionsGTK.cmake 2018-12-12 09:07:19 UTC (rev 239100)
@@ -125,6 +125,14 @@
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.
Modified: trunk/Tools/ChangeLog (239099 => 239100)
--- trunk/Tools/ChangeLog 2018-12-12 08:38:45 UTC (rev 239099)
+++ trunk/Tools/ChangeLog 2018-12-12 09:07:19 UTC (rev 239100)
@@ -1,3 +1,15 @@
+2018-12-12 Carlos Garcia Campos <[email protected]>
+
+ [FreeType] Add initial implementation of variation fonts
+ https://bugs.webkit.org/show_bug.cgi?id=192151
+
+ Reviewed by Michael Catanzaro.
+
+ Add cairo patch to avoid crashes.
+
+ * gtk/jhbuild.modules:
+ * gtk/patches/cairo-ft-Use-FT_Done_MM_Var-instead-of-free-when-available.patch: Added.
+
2018-12-11 Justin Michaud <[email protected]>
Implement feature flag for CSS Typed OM
Modified: trunk/Tools/gtk/jhbuild.modules (239099 => 239100)
--- trunk/Tools/gtk/jhbuild.modules 2018-12-12 08:38:45 UTC (rev 239099)
+++ trunk/Tools/gtk/jhbuild.modules 2018-12-12 09:07:19 UTC (rev 239100)
@@ -107,7 +107,10 @@
</dependencies>
<branch module="releases/cairo-1.16.0.tar.xz" version="1.16.0"
repo="cairographics.org"
- hash="sha1:00e81842ae5e81bb0343108884eb5205be0eac14"/>
+ 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>
</autotools>
<!-- FIXME: Pixman 0.32.6 ARM iwMMXt fast path isn't buildable with GCC 4.9 and
Added: trunk/Tools/gtk/patches/cairo-ft-Use-FT_Done_MM_Var-instead-of-free-when-available.patch (0 => 239100)
--- trunk/Tools/gtk/patches/cairo-ft-Use-FT_Done_MM_Var-instead-of-free-when-available.patch (rev 0)
+++ trunk/Tools/gtk/patches/cairo-ft-Use-FT_Done_MM_Var-instead-of-free-when-available.patch 2018-12-12 09:07:19 UTC (rev 239100)
@@ -0,0 +1,30 @@
+From b84d0cfd25f82eb25e0b3a708005a9d5502069c7 Mon Sep 17 00:00:00 2001
+From: Carlos Garcia Campos <[email protected]>
+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
+