1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: fontcache.cxx,v $
11 * This file is part of OpenOffice.org.
13 * OpenOffice.org is free software: you can redistribute it and/or modify
14 * it under the terms of the GNU Lesser General Public License version 3
15 * only, as published by the Free Software Foundation.
17 * OpenOffice.org is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU Lesser General Public License version 3 for more details
21 * (a copy is included in the LICENSE file that accompanied this code).
23 * You should have received a copy of the GNU Lesser General Public License
24 * version 3 along with OpenOffice.org. If not, see
25 * <http://www.openoffice.org/license.html>
26 * for a copy of the LGPLv3 License.
28 ************************************************************************/
30 // MARKER(update_precomp.py): autogen include statement, do not remove
31 #include "precompiled_vcl.hxx"
36 #include "vcl/fontcache.hxx"
38 #include "osl/thread.h"
40 #include "unotools/atom.hxx"
42 #include "tools/stream.hxx"
47 #if OSL_DEBUG_LEVEL >1
51 #define FONTCACHEFILE "/user/psprint/pspfontcache"
52 #define CACHE_MAGIC "PspFontCacheFile format 4"
64 * FontCache constructor
67 FontCache::FontCache()
70 m_aCacheFile
= getOfficePath( UserPath
);
71 if( m_aCacheFile
.Len() )
73 m_aCacheFile
.AppendAscii( FONTCACHEFILE
);
79 * FontCache destructor
82 FontCache::~FontCache()
88 * FontCache::clearCache
90 void FontCache::clearCache()
92 for( FontCacheData::iterator dir_it
= m_aCache
.begin(); dir_it
!= m_aCache
.end(); ++dir_it
)
94 for( FontDirMap::iterator entry_it
= dir_it
->second
.m_aEntries
.begin(); entry_it
!= dir_it
->second
.m_aEntries
.end(); ++entry_it
)
96 for( FontCacheEntry::iterator font_it
= entry_it
->second
.m_aEntry
.begin(); font_it
!= entry_it
->second
.m_aEntry
.end(); ++font_it
)
107 void FontCache::flush()
109 if( ! m_bDoFlush
|| ! m_aCacheFile
.Len() )
112 SvFileStream aStream
;
113 aStream
.Open( m_aCacheFile
, STREAM_WRITE
| STREAM_TRUNC
);
114 if( ! (aStream
.IsOpen() && aStream
.IsWritable()) )
116 #if OSL_DEBUG_LEVEL > 1
117 fprintf( stderr
, "FontCache::flush: opening cache file %s failed\n", ByteString( m_aCacheFile
, osl_getThreadTextEncoding() ).GetBuffer() );
122 aStream
.SetLineDelimiter( LINEEND_LF
);
123 aStream
.WriteLine( ByteString( CACHE_MAGIC
) );
125 PrintFontManager
& rManager( PrintFontManager::get() );
126 MultiAtomProvider
* pAtoms
= rManager
.m_pAtoms
;
128 for( FontCacheData::const_iterator dir_it
= m_aCache
.begin(); dir_it
!= m_aCache
.end(); ++ dir_it
)
130 const FontDirMap
& rDir( dir_it
->second
.m_aEntries
);
132 ByteString
aDirectory( rManager
.getDirectory( dir_it
->first
) );
133 ByteString
aLine( "FontCacheDirectory:" );
134 aLine
.Append( ByteString::CreateFromInt64( dir_it
->second
.m_nTimestamp
) );
136 aLine
.Append( aDirectory
);
137 if( rDir
.empty() && dir_it
->second
.m_bNoFiles
)
138 aLine
.Insert( "Empty", 0 );
139 aStream
.WriteLine( aLine
);
141 for( FontDirMap::const_iterator entry_it
= rDir
.begin(); entry_it
!= rDir
.end(); ++entry_it
)
143 // insert cache entries
144 const FontCacheEntry
& rEntry( entry_it
->second
.m_aEntry
);
145 if( rEntry
.begin() == rEntry
.end() )
149 aLine
.Append( ByteString( entry_it
->first
) );
150 aStream
.WriteLine( aLine
);
152 int nEntrySize
= entry_it
->second
.m_aEntry
.size();
153 // write: type;nfonts
154 aLine
= ByteString::CreateFromInt32( rEntry
.front()->m_eType
);
156 aLine
.Append( ByteString::CreateFromInt32( nEntrySize
) );
157 aStream
.WriteLine( aLine
);
159 sal_Int32 nSubEntry
= 0;
160 for( FontCacheEntry::const_iterator it
= rEntry
.begin(); it
!= rEntry
.end(); ++it
, nSubEntry
++ )
163 * for each font entry write:
165 * fontnr;PSName;italic;weight;width;pitch;encoding;ascend;descend;leading;vsubst;gxw;gxh;gyw;gyh;useroverrride;embed;antialias[;{metricfile,typeflags}][;stylename]
168 nSubEntry
= static_cast<const PrintFontManager::TrueTypeFontFile
*>(*it
)->m_nCollectionEntry
;
172 aLine
= OUStringToOString( pAtoms
->getString( ATOM_FAMILYNAME
, (*it
)->m_nFamilyName
), RTL_TEXTENCODING_UTF8
);
173 for( ::std::list
< int >::const_iterator name_it
= (*it
)->m_aAliases
.begin(); name_it
!= (*it
)->m_aAliases
.end(); ++name_it
)
175 const OUString
& rAdd( pAtoms
->getString( ATOM_FAMILYNAME
, *name_it
) );
176 if( rAdd
.getLength() )
179 aLine
.Append( ByteString( String( rAdd
), RTL_TEXTENCODING_UTF8
) );
182 aStream
.WriteLine( aLine
);
184 const OUString
& rPSName( pAtoms
->getString( ATOM_PSNAME
, (*it
)->m_nPSName
) );
185 aLine
= ByteString::CreateFromInt32( nSubEntry
);
187 aLine
.Append( ByteString( String( rPSName
), RTL_TEXTENCODING_UTF8
) );
189 aLine
.Append( ByteString::CreateFromInt32( (*it
)->m_eItalic
) );
191 aLine
.Append( ByteString::CreateFromInt32( (*it
)->m_eWeight
) );
193 aLine
.Append( ByteString::CreateFromInt32( (*it
)->m_eWidth
) );
195 aLine
.Append( ByteString::CreateFromInt32( (*it
)->m_ePitch
) );
197 aLine
.Append( ByteString::CreateFromInt32( (*it
)->m_aEncoding
) );
199 aLine
.Append( ByteString::CreateFromInt32( (*it
)->m_nAscend
) );
201 aLine
.Append( ByteString::CreateFromInt32( (*it
)->m_nDescend
) );
203 aLine
.Append( ByteString::CreateFromInt32( (*it
)->m_nLeading
) );
205 aLine
.Append( (*it
)->m_bHaveVerticalSubstitutedGlyphs
? "1" : "0" );
207 aLine
.Append( ByteString::CreateFromInt32( (*it
)->m_aGlobalMetricX
.width
) );
209 aLine
.Append( ByteString::CreateFromInt32( (*it
)->m_aGlobalMetricX
.height
) );
211 aLine
.Append( ByteString::CreateFromInt32( (*it
)->m_aGlobalMetricY
.width
) );
213 aLine
.Append( ByteString::CreateFromInt32( (*it
)->m_aGlobalMetricY
.height
) );
215 aLine
.Append( (*it
)->m_bUserOverride
? "1" : "0" );
217 aLine
.Append( ByteString::CreateFromInt32( (*it
)->m_eEmbeddedbitmap
) );
219 aLine
.Append( ByteString::CreateFromInt32( (*it
)->m_eAntialias
) );
221 switch( (*it
)->m_eType
)
223 case fonttype::Type1
:
225 aLine
.Append( ByteString( static_cast<const PrintFontManager::Type1FontFile
*>(*it
)->m_aMetricFile
) );
227 case fonttype::TrueType
:
229 aLine
.Append( ByteString::CreateFromInt32( static_cast<const PrintFontManager::TrueTypeFontFile
*>(*it
)->m_nTypeFlags
) );
233 if( (*it
)->m_aStyleName
.getLength() )
236 aLine
.Append( ByteString( String( (*it
)->m_aStyleName
), RTL_TEXTENCODING_UTF8
) );
238 aStream
.WriteLine( aLine
);
240 aStream
.WriteLine( ByteString() );
250 void FontCache::read()
252 PrintFontManager
& rManager( PrintFontManager::get() );
253 MultiAtomProvider
* pAtoms
= rManager
.m_pAtoms
;
255 SvFileStream
aStream( m_aCacheFile
, STREAM_READ
);
256 if( ! aStream
.IsOpen() )
258 #if OSL_DEBUG_LEVEL > 1
259 fprintf( stderr
, "FontCache::read: opening cache file %s failed\n", ByteString( m_aCacheFile
, osl_getThreadTextEncoding() ).GetBuffer() );
266 aStream
.ReadLine( aLine
);
267 if( !aLine
.Equals( CACHE_MAGIC
) )
269 #if OSL_DEBUG_LEVEL >1
270 fprintf( stderr
, "FontCache::read: cache file %s fails magic test\n", ByteString( m_aCacheFile
, osl_getThreadTextEncoding() ).GetBuffer() );
276 FontDirMap
* pDir
= NULL
;
278 bool bKeepOnlyUserOverridden
= false;
281 aStream
.ReadLine( aLine
);
282 if( aLine
.CompareTo( "FontCacheDirectory:", 19 ) == COMPARE_EQUAL
||
283 aLine
.CompareTo( "EmptyFontCacheDirectory:", 24 ) == COMPARE_EQUAL
)
285 bool bEmpty
= (aLine
.CompareTo( "Empty", 5 ) == COMPARE_EQUAL
);
286 xub_StrLen nSearchIndex
= bEmpty
? 24 : 19;
289 sal_Int64 nTimestamp
= 0;
290 xub_StrLen nTEnd
= aLine
.Search( ':', nSearchIndex
);
291 if( nTEnd
!= STRING_NOTFOUND
)
293 nTimestamp
= aLine
.Copy( nSearchIndex
, nTEnd
- nSearchIndex
).ToInt64();
294 aDir
= aLine
.Copy( nTEnd
+1 );
298 // invalid format, remove
305 // is the directory modified ?
307 if( stat( aDir
.getStr(), &aStat
) ||
308 ! S_ISDIR(aStat
.st_mode
) )
310 // remove outdated cache data
318 nDir
= rManager
.getDirectoryAtom( aDir
, true );
319 m_aCache
[ nDir
].m_nTimestamp
= (sal_Int64
)aStat
.st_mtime
;
320 m_aCache
[ nDir
].m_bNoFiles
= bEmpty
;
321 pDir
= bEmpty
? NULL
: &m_aCache
[ nDir
].m_aEntries
;
322 bKeepOnlyUserOverridden
= ((sal_Int64
)aStat
.st_mtime
!= nTimestamp
);
323 m_aCache
[ nDir
].m_bUserOverrideOnly
= bKeepOnlyUserOverridden
;
326 else if( pDir
&& aLine
.CompareTo( "File:", 5 ) == COMPARE_EQUAL
)
328 OString
aFile( aLine
.Copy( 5 ) );
329 aStream
.ReadLine( aLine
);
331 const char* pLine
= aLine
.GetBuffer();
333 fonttype::type eType
= (fonttype::type
)atoi( pLine
);
334 if( eType
!= fonttype::TrueType
&&
335 eType
!= fonttype::Type1
&&
336 eType
!= fonttype::Builtin
339 while( *pLine
&& *pLine
!= ';' )
345 sal_Int32 nFonts
= atoi( pLine
);
346 for( int n
= 0; n
< nFonts
; n
++ )
348 aStream
.ReadLine( aLine
);
349 pLine
= aLine
.GetBuffer();
350 int nLen
= aLine
.Len();
352 PrintFontManager::PrintFont
* pFont
= NULL
;
355 case fonttype::TrueType
:
356 pFont
= new PrintFontManager::TrueTypeFontFile();
358 case fonttype::Type1
:
359 pFont
= new PrintFontManager::Type1FontFile();
361 case fonttype::Builtin
:
362 pFont
= new PrintFontManager::BuiltinFont();
367 for( nIndex
= 0; nIndex
< nLen
&& pLine
[nIndex
] != ';'; nIndex
++ )
370 pFont
->m_nFamilyName
= pAtoms
->getAtom( ATOM_FAMILYNAME
,
371 OUString( pLine
, nIndex
, RTL_TEXTENCODING_UTF8
),
373 while( nIndex
< nLen
)
375 xub_StrLen nLastIndex
= nIndex
+1;
376 for( nIndex
= nLastIndex
; nIndex
< nLen
&& pLine
[nIndex
] != ';'; nIndex
++ )
378 if( nIndex
- nLastIndex
> 1 )
380 OUString
aAlias( pLine
+nLastIndex
, nIndex
-nLastIndex
-1, RTL_TEXTENCODING_UTF8
);
381 pFont
->m_aAliases
.push_back( pAtoms
->getAtom( ATOM_FAMILYNAME
, aAlias
, sal_True
) );
384 aStream
.ReadLine( aLine
);
385 pLine
= aLine
.GetBuffer();
388 // get up to 20 token positions
389 const int nMaxTokens
= 20;
390 int nTokenPos
[nMaxTokens
];
393 for( int i
= 0; i
< nLen
; i
++ )
395 if( pLine
[i
] == ';' )
397 nTokenPos
[nTokens
++] = i
+1;
398 if( nTokens
== nMaxTokens
)
407 int nCollEntry
= atoi( pLine
);
408 pFont
->m_nPSName
= pAtoms
->getAtom( ATOM_PSNAME
, OUString( pLine
+ nTokenPos
[1], nTokenPos
[2]-nTokenPos
[1]-1, RTL_TEXTENCODING_UTF8
), sal_True
);
409 pFont
->m_eItalic
= (italic::type
)atoi( pLine
+nTokenPos
[2] );
410 pFont
->m_eWeight
= (weight::type
)atoi( pLine
+nTokenPos
[3] );
411 pFont
->m_eWidth
= (width::type
)atoi( pLine
+nTokenPos
[4] );
412 pFont
->m_ePitch
= (pitch::type
)atoi( pLine
+nTokenPos
[5] );
413 pFont
->m_aEncoding
= (rtl_TextEncoding
)atoi( pLine
+nTokenPos
[6] );
414 pFont
->m_nAscend
= atoi( pLine
+ nTokenPos
[7] );
415 pFont
->m_nDescend
= atoi( pLine
+ nTokenPos
[8] );
416 pFont
->m_nLeading
= atoi( pLine
+ nTokenPos
[9] );
417 pFont
->m_bHaveVerticalSubstitutedGlyphs
418 = (atoi( pLine
+ nTokenPos
[10] ) != 0);
419 pFont
->m_aGlobalMetricX
.width
420 = atoi( pLine
+ nTokenPos
[11] );
421 pFont
->m_aGlobalMetricX
.height
422 = atoi( pLine
+ nTokenPos
[12] );
423 pFont
->m_aGlobalMetricY
.width
424 = atoi( pLine
+ nTokenPos
[13] );
425 pFont
->m_aGlobalMetricY
.height
426 = atoi( pLine
+ nTokenPos
[14] );
427 pFont
->m_bUserOverride
428 = (atoi( pLine
+ nTokenPos
[15] ) != 0);
429 pFont
->m_eEmbeddedbitmap
430 = (fcstatus::type
)atoi(pLine
+nTokenPos
[16]);
431 pFont
->m_eAntialias
= (fcstatus::type
)atoi(pLine
+nTokenPos
[17]);
432 int nStyleTokenNr
= 18;
435 case fonttype::TrueType
:
436 static_cast<PrintFontManager::TrueTypeFontFile
*>(pFont
)->m_nTypeFlags
= atoi( pLine
+ nTokenPos
[18] );
437 static_cast<PrintFontManager::TrueTypeFontFile
*>(pFont
)->m_nCollectionEntry
= nCollEntry
;
438 static_cast<PrintFontManager::TrueTypeFontFile
*>(pFont
)->m_nDirectory
= nDir
;
439 static_cast<PrintFontManager::TrueTypeFontFile
*>(pFont
)->m_aFontFile
= aFile
;
442 case fonttype::Type1
:
444 int nTokLen
= (nTokens
> 19 ) ? nTokenPos
[19]-nTokenPos
[18]-1 : nLen
- nTokenPos
[18];
445 static_cast<PrintFontManager::Type1FontFile
*>(pFont
)->m_aMetricFile
= OString( pLine
+ nTokenPos
[18], nTokLen
);
446 static_cast<PrintFontManager::Type1FontFile
*>(pFont
)->m_nDirectory
= nDir
;
447 static_cast<PrintFontManager::Type1FontFile
*>(pFont
)->m_aFontFile
= aFile
;
451 case fonttype::Builtin
:
452 static_cast<PrintFontManager::BuiltinFont
*>(pFont
)->m_nDirectory
= nDir
;
453 static_cast<PrintFontManager::BuiltinFont
*>(pFont
)->m_aMetricFile
= aFile
;
457 if( nTokens
> nStyleTokenNr
)
458 pFont
->m_aStyleName
= OUString::intern( pLine
+ nTokenPos
[nStyleTokenNr
],
459 nLen
- nTokenPos
[nStyleTokenNr
],
460 RTL_TEXTENCODING_UTF8
);
462 bool bObsolete
= false;
463 if( bKeepOnlyUserOverridden
)
465 if( pFont
->m_bUserOverride
)
467 ByteString aFilePath
= rManager
.getDirectory( nDir
);
468 aFilePath
.Append( '/' );
469 aFilePath
.Append( ByteString(aFile
) );
471 if( stat( aFilePath
.GetBuffer(), &aStat
) ||
472 ! S_ISREG( aStat
.st_mode
) ||
477 #if OSL_DEBUG_LEVEL > 2
479 fprintf( stderr
, "keeping file %s in outdated cache entry due to user override\n",
480 aFilePath
.GetBuffer() );
489 #if OSL_DEBUG_LEVEL > 2
490 fprintf( stderr
, "removing obsolete font %s\n", aFile
.getStr() );
496 FontCacheEntry
& rEntry
= (*pDir
)[aFile
].m_aEntry
;
497 rEntry
.push_back( pFont
);
500 } while( ! aStream
.IsEof() );
504 * FontCache::updateDirTimestamp
506 void FontCache::updateDirTimestamp( int nDirID
)
508 PrintFontManager
& rManager( PrintFontManager::get() );
509 const OString
& rDir
= rManager
.getDirectory( nDirID
);
512 if( ! stat( rDir
.getStr(), &aStat
) )
513 m_aCache
[ nDirID
].m_nTimestamp
= (sal_Int64
)aStat
.st_mtime
;
518 * FontCache::copyPrintFont
520 void FontCache::copyPrintFont( const PrintFontManager::PrintFont
* pFrom
, PrintFontManager::PrintFont
* pTo
) const
522 if( pFrom
->m_eType
!= pTo
->m_eType
)
524 switch( pFrom
->m_eType
)
526 case fonttype::TrueType
:
527 static_cast<PrintFontManager::TrueTypeFontFile
*>(pTo
)->m_nDirectory
= static_cast<const PrintFontManager::TrueTypeFontFile
*>(pFrom
)->m_nDirectory
;
528 static_cast<PrintFontManager::TrueTypeFontFile
*>(pTo
)->m_aFontFile
= static_cast<const PrintFontManager::TrueTypeFontFile
*>(pFrom
)->m_aFontFile
;
529 static_cast<PrintFontManager::TrueTypeFontFile
*>(pTo
)->m_nCollectionEntry
= static_cast<const PrintFontManager::TrueTypeFontFile
*>(pFrom
)->m_nCollectionEntry
;
530 static_cast<PrintFontManager::TrueTypeFontFile
*>(pTo
)->m_nTypeFlags
= static_cast<const PrintFontManager::TrueTypeFontFile
*>(pFrom
)->m_nTypeFlags
;
532 case fonttype::Type1
:
533 static_cast<PrintFontManager::Type1FontFile
*>(pTo
)->m_nDirectory
= static_cast<const PrintFontManager::Type1FontFile
*>(pFrom
)->m_nDirectory
;
534 static_cast<PrintFontManager::Type1FontFile
*>(pTo
)->m_aFontFile
= static_cast<const PrintFontManager::Type1FontFile
*>(pFrom
)->m_aFontFile
;
535 static_cast<PrintFontManager::Type1FontFile
*>(pTo
)->m_aMetricFile
= static_cast<const PrintFontManager::Type1FontFile
*>(pFrom
)->m_aMetricFile
;
537 case fonttype::Builtin
:
538 static_cast<PrintFontManager::BuiltinFont
*>(pTo
)->m_nDirectory
= static_cast<const PrintFontManager::BuiltinFont
*>(pFrom
)->m_nDirectory
;
539 static_cast<PrintFontManager::BuiltinFont
*>(pTo
)->m_aMetricFile
= static_cast<const PrintFontManager::BuiltinFont
*>(pFrom
)->m_aMetricFile
;
543 pTo
->m_nFamilyName
= pFrom
->m_nFamilyName
;
544 pTo
->m_aStyleName
= pFrom
->m_aStyleName
;
545 pTo
->m_aAliases
= pFrom
->m_aAliases
;
546 pTo
->m_nPSName
= pFrom
->m_nPSName
;
547 pTo
->m_eItalic
= pFrom
->m_eItalic
;
548 pTo
->m_eWeight
= pFrom
->m_eWeight
;
549 pTo
->m_eWidth
= pFrom
->m_eWidth
;
550 pTo
->m_ePitch
= pFrom
->m_ePitch
;
551 pTo
->m_aEncoding
= pFrom
->m_aEncoding
;
552 pTo
->m_aGlobalMetricX
= pFrom
->m_aGlobalMetricX
;
553 pTo
->m_aGlobalMetricY
= pFrom
->m_aGlobalMetricY
;
554 pTo
->m_nAscend
= pFrom
->m_nAscend
;
555 pTo
->m_nDescend
= pFrom
->m_nDescend
;
556 pTo
->m_nLeading
= pFrom
->m_nLeading
;
557 pTo
->m_nXMin
= pFrom
->m_nXMin
;
558 pTo
->m_nYMin
= pFrom
->m_nYMin
;
559 pTo
->m_nXMax
= pFrom
->m_nXMax
;
560 pTo
->m_nYMax
= pFrom
->m_nYMax
;
561 pTo
->m_bHaveVerticalSubstitutedGlyphs
= pFrom
->m_bHaveVerticalSubstitutedGlyphs
;
562 pTo
->m_bUserOverride
= pFrom
->m_bUserOverride
;
563 pTo
->m_eEmbeddedbitmap
= pFrom
->m_eEmbeddedbitmap
;
564 pTo
->m_eAntialias
= pFrom
->m_eAntialias
;
568 * FontCache::equalsPrintFont
570 bool FontCache::equalsPrintFont( const PrintFontManager::PrintFont
* pLeft
, PrintFontManager::PrintFont
* pRight
) const
572 if( pLeft
->m_eType
!= pRight
->m_eType
)
574 switch( pLeft
->m_eType
)
576 case fonttype::TrueType
:
578 const PrintFontManager::TrueTypeFontFile
* pLT
= static_cast<const PrintFontManager::TrueTypeFontFile
*>(pLeft
);
579 const PrintFontManager::TrueTypeFontFile
* pRT
= static_cast<const PrintFontManager::TrueTypeFontFile
*>(pRight
);
580 if( pRT
->m_nDirectory
!= pLT
->m_nDirectory
||
581 pRT
->m_aFontFile
!= pLT
->m_aFontFile
||
582 pRT
->m_nCollectionEntry
!= pLT
->m_nCollectionEntry
||
583 pRT
->m_nTypeFlags
!= pLT
->m_nTypeFlags
)
587 case fonttype::Type1
:
589 const PrintFontManager::Type1FontFile
* pLT
= static_cast<const PrintFontManager::Type1FontFile
*>(pLeft
);
590 const PrintFontManager::Type1FontFile
* pRT
= static_cast<const PrintFontManager::Type1FontFile
*>(pRight
);
591 if( pRT
->m_nDirectory
!= pLT
->m_nDirectory
||
592 pRT
->m_aFontFile
!= pLT
->m_aFontFile
||
593 pRT
->m_aMetricFile
!= pLT
->m_aMetricFile
)
597 case fonttype::Builtin
:
599 const PrintFontManager::BuiltinFont
* pLT
= static_cast<const PrintFontManager::BuiltinFont
*>(pLeft
);
600 const PrintFontManager::BuiltinFont
* pRT
= static_cast<const PrintFontManager::BuiltinFont
*>(pRight
);
601 if( pRT
->m_nDirectory
!= pLT
->m_nDirectory
||
602 pRT
->m_aMetricFile
!= pLT
->m_aMetricFile
)
608 if( pRight
->m_nFamilyName
!= pLeft
->m_nFamilyName
||
609 pRight
->m_aStyleName
!= pLeft
->m_aStyleName
||
610 pRight
->m_nPSName
!= pLeft
->m_nPSName
||
611 pRight
->m_eItalic
!= pLeft
->m_eItalic
||
612 pRight
->m_eWeight
!= pLeft
->m_eWeight
||
613 pRight
->m_eWidth
!= pLeft
->m_eWidth
||
614 pRight
->m_ePitch
!= pLeft
->m_ePitch
||
615 pRight
->m_aEncoding
!= pLeft
->m_aEncoding
||
616 pRight
->m_aGlobalMetricX
!= pLeft
->m_aGlobalMetricX
||
617 pRight
->m_aGlobalMetricY
!= pLeft
->m_aGlobalMetricY
||
618 pRight
->m_nAscend
!= pLeft
->m_nAscend
||
619 pRight
->m_nDescend
!= pLeft
->m_nDescend
||
620 pRight
->m_nLeading
!= pLeft
->m_nLeading
||
621 pRight
->m_nXMin
!= pLeft
->m_nXMin
||
622 pRight
->m_nYMin
!= pLeft
->m_nYMin
||
623 pRight
->m_nXMax
!= pLeft
->m_nXMax
||
624 pRight
->m_nYMax
!= pLeft
->m_nYMax
||
625 pRight
->m_bHaveVerticalSubstitutedGlyphs
!= pLeft
->m_bHaveVerticalSubstitutedGlyphs
||
626 pRight
->m_bUserOverride
!= pLeft
->m_bUserOverride
||
627 pRight
->m_eEmbeddedbitmap
!= pLeft
->m_eEmbeddedbitmap
||
628 pRight
->m_eAntialias
!= pLeft
->m_eAntialias
631 std::list
< int >::const_iterator lit
, rit
;
632 for( lit
= pLeft
->m_aAliases
.begin(), rit
= pRight
->m_aAliases
.begin();
633 lit
!= pLeft
->m_aAliases
.end() && rit
!= pRight
->m_aAliases
.end() && (*lit
) == (*rit
);
636 return lit
== pLeft
->m_aAliases
.end() && rit
== pRight
->m_aAliases
.end();
640 * FontCache::clonePrintFont
642 PrintFontManager::PrintFont
* FontCache::clonePrintFont( const PrintFontManager::PrintFont
* pOldFont
) const
644 PrintFontManager::PrintFont
* pFont
= NULL
;
645 switch( pOldFont
->m_eType
)
647 case fonttype::TrueType
:
648 pFont
= new PrintFontManager::TrueTypeFontFile();
650 case fonttype::Type1
:
651 pFont
= new PrintFontManager::Type1FontFile();
653 case fonttype::Builtin
:
654 pFont
= new PrintFontManager::BuiltinFont();
660 copyPrintFont( pOldFont
, pFont
);
666 * FontCache::getFontCacheFile
668 bool FontCache::getFontCacheFile( int nDirID
, const OString
& rFile
, list
< PrintFontManager::PrintFont
* >& rNewFonts
) const
670 bool bSuccess
= false;
672 FontCacheData::const_iterator dir
= m_aCache
.find( nDirID
);
673 if( dir
!= m_aCache
.end() )
675 FontDirMap::const_iterator entry
= dir
->second
.m_aEntries
.find( rFile
);
676 if( entry
!= dir
->second
.m_aEntries
.end() )
678 for( FontCacheEntry::const_iterator font
= entry
->second
.m_aEntry
.begin(); font
!= entry
->second
.m_aEntry
.end(); ++font
)
681 PrintFontManager::PrintFont
* pFont
= clonePrintFont( *font
);
682 rNewFonts
.push_back( pFont
);
690 * FontCache::updateFontCacheEntry
692 void FontCache::updateFontCacheEntry( const PrintFontManager::PrintFont
* pFont
, bool bFlush
)
694 PrintFontManager
& rManager( PrintFontManager::get() );
698 switch( pFont
->m_eType
)
700 case fonttype::TrueType
:
701 nDirID
= static_cast<const PrintFontManager::TrueTypeFontFile
*>(pFont
)->m_nDirectory
;
702 aFile
= static_cast<const PrintFontManager::TrueTypeFontFile
*>(pFont
)->m_aFontFile
;
704 case fonttype::Type1
:
705 nDirID
= static_cast<const PrintFontManager::Type1FontFile
*>(pFont
)->m_nDirectory
;
706 aFile
= static_cast<const PrintFontManager::Type1FontFile
*>(pFont
)->m_aFontFile
;
708 case fonttype::Builtin
:
709 nDirID
= static_cast<const PrintFontManager::BuiltinFont
*>(pFont
)->m_nDirectory
;
710 aFile
= static_cast<const PrintFontManager::BuiltinFont
*>(pFont
)->m_aMetricFile
;
715 FontCacheData::const_iterator dir
= m_aCache
.find( nDirID
);
716 FontDirMap::const_iterator entry
;
717 FontCacheEntry::const_iterator font
;
718 PrintFontManager::PrintFont
* pCacheFont
= NULL
;
720 if( dir
!= m_aCache
.end() )
722 entry
= dir
->second
.m_aEntries
.find( aFile
);
723 if( entry
!= dir
->second
.m_aEntries
.end() )
725 for( font
= entry
->second
.m_aEntry
.begin(); font
!= entry
->second
.m_aEntry
.end(); ++font
)
727 if( (*font
)->m_eType
== pFont
->m_eType
&&
728 ( (*font
)->m_eType
!= fonttype::TrueType
||
729 static_cast<const PrintFontManager::TrueTypeFontFile
*>(*font
)->m_nCollectionEntry
== static_cast<const PrintFontManager::TrueTypeFontFile
*>(pFont
)->m_nCollectionEntry
733 if( font
!= entry
->second
.m_aEntry
.end() )
738 createCacheDir( nDirID
);
742 if( ! equalsPrintFont( pFont
, pCacheFont
) )
744 copyPrintFont( pFont
, pCacheFont
);
750 pCacheFont
= clonePrintFont( pFont
);
751 m_aCache
[nDirID
].m_aEntries
[aFile
].m_aEntry
.push_back( pCacheFont
);
753 ByteString aPath
= rManager
.getDirectory( nDirID
);
755 aPath
.Append( ByteString( aFile
) );
763 * FontCache::listDirectory
765 bool FontCache::listDirectory( const OString
& rDir
, std::list
< PrintFontManager::PrintFont
* >& rNewFonts
) const
767 PrintFontManager
& rManager( PrintFontManager::get() );
768 int nDirID
= rManager
.getDirectoryAtom( rDir
);
769 FontCacheData::const_iterator dir
= m_aCache
.find( nDirID
);
770 bool bFound
= (dir
!= m_aCache
.end());
772 if( bFound
&& !dir
->second
.m_bNoFiles
)
774 for( FontDirMap::const_iterator file
= dir
->second
.m_aEntries
.begin(); file
!= dir
->second
.m_aEntries
.end(); ++file
)
776 for( FontCacheEntry::const_iterator font
= file
->second
.m_aEntry
.begin(); font
!= file
->second
.m_aEntry
.end(); ++font
)
778 PrintFontManager::PrintFont
* pFont
= clonePrintFont( *font
);
779 rNewFonts
.push_back( pFont
);
787 * FontCache::listDirectory
789 bool FontCache::scanAdditionalFiles( const OString
& rDir
)
791 PrintFontManager
& rManager( PrintFontManager::get() );
792 int nDirID
= rManager
.getDirectoryAtom( rDir
);
793 FontCacheData::const_iterator dir
= m_aCache
.find( nDirID
);
794 bool bFound
= (dir
!= m_aCache
.end());
796 return (bFound
&& dir
->second
.m_bUserOverrideOnly
);
800 * FontCache::createCacheDir
802 void FontCache::createCacheDir( int nDirID
)
804 PrintFontManager
& rManager( PrintFontManager::get() );
806 const OString
& rDir
= rManager
.getDirectory( nDirID
);
808 if( ! stat( rDir
.getStr(), &aStat
) )
809 m_aCache
[nDirID
].m_nTimestamp
= (sal_Int64
)aStat
.st_mtime
;
813 * FontCache::markEmptyDir
815 void FontCache::markEmptyDir( int nDirID
, bool bNoFiles
)
817 createCacheDir( nDirID
);
818 m_aCache
[nDirID
].m_bNoFiles
= bNoFiles
;