WebKit Bugzilla
Attachment 357217 Details for
Bug 192151
: [FreeType] Add initial implementation of variation fonts
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch for landing
wk-ft-variation-fonts.diff (text/plain), 40.86 KB, created by
Carlos Garcia Campos
on 2018-12-13 00:39:07 PST
(
hide
)
Description:
Patch for landing
Filename:
MIME Type:
Creator:
Carlos Garcia Campos
Created:
2018-12-13 00:39:07 PST
Size:
40.86 KB
patch
obsolete
>diff --git a/ChangeLog b/ChangeLog >index 54910db0765..ddee8a71d6c 100644 >--- a/ChangeLog >+++ b/ChangeLog >@@ -1,3 +1,14 @@ >+2018-12-12 Carlos Garcia Campos <cgarcia@igalia.com> >+ >+ [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-12 Michael Catanzaro <mcatanzaro@igalia.com> > > Unreviewed manual rollout of r239100-r239102 and r239116 >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index 881cbfbf0fe..d4c3a3475d9 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,14 @@ >+2018-12-12 Carlos Garcia Campos <cgarcia@igalia.com> >+ >+ [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-12 Simon Fraser <simon.fraser@apple.com> > > REGRESSION (r238090): CAPCHA UI jumps to the wrong location >diff --git a/LayoutTests/platform/gtk/TestExpectations b/LayoutTests/platform/gtk/TestExpectations >index 46aede23bde..2aad6a738d0 100644 >--- a/LayoutTests/platform/gtk/TestExpectations >+++ b/LayoutTests/platform/gtk/TestExpectations >@@ -1046,11 +1046,6 @@ 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. >@@ -3642,6 +3637,10 @@ 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 > #//////////////////////////////////////////////////////////////////////////////////////// >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index b3d566f8f04..af0e6b01ec3 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,49 @@ >+2018-12-12 Carlos Garcia Campos <cgarcia@igalia.com> >+ >+ [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-12 Fujii Hironori <Hironori.Fujii@sony.com> > > [Win][Clang][WebKitLegacy] WebFrame.cpp: warning: delete called on non-final 'WebFrame' that has virtual functions but non-virtual destructor [-Wdelete-non-virtual-dtor] >diff --git a/Source/WebCore/css/CSSFontFaceSource.cpp b/Source/WebCore/css/CSSFontFaceSource.cpp >index dc2bd7e5bc3..33a8589e176 100644 >--- a/Source/WebCore/css/CSSFontFaceSource.cpp >+++ b/Source/WebCore/css/CSSFontFaceSource.cpp >@@ -232,11 +232,7 @@ 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(); >diff --git a/Source/WebCore/loader/cache/CachedFont.cpp b/Source/WebCore/loader/cache/CachedFont.cpp >index f60a38cc7c9..8d47754b30f 100644 >--- a/Source/WebCore/loader/cache/CachedFont.cpp >+++ b/Source/WebCore/loader/cache/CachedFont.cpp >@@ -141,14 +141,7 @@ 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() >diff --git a/Source/WebCore/platform/graphics/FontPlatformData.h b/Source/WebCore/platform/graphics/FontPlatformData.h >index 0ecf88611e4..bf623add32f 100644 >--- a/Source/WebCore/platform/graphics/FontPlatformData.h >+++ b/Source/WebCore/platform/graphics/FontPlatformData.h >@@ -112,8 +112,7 @@ public: > #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 @@ public: > #if USE(FREETYPE) > HarfBuzzFace& harfBuzzFace() const; > bool hasCompatibleCharmap() const; >+ FcPattern* fcPattern() const; >+ bool isFixedWidth() const { return m_fixedWidth; } > #endif > > unsigned hash() const; >diff --git a/Source/WebCore/platform/graphics/cairo/FontCustomPlatformData.h b/Source/WebCore/platform/graphics/cairo/FontCustomPlatformData.h >index c0d72ec0215..c31cc6e38ba 100644 >--- a/Source/WebCore/platform/graphics/cairo/FontCustomPlatformData.h >+++ b/Source/WebCore/platform/graphics/cairo/FontCustomPlatformData.h >@@ -19,33 +19,37 @@ > * > */ > >-#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 { > > 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 @@ std::unique_ptr<FontCustomPlatformData> createFontCustomPlatformData(SharedBuffe > } // namespace WebCore > > #endif // USE(CAIRO) >- >-#endif // FontCustomPlatformData_h >diff --git a/Source/WebCore/platform/graphics/freetype/FontCacheFreeType.cpp b/Source/WebCore/platform/graphics/freetype/FontCacheFreeType.cpp >index 860fc6bddc0..c446edb5107 100644 >--- a/Source/WebCore/platform/graphics/freetype/FontCacheFreeType.cpp >+++ b/Source/WebCore/platform/graphics/freetype/FontCacheFreeType.cpp >@@ -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 @@ 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()); >@@ -106,7 +145,11 @@ RefPtr<Font> FontCache::systemFallbackForCharacters(const FontDescription& descr > 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 @@ 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; >@@ -382,10 +428,28 @@ 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; > >@@ -397,4 +461,67 @@ 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 >new file mode 100644 >index 00000000000..81e823ce2ce >--- /dev/null >+++ b/Source/WebCore/platform/graphics/freetype/FontCacheFreeType.h >@@ -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 >+}; >diff --git a/Source/WebCore/platform/graphics/freetype/FontCustomPlatformDataFreeType.cpp b/Source/WebCore/platform/graphics/freetype/FontCustomPlatformDataFreeType.cpp >index 53625df7acf..8821d42a729 100644 >--- a/Source/WebCore/platform/graphics/freetype/FontCustomPlatformDataFreeType.cpp >+++ b/Source/WebCore/platform/graphics/freetype/FontCustomPlatformDataFreeType.cpp >@@ -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 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(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,6 +138,14 @@ 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"); > } >diff --git a/Source/WebCore/platform/graphics/freetype/FontPlatformDataFreeType.cpp b/Source/WebCore/platform/graphics/freetype/FontPlatformDataFreeType.cpp >index f77d6a4b657..b46744c0cef 100644 >--- a/Source/WebCore/platform/graphics/freetype/FontPlatformDataFreeType.cpp >+++ b/Source/WebCore/platform/graphics/freetype/FontPlatformDataFreeType.cpp >@@ -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 @@ 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); >-} > >-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(FcPattern* pattern, const FontDescription& fontDescription) >- : m_pattern(pattern) >- , m_size(fontDescription.computedPixelSize()) >- , m_orientation(fontDescription.orientation()) >-{ >- 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; >+#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)); > } >- >- buildScaledFont(fontFace.get()); >+#endif > } > >-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) >+FontPlatformData::FontPlatformData(cairo_font_face_t* fontFace, FcPattern* pattern, float size, bool fixedWidth, bool syntheticBold, bool syntheticOblique, FontOrientation orientation) >+ : FontPlatformData(size, syntheticBold, syntheticOblique, orientation) > { >- buildScaledFont(fontFace); >+ m_pattern = pattern; >+ m_fixedWidth = fixedWidth; > >- CairoFtFaceLocker cairoFtFaceLocker(m_scaledFont.get()); >- if (FT_Face fontConfigFace = cairoFtFaceLocker.ftFace()) >- m_fixedWidth = fontConfigFace->face_flags & FT_FACE_FLAG_FIXED_WIDTH; >+ buildScaledFont(fontFace); > } > > FontPlatformData::FontPlatformData(const FontPlatformData& other) >@@ -244,6 +191,11 @@ HarfBuzzFace& FontPlatformData::harfBuzzFace() const > return *m_harfBuzzFace; > } > >+FcPattern* FontPlatformData::fcPattern() const >+{ >+ return m_pattern.get(); >+} >+ > bool FontPlatformData::isFixedPitch() const > { > return m_fixedWidth; >@@ -274,9 +226,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())); >- 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 +240,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(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); >diff --git a/Source/WebCore/platform/graphics/freetype/SimpleFontDataFreeType.cpp b/Source/WebCore/platform/graphics/freetype/SimpleFontDataFreeType.cpp >index 622a3e63d6b..4bff7cc83d0 100644 >--- a/Source/WebCore/platform/graphics/freetype/SimpleFontDataFreeType.cpp >+++ b/Source/WebCore/platform/graphics/freetype/SimpleFontDataFreeType.cpp >@@ -143,12 +143,13 @@ 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()), >- scaledFontDescription, >+ m_platformData.fcPattern(), >+ scaleFactor * fontDescription.computedSize(), >+ m_platformData.isFixedWidth(), > m_platformData.syntheticBold(), >- m_platformData.syntheticOblique()), >+ m_platformData.syntheticOblique(), >+ fontDescription.orientation()), > origin(), Interstitial::No); > } > >diff --git a/Source/WebCore/platform/graphics/harfbuzz/HarfBuzzFaceCairo.cpp b/Source/WebCore/platform/graphics/harfbuzz/HarfBuzzFaceCairo.cpp >index b3fd8c0f6eb..d54b5894aab 100644 >--- a/Source/WebCore/platform/graphics/harfbuzz/HarfBuzzFaceCairo.cpp >+++ b/Source/WebCore/platform/graphics/harfbuzz/HarfBuzzFaceCairo.cpp >@@ -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_t* HarfBuzzFace::createFont() > 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; > } >diff --git a/Source/WebCore/platform/graphics/win/FontCustomPlatformData.cpp b/Source/WebCore/platform/graphics/win/FontCustomPlatformData.cpp >index 1a62d336152..387a239f829 100644 >--- a/Source/WebCore/platform/graphics/win/FontCustomPlatformData.cpp >+++ b/Source/WebCore/platform/graphics/win/FontCustomPlatformData.cpp >@@ -46,7 +46,7 @@ FontCustomPlatformData::~FontCustomPlatformData() > 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(); >diff --git a/Source/WebCore/platform/graphics/win/FontCustomPlatformData.h b/Source/WebCore/platform/graphics/win/FontCustomPlatformData.h >index 28aaaadcc5f..1904490045f 100644 >--- a/Source/WebCore/platform/graphics/win/FontCustomPlatformData.h >+++ b/Source/WebCore/platform/graphics/win/FontCustomPlatformData.h >@@ -34,6 +34,11 @@ 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); >@@ -46,7 +51,7 @@ public: > > ~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&); > >diff --git a/Source/WebCore/platform/graphics/win/FontCustomPlatformDataCairo.cpp b/Source/WebCore/platform/graphics/win/FontCustomPlatformDataCairo.cpp >index a3400f11193..a57e69b2a7d 100644 >--- a/Source/WebCore/platform/graphics/win/FontCustomPlatformDataCairo.cpp >+++ b/Source/WebCore/platform/graphics/win/FontCustomPlatformDataCairo.cpp >@@ -40,7 +40,7 @@ FontCustomPlatformData::~FontCustomPlatformData() > 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(); >diff --git a/Source/cmake/OptionsGTK.cmake b/Source/cmake/OptionsGTK.cmake >index 58d00a05881..91b09365409 100644 >--- a/Source/cmake/OptionsGTK.cmake >+++ b/Source/cmake/OptionsGTK.cmake >@@ -125,6 +125,14 @@ 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. >diff --git a/Tools/ChangeLog b/Tools/ChangeLog >index d3d8194cf5b..1a8ac57a914 100644 >--- a/Tools/ChangeLog >+++ b/Tools/ChangeLog >@@ -1,3 +1,15 @@ >+2018-12-12 Carlos Garcia Campos <cgarcia@igalia.com> >+ >+ [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-12 Fujii Hironori <Hironori.Fujii@sony.com> > > [Win][Clang][WebKitLegacy] WebFrame.cpp: warning: delete called on non-final 'WebFrame' that has virtual functions but non-virtual destructor [-Wdelete-non-virtual-dtor] >diff --git a/Tools/gtk/jhbuild.modules b/Tools/gtk/jhbuild.modules >index 05746c29a88..d6a5a810859 100644 >--- a/Tools/gtk/jhbuild.modules >+++ b/Tools/gtk/jhbuild.modules >@@ -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 >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 >new file mode 100644 >index 00000000000..210d7d1fe52 >--- /dev/null >+++ b/Tools/gtk/patches/cairo-ft-Use-FT_Done_MM_Var-instead-of-free-when-available.patch >@@ -0,0 +1,30 @@ >+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 >+
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 192151
:
356007
|
356597
|
356600
|
356952
| 357217