[libreoffice] Resolves: rhbz#665800 missing glyph symbol shown when toggling bold/italic for Sinhala text
Caolan McNamara
caolanm at fedoraproject.org
Thu Oct 27 12:04:25 UTC 2011
commit 81d48c0b6ce9feb35fee9cf8ea00f287a3d371db
Author: Caolán McNamara <caolanm at redhat.com>
Date: Thu Oct 27 13:04:20 2011 +0100
Resolves: rhbz#665800 missing glyph symbol shown when toggling bold/italic for Sinhala text
...o-32665-handle-that-FreeSerif-lacks-some-.patch | 286 ++++++++++++++++++++
...o-41556-font-sub-cache-of-nameA-nameB-is-.patch | 76 ++++++
libreoffice.spec | 11 +-
3 files changed, 372 insertions(+), 1 deletions(-)
---
diff --git a/0001-Resolves-fdo-32665-handle-that-FreeSerif-lacks-some-.patch b/0001-Resolves-fdo-32665-handle-that-FreeSerif-lacks-some-.patch
new file mode 100644
index 0000000..62c19c7
--- /dev/null
+++ b/0001-Resolves-fdo-32665-handle-that-FreeSerif-lacks-some-.patch
@@ -0,0 +1,286 @@
+From 58b48f188bbfd9a3382460d6de63848eb3db416d Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= <caolanm at redhat.com>
+Date: Thu, 27 Oct 2011 12:24:11 +0100
+Subject: [PATCH] Resolves: fdo#32665 handle that FreeSerif lacks some glyphs
+ in bold/italic
+
+FreeSerif lacks glyphs in bold/italic variants that it has in the normal one. A
+lot of our glyph fallback infrastructure, especially the caches don't expect
+that a normal variant of a font with extra emboldening or extra font skew can
+be a fallback for a bold/italic variant of itself which exists, but doesn't
+have the missing glyphs that the normal one does.
+
+We really need to improve our glyph/font caching, but we can get 90% of the
+way there by excluding such cases from the caches.
+---
+ vcl/generic/fontmanager/fontconfig.cxx | 18 ++++++++-
+ vcl/generic/fontmanager/fontsubst.cxx | 6 +++-
+ vcl/generic/glyphs/glyphcache.cxx | 7 ++++
+ vcl/inc/outfont.hxx | 19 ++++++++++
+ vcl/inc/vcl/fontmanager.hxx | 3 +-
+ vcl/source/gdi/outdev3.cxx | 60 ++++++++++++++++++++++----------
+ 6 files changed, 90 insertions(+), 23 deletions(-)
+
+diff --git a/vcl/generic/fontmanager/fontconfig.cxx b/vcl/generic/fontmanager/fontconfig.cxx
+index be91349..a4f5f7f 100644
+--- a/vcl/generic/fontmanager/fontconfig.cxx
++++ b/vcl/generic/fontmanager/fontconfig.cxx
+@@ -68,6 +68,9 @@ using namespace psp;
+ #ifndef FC_EMBOLDEN
+ #define FC_EMBOLDEN "embolden"
+ #endif
++#ifndef FC_MATRIX
++ #define FC_MATRIX "matrix"
++#endif
+ #ifndef FC_FONTFORMAT
+ #define FC_FONTFORMAT "fontformat"
+ #endif
+@@ -747,7 +750,7 @@ static void addtopattern(FcPattern *pPattern,
+ rtl::OUString PrintFontManager::Substitute(const rtl::OUString& rFontName,
+ rtl::OUString& rMissingCodes, const rtl::OString &rLangAttrib,
+ FontItalic &rItalic, FontWeight &rWeight,
+- FontWidth &rWidth, FontPitch &rPitch) const
++ FontWidth &rWidth, FontPitch &rPitch, bool &rEmbolden, ItalicMatrix &rMatrix) const
+ {
+ rtl::OUString aName;
+ FontCfgWrapper& rWrapper = FontCfgWrapper::get();
+@@ -834,6 +837,17 @@ rtl::OUString PrintFontManager::Substitute(const rtl::OUString& rFontName,
+ rPitch = convertSpacing(val);
+ if (FcResultMatch == FcPatternGetInteger(pSet->fonts[0], FC_WIDTH, 0, &val))
+ rWidth = convertWidth(val);
++ FcBool bEmbolden;
++ if (FcResultMatch == FcPatternGetBool(pSet->fonts[0], FC_EMBOLDEN, 0, &bEmbolden))
++ rEmbolden = bEmbolden;
++ FcMatrix *pMatrix = 0;
++ if (FcResultMatch == FcPatternGetMatrix(pSet->fonts[0], FC_MATRIX, 0, &pMatrix))
++ {
++ rMatrix.xx = pMatrix->xx;
++ rMatrix.xy = pMatrix->xy;
++ rMatrix.yx = pMatrix->yx;
++ rMatrix.yy = pMatrix->yy;
++ }
+ }
+
+ // update rMissingCodes by removing resolved unicodes
+@@ -844,7 +858,7 @@ rtl::OUString PrintFontManager::Substitute(const rtl::OUString& rFontName,
+ FcCharSet* unicodes;
+ if (!FcPatternGetCharSet(pSet->fonts[0], FC_CHARSET, 0, &unicodes))
+ {
+- for( sal_Int32 nStrIndex = 0; nStrIndex < rMissingCodes.getLength(); )
++ for( sal_Int32 nStrIndex = 0; nStrIndex < rMissingCodes.getLength(); )
+ {
+ // also handle unicode surrogates
+ const sal_uInt32 nCode = rMissingCodes.iterateCodePoints( &nStrIndex );
+diff --git a/vcl/generic/fontmanager/fontsubst.cxx b/vcl/generic/fontmanager/fontsubst.cxx
+index 3bf2d07..2d187b1 100644
+--- a/vcl/generic/fontmanager/fontsubst.cxx
++++ b/vcl/generic/fontmanager/fontsubst.cxx
+@@ -127,10 +127,14 @@ static ImplFontSelectData GetFcSubstitute(const ImplFontSelectData &rFontSelData
+ FontWeight eWeight = rFontSelData.GetWeight();
+ FontWidth eWidth = rFontSelData.GetWidthType();
+ FontPitch ePitch = rFontSelData.GetPitch();
++ bool bEmbolden = rFontSelData.mbEmbolden;
++ ItalicMatrix aMatrix = rFontSelData.maItalicMatrix;
+
+ const psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
+- aRet.maSearchName = rMgr.Substitute( rFontSelData.maTargetName, rMissingCodes, aLangAttrib, eItalic, eWeight, eWidth, ePitch);
++ aRet.maSearchName = rMgr.Substitute( rFontSelData.maTargetName, rMissingCodes, aLangAttrib, eItalic, eWeight, eWidth, ePitch, bEmbolden, aMatrix );
+
++ aRet.maItalicMatrix = aMatrix;
++ aRet.mbEmbolden = bEmbolden;
+ aRet.meItalic = eItalic;
+ aRet.meWeight = eWeight;
+ aRet.meWidthType = eWidth;
+diff --git a/vcl/generic/glyphs/glyphcache.cxx b/vcl/generic/glyphs/glyphcache.cxx
+index 5322b65..fa712bb 100644
+--- a/vcl/generic/glyphs/glyphcache.cxx
++++ b/vcl/generic/glyphs/glyphcache.cxx
+@@ -163,6 +163,13 @@ bool GlyphCache::IFSD_Equal::operator()( const ImplFontSelectData& rA, const Imp
+ != STRING_NOTFOUND) && rA.maTargetName != rB.maTargetName)
+ return false;
+ #endif
++
++ if (rA.mbEmbolden != rB.mbEmbolden)
++ return false;
++
++ if (rA.maItalicMatrix != rB.maItalicMatrix)
++ return false;
++
+ return true;
+ }
+
+diff --git a/vcl/inc/outfont.hxx b/vcl/inc/outfont.hxx
+index faf2b00..857d944 100644
+--- a/vcl/inc/outfont.hxx
++++ b/vcl/inc/outfont.hxx
+@@ -156,6 +156,22 @@ friend class ImplDevFontListData;
+ // - ImplFontSelectData -
+ // ----------------------
+
++struct ItalicMatrix
++{
++ double xx, xy, yx, yy;
++ ItalicMatrix() : xx(1), xy(0), yx(0), yy(1) {}
++};
++
++inline bool operator ==(const ItalicMatrix& a, const ItalicMatrix& b)
++{
++ return a.xx == b.xx && a.xy == b.xy && a.yx == b.yx && a.yy == b.yy;
++}
++
++inline bool operator !=(const ItalicMatrix& a, const ItalicMatrix& b)
++{
++ return a.xx != b.xx || a.xy != b.xy || a.yx != b.yx || a.yy != b.yy;
++}
++
+ class ImplFontSelectData : public ImplFontAttributes
+ {
+ public:
+@@ -175,6 +191,9 @@ public: // TODO: change to private
+ bool mbVertical; // vertical mode of requested font
+ bool mbNonAntialiased; // true if antialiasing is disabled
+
++ bool mbEmbolden; // Force emboldening
++ ItalicMatrix maItalicMatrix; // Force matrix for slant
++
+ const ImplFontData* mpFontData; // a matching ImplFontData object
+ ImplFontEntry* mpFontEntry; // pointer to the resulting FontCache entry
+ };
+diff --git a/vcl/inc/vcl/fontmanager.hxx b/vcl/inc/vcl/fontmanager.hxx
+index 0af5e14..4a110ad 100644
+--- a/vcl/inc/vcl/fontmanager.hxx
++++ b/vcl/inc/vcl/fontmanager.hxx
+@@ -37,6 +37,7 @@
+ #include "vcl/dllapi.h"
+ #include "vcl/helper.hxx"
+ #include "vcl/vclenum.hxx"
++#include "outfont.hxx"
+ #include "com/sun/star/lang/Locale.hpp"
+
+ #include <vector>
+@@ -649,7 +650,7 @@ public:
+
+ rtl::OUString Substitute( const rtl::OUString& rFontName, rtl::OUString& rMissingCodes,
+ const rtl::OString& rLangAttrib, FontItalic& rItalic, FontWeight& rWeight,
+- FontWidth& rWidth, FontPitch& rPitch) const;
++ FontWidth& rWidth, FontPitch& rPitch, bool &rEmboldening, ItalicMatrix &rMatrix) const;
+ bool hasFontconfig() const { return m_bFontconfigSuccess; }
+
+ int FreeTypeCharIndex( void *pFace, sal_uInt32 aChar );
+diff --git a/vcl/source/gdi/outdev3.cxx b/vcl/source/gdi/outdev3.cxx
+index b0f59cd..3cc438c 100755
+--- a/vcl/source/gdi/outdev3.cxx
++++ b/vcl/source/gdi/outdev3.cxx
+@@ -865,9 +865,11 @@ bool ImplFontData::IsBetterMatch( const ImplFontSelectData& rFSD, FontMatchStatu
+
+ if( rFSD.meWeight != WEIGHT_DONTKNOW )
+ {
+- // if not bold prefer light fonts to bold fonts
+- int nReqWeight = (int)rFSD.meWeight;
+- if ( rFSD.meWeight > WEIGHT_MEDIUM )
++ // if not bold or requiring emboldening prefer light fonts to bold fonts
++ FontWeight ePatternWeight = rFSD.mbEmbolden ? WEIGHT_NORMAL : rFSD.meWeight;
++
++ int nReqWeight = (int)ePatternWeight;
++ if ( ePatternWeight > WEIGHT_MEDIUM )
+ nReqWeight += 100;
+
+ int nGivenWeight = (int)meWeight;
+@@ -897,14 +899,17 @@ bool ImplFontData::IsBetterMatch( const ImplFontSelectData& rFSD, FontMatchStatu
+ nMatch += 150;
+ }
+
+- if ( rFSD.meItalic == ITALIC_NONE )
++ // if requiring custom matrix to fake italic, prefer upright font
++ FontItalic ePatternItalic = rFSD.maItalicMatrix != ItalicMatrix() ? ITALIC_NONE : rFSD.meItalic;
++
++ if ( ePatternItalic == ITALIC_NONE )
+ {
+ if( meItalic == ITALIC_NONE )
+ nMatch += 900;
+ }
+ else
+ {
+- if( rFSD.meItalic == meItalic )
++ if( ePatternItalic == meItalic )
+ nMatch += 900;
+ else if( meItalic != ITALIC_NONE )
+ nMatch += 600;
+@@ -1457,22 +1462,31 @@ ImplDevFontListData* ImplDevFontList::GetGlyphFallbackFont( ImplFontSelectData&
+ else
+ rFontSelData.maSearchName = String();
+
+- // cache the result even if there was no match
+- for(;;)
+- {
+- if( !rFontSelData.mpFontEntry->GetFallbackForUnicode( cChar, rFontSelData.GetWeight(), &rFontSelData.maSearchName ) )
+- rFontSelData.mpFontEntry->AddFallbackForUnicode( cChar, rFontSelData.GetWeight(), rFontSelData.maSearchName );
+- if( nStrIndex >= aOldMissingCodes.getLength() )
+- break;
+- cChar = aOldMissingCodes.iterateCodePoints( &nStrIndex );
+- }
+- if( rFontSelData.maSearchName.Len() != 0 )
++ //See fdo#32665 for an example. FreeSerif that has glyphs in normal
++ //font, but not in the italic or bold version
++ bool bSubSetOfFontRequiresPropertyFaking = rFontSelData.mbEmbolden || rFontSelData.maItalicMatrix != ItalicMatrix();
++
++ // cache the result even if there was no match, unless its from part of a font for which the properties need
++ // to be faked. We need to rework this cache to take into account that fontconfig can return different fonts
++ // for different input sizes, weights, etc. Basically the cache is way to naive
++ if (!bSubSetOfFontRequiresPropertyFaking)
+ {
+- // remove cache entries that were still not resolved
+- for( nStrIndex = 0; nStrIndex < rMissingCodes.getLength(); )
++ for(;;)
+ {
+- cChar = rMissingCodes.iterateCodePoints( &nStrIndex );
+- rFontSelData.mpFontEntry->IgnoreFallbackForUnicode( cChar, rFontSelData.GetWeight(), rFontSelData.maSearchName );
++ if( !rFontSelData.mpFontEntry->GetFallbackForUnicode( cChar, rFontSelData.GetWeight(), &rFontSelData.maSearchName ) )
++ rFontSelData.mpFontEntry->AddFallbackForUnicode( cChar, rFontSelData.GetWeight(), rFontSelData.maSearchName );
++ if( nStrIndex >= aOldMissingCodes.getLength() )
++ break;
++ cChar = aOldMissingCodes.iterateCodePoints( &nStrIndex );
++ }
++ if( rFontSelData.maSearchName.Len() != 0 )
++ {
++ // remove cache entries that were still not resolved
++ for( nStrIndex = 0; nStrIndex < rMissingCodes.getLength(); )
++ {
++ cChar = rMissingCodes.iterateCodePoints( &nStrIndex );
++ rFontSelData.mpFontEntry->IgnoreFallbackForUnicode( cChar, rFontSelData.GetWeight(), rFontSelData.maSearchName );
++ }
+ }
+ }
+ }
+@@ -2180,6 +2194,7 @@ ImplFontSelectData::ImplFontSelectData( const Font& rFont,
+ meLanguage( rFont.GetLanguage() ),
+ mbVertical( rFont.IsVertical() ),
+ mbNonAntialiased( false ),
++ mbEmbolden( false ),
+ mpFontData( NULL ),
+ mpFontEntry( NULL )
+ {
+@@ -2215,6 +2230,7 @@ ImplFontSelectData::ImplFontSelectData( const ImplFontData& rFontData,
+ meLanguage( 0 ),
+ mbVertical( bVertical ),
+ mbNonAntialiased( false ),
++ mbEmbolden( false ),
+ mpFontData( &rFontData ),
+ mpFontEntry( NULL )
+ {
+@@ -2297,6 +2313,12 @@ bool ImplFontCache::IFSD_Equal::operator()(const ImplFontSelectData& rA, const I
+ return false;
+ #endif
+
++ if (rA.mbEmbolden != rB.mbEmbolden)
++ return false;
++
++ if (rA.maItalicMatrix != rB.maItalicMatrix)
++ return false;
++
+ return true;
+ }
+
+--
+1.7.6.4
+
diff --git a/0001-Resolves-fdo-41556-font-sub-cache-of-nameA-nameB-is-.patch b/0001-Resolves-fdo-41556-font-sub-cache-of-nameA-nameB-is-.patch
new file mode 100644
index 0000000..5668691
--- /dev/null
+++ b/0001-Resolves-fdo-41556-font-sub-cache-of-nameA-nameB-is-.patch
@@ -0,0 +1,76 @@
+From 3f9a28f1f704967446b411b3b7e176deeb78ca83 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= <caolanm at redhat.com>
+Date: Wed, 19 Oct 2011 16:03:29 +0100
+Subject: [PATCH] Resolves: fdo#41556 font sub cache of nameA => nameB is too
+ simplistic
+
+---
+ vcl/source/gdi/outdev3.cxx | 2 +-
+ vcl/unx/generic/gdi/salgdi3.cxx | 21 +++++----------------
+ 2 files changed, 6 insertions(+), 17 deletions(-)
+
+diff --git a/vcl/source/gdi/outdev3.cxx b/vcl/source/gdi/outdev3.cxx
+index 4d21f5d..b0f59cd 100755
+--- a/vcl/source/gdi/outdev3.cxx
++++ b/vcl/source/gdi/outdev3.cxx
+@@ -3304,7 +3304,6 @@ ImplFontMetricData::ImplFontMetricData( const ImplFontSelectData& rFontSelData )
+ {
+ // initialize the members provided by the font request
+ mnWidth = rFontSelData.mnWidth;
+- mnSlant = rFontSelData.GetSlant();
+ mnOrientation = sal::static_int_cast<short>(rFontSelData.mnOrientation);
+
+ // intialize the used font name
+@@ -3329,6 +3328,7 @@ ImplFontMetricData::ImplFontMetricData( const ImplFontSelectData& rFontSelData )
+ mnDescent = 0;
+ mnIntLeading = 0;
+ mnExtLeading = 0;
++ mnSlant = 0;
+ mnMinKashida = 0;
+
+ // reset metrics that are usually derived from the measurements
+diff --git a/vcl/unx/generic/gdi/salgdi3.cxx b/vcl/unx/generic/gdi/salgdi3.cxx
+index 7c94d40..0ced020 100644
+--- a/vcl/unx/generic/gdi/salgdi3.cxx
++++ b/vcl/unx/generic/gdi/salgdi3.cxx
+@@ -847,11 +847,6 @@ class FcPreMatchSubstititution
+ {
+ public:
+ bool FindFontSubstitute( ImplFontSelectData& ) const;
+-
+-private:
+- typedef ::boost::unordered_map< ::rtl::OUString, ::rtl::OUString, ::rtl::OUStringHash >
+- CachedFontMapType;
+- mutable CachedFontMapType maCachedFontMap;
+ };
+
+ class FcGlyphFallbackSubstititution
+@@ -945,20 +940,14 @@ bool FcPreMatchSubstititution::FindFontSubstitute( ImplFontSelectData &rFontSelD
+ || 0 == rFontSelData.maSearchName.CompareIgnoreCaseToAscii( "opensymbol", 10) )
+ return false;
+
+- CachedFontMapType::const_iterator itr = maCachedFontMap.find(rFontSelData.maTargetName);
+- if (itr != maCachedFontMap.end())
+- {
+- // Cached substitution pair
+- rFontSelData.maSearchName = itr->second;
+- return true;
+- }
+-
++ //Note: see fdo#41556 if you feel compelled to cache the results here,
++ //remember that fontconfig can return e.g. an italic font for a non-italic
++ //input and/or different fonts depending on fontsize, bold, etc settings so
++ //don't cache just on the name, cache on all the input and be don't just
++ //return the original selection data with the fontname updated
+ rtl::OUString aDummy;
+ const ImplFontSelectData aOut = GetFcSubstitute( rFontSelData, aDummy );
+
+- maCachedFontMap.insert(
+- CachedFontMapType::value_type(rFontSelData.maTargetName, aOut.maSearchName));
+-
+ if( !aOut.maSearchName.Len() )
+ return false;
+
+--
+1.7.6.4
+
diff --git a/libreoffice.spec b/libreoffice.spec
index 842dd12..5523ad6 100644
--- a/libreoffice.spec
+++ b/libreoffice.spec
@@ -27,7 +27,7 @@ Summary: Free Software Productivity Suite
Name: libreoffice
Epoch: 1
Version: 3.4.4.1
-Release: 2%{?dist}
+Release: 3%{?dist}
License: LGPLv3 and LGPLv2+ and BSD and (MPLv1.1 or GPLv2 or LGPLv2 or Netscape) and (CDDL or GPLv2) and Public Domain
Group: Applications/Productivity
URL: http://www.documentfoundation.org/develop
@@ -123,6 +123,8 @@ Patch27: 0001-Related-fdo-37195-migrationoo3-not-registered.patch
Patch28: 0001-Resolves-rhbz-738255-avoid-crash-on-NULL-pointer.patch
Patch29: 0001-avoid-using-com.sun.org-apis.patch
Patch30: 0001-add-Oracle-Java-1.7.0-recognition.patch
+Patch31: 0001-Resolves-fdo-41556-font-sub-cache-of-nameA-nameB-is-.patch
+Patch32: 0001-Resolves-fdo-32665-handle-that-FreeSerif-lacks-some-.patch
%{!?python_sitearch: %global python_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(1))")}
%define instdir %{_libdir}
@@ -795,6 +797,8 @@ mv -f redhat.soc extras/source/palettes/standard.soc
%patch28 -p1 -b .rhbz738255-avoid-crash-on-NULL-pointer.patch
%patch29 -p1 -b .avoid-using-com.sun.org-apis.patch
%patch30 -p1 -b .add-Oracle-Java-1.7.0-recognition.patch
+%patch31 -p1 -b .fdo41556-font-sub-cache-of-nameA-nameB-is-.patch
+%patch32 -p1 -b .fdo32665-handle-that-FreeSerif-lacks-some-.patch
# these are horribly incomplete--empty translations and copied english
# strings with spattering of translated strings
@@ -2096,9 +2100,14 @@ update-desktop-database %{_datadir}/applications &> /dev/null || :
%{basisinstdir}/program/kde-open-url
%changelog
+* Thu Oct 27 2011 Caolán McNamara <caolanm at redhat.com> - 3.4.4.1-3
+- Resolves: rhbz#665800 missing glyph symbol shown when toggling bold/italic
+ for Sinhala text
+
* Thu Oct 27 2011 Caolán McNamara <caolanm at redhat.com> - 3.4.4.1-2
- possible fix for java 1.7.0 detection
+
* Wed Oct 26 2011 David Tardon <dtardon at redhat.com> - 3.4.4.1-1
- 3.4.4 rc1
More information about the scm-commits
mailing list