/[packages]/cauldron/libreoffice/branches/3.5/current/SOURCES/0001-Resolves-fdo-32665-handle-that-FreeSerif-lacks-some-.patch
ViewVC logotype

Contents of /cauldron/libreoffice/branches/3.5/current/SOURCES/0001-Resolves-fdo-32665-handle-that-FreeSerif-lacks-some-.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 179475 - (show annotations) (download)
Fri Dec 9 06:27:22 2011 UTC (12 years, 4 months ago) by dmorgan
File size: 13681 byte(s)
Add sources and spec file
1 From 58b48f188bbfd9a3382460d6de63848eb3db416d Mon Sep 17 00:00:00 2001
2 From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= <caolanm@redhat.com>
3 Date: Thu, 27 Oct 2011 12:24:11 +0100
4 Subject: [PATCH] Resolves: fdo#32665 handle that FreeSerif lacks some glyphs
5 in bold/italic
6
7 FreeSerif lacks glyphs in bold/italic variants that it has in the normal one. A
8 lot of our glyph fallback infrastructure, especially the caches don't expect
9 that a normal variant of a font with extra emboldening or extra font skew can
10 be a fallback for a bold/italic variant of itself which exists, but doesn't
11 have the missing glyphs that the normal one does.
12
13 We really need to improve our glyph/font caching, but we can get 90% of the
14 way there by excluding such cases from the caches.
15 ---
16 vcl/generic/fontmanager/fontconfig.cxx | 18 ++++++++-
17 vcl/generic/fontmanager/fontsubst.cxx | 6 +++-
18 vcl/generic/glyphs/glyphcache.cxx | 7 ++++
19 vcl/inc/outfont.hxx | 19 ++++++++++
20 vcl/inc/vcl/fontmanager.hxx | 3 +-
21 vcl/source/gdi/outdev3.cxx | 60 ++++++++++++++++++++++----------
22 6 files changed, 90 insertions(+), 23 deletions(-)
23
24 diff --git a/vcl/generic/fontmanager/fontconfig.cxx b/vcl/generic/fontmanager/fontconfig.cxx
25 index be91349..a4f5f7f 100644
26 --- a/vcl/unx/source/fontmanager/fontconfig.cxx
27 +++ b/vcl/unx/source/fontmanager/fontconfig.cxx
28 @@ -68,6 +68,9 @@
29 #ifndef FC_EMBOLDEN
30 #define FC_EMBOLDEN "embolden"
31 #endif
32 + #ifndef FC_MATRIX
33 + #define FC_MATRIX "matrix"
34 + #endif
35 #ifndef FC_FONTFORMAT
36 #define FC_FONTFORMAT "fontformat"
37 #endif
38 @@ -145,6 +148,7 @@
39 FcResult (*m_pFcPatternGetString)(const FcPattern*,const char*,int,FcChar8**);
40 FcResult (*m_pFcPatternGetInteger)(const FcPattern*,const char*,int,int*);
41 FcResult (*m_pFcPatternGetDouble)(const FcPattern*,const char*,int,double*);
42 + FcResult (*m_pFcPatternGetMatrix)(const FcPattern*,const char*,int,FcMatrix**);
43 FcResult (*m_pFcPatternGetBool)(const FcPattern*,const char*,int,FcBool*);
44 void (*m_pFcDefaultSubstitute)(FcPattern *);
45 FcPattern* (*m_pFcFontSetMatch)(FcConfig*,FcFontSet**, int, FcPattern*,FcResult*);
46 @@ -255,6 +259,9 @@
47 FcResult FcPatternGetDouble( const FcPattern* pPattern, const char* object, int n, double* s )
48 { return m_pFcPatternGetDouble( pPattern, object, n, s ); }
49
50 + FcResult FcPatternGetMatrix( const FcPattern* pPattern, const char* object, int n, FcMatrix** s )
51 + { return m_pFcPatternGetMatrix( pPattern, object, n, s ); }
52 +
53 FcResult FcPatternGetBool( const FcPattern* pPattern, const char* object, int n, FcBool* s )
54 { return m_pFcPatternGetBool( pPattern, object, n, s ); }
55 FcBool FcConfigAppFontAddFile( FcConfig* pConfig, const FcChar8* pFileName )
56 @@ -381,6 +388,8 @@
57 loadSymbol( "FcPatternGetInteger" );
58 m_pFcPatternGetDouble = (FcResult(*)(const FcPattern*,const char*,int,double*))
59 loadSymbol( "FcPatternGetDouble" );
60 + m_pFcPatternGetMatrix = (FcResult(*)(const FcPattern*,const char*,int,FcMatrix**))
61 + loadSymbol( "FcPatternGetMatrix" );
62 m_pFcPatternGetBool = (FcResult(*)(const FcPattern*,const char*,int,FcBool*))
63 loadSymbol( "FcPatternGetBool" );
64 m_pFcConfigAppFontAddFile = (FcBool(*)(FcConfig*, const FcChar8*))
65 @@ -453,6 +462,7 @@
66 m_pFcPatternGetString &&
67 m_pFcPatternGetInteger &&
68 m_pFcPatternGetDouble &&
69 + m_pFcPatternGetMatrix &&
70 m_pFcPatternGetBool &&
71 m_pFcConfigAppFontAddFile &&
72 m_pFcConfigAppFontAddDir &&
73 @@ -1260,7 +1270,7 @@
74 rtl::OUString PrintFontManager::Substitute(const rtl::OUString& rFontName,
75 rtl::OUString& rMissingCodes, const rtl::OString &rLangAttrib,
76 italic::type &rItalic, weight::type &rWeight,
77 - width::type &rWidth, pitch::type &rPitch) const
78 + width::type &rWidth, pitch::type &rPitch, bool &rEmbolden, ItalicMatrix &rMatrix) const
79 {
80 rtl::OUString aName;
81 FontCfgWrapper& rWrapper = FontCfgWrapper::get();
82 @@ -1353,6 +1363,17 @@
83 rPitch = convertSpacing(val);
84 if ( FcResultMatch == rWrapper.FcPatternGetInteger( pSet->fonts[0], FC_WIDTH, 0, &val))
85 rWidth = convertWidth(val);
86 + FcBool bEmbolden;
87 + if (FcResultMatch == rWrapper.FcPatternGetBool(pSet->fonts[0], FC_EMBOLDEN, 0, &bEmbolden))
88 + rEmbolden = bEmbolden;
89 + FcMatrix *pMatrix = 0;
90 + if (FcResultMatch == rWrapper.FcPatternGetMatrix(pSet->fonts[0], FC_MATRIX, 0, &pMatrix))
91 + {
92 + rMatrix.xx = pMatrix->xx;
93 + rMatrix.xy = pMatrix->xy;
94 + rMatrix.yx = pMatrix->yx;
95 + rMatrix.yy = pMatrix->yy;
96 + }
97 }
98
99 // update rMissingCodes by removing resolved unicodes
100 diff --git a/vcl/generic/fontmanager/fontsubst.cxx b/vcl/generic/fontmanager/fontsubst.cxx
101 index 3bf2d07..2d187b1 100644
102 --- a/vcl/unx/source/gdi/salgdi3.cxx
103 +++ b/vcl/unx/source/gdi/salgdi3.cxx
104 @@ -1526,8 +1526,14 @@
105 }
106 }
107
108 + bool bEmbolden = rFontSelData.mbEmbolden;
109 + ItalicMatrix aMatrix = rFontSelData.maItalicMatrix;
110 +
111 const psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
112 - aRet.maSearchName = rMgr.Substitute( rFontSelData.maTargetName, rMissingCodes, aLangAttrib, eItalic, eWeight, eWidth, ePitch);
113 + aRet.maSearchName = rMgr.Substitute( rFontSelData.maTargetName, rMissingCodes, aLangAttrib, eItalic, eWeight, eWidth, ePitch, bEmbolden, aMatrix );
114 +
115 + aRet.maItalicMatrix = aMatrix;
116 + aRet.mbEmbolden = bEmbolden;
117
118 switch (eItalic)
119 {
120 diff --git a/vcl/generic/glyphs/glyphcache.cxx b/vcl/generic/glyphs/glyphcache.cxx
121 index 5322b65..fa712bb 100644
122 --- a/vcl/source/glyphs/glyphcache.cxx
123 +++ b/vcl/source/glyphs/glyphcache.cxx
124 @@ -163,6 +163,13 @@ bool GlyphCache::IFSD_Equal::operator()( const ImplFontSelectData& rA, const Imp
125 != STRING_NOTFOUND) && rA.maTargetName != rB.maTargetName)
126 return false;
127 #endif
128 +
129 + if (rA.mbEmbolden != rB.mbEmbolden)
130 + return false;
131 +
132 + if (rA.maItalicMatrix != rB.maItalicMatrix)
133 + return false;
134 +
135 return true;
136 }
137
138 diff --git a/vcl/inc/outfont.hxx b/vcl/inc/outfont.hxx
139 index faf2b00..857d944 100644
140 --- a/vcl/inc/vcl/outfont.hxx
141 +++ b/vcl/inc/vcl/outfont.hxx
142 @@ -175,6 +191,9 @@ public: // TODO: change to private
143 bool mbVertical; // vertical mode of requested font
144 bool mbNonAntialiased; // true if antialiasing is disabled
145
146 + bool mbEmbolden; // Force emboldening
147 + ItalicMatrix maItalicMatrix; // Force matrix for slant
148 +
149 const ImplFontData* mpFontData; // a matching ImplFontData object
150 ImplFontEntry* mpFontEntry; // pointer to the resulting FontCache entry
151 };
152 diff --git a/vcl/inc/vcl/fontmanager.hxx b/vcl/inc/vcl/fontmanager.hxx
153 index 0af5e14..4a110ad 100644
154 --- a/vcl/inc/vcl/fontmanager.hxx
155 +++ b/vcl/inc/vcl/fontmanager.hxx
156 @@ -36,6 +36,7 @@
157
158 #include "vcl/dllapi.h"
159 #include "vcl/helper.hxx"
160 +#include "vcl/vclenum.hxx"
161
162 #include "com/sun/star/lang/Locale.hpp"
163
164 @@ -737,7 +738,7 @@
165
166 rtl::OUString Substitute( const rtl::OUString& rFontName, rtl::OUString& rMissingCodes,
167 const rtl::OString& rLangAttrib, italic::type& rItalic, weight::type& rWeight,
168 - width::type& rWidth, pitch::type& rPitch) const;
169 + width::type& rWidth, pitch::type& rPitch, bool &rEmboldening, ItalicMatrix &rMatrix) const;
170 bool hasFontconfig() const { return m_bFontconfigSuccess; }
171
172 int FreeTypeCharIndex( void *pFace, sal_uInt32 aChar );
173 diff --git a/vcl/source/gdi/outdev3.cxx b/vcl/source/gdi/outdev3.cxx
174 index b0f59cd..3cc438c 100755
175 --- a/vcl/source/gdi/outdev3.cxx
176 +++ b/vcl/source/gdi/outdev3.cxx
177 @@ -865,9 +865,11 @@ bool ImplFontData::IsBetterMatch( const ImplFontSelectData& rFSD, FontMatchStatu
178
179 if( rFSD.meWeight != WEIGHT_DONTKNOW )
180 {
181 - // if not bold prefer light fonts to bold fonts
182 - int nReqWeight = (int)rFSD.meWeight;
183 - if ( rFSD.meWeight > WEIGHT_MEDIUM )
184 + // if not bold or requiring emboldening prefer light fonts to bold fonts
185 + FontWeight ePatternWeight = rFSD.mbEmbolden ? WEIGHT_NORMAL : rFSD.meWeight;
186 +
187 + int nReqWeight = (int)ePatternWeight;
188 + if ( ePatternWeight > WEIGHT_MEDIUM )
189 nReqWeight += 100;
190
191 int nGivenWeight = (int)meWeight;
192 @@ -897,14 +899,17 @@ bool ImplFontData::IsBetterMatch( const ImplFontSelectData& rFSD, FontMatchStatu
193 nMatch += 150;
194 }
195
196 - if ( rFSD.meItalic == ITALIC_NONE )
197 + // if requiring custom matrix to fake italic, prefer upright font
198 + FontItalic ePatternItalic = rFSD.maItalicMatrix != ItalicMatrix() ? ITALIC_NONE : rFSD.meItalic;
199 +
200 + if ( ePatternItalic == ITALIC_NONE )
201 {
202 if( meItalic == ITALIC_NONE )
203 nMatch += 900;
204 }
205 else
206 {
207 - if( rFSD.meItalic == meItalic )
208 + if( ePatternItalic == meItalic )
209 nMatch += 900;
210 else if( meItalic != ITALIC_NONE )
211 nMatch += 600;
212 @@ -1457,22 +1462,31 @@ ImplDevFontListData* ImplDevFontList::GetGlyphFallbackFont( ImplFontSelectData&
213 else
214 rFontSelData.maSearchName = String();
215
216 - // cache the result even if there was no match
217 - for(;;)
218 - {
219 - if( !rFontSelData.mpFontEntry->GetFallbackForUnicode( cChar, rFontSelData.GetWeight(), &rFontSelData.maSearchName ) )
220 - rFontSelData.mpFontEntry->AddFallbackForUnicode( cChar, rFontSelData.GetWeight(), rFontSelData.maSearchName );
221 - if( nStrIndex >= aOldMissingCodes.getLength() )
222 - break;
223 - cChar = aOldMissingCodes.iterateCodePoints( &nStrIndex );
224 - }
225 - if( rFontSelData.maSearchName.Len() != 0 )
226 + //See fdo#32665 for an example. FreeSerif that has glyphs in normal
227 + //font, but not in the italic or bold version
228 + bool bSubSetOfFontRequiresPropertyFaking = rFontSelData.mbEmbolden || rFontSelData.maItalicMatrix != ItalicMatrix();
229 +
230 + // cache the result even if there was no match, unless its from part of a font for which the properties need
231 + // to be faked. We need to rework this cache to take into account that fontconfig can return different fonts
232 + // for different input sizes, weights, etc. Basically the cache is way to naive
233 + if (!bSubSetOfFontRequiresPropertyFaking)
234 {
235 - // remove cache entries that were still not resolved
236 - for( nStrIndex = 0; nStrIndex < rMissingCodes.getLength(); )
237 + for(;;)
238 {
239 - cChar = rMissingCodes.iterateCodePoints( &nStrIndex );
240 - rFontSelData.mpFontEntry->IgnoreFallbackForUnicode( cChar, rFontSelData.GetWeight(), rFontSelData.maSearchName );
241 + if( !rFontSelData.mpFontEntry->GetFallbackForUnicode( cChar, rFontSelData.GetWeight(), &rFontSelData.maSearchName ) )
242 + rFontSelData.mpFontEntry->AddFallbackForUnicode( cChar, rFontSelData.GetWeight(), rFontSelData.maSearchName );
243 + if( nStrIndex >= aOldMissingCodes.getLength() )
244 + break;
245 + cChar = aOldMissingCodes.iterateCodePoints( &nStrIndex );
246 + }
247 + if( rFontSelData.maSearchName.Len() != 0 )
248 + {
249 + // remove cache entries that were still not resolved
250 + for( nStrIndex = 0; nStrIndex < rMissingCodes.getLength(); )
251 + {
252 + cChar = rMissingCodes.iterateCodePoints( &nStrIndex );
253 + rFontSelData.mpFontEntry->IgnoreFallbackForUnicode( cChar, rFontSelData.GetWeight(), rFontSelData.maSearchName );
254 + }
255 }
256 }
257 }
258 @@ -2180,6 +2194,7 @@ ImplFontSelectData::ImplFontSelectData( const Font& rFont,
259 meLanguage( rFont.GetLanguage() ),
260 mbVertical( rFont.IsVertical() ),
261 mbNonAntialiased( false ),
262 + mbEmbolden( false ),
263 mpFontData( NULL ),
264 mpFontEntry( NULL )
265 {
266 @@ -2215,6 +2230,7 @@ ImplFontSelectData::ImplFontSelectData( const ImplFontData& rFontData,
267 meLanguage( 0 ),
268 mbVertical( bVertical ),
269 mbNonAntialiased( false ),
270 + mbEmbolden( false ),
271 mpFontData( &rFontData ),
272 mpFontEntry( NULL )
273 {
274 @@ -2297,6 +2313,12 @@ bool ImplFontCache::IFSD_Equal::operator()(const ImplFontSelectData& rA, const I
275 return false;
276 #endif
277
278 + if (rA.mbEmbolden != rB.mbEmbolden)
279 + return false;
280 +
281 + if (rA.maItalicMatrix != rB.maItalicMatrix)
282 + return false;
283 +
284 return true;
285 }
286
287 --- a/vcl/inc/vcl/vclenum.hxx 2011-10-27 15:10:10.402317337 +0100
288 +++ b/vcl/inc/vcl/vclenum.hxx 2011-10-27 15:10:29.561528762 +0100
289 @@ -326,6 +326,22 @@
290
291 #endif
292
293 +struct ItalicMatrix
294 +{
295 + double xx, xy, yx, yy;
296 + ItalicMatrix() : xx(1), xy(0), yx(0), yy(1) {}
297 +};
298 +
299 +inline bool operator ==(const ItalicMatrix& a, const ItalicMatrix& b)
300 +{
301 + return a.xx == b.xx && a.xy == b.xy && a.yx == b.yx && a.yy == b.yy;
302 +}
303 +
304 +inline bool operator !=(const ItalicMatrix& a, const ItalicMatrix& b)
305 +{
306 + return a.xx != b.xx || a.xy != b.xy || a.yx != b.yx || a.yy != b.yy;
307 +}
308 +
309 #endif // _VCL_VCLENUM_HXX
310
311 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

  ViewVC Help
Powered by ViewVC 1.1.30