summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKhaled Hosny <khaledhosny@eglug.org>2019-08-21 11:17:53 +0200
committerKhaled Hosny <khaledhosny@eglug.org>2019-08-25 12:07:57 +0200
commit502d73cda8fa1f482634bb6435fd1440757fdad9 (patch)
treef3b3221d1019fb8351db6a3ad2ca5e7b3d5e69a7
parent3975c4e85ff34e48d953b110f947c1768b59e750 (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.hxx2
-rw-r--r--vcl/source/font/fontinstance.cxx43
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;