Diff
Modified: trunk/LayoutTests/ChangeLog (239100 => 239101)
--- trunk/LayoutTests/ChangeLog 2018-12-12 09:07:19 UTC (rev 239100)
+++ trunk/LayoutTests/ChangeLog 2018-12-12 09:19:48 UTC (rev 239101)
@@ -1,5 +1,17 @@
2018-12-12 Carlos Garcia Campos <[email protected]>
+ [FreeType] Remove HarfBuzzFace
+ https://bugs.webkit.org/show_bug.cgi?id=192589
+
+ Reviewed by Michael Catanzaro.
+
+ Rebaseline test that now matches the firefox output.
+
+ * platform/gtk/mathml/opentype/opentype-stretchy-expected.png:
+ * platform/gtk/mathml/opentype/opentype-stretchy-expected.txt:
+
+2018-12-12 Carlos Garcia Campos <[email protected]>
+
[FreeType] Add initial implementation of variation fonts
https://bugs.webkit.org/show_bug.cgi?id=192151
Modified: trunk/LayoutTests/platform/gtk/mathml/opentype/opentype-stretchy-expected.png
(Binary files differ)
Modified: trunk/LayoutTests/platform/gtk/mathml/opentype/opentype-stretchy-expected.txt (239100 => 239101)
--- trunk/LayoutTests/platform/gtk/mathml/opentype/opentype-stretchy-expected.txt 2018-12-12 09:07:19 UTC (rev 239100)
+++ trunk/LayoutTests/platform/gtk/mathml/opentype/opentype-stretchy-expected.txt 2018-12-12 09:19:48 UTC (rev 239101)
@@ -1,8 +1,8 @@
layer at (0,0) size 800x600
RenderView at (0,0) size 800x600
-layer at (0,0) size 800x339
- RenderBlock {HTML} at (0,0) size 800x339
- RenderBody {BODY} at (8,16) size 784x307
+layer at (0,0) size 800x350
+ RenderBlock {HTML} at (0,0) size 800x350
+ RenderBody {BODY} at (8,16) size 784x318
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 @@
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 784x86
- RenderMathMLMath {math} at (0,0) size 84x82
- RenderMathMLRow {mrow} at (0,0) size 84x82
- RenderMathMLOperator {mo} at (0,0) size 84x82
+ 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 (anonymous) at (0,0) size 10x12
RenderText {#text} at (0,6) size 10x0
text run at (0,6) width 10: "\x{2A1B}"
Modified: trunk/Source/WebCore/ChangeLog (239100 => 239101)
--- trunk/Source/WebCore/ChangeLog 2018-12-12 09:07:19 UTC (rev 239100)
+++ trunk/Source/WebCore/ChangeLog 2018-12-12 09:19:48 UTC (rev 239101)
@@ -1,5 +1,39 @@
2018-12-12 Carlos Garcia Campos <[email protected]>
+ [FreeType] Remove HarfBuzzFace
+ https://bugs.webkit.org/show_bug.cgi?id=192589
+
+ Reviewed by Michael Catanzaro.
+
+ This was used to share the common implementation with the chromium port, but now that only freetype based ports
+ use it, it can be removed and use hb_ft_face_create_cached() instead. We don't need the glyph cache either,
+ since we are already caching glyphs in Font.
+
+ * platform/FreeType.cmake: Remove HarfBuzzFaceCairo.cpp and HarfBuzzFace.cpp.
+ * platform/graphics/FontPlatformData.h: Remove HarfBuzzFace member.
+ * platform/graphics/freetype/FontCustomPlatformDataFreeType.cpp: Add missing include.
+ * platform/graphics/freetype/FontPlatformDataFreeType.cpp:
+ (WebCore::FontPlatformData::operator=): Remove m_harfBuzzFace handling.
+ (WebCore::FontPlatformData::createOpenTypeMathHarfBuzzFont const): New funtction to create a hb_font_t for
+ OpenType math.
+ * platform/graphics/harfbuzz/ComplexTextControllerHarfBuzz.cpp:
+ (WebCore::floatToHarfBuzzPosition): Moved from HarfBuzzFaceCairo.cpp.
+ (WebCore::doubleToHarfBuzzPosition): Ditto.
+ (WebCore::harfBuzzFontFunctions): Also moved from HarfBuzzFaceCairo.cpp, but implement get_nominal/variation
+ functions when using HarfBuzz >= 1.2.3 and use Font::glyphForCharacter() to make it simpler.
+ (WebCore::fontFeatures): Moved from HarfBuzzFaceCairo.cpp.
+ (WebCore::findScriptForVerticalGlyphSubstitution): Moved from HarfBuzzFace.cpp.
+ (WebCore::ComplexTextController::collectComplexTextRunsForCharacters): Create the HarfBuzz face and font here.
+ * platform/graphics/harfbuzz/HarfBuzzFace.cpp: Removed.
+ * platform/graphics/harfbuzz/HarfBuzzFace.h: Removed.
+ * platform/graphics/harfbuzz/HarfBuzzFaceCairo.cpp: Removed.
+ * platform/graphics/harfbuzz/HbUniquePtr.h:
+ (WebCore::HbPtrDeleter<hb_face_t>::operator() const): Add deleter for hb_face_t.
+ * platform/graphics/opentype/OpenTypeMathData.cpp:
+ (WebCore::OpenTypeMathData::OpenTypeMathData): Use FontPlatformData::createOpenTypeMathHarfBuzzFont().
+
+2018-12-12 Carlos Garcia Campos <[email protected]>
+
[FreeType] Add initial implementation of variation fonts
https://bugs.webkit.org/show_bug.cgi?id=192151
Modified: trunk/Source/WebCore/platform/FreeType.cmake (239100 => 239101)
--- trunk/Source/WebCore/platform/FreeType.cmake 2018-12-12 09:07:19 UTC (rev 239100)
+++ trunk/Source/WebCore/platform/FreeType.cmake 2018-12-12 09:19:48 UTC (rev 239101)
@@ -11,7 +11,6 @@
platform/graphics/freetype/SimpleFontDataFreeType.cpp
platform/graphics/harfbuzz/ComplexTextControllerHarfBuzz.cpp
- platform/graphics/harfbuzz/HarfBuzzFace.cpp
)
if (PORT STREQUAL "GTK")
@@ -27,8 +26,6 @@
if (USE_CAIRO)
list(APPEND WebCore_SOURCES
platform/graphics/cairo/FontCairoHarfbuzzNG.cpp
-
- platform/graphics/harfbuzz/HarfBuzzFaceCairo.cpp
)
endif ()
Modified: trunk/Source/WebCore/platform/graphics/FontPlatformData.h (239100 => 239101)
--- trunk/Source/WebCore/platform/graphics/FontPlatformData.h 2018-12-12 09:07:19 UTC (rev 239100)
+++ trunk/Source/WebCore/platform/graphics/FontPlatformData.h 2018-12-12 09:19:48 UTC (rev 239101)
@@ -40,7 +40,7 @@
#if USE(FREETYPE)
#include "FcUniquePtr.h"
-#include "HarfBuzzFace.h"
+#include "HbUniquePtr.h"
#include "RefPtrFontconfig.h"
#include <memory>
#endif
@@ -168,7 +168,7 @@
#endif
#if USE(FREETYPE)
- HarfBuzzFace& harfBuzzFace() const;
+ HbUniquePtr<hb_font_t> createOpenTypeMathHarfBuzzFont() const;
bool hasCompatibleCharmap() const;
FcPattern* fcPattern() const;
bool isFixedWidth() const { return m_fixedWidth; }
@@ -249,7 +249,6 @@
#if USE(FREETYPE)
RefPtr<FcPattern> m_pattern;
- mutable std::unique_ptr<HarfBuzzFace> m_harfBuzzFace;
#endif
// The values below are common to all ports
Modified: trunk/Source/WebCore/platform/graphics/freetype/FontCustomPlatformDataFreeType.cpp (239100 => 239101)
--- trunk/Source/WebCore/platform/graphics/freetype/FontCustomPlatformDataFreeType.cpp 2018-12-12 09:07:19 UTC (rev 239100)
+++ trunk/Source/WebCore/platform/graphics/freetype/FontCustomPlatformDataFreeType.cpp 2018-12-12 09:19:48 UTC (rev 239101)
@@ -31,6 +31,7 @@
#include <cairo.h>
#include <ft2build.h>
#include FT_MODULE_H
+#include <mutex>
namespace WebCore {
Modified: trunk/Source/WebCore/platform/graphics/freetype/FontPlatformDataFreeType.cpp (239100 => 239101)
--- trunk/Source/WebCore/platform/graphics/freetype/FontPlatformDataFreeType.cpp 2018-12-12 09:07:19 UTC (rev 239100)
+++ trunk/Source/WebCore/platform/graphics/freetype/FontPlatformDataFreeType.cpp 2018-12-12 09:19:48 UTC (rev 239101)
@@ -33,6 +33,8 @@
#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>
@@ -144,9 +146,6 @@
m_scaledFont = other.m_scaledFont;
- // This will be re-created on demand.
- m_harfBuzzFace = nullptr;
-
return *this;
}
@@ -184,13 +183,6 @@
return copy;
}
-HarfBuzzFace& FontPlatformData::harfBuzzFace() const
-{
- if (!m_harfBuzzFace)
- m_harfBuzzFace = std::make_unique<HarfBuzzFace>(const_cast<FontPlatformData&>(*this), hash());
- return *m_harfBuzzFace;
-}
-
FcPattern* FontPlatformData::fcPattern() const
{
return m_pattern.get();
@@ -301,4 +293,18 @@
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
Modified: trunk/Source/WebCore/platform/graphics/harfbuzz/ComplexTextControllerHarfBuzz.cpp (239100 => 239101)
--- trunk/Source/WebCore/platform/graphics/harfbuzz/ComplexTextControllerHarfBuzz.cpp 2018-12-12 09:07:19 UTC (rev 239100)
+++ trunk/Source/WebCore/platform/graphics/harfbuzz/ComplexTextControllerHarfBuzz.cpp 2018-12-12 09:19:48 UTC (rev 239101)
@@ -26,11 +26,17 @@
#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>
+#if ENABLE(VARIATION_FONTS)
+#include FT_MULTIPLE_MASTERS_H
+#endif
+
namespace WebCore {
static inline float harfBuzzPositionToFloat(hb_position_t value)
@@ -38,6 +44,90 @@
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)
@@ -83,7 +173,10 @@
}
}
-static const unsigned hbEnd = static_cast<unsigned>(-1);
+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 Vector<hb_feature_t, 4> fontFeatures(const FontCascade& font, FontOrientation orientation)
{
@@ -90,11 +183,11 @@
Vector<hb_feature_t, 4> features;
if (orientation == FontOrientation::Vertical) {
- features.append({ HarfBuzzFace::vertTag, 1, 0, hbEnd });
- features.append({ HarfBuzzFace::vrt2Tag, 1, 0, hbEnd });
+ features.append({ s_vertTag, 1, 0, s_hbEnd });
+ features.append({ s_vrt2Tag, 1, 0, s_hbEnd });
}
- hb_feature_t kerning = { HarfBuzzFace::kernTag, 0, 0, hbEnd };
+ hb_feature_t kerning = { s_kernTag, 0, 0, s_hbEnd };
if (font.enableKerning())
kerning.value = 1;
features.append(WTFMove(kerning));
@@ -101,7 +194,7 @@
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, hbEnd });
+ features.append({ HB_TAG(tag[0], tag[1], tag[2], tag[3]), static_cast<uint32_t>(feature.value()), 0, s_hbEnd });
}
return features;
@@ -168,6 +261,27 @@
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) {
@@ -191,13 +305,50 @@
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];
- hb_buffer_set_script(buffer.get(), hb_icu_script_to_script(run.script));
+ if (fontPlatformData.orientation() != FontOrientation::Vertical)
+ 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 {
@@ -206,11 +357,6 @@
}
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());
Deleted: trunk/Source/WebCore/platform/graphics/harfbuzz/HarfBuzzFace.cpp (239100 => 239101)
--- trunk/Source/WebCore/platform/graphics/harfbuzz/HarfBuzzFace.cpp 2018-12-12 09:07:19 UTC (rev 239100)
+++ trunk/Source/WebCore/platform/graphics/harfbuzz/HarfBuzzFace.cpp 2018-12-12 09:19:48 UTC (rev 239101)
@@ -1,118 +0,0 @@
-/*
- * 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
Deleted: trunk/Source/WebCore/platform/graphics/harfbuzz/HarfBuzzFace.h (239100 => 239101)
--- trunk/Source/WebCore/platform/graphics/harfbuzz/HarfBuzzFace.h 2018-12-12 09:07:19 UTC (rev 239100)
+++ trunk/Source/WebCore/platform/graphics/harfbuzz/HarfBuzzFace.h 2018-12-12 09:19:48 UTC (rev 239101)
@@ -1,94 +0,0 @@
-/*
- * 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
Deleted: trunk/Source/WebCore/platform/graphics/harfbuzz/HarfBuzzFaceCairo.cpp (239100 => 239101)
--- trunk/Source/WebCore/platform/graphics/harfbuzz/HarfBuzzFaceCairo.cpp 2018-12-12 09:07:19 UTC (rev 239100)
+++ trunk/Source/WebCore/platform/graphics/harfbuzz/HarfBuzzFaceCairo.cpp 2018-12-12 09:19:48 UTC (rev 239101)
@@ -1,247 +0,0 @@
-/*
- * 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>
-
-#if ENABLE(VARIATION_FONTS)
-#include FT_MULTIPLE_MASTERS_H
-#endif
-
-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);
-
-#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;
-}
-
-} // namespace WebCore
Modified: trunk/Source/WebCore/platform/graphics/harfbuzz/HbUniquePtr.h (239100 => 239101)
--- trunk/Source/WebCore/platform/graphics/harfbuzz/HbUniquePtr.h 2018-12-12 09:07:19 UTC (rev 239100)
+++ trunk/Source/WebCore/platform/graphics/harfbuzz/HbUniquePtr.h 2018-12-12 09:19:48 UTC (rev 239101)
@@ -52,6 +52,13 @@
}
};
+template<> struct HbPtrDeleter<hb_face_t> {
+ void operator()(hb_face_t* ptr) const
+ {
+ hb_face_destroy(ptr);
+ }
+};
+
} // namespace WebCore
using WebCore::HbUniquePtr;
Modified: trunk/Source/WebCore/platform/graphics/opentype/OpenTypeMathData.cpp (239100 => 239101)
--- trunk/Source/WebCore/platform/graphics/opentype/OpenTypeMathData.cpp 2018-12-12 09:07:19 UTC (rev 239100)
+++ trunk/Source/WebCore/platform/graphics/opentype/OpenTypeMathData.cpp 2018-12-12 09:19:48 UTC (rev 239101)
@@ -34,7 +34,6 @@
#endif
#include "SharedBuffer.h"
-
namespace WebCore {
using namespace std;
@@ -257,10 +256,8 @@
}
#elif USE(HARFBUZZ)
OpenTypeMathData::OpenTypeMathData(const FontPlatformData& font)
- : m_mathFont(font.harfBuzzFace().createFont())
+ : m_mathFont(font.createOpenTypeMathHarfBuzzFont())
{
- if (!hb_ot_math_has_data(hb_font_get_face(m_mathFont.get())))
- m_mathFont = nullptr;
}
#elif USE(DIRECT2D)
OpenTypeMathData::OpenTypeMathData(const FontPlatformData& font)
@@ -296,13 +293,13 @@
return value * font.sizePerUnit();
#elif USE(HARFBUZZ)
-float OpenTypeMathData::getMathConstant(const Font&, MathConstant constant) const
+float OpenTypeMathData::getMathConstant(const Font& 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 / 65536.0;
+ return value * font.sizePerUnit();
#else
float OpenTypeMathData::getMathConstant(const Font&, MathConstant) const
{
@@ -326,9 +323,9 @@
return mathItalicsCorrectionInfo->getItalicCorrection(*m_mathBuffer, glyph) * font.sizePerUnit();
#elif USE(HARFBUZZ)
-float OpenTypeMathData::getItalicCorrection(const Font&, Glyph glyph) const
+float OpenTypeMathData::getItalicCorrection(const Font& font, Glyph glyph) const
{
- return hb_ot_math_get_glyph_italics_correction(m_mathFont.get(), glyph) / 65536.0;
+ return hb_ot_math_get_glyph_italics_correction(m_mathFont.get(), glyph) * font.sizePerUnit();
#else
float OpenTypeMathData::getItalicCorrection(const Font&, Glyph) const
{