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 ;
-
 }
 
 

Reply via email to