diff options
author | Khaled Hosny <khaledhosny@eglug.org> | 2019-08-21 11:17:53 +0200 |
---|---|---|
committer | Khaled Hosny <khaledhosny@eglug.org> | 2019-08-25 12:07:57 +0200 |
commit | 502d73cda8fa1f482634bb6435fd1440757fdad9 (patch) | |
tree | f3b3221d1019fb8351db6a3ad2ca5e7b3d5e69a7 | |
parent | 3975c4e85ff34e48d953b110f947c1768b59e750 (diff) |
Use HarfBuzz to get glyph bounding rectangle
For consistent cross-platform results that also matches our glyph
advances since platform functions might be using hints which we don’t
use.
Keep platform-specific implementations as fallback since HarfBuzz
internal font functions (that we use) did not support glyph extents for
fonts with CFF table before 2.3.0.
Change-Id: I62c6c703ea37d41fd0998309dacadd56565a0fae
Reviewed-on: https://gerrit.libreoffice.org/77870
Tested-by: Jenkins
Reviewed-by: Khaled Hosny <khaledhosny@eglug.org>
-rw-r--r-- | vcl/inc/fontinstance.hxx | 2 | ||||
-rw-r--r-- | vcl/source/font/fontinstance.cxx | 43 |
2 files changed, 42 insertions, 3 deletions
diff --git a/vcl/inc/fontinstance.hxx b/vcl/inc/fontinstance.hxx index fc3f206dba56..b22d76e3b070 100644 --- a/vcl/inc/fontinstance.hxx +++ b/vcl/inc/fontinstance.hxx @@ -71,7 +71,7 @@ public: // TODO: make data members private const PhysicalFontFace* GetFontFace() const { return m_pFontFace.get(); } const ImplFontCache* GetFontCache() const { return mpFontCache; } - bool GetGlyphBoundRect(sal_GlyphId, tools::Rectangle&, bool) const; + bool GetGlyphBoundRect(sal_GlyphId, tools::Rectangle&, bool); virtual bool GetGlyphOutline(sal_GlyphId, basegfx::B2DPolyPolygon&, bool) const = 0; int GetKashidaWidth(); diff --git a/vcl/source/font/fontinstance.cxx b/vcl/source/font/fontinstance.cxx index 58d72083f130..808f2d0a5c27 100644 --- a/vcl/source/font/fontinstance.cxx +++ b/vcl/source/font/fontinstance.cxx @@ -144,12 +144,51 @@ void LogicalFontInstance::IgnoreFallbackForUnicode( sal_UCS4 cChar, FontWeight e mpUnicodeFallbackList->erase( it ); } -bool LogicalFontInstance::GetGlyphBoundRect(sal_GlyphId nID, tools::Rectangle &rRect, bool bVertical) const +bool LogicalFontInstance::GetGlyphBoundRect(sal_GlyphId nID, tools::Rectangle &rRect, bool bVertical) { if (mpFontCache && mpFontCache->GetCachedGlyphBoundRect(this, nID, rRect)) return true; - bool res = ImplGetGlyphBoundRect(nID, rRect, bVertical); + hb_font_t* pHbFont = GetHbFont(); + hb_glyph_extents_t aExtents; + bool res = hb_font_get_glyph_extents(pHbFont, nID, &aExtents); + if (res) + { + double nXScale = 0, nYScale = 0; + GetScale(&nXScale, &nYScale); + + double fMinX = aExtents.x_bearing; + double fMinY = aExtents.y_bearing; + double fMaxX = aExtents.x_bearing + aExtents.width; + double fMaxY = aExtents.y_bearing + aExtents.height; + + tools::Rectangle aRect( std::floor(fMinX * nXScale), + -std::ceil(fMinY * nYScale), + std::ceil(fMaxX * nXScale), + -std::floor(fMaxY * nYScale)); + + if (mnOrientation && !bVertical) + { + // Apply font rotation. + const double fRad = basegfx::deg2rad(mnOrientation); + const double fCos = cos(fRad); + const double fSin = sin(fRad); + + rRect.SetLeft( fCos * aRect.Left() + fSin * aRect.Top()); + rRect.SetTop( -fSin * aRect.Left() - fCos * aRect.Top()); + rRect.SetRight( fCos * aRect.Right() + fSin * aRect.Bottom()); + rRect.SetBottom(-fSin * aRect.Right() - fCos * aRect.Bottom()); + } + else + rRect = aRect; + } + else + { + // Fallback to platform implementations. + // TODO: remove once we require HarfBuzz >= 2.3.0 + res = ImplGetGlyphBoundRect(nID, rRect, bVertical); + } + if (mpFontCache && res) mpFontCache->CacheGlyphBoundRect(this, nID, rRect); return res; |