summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2019-09-04 10:57:06 +0100
committerMichael Stahl <Michael.Stahl@cib.de>2019-09-05 14:08:33 +0200
commitaab09918d349c251e0741263bfe252488690dd97 (patch)
treeb4df647e2883948c3420fb5805a1111115288dc4
parenttdf#127304 Chart: fix rotation of multilevel axis labels (diff)
downloadcore-aab09918d349c251e0741263bfe252488690dd97.tar.gz
core-aab09918d349c251e0741263bfe252488690dd97.zip
tdf#127189 FreeType <= 2.8 will fail to render stretched horizontal brace...
glyphs in starmath at a fairly low stretch ratio. The failure will set CAIRO_STATUS_FREETYPE_ERROR on the surface which cannot be cleared, so all further painting to the surface fails. This appears fixed in 2.9 with https://git.savannah.gnu.org/cgit/freetype/freetype2.git/commit/?id=91015cb41d8f56777f93394f5a60914bc0c0f330 "Improve complex rendering at high ppem" Change-Id: I8cbf8347ccd29beda4057b14f2e68678f6030bf4 Reviewed-on: https://gerrit.libreoffice.org/78588 Tested-by: Jenkins Reviewed-by: Michael Stahl <Michael.Stahl@cib.de>
-rw-r--r--vcl/inc/unx/glyphcache.hxx7
-rw-r--r--vcl/unx/generic/gdi/cairotextrender.cxx20
-rw-r--r--vcl/unx/generic/glyphs/freetype_glyphcache.cxx20
3 files changed, 47 insertions, 0 deletions
diff --git a/vcl/inc/unx/glyphcache.hxx b/vcl/inc/unx/glyphcache.hxx
index bc4d038b15b1..91881688fa22 100644
--- a/vcl/inc/unx/glyphcache.hxx
+++ b/vcl/inc/unx/glyphcache.hxx
@@ -120,6 +120,13 @@ public:
FreetypeFontInstance* GetFontInstance() const { return mpFontInstance.get(); }
void SetFontVariationsOnHBFont(hb_font_t* pHbFace) const;
+
+ // tdf#127189 FreeType <= 2.8 will fail to render stretched horizontal brace glyphs
+ // in starmath at a fairly low stretch ratio. This appears fixed in 2.9 with
+ // https://git.savannah.gnu.org/cgit/freetype/freetype2.git/commit/?id=91015cb41d8f56777f93394f5a60914bc0c0f330
+ // "Improve complex rendering at high ppem"
+ static bool AlmostHorizontalDrainsRenderingPool();
+
private:
friend class GlyphCache;
friend class FreetypeFontInstance;
diff --git a/vcl/unx/generic/gdi/cairotextrender.cxx b/vcl/unx/generic/gdi/cairotextrender.cxx
index d6355e65f173..aa006fa7c5d3 100644
--- a/vcl/unx/generic/gdi/cairotextrender.cxx
+++ b/vcl/unx/generic/gdi/cairotextrender.cxx
@@ -204,6 +204,22 @@ void CairoTextRender::DrawTextLayout(const GenericSalLayout& rLayout, const SalG
if (nWidth == 0 || nHeight == 0)
return;
+ int nRatio = nWidth * 10 / nHeight;
+ if (nRatio > 100 && rFSD.maTargetName == "OpenSymbol" && FreetypeFont::AlmostHorizontalDrainsRenderingPool())
+ {
+ // tdf#127189 FreeType <= 2.8 will fail to render stretched horizontal
+ // brace glyphs in starmath at a fairly low stretch ratio. The failure
+ // will set CAIRO_STATUS_FREETYPE_ERROR on the surface which cannot be
+ // cleared, so all further painting to the surface fails.
+
+ // This appears fixed in >= freetype 2.9
+
+ // Restrict this bodge to a stretch ratio > ~10 of the OpenSymbol font
+ // where it has been seen in practice.
+ SAL_WARN("vcl", "rendering text would fail with stretch ratio of: " << nRatio << ", with FreeType <= 2.8");
+ return;
+ }
+
/*
* It might be ideal to cache surface and cairo context between calls and
* only destroy it when the drawable changes, but to do that we need to at
@@ -330,6 +346,10 @@ void CairoTextRender::DrawTextLayout(const GenericSalLayout& rLayout, const SalG
cairo_set_font_matrix(cr, &m);
cairo_show_glyphs(cr, &cairo_glyphs[nStartIndex], nLen);
+ if (cairo_status(cr) != CAIRO_STATUS_SUCCESS)
+ {
+ SAL_WARN("vcl", "rendering text failed with stretch ratio of: " << nRatio << ", " << cairo_status_to_string(cairo_status(cr)));
+ }
#if OSL_DEBUG_LEVEL > 2
//draw origin
diff --git a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx
index 396c937f152c..0b65a8cb78e3 100644
--- a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx
+++ b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx
@@ -324,6 +324,26 @@ void GlyphCache::InitFreetype()
(void)vclFontFileList::get();
}
+namespace
+{
+ bool DoesAlmostHorizontalDrainRenderingPool()
+ {
+ FT_Int nMajor, nMinor, nPatch;
+ FT_Library_Version(aLibFT, &nMajor, &nMinor, &nPatch);
+ if (nMajor > 2)
+ return false;
+ if (nMajor == 2 && nMinor <= 8)
+ return true;
+ return false;
+ }
+}
+
+bool FreetypeFont::AlmostHorizontalDrainsRenderingPool()
+{
+ static bool bAlmostHorizontalDrainsRenderingPool = DoesAlmostHorizontalDrainRenderingPool();
+ return bAlmostHorizontalDrainsRenderingPool;
+}
+
FT_Face FreetypeFont::GetFtFace() const
{
FT_Activate_Size( maSizeFT );