Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include <cstdlib>
31 : : #include <cstring>
32 : :
33 : : #include "fontcache.hxx"
34 : :
35 : : #include "osl/thread.h"
36 : :
37 : : #include "unotools/atom.hxx"
38 : :
39 : : #include "tools/stream.hxx"
40 : :
41 : : #include <rtl/strbuf.hxx>
42 : :
43 : : #include <unistd.h>
44 : : #include <sys/stat.h>
45 : :
46 : : #if OSL_DEBUG_LEVEL >1
47 : : #include <cstdio>
48 : : #endif
49 : :
50 : : #define FONTCACHEFILE "/user/psprint/pspfontcache"
51 : : #define CACHE_MAGIC "LibreOffice PspFontCacheFile format 5"
52 : :
53 : : using namespace std;
54 : : using namespace psp;
55 : : using namespace utl;
56 : :
57 : : using ::rtl::OUString;
58 : : using ::rtl::OString;
59 : : using ::rtl::OUStringToOString;
60 : :
61 : : /*
62 : : * FontCache constructor
63 : : */
64 : :
65 [ + - ][ + - ]: 236 : FontCache::FontCache()
66 : : {
67 : 236 : m_bDoFlush = false;
68 [ + - ][ + - ]: 236 : m_aCacheFile = getOfficePath( UserPath );
69 [ + + ]: 236 : if( m_aCacheFile.Len() )
70 : : {
71 [ + - ]: 233 : m_aCacheFile.AppendAscii( FONTCACHEFILE );
72 [ + - ]: 233 : read();
73 : : }
74 : 236 : }
75 : :
76 : : /*
77 : : * FontCache destructor
78 : : */
79 : :
80 [ + - ]: 236 : FontCache::~FontCache()
81 : : {
82 [ + - ]: 236 : clearCache();
83 : 236 : }
84 : :
85 : : /*
86 : : * FontCache::clearCache
87 : : */
88 : 236 : void FontCache::clearCache()
89 : : {
90 [ + - ][ + - ]: 7160 : for( FontCacheData::iterator dir_it = m_aCache.begin(); dir_it != m_aCache.end(); ++dir_it )
[ + + ]
91 : : {
92 [ + - ][ + - ]: 45604 : for( FontDirMap::iterator entry_it = dir_it->second.m_aEntries.begin(); entry_it != dir_it->second.m_aEntries.end(); ++entry_it )
[ + - ][ + - ]
[ + + ]
93 : : {
94 [ + - ][ + - ]: 78540 : for( FontCacheEntry::iterator font_it = entry_it->second.m_aEntry.begin(); font_it != entry_it->second.m_aEntry.end(); ++font_it )
[ + - ][ + - ]
[ + + ]
95 [ + - ][ + - ]: 39860 : delete *font_it;
[ + - ]
96 : : }
97 : : }
98 : 236 : m_aCache.clear();
99 : 236 : }
100 : :
101 : : /*
102 : : * FontCache::Commit
103 : : */
104 : :
105 : 236 : void FontCache::flush()
106 : : {
107 [ + + ][ + + ]: 236 : if( ! m_bDoFlush || ! m_aCacheFile.Len() )
[ + + ]
108 : : return;
109 : :
110 [ + - ]: 62 : SvFileStream aStream;
111 [ + - ]: 62 : aStream.Open( m_aCacheFile, STREAM_WRITE | STREAM_TRUNC );
112 [ + - ][ - + ]: 62 : if( ! (aStream.IsOpen() && aStream.IsWritable()) )
[ - + ]
113 : : {
114 : : #if OSL_DEBUG_LEVEL > 1
115 : : fprintf( stderr, "FontCache::flush: opening cache file %s failed\n", rtl::OUStringToOString(m_aCacheFile, osl_getThreadTextEncoding()).getStr() );
116 : : #endif
117 : : return;
118 : : }
119 : :
120 : 62 : aStream.SetLineDelimiter( LINEEND_LF );
121 [ + - ]: 62 : aStream.WriteLine(rtl::OString(RTL_CONSTASCII_STRINGPARAM(CACHE_MAGIC)));
122 : :
123 [ + - ]: 62 : PrintFontManager& rManager( PrintFontManager::get() );
124 : 62 : MultiAtomProvider* pAtoms = rManager.m_pAtoms;
125 : :
126 [ + - ][ + - ]: 1922 : for( FontCacheData::const_iterator dir_it = m_aCache.begin(); dir_it != m_aCache.end(); ++ dir_it )
[ + + ]
127 : : {
128 [ + - ]: 1860 : const FontDirMap& rDir( dir_it->second.m_aEntries );
129 : :
130 [ + - ][ + - ]: 1860 : rtl::OString aDirectory(rManager.getDirectory(dir_it->first));
131 : : rtl::OStringBuffer aLine(
132 [ + - ]: 1860 : RTL_CONSTASCII_STRINGPARAM("FontCacheDirectory:"));
133 [ + - ][ + - ]: 1860 : aLine.append(dir_it->second.m_nTimestamp);
134 [ + - ]: 1860 : aLine.append(':');
135 [ + - ]: 1860 : aLine.append(aDirectory);
136 [ + + ][ + - ]: 1860 : if( rDir.empty() && dir_it->second.m_bNoFiles )
[ + - ][ + + ]
137 [ + - ]: 62 : aLine.insert(0, RTL_CONSTASCII_STRINGPARAM("Empty"));
138 [ + - ]: 1860 : aStream.WriteLine(aLine.makeStringAndClear());
139 : :
140 [ + - ][ + + ]: 13702 : for( FontDirMap::const_iterator entry_it = rDir.begin(); entry_it != rDir.end(); ++entry_it )
[ + - ]
141 : : {
142 : : // insert cache entries
143 [ + - ]: 11842 : const FontCacheEntry& rEntry( entry_it->second.m_aEntry );
144 [ + - ][ - + ]: 11842 : if( rEntry.begin() == rEntry.end() )
145 : 0 : continue;
146 : :
147 [ + - ]: 11842 : aLine.append(RTL_CONSTASCII_STRINGPARAM("File:"));
148 [ + - ][ + - ]: 11842 : aLine.append(entry_it->first);
149 [ + - ]: 11842 : aStream.WriteLine(aLine.makeStringAndClear());
150 : :
151 [ + - ]: 11842 : int nEntrySize = entry_it->second.m_aEntry.size();
152 : : // write: type;nfonts
153 [ + - ][ + - ]: 11842 : aLine.append(static_cast<sal_Int32>(rEntry.front()->m_eType));
154 [ + - ]: 11842 : aLine.append(';');
155 [ + - ]: 11842 : aLine.append(static_cast<sal_Int32>(nEntrySize));
156 [ + - ]: 11842 : aStream.WriteLine(aLine.makeStringAndClear());
157 : :
158 : 11842 : sal_Int32 nSubEntry = 0;
159 [ + - ][ + + ]: 23994 : for( FontCacheEntry::const_iterator it = rEntry.begin(); it != rEntry.end(); ++it, nSubEntry++ )
[ + - ]
160 : : {
161 : : /*
162 : : * for each font entry write:
163 : : * name[;name[;name]]
164 : : * fontnr;PSName;italic;weight;width;pitch;encoding;ascend;descend;leading;vsubst;gxw;gxh;gyw;gyh;useroverrride;embed;antialias[;{metricfile,typeflags}][;stylename]
165 : : */
166 [ + + ]: 12152 : if( nEntrySize > 1 )
167 [ + - ]: 434 : nSubEntry = static_cast<const PrintFontManager::TrueTypeFontFile*>(*it)->m_nCollectionEntry;
168 : : else
169 : 11718 : nSubEntry = 0;
170 : :
171 [ + - ][ + - ]: 12152 : aLine.append(OUStringToOString(pAtoms->getString( ATOM_FAMILYNAME, (*it)->m_nFamilyName), RTL_TEXTENCODING_UTF8));
[ + - ][ + - ]
172 [ + - ][ + - ]: 12772 : for( ::std::list< int >::const_iterator name_it = (*it)->m_aAliases.begin(); name_it != (*it)->m_aAliases.end(); ++name_it )
[ + - ][ + - ]
[ + - ][ + + ]
[ + - ]
173 : : {
174 [ + - ][ + - ]: 620 : const OUString& rAdd( pAtoms->getString( ATOM_FAMILYNAME, *name_it ) );
175 [ + - ]: 620 : if( !rAdd.isEmpty() )
176 : : {
177 [ + - ]: 620 : aLine.append(';');
178 [ + - ][ + - ]: 620 : aLine.append(OUStringToOString(rAdd, RTL_TEXTENCODING_UTF8));
179 : : }
180 : : }
181 [ + - ]: 12152 : aStream.WriteLine(aLine.makeStringAndClear());
182 : :
183 [ + - ][ + - ]: 12152 : const OUString& rPSName( pAtoms->getString( ATOM_PSNAME, (*it)->m_nPSName ) );
184 [ + - ]: 12152 : aLine.append(nSubEntry);
185 [ + - ]: 12152 : aLine.append(';');
186 [ + - ][ + - ]: 12152 : aLine.append(OUStringToOString(rPSName, RTL_TEXTENCODING_UTF8));
187 [ + - ]: 12152 : aLine.append(';');
188 [ + - ][ + - ]: 12152 : aLine.append(static_cast<sal_Int32>((*it)->m_eItalic));
189 [ + - ]: 12152 : aLine.append(';');
190 [ + - ][ + - ]: 12152 : aLine.append(static_cast<sal_Int32>((*it)->m_eWeight));
191 [ + - ]: 12152 : aLine.append(';');
192 [ + - ][ + - ]: 12152 : aLine.append(static_cast<sal_Int32>((*it)->m_eWidth));
193 [ + - ]: 12152 : aLine.append(';');
194 [ + - ][ + - ]: 12152 : aLine.append(static_cast<sal_Int32>((*it)->m_ePitch));
195 [ + - ]: 12152 : aLine.append(';');
196 [ + - ][ + - ]: 12152 : aLine.append(static_cast<sal_Int32>((*it)->m_aEncoding));
197 [ + - ]: 12152 : aLine.append(';');
198 [ + - ][ + - ]: 12152 : aLine.append(static_cast<sal_Int32>((*it)->m_nAscend));
199 [ + - ]: 12152 : aLine.append(';');
200 [ + - ][ + - ]: 12152 : aLine.append(static_cast<sal_Int32>((*it)->m_nDescend));
201 [ + - ]: 12152 : aLine.append(';');
202 [ + - ][ + - ]: 12152 : aLine.append(static_cast<sal_Int32>((*it)->m_nLeading));
203 [ + - ]: 12152 : aLine.append(';');
204 [ + - ][ + + ]: 12152 : aLine.append((*it)->m_bHaveVerticalSubstitutedGlyphs ? '1' : '0');
[ + - ]
205 [ + - ]: 12152 : aLine.append(';');
206 [ + - ][ + - ]: 12152 : aLine.append(static_cast<sal_Int32>((*it)->m_aGlobalMetricX.width ));
207 [ + - ]: 12152 : aLine.append(';');
208 [ + - ][ + - ]: 12152 : aLine.append(static_cast<sal_Int32>((*it)->m_aGlobalMetricX.height));
209 [ + - ]: 12152 : aLine.append(';');
210 [ + - ][ + - ]: 12152 : aLine.append(static_cast<sal_Int32>((*it)->m_aGlobalMetricY.width ));
211 [ + - ]: 12152 : aLine.append(';');
212 [ + - ][ + - ]: 12152 : aLine.append(static_cast<sal_Int32>((*it)->m_aGlobalMetricY.height));
213 [ + - ]: 12152 : aLine.append(';');
214 [ + - ][ - + ]: 12152 : aLine.append((*it)->m_bUserOverride ? '1' : '0');
[ + - ]
215 [ + - ]: 12152 : aLine.append(';');
216 [ + - ]: 12152 : aLine.append(static_cast<sal_Int32>(0));
217 [ + - ]: 12152 : aLine.append(';');
218 [ + - ]: 12152 : aLine.append(static_cast<sal_Int32>(0));
219 : :
220 [ + - ]: 12152 : switch( (*it)->m_eType )
[ + + + ]
221 : : {
222 : : case fonttype::Type1:
223 [ + - ]: 2170 : aLine.append(';');
224 [ + - ][ + - ]: 2170 : aLine.append(static_cast<const PrintFontManager::Type1FontFile*>(*it)->m_aMetricFile);
225 : 2170 : break;
226 : : case fonttype::TrueType:
227 [ + - ]: 8060 : aLine.append(';');
228 [ + - ][ + - ]: 8060 : aLine.append(static_cast<sal_Int32>(static_cast<const PrintFontManager::TrueTypeFontFile*>(*it)->m_nTypeFlags));
229 : 8060 : break;
230 : 1922 : default: break;
231 : : }
232 [ + - ][ + + ]: 12152 : if( !(*it)->m_aStyleName.isEmpty() )
233 : : {
234 [ + - ]: 11904 : aLine.append(';');
235 [ + - ][ + - ]: 11904 : aLine.append(OUStringToOString((*it)->m_aStyleName, RTL_TEXTENCODING_UTF8));
[ + - ]
236 : : }
237 [ + - ]: 12152 : aStream.WriteLine(aLine.makeStringAndClear());
238 : : }
239 [ + - ]: 11842 : aStream.WriteLine(rtl::OString());
240 : : }
241 : 1860 : }
242 [ + - ][ + - ]: 236 : m_bDoFlush = false;
243 : : }
244 : :
245 : : /*
246 : : * FontCache::read
247 : : */
248 : :
249 : 233 : void FontCache::read()
250 : : {
251 [ + - ]: 233 : PrintFontManager& rManager( PrintFontManager::get() );
252 : 233 : MultiAtomProvider* pAtoms = rManager.m_pAtoms;
253 : :
254 [ + - ]: 233 : SvFileStream aStream( m_aCacheFile, STREAM_READ );
255 [ + + ]: 233 : if( ! aStream.IsOpen() )
256 : : {
257 : : #if OSL_DEBUG_LEVEL > 1
258 : : fprintf( stderr, "FontCache::read: opening cache file %s failed\n", rtl::OUStringToOString(m_aCacheFile, osl_getThreadTextEncoding()).getStr() );
259 : : #endif
260 : : return;
261 : : }
262 : :
263 : :
264 : 171 : OString aLine;
265 [ + - ]: 171 : aStream.ReadLine( aLine );
266 [ - + ]: 171 : if (!aLine.equalsL(RTL_CONSTASCII_STRINGPARAM(CACHE_MAGIC)))
267 : : {
268 : : #if OSL_DEBUG_LEVEL >1
269 : : fprintf( stderr, "FontCache::read: cache file %s fails magic test\n", rtl::OUStringToOString(m_aCacheFile, osl_getThreadTextEncoding()).getStr() );
270 : : #endif
271 : : return;
272 : : }
273 : :
274 : 171 : int nDir = 0;
275 : 171 : FontDirMap* pDir = NULL;
276 : 171 : bool bKeepOnlyUserOverridden = false;
277 [ + + ]: 58173 : do
278 : : {
279 [ + - ]: 58173 : aStream.ReadLine( aLine );
280 [ + + + + ]: 169710 : if( aLine.compareTo( RTL_CONSTASCII_STRINGPARAM( "FontCacheDirectory:" ) ) == 0 ||
[ + - ][ + - ]
[ + - ][ + + ]
281 [ + + ][ + + ]: 111537 : aLine.compareTo( RTL_CONSTASCII_STRINGPARAM( "EmptyFontCacheDirectory:" ) ) == 0 )
[ + + ]
282 : : {
283 : 4980 : bool bEmpty = (aLine.compareTo( RTL_CONSTASCII_STRINGPARAM ("Empty" ) ) == 0);
284 [ + + ]: 4980 : sal_Int32 nSearchIndex = bEmpty ? 24 : 19;
285 : :
286 : 4980 : OString aDir;
287 : 4980 : sal_Int64 nTimestamp = 0;
288 : 4980 : sal_Int32 nTEnd = aLine.indexOf( ':', nSearchIndex );
289 [ + - ]: 4980 : if( nTEnd != -1 )
290 : : {
291 : 4980 : rtl::OString aTimeStamp = aLine.copy( nSearchIndex, nTEnd - nSearchIndex );
292 : 4980 : nTimestamp = aTimeStamp.toInt64();
293 : 4980 : aDir = aLine.copy( nTEnd+1 );
294 : : }
295 : : else
296 : : {
297 : : // invalid format, remove
298 : 0 : pDir = NULL;
299 : 0 : nDir = 0;
300 : 0 : m_bDoFlush = true;
301 : 0 : continue;
302 : : }
303 : :
304 : : // is the directory modified ?
305 : : struct stat aStat;
306 [ - + ][ - + ]: 4980 : if( stat( aDir.getStr(), &aStat ) ||
[ + - ]
307 : 4980 : ! S_ISDIR(aStat.st_mode) )
308 : : {
309 : : // remove outdated cache data
310 : 0 : pDir = NULL;
311 : 0 : nDir = 0;
312 : 0 : m_bDoFlush = true;
313 : 0 : continue;
314 : : }
315 : : else
316 : : {
317 [ + - ]: 4980 : nDir = rManager.getDirectoryAtom( aDir, true );
318 [ + - ]: 4980 : m_aCache[ nDir ].m_nTimestamp = (sal_Int64)aStat.st_mtime;
319 [ + - ]: 4980 : m_aCache[ nDir ].m_bNoFiles = bEmpty;
320 [ + + ][ + - ]: 4980 : pDir = bEmpty ? NULL : &m_aCache[ nDir ].m_aEntries;
321 : 4980 : bKeepOnlyUserOverridden = ((sal_Int64)aStat.st_mtime != nTimestamp);
322 [ + - ][ + - ]: 9960 : m_aCache[ nDir ].m_bUserOverrideOnly = bKeepOnlyUserOverridden;
323 : 4980 : }
324 : : }
325 [ + - ][ + + ]: 53193 : else if( pDir && aLine.compareTo( RTL_CONSTASCII_STRINGPARAM( "File:" ) ) == 0 )
[ + - ][ + - ]
[ + - ][ + + ]
326 : : {
327 : 26511 : OString aFile( aLine.copy( 5 ) );
328 [ + - ]: 26511 : aStream.ReadLine( aLine );
329 : :
330 : 26511 : const char* pLine = aLine.getStr();
331 : :
332 : 26511 : fonttype::type eType = (fonttype::type)atoi( pLine );
333 [ + + ][ - + ]: 26511 : if( eType != fonttype::TrueType &&
[ + + ]
334 : : eType != fonttype::Type1 &&
335 : : eType != fonttype::Builtin
336 : : )
337 : 0 : continue;
338 [ + - ][ + + ]: 53022 : while( *pLine && *pLine != ';' )
[ + + ]
339 : 26511 : pLine++;
340 [ - + ]: 26511 : if( *pLine != ';' )
341 : 0 : continue;
342 : :
343 : 26511 : pLine++;
344 : 26511 : sal_Int32 nFonts = atoi( pLine );
345 [ + + ]: 53877 : for( int n = 0; n < nFonts; n++ )
346 : : {
347 [ + - ]: 27366 : aStream.ReadLine( aLine );
348 : 27366 : pLine = aLine.getStr();
349 : 27366 : int nLen = aLine.getLength();
350 : :
351 : 27366 : PrintFontManager::PrintFont* pFont = NULL;
352 [ + + + - ]: 27366 : switch( eType )
353 : : {
354 : : case fonttype::TrueType:
355 [ + - ][ + - ]: 18405 : pFont = new PrintFontManager::TrueTypeFontFile();
356 : 18405 : break;
357 : : case fonttype::Type1:
358 [ + - ][ + - ]: 5985 : pFont = new PrintFontManager::Type1FontFile();
359 : 5985 : break;
360 : : case fonttype::Builtin:
361 [ + - ][ + - ]: 2976 : pFont = new PrintFontManager::BuiltinFont();
362 : 2976 : break;
363 : 0 : default: break;
364 : : }
365 : :
366 : : sal_Int32 nIndex;
367 : :
368 [ + + ][ + + ]: 410136 : for( nIndex = 0; nIndex < nLen && pLine[nIndex] != ';'; nIndex++ )
[ + + ]
369 : : ;
370 : :
371 : : pFont->m_nFamilyName = pAtoms->getAtom( ATOM_FAMILYNAME,
372 : : OUString( pLine, nIndex, RTL_TEXTENCODING_UTF8 ),
373 [ + - ][ + - ]: 27366 : sal_True );
374 [ + + ]: 29076 : while( nIndex < nLen )
375 : : {
376 : 1710 : sal_Int32 nLastIndex = nIndex+1;
377 [ + + ][ + + ]: 31635 : for( nIndex = nLastIndex ; nIndex < nLen && pLine[nIndex] != ';'; nIndex++ )
[ + + ]
378 : : ;
379 [ + - ]: 1710 : if( nIndex - nLastIndex )
380 : : {
381 [ + - ]: 1710 : OUString aAlias( pLine+nLastIndex, nIndex-nLastIndex, RTL_TEXTENCODING_UTF8 );
382 [ + - ][ + - ]: 1710 : pFont->m_aAliases.push_back( pAtoms->getAtom( ATOM_FAMILYNAME, aAlias, sal_True ) );
383 : : }
384 : : }
385 [ + - ]: 27366 : aStream.ReadLine( aLine );
386 : 27366 : pLine = aLine.getStr();
387 : 27366 : nLen = aLine.getLength();
388 : :
389 : : // get up to 20 token positions
390 : 27366 : const int nMaxTokens = 20;
391 : : int nTokenPos[nMaxTokens];
392 : 27366 : nTokenPos[0] = 0;
393 : 27366 : int nTokens = 1;
394 [ + + ]: 2125902 : for( int i = 0; i < nLen; i++ )
395 : : {
396 [ + + ]: 2122926 : if( pLine[i] == ';' )
397 : : {
398 : 516594 : nTokenPos[nTokens++] = i+1;
399 [ + + ]: 516594 : if( nTokens == nMaxTokens )
400 : 24390 : break;
401 : : }
402 : : }
403 [ - + ]: 27366 : if( nTokens < 18 )
404 : : {
405 [ # # ][ # # ]: 0 : delete pFont;
406 : 0 : continue;
407 : : }
408 : 27366 : int nCollEntry = atoi( pLine );
409 [ + - ][ + - ]: 27366 : pFont->m_nPSName = pAtoms->getAtom( ATOM_PSNAME, OUString( pLine + nTokenPos[1], nTokenPos[2]-nTokenPos[1]-1, RTL_TEXTENCODING_UTF8 ), sal_True );
410 : 27366 : pFont->m_eItalic = (FontItalic)atoi( pLine+nTokenPos[2] );
411 : 27366 : pFont->m_eWeight = (FontWeight)atoi( pLine+nTokenPos[3] );
412 : 27366 : pFont->m_eWidth = (FontWidth)atoi( pLine+nTokenPos[4] );
413 : 27366 : pFont->m_ePitch = (FontPitch)atoi( pLine+nTokenPos[5] );
414 : 27366 : pFont->m_aEncoding = (rtl_TextEncoding)atoi( pLine+nTokenPos[6] );
415 : 27366 : pFont->m_nAscend = atoi( pLine + nTokenPos[7] );
416 : 27366 : pFont->m_nDescend = atoi( pLine + nTokenPos[8] );
417 : 27366 : pFont->m_nLeading = atoi( pLine + nTokenPos[9] );
418 : : pFont->m_bHaveVerticalSubstitutedGlyphs
419 : 27366 : = (atoi( pLine + nTokenPos[10] ) != 0);
420 : : pFont->m_aGlobalMetricX.width
421 : 27366 : = atoi( pLine + nTokenPos[11] );
422 : : pFont->m_aGlobalMetricX.height
423 : 27366 : = atoi( pLine + nTokenPos[12] );
424 : : pFont->m_aGlobalMetricY.width
425 : 27366 : = atoi( pLine + nTokenPos[13] );
426 : : pFont->m_aGlobalMetricY.height
427 : 27366 : = atoi( pLine + nTokenPos[14] );
428 : : pFont->m_bUserOverride
429 : 27366 : = (atoi( pLine + nTokenPos[15] ) != 0);
430 : 27366 : int nStyleTokenNr = 18;
431 [ + + + - ]: 27366 : switch( eType )
432 : : {
433 : : case fonttype::TrueType:
434 : 18405 : static_cast<PrintFontManager::TrueTypeFontFile*>(pFont)->m_nTypeFlags = atoi( pLine + nTokenPos[18] );
435 : 18405 : static_cast<PrintFontManager::TrueTypeFontFile*>(pFont)->m_nCollectionEntry = nCollEntry;
436 : 18405 : static_cast<PrintFontManager::TrueTypeFontFile*>(pFont)->m_nDirectory = nDir;
437 : 18405 : static_cast<PrintFontManager::TrueTypeFontFile*>(pFont)->m_aFontFile = aFile;
438 : 18405 : nStyleTokenNr++;
439 : 18405 : break;
440 : : case fonttype::Type1:
441 : : {
442 [ + - ]: 5985 : int nTokLen = (nTokens > 19 ) ? nTokenPos[19]-nTokenPos[18]-1 : nLen - nTokenPos[18];
443 : 5985 : static_cast<PrintFontManager::Type1FontFile*>(pFont)->m_aMetricFile = OString( pLine + nTokenPos[18], nTokLen );
444 : 5985 : static_cast<PrintFontManager::Type1FontFile*>(pFont)->m_nDirectory = nDir;
445 : 5985 : static_cast<PrintFontManager::Type1FontFile*>(pFont)->m_aFontFile = aFile;
446 : 5985 : nStyleTokenNr++;
447 : : }
448 : 5985 : break;
449 : : case fonttype::Builtin:
450 : 2976 : static_cast<PrintFontManager::BuiltinFont*>(pFont)->m_nDirectory = nDir;
451 : 2976 : static_cast<PrintFontManager::BuiltinFont*>(pFont)->m_aMetricFile = aFile;
452 : 2976 : break;
453 : 0 : default: break;
454 : : }
455 [ + + ]: 27366 : if( nTokens > nStyleTokenNr )
456 : 26982 : pFont->m_aStyleName = OUString::intern( pLine + nTokenPos[nStyleTokenNr],
457 : 26982 : nLen - nTokenPos[nStyleTokenNr],
458 [ + - ]: 26982 : RTL_TEXTENCODING_UTF8 );
459 : :
460 : 27366 : bool bObsolete = false;
461 [ - + ]: 27366 : if( bKeepOnlyUserOverridden )
462 : : {
463 [ # # ]: 0 : if( pFont->m_bUserOverride )
464 : : {
465 [ # # ][ # # ]: 0 : rtl::OStringBuffer aFilePath(rManager.getDirectory(nDir));
466 [ # # ][ # # ]: 0 : aFilePath.append('/').append(aFile);
467 : : struct stat aStat;
468 [ # # ][ # # ]: 0 : if( stat( aFilePath.getStr(), &aStat ) ||
[ # # ][ # # ]
469 : 0 : ! S_ISREG( aStat.st_mode ) ||
470 : : aStat.st_size < 16 )
471 : : {
472 : 0 : bObsolete = true;
473 : 0 : }
474 : : #if OSL_DEBUG_LEVEL > 2
475 : : else
476 : : fprintf( stderr, "keeping file %s in outdated cache entry due to user override\n",
477 : : aFilePath.getStr() );
478 : : #endif
479 : : }
480 : : else
481 : 0 : bObsolete = true;
482 : : }
483 [ - + ]: 27366 : if( bObsolete )
484 : : {
485 : 0 : m_bDoFlush = true;
486 : : #if OSL_DEBUG_LEVEL > 2
487 : : fprintf( stderr, "removing obsolete font %s\n", aFile.getStr() );
488 : : #endif
489 [ # # ][ # # ]: 0 : delete pFont;
490 : 0 : continue;
491 : : }
492 : :
493 [ + - ]: 27366 : FontCacheEntry& rEntry = (*pDir)[aFile].m_aEntry;
494 [ + - ]: 27366 : rEntry.push_back( pFont );
495 [ + - ]: 26511 : }
496 : : }
497 [ - + ][ + - ]: 58406 : } while( ! aStream.IsEof() );
[ + + ]
498 : : }
499 : :
500 : : /*
501 : : * FontCache::copyPrintFont
502 : : */
503 : 44433 : void FontCache::copyPrintFont( const PrintFontManager::PrintFont* pFrom, PrintFontManager::PrintFont* pTo ) const
504 : : {
505 [ - + ]: 44433 : if( pFrom->m_eType != pTo->m_eType )
506 : 44433 : return;
507 [ + + + - ]: 44433 : switch( pFrom->m_eType )
508 : : {
509 : : case fonttype::TrueType:
510 : 31275 : static_cast<PrintFontManager::TrueTypeFontFile*>(pTo)->m_nDirectory = static_cast<const PrintFontManager::TrueTypeFontFile*>(pFrom)->m_nDirectory;
511 : 31275 : static_cast<PrintFontManager::TrueTypeFontFile*>(pTo)->m_aFontFile = static_cast<const PrintFontManager::TrueTypeFontFile*>(pFrom)->m_aFontFile;
512 : 31275 : static_cast<PrintFontManager::TrueTypeFontFile*>(pTo)->m_nCollectionEntry = static_cast<const PrintFontManager::TrueTypeFontFile*>(pFrom)->m_nCollectionEntry;
513 : 31275 : static_cast<PrintFontManager::TrueTypeFontFile*>(pTo)->m_nTypeFlags = static_cast<const PrintFontManager::TrueTypeFontFile*>(pFrom)->m_nTypeFlags;
514 : 31275 : break;
515 : : case fonttype::Type1:
516 : 8260 : static_cast<PrintFontManager::Type1FontFile*>(pTo)->m_nDirectory = static_cast<const PrintFontManager::Type1FontFile*>(pFrom)->m_nDirectory;
517 : 8260 : static_cast<PrintFontManager::Type1FontFile*>(pTo)->m_aFontFile = static_cast<const PrintFontManager::Type1FontFile*>(pFrom)->m_aFontFile;
518 : 8260 : static_cast<PrintFontManager::Type1FontFile*>(pTo)->m_aMetricFile = static_cast<const PrintFontManager::Type1FontFile*>(pFrom)->m_aMetricFile;
519 : 8260 : break;
520 : : case fonttype::Builtin:
521 : 4898 : static_cast<PrintFontManager::BuiltinFont*>(pTo)->m_nDirectory = static_cast<const PrintFontManager::BuiltinFont*>(pFrom)->m_nDirectory;
522 : 4898 : static_cast<PrintFontManager::BuiltinFont*>(pTo)->m_aMetricFile = static_cast<const PrintFontManager::BuiltinFont*>(pFrom)->m_aMetricFile;
523 : 4898 : break;
524 : 0 : default: break;
525 : : }
526 : 44433 : pTo->m_nFamilyName = pFrom->m_nFamilyName;
527 : 44433 : pTo->m_aStyleName = pFrom->m_aStyleName;
528 : 44433 : pTo->m_aAliases = pFrom->m_aAliases;
529 : 44433 : pTo->m_nPSName = pFrom->m_nPSName;
530 : 44433 : pTo->m_eItalic = pFrom->m_eItalic;
531 : 44433 : pTo->m_eWeight = pFrom->m_eWeight;
532 : 44433 : pTo->m_eWidth = pFrom->m_eWidth;
533 : 44433 : pTo->m_ePitch = pFrom->m_ePitch;
534 : 44433 : pTo->m_aEncoding = pFrom->m_aEncoding;
535 : 44433 : pTo->m_aGlobalMetricX = pFrom->m_aGlobalMetricX;
536 : 44433 : pTo->m_aGlobalMetricY = pFrom->m_aGlobalMetricY;
537 : 44433 : pTo->m_nAscend = pFrom->m_nAscend;
538 : 44433 : pTo->m_nDescend = pFrom->m_nDescend;
539 : 44433 : pTo->m_nLeading = pFrom->m_nLeading;
540 : 44433 : pTo->m_nXMin = pFrom->m_nXMin;
541 : 44433 : pTo->m_nYMin = pFrom->m_nYMin;
542 : 44433 : pTo->m_nXMax = pFrom->m_nXMax;
543 : 44433 : pTo->m_nYMax = pFrom->m_nYMax;
544 : 44433 : pTo->m_bHaveVerticalSubstitutedGlyphs = pFrom->m_bHaveVerticalSubstitutedGlyphs;
545 : 44433 : pTo->m_bUserOverride = pFrom->m_bUserOverride;
546 : : }
547 : :
548 : : /*
549 : : * FontCache::equalsPrintFont
550 : : */
551 : 28638 : bool FontCache::equalsPrintFont( const PrintFontManager::PrintFont* pLeft, PrintFontManager::PrintFont* pRight ) const
552 : : {
553 [ - + ]: 28638 : if( pLeft->m_eType != pRight->m_eType )
554 : 0 : return false;
555 [ + + - - ]: 28638 : switch( pLeft->m_eType )
556 : : {
557 : : case fonttype::TrueType:
558 : : {
559 : 22653 : const PrintFontManager::TrueTypeFontFile* pLT = static_cast<const PrintFontManager::TrueTypeFontFile*>(pLeft);
560 : 22653 : const PrintFontManager::TrueTypeFontFile* pRT = static_cast<const PrintFontManager::TrueTypeFontFile*>(pRight);
561 [ + - + - ]: 45306 : if( pRT->m_nDirectory != pLT->m_nDirectory ||
[ + - ][ - + ]
[ - + ]
562 : 22653 : pRT->m_aFontFile != pLT->m_aFontFile ||
563 : : pRT->m_nCollectionEntry != pLT->m_nCollectionEntry ||
564 : : pRT->m_nTypeFlags != pLT->m_nTypeFlags )
565 : 0 : return false;
566 : : }
567 : 22653 : break;
568 : : case fonttype::Type1:
569 : : {
570 : 5985 : const PrintFontManager::Type1FontFile* pLT = static_cast<const PrintFontManager::Type1FontFile*>(pLeft);
571 : 5985 : const PrintFontManager::Type1FontFile* pRT = static_cast<const PrintFontManager::Type1FontFile*>(pRight);
572 [ + - + - : 17955 : if( pRT->m_nDirectory != pLT->m_nDirectory ||
- + ][ - + ]
573 : 5985 : pRT->m_aFontFile != pLT->m_aFontFile ||
574 : 5985 : pRT->m_aMetricFile != pLT->m_aMetricFile )
575 : 0 : return false;
576 : : }
577 : 5985 : break;
578 : : case fonttype::Builtin:
579 : : {
580 : 0 : const PrintFontManager::BuiltinFont* pLT = static_cast<const PrintFontManager::BuiltinFont*>(pLeft);
581 : 0 : const PrintFontManager::BuiltinFont* pRT = static_cast<const PrintFontManager::BuiltinFont*>(pRight);
582 [ # # # # ]: 0 : if( pRT->m_nDirectory != pLT->m_nDirectory ||
[ # # ]
583 : 0 : pRT->m_aMetricFile != pLT->m_aMetricFile )
584 : 0 : return false;
585 : : }
586 : 0 : break;
587 : 0 : default: break;
588 : : }
589 [ + - + + ]: 113902 : if( pRight->m_nFamilyName != pLeft->m_nFamilyName ||
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + -
+ - + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ - + ][ + + ]
590 : 28638 : pRight->m_aStyleName != pLeft->m_aStyleName ||
591 : : pRight->m_nPSName != pLeft->m_nPSName ||
592 : : pRight->m_eItalic != pLeft->m_eItalic ||
593 : : pRight->m_eWeight != pLeft->m_eWeight ||
594 : : pRight->m_eWidth != pLeft->m_eWidth ||
595 : : pRight->m_ePitch != pLeft->m_ePitch ||
596 : : pRight->m_aEncoding != pLeft->m_aEncoding ||
597 : 28313 : pRight->m_aGlobalMetricX != pLeft->m_aGlobalMetricX ||
598 : 28313 : pRight->m_aGlobalMetricY != pLeft->m_aGlobalMetricY ||
599 : : pRight->m_nAscend != pLeft->m_nAscend ||
600 : : pRight->m_nDescend != pLeft->m_nDescend ||
601 : : pRight->m_nLeading != pLeft->m_nLeading ||
602 : : pRight->m_nXMin != pLeft->m_nXMin ||
603 : : pRight->m_nYMin != pLeft->m_nYMin ||
604 : : pRight->m_nXMax != pLeft->m_nXMax ||
605 : : pRight->m_nYMax != pLeft->m_nYMax ||
606 : : pRight->m_bHaveVerticalSubstitutedGlyphs != pLeft->m_bHaveVerticalSubstitutedGlyphs ||
607 : : pRight->m_bUserOverride != pLeft->m_bUserOverride
608 : : )
609 : 325 : return false;
610 [ + - ][ + - ]: 28313 : std::list< int >::const_iterator lit, rit;
611 [ + - ][ + - ]: 102067 : for( lit = pLeft->m_aAliases.begin(), rit = pRight->m_aAliases.begin();
[ + - ][ + + ]
[ + - ][ + - ]
[ + + ]
612 [ + - ][ + - ]: 73754 : lit != pLeft->m_aAliases.end() && rit != pRight->m_aAliases.end() && (*lit) == (*rit);
[ + - ][ + - ]
[ + - ][ + + ]
[ + + ][ + - ]
[ # # # #
# # ]
613 : : ++lit, ++rit )
614 : : ;
615 [ + - ][ + - ]: 28638 : return lit == pLeft->m_aAliases.end() && rit == pRight->m_aAliases.end();
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ # # # #
# # ]
616 : : }
617 : :
618 : : /*
619 : : * FontCache::clonePrintFont
620 : : */
621 : 44108 : PrintFontManager::PrintFont* FontCache::clonePrintFont( const PrintFontManager::PrintFont* pOldFont ) const
622 : : {
623 : 44108 : PrintFontManager::PrintFont* pFont = NULL;
624 [ + + + - ]: 44108 : switch( pOldFont->m_eType )
625 : : {
626 : : case fonttype::TrueType:
627 [ + - ]: 30950 : pFont = new PrintFontManager::TrueTypeFontFile();
628 : 30950 : break;
629 : : case fonttype::Type1:
630 [ + - ]: 8260 : pFont = new PrintFontManager::Type1FontFile();
631 : 8260 : break;
632 : : case fonttype::Builtin:
633 [ + - ]: 4898 : pFont = new PrintFontManager::BuiltinFont();
634 : 4898 : break;
635 : 0 : default: break;
636 : : }
637 [ + - ]: 44108 : if( pFont )
638 : : {
639 : 44108 : copyPrintFont( pOldFont, pFont );
640 : : }
641 : 44108 : return pFont;
642 : : }
643 : :
644 : : /*
645 : : * FontCache::getFontCacheFile
646 : : */
647 : 35906 : bool FontCache::getFontCacheFile( int nDirID, const OString& rFile, list< PrintFontManager::PrintFont* >& rNewFonts ) const
648 : : {
649 : 35906 : bool bSuccess = false;
650 : :
651 [ + - ]: 35906 : FontCacheData::const_iterator dir = m_aCache.find( nDirID );
652 [ + - ][ + + ]: 35906 : if( dir != m_aCache.end() )
653 : : {
654 [ + - ][ + - ]: 33145 : FontDirMap::const_iterator entry = dir->second.m_aEntries.find( rFile );
655 [ + - ][ + - ]: 33145 : if( entry != dir->second.m_aEntries.end() )
[ + + ]
656 : : {
657 [ + - ][ + - ]: 61783 : for( FontCacheEntry::const_iterator font = entry->second.m_aEntry.begin(); font != entry->second.m_aEntry.end(); ++font )
[ + - ][ + - ]
[ + + ]
658 : : {
659 : 28638 : bSuccess = true;
660 [ + - ][ + - ]: 28638 : PrintFontManager::PrintFont* pFont = clonePrintFont( *font );
661 [ + - ]: 28638 : rNewFonts.push_back( pFont );
662 : : }
663 : : }
664 : : }
665 : 35906 : return bSuccess;
666 : : }
667 : :
668 : : /*
669 : : * FontCache::updateFontCacheEntry
670 : : */
671 : 41132 : void FontCache::updateFontCacheEntry( const PrintFontManager::PrintFont* pFont, bool bFlush )
672 : : {
673 : 41132 : OString aFile;
674 : 41132 : int nDirID = 0;
675 [ + + + - ]: 41132 : switch( pFont->m_eType )
676 : : {
677 : : case fonttype::TrueType:
678 : 30950 : nDirID = static_cast<const PrintFontManager::TrueTypeFontFile*>(pFont)->m_nDirectory;
679 : 30950 : aFile = static_cast<const PrintFontManager::TrueTypeFontFile*>(pFont)->m_aFontFile;
680 : 30950 : break;
681 : : case fonttype::Type1:
682 : 8260 : nDirID = static_cast<const PrintFontManager::Type1FontFile*>(pFont)->m_nDirectory;
683 : 8260 : aFile = static_cast<const PrintFontManager::Type1FontFile*>(pFont)->m_aFontFile;
684 : 8260 : break;
685 : : case fonttype::Builtin:
686 : 1922 : nDirID = static_cast<const PrintFontManager::BuiltinFont*>(pFont)->m_nDirectory;
687 : 1922 : aFile = static_cast<const PrintFontManager::BuiltinFont*>(pFont)->m_aMetricFile;
688 : 1922 : break;
689 : : default:
690 : 41132 : return;
691 : : }
692 [ + - ]: 41132 : FontCacheData::const_iterator dir = m_aCache.find( nDirID );
693 : 41132 : FontDirMap::const_iterator entry;
694 [ + - ]: 41132 : FontCacheEntry::const_iterator font;
695 : 41132 : PrintFontManager::PrintFont* pCacheFont = NULL;
696 : :
697 [ + - ][ + + ]: 41132 : if( dir != m_aCache.end() )
698 : : {
699 [ + - ][ + - ]: 39253 : entry = dir->second.m_aEntries.find( aFile );
700 [ + - ][ + - ]: 39253 : if( entry != dir->second.m_aEntries.end() )
[ + + ]
701 : : {
702 [ + - ][ + - ]: 36751 : for( font = entry->second.m_aEntry.begin(); font != entry->second.m_aEntry.end(); ++font )
[ + - ][ + - ]
[ + + ]
703 : : {
704 [ + - ][ + - ]: 103293 : if( (*font)->m_eType == pFont->m_eType &&
[ + + ][ + + ]
[ + + ]
705 [ + - ]: 36426 : ( (*font)->m_eType != fonttype::TrueType ||
706 [ + - ]: 30441 : static_cast<const PrintFontManager::TrueTypeFontFile*>(*font)->m_nCollectionEntry == static_cast<const PrintFontManager::TrueTypeFontFile*>(pFont)->m_nCollectionEntry
707 : : ) )
708 : 28638 : break;
709 : : }
710 [ + - ][ + - ]: 28963 : if( font != entry->second.m_aEntry.end() )
[ + + ]
711 [ + - ]: 28638 : pCacheFont = *font;
712 : : }
713 : : }
714 : : else
715 [ + - ]: 1879 : createCacheDir( nDirID );
716 : :
717 [ + + ]: 41132 : if( pCacheFont )
718 : : {
719 [ + - ][ + + ]: 28638 : if( ! equalsPrintFont( pFont, pCacheFont ) )
720 : : {
721 [ + - ]: 325 : copyPrintFont( pFont, pCacheFont );
722 : 325 : m_bDoFlush = true;
723 : : }
724 : : }
725 : : else
726 : : {
727 [ + - ]: 12494 : pCacheFont = clonePrintFont( pFont );
728 [ + - ][ + - ]: 12494 : m_aCache[nDirID].m_aEntries[aFile].m_aEntry.push_back( pCacheFont );
[ + - ]
729 : 12494 : m_bDoFlush = true;
730 : : }
731 [ - + ]: 41132 : if( bFlush )
732 [ # # ][ + - ]: 41132 : flush();
733 : : }
734 : :
735 : : /*
736 : : * FontCache::listDirectory
737 : : */
738 : 785 : bool FontCache::listDirectory( const OString& rDir, std::list< PrintFontManager::PrintFont* >& rNewFonts ) const
739 : : {
740 [ + - ]: 785 : PrintFontManager& rManager( PrintFontManager::get() );
741 [ + - ]: 785 : int nDirID = rManager.getDirectoryAtom( rDir );
742 [ + - ]: 785 : FontCacheData::const_iterator dir = m_aCache.find( nDirID );
743 [ + - ]: 785 : bool bFound = (dir != m_aCache.end());
744 : :
745 [ + - ][ + + ]: 785 : if( bFound && !dir->second.m_bNoFiles )
[ + + ][ + + ]
746 : : {
747 [ + - ][ + - ]: 3072 : for( FontDirMap::const_iterator file = dir->second.m_aEntries.begin(); file != dir->second.m_aEntries.end(); ++file )
[ + - ][ + - ]
[ + + ]
748 : : {
749 [ + - ][ + - ]: 5952 : for( FontCacheEntry::const_iterator font = file->second.m_aEntry.begin(); font != file->second.m_aEntry.end(); ++font )
[ + - ][ + - ]
[ + + ]
750 : : {
751 [ + - ][ + - ]: 2976 : PrintFontManager::PrintFont* pFont = clonePrintFont( *font );
752 [ + - ]: 2976 : rNewFonts.push_back( pFont );
753 : : }
754 : : }
755 : : }
756 : 785 : return bFound;
757 : : }
758 : :
759 : : /*
760 : : * FontCache::listDirectory
761 : : */
762 : 0 : bool FontCache::scanAdditionalFiles( const OString& rDir )
763 : : {
764 [ # # ]: 0 : PrintFontManager& rManager( PrintFontManager::get() );
765 [ # # ]: 0 : int nDirID = rManager.getDirectoryAtom( rDir );
766 [ # # ]: 0 : FontCacheData::const_iterator dir = m_aCache.find( nDirID );
767 [ # # ]: 0 : bool bFound = (dir != m_aCache.end());
768 : :
769 [ # # ][ # # ]: 0 : return (bFound && dir->second.m_bUserOverrideOnly);
[ # # ]
770 : : }
771 : :
772 : : /*
773 : : * FontCache::createCacheDir
774 : : */
775 : 2006 : void FontCache::createCacheDir( int nDirID )
776 : : {
777 [ + - ]: 2006 : PrintFontManager& rManager( PrintFontManager::get() );
778 : :
779 [ + - ]: 2006 : const OString& rDir = rManager.getDirectory( nDirID );
780 : : struct stat aStat;
781 [ + - ]: 2006 : if( ! stat( rDir.getStr(), &aStat ) )
782 [ + - ]: 2006 : m_aCache[nDirID].m_nTimestamp = (sal_Int64)aStat.st_mtime;
783 : 2006 : }
784 : :
785 : : /*
786 : : * FontCache::markEmptyDir
787 : : */
788 : 127 : void FontCache::markEmptyDir( int nDirID, bool bNoFiles )
789 : : {
790 : 127 : createCacheDir( nDirID );
791 : 127 : m_aCache[nDirID].m_bNoFiles = bNoFiles;
792 : 127 : m_bDoFlush = true;
793 : 127 : }
794 : :
795 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|