diff --git a/framework/draw/internal/fontfacedu.cpp b/framework/draw/internal/fontfacedu.cpp index 321cb9d43c..a53de24981 100644 --- a/framework/draw/internal/fontfacedu.cpp +++ b/framework/draw/internal/fontfacedu.cpp @@ -93,6 +93,26 @@ f26dot6_t FontFaceDU::capHeight() const return m_origin->capHeight(); } +f26dot6_t FontFaceDU::underlinePosition() const +{ + return m_origin->underlinePosition(); +} + +f26dot6_t FontFaceDU::underlineThickness() const +{ + return m_origin->underlineThickness(); +} + +f26dot6_t FontFaceDU::strikeoutPosition() const +{ + return m_origin->strikeoutPosition(); +} + +f26dot6_t FontFaceDU::strikeoutThickness() const +{ + return m_origin->strikeoutThickness(); +} + std::vector FontFaceDU::glyphs(const char32_t* text, int text_length) const { std::vector glyphs = m_origin->glyphs(text, text_length); diff --git a/framework/draw/internal/fontfacedu.h b/framework/draw/internal/fontfacedu.h index a835443cef..1444a77dad 100644 --- a/framework/draw/internal/fontfacedu.h +++ b/framework/draw/internal/fontfacedu.h @@ -41,6 +41,11 @@ class FontFaceDU : public IFontFace f26dot6_t xHeight() const override; f26dot6_t capHeight() const override; + f26dot6_t underlinePosition() const override; + f26dot6_t underlineThickness() const override; + f26dot6_t strikeoutPosition() const override; + f26dot6_t strikeoutThickness() const override; + std::vector glyphs(const char32_t* text, int text_length) const override; glyph_idx_t glyphIndex(char32_t ucs4) const override; glyph_idx_t glyphIndex(const std::string& glyphName) const override; diff --git a/framework/draw/internal/fontfaceft.cpp b/framework/draw/internal/fontfaceft.cpp index 4e2c1978de..04611c9ecb 100644 --- a/framework/draw/internal/fontfaceft.cpp +++ b/framework/draw/internal/fontfaceft.cpp @@ -573,6 +573,44 @@ f26dot6_t FontFaceFT::capHeight() const return gm->bbox.height(); } +f26dot6_t FontFaceFT::underlinePosition() const +{ + f26dot6_t thickness = std::round(m_data->face->underline_thickness * m_data->face->size->metrics.y_ppem * 64.0 + / (double)m_data->face->units_per_EM); + f26dot6_t centerPos = std::round(-m_data->face->underline_position * m_data->face->size->metrics.y_ppem * 64.0 + / (double)m_data->face->units_per_EM); + return centerPos - thickness / 2; +} + +f26dot6_t FontFaceFT::underlineThickness() const +{ + f26dot6_t result = std::round(m_data->face->underline_thickness * m_data->face->size->metrics.y_ppem * 64.0 + / (double)m_data->face->units_per_EM); + return std::max(result, (f26dot6_t)64); +} + +f26dot6_t FontFaceFT::strikeoutPosition() const +{ + TT_OS2* os2 = (TT_OS2*)FT_Get_Sfnt_Table(m_data->face, ft_sfnt_os2); + if (os2 && os2->yStrikeoutPosition) { + f26dot6_t result = std::round(os2->yStrikeoutPosition * m_data->face->size->metrics.y_ppem * 64.0 + / (double)m_data->face->units_per_EM); + return result; + } + return ascent() / 3; +} + +f26dot6_t FontFaceFT::strikeoutThickness() const +{ + TT_OS2* os2 = (TT_OS2*)FT_Get_Sfnt_Table(m_data->face, ft_sfnt_os2); + if (os2 && os2->yStrikeoutSize) { + f26dot6_t result = std::round(os2->yStrikeoutSize * m_data->face->size->metrics.y_ppem * 64.0 + / (double)m_data->face->units_per_EM); + return std::max(result, (f26dot6_t)64); + } + return underlineThickness(); +} + GlyphMetrics* FontFaceFT::glyphMetrics(glyph_idx_t idx) const { if (m_data->glyphsMetrics.find(idx) != m_data->glyphsMetrics.end()) { diff --git a/framework/draw/internal/fontfaceft.h b/framework/draw/internal/fontfaceft.h index c7284cf240..dd28576980 100644 --- a/framework/draw/internal/fontfaceft.h +++ b/framework/draw/internal/fontfaceft.h @@ -45,6 +45,11 @@ class FontFaceFT : public IFontFace f26dot6_t xHeight() const override; f26dot6_t capHeight() const override; + f26dot6_t underlinePosition() const override; + f26dot6_t underlineThickness() const override; + f26dot6_t strikeoutPosition() const override; + f26dot6_t strikeoutThickness() const override; + std::vector glyphs(const char32_t* text, int text_length) const override; glyph_idx_t glyphIndex(char32_t ucs4) const override; glyph_idx_t glyphIndex(const std::string& glyphName) const override; diff --git a/framework/draw/internal/fontfacext.cpp b/framework/draw/internal/fontfacext.cpp index 5ad4a21e4e..5526538dc9 100644 --- a/framework/draw/internal/fontfacext.cpp +++ b/framework/draw/internal/fontfacext.cpp @@ -105,6 +105,14 @@ bool FontFaceXT::load(const FaceKey& key, const muse::io::path_t& path, bool isS m_xHeight = std::stol(valStr); } else if (name == "capHeight") { m_capHeight = std::stol(valStr); + } else if (name == "underlinePosition") { + m_underlinePosition = std::stol(valStr); + } else if (name == "underlineThickness") { + m_underlineThickness = std::stol(valStr); + } else if (name == "strikeoutPosition") { + m_strikeoutPosition = std::stol(valStr); + } else if (name == "strikeoutThickness") { + m_strikeoutThickness = std::stol(valStr); } else { LOGW() << "unknown param: " << name; } @@ -275,6 +283,26 @@ f26dot6_t FontFaceXT::capHeight() const return m_capHeight; } +f26dot6_t FontFaceXT::underlinePosition() const +{ + return m_underlinePosition; +} + +f26dot6_t FontFaceXT::underlineThickness() const +{ + return m_underlineThickness; +} + +f26dot6_t FontFaceXT::strikeoutPosition() const +{ + return m_strikeoutPosition; +} + +f26dot6_t FontFaceXT::strikeoutThickness() const +{ + return m_strikeoutThickness; +} + void FontFaceXT::applyLigatures(std::vector& glyphs, const Ligatures& ls) { for (const Ligature& l : ls) { diff --git a/framework/draw/internal/fontfacext.h b/framework/draw/internal/fontfacext.h index bfff0b446b..d1d76b06ff 100644 --- a/framework/draw/internal/fontfacext.h +++ b/framework/draw/internal/fontfacext.h @@ -89,6 +89,11 @@ class FontFaceXT : public IFontFace f26dot6_t xHeight() const override; f26dot6_t capHeight() const override; + f26dot6_t underlinePosition() const override; + f26dot6_t underlineThickness() const override; + f26dot6_t strikeoutPosition() const override; + f26dot6_t strikeoutThickness() const override; + std::vector glyphs(const char32_t* text, int text_length) const override; glyph_idx_t glyphIndex(char32_t ucs4) const override; glyph_idx_t glyphIndex(const std::string& glyphName) const override; @@ -119,6 +124,10 @@ class FontFaceXT : public IFontFace f26dot6_t m_descent = -1; f26dot6_t m_xHeight = -1; f26dot6_t m_capHeight = -1; + f26dot6_t m_underlinePosition = -1; + f26dot6_t m_underlineThickness = -1; + f26dot6_t m_strikeoutPosition = -1; + f26dot6_t m_strikeoutThickness = -1; Ligatures m_ligatures; Kernings m_kernings; diff --git a/framework/draw/internal/fontsengine.cpp b/framework/draw/internal/fontsengine.cpp index debb38a563..07eb3b8fee 100644 --- a/framework/draw/internal/fontsengine.cpp +++ b/framework/draw/internal/fontsengine.cpp @@ -216,6 +216,42 @@ double FontsEngine::descent(const Font& f) const return from_f26d6(rf->face->descent()) * rf->pixelScale(); } +double FontsEngine::underlinePosition(const Font& f) const +{ + RequireFace* rf = fontFace(f); + IF_ASSERT_FAILED(rf && rf->face) { + return 0.0; + } + return from_f26d6(rf->face->underlinePosition()) * rf->pixelScale(); +} + +double FontsEngine::underlineThickness(const Font& f) const +{ + RequireFace* rf = fontFace(f); + IF_ASSERT_FAILED(rf && rf->face) { + return 1.0; + } + return from_f26d6(rf->face->underlineThickness()) * rf->pixelScale(); +} + +double FontsEngine::strikeoutPosition(const Font& f) const +{ + RequireFace* rf = fontFace(f); + IF_ASSERT_FAILED(rf && rf->face) { + return 0.0; + } + return from_f26d6(rf->face->strikeoutPosition()) * rf->pixelScale(); +} + +double FontsEngine::strikeoutThickness(const Font& f) const +{ + RequireFace* rf = fontFace(f); + IF_ASSERT_FAILED(rf && rf->face) { + return 1.0; + } + return from_f26d6(rf->face->strikeoutThickness()) * rf->pixelScale(); +} + bool FontsEngine::inFont(const Font& f, char32_t ucs4) const { RequireFace* rf = fontFace(f); diff --git a/framework/draw/internal/fontsengine.h b/framework/draw/internal/fontsengine.h index 70ba94fbc7..c9e9e8a24c 100644 --- a/framework/draw/internal/fontsengine.h +++ b/framework/draw/internal/fontsengine.h @@ -53,6 +53,11 @@ class FontsEngine : public IFontsEngine, public Contextable double ascent(const Font& f) const override; double descent(const Font& f) const override; + double underlinePosition(const Font& f) const override; + double underlineThickness(const Font& f) const override; + double strikeoutPosition(const Font& f) const override; + double strikeoutThickness(const Font& f) const override; + bool inFont(const Font& f, char32_t ucs4) const override; double horizontalAdvance(const Font& f, const char32_t& ch) const override; diff --git a/framework/draw/internal/ifontface.h b/framework/draw/internal/ifontface.h index d56041c465..3cd5374d5e 100644 --- a/framework/draw/internal/ifontface.h +++ b/framework/draw/internal/ifontface.h @@ -54,6 +54,11 @@ class IFontFace virtual f26dot6_t xHeight() const = 0; virtual f26dot6_t capHeight() const = 0; + virtual f26dot6_t underlinePosition() const = 0; + virtual f26dot6_t underlineThickness() const = 0; + virtual f26dot6_t strikeoutPosition() const = 0; + virtual f26dot6_t strikeoutThickness() const = 0; + virtual std::vector glyphs(const char32_t* text, int text_length) const = 0; virtual glyph_idx_t glyphIndex(char32_t ucs4) const = 0; virtual glyph_idx_t glyphIndex(const std::string& glyphName) const = 0; diff --git a/framework/draw/internal/ifontsengine.h b/framework/draw/internal/ifontsengine.h index cf9a44d4b7..74854404ad 100644 --- a/framework/draw/internal/ifontsengine.h +++ b/framework/draw/internal/ifontsengine.h @@ -46,6 +46,11 @@ class IFontsEngine : MODULE_GLOBAL_INTERFACE virtual double ascent(const Font& f) const = 0; virtual double descent(const Font& f) const = 0; + virtual double underlinePosition(const Font& f) const = 0; + virtual double underlineThickness(const Font& f) const = 0; + virtual double strikeoutPosition(const Font& f) const = 0; + virtual double strikeoutThickness(const Font& f) const = 0; + virtual bool inFont(const Font& f, char32_t ucs4) const = 0; virtual double horizontalAdvance(const Font& f, const char32_t& ch) const = 0; diff --git a/framework/draw/types/fontstypes.h b/framework/draw/types/fontstypes.h index cdc078aaae..9c82a5b0cc 100644 --- a/framework/draw/types/fontstypes.h +++ b/framework/draw/types/fontstypes.h @@ -149,6 +149,8 @@ struct FontParams { Font::Type type = Font::Type::Undefined; bool bold = false; bool italic = false; + bool underline = false; + bool strike = false; float pointSize = 0.0f; }; }