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 .
24 #include "fontcache.hxx"
26 #include "osl/thread.h"
28 #include "unotools/atom.hxx"
30 #include "tools/stream.hxx"
32 #include <rtl/strbuf.hxx>
37 #if OSL_DEBUG_LEVEL >1
41 #define FONTCACHEFILE "/user/psprint/pspfontcache"
42 #define CACHE_MAGIC "LibreOffice PspFontCacheFile format 5"
50 * FontCache constructor
53 FontCache::FontCache()
56 m_aCacheFile
= getOfficePath( UserPath
);
57 if( m_aCacheFile
.Len() )
59 m_aCacheFile
.AppendAscii( FONTCACHEFILE
);
65 * FontCache destructor
68 FontCache::~FontCache()
74 * FontCache::clearCache
76 void FontCache::clearCache()
78 for( FontCacheData::iterator dir_it
= m_aCache
.begin(); dir_it
!= m_aCache
.end(); ++dir_it
)
80 for( FontDirMap::iterator entry_it
= dir_it
->second
.m_aEntries
.begin(); entry_it
!= dir_it
->second
.m_aEntries
.end(); ++entry_it
)
82 for( FontCacheEntry::iterator font_it
= entry_it
->second
.m_aEntry
.begin(); font_it
!= entry_it
->second
.m_aEntry
.end(); ++font_it
)
93 void FontCache::flush()
95 if( ! m_bDoFlush
|| ! m_aCacheFile
.Len() )
99 aStream
.Open( m_aCacheFile
, STREAM_WRITE
| STREAM_TRUNC
);
100 if( ! (aStream
.IsOpen() && aStream
.IsWritable()) )
102 #if OSL_DEBUG_LEVEL > 1
103 fprintf( stderr
, "FontCache::flush: opening cache file %s failed\n", OUStringToOString(m_aCacheFile
, osl_getThreadTextEncoding()).getStr() );
108 aStream
.SetLineDelimiter( LINEEND_LF
);
109 aStream
.WriteLine( CACHE_MAGIC
);
111 PrintFontManager
& rManager( PrintFontManager::get() );
112 MultiAtomProvider
* pAtoms
= rManager
.m_pAtoms
;
114 for( FontCacheData::const_iterator dir_it
= m_aCache
.begin(); dir_it
!= m_aCache
.end(); ++ dir_it
)
116 const FontDirMap
& rDir( dir_it
->second
.m_aEntries
);
118 OString
aDirectory(rManager
.getDirectory(dir_it
->first
));
119 OStringBuffer
aLine("FontCacheDirectory:");
120 aLine
.append(dir_it
->second
.m_nTimestamp
);
122 aLine
.append(aDirectory
);
123 if( rDir
.empty() && dir_it
->second
.m_bNoFiles
)
124 aLine
.insert(0, "Empty");
125 aStream
.WriteLine(aLine
.makeStringAndClear());
127 for( FontDirMap::const_iterator entry_it
= rDir
.begin(); entry_it
!= rDir
.end(); ++entry_it
)
129 // insert cache entries
130 const FontCacheEntry
& rEntry( entry_it
->second
.m_aEntry
);
131 if( rEntry
.begin() == rEntry
.end() )
134 aLine
.append("File:");
135 aLine
.append(entry_it
->first
);
136 aStream
.WriteLine(aLine
.makeStringAndClear());
138 int nEntrySize
= entry_it
->second
.m_aEntry
.size();
139 // write: type;nfonts
140 aLine
.append(static_cast<sal_Int32
>(rEntry
.front()->m_eType
));
142 aLine
.append(static_cast<sal_Int32
>(nEntrySize
));
143 aStream
.WriteLine(aLine
.makeStringAndClear());
145 sal_Int32 nSubEntry
= 0;
146 for( FontCacheEntry::const_iterator it
= rEntry
.begin(); it
!= rEntry
.end(); ++it
, nSubEntry
++ )
149 * for each font entry write:
151 * fontnr;PSName;italic;weight;width;pitch;encoding;ascend;descend;leading;vsubst;gxw;gxh;gyw;gyh;useroverrride;embed;antialias[;{metricfile,typeflags}][;stylename]
154 nSubEntry
= static_cast<const PrintFontManager::TrueTypeFontFile
*>(*it
)->m_nCollectionEntry
;
158 aLine
.append(OUStringToOString(pAtoms
->getString( ATOM_FAMILYNAME
, (*it
)->m_nFamilyName
), RTL_TEXTENCODING_UTF8
));
159 for( ::std::list
< int >::const_iterator name_it
= (*it
)->m_aAliases
.begin(); name_it
!= (*it
)->m_aAliases
.end(); ++name_it
)
161 const OUString
& rAdd( pAtoms
->getString( ATOM_FAMILYNAME
, *name_it
) );
162 if( !rAdd
.isEmpty() )
165 aLine
.append(OUStringToOString(rAdd
, RTL_TEXTENCODING_UTF8
));
168 aStream
.WriteLine(aLine
.makeStringAndClear());
170 const OUString
& rPSName( pAtoms
->getString( ATOM_PSNAME
, (*it
)->m_nPSName
) );
171 aLine
.append(nSubEntry
);
173 aLine
.append(OUStringToOString(rPSName
, RTL_TEXTENCODING_UTF8
));
175 aLine
.append(static_cast<sal_Int32
>((*it
)->m_eItalic
));
177 aLine
.append(static_cast<sal_Int32
>((*it
)->m_eWeight
));
179 aLine
.append(static_cast<sal_Int32
>((*it
)->m_eWidth
));
181 aLine
.append(static_cast<sal_Int32
>((*it
)->m_ePitch
));
183 aLine
.append(static_cast<sal_Int32
>((*it
)->m_aEncoding
));
185 aLine
.append(static_cast<sal_Int32
>((*it
)->m_nAscend
));
187 aLine
.append(static_cast<sal_Int32
>((*it
)->m_nDescend
));
189 aLine
.append(static_cast<sal_Int32
>((*it
)->m_nLeading
));
191 aLine
.append((*it
)->m_bHaveVerticalSubstitutedGlyphs
? '1' : '0');
193 aLine
.append(static_cast<sal_Int32
>((*it
)->m_aGlobalMetricX
.width
));
195 aLine
.append(static_cast<sal_Int32
>((*it
)->m_aGlobalMetricX
.height
));
197 aLine
.append(static_cast<sal_Int32
>((*it
)->m_aGlobalMetricY
.width
));
199 aLine
.append(static_cast<sal_Int32
>((*it
)->m_aGlobalMetricY
.height
));
201 aLine
.append((*it
)->m_bUserOverride
? '1' : '0');
203 aLine
.append(static_cast<sal_Int32
>(0));
205 aLine
.append(static_cast<sal_Int32
>(0));
207 switch( (*it
)->m_eType
)
209 case fonttype::Type1
:
211 aLine
.append(static_cast<const PrintFontManager::Type1FontFile
*>(*it
)->m_aMetricFile
);
213 case fonttype::TrueType
:
215 aLine
.append(static_cast<sal_Int32
>(static_cast<const PrintFontManager::TrueTypeFontFile
*>(*it
)->m_nTypeFlags
));
219 if( !(*it
)->m_aStyleName
.isEmpty() )
222 aLine
.append(OUStringToOString((*it
)->m_aStyleName
, RTL_TEXTENCODING_UTF8
));
224 aStream
.WriteLine(aLine
.makeStringAndClear());
226 aStream
.WriteLine(OString());
236 void FontCache::read()
238 PrintFontManager
& rManager( PrintFontManager::get() );
239 MultiAtomProvider
* pAtoms
= rManager
.m_pAtoms
;
241 SvFileStream
aStream( m_aCacheFile
, STREAM_READ
);
242 if( ! aStream
.IsOpen() )
244 #if OSL_DEBUG_LEVEL > 1
245 fprintf( stderr
, "FontCache::read: opening cache file %s failed\n", OUStringToOString(m_aCacheFile
, osl_getThreadTextEncoding()).getStr() );
252 aStream
.ReadLine( aLine
);
253 if ( !(aLine
== CACHE_MAGIC
) )
255 #if OSL_DEBUG_LEVEL >1
256 fprintf( stderr
, "FontCache::read: cache file %s fails magic test\n", OUStringToOString(m_aCacheFile
, osl_getThreadTextEncoding()).getStr() );
262 FontDirMap
* pDir
= NULL
;
263 bool bKeepOnlyUserOverridden
= false;
266 aStream
.ReadLine( aLine
);
267 if( aLine
.startsWith("FontCacheDirectory:") ||
268 aLine
.startsWith("EmptyFontCacheDirectory:") )
270 bool bEmpty
= aLine
.startsWith("Empty");
271 sal_Int32 nSearchIndex
= bEmpty
? 24 : 19;
274 sal_Int64 nTimestamp
= 0;
275 sal_Int32 nTEnd
= aLine
.indexOf( ':', nSearchIndex
);
278 OString aTimeStamp
= aLine
.copy( nSearchIndex
, nTEnd
- nSearchIndex
);
279 nTimestamp
= aTimeStamp
.toInt64();
280 aDir
= aLine
.copy( nTEnd
+1 );
284 // invalid format, remove
291 // is the directory modified ?
293 if( stat( aDir
.getStr(), &aStat
) ||
294 ! S_ISDIR(aStat
.st_mode
) )
296 // remove outdated cache data
304 nDir
= rManager
.getDirectoryAtom( aDir
, true );
305 m_aCache
[ nDir
].m_nTimestamp
= (sal_Int64
)aStat
.st_mtime
;
306 m_aCache
[ nDir
].m_bNoFiles
= bEmpty
;
307 pDir
= bEmpty
? NULL
: &m_aCache
[ nDir
].m_aEntries
;
308 bKeepOnlyUserOverridden
= ((sal_Int64
)aStat
.st_mtime
!= nTimestamp
);
309 m_aCache
[ nDir
].m_bUserOverrideOnly
= bKeepOnlyUserOverridden
;
312 else if( pDir
&& aLine
.startsWith("File:") )
314 OString
aFile( aLine
.copy( 5 ) );
315 aStream
.ReadLine( aLine
);
317 const char* pLine
= aLine
.getStr();
319 fonttype::type eType
= (fonttype::type
)atoi( pLine
);
320 if( eType
!= fonttype::TrueType
&&
321 eType
!= fonttype::Type1
&&
322 eType
!= fonttype::Builtin
325 while( *pLine
&& *pLine
!= ';' )
331 sal_Int32 nFonts
= atoi( pLine
);
332 for( int n
= 0; n
< nFonts
; n
++ )
334 aStream
.ReadLine( aLine
);
335 pLine
= aLine
.getStr();
336 int nLen
= aLine
.getLength();
338 PrintFontManager::PrintFont
* pFont
= NULL
;
341 case fonttype::TrueType
:
342 pFont
= new PrintFontManager::TrueTypeFontFile();
344 case fonttype::Type1
:
345 pFont
= new PrintFontManager::Type1FontFile();
347 case fonttype::Builtin
:
348 pFont
= new PrintFontManager::BuiltinFont();
355 for( nIndex
= 0; nIndex
< nLen
&& pLine
[nIndex
] != ';'; nIndex
++ )
358 pFont
->m_nFamilyName
= pAtoms
->getAtom( ATOM_FAMILYNAME
,
359 OUString( pLine
, nIndex
, RTL_TEXTENCODING_UTF8
),
361 while( nIndex
< nLen
)
363 sal_Int32 nLastIndex
= nIndex
+1;
364 for( nIndex
= nLastIndex
; nIndex
< nLen
&& pLine
[nIndex
] != ';'; nIndex
++ )
366 if( nIndex
- nLastIndex
)
368 OUString
aAlias( pLine
+nLastIndex
, nIndex
-nLastIndex
, RTL_TEXTENCODING_UTF8
);
369 pFont
->m_aAliases
.push_back( pAtoms
->getAtom( ATOM_FAMILYNAME
, aAlias
, sal_True
) );
372 aStream
.ReadLine( aLine
);
373 pLine
= aLine
.getStr();
374 nLen
= aLine
.getLength();
376 // get up to 20 token positions
377 const int nMaxTokens
= 20;
378 int nTokenPos
[nMaxTokens
];
381 for( int i
= 0; i
< nLen
; i
++ )
383 if( pLine
[i
] == ';' )
385 nTokenPos
[nTokens
++] = i
+1;
386 if( nTokens
== nMaxTokens
)
395 int nCollEntry
= atoi( pLine
);
396 pFont
->m_nPSName
= pAtoms
->getAtom( ATOM_PSNAME
, OUString( pLine
+ nTokenPos
[1], nTokenPos
[2]-nTokenPos
[1]-1, RTL_TEXTENCODING_UTF8
), sal_True
);
397 pFont
->m_eItalic
= (FontItalic
)atoi( pLine
+nTokenPos
[2] );
398 pFont
->m_eWeight
= (FontWeight
)atoi( pLine
+nTokenPos
[3] );
399 pFont
->m_eWidth
= (FontWidth
)atoi( pLine
+nTokenPos
[4] );
400 pFont
->m_ePitch
= (FontPitch
)atoi( pLine
+nTokenPos
[5] );
401 pFont
->m_aEncoding
= (rtl_TextEncoding
)atoi( pLine
+nTokenPos
[6] );
402 pFont
->m_nAscend
= atoi( pLine
+ nTokenPos
[7] );
403 pFont
->m_nDescend
= atoi( pLine
+ nTokenPos
[8] );
404 pFont
->m_nLeading
= atoi( pLine
+ nTokenPos
[9] );
405 pFont
->m_bHaveVerticalSubstitutedGlyphs
406 = (atoi( pLine
+ nTokenPos
[10] ) != 0);
407 pFont
->m_aGlobalMetricX
.width
408 = atoi( pLine
+ nTokenPos
[11] );
409 pFont
->m_aGlobalMetricX
.height
410 = atoi( pLine
+ nTokenPos
[12] );
411 pFont
->m_aGlobalMetricY
.width
412 = atoi( pLine
+ nTokenPos
[13] );
413 pFont
->m_aGlobalMetricY
.height
414 = atoi( pLine
+ nTokenPos
[14] );
415 pFont
->m_bUserOverride
416 = (atoi( pLine
+ nTokenPos
[15] ) != 0);
417 int nStyleTokenNr
= 18;
420 case fonttype::TrueType
:
421 static_cast<PrintFontManager::TrueTypeFontFile
*>(pFont
)->m_nTypeFlags
= atoi( pLine
+ nTokenPos
[18] );
422 static_cast<PrintFontManager::TrueTypeFontFile
*>(pFont
)->m_nCollectionEntry
= nCollEntry
;
423 static_cast<PrintFontManager::TrueTypeFontFile
*>(pFont
)->m_nDirectory
= nDir
;
424 static_cast<PrintFontManager::TrueTypeFontFile
*>(pFont
)->m_aFontFile
= aFile
;
427 case fonttype::Type1
:
429 int nTokLen
= (nTokens
> 19 ) ? nTokenPos
[19]-nTokenPos
[18]-1 : nLen
- nTokenPos
[18];
430 static_cast<PrintFontManager::Type1FontFile
*>(pFont
)->m_aMetricFile
= OString( pLine
+ nTokenPos
[18], nTokLen
);
431 static_cast<PrintFontManager::Type1FontFile
*>(pFont
)->m_nDirectory
= nDir
;
432 static_cast<PrintFontManager::Type1FontFile
*>(pFont
)->m_aFontFile
= aFile
;
436 case fonttype::Builtin
:
437 static_cast<PrintFontManager::BuiltinFont
*>(pFont
)->m_nDirectory
= nDir
;
438 static_cast<PrintFontManager::BuiltinFont
*>(pFont
)->m_aMetricFile
= aFile
;
442 if( nTokens
> nStyleTokenNr
)
443 pFont
->m_aStyleName
= OUString::intern( pLine
+ nTokenPos
[nStyleTokenNr
],
444 nLen
- nTokenPos
[nStyleTokenNr
],
445 RTL_TEXTENCODING_UTF8
);
447 bool bObsolete
= false;
448 if( bKeepOnlyUserOverridden
)
450 if( pFont
->m_bUserOverride
)
452 OStringBuffer
aFilePath(rManager
.getDirectory(nDir
));
453 aFilePath
.append('/').append(aFile
);
455 if( stat( aFilePath
.getStr(), &aStat
) ||
456 ! S_ISREG( aStat
.st_mode
) ||
461 #if OSL_DEBUG_LEVEL > 2
463 fprintf( stderr
, "keeping file %s in outdated cache entry due to user override\n",
464 aFilePath
.getStr() );
473 #if OSL_DEBUG_LEVEL > 2
474 fprintf( stderr
, "removing obsolete font %s\n", aFile
.getStr() );
480 FontCacheEntry
& rEntry
= (*pDir
)[aFile
].m_aEntry
;
481 rEntry
.push_back( pFont
);
484 } while( ! aStream
.IsEof() );
488 * FontCache::copyPrintFont
490 void FontCache::copyPrintFont( const PrintFontManager::PrintFont
* pFrom
, PrintFontManager::PrintFont
* pTo
) const
492 if( pFrom
->m_eType
!= pTo
->m_eType
)
494 switch( pFrom
->m_eType
)
496 case fonttype::TrueType
:
497 static_cast<PrintFontManager::TrueTypeFontFile
*>(pTo
)->m_nDirectory
= static_cast<const PrintFontManager::TrueTypeFontFile
*>(pFrom
)->m_nDirectory
;
498 static_cast<PrintFontManager::TrueTypeFontFile
*>(pTo
)->m_aFontFile
= static_cast<const PrintFontManager::TrueTypeFontFile
*>(pFrom
)->m_aFontFile
;
499 static_cast<PrintFontManager::TrueTypeFontFile
*>(pTo
)->m_nCollectionEntry
= static_cast<const PrintFontManager::TrueTypeFontFile
*>(pFrom
)->m_nCollectionEntry
;
500 static_cast<PrintFontManager::TrueTypeFontFile
*>(pTo
)->m_nTypeFlags
= static_cast<const PrintFontManager::TrueTypeFontFile
*>(pFrom
)->m_nTypeFlags
;
502 case fonttype::Type1
:
503 static_cast<PrintFontManager::Type1FontFile
*>(pTo
)->m_nDirectory
= static_cast<const PrintFontManager::Type1FontFile
*>(pFrom
)->m_nDirectory
;
504 static_cast<PrintFontManager::Type1FontFile
*>(pTo
)->m_aFontFile
= static_cast<const PrintFontManager::Type1FontFile
*>(pFrom
)->m_aFontFile
;
505 static_cast<PrintFontManager::Type1FontFile
*>(pTo
)->m_aMetricFile
= static_cast<const PrintFontManager::Type1FontFile
*>(pFrom
)->m_aMetricFile
;
507 case fonttype::Builtin
:
508 static_cast<PrintFontManager::BuiltinFont
*>(pTo
)->m_nDirectory
= static_cast<const PrintFontManager::BuiltinFont
*>(pFrom
)->m_nDirectory
;
509 static_cast<PrintFontManager::BuiltinFont
*>(pTo
)->m_aMetricFile
= static_cast<const PrintFontManager::BuiltinFont
*>(pFrom
)->m_aMetricFile
;
513 pTo
->m_nFamilyName
= pFrom
->m_nFamilyName
;
514 pTo
->m_aStyleName
= pFrom
->m_aStyleName
;
515 pTo
->m_aAliases
= pFrom
->m_aAliases
;
516 pTo
->m_nPSName
= pFrom
->m_nPSName
;
517 pTo
->m_eItalic
= pFrom
->m_eItalic
;
518 pTo
->m_eWeight
= pFrom
->m_eWeight
;
519 pTo
->m_eWidth
= pFrom
->m_eWidth
;
520 pTo
->m_ePitch
= pFrom
->m_ePitch
;
521 pTo
->m_aEncoding
= pFrom
->m_aEncoding
;
522 pTo
->m_aGlobalMetricX
= pFrom
->m_aGlobalMetricX
;
523 pTo
->m_aGlobalMetricY
= pFrom
->m_aGlobalMetricY
;
524 pTo
->m_nAscend
= pFrom
->m_nAscend
;
525 pTo
->m_nDescend
= pFrom
->m_nDescend
;
526 pTo
->m_nLeading
= pFrom
->m_nLeading
;
527 pTo
->m_nXMin
= pFrom
->m_nXMin
;
528 pTo
->m_nYMin
= pFrom
->m_nYMin
;
529 pTo
->m_nXMax
= pFrom
->m_nXMax
;
530 pTo
->m_nYMax
= pFrom
->m_nYMax
;
531 pTo
->m_bHaveVerticalSubstitutedGlyphs
= pFrom
->m_bHaveVerticalSubstitutedGlyphs
;
532 pTo
->m_bUserOverride
= pFrom
->m_bUserOverride
;
536 * FontCache::equalsPrintFont
538 bool FontCache::equalsPrintFont( const PrintFontManager::PrintFont
* pLeft
, PrintFontManager::PrintFont
* pRight
) const
540 if( pLeft
->m_eType
!= pRight
->m_eType
)
542 switch( pLeft
->m_eType
)
544 case fonttype::TrueType
:
546 const PrintFontManager::TrueTypeFontFile
* pLT
= static_cast<const PrintFontManager::TrueTypeFontFile
*>(pLeft
);
547 const PrintFontManager::TrueTypeFontFile
* pRT
= static_cast<const PrintFontManager::TrueTypeFontFile
*>(pRight
);
548 if( pRT
->m_nDirectory
!= pLT
->m_nDirectory
||
549 pRT
->m_aFontFile
!= pLT
->m_aFontFile
||
550 pRT
->m_nCollectionEntry
!= pLT
->m_nCollectionEntry
||
551 pRT
->m_nTypeFlags
!= pLT
->m_nTypeFlags
)
555 case fonttype::Type1
:
557 const PrintFontManager::Type1FontFile
* pLT
= static_cast<const PrintFontManager::Type1FontFile
*>(pLeft
);
558 const PrintFontManager::Type1FontFile
* pRT
= static_cast<const PrintFontManager::Type1FontFile
*>(pRight
);
559 if( pRT
->m_nDirectory
!= pLT
->m_nDirectory
||
560 pRT
->m_aFontFile
!= pLT
->m_aFontFile
||
561 pRT
->m_aMetricFile
!= pLT
->m_aMetricFile
)
565 case fonttype::Builtin
:
567 const PrintFontManager::BuiltinFont
* pLT
= static_cast<const PrintFontManager::BuiltinFont
*>(pLeft
);
568 const PrintFontManager::BuiltinFont
* pRT
= static_cast<const PrintFontManager::BuiltinFont
*>(pRight
);
569 if( pRT
->m_nDirectory
!= pLT
->m_nDirectory
||
570 pRT
->m_aMetricFile
!= pLT
->m_aMetricFile
)
576 if( pRight
->m_nFamilyName
!= pLeft
->m_nFamilyName
||
577 pRight
->m_aStyleName
!= pLeft
->m_aStyleName
||
578 pRight
->m_nPSName
!= pLeft
->m_nPSName
||
579 pRight
->m_eItalic
!= pLeft
->m_eItalic
||
580 pRight
->m_eWeight
!= pLeft
->m_eWeight
||
581 pRight
->m_eWidth
!= pLeft
->m_eWidth
||
582 pRight
->m_ePitch
!= pLeft
->m_ePitch
||
583 pRight
->m_aEncoding
!= pLeft
->m_aEncoding
||
584 pRight
->m_aGlobalMetricX
!= pLeft
->m_aGlobalMetricX
||
585 pRight
->m_aGlobalMetricY
!= pLeft
->m_aGlobalMetricY
||
586 pRight
->m_nAscend
!= pLeft
->m_nAscend
||
587 pRight
->m_nDescend
!= pLeft
->m_nDescend
||
588 pRight
->m_nLeading
!= pLeft
->m_nLeading
||
589 pRight
->m_nXMin
!= pLeft
->m_nXMin
||
590 pRight
->m_nYMin
!= pLeft
->m_nYMin
||
591 pRight
->m_nXMax
!= pLeft
->m_nXMax
||
592 pRight
->m_nYMax
!= pLeft
->m_nYMax
||
593 pRight
->m_bHaveVerticalSubstitutedGlyphs
!= pLeft
->m_bHaveVerticalSubstitutedGlyphs
||
594 pRight
->m_bUserOverride
!= pLeft
->m_bUserOverride
597 std::list
< int >::const_iterator lit
, rit
;
598 for( lit
= pLeft
->m_aAliases
.begin(), rit
= pRight
->m_aAliases
.begin();
599 lit
!= pLeft
->m_aAliases
.end() && rit
!= pRight
->m_aAliases
.end() && (*lit
) == (*rit
);
602 return lit
== pLeft
->m_aAliases
.end() && rit
== pRight
->m_aAliases
.end();
606 * FontCache::clonePrintFont
608 PrintFontManager::PrintFont
* FontCache::clonePrintFont( const PrintFontManager::PrintFont
* pOldFont
) const
610 PrintFontManager::PrintFont
* pFont
= NULL
;
611 switch( pOldFont
->m_eType
)
613 case fonttype::TrueType
:
614 pFont
= new PrintFontManager::TrueTypeFontFile();
616 case fonttype::Type1
:
617 pFont
= new PrintFontManager::Type1FontFile();
619 case fonttype::Builtin
:
620 pFont
= new PrintFontManager::BuiltinFont();
626 copyPrintFont( pOldFont
, pFont
);
632 * FontCache::getFontCacheFile
634 bool FontCache::getFontCacheFile( int nDirID
, const OString
& rFile
, list
< PrintFontManager::PrintFont
* >& rNewFonts
) const
636 bool bSuccess
= false;
638 FontCacheData::const_iterator dir
= m_aCache
.find( nDirID
);
639 if( dir
!= m_aCache
.end() )
641 FontDirMap::const_iterator entry
= dir
->second
.m_aEntries
.find( rFile
);
642 if( entry
!= dir
->second
.m_aEntries
.end() )
644 for( FontCacheEntry::const_iterator font
= entry
->second
.m_aEntry
.begin(); font
!= entry
->second
.m_aEntry
.end(); ++font
)
647 PrintFontManager::PrintFont
* pFont
= clonePrintFont( *font
);
648 rNewFonts
.push_back( pFont
);
656 * FontCache::updateFontCacheEntry
658 void FontCache::updateFontCacheEntry( const PrintFontManager::PrintFont
* pFont
, bool bFlush
)
662 switch( pFont
->m_eType
)
664 case fonttype::TrueType
:
665 nDirID
= static_cast<const PrintFontManager::TrueTypeFontFile
*>(pFont
)->m_nDirectory
;
666 aFile
= static_cast<const PrintFontManager::TrueTypeFontFile
*>(pFont
)->m_aFontFile
;
668 case fonttype::Type1
:
669 nDirID
= static_cast<const PrintFontManager::Type1FontFile
*>(pFont
)->m_nDirectory
;
670 aFile
= static_cast<const PrintFontManager::Type1FontFile
*>(pFont
)->m_aFontFile
;
672 case fonttype::Builtin
:
673 nDirID
= static_cast<const PrintFontManager::BuiltinFont
*>(pFont
)->m_nDirectory
;
674 aFile
= static_cast<const PrintFontManager::BuiltinFont
*>(pFont
)->m_aMetricFile
;
679 FontCacheData::const_iterator dir
= m_aCache
.find( nDirID
);
680 FontDirMap::const_iterator entry
;
681 FontCacheEntry::const_iterator font
;
682 PrintFontManager::PrintFont
* pCacheFont
= NULL
;
684 if( dir
!= m_aCache
.end() )
686 entry
= dir
->second
.m_aEntries
.find( aFile
);
687 if( entry
!= dir
->second
.m_aEntries
.end() )
689 for( font
= entry
->second
.m_aEntry
.begin(); font
!= entry
->second
.m_aEntry
.end(); ++font
)
691 if( (*font
)->m_eType
== pFont
->m_eType
&&
692 ( (*font
)->m_eType
!= fonttype::TrueType
||
693 static_cast<const PrintFontManager::TrueTypeFontFile
*>(*font
)->m_nCollectionEntry
== static_cast<const PrintFontManager::TrueTypeFontFile
*>(pFont
)->m_nCollectionEntry
697 if( font
!= entry
->second
.m_aEntry
.end() )
702 createCacheDir( nDirID
);
706 if( ! equalsPrintFont( pFont
, pCacheFont
) )
708 copyPrintFont( pFont
, pCacheFont
);
714 pCacheFont
= clonePrintFont( pFont
);
715 m_aCache
[nDirID
].m_aEntries
[aFile
].m_aEntry
.push_back( pCacheFont
);
723 * FontCache::listDirectory
725 bool FontCache::listDirectory( const OString
& rDir
, std::list
< PrintFontManager::PrintFont
* >& rNewFonts
) const
727 PrintFontManager
& rManager( PrintFontManager::get() );
728 int nDirID
= rManager
.getDirectoryAtom( rDir
);
730 FontCacheData::const_iterator dir
= m_aCache
.find( nDirID
);
731 bool bFound
= (dir
!= m_aCache
.end());
733 if( bFound
&& !dir
->second
.m_bNoFiles
)
735 for( FontDirMap::const_iterator file
= dir
->second
.m_aEntries
.begin(); file
!= dir
->second
.m_aEntries
.end(); ++file
)
737 for( FontCacheEntry::const_iterator font
= file
->second
.m_aEntry
.begin(); font
!= file
->second
.m_aEntry
.end(); ++font
)
739 PrintFontManager::PrintFont
* pFont
= clonePrintFont( *font
);
740 rNewFonts
.push_back( pFont
);
748 * FontCache::listDirectory
750 bool FontCache::scanAdditionalFiles( const OString
& rDir
)
752 PrintFontManager
& rManager( PrintFontManager::get() );
753 int nDirID
= rManager
.getDirectoryAtom( rDir
);
754 FontCacheData::const_iterator dir
= m_aCache
.find( nDirID
);
755 bool bFound
= (dir
!= m_aCache
.end());
757 return (bFound
&& dir
->second
.m_bUserOverrideOnly
);
761 * FontCache::createCacheDir
763 void FontCache::createCacheDir( int nDirID
)
765 PrintFontManager
& rManager( PrintFontManager::get() );
767 const OString
& rDir
= rManager
.getDirectory( nDirID
);
769 if( ! stat( rDir
.getStr(), &aStat
) )
770 m_aCache
[nDirID
].m_nTimestamp
= (sal_Int64
)aStat
.st_mtime
;
774 * FontCache::markEmptyDir
776 void FontCache::markEmptyDir( int nDirID
, bool bNoFiles
)
778 createCacheDir( nDirID
);
779 m_aCache
[nDirID
].m_bNoFiles
= bNoFiles
;
783 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */