include/vcl/metric.hxx                         |    3 +++
 vcl/inc/impfontmetricdata.hxx                  |    3 +++
 vcl/qt5/QtGraphics_Text.cxx                    |    1 +
 vcl/quartz/ctfonts.cxx                         |    1 +
 vcl/source/font/fontmetric.cxx                 |   21 +++++++++++++++++++++
 vcl/source/outdev/font.cxx                     |    1 +
 vcl/unx/generic/glyphs/freetype_glyphcache.cxx |    1 +
 vcl/win/gdi/salfont.cxx                        |    1 +
 8 files changed, 32 insertions(+)

New commits:
commit 5f92e8cf3da6b5f66b6ef23219fcc91d2ad7c754
Author:     Mark Hung <mark...@gmail.com>
AuthorDate: Sun May 1 13:50:00 2022 +0800
Commit:     Mark Hung <mark...@gmail.com>
CommitDate: Tue May 10 15:01:25 2022 +0200

    tdf#104930 Implement TextMetric::GetHangingBaseline.
    
    The text metric value is initialized in 
ImplFontMetricData::ImplInitBaselines() using harfbuzz API 
hb_ot_layout_get_baseline. It can't handle multiple hanging baselines of the 
same font for different scripts yet because the script is fixed to 
HB_SCRIPT_UNKOWN.
    
    Change-Id: I2574f0dba45501187064b9341c573159914a4a17
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133667
    Tested-by: Jenkins
    Reviewed-by: Mark Hung <mark...@gmail.com>

diff --git a/include/vcl/metric.hxx b/include/vcl/metric.hxx
index a89e8eedfb0c..36964eef2347 100644
--- a/include/vcl/metric.hxx
+++ b/include/vcl/metric.hxx
@@ -47,6 +47,7 @@ public:
     tools::Long                GetLineHeight() const                       { 
return mnLineHeight; } // TODO this is ascent + descnt
     tools::Long                GetSlant() const                            { 
return mnSlant; }
     tools::Long                GetBulletOffset() const                     { 
return mnBulletOffset; }
+    tools::Long                GetHangingBaseline() const                  { 
return mnHangingBaseline; }
 
     void                SetAscent( tools::Long nAscent )                   { 
mnAscent = nAscent; }
     void                SetDescent( tools::Long nDescent )                 { 
mnDescent = nDescent; }
@@ -55,6 +56,7 @@ public:
     void                SetLineHeight( tools::Long nHeight )               { 
mnLineHeight = nHeight; } // TODO this is ascent + descent
     void                SetSlant( tools::Long nSlant )                     { 
mnSlant = nSlant; }
     void                SetBulletOffset( tools::Long nOffset )             { 
mnBulletOffset = nOffset; }
+    void                SetHangingBaseline( tools::Long nBaseline )        { 
mnHangingBaseline = nBaseline; }
 
     bool                IsFullstopCentered() const                  { return 
mbFullstopCentered; }
 
@@ -74,6 +76,7 @@ private:
     tools::Long                mnLineHeight;                  // 
Ascent+Descent+EmphasisMark
     tools::Long                mnSlant;                       // Slant
     tools::Long                mnBulletOffset;                // Offset for 
non-printing character
+    tools::Long                mnHangingBaseline;             // Offset from 
Romn baseline to hanigng baseline.
 
     bool                mbFullstopCentered;
 };
diff --git a/vcl/inc/impfontmetricdata.hxx b/vcl/inc/impfontmetricdata.hxx
index aca6da417367..0ad29f3e821e 100644
--- a/vcl/inc/impfontmetricdata.hxx
+++ b/vcl/inc/impfontmetricdata.hxx
@@ -58,6 +58,7 @@ public:
     tools::Long            GetExternalLeading() const                          
            { return mnExtLeading; }
     int             GetSlant() const                                           
     { return mnSlant; }
     tools::Long            GetMinKashida() const                               
            { return mnMinKashida; }
+    tools::Long            GetHangingBaseline() const                          
            { return mnHangingBaseline; }
 
     void            SetSlant(int nSlant)                                       
     { mnSlant=nSlant; }
     void            SetMinKashida( tools::Long nMinKashida )                   
            { mnMinKashida=nMinKashida; }
@@ -99,6 +100,7 @@ public:
     void            ImplInitAboveTextLineSize();
     void            ImplInitFlags( const OutputDevice* pDev );
     void            ImplCalcLineSpacing(LogicalFontInstance *pFontInstance);
+    void            ImplInitBaselines(LogicalFontInstance *pFontInstance);
 
 private:
     bool            ShouldUseWinMetrics(const vcl::TTGlobalFontInfo& rInfo) 
const;
@@ -115,6 +117,7 @@ private:
     tools::Long            mnExtLeading;               // External Leading
     int             mnSlant;                    // Slant (Italic/Oblique)
     tools::Long            mnMinKashida;               // Minimal width of 
kashida (Arabic)
+    tools::Long            mnHangingBaseline;          // Offset of haning 
baseline to Romn baseline
 
     // font attributes queried from the font instance
     bool            mbFullstopCentered;
diff --git a/vcl/qt5/QtGraphics_Text.cxx b/vcl/qt5/QtGraphics_Text.cxx
index 02158fca29db..9859ff02f061 100644
--- a/vcl/qt5/QtGraphics_Text.cxx
+++ b/vcl/qt5/QtGraphics_Text.cxx
@@ -63,6 +63,7 @@ void QtGraphics::GetFontMetric(ImplFontMetricDataRef& rFMD, 
int nFallbackLevel)
     QtFontFace::fillAttributesFromQFont(*m_pTextStyle[nFallbackLevel], *rFMD);
 
     rFMD->ImplCalcLineSpacing(m_pTextStyle[nFallbackLevel].get());
+    rFMD->ImplInitBaselines(m_pTextStyle[nFallbackLevel].get());
 
     rFMD->SetSlant(0);
     rFMD->SetWidth(aRawFont.averageCharWidth());
diff --git a/vcl/quartz/ctfonts.cxx b/vcl/quartz/ctfonts.cxx
index 99b9066d3a0a..7985905cc404 100644
--- a/vcl/quartz/ctfonts.cxx
+++ b/vcl/quartz/ctfonts.cxx
@@ -107,6 +107,7 @@ void CoreTextStyle::GetFontMetric( ImplFontMetricDataRef 
const & rxFontMetric )
     CTFontRef aCTFontRef = static_cast<CTFontRef>(CFDictionaryGetValue( 
mpStyleDict, kCTFontAttributeName ));
 
     rxFontMetric->ImplCalcLineSpacing(this);
+    rxFontMetric->ImplInitBaselines(this);
 
     // since ImplFontMetricData::mnWidth is only used for stretching/squeezing 
fonts
     // setting this width to the pixel height of the fontsize is good enough
diff --git a/vcl/source/font/fontmetric.cxx b/vcl/source/font/fontmetric.cxx
index 660b1a7d1f78..0021c454fa99 100644
--- a/vcl/source/font/fontmetric.cxx
+++ b/vcl/source/font/fontmetric.cxx
@@ -34,6 +34,7 @@
 
 #include <com/sun/star/uno/Sequence.hxx>
 #include <comphelper/sequence.hxx>
+#include <hb-ot.h>
 
 using namespace ::com::sun::star;
 using namespace ::com::sun::star::uno;
@@ -48,6 +49,7 @@ FontMetric::FontMetric()
     mnLineHeight( 0 ),
     mnSlant( 0 ),
     mnBulletOffset( 0 ),
+    mnHangingBaseline( 0 ),
     mbFullstopCentered( false )
 {}
 
@@ -408,4 +410,23 @@ void 
ImplFontMetricData::ImplCalcLineSpacing(LogicalFontInstance *pFontInstance)
              );
 }
 
+void ImplFontMetricData::ImplInitBaselines(LogicalFontInstance *pFontInstance)
+{
+    hb_font_t* pHbFont = pFontInstance->GetHbFont();
+    hb_face_t* pHbFace = hb_font_get_face(pHbFont);
+    double nUPEM = hb_face_get_upem(pHbFace);
+    double fScale = mnHeight / nUPEM;
+    hb_position_t nBaseline = 0;
+
+    if (hb_ot_layout_get_baseline(pHbFont,
+             HB_OT_LAYOUT_BASELINE_TAG_HANGING,
+                                HB_DIRECTION_INVALID,
+                                HB_SCRIPT_UNKNOWN,
+                                HB_TAG_NONE,
+                                &nBaseline))
+    {
+        mnHangingBaseline = nBaseline * fScale;
+    }
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/outdev/font.cxx b/vcl/source/outdev/font.cxx
index ba487b0198c3..611a49bbdacf 100644
--- a/vcl/source/outdev/font.cxx
+++ b/vcl/source/outdev/font.cxx
@@ -214,6 +214,7 @@ FontMetric OutputDevice::GetFontMetric() const
     aMetric.SetExternalLeading( ImplDevicePixelToLogicHeight( 
GetFontExtLeading() ) );
     aMetric.SetLineHeight( ImplDevicePixelToLogicHeight( 
xFontMetric->GetAscent() + xFontMetric->GetDescent() + mnEmphasisAscent + 
mnEmphasisDescent ) );
     aMetric.SetSlant( ImplDevicePixelToLogicHeight( xFontMetric->GetSlant() ) 
);
+    aMetric.SetHangingBaseline( ImplDevicePixelToLogicHeight( 
xFontMetric->GetHangingBaseline() ) );
 
     // get miscellaneous data
     aMetric.SetQuality( xFontMetric->GetQuality() );
diff --git a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx 
b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx
index 39fee3853dce..bb7d3e10e474 100644
--- a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx
+++ b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx
@@ -542,6 +542,7 @@ void FreetypeFont::GetFontMetric(ImplFontMetricDataRef 
const & rxTo) const
     FT_Activate_Size( maSizeFT );
 
     rxTo->ImplCalcLineSpacing(&mrFontInstance);
+    rxTo->ImplInitBaselines(&mrFontInstance);
 
     rxTo->SetSlant( 0 );
     rxTo->SetWidth( mnWidth );
diff --git a/vcl/win/gdi/salfont.cxx b/vcl/win/gdi/salfont.cxx
index bc112a26d2ee..3a2eb226114a 100644
--- a/vcl/win/gdi/salfont.cxx
+++ b/vcl/win/gdi/salfont.cxx
@@ -946,6 +946,7 @@ void WinSalGraphics::GetFontMetric( ImplFontMetricDataRef& 
rxFontMetric, int nFa
 
     rxFontMetric->SetMinKashida(pFontInstance->GetKashidaWidth());
     rxFontMetric->ImplCalcLineSpacing(pFontInstance.get());
+    rxFontMetric->ImplInitBaselines(pFontInstance.get());
 
     // get the font metric
     OUTLINETEXTMETRICW aOutlineMetric;

Reply via email to