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;