Branch libreoffice-5-0-4
[LibreOffice.git] / vcl / generic / fontmanager / fontcache.cxx
blob7448570c8adab4de6c5a1d7e4367e1fd3e3f637d
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <cstdlib>
21 #include <cstring>
23 #include "fontcache.hxx"
25 #include "osl/thread.h"
27 #include "unotools/atom.hxx"
29 #include "tools/stream.hxx"
31 #include <rtl/strbuf.hxx>
33 #include <unistd.h>
34 #include <sys/stat.h>
36 #if OSL_DEBUG_LEVEL >1
37 #include <cstdio>
38 #endif
40 #define CACHE_MAGIC "LibreOffice PspFontCacheFile format 6"
42 using namespace std;
43 using namespace psp;
44 using namespace utl;
47 * FontCache constructor
50 FontCache::FontCache()
52 m_bDoFlush = false;
53 m_aCacheFile = getOfficePath( UserPath );
54 if( !m_aCacheFile.isEmpty() )
56 m_aCacheFile += "/user/psprint/pspfontcache";
57 read();
62 * FontCache destructor
65 FontCache::~FontCache()
67 clearCache();
71 * FontCache::clearCache
73 void FontCache::clearCache()
75 for( FontCacheData::iterator dir_it = m_aCache.begin(); dir_it != m_aCache.end(); ++dir_it )
77 for( FontDirMap::iterator entry_it = dir_it->second.m_aEntries.begin(); entry_it != dir_it->second.m_aEntries.end(); ++entry_it )
79 for( FontCacheEntry::iterator font_it = entry_it->second.m_aEntry.begin(); font_it != entry_it->second.m_aEntry.end(); ++font_it )
80 delete *font_it;
83 m_aCache.clear();
87 * FontCache::Commit
90 void FontCache::flush()
92 if( ! m_bDoFlush || m_aCacheFile.isEmpty() )
93 return;
95 SvFileStream aStream;
96 aStream.Open( m_aCacheFile, StreamMode::WRITE | StreamMode::TRUNC );
97 if( ! (aStream.IsOpen() && aStream.IsWritable()) )
99 #if OSL_DEBUG_LEVEL > 1
100 fprintf( stderr, "FontCache::flush: opening cache file %s failed\n", OUStringToOString(m_aCacheFile, osl_getThreadTextEncoding()).getStr() );
101 #endif
102 return;
105 aStream.SetLineDelimiter( LINEEND_LF );
106 aStream.WriteLine( CACHE_MAGIC );
108 PrintFontManager& rManager( PrintFontManager::get() );
109 MultiAtomProvider* pAtoms = rManager.m_pAtoms;
111 for( FontCacheData::const_iterator dir_it = m_aCache.begin(); dir_it != m_aCache.end(); ++ dir_it )
113 const FontDirMap& rDir( dir_it->second.m_aEntries );
115 OString aDirectory(rManager.getDirectory(dir_it->first));
116 OStringBuffer aLine("FontCacheDirectory:");
117 aLine.append(dir_it->second.m_nTimestamp);
118 aLine.append(':');
119 aLine.append(aDirectory);
120 if( rDir.empty() && dir_it->second.m_bNoFiles )
121 aLine.insert(0, "Empty");
122 aStream.WriteLine(aLine.makeStringAndClear());
124 for( FontDirMap::const_iterator entry_it = rDir.begin(); entry_it != rDir.end(); ++entry_it )
126 // insert cache entries
127 const FontCacheEntry& rEntry( entry_it->second.m_aEntry );
128 if( rEntry.begin() == rEntry.end() )
129 continue;
131 aLine.append("File:");
132 aLine.append(entry_it->first);
133 aStream.WriteLine(aLine.makeStringAndClear());
135 int nEntrySize = entry_it->second.m_aEntry.size();
136 // write: type;nfonts
137 aLine.append(static_cast<sal_Int32>(rEntry.front()->m_eType));
138 aLine.append(';');
139 aLine.append(static_cast<sal_Int32>(nEntrySize));
140 aStream.WriteLine(aLine.makeStringAndClear());
142 sal_Int32 nSubEntry = 0;
143 for( FontCacheEntry::const_iterator it = rEntry.begin(); it != rEntry.end(); ++it, nSubEntry++ )
146 * for each font entry write:
147 * name[;name[;name]]
148 * fontnr;PSName;italic;weight;width;pitch;encoding;ascend;descend;leading;vsubst;gxw;gxh;gyw;gyh;useroverrride;embed;antialias[;{metricfile,typeflags}][;stylename]
150 if( nEntrySize > 1 )
151 nSubEntry = static_cast<const PrintFontManager::TrueTypeFontFile*>(*it)->m_nCollectionEntry;
152 else
153 nSubEntry = 0;
155 aLine.append(OUStringToOString(pAtoms->getString( ATOM_FAMILYNAME, (*it)->m_nFamilyName), RTL_TEXTENCODING_UTF8));
156 for( ::std::list< int >::const_iterator name_it = (*it)->m_aAliases.begin(); name_it != (*it)->m_aAliases.end(); ++name_it )
158 const OUString& rAdd( pAtoms->getString( ATOM_FAMILYNAME, *name_it ) );
159 if( !rAdd.isEmpty() )
161 aLine.append(';');
162 aLine.append(OUStringToOString(rAdd, RTL_TEXTENCODING_UTF8));
165 aStream.WriteLine(aLine.makeStringAndClear());
167 const OUString& rPSName( pAtoms->getString( ATOM_PSNAME, (*it)->m_nPSName ) );
168 aLine.append(nSubEntry);
169 aLine.append(';');
170 aLine.append(OUStringToOString(rPSName, RTL_TEXTENCODING_UTF8));
171 aLine.append(';');
172 aLine.append(static_cast<sal_Int32>((*it)->m_eItalic));
173 aLine.append(';');
174 aLine.append(static_cast<sal_Int32>((*it)->m_eWeight));
175 aLine.append(';');
176 aLine.append(static_cast<sal_Int32>((*it)->m_eWidth));
177 aLine.append(';');
178 aLine.append(static_cast<sal_Int32>((*it)->m_ePitch));
179 aLine.append(';');
180 aLine.append(static_cast<sal_Int32>((*it)->m_aEncoding));
181 aLine.append(';');
182 aLine.append(static_cast<sal_Int32>((*it)->m_nAscend));
183 aLine.append(';');
184 aLine.append(static_cast<sal_Int32>((*it)->m_nDescend));
185 aLine.append(';');
186 aLine.append(static_cast<sal_Int32>((*it)->m_nLeading));
187 aLine.append(';');
188 aLine.append((*it)->m_bHaveVerticalSubstitutedGlyphs ? '1' : '0');
189 aLine.append(';');
190 aLine.append(static_cast<sal_Int32>((*it)->m_aGlobalMetricX.width ));
191 aLine.append(';');
192 aLine.append(static_cast<sal_Int32>((*it)->m_aGlobalMetricX.height));
193 aLine.append(';');
194 aLine.append(static_cast<sal_Int32>((*it)->m_aGlobalMetricY.width ));
195 aLine.append(';');
196 aLine.append(static_cast<sal_Int32>((*it)->m_aGlobalMetricY.height));
197 aLine.append(';');
198 aLine.append((*it)->m_bUserOverride ? '1' : '0');
199 aLine.append(';');
200 aLine.append(static_cast<sal_Int32>(0));
201 aLine.append(';');
202 aLine.append(static_cast<sal_Int32>(0));
204 switch( (*it)->m_eType )
206 case fonttype::Type1:
207 aLine.append(';');
208 aLine.append(static_cast<const PrintFontManager::Type1FontFile*>(*it)->m_aMetricFile);
209 break;
210 case fonttype::TrueType:
211 aLine.append(';');
212 aLine.append(static_cast<sal_Int32>(static_cast<const PrintFontManager::TrueTypeFontFile*>(*it)->m_nTypeFlags));
213 break;
214 default: break;
216 if( !(*it)->m_aStyleName.isEmpty() )
218 aLine.append(';');
219 aLine.append(OUStringToOString((*it)->m_aStyleName, RTL_TEXTENCODING_UTF8));
221 aStream.WriteLine(aLine.makeStringAndClear());
223 aStream.WriteLine(OString());
226 m_bDoFlush = false;
230 * FontCache::read
233 void FontCache::read()
235 PrintFontManager& rManager( PrintFontManager::get() );
236 MultiAtomProvider* pAtoms = rManager.m_pAtoms;
238 SvFileStream aStream( m_aCacheFile, StreamMode::READ );
239 if( ! aStream.IsOpen() )
241 #if OSL_DEBUG_LEVEL > 1
242 fprintf( stderr, "FontCache::read: opening cache file %s failed\n", OUStringToOString(m_aCacheFile, osl_getThreadTextEncoding()).getStr() );
243 #endif
244 return;
247 OString aLine;
248 aStream.ReadLine( aLine );
249 if ( !(aLine == CACHE_MAGIC) )
251 #if OSL_DEBUG_LEVEL >1
252 fprintf( stderr, "FontCache::read: cache file %s fails magic test\n", OUStringToOString(m_aCacheFile, osl_getThreadTextEncoding()).getStr() );
253 #endif
254 return;
257 int nDir = 0;
258 FontDirMap* pDir = NULL;
259 bool bKeepOnlyUserOverridden = false;
262 aStream.ReadLine( aLine );
263 if( aLine.startsWith("FontCacheDirectory:") ||
264 aLine.startsWith("EmptyFontCacheDirectory:") )
266 bool bEmpty = aLine.startsWith("Empty");
267 sal_Int32 nSearchIndex = bEmpty ? 24 : 19;
269 OString aDir;
270 sal_Int64 nTimestamp = 0;
271 sal_Int32 nTEnd = aLine.indexOf( ':', nSearchIndex );
272 if( nTEnd != -1 )
274 OString aTimeStamp = aLine.copy( nSearchIndex, nTEnd - nSearchIndex );
275 nTimestamp = aTimeStamp.toInt64();
276 aDir = aLine.copy( nTEnd+1 );
278 else
280 // invalid format, remove
281 pDir = NULL;
282 nDir = 0;
283 m_bDoFlush = true;
284 continue;
287 // is the directory modified ?
288 struct stat aStat;
289 if( stat( aDir.getStr(), &aStat ) ||
290 ! S_ISDIR(aStat.st_mode) )
292 // remove outdated cache data
293 pDir = NULL;
294 nDir = 0;
295 m_bDoFlush = true;
296 continue;
298 else
300 nDir = rManager.getDirectoryAtom( aDir, true );
301 m_aCache[ nDir ].m_nTimestamp = (sal_Int64)aStat.st_mtime;
302 m_aCache[ nDir ].m_bNoFiles = bEmpty;
303 pDir = bEmpty ? NULL : &m_aCache[ nDir ].m_aEntries;
304 bKeepOnlyUserOverridden = ((sal_Int64)aStat.st_mtime != nTimestamp);
305 m_aCache[ nDir ].m_bUserOverrideOnly = bKeepOnlyUserOverridden;
308 else if( pDir && aLine.startsWith("File:") )
310 OString aFile( aLine.copy( 5 ) );
311 aStream.ReadLine( aLine );
313 const char* pLine = aLine.getStr();
315 fonttype::type eType = (fonttype::type)atoi( pLine );
316 if( eType != fonttype::TrueType &&
317 eType != fonttype::Type1 )
318 continue;
319 while( *pLine && *pLine != ';' )
320 pLine++;
321 if( *pLine != ';' )
322 continue;
324 pLine++;
325 sal_Int32 nFonts = atoi( pLine );
326 for( int n = 0; n < nFonts; n++ )
328 aStream.ReadLine( aLine );
329 pLine = aLine.getStr();
330 int nLen = aLine.getLength();
332 PrintFontManager::PrintFont* pFont = NULL;
333 switch( eType )
335 case fonttype::TrueType:
336 pFont = new PrintFontManager::TrueTypeFontFile();
337 break;
338 case fonttype::Type1:
339 pFont = new PrintFontManager::Type1FontFile();
340 break;
341 default: break;
344 sal_Int32 nIndex;
346 for( nIndex = 0; nIndex < nLen && pLine[nIndex] != ';'; nIndex++ )
349 pFont->m_nFamilyName = pAtoms->getAtom( ATOM_FAMILYNAME,
350 OUString( pLine, nIndex, RTL_TEXTENCODING_UTF8 ),
351 true );
352 while( nIndex < nLen )
354 sal_Int32 nLastIndex = nIndex+1;
355 for( nIndex = nLastIndex ; nIndex < nLen && pLine[nIndex] != ';'; nIndex++ )
357 if( nIndex - nLastIndex )
359 OUString aAlias( pLine+nLastIndex, nIndex-nLastIndex, RTL_TEXTENCODING_UTF8 );
360 pFont->m_aAliases.push_back( pAtoms->getAtom( ATOM_FAMILYNAME, aAlias, true ) );
363 aStream.ReadLine( aLine );
364 pLine = aLine.getStr();
365 nLen = aLine.getLength();
367 // get up to 20 token positions
368 const int nMaxTokens = 20;
369 int nTokenPos[nMaxTokens];
370 nTokenPos[0] = 0;
371 int nTokens = 1;
372 for( int i = 0; i < nLen; i++ )
374 if( pLine[i] == ';' )
376 nTokenPos[nTokens++] = i+1;
377 if( nTokens == nMaxTokens )
378 break;
381 if( nTokens < 18 )
383 delete pFont;
384 continue;
386 int nCollEntry = atoi( pLine );
387 pFont->m_nPSName = pAtoms->getAtom( ATOM_PSNAME, OUString( pLine + nTokenPos[1], nTokenPos[2]-nTokenPos[1]-1, RTL_TEXTENCODING_UTF8 ), true );
388 pFont->m_eItalic = (FontItalic)atoi( pLine+nTokenPos[2] );
389 pFont->m_eWeight = (FontWeight)atoi( pLine+nTokenPos[3] );
390 pFont->m_eWidth = (FontWidth)atoi( pLine+nTokenPos[4] );
391 pFont->m_ePitch = (FontPitch)atoi( pLine+nTokenPos[5] );
392 pFont->m_aEncoding = (rtl_TextEncoding)atoi( pLine+nTokenPos[6] );
393 pFont->m_nAscend = atoi( pLine + nTokenPos[7] );
394 pFont->m_nDescend = atoi( pLine + nTokenPos[8] );
395 pFont->m_nLeading = atoi( pLine + nTokenPos[9] );
396 pFont->m_bHaveVerticalSubstitutedGlyphs
397 = (atoi( pLine + nTokenPos[10] ) != 0);
398 pFont->m_aGlobalMetricX.width
399 = atoi( pLine + nTokenPos[11] );
400 pFont->m_aGlobalMetricX.height
401 = atoi( pLine + nTokenPos[12] );
402 pFont->m_aGlobalMetricY.width
403 = atoi( pLine + nTokenPos[13] );
404 pFont->m_aGlobalMetricY.height
405 = atoi( pLine + nTokenPos[14] );
406 pFont->m_bUserOverride
407 = (atoi( pLine + nTokenPos[15] ) != 0);
408 int nStyleTokenNr = 18;
409 switch( eType )
411 case fonttype::TrueType:
412 static_cast<PrintFontManager::TrueTypeFontFile*>(pFont)->m_nTypeFlags = atoi( pLine + nTokenPos[18] );
413 static_cast<PrintFontManager::TrueTypeFontFile*>(pFont)->m_nCollectionEntry = nCollEntry;
414 static_cast<PrintFontManager::TrueTypeFontFile*>(pFont)->m_nDirectory = nDir;
415 static_cast<PrintFontManager::TrueTypeFontFile*>(pFont)->m_aFontFile = aFile;
416 nStyleTokenNr++;
417 break;
418 case fonttype::Type1:
420 int nTokLen = (nTokens > 19 ) ? nTokenPos[19]-nTokenPos[18]-1 : nLen - nTokenPos[18];
421 static_cast<PrintFontManager::Type1FontFile*>(pFont)->m_aMetricFile = OString( pLine + nTokenPos[18], nTokLen );
422 static_cast<PrintFontManager::Type1FontFile*>(pFont)->m_nDirectory = nDir;
423 static_cast<PrintFontManager::Type1FontFile*>(pFont)->m_aFontFile = aFile;
424 nStyleTokenNr++;
426 break;
427 default: break;
429 if( nTokens > nStyleTokenNr )
430 pFont->m_aStyleName = OUString::intern( pLine + nTokenPos[nStyleTokenNr],
431 nLen - nTokenPos[nStyleTokenNr],
432 RTL_TEXTENCODING_UTF8 );
434 bool bObsolete = false;
435 if( bKeepOnlyUserOverridden )
437 if( pFont->m_bUserOverride )
439 OStringBuffer aFilePath(rManager.getDirectory(nDir));
440 aFilePath.append('/').append(aFile);
441 struct stat aStat;
442 if( stat( aFilePath.getStr(), &aStat ) ||
443 ! S_ISREG( aStat.st_mode ) ||
444 aStat.st_size < 16 )
446 bObsolete = true;
448 #if OSL_DEBUG_LEVEL > 2
449 else
450 fprintf( stderr, "keeping file %s in outdated cache entry due to user override\n",
451 aFilePath.getStr() );
452 #endif
454 else
455 bObsolete = true;
457 if( bObsolete )
459 m_bDoFlush = true;
460 #if OSL_DEBUG_LEVEL > 2
461 fprintf( stderr, "removing obsolete font %s\n", aFile.getStr() );
462 #endif
463 delete pFont;
464 continue;
467 FontCacheEntry& rEntry = (*pDir)[aFile].m_aEntry;
468 rEntry.push_back( pFont );
471 } while( ! aStream.IsEof() );
475 * FontCache::copyPrintFont
477 void FontCache::copyPrintFont( const PrintFontManager::PrintFont* pFrom, PrintFontManager::PrintFont* pTo )
479 if( pFrom->m_eType != pTo->m_eType )
480 return;
481 switch( pFrom->m_eType )
483 case fonttype::TrueType:
484 static_cast<PrintFontManager::TrueTypeFontFile*>(pTo)->m_nDirectory = static_cast<const PrintFontManager::TrueTypeFontFile*>(pFrom)->m_nDirectory;
485 static_cast<PrintFontManager::TrueTypeFontFile*>(pTo)->m_aFontFile = static_cast<const PrintFontManager::TrueTypeFontFile*>(pFrom)->m_aFontFile;
486 static_cast<PrintFontManager::TrueTypeFontFile*>(pTo)->m_nCollectionEntry = static_cast<const PrintFontManager::TrueTypeFontFile*>(pFrom)->m_nCollectionEntry;
487 static_cast<PrintFontManager::TrueTypeFontFile*>(pTo)->m_nTypeFlags = static_cast<const PrintFontManager::TrueTypeFontFile*>(pFrom)->m_nTypeFlags;
488 break;
489 case fonttype::Type1:
490 static_cast<PrintFontManager::Type1FontFile*>(pTo)->m_nDirectory = static_cast<const PrintFontManager::Type1FontFile*>(pFrom)->m_nDirectory;
491 static_cast<PrintFontManager::Type1FontFile*>(pTo)->m_aFontFile = static_cast<const PrintFontManager::Type1FontFile*>(pFrom)->m_aFontFile;
492 static_cast<PrintFontManager::Type1FontFile*>(pTo)->m_aMetricFile = static_cast<const PrintFontManager::Type1FontFile*>(pFrom)->m_aMetricFile;
493 break;
494 default: break;
496 pTo->m_nFamilyName = pFrom->m_nFamilyName;
497 pTo->m_aStyleName = pFrom->m_aStyleName;
498 pTo->m_aAliases = pFrom->m_aAliases;
499 pTo->m_nPSName = pFrom->m_nPSName;
500 pTo->m_eItalic = pFrom->m_eItalic;
501 pTo->m_eWeight = pFrom->m_eWeight;
502 pTo->m_eWidth = pFrom->m_eWidth;
503 pTo->m_ePitch = pFrom->m_ePitch;
504 pTo->m_aEncoding = pFrom->m_aEncoding;
505 pTo->m_aGlobalMetricX = pFrom->m_aGlobalMetricX;
506 pTo->m_aGlobalMetricY = pFrom->m_aGlobalMetricY;
507 pTo->m_nAscend = pFrom->m_nAscend;
508 pTo->m_nDescend = pFrom->m_nDescend;
509 pTo->m_nLeading = pFrom->m_nLeading;
510 pTo->m_nXMin = pFrom->m_nXMin;
511 pTo->m_nYMin = pFrom->m_nYMin;
512 pTo->m_nXMax = pFrom->m_nXMax;
513 pTo->m_nYMax = pFrom->m_nYMax;
514 pTo->m_bHaveVerticalSubstitutedGlyphs = pFrom->m_bHaveVerticalSubstitutedGlyphs;
515 pTo->m_bUserOverride = pFrom->m_bUserOverride;
519 * FontCache::equalsPrintFont
521 bool FontCache::equalsPrintFont( const PrintFontManager::PrintFont* pLeft, PrintFontManager::PrintFont* pRight )
523 if( pLeft->m_eType != pRight->m_eType )
524 return false;
525 switch( pLeft->m_eType )
527 case fonttype::TrueType:
529 const PrintFontManager::TrueTypeFontFile* pLT = static_cast<const PrintFontManager::TrueTypeFontFile*>(pLeft);
530 const PrintFontManager::TrueTypeFontFile* pRT = static_cast<const PrintFontManager::TrueTypeFontFile*>(pRight);
531 if( pRT->m_nDirectory != pLT->m_nDirectory ||
532 pRT->m_aFontFile != pLT->m_aFontFile ||
533 pRT->m_nCollectionEntry != pLT->m_nCollectionEntry ||
534 pRT->m_nTypeFlags != pLT->m_nTypeFlags )
535 return false;
537 break;
538 case fonttype::Type1:
540 const PrintFontManager::Type1FontFile* pLT = static_cast<const PrintFontManager::Type1FontFile*>(pLeft);
541 const PrintFontManager::Type1FontFile* pRT = static_cast<const PrintFontManager::Type1FontFile*>(pRight);
542 if( pRT->m_nDirectory != pLT->m_nDirectory ||
543 pRT->m_aFontFile != pLT->m_aFontFile ||
544 pRT->m_aMetricFile != pLT->m_aMetricFile )
545 return false;
547 break;
548 default: break;
550 if( pRight->m_nFamilyName != pLeft->m_nFamilyName ||
551 pRight->m_aStyleName != pLeft->m_aStyleName ||
552 pRight->m_nPSName != pLeft->m_nPSName ||
553 pRight->m_eItalic != pLeft->m_eItalic ||
554 pRight->m_eWeight != pLeft->m_eWeight ||
555 pRight->m_eWidth != pLeft->m_eWidth ||
556 pRight->m_ePitch != pLeft->m_ePitch ||
557 pRight->m_aEncoding != pLeft->m_aEncoding ||
558 pRight->m_aGlobalMetricX != pLeft->m_aGlobalMetricX ||
559 pRight->m_aGlobalMetricY != pLeft->m_aGlobalMetricY ||
560 pRight->m_nAscend != pLeft->m_nAscend ||
561 pRight->m_nDescend != pLeft->m_nDescend ||
562 pRight->m_nLeading != pLeft->m_nLeading ||
563 pRight->m_nXMin != pLeft->m_nXMin ||
564 pRight->m_nYMin != pLeft->m_nYMin ||
565 pRight->m_nXMax != pLeft->m_nXMax ||
566 pRight->m_nYMax != pLeft->m_nYMax ||
567 pRight->m_bHaveVerticalSubstitutedGlyphs != pLeft->m_bHaveVerticalSubstitutedGlyphs ||
568 pRight->m_bUserOverride != pLeft->m_bUserOverride
570 return false;
571 std::list< int >::const_iterator lit, rit;
572 for( lit = pLeft->m_aAliases.begin(), rit = pRight->m_aAliases.begin();
573 lit != pLeft->m_aAliases.end() && rit != pRight->m_aAliases.end() && (*lit) == (*rit);
574 ++lit, ++rit )
576 return lit == pLeft->m_aAliases.end() && rit == pRight->m_aAliases.end();
580 * FontCache::clonePrintFont
582 PrintFontManager::PrintFont* FontCache::clonePrintFont( const PrintFontManager::PrintFont* pOldFont )
584 PrintFontManager::PrintFont* pFont = NULL;
585 switch( pOldFont->m_eType )
587 case fonttype::TrueType:
588 pFont = new PrintFontManager::TrueTypeFontFile();
589 break;
590 case fonttype::Type1:
591 pFont = new PrintFontManager::Type1FontFile();
592 break;
593 default: break;
595 if( pFont )
597 copyPrintFont( pOldFont, pFont );
599 return pFont;
603 * FontCache::getFontCacheFile
605 bool FontCache::getFontCacheFile( int nDirID, const OString& rFile, list< PrintFontManager::PrintFont* >& rNewFonts ) const
607 bool bSuccess = false;
609 FontCacheData::const_iterator dir = m_aCache.find( nDirID );
610 if( dir != m_aCache.end() )
612 FontDirMap::const_iterator entry = dir->second.m_aEntries.find( rFile );
613 if( entry != dir->second.m_aEntries.end() )
615 for( FontCacheEntry::const_iterator font = entry->second.m_aEntry.begin(); font != entry->second.m_aEntry.end(); ++font )
617 bSuccess = true;
618 PrintFontManager::PrintFont* pFont = clonePrintFont( *font );
619 rNewFonts.push_back( pFont );
623 return bSuccess;
627 * FontCache::updateFontCacheEntry
629 void FontCache::updateFontCacheEntry( const PrintFontManager::PrintFont* pFont, bool bFlush )
631 OString aFile;
632 int nDirID = 0;
633 switch( pFont->m_eType )
635 case fonttype::TrueType:
636 nDirID = static_cast<const PrintFontManager::TrueTypeFontFile*>(pFont)->m_nDirectory;
637 aFile = static_cast<const PrintFontManager::TrueTypeFontFile*>(pFont)->m_aFontFile;
638 break;
639 case fonttype::Type1:
640 nDirID = static_cast<const PrintFontManager::Type1FontFile*>(pFont)->m_nDirectory;
641 aFile = static_cast<const PrintFontManager::Type1FontFile*>(pFont)->m_aFontFile;
642 break;
643 default:
644 return;
646 FontCacheData::const_iterator dir = m_aCache.find( nDirID );
647 FontDirMap::const_iterator entry;
648 FontCacheEntry::const_iterator font;
649 PrintFontManager::PrintFont* pCacheFont = NULL;
651 if( dir != m_aCache.end() )
653 entry = dir->second.m_aEntries.find( aFile );
654 if( entry != dir->second.m_aEntries.end() )
656 for( font = entry->second.m_aEntry.begin(); font != entry->second.m_aEntry.end(); ++font )
658 if( (*font)->m_eType == pFont->m_eType &&
659 ( (*font)->m_eType != fonttype::TrueType ||
660 static_cast<const PrintFontManager::TrueTypeFontFile*>(*font)->m_nCollectionEntry == static_cast<const PrintFontManager::TrueTypeFontFile*>(pFont)->m_nCollectionEntry
662 break;
664 if( font != entry->second.m_aEntry.end() )
665 pCacheFont = *font;
668 else
669 createCacheDir( nDirID );
671 if( pCacheFont )
673 if( ! equalsPrintFont( pFont, pCacheFont ) )
675 copyPrintFont( pFont, pCacheFont );
676 m_bDoFlush = true;
679 else
681 pCacheFont = clonePrintFont( pFont );
682 m_aCache[nDirID].m_aEntries[aFile].m_aEntry.push_back( pCacheFont );
683 m_bDoFlush = true;
685 if( bFlush )
686 flush();
690 * FontCache::listDirectory
692 bool FontCache::listDirectory( const OString& rDir, std::list< PrintFontManager::PrintFont* >& rNewFonts ) const
694 PrintFontManager& rManager( PrintFontManager::get() );
695 int nDirID = rManager.getDirectoryAtom( rDir );
697 FontCacheData::const_iterator dir = m_aCache.find( nDirID );
698 bool bFound = (dir != m_aCache.end());
700 if( bFound && !dir->second.m_bNoFiles )
702 for( FontDirMap::const_iterator file = dir->second.m_aEntries.begin(); file != dir->second.m_aEntries.end(); ++file )
704 for( FontCacheEntry::const_iterator font = file->second.m_aEntry.begin(); font != file->second.m_aEntry.end(); ++font )
706 PrintFontManager::PrintFont* pFont = clonePrintFont( *font );
707 rNewFonts.push_back( pFont );
711 return bFound;
715 * FontCache::listDirectory
717 bool FontCache::scanAdditionalFiles( const OString& rDir )
719 PrintFontManager& rManager( PrintFontManager::get() );
720 int nDirID = rManager.getDirectoryAtom( rDir );
721 FontCacheData::const_iterator dir = m_aCache.find( nDirID );
722 bool bFound = (dir != m_aCache.end());
724 return (bFound && dir->second.m_bUserOverrideOnly);
728 * FontCache::createCacheDir
730 void FontCache::createCacheDir( int nDirID )
732 PrintFontManager& rManager( PrintFontManager::get() );
734 const OString& rDir = rManager.getDirectory( nDirID );
735 struct stat aStat;
736 if( ! stat( rDir.getStr(), &aStat ) )
737 m_aCache[nDirID].m_nTimestamp = (sal_Int64)aStat.st_mtime;
740 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */