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"
48 using ::rtl::OUString
;
50 using ::rtl::OUStringToOString
;
53 * FontCache constructor
56 FontCache::FontCache()
59 m_aCacheFile
= getOfficePath( UserPath
);
60 if( m_aCacheFile
.Len() )
62 m_aCacheFile
.AppendAscii( FONTCACHEFILE
);
68 * FontCache destructor
71 FontCache::~FontCache()
77 * FontCache::clearCache
79 void FontCache::clearCache()
81 for( FontCacheData::iterator dir_it
= m_aCache
.begin(); dir_it
!= m_aCache
.end(); ++dir_it
)
83 for( FontDirMap::iterator entry_it
= dir_it
->second
.m_aEntries
.begin(); entry_it
!= dir_it
->second
.m_aEntries
.end(); ++entry_it
)
85 for( FontCacheEntry::iterator font_it
= entry_it
->second
.m_aEntry
.begin(); font_it
!= entry_it
->second
.m_aEntry
.end(); ++font_it
)
96 void FontCache::flush()
98 if( ! m_bDoFlush
|| ! m_aCacheFile
.Len() )
101 SvFileStream aStream
;
102 aStream
.Open( m_aCacheFile
, STREAM_WRITE
| STREAM_TRUNC
);
103 if( ! (aStream
.IsOpen() && aStream
.IsWritable()) )
105 #if OSL_DEBUG_LEVEL > 1
106 fprintf( stderr
, "FontCache::flush: opening cache file %s failed\n", rtl::OUStringToOString(m_aCacheFile
, osl_getThreadTextEncoding()).getStr() );
111 aStream
.SetLineDelimiter( LINEEND_LF
);
112 aStream
.WriteLine(rtl::OString(RTL_CONSTASCII_STRINGPARAM(CACHE_MAGIC
)));
114 PrintFontManager
& rManager( PrintFontManager::get() );
115 MultiAtomProvider
* pAtoms
= rManager
.m_pAtoms
;
117 for( FontCacheData::const_iterator dir_it
= m_aCache
.begin(); dir_it
!= m_aCache
.end(); ++ dir_it
)
119 const FontDirMap
& rDir( dir_it
->second
.m_aEntries
);
121 rtl::OString
aDirectory(rManager
.getDirectory(dir_it
->first
));
122 rtl::OStringBuffer
aLine(
123 RTL_CONSTASCII_STRINGPARAM("FontCacheDirectory:"));
124 aLine
.append(dir_it
->second
.m_nTimestamp
);
126 aLine
.append(aDirectory
);
127 if( rDir
.empty() && dir_it
->second
.m_bNoFiles
)
128 aLine
.insert(0, RTL_CONSTASCII_STRINGPARAM("Empty"));
129 aStream
.WriteLine(aLine
.makeStringAndClear());
131 for( FontDirMap::const_iterator entry_it
= rDir
.begin(); entry_it
!= rDir
.end(); ++entry_it
)
133 // insert cache entries
134 const FontCacheEntry
& rEntry( entry_it
->second
.m_aEntry
);
135 if( rEntry
.begin() == rEntry
.end() )
138 aLine
.append(RTL_CONSTASCII_STRINGPARAM("File:"));
139 aLine
.append(entry_it
->first
);
140 aStream
.WriteLine(aLine
.makeStringAndClear());
142 int nEntrySize
= entry_it
->second
.m_aEntry
.size();
143 // write: type;nfonts
144 aLine
.append(static_cast<sal_Int32
>(rEntry
.front()->m_eType
));
146 aLine
.append(static_cast<sal_Int32
>(nEntrySize
));
147 aStream
.WriteLine(aLine
.makeStringAndClear());
149 sal_Int32 nSubEntry
= 0;
150 for( FontCacheEntry::const_iterator it
= rEntry
.begin(); it
!= rEntry
.end(); ++it
, nSubEntry
++ )
153 * for each font entry write:
155 * fontnr;PSName;italic;weight;width;pitch;encoding;ascend;descend;leading;vsubst;gxw;gxh;gyw;gyh;useroverrride;embed;antialias[;{metricfile,typeflags}][;stylename]
158 nSubEntry
= static_cast<const PrintFontManager::TrueTypeFontFile
*>(*it
)->m_nCollectionEntry
;
162 aLine
.append(OUStringToOString(pAtoms
->getString( ATOM_FAMILYNAME
, (*it
)->m_nFamilyName
), RTL_TEXTENCODING_UTF8
));
163 for( ::std::list
< int >::const_iterator name_it
= (*it
)->m_aAliases
.begin(); name_it
!= (*it
)->m_aAliases
.end(); ++name_it
)
165 const OUString
& rAdd( pAtoms
->getString( ATOM_FAMILYNAME
, *name_it
) );
166 if( !rAdd
.isEmpty() )
169 aLine
.append(OUStringToOString(rAdd
, RTL_TEXTENCODING_UTF8
));
172 aStream
.WriteLine(aLine
.makeStringAndClear());
174 const OUString
& rPSName( pAtoms
->getString( ATOM_PSNAME
, (*it
)->m_nPSName
) );
175 aLine
.append(nSubEntry
);
177 aLine
.append(OUStringToOString(rPSName
, RTL_TEXTENCODING_UTF8
));
179 aLine
.append(static_cast<sal_Int32
>((*it
)->m_eItalic
));
181 aLine
.append(static_cast<sal_Int32
>((*it
)->m_eWeight
));
183 aLine
.append(static_cast<sal_Int32
>((*it
)->m_eWidth
));
185 aLine
.append(static_cast<sal_Int32
>((*it
)->m_ePitch
));
187 aLine
.append(static_cast<sal_Int32
>((*it
)->m_aEncoding
));
189 aLine
.append(static_cast<sal_Int32
>((*it
)->m_nAscend
));
191 aLine
.append(static_cast<sal_Int32
>((*it
)->m_nDescend
));
193 aLine
.append(static_cast<sal_Int32
>((*it
)->m_nLeading
));
195 aLine
.append((*it
)->m_bHaveVerticalSubstitutedGlyphs
? '1' : '0');
197 aLine
.append(static_cast<sal_Int32
>((*it
)->m_aGlobalMetricX
.width
));
199 aLine
.append(static_cast<sal_Int32
>((*it
)->m_aGlobalMetricX
.height
));
201 aLine
.append(static_cast<sal_Int32
>((*it
)->m_aGlobalMetricY
.width
));
203 aLine
.append(static_cast<sal_Int32
>((*it
)->m_aGlobalMetricY
.height
));
205 aLine
.append((*it
)->m_bUserOverride
? '1' : '0');
207 aLine
.append(static_cast<sal_Int32
>(0));
209 aLine
.append(static_cast<sal_Int32
>(0));
211 switch( (*it
)->m_eType
)
213 case fonttype::Type1
:
215 aLine
.append(static_cast<const PrintFontManager::Type1FontFile
*>(*it
)->m_aMetricFile
);
217 case fonttype::TrueType
:
219 aLine
.append(static_cast<sal_Int32
>(static_cast<const PrintFontManager::TrueTypeFontFile
*>(*it
)->m_nTypeFlags
));
223 if( !(*it
)->m_aStyleName
.isEmpty() )
226 aLine
.append(OUStringToOString((*it
)->m_aStyleName
, RTL_TEXTENCODING_UTF8
));
228 aStream
.WriteLine(aLine
.makeStringAndClear());
230 aStream
.WriteLine(rtl::OString());
240 void FontCache::read()
242 PrintFontManager
& rManager( PrintFontManager::get() );
243 MultiAtomProvider
* pAtoms
= rManager
.m_pAtoms
;
245 SvFileStream
aStream( m_aCacheFile
, STREAM_READ
);
246 if( ! aStream
.IsOpen() )
248 #if OSL_DEBUG_LEVEL > 1
249 fprintf( stderr
, "FontCache::read: opening cache file %s failed\n", rtl::OUStringToOString(m_aCacheFile
, osl_getThreadTextEncoding()).getStr() );
256 aStream
.ReadLine( aLine
);
257 if (!aLine
.equalsL(RTL_CONSTASCII_STRINGPARAM(CACHE_MAGIC
)))
259 #if OSL_DEBUG_LEVEL >1
260 fprintf( stderr
, "FontCache::read: cache file %s fails magic test\n", rtl::OUStringToOString(m_aCacheFile
, osl_getThreadTextEncoding()).getStr() );
266 FontDirMap
* pDir
= NULL
;
267 bool bKeepOnlyUserOverridden
= false;
270 aStream
.ReadLine( aLine
);
271 if( aLine
.compareTo( RTL_CONSTASCII_STRINGPARAM( "FontCacheDirectory:" ) ) == 0 ||
272 aLine
.compareTo( RTL_CONSTASCII_STRINGPARAM( "EmptyFontCacheDirectory:" ) ) == 0 )
274 bool bEmpty
= (aLine
.compareTo( RTL_CONSTASCII_STRINGPARAM ("Empty" ) ) == 0);
275 sal_Int32 nSearchIndex
= bEmpty
? 24 : 19;
278 sal_Int64 nTimestamp
= 0;
279 sal_Int32 nTEnd
= aLine
.indexOf( ':', nSearchIndex
);
282 rtl::OString aTimeStamp
= aLine
.copy( nSearchIndex
, nTEnd
- nSearchIndex
);
283 nTimestamp
= aTimeStamp
.toInt64();
284 aDir
= aLine
.copy( nTEnd
+1 );
288 // invalid format, remove
295 // is the directory modified ?
297 if( stat( aDir
.getStr(), &aStat
) ||
298 ! S_ISDIR(aStat
.st_mode
) )
300 // remove outdated cache data
308 nDir
= rManager
.getDirectoryAtom( aDir
, true );
309 m_aCache
[ nDir
].m_nTimestamp
= (sal_Int64
)aStat
.st_mtime
;
310 m_aCache
[ nDir
].m_bNoFiles
= bEmpty
;
311 pDir
= bEmpty
? NULL
: &m_aCache
[ nDir
].m_aEntries
;
312 bKeepOnlyUserOverridden
= ((sal_Int64
)aStat
.st_mtime
!= nTimestamp
);
313 m_aCache
[ nDir
].m_bUserOverrideOnly
= bKeepOnlyUserOverridden
;
316 else if( pDir
&& aLine
.compareTo( RTL_CONSTASCII_STRINGPARAM( "File:" ) ) == 0 )
318 OString
aFile( aLine
.copy( 5 ) );
319 aStream
.ReadLine( aLine
);
321 const char* pLine
= aLine
.getStr();
323 fonttype::type eType
= (fonttype::type
)atoi( pLine
);
324 if( eType
!= fonttype::TrueType
&&
325 eType
!= fonttype::Type1
&&
326 eType
!= fonttype::Builtin
329 while( *pLine
&& *pLine
!= ';' )
335 sal_Int32 nFonts
= atoi( pLine
);
336 for( int n
= 0; n
< nFonts
; n
++ )
338 aStream
.ReadLine( aLine
);
339 pLine
= aLine
.getStr();
340 int nLen
= aLine
.getLength();
342 PrintFontManager::PrintFont
* pFont
= NULL
;
345 case fonttype::TrueType
:
346 pFont
= new PrintFontManager::TrueTypeFontFile();
348 case fonttype::Type1
:
349 pFont
= new PrintFontManager::Type1FontFile();
351 case fonttype::Builtin
:
352 pFont
= new PrintFontManager::BuiltinFont();
359 for( nIndex
= 0; nIndex
< nLen
&& pLine
[nIndex
] != ';'; nIndex
++ )
362 pFont
->m_nFamilyName
= pAtoms
->getAtom( ATOM_FAMILYNAME
,
363 OUString( pLine
, nIndex
, RTL_TEXTENCODING_UTF8
),
365 while( nIndex
< nLen
)
367 sal_Int32 nLastIndex
= nIndex
+1;
368 for( nIndex
= nLastIndex
; nIndex
< nLen
&& pLine
[nIndex
] != ';'; nIndex
++ )
370 if( nIndex
- nLastIndex
)
372 OUString
aAlias( pLine
+nLastIndex
, nIndex
-nLastIndex
, RTL_TEXTENCODING_UTF8
);
373 pFont
->m_aAliases
.push_back( pAtoms
->getAtom( ATOM_FAMILYNAME
, aAlias
, sal_True
) );
376 aStream
.ReadLine( aLine
);
377 pLine
= aLine
.getStr();
378 nLen
= aLine
.getLength();
380 // get up to 20 token positions
381 const int nMaxTokens
= 20;
382 int nTokenPos
[nMaxTokens
];
385 for( int i
= 0; i
< nLen
; i
++ )
387 if( pLine
[i
] == ';' )
389 nTokenPos
[nTokens
++] = i
+1;
390 if( nTokens
== nMaxTokens
)
399 int nCollEntry
= atoi( pLine
);
400 pFont
->m_nPSName
= pAtoms
->getAtom( ATOM_PSNAME
, OUString( pLine
+ nTokenPos
[1], nTokenPos
[2]-nTokenPos
[1]-1, RTL_TEXTENCODING_UTF8
), sal_True
);
401 pFont
->m_eItalic
= (FontItalic
)atoi( pLine
+nTokenPos
[2] );
402 pFont
->m_eWeight
= (FontWeight
)atoi( pLine
+nTokenPos
[3] );
403 pFont
->m_eWidth
= (FontWidth
)atoi( pLine
+nTokenPos
[4] );
404 pFont
->m_ePitch
= (FontPitch
)atoi( pLine
+nTokenPos
[5] );
405 pFont
->m_aEncoding
= (rtl_TextEncoding
)atoi( pLine
+nTokenPos
[6] );
406 pFont
->m_nAscend
= atoi( pLine
+ nTokenPos
[7] );
407 pFont
->m_nDescend
= atoi( pLine
+ nTokenPos
[8] );
408 pFont
->m_nLeading
= atoi( pLine
+ nTokenPos
[9] );
409 pFont
->m_bHaveVerticalSubstitutedGlyphs
410 = (atoi( pLine
+ nTokenPos
[10] ) != 0);
411 pFont
->m_aGlobalMetricX
.width
412 = atoi( pLine
+ nTokenPos
[11] );
413 pFont
->m_aGlobalMetricX
.height
414 = atoi( pLine
+ nTokenPos
[12] );
415 pFont
->m_aGlobalMetricY
.width
416 = atoi( pLine
+ nTokenPos
[13] );
417 pFont
->m_aGlobalMetricY
.height
418 = atoi( pLine
+ nTokenPos
[14] );
419 pFont
->m_bUserOverride
420 = (atoi( pLine
+ nTokenPos
[15] ) != 0);
421 int nStyleTokenNr
= 18;
424 case fonttype::TrueType
:
425 static_cast<PrintFontManager::TrueTypeFontFile
*>(pFont
)->m_nTypeFlags
= atoi( pLine
+ nTokenPos
[18] );
426 static_cast<PrintFontManager::TrueTypeFontFile
*>(pFont
)->m_nCollectionEntry
= nCollEntry
;
427 static_cast<PrintFontManager::TrueTypeFontFile
*>(pFont
)->m_nDirectory
= nDir
;
428 static_cast<PrintFontManager::TrueTypeFontFile
*>(pFont
)->m_aFontFile
= aFile
;
431 case fonttype::Type1
:
433 int nTokLen
= (nTokens
> 19 ) ? nTokenPos
[19]-nTokenPos
[18]-1 : nLen
- nTokenPos
[18];
434 static_cast<PrintFontManager::Type1FontFile
*>(pFont
)->m_aMetricFile
= OString( pLine
+ nTokenPos
[18], nTokLen
);
435 static_cast<PrintFontManager::Type1FontFile
*>(pFont
)->m_nDirectory
= nDir
;
436 static_cast<PrintFontManager::Type1FontFile
*>(pFont
)->m_aFontFile
= aFile
;
440 case fonttype::Builtin
:
441 static_cast<PrintFontManager::BuiltinFont
*>(pFont
)->m_nDirectory
= nDir
;
442 static_cast<PrintFontManager::BuiltinFont
*>(pFont
)->m_aMetricFile
= aFile
;
446 if( nTokens
> nStyleTokenNr
)
447 pFont
->m_aStyleName
= OUString::intern( pLine
+ nTokenPos
[nStyleTokenNr
],
448 nLen
- nTokenPos
[nStyleTokenNr
],
449 RTL_TEXTENCODING_UTF8
);
451 bool bObsolete
= false;
452 if( bKeepOnlyUserOverridden
)
454 if( pFont
->m_bUserOverride
)
456 rtl::OStringBuffer
aFilePath(rManager
.getDirectory(nDir
));
457 aFilePath
.append('/').append(aFile
);
459 if( stat( aFilePath
.getStr(), &aStat
) ||
460 ! S_ISREG( aStat
.st_mode
) ||
465 #if OSL_DEBUG_LEVEL > 2
467 fprintf( stderr
, "keeping file %s in outdated cache entry due to user override\n",
468 aFilePath
.getStr() );
477 #if OSL_DEBUG_LEVEL > 2
478 fprintf( stderr
, "removing obsolete font %s\n", aFile
.getStr() );
484 FontCacheEntry
& rEntry
= (*pDir
)[aFile
].m_aEntry
;
485 rEntry
.push_back( pFont
);
488 } while( ! aStream
.IsEof() );
492 * FontCache::copyPrintFont
494 void FontCache::copyPrintFont( const PrintFontManager::PrintFont
* pFrom
, PrintFontManager::PrintFont
* pTo
) const
496 if( pFrom
->m_eType
!= pTo
->m_eType
)
498 switch( pFrom
->m_eType
)
500 case fonttype::TrueType
:
501 static_cast<PrintFontManager::TrueTypeFontFile
*>(pTo
)->m_nDirectory
= static_cast<const PrintFontManager::TrueTypeFontFile
*>(pFrom
)->m_nDirectory
;
502 static_cast<PrintFontManager::TrueTypeFontFile
*>(pTo
)->m_aFontFile
= static_cast<const PrintFontManager::TrueTypeFontFile
*>(pFrom
)->m_aFontFile
;
503 static_cast<PrintFontManager::TrueTypeFontFile
*>(pTo
)->m_nCollectionEntry
= static_cast<const PrintFontManager::TrueTypeFontFile
*>(pFrom
)->m_nCollectionEntry
;
504 static_cast<PrintFontManager::TrueTypeFontFile
*>(pTo
)->m_nTypeFlags
= static_cast<const PrintFontManager::TrueTypeFontFile
*>(pFrom
)->m_nTypeFlags
;
506 case fonttype::Type1
:
507 static_cast<PrintFontManager::Type1FontFile
*>(pTo
)->m_nDirectory
= static_cast<const PrintFontManager::Type1FontFile
*>(pFrom
)->m_nDirectory
;
508 static_cast<PrintFontManager::Type1FontFile
*>(pTo
)->m_aFontFile
= static_cast<const PrintFontManager::Type1FontFile
*>(pFrom
)->m_aFontFile
;
509 static_cast<PrintFontManager::Type1FontFile
*>(pTo
)->m_aMetricFile
= static_cast<const PrintFontManager::Type1FontFile
*>(pFrom
)->m_aMetricFile
;
511 case fonttype::Builtin
:
512 static_cast<PrintFontManager::BuiltinFont
*>(pTo
)->m_nDirectory
= static_cast<const PrintFontManager::BuiltinFont
*>(pFrom
)->m_nDirectory
;
513 static_cast<PrintFontManager::BuiltinFont
*>(pTo
)->m_aMetricFile
= static_cast<const PrintFontManager::BuiltinFont
*>(pFrom
)->m_aMetricFile
;
517 pTo
->m_nFamilyName
= pFrom
->m_nFamilyName
;
518 pTo
->m_aStyleName
= pFrom
->m_aStyleName
;
519 pTo
->m_aAliases
= pFrom
->m_aAliases
;
520 pTo
->m_nPSName
= pFrom
->m_nPSName
;
521 pTo
->m_eItalic
= pFrom
->m_eItalic
;
522 pTo
->m_eWeight
= pFrom
->m_eWeight
;
523 pTo
->m_eWidth
= pFrom
->m_eWidth
;
524 pTo
->m_ePitch
= pFrom
->m_ePitch
;
525 pTo
->m_aEncoding
= pFrom
->m_aEncoding
;
526 pTo
->m_aGlobalMetricX
= pFrom
->m_aGlobalMetricX
;
527 pTo
->m_aGlobalMetricY
= pFrom
->m_aGlobalMetricY
;
528 pTo
->m_nAscend
= pFrom
->m_nAscend
;
529 pTo
->m_nDescend
= pFrom
->m_nDescend
;
530 pTo
->m_nLeading
= pFrom
->m_nLeading
;
531 pTo
->m_nXMin
= pFrom
->m_nXMin
;
532 pTo
->m_nYMin
= pFrom
->m_nYMin
;
533 pTo
->m_nXMax
= pFrom
->m_nXMax
;
534 pTo
->m_nYMax
= pFrom
->m_nYMax
;
535 pTo
->m_bHaveVerticalSubstitutedGlyphs
= pFrom
->m_bHaveVerticalSubstitutedGlyphs
;
536 pTo
->m_bUserOverride
= pFrom
->m_bUserOverride
;
540 * FontCache::equalsPrintFont
542 bool FontCache::equalsPrintFont( const PrintFontManager::PrintFont
* pLeft
, PrintFontManager::PrintFont
* pRight
) const
544 if( pLeft
->m_eType
!= pRight
->m_eType
)
546 switch( pLeft
->m_eType
)
548 case fonttype::TrueType
:
550 const PrintFontManager::TrueTypeFontFile
* pLT
= static_cast<const PrintFontManager::TrueTypeFontFile
*>(pLeft
);
551 const PrintFontManager::TrueTypeFontFile
* pRT
= static_cast<const PrintFontManager::TrueTypeFontFile
*>(pRight
);
552 if( pRT
->m_nDirectory
!= pLT
->m_nDirectory
||
553 pRT
->m_aFontFile
!= pLT
->m_aFontFile
||
554 pRT
->m_nCollectionEntry
!= pLT
->m_nCollectionEntry
||
555 pRT
->m_nTypeFlags
!= pLT
->m_nTypeFlags
)
559 case fonttype::Type1
:
561 const PrintFontManager::Type1FontFile
* pLT
= static_cast<const PrintFontManager::Type1FontFile
*>(pLeft
);
562 const PrintFontManager::Type1FontFile
* pRT
= static_cast<const PrintFontManager::Type1FontFile
*>(pRight
);
563 if( pRT
->m_nDirectory
!= pLT
->m_nDirectory
||
564 pRT
->m_aFontFile
!= pLT
->m_aFontFile
||
565 pRT
->m_aMetricFile
!= pLT
->m_aMetricFile
)
569 case fonttype::Builtin
:
571 const PrintFontManager::BuiltinFont
* pLT
= static_cast<const PrintFontManager::BuiltinFont
*>(pLeft
);
572 const PrintFontManager::BuiltinFont
* pRT
= static_cast<const PrintFontManager::BuiltinFont
*>(pRight
);
573 if( pRT
->m_nDirectory
!= pLT
->m_nDirectory
||
574 pRT
->m_aMetricFile
!= pLT
->m_aMetricFile
)
580 if( pRight
->m_nFamilyName
!= pLeft
->m_nFamilyName
||
581 pRight
->m_aStyleName
!= pLeft
->m_aStyleName
||
582 pRight
->m_nPSName
!= pLeft
->m_nPSName
||
583 pRight
->m_eItalic
!= pLeft
->m_eItalic
||
584 pRight
->m_eWeight
!= pLeft
->m_eWeight
||
585 pRight
->m_eWidth
!= pLeft
->m_eWidth
||
586 pRight
->m_ePitch
!= pLeft
->m_ePitch
||
587 pRight
->m_aEncoding
!= pLeft
->m_aEncoding
||
588 pRight
->m_aGlobalMetricX
!= pLeft
->m_aGlobalMetricX
||
589 pRight
->m_aGlobalMetricY
!= pLeft
->m_aGlobalMetricY
||
590 pRight
->m_nAscend
!= pLeft
->m_nAscend
||
591 pRight
->m_nDescend
!= pLeft
->m_nDescend
||
592 pRight
->m_nLeading
!= pLeft
->m_nLeading
||
593 pRight
->m_nXMin
!= pLeft
->m_nXMin
||
594 pRight
->m_nYMin
!= pLeft
->m_nYMin
||
595 pRight
->m_nXMax
!= pLeft
->m_nXMax
||
596 pRight
->m_nYMax
!= pLeft
->m_nYMax
||
597 pRight
->m_bHaveVerticalSubstitutedGlyphs
!= pLeft
->m_bHaveVerticalSubstitutedGlyphs
||
598 pRight
->m_bUserOverride
!= pLeft
->m_bUserOverride
601 std::list
< int >::const_iterator lit
, rit
;
602 for( lit
= pLeft
->m_aAliases
.begin(), rit
= pRight
->m_aAliases
.begin();
603 lit
!= pLeft
->m_aAliases
.end() && rit
!= pRight
->m_aAliases
.end() && (*lit
) == (*rit
);
606 return lit
== pLeft
->m_aAliases
.end() && rit
== pRight
->m_aAliases
.end();
610 * FontCache::clonePrintFont
612 PrintFontManager::PrintFont
* FontCache::clonePrintFont( const PrintFontManager::PrintFont
* pOldFont
) const
614 PrintFontManager::PrintFont
* pFont
= NULL
;
615 switch( pOldFont
->m_eType
)
617 case fonttype::TrueType
:
618 pFont
= new PrintFontManager::TrueTypeFontFile();
620 case fonttype::Type1
:
621 pFont
= new PrintFontManager::Type1FontFile();
623 case fonttype::Builtin
:
624 pFont
= new PrintFontManager::BuiltinFont();
630 copyPrintFont( pOldFont
, pFont
);
636 * FontCache::getFontCacheFile
638 bool FontCache::getFontCacheFile( int nDirID
, const OString
& rFile
, list
< PrintFontManager::PrintFont
* >& rNewFonts
) const
640 bool bSuccess
= false;
642 FontCacheData::const_iterator dir
= m_aCache
.find( nDirID
);
643 if( dir
!= m_aCache
.end() )
645 FontDirMap::const_iterator entry
= dir
->second
.m_aEntries
.find( rFile
);
646 if( entry
!= dir
->second
.m_aEntries
.end() )
648 for( FontCacheEntry::const_iterator font
= entry
->second
.m_aEntry
.begin(); font
!= entry
->second
.m_aEntry
.end(); ++font
)
651 PrintFontManager::PrintFont
* pFont
= clonePrintFont( *font
);
652 rNewFonts
.push_back( pFont
);
660 * FontCache::updateFontCacheEntry
662 void FontCache::updateFontCacheEntry( const PrintFontManager::PrintFont
* pFont
, bool bFlush
)
666 switch( pFont
->m_eType
)
668 case fonttype::TrueType
:
669 nDirID
= static_cast<const PrintFontManager::TrueTypeFontFile
*>(pFont
)->m_nDirectory
;
670 aFile
= static_cast<const PrintFontManager::TrueTypeFontFile
*>(pFont
)->m_aFontFile
;
672 case fonttype::Type1
:
673 nDirID
= static_cast<const PrintFontManager::Type1FontFile
*>(pFont
)->m_nDirectory
;
674 aFile
= static_cast<const PrintFontManager::Type1FontFile
*>(pFont
)->m_aFontFile
;
676 case fonttype::Builtin
:
677 nDirID
= static_cast<const PrintFontManager::BuiltinFont
*>(pFont
)->m_nDirectory
;
678 aFile
= static_cast<const PrintFontManager::BuiltinFont
*>(pFont
)->m_aMetricFile
;
683 FontCacheData::const_iterator dir
= m_aCache
.find( nDirID
);
684 FontDirMap::const_iterator entry
;
685 FontCacheEntry::const_iterator font
;
686 PrintFontManager::PrintFont
* pCacheFont
= NULL
;
688 if( dir
!= m_aCache
.end() )
690 entry
= dir
->second
.m_aEntries
.find( aFile
);
691 if( entry
!= dir
->second
.m_aEntries
.end() )
693 for( font
= entry
->second
.m_aEntry
.begin(); font
!= entry
->second
.m_aEntry
.end(); ++font
)
695 if( (*font
)->m_eType
== pFont
->m_eType
&&
696 ( (*font
)->m_eType
!= fonttype::TrueType
||
697 static_cast<const PrintFontManager::TrueTypeFontFile
*>(*font
)->m_nCollectionEntry
== static_cast<const PrintFontManager::TrueTypeFontFile
*>(pFont
)->m_nCollectionEntry
701 if( font
!= entry
->second
.m_aEntry
.end() )
706 createCacheDir( nDirID
);
710 if( ! equalsPrintFont( pFont
, pCacheFont
) )
712 copyPrintFont( pFont
, pCacheFont
);
718 pCacheFont
= clonePrintFont( pFont
);
719 m_aCache
[nDirID
].m_aEntries
[aFile
].m_aEntry
.push_back( pCacheFont
);
727 * FontCache::listDirectory
729 bool FontCache::listDirectory( const OString
& rDir
, std::list
< PrintFontManager::PrintFont
* >& rNewFonts
) const
731 PrintFontManager
& rManager( PrintFontManager::get() );
732 int nDirID
= rManager
.getDirectoryAtom( rDir
);
733 FontCacheData::const_iterator dir
= m_aCache
.find( nDirID
);
734 bool bFound
= (dir
!= m_aCache
.end());
736 if( bFound
&& !dir
->second
.m_bNoFiles
)
738 for( FontDirMap::const_iterator file
= dir
->second
.m_aEntries
.begin(); file
!= dir
->second
.m_aEntries
.end(); ++file
)
740 for( FontCacheEntry::const_iterator font
= file
->second
.m_aEntry
.begin(); font
!= file
->second
.m_aEntry
.end(); ++font
)
742 PrintFontManager::PrintFont
* pFont
= clonePrintFont( *font
);
743 rNewFonts
.push_back( pFont
);
751 * FontCache::listDirectory
753 bool FontCache::scanAdditionalFiles( const OString
& rDir
)
755 PrintFontManager
& rManager( PrintFontManager::get() );
756 int nDirID
= rManager
.getDirectoryAtom( rDir
);
757 FontCacheData::const_iterator dir
= m_aCache
.find( nDirID
);
758 bool bFound
= (dir
!= m_aCache
.end());
760 return (bFound
&& dir
->second
.m_bUserOverrideOnly
);
764 * FontCache::createCacheDir
766 void FontCache::createCacheDir( int nDirID
)
768 PrintFontManager
& rManager( PrintFontManager::get() );
770 const OString
& rDir
= rManager
.getDirectory( nDirID
);
772 if( ! stat( rDir
.getStr(), &aStat
) )
773 m_aCache
[nDirID
].m_nTimestamp
= (sal_Int64
)aStat
.st_mtime
;
777 * FontCache::markEmptyDir
779 void FontCache::markEmptyDir( int nDirID
, bool bNoFiles
)
781 createCacheDir( nDirID
);
782 m_aCache
[nDirID
].m_bNoFiles
= bNoFiles
;
786 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */