1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
23 #include "fontcache.hxx"
25 #include "osl/thread.h"
27 #include "unotools/atom.hxx"
29 #include "tools/stream.hxx"
31 #include <rtl/strbuf.hxx>
36 #if OSL_DEBUG_LEVEL >1
40 #define CACHE_MAGIC "LibreOffice PspFontCacheFile format 6"
47 * FontCache constructor
50 FontCache::FontCache()
53 m_aCacheFile
= getOfficePath( UserPath
);
54 if( !m_aCacheFile
.isEmpty() )
56 m_aCacheFile
+= "/user/psprint/pspfontcache";
62 * FontCache destructor
65 FontCache::~FontCache()
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
)
90 void FontCache::flush()
92 if( ! m_bDoFlush
|| m_aCacheFile
.isEmpty() )
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() );
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
);
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() )
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
));
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:
148 * fontnr;PSName;italic;weight;width;pitch;encoding;ascend;descend;leading;vsubst;gxw;gxh;gyw;gyh;useroverrride;embed;antialias[;{metricfile,typeflags}][;stylename]
151 nSubEntry
= static_cast<const PrintFontManager::TrueTypeFontFile
*>(*it
)->m_nCollectionEntry
;
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() )
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
);
170 aLine
.append(OUStringToOString(rPSName
, RTL_TEXTENCODING_UTF8
));
172 aLine
.append(static_cast<sal_Int32
>((*it
)->m_eItalic
));
174 aLine
.append(static_cast<sal_Int32
>((*it
)->m_eWeight
));
176 aLine
.append(static_cast<sal_Int32
>((*it
)->m_eWidth
));
178 aLine
.append(static_cast<sal_Int32
>((*it
)->m_ePitch
));
180 aLine
.append(static_cast<sal_Int32
>((*it
)->m_aEncoding
));
182 aLine
.append(static_cast<sal_Int32
>((*it
)->m_nAscend
));
184 aLine
.append(static_cast<sal_Int32
>((*it
)->m_nDescend
));
186 aLine
.append(static_cast<sal_Int32
>((*it
)->m_nLeading
));
188 aLine
.append((*it
)->m_bHaveVerticalSubstitutedGlyphs
? '1' : '0');
190 aLine
.append(static_cast<sal_Int32
>((*it
)->m_aGlobalMetricX
.width
));
192 aLine
.append(static_cast<sal_Int32
>((*it
)->m_aGlobalMetricX
.height
));
194 aLine
.append(static_cast<sal_Int32
>((*it
)->m_aGlobalMetricY
.width
));
196 aLine
.append(static_cast<sal_Int32
>((*it
)->m_aGlobalMetricY
.height
));
198 aLine
.append((*it
)->m_bUserOverride
? '1' : '0');
200 aLine
.append(static_cast<sal_Int32
>(0));
202 aLine
.append(static_cast<sal_Int32
>(0));
204 switch( (*it
)->m_eType
)
206 case fonttype::Type1
:
208 aLine
.append(static_cast<const PrintFontManager::Type1FontFile
*>(*it
)->m_aMetricFile
);
210 case fonttype::TrueType
:
212 aLine
.append(static_cast<sal_Int32
>(static_cast<const PrintFontManager::TrueTypeFontFile
*>(*it
)->m_nTypeFlags
));
216 if( !(*it
)->m_aStyleName
.isEmpty() )
219 aLine
.append(OUStringToOString((*it
)->m_aStyleName
, RTL_TEXTENCODING_UTF8
));
221 aStream
.WriteLine(aLine
.makeStringAndClear());
223 aStream
.WriteLine(OString());
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() );
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() );
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;
270 sal_Int64 nTimestamp
= 0;
271 sal_Int32 nTEnd
= aLine
.indexOf( ':', nSearchIndex
);
274 OString aTimeStamp
= aLine
.copy( nSearchIndex
, nTEnd
- nSearchIndex
);
275 nTimestamp
= aTimeStamp
.toInt64();
276 aDir
= aLine
.copy( nTEnd
+1 );
280 // invalid format, remove
287 // is the directory modified ?
289 if( stat( aDir
.getStr(), &aStat
) ||
290 ! S_ISDIR(aStat
.st_mode
) )
292 // remove outdated cache data
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
)
319 while( *pLine
&& *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
;
335 case fonttype::TrueType
:
336 pFont
= new PrintFontManager::TrueTypeFontFile();
338 case fonttype::Type1
:
339 pFont
= new PrintFontManager::Type1FontFile();
346 for( nIndex
= 0; nIndex
< nLen
&& pLine
[nIndex
] != ';'; nIndex
++ )
349 pFont
->m_nFamilyName
= pAtoms
->getAtom( ATOM_FAMILYNAME
,
350 OUString( pLine
, nIndex
, RTL_TEXTENCODING_UTF8
),
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
];
372 for( int i
= 0; i
< nLen
; i
++ )
374 if( pLine
[i
] == ';' )
376 nTokenPos
[nTokens
++] = i
+1;
377 if( nTokens
== nMaxTokens
)
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;
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
;
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
;
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
);
442 if( stat( aFilePath
.getStr(), &aStat
) ||
443 ! S_ISREG( aStat
.st_mode
) ||
448 #if OSL_DEBUG_LEVEL > 2
450 fprintf( stderr
, "keeping file %s in outdated cache entry due to user override\n",
451 aFilePath
.getStr() );
460 #if OSL_DEBUG_LEVEL > 2
461 fprintf( stderr
, "removing obsolete font %s\n", aFile
.getStr() );
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
)
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
;
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
;
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
)
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
)
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
)
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
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
);
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();
590 case fonttype::Type1
:
591 pFont
= new PrintFontManager::Type1FontFile();
597 copyPrintFont( pOldFont
, 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
)
618 PrintFontManager::PrintFont
* pFont
= clonePrintFont( *font
);
619 rNewFonts
.push_back( pFont
);
627 * FontCache::updateFontCacheEntry
629 void FontCache::updateFontCacheEntry( const PrintFontManager::PrintFont
* pFont
, bool bFlush
)
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
;
639 case fonttype::Type1
:
640 nDirID
= static_cast<const PrintFontManager::Type1FontFile
*>(pFont
)->m_nDirectory
;
641 aFile
= static_cast<const PrintFontManager::Type1FontFile
*>(pFont
)->m_aFontFile
;
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
664 if( font
!= entry
->second
.m_aEntry
.end() )
669 createCacheDir( nDirID
);
673 if( ! equalsPrintFont( pFont
, pCacheFont
) )
675 copyPrintFont( pFont
, pCacheFont
);
681 pCacheFont
= clonePrintFont( pFont
);
682 m_aCache
[nDirID
].m_aEntries
[aFile
].m_aEntry
.push_back( pCacheFont
);
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
);
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
);
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: */