vcl/inc/impfontmetricdata.hxx | 1 vcl/source/font/fontmetric.cxx | 61 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 60 insertions(+), 2 deletions(-)
New commits: commit ba03e033d1be4bc49f2a8d6afbeecd381507b242 Author: Khaled Hosny <kha...@aliftype.com> AuthorDate: Fri Sep 30 18:36:59 2022 +0200 Commit: خالد حسني <kha...@aliftype.com> CommitDate: Fri Sep 30 20:54:47 2022 +0200 vcl: Use font’s underline/strike position and size This respects the values set by font designer, which are usually better than the values we calculate especially for fonts with deep descenders (like Amiri). Old code is kept as fallback in case the font does not provide such values. Change-Id: I51a5147e4c6e006d1dcd13817ed21f0f62b47e97 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/140803 Tested-by: Jenkins Reviewed-by: خالد حسني <kha...@aliftype.com> diff --git a/vcl/inc/impfontmetricdata.hxx b/vcl/inc/impfontmetricdata.hxx index d5b244309047..0fb44a840bda 100644 --- a/vcl/inc/impfontmetricdata.hxx +++ b/vcl/inc/impfontmetricdata.hxx @@ -102,6 +102,7 @@ public: void ImplInitBaselines(LogicalFontInstance *pFontInstance); private: + bool ImplInitTextLineSizeHarfBuzz(LogicalFontInstance *pFontInstance); bool ShouldUseWinMetrics(int, int, int, int, int, int) const; // font instance attributes from the font request diff --git a/vcl/source/font/fontmetric.cxx b/vcl/source/font/fontmetric.cxx index 95263c694b3b..3895caf7b0fb 100644 --- a/vcl/source/font/fontmetric.cxx +++ b/vcl/source/font/fontmetric.cxx @@ -176,8 +176,67 @@ ImplFontMetricData::ImplFontMetricData( const vcl::font::FontSelectPattern& rFon SetStyleName( rFontSelData.GetStyleName() ); } +bool ImplFontMetricData::ImplInitTextLineSizeHarfBuzz(LogicalFontInstance* pFont) +{ + auto* pHbFont = pFont->GetHbFont(); + double fScale = 0; + pFont->GetScale(nullptr, &fScale); + + hb_position_t nUnderlineSize, nUnderlineOffset, nStrikeoutSize, nStrikeoutOffset; + if (hb_ot_metrics_get_position(pHbFont, HB_OT_METRICS_TAG_UNDERLINE_SIZE, &nUnderlineSize) + && hb_ot_metrics_get_position(pHbFont, HB_OT_METRICS_TAG_UNDERLINE_OFFSET, + &nUnderlineOffset) + && hb_ot_metrics_get_position(pHbFont, HB_OT_METRICS_TAG_STRIKEOUT_SIZE, &nStrikeoutSize) + && hb_ot_metrics_get_position(pHbFont, HB_OT_METRICS_TAG_STRIKEOUT_OFFSET, + &nStrikeoutOffset)) + { + double nOffset = -nUnderlineOffset; + double nSize = nUnderlineSize; + double nSize2 = nSize / 2.; + double nBSize = nSize * 2.; + double n2Size = nBSize / 3.; + + mnUnderlineSize = round(nSize * fScale); + mnUnderlineOffset = round(nOffset * fScale); + + mnBUnderlineSize = round(nBSize * fScale); + mnBUnderlineOffset = round((nOffset - nSize2) * fScale); + + mnDUnderlineSize = round(n2Size * fScale); + mnDUnderlineOffset1 = mnBUnderlineOffset; + mnDUnderlineOffset2 = round((nOffset - nSize2 - n2Size + nBSize) * fScale); + + mnWUnderlineSize = mnBUnderlineSize; + mnWUnderlineOffset = round((nOffset + nSize) * fScale); + + nOffset = -nStrikeoutOffset; + nSize = nStrikeoutSize; + nSize2 = nSize / 2.; + nBSize = nSize * 2.; + n2Size = nBSize / 3.; + + mnStrikeoutSize = round(nSize * fScale); + mnStrikeoutOffset = round(nOffset * fScale); + + mnBStrikeoutSize = round(nBSize * fScale); + mnBStrikeoutOffset = round((nOffset - nSize2) * fScale); + + mnDStrikeoutSize = round(n2Size * fScale); + mnDStrikeoutOffset1 = mnBStrikeoutOffset; + mnDStrikeoutOffset2 = round((nOffset - nSize2 - n2Size + nBSize) * fScale); + + return true; + } + return false; +} + void ImplFontMetricData::ImplInitTextLineSize( const OutputDevice* pDev ) { + mnBulletOffset = ( pDev->GetTextWidth( OUString( u' ' ) ) - pDev->GetTextWidth( OUString( u'\x00b7' ) ) ) >> 1 ; + + if (ImplInitTextLineSizeHarfBuzz(const_cast<LogicalFontInstance*>(pDev->GetFontInstance()))) + return; + tools::Long nDescent = mnDescent; if ( nDescent <= 0 ) { @@ -261,8 +320,6 @@ void ImplFontMetricData::ImplInitTextLineSize( const OutputDevice* pDev ) mnDStrikeoutOffset1 = nStrikeoutOffset - n2LineDY2 - n2LineHeight; mnDStrikeoutOffset2 = mnDStrikeoutOffset1 + n2LineDY + n2LineHeight; - mnBulletOffset = ( pDev->GetTextWidth( OUString( u' ' ) ) - pDev->GetTextWidth( OUString( u'\x00b7' ) ) ) >> 1 ; - }