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: خالد حسني <[email protected]>
diff --git a/vcl/inc/impfontmetricdata.hxx b/vcl/inc/impfontmetricdata.hxx
index d5b24430..0fb44a8 100644
--- a/vcl/inc/impfontmetricdata.hxx
+++ b/vcl/inc/impfontmetricdata.hxx
@@ -102,6 +102,7 @@
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 95263c6..3895caf 100644
--- a/vcl/source/font/fontmetric.cxx
+++ b/vcl/source/font/fontmetric.cxx
@@ -176,8 +176,67 @@
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 @@
mnDStrikeoutOffset1 = nStrikeoutOffset - n2LineDY2 - n2LineHeight;
mnDStrikeoutOffset2 = mnDStrikeoutOffset1 + n2LineDY + n2LineHeight;
mnBulletOffset = ( pDev->GetTextWidth( OUString( u' ' ) ) - pDev->GetTextWidth( OUString( u'\x00b7' ) ) ) >> 1 ;
}