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?= +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 +@@ -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?= +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(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 - 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 - 3.4.4.1-2 - possible fix for java 1.7.0 detection + * Wed Oct 26 2011 David Tardon - 3.4.4.1-1 - 3.4.4 rc1