1*c82f2877SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*c82f2877SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*c82f2877SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*c82f2877SAndrew Rist  * distributed with this work for additional information
6*c82f2877SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*c82f2877SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*c82f2877SAndrew Rist  * "License"); you may not use this file except in compliance
9*c82f2877SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*c82f2877SAndrew Rist  *
11*c82f2877SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*c82f2877SAndrew Rist  *
13*c82f2877SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*c82f2877SAndrew Rist  * software distributed under the License is distributed on an
15*c82f2877SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*c82f2877SAndrew Rist  * KIND, either express or implied.  See the License for the
17*c82f2877SAndrew Rist  * specific language governing permissions and limitations
18*c82f2877SAndrew Rist  * under the License.
19*c82f2877SAndrew Rist  *
20*c82f2877SAndrew Rist  *************************************************************/
21*c82f2877SAndrew Rist 
22*c82f2877SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_vcl.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include <cstdlib>
28cdf0e10cSrcweir #include <cstring>
29cdf0e10cSrcweir 
30cdf0e10cSrcweir #include "fontcache.hxx"
31cdf0e10cSrcweir 
32cdf0e10cSrcweir #include "osl/thread.h"
33cdf0e10cSrcweir 
34cdf0e10cSrcweir #include "unotools/atom.hxx"
35cdf0e10cSrcweir 
36cdf0e10cSrcweir #include "tools/stream.hxx"
37cdf0e10cSrcweir 
38cdf0e10cSrcweir #include <unistd.h>
39cdf0e10cSrcweir #include <sys/stat.h>
40cdf0e10cSrcweir 
41cdf0e10cSrcweir #if OSL_DEBUG_LEVEL >1
42cdf0e10cSrcweir #include <cstdio>
43cdf0e10cSrcweir #endif
44cdf0e10cSrcweir 
45cdf0e10cSrcweir #define FONTCACHEFILE "/user/psprint/pspfontcache"
46cdf0e10cSrcweir #define CACHE_MAGIC "PspFontCacheFile format 4"
47cdf0e10cSrcweir 
48cdf0e10cSrcweir using namespace std;
49cdf0e10cSrcweir using namespace rtl;
50cdf0e10cSrcweir using namespace psp;
51cdf0e10cSrcweir using namespace utl;
52cdf0e10cSrcweir 
53cdf0e10cSrcweir /*
54cdf0e10cSrcweir  *  static helpers
55cdf0e10cSrcweir  */
56cdf0e10cSrcweir 
57cdf0e10cSrcweir /*
58cdf0e10cSrcweir  *  FontCache constructor
59cdf0e10cSrcweir  */
60cdf0e10cSrcweir 
FontCache()61cdf0e10cSrcweir FontCache::FontCache()
62cdf0e10cSrcweir {
63cdf0e10cSrcweir     m_bDoFlush = false;
64cdf0e10cSrcweir     m_aCacheFile = getOfficePath( UserPath );
65cdf0e10cSrcweir     if( m_aCacheFile.Len() )
66cdf0e10cSrcweir     {
67cdf0e10cSrcweir         m_aCacheFile.AppendAscii( FONTCACHEFILE );
68cdf0e10cSrcweir         read();
69cdf0e10cSrcweir     }
70cdf0e10cSrcweir }
71cdf0e10cSrcweir 
72cdf0e10cSrcweir /*
73cdf0e10cSrcweir  *  FontCache destructor
74cdf0e10cSrcweir  */
75cdf0e10cSrcweir 
~FontCache()76cdf0e10cSrcweir FontCache::~FontCache()
77cdf0e10cSrcweir {
78cdf0e10cSrcweir     clearCache();
79cdf0e10cSrcweir }
80cdf0e10cSrcweir 
81cdf0e10cSrcweir /*
82cdf0e10cSrcweir  *  FontCache::clearCache
83cdf0e10cSrcweir  */
clearCache()84cdf0e10cSrcweir void FontCache::clearCache()
85cdf0e10cSrcweir {
86cdf0e10cSrcweir     for( FontCacheData::iterator dir_it = m_aCache.begin(); dir_it != m_aCache.end(); ++dir_it )
87cdf0e10cSrcweir     {
88cdf0e10cSrcweir         for( FontDirMap::iterator entry_it = dir_it->second.m_aEntries.begin(); entry_it != dir_it->second.m_aEntries.end(); ++entry_it )
89cdf0e10cSrcweir         {
90cdf0e10cSrcweir             for( FontCacheEntry::iterator font_it = entry_it->second.m_aEntry.begin(); font_it != entry_it->second.m_aEntry.end(); ++font_it )
91cdf0e10cSrcweir                 delete *font_it;
92cdf0e10cSrcweir         }
93cdf0e10cSrcweir     }
94cdf0e10cSrcweir     m_aCache.clear();
95cdf0e10cSrcweir }
96cdf0e10cSrcweir 
97cdf0e10cSrcweir /*
98cdf0e10cSrcweir  *  FontCache::Commit
99cdf0e10cSrcweir  */
100cdf0e10cSrcweir 
flush()101cdf0e10cSrcweir void FontCache::flush()
102cdf0e10cSrcweir {
103cdf0e10cSrcweir     if( ! m_bDoFlush || ! m_aCacheFile.Len() )
104cdf0e10cSrcweir         return;
105cdf0e10cSrcweir 
106cdf0e10cSrcweir     SvFileStream aStream;
107cdf0e10cSrcweir     aStream.Open( m_aCacheFile, STREAM_WRITE | STREAM_TRUNC );
108cdf0e10cSrcweir     if( ! (aStream.IsOpen() && aStream.IsWritable()) )
109cdf0e10cSrcweir     {
110cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
111cdf0e10cSrcweir         fprintf( stderr, "FontCache::flush: opening cache file %s failed\n", ByteString( m_aCacheFile, osl_getThreadTextEncoding() ).GetBuffer() );
112cdf0e10cSrcweir #endif
113cdf0e10cSrcweir         return;
114cdf0e10cSrcweir     }
115cdf0e10cSrcweir 
116cdf0e10cSrcweir     aStream.SetLineDelimiter( LINEEND_LF );
117cdf0e10cSrcweir     aStream.WriteLine( ByteString( CACHE_MAGIC ) );
118cdf0e10cSrcweir 
119cdf0e10cSrcweir     PrintFontManager& rManager( PrintFontManager::get() );
120cdf0e10cSrcweir     MultiAtomProvider* pAtoms = rManager.m_pAtoms;
121cdf0e10cSrcweir 
122cdf0e10cSrcweir     for( FontCacheData::const_iterator dir_it = m_aCache.begin(); dir_it != m_aCache.end(); ++ dir_it )
123cdf0e10cSrcweir     {
124cdf0e10cSrcweir         const FontDirMap& rDir( dir_it->second.m_aEntries );
125cdf0e10cSrcweir 
126cdf0e10cSrcweir         ByteString aDirectory( rManager.getDirectory( dir_it->first ) );
127cdf0e10cSrcweir         ByteString aLine( "FontCacheDirectory:" );
128cdf0e10cSrcweir         aLine.Append( ByteString::CreateFromInt64( dir_it->second.m_nTimestamp ) );
129cdf0e10cSrcweir         aLine.Append( ':' );
130cdf0e10cSrcweir         aLine.Append( aDirectory );
131cdf0e10cSrcweir         if( rDir.empty() && dir_it->second.m_bNoFiles )
132cdf0e10cSrcweir             aLine.Insert( "Empty", 0 );
133cdf0e10cSrcweir         aStream.WriteLine( aLine );
134cdf0e10cSrcweir 
135cdf0e10cSrcweir         for( FontDirMap::const_iterator entry_it = rDir.begin(); entry_it != rDir.end(); ++entry_it )
136cdf0e10cSrcweir         {
137cdf0e10cSrcweir             // insert cache entries
138cdf0e10cSrcweir             const FontCacheEntry& rEntry( entry_it->second.m_aEntry );
139cdf0e10cSrcweir             if( rEntry.begin() == rEntry.end() )
140cdf0e10cSrcweir                 continue;
141cdf0e10cSrcweir 
142cdf0e10cSrcweir             aLine = "File:";
143cdf0e10cSrcweir             aLine.Append( ByteString( entry_it->first ) );
144cdf0e10cSrcweir             aStream.WriteLine( aLine );
145cdf0e10cSrcweir 
146cdf0e10cSrcweir             int nEntrySize = entry_it->second.m_aEntry.size();
147cdf0e10cSrcweir             // write: type;nfonts
148cdf0e10cSrcweir             aLine = ByteString::CreateFromInt32( rEntry.front()->m_eType );
149cdf0e10cSrcweir             aLine.Append( ';' );
150cdf0e10cSrcweir             aLine.Append( ByteString::CreateFromInt32( nEntrySize ) );
151cdf0e10cSrcweir             aStream.WriteLine( aLine );
152cdf0e10cSrcweir 
153cdf0e10cSrcweir             sal_Int32 nSubEntry = 0;
154cdf0e10cSrcweir             for( FontCacheEntry::const_iterator it = rEntry.begin(); it != rEntry.end(); ++it, nSubEntry++ )
155cdf0e10cSrcweir             {
156cdf0e10cSrcweir                 /*
157cdf0e10cSrcweir                  *  for each font entry write:
158cdf0e10cSrcweir                  *  name[;name[;name]]
159cdf0e10cSrcweir                  *  fontnr;PSName;italic;weight;width;pitch;encoding;ascend;descend;leading;vsubst;gxw;gxh;gyw;gyh;useroverrride;embed;antialias[;{metricfile,typeflags}][;stylename]
160cdf0e10cSrcweir                  */
161cdf0e10cSrcweir                 if( nEntrySize > 1 )
162cdf0e10cSrcweir                     nSubEntry = static_cast<const PrintFontManager::TrueTypeFontFile*>(*it)->m_nCollectionEntry;
163cdf0e10cSrcweir                 else
164cdf0e10cSrcweir                     nSubEntry = -1;
165cdf0e10cSrcweir 
166cdf0e10cSrcweir                 aLine = OUStringToOString( pAtoms->getString( ATOM_FAMILYNAME, (*it)->m_nFamilyName ), RTL_TEXTENCODING_UTF8 );
167cdf0e10cSrcweir                 for( ::std::list< int >::const_iterator name_it = (*it)->m_aAliases.begin(); name_it != (*it)->m_aAliases.end(); ++name_it )
168cdf0e10cSrcweir                 {
169cdf0e10cSrcweir                     const OUString& rAdd( pAtoms->getString( ATOM_FAMILYNAME, *name_it ) );
170cdf0e10cSrcweir                     if( rAdd.getLength() )
171cdf0e10cSrcweir                     {
172cdf0e10cSrcweir                         aLine.Append( ';' );
173cdf0e10cSrcweir                         aLine.Append( ByteString( String( rAdd ), RTL_TEXTENCODING_UTF8 ) );
174cdf0e10cSrcweir                     }
175cdf0e10cSrcweir                 }
176cdf0e10cSrcweir                 aStream.WriteLine( aLine );
177cdf0e10cSrcweir 
178cdf0e10cSrcweir                 const OUString& rPSName( pAtoms->getString( ATOM_PSNAME, (*it)->m_nPSName ) );
179cdf0e10cSrcweir                 aLine = ByteString::CreateFromInt32( nSubEntry );
180cdf0e10cSrcweir                 aLine.Append( ';' );
181cdf0e10cSrcweir                 aLine.Append( ByteString( String( rPSName ), RTL_TEXTENCODING_UTF8 ) );
182cdf0e10cSrcweir                 aLine.Append( ';' );
183cdf0e10cSrcweir                 aLine.Append( ByteString::CreateFromInt32( (*it)->m_eItalic ) );
184cdf0e10cSrcweir                 aLine.Append( ';' );
185cdf0e10cSrcweir                 aLine.Append( ByteString::CreateFromInt32( (*it)->m_eWeight ) );
186cdf0e10cSrcweir                 aLine.Append( ';' );
187cdf0e10cSrcweir                 aLine.Append( ByteString::CreateFromInt32( (*it)->m_eWidth ) );
188cdf0e10cSrcweir                 aLine.Append( ';' );
189cdf0e10cSrcweir                 aLine.Append( ByteString::CreateFromInt32( (*it)->m_ePitch ) );
190cdf0e10cSrcweir                 aLine.Append( ';' );
191cdf0e10cSrcweir                 aLine.Append( ByteString::CreateFromInt32( (*it)->m_aEncoding ) );
192cdf0e10cSrcweir                 aLine.Append( ';' );
193cdf0e10cSrcweir                 aLine.Append( ByteString::CreateFromInt32( (*it)->m_nAscend ) );
194cdf0e10cSrcweir                 aLine.Append( ';' );
195cdf0e10cSrcweir                 aLine.Append( ByteString::CreateFromInt32( (*it)->m_nDescend ) );
196cdf0e10cSrcweir                 aLine.Append( ';' );
197cdf0e10cSrcweir                 aLine.Append( ByteString::CreateFromInt32( (*it)->m_nLeading ) );
198cdf0e10cSrcweir                 aLine.Append( ';' );
199cdf0e10cSrcweir                 aLine.Append( (*it)->m_bHaveVerticalSubstitutedGlyphs ? "1" : "0" );
200cdf0e10cSrcweir                 aLine.Append( ';' );
201cdf0e10cSrcweir                 aLine.Append( ByteString::CreateFromInt32( (*it)->m_aGlobalMetricX.width ) );
202cdf0e10cSrcweir                 aLine.Append( ';' );
203cdf0e10cSrcweir                 aLine.Append( ByteString::CreateFromInt32( (*it)->m_aGlobalMetricX.height ) );
204cdf0e10cSrcweir                 aLine.Append( ';' );
205cdf0e10cSrcweir                 aLine.Append( ByteString::CreateFromInt32( (*it)->m_aGlobalMetricY.width ) );
206cdf0e10cSrcweir                 aLine.Append( ';' );
207cdf0e10cSrcweir                 aLine.Append( ByteString::CreateFromInt32( (*it)->m_aGlobalMetricY.height ) );
208cdf0e10cSrcweir                 aLine.Append( ';' );
209cdf0e10cSrcweir                 aLine.Append( (*it)->m_bUserOverride ? "1" : "0" );
210cdf0e10cSrcweir                 aLine.Append( ';' );
211cdf0e10cSrcweir                 aLine.Append( ByteString::CreateFromInt32( 0 ) );
212cdf0e10cSrcweir                 aLine.Append( ';' );
213cdf0e10cSrcweir                 aLine.Append( ByteString::CreateFromInt32( 0 ) );
214cdf0e10cSrcweir 
215cdf0e10cSrcweir                 switch( (*it)->m_eType )
216cdf0e10cSrcweir                 {
217cdf0e10cSrcweir                     case fonttype::Type1:
218cdf0e10cSrcweir                         aLine.Append( ';' );
219cdf0e10cSrcweir                         aLine.Append( ByteString( static_cast<const PrintFontManager::Type1FontFile*>(*it)->m_aMetricFile ) );
220cdf0e10cSrcweir                         break;
221cdf0e10cSrcweir                     case fonttype::TrueType:
222cdf0e10cSrcweir                         aLine.Append( ';' );
223cdf0e10cSrcweir                         aLine.Append( ByteString::CreateFromInt32( static_cast<const PrintFontManager::TrueTypeFontFile*>(*it)->m_nTypeFlags ) );
224cdf0e10cSrcweir                         break;
225cdf0e10cSrcweir                     default: break;
226cdf0e10cSrcweir                 }
227cdf0e10cSrcweir                 if( (*it)->m_aStyleName.getLength() )
228cdf0e10cSrcweir                 {
229cdf0e10cSrcweir                     aLine.Append( ';' );
230cdf0e10cSrcweir                     aLine.Append( ByteString( String( (*it)->m_aStyleName ), RTL_TEXTENCODING_UTF8 ) );
231cdf0e10cSrcweir                 }
232cdf0e10cSrcweir                 aStream.WriteLine( aLine );
233cdf0e10cSrcweir             }
234cdf0e10cSrcweir             aStream.WriteLine( ByteString() );
235cdf0e10cSrcweir         }
236cdf0e10cSrcweir     }
237cdf0e10cSrcweir     m_bDoFlush = false;
238cdf0e10cSrcweir }
239cdf0e10cSrcweir 
240cdf0e10cSrcweir /*
241cdf0e10cSrcweir  * FontCache::read
242cdf0e10cSrcweir  */
243cdf0e10cSrcweir 
read()244cdf0e10cSrcweir void FontCache::read()
245cdf0e10cSrcweir {
246cdf0e10cSrcweir     PrintFontManager& rManager( PrintFontManager::get() );
247cdf0e10cSrcweir     MultiAtomProvider* pAtoms = rManager.m_pAtoms;
248cdf0e10cSrcweir 
249cdf0e10cSrcweir     SvFileStream aStream( m_aCacheFile, STREAM_READ );
250cdf0e10cSrcweir     if( ! aStream.IsOpen() )
251cdf0e10cSrcweir     {
252cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
253cdf0e10cSrcweir         fprintf( stderr, "FontCache::read: opening cache file %s failed\n", ByteString( m_aCacheFile, osl_getThreadTextEncoding() ).GetBuffer() );
254cdf0e10cSrcweir #endif
255cdf0e10cSrcweir         return;
256cdf0e10cSrcweir     }
257cdf0e10cSrcweir 
258cdf0e10cSrcweir 
259cdf0e10cSrcweir     ByteString aLine;
260cdf0e10cSrcweir     aStream.ReadLine( aLine );
261cdf0e10cSrcweir     if( !aLine.Equals( CACHE_MAGIC ) )
262cdf0e10cSrcweir     {
263cdf0e10cSrcweir         #if OSL_DEBUG_LEVEL >1
264cdf0e10cSrcweir         fprintf( stderr, "FontCache::read: cache file %s fails magic test\n", ByteString( m_aCacheFile, osl_getThreadTextEncoding() ).GetBuffer() );
265cdf0e10cSrcweir         #endif
266cdf0e10cSrcweir         return;
267cdf0e10cSrcweir     }
268cdf0e10cSrcweir 
269cdf0e10cSrcweir     int nDir = 0;
270cdf0e10cSrcweir     FontDirMap* pDir = NULL;
271cdf0e10cSrcweir     xub_StrLen nIndex;
272cdf0e10cSrcweir     bool bKeepOnlyUserOverridden = false;
273cdf0e10cSrcweir     do
274cdf0e10cSrcweir     {
275cdf0e10cSrcweir         aStream.ReadLine( aLine );
276cdf0e10cSrcweir         if( aLine.CompareTo( "FontCacheDirectory:", 19 ) == COMPARE_EQUAL ||
277cdf0e10cSrcweir             aLine.CompareTo( "EmptyFontCacheDirectory:", 24 ) == COMPARE_EQUAL )
278cdf0e10cSrcweir         {
279cdf0e10cSrcweir             bool bEmpty = (aLine.CompareTo( "Empty", 5 ) == COMPARE_EQUAL);
280cdf0e10cSrcweir             xub_StrLen nSearchIndex = bEmpty ? 24 : 19;
281cdf0e10cSrcweir 
282cdf0e10cSrcweir             OString aDir;
283cdf0e10cSrcweir             sal_Int64 nTimestamp = 0;
284cdf0e10cSrcweir             xub_StrLen nTEnd = aLine.Search( ':', nSearchIndex );
285cdf0e10cSrcweir             if( nTEnd != STRING_NOTFOUND )
286cdf0e10cSrcweir             {
287cdf0e10cSrcweir                 nTimestamp = aLine.Copy( nSearchIndex, nTEnd - nSearchIndex ).ToInt64();
288cdf0e10cSrcweir                 aDir = aLine.Copy( nTEnd+1 );
289cdf0e10cSrcweir             }
290cdf0e10cSrcweir             else
291cdf0e10cSrcweir             {
292cdf0e10cSrcweir                 // invalid format, remove
293cdf0e10cSrcweir                 pDir = NULL;
294cdf0e10cSrcweir                 nDir = 0;
295cdf0e10cSrcweir                 m_bDoFlush = true;
296cdf0e10cSrcweir                 continue;
297cdf0e10cSrcweir             }
298cdf0e10cSrcweir 
299cdf0e10cSrcweir             // is the directory modified ?
300cdf0e10cSrcweir             struct stat aStat;
301cdf0e10cSrcweir             if( stat( aDir.getStr(), &aStat )				||
302cdf0e10cSrcweir                 ! S_ISDIR(aStat.st_mode) )
303cdf0e10cSrcweir             {
304cdf0e10cSrcweir                 // remove outdated cache data
305cdf0e10cSrcweir                 pDir = NULL;
306cdf0e10cSrcweir                 nDir = 0;
307cdf0e10cSrcweir                 m_bDoFlush = true;
308cdf0e10cSrcweir                 continue;
309cdf0e10cSrcweir             }
310cdf0e10cSrcweir             else
311cdf0e10cSrcweir             {
312cdf0e10cSrcweir                 nDir = rManager.getDirectoryAtom( aDir, true );
313cdf0e10cSrcweir                 m_aCache[ nDir ].m_nTimestamp = (sal_Int64)aStat.st_mtime;
314cdf0e10cSrcweir                 m_aCache[ nDir ].m_bNoFiles = bEmpty;
315cdf0e10cSrcweir                 pDir = bEmpty ? NULL : &m_aCache[ nDir ].m_aEntries;
316cdf0e10cSrcweir                 bKeepOnlyUserOverridden = ((sal_Int64)aStat.st_mtime != nTimestamp);
317cdf0e10cSrcweir                 m_aCache[ nDir ].m_bUserOverrideOnly = bKeepOnlyUserOverridden;
318cdf0e10cSrcweir             }
319cdf0e10cSrcweir         }
320cdf0e10cSrcweir         else if( pDir && aLine.CompareTo( "File:", 5 ) == COMPARE_EQUAL )
321cdf0e10cSrcweir         {
322cdf0e10cSrcweir             OString aFile( aLine.Copy( 5 ) );
323cdf0e10cSrcweir             aStream.ReadLine( aLine );
324cdf0e10cSrcweir 
325cdf0e10cSrcweir             const char* pLine = aLine.GetBuffer();
326cdf0e10cSrcweir 
327cdf0e10cSrcweir             fonttype::type eType = (fonttype::type)atoi( pLine );
328cdf0e10cSrcweir             if( eType != fonttype::TrueType		&&
329cdf0e10cSrcweir                 eType != fonttype::Type1		&&
330cdf0e10cSrcweir                 eType != fonttype::Builtin
331cdf0e10cSrcweir                 )
332cdf0e10cSrcweir                 continue;
333cdf0e10cSrcweir             while( *pLine && *pLine != ';' )
334cdf0e10cSrcweir                 pLine++;
335cdf0e10cSrcweir             if( *pLine != ';' )
336cdf0e10cSrcweir                 continue;
337cdf0e10cSrcweir 
338cdf0e10cSrcweir             pLine++;
339cdf0e10cSrcweir             sal_Int32 nFonts = atoi( pLine );
340cdf0e10cSrcweir             for( int n = 0; n < nFonts; n++ )
341cdf0e10cSrcweir             {
342cdf0e10cSrcweir                 aStream.ReadLine( aLine );
343cdf0e10cSrcweir                 pLine = aLine.GetBuffer();
344cdf0e10cSrcweir                 int nLen = aLine.Len();
345cdf0e10cSrcweir 
346cdf0e10cSrcweir                 PrintFontManager::PrintFont* pFont = NULL;
347cdf0e10cSrcweir                 switch( eType )
348cdf0e10cSrcweir                 {
349cdf0e10cSrcweir                     case fonttype::TrueType:
350cdf0e10cSrcweir                         pFont = new PrintFontManager::TrueTypeFontFile();
351cdf0e10cSrcweir                         break;
352cdf0e10cSrcweir                     case fonttype::Type1:
353cdf0e10cSrcweir                         pFont = new PrintFontManager::Type1FontFile();
354cdf0e10cSrcweir                         break;
355cdf0e10cSrcweir                     case fonttype::Builtin:
356cdf0e10cSrcweir                         pFont = new PrintFontManager::BuiltinFont();
357cdf0e10cSrcweir                         break;
358cdf0e10cSrcweir                     default: break;
359cdf0e10cSrcweir                 }
360cdf0e10cSrcweir 
361cdf0e10cSrcweir                 for( nIndex = 0; nIndex < nLen && pLine[nIndex] != ';'; nIndex++ )
362cdf0e10cSrcweir                     ;
363cdf0e10cSrcweir 
364cdf0e10cSrcweir                 pFont->m_nFamilyName = pAtoms->getAtom( ATOM_FAMILYNAME,
365cdf0e10cSrcweir                                                         OUString( pLine, nIndex, RTL_TEXTENCODING_UTF8 ),
366cdf0e10cSrcweir                                                         sal_True );
367cdf0e10cSrcweir                 while( nIndex < nLen )
368cdf0e10cSrcweir                 {
369cdf0e10cSrcweir                     xub_StrLen nLastIndex = nIndex+1;
370cdf0e10cSrcweir                     for( nIndex = nLastIndex ; nIndex < nLen && pLine[nIndex] != ';'; nIndex++ )
371cdf0e10cSrcweir                         ;
372cdf0e10cSrcweir                     if( nIndex - nLastIndex )
373cdf0e10cSrcweir                     {
374cdf0e10cSrcweir                         OUString aAlias( pLine+nLastIndex, nIndex-nLastIndex, RTL_TEXTENCODING_UTF8 );
375cdf0e10cSrcweir                         pFont->m_aAliases.push_back( pAtoms->getAtom( ATOM_FAMILYNAME, aAlias, sal_True ) );
376cdf0e10cSrcweir                     }
377cdf0e10cSrcweir                 }
378cdf0e10cSrcweir                 aStream.ReadLine( aLine );
379cdf0e10cSrcweir                 pLine = aLine.GetBuffer();
380cdf0e10cSrcweir                 nLen = aLine.Len();
381cdf0e10cSrcweir 
382cdf0e10cSrcweir                 // get up to 20 token positions
383cdf0e10cSrcweir                 const int nMaxTokens = 20;
384cdf0e10cSrcweir                 int nTokenPos[nMaxTokens];
385cdf0e10cSrcweir                 nTokenPos[0] = 0;
386cdf0e10cSrcweir                 int nTokens = 1;
387cdf0e10cSrcweir                 for( int i = 0; i < nLen; i++ )
388cdf0e10cSrcweir                 {
389cdf0e10cSrcweir                     if( pLine[i] == ';' )
390cdf0e10cSrcweir                     {
391cdf0e10cSrcweir                         nTokenPos[nTokens++] = i+1;
392cdf0e10cSrcweir                         if( nTokens == nMaxTokens )
393cdf0e10cSrcweir                             break;
394cdf0e10cSrcweir                     }
395cdf0e10cSrcweir                 }
396cdf0e10cSrcweir                 if( nTokens < 18 )
397cdf0e10cSrcweir                 {
398cdf0e10cSrcweir                     delete pFont;
399cdf0e10cSrcweir                     continue;
400cdf0e10cSrcweir                 }
401cdf0e10cSrcweir                 int nCollEntry      = atoi( pLine );
402cdf0e10cSrcweir                 pFont->m_nPSName    = pAtoms->getAtom( ATOM_PSNAME, OUString( pLine + nTokenPos[1], nTokenPos[2]-nTokenPos[1]-1, RTL_TEXTENCODING_UTF8 ), sal_True );
403cdf0e10cSrcweir                 pFont->m_eItalic    = (italic::type)atoi( pLine+nTokenPos[2] );
404cdf0e10cSrcweir                 pFont->m_eWeight    = (weight::type)atoi( pLine+nTokenPos[3] );
405cdf0e10cSrcweir                 pFont->m_eWidth     = (width::type)atoi( pLine+nTokenPos[4] );
406cdf0e10cSrcweir                 pFont->m_ePitch     = (pitch::type)atoi( pLine+nTokenPos[5] );
407cdf0e10cSrcweir                 pFont->m_aEncoding  = (rtl_TextEncoding)atoi( pLine+nTokenPos[6] );
408cdf0e10cSrcweir                 pFont->m_nAscend    = atoi( pLine + nTokenPos[7] );
409cdf0e10cSrcweir                 pFont->m_nDescend   = atoi( pLine + nTokenPos[8] );
410cdf0e10cSrcweir                 pFont->m_nLeading   = atoi( pLine + nTokenPos[9] );
411cdf0e10cSrcweir                 pFont->m_bHaveVerticalSubstitutedGlyphs
412cdf0e10cSrcweir                                     = (atoi( pLine + nTokenPos[10] ) != 0);
413cdf0e10cSrcweir                 pFont->m_aGlobalMetricX.width
414cdf0e10cSrcweir                                     = atoi( pLine + nTokenPos[11] );
415cdf0e10cSrcweir                 pFont->m_aGlobalMetricX.height
416cdf0e10cSrcweir                                     = atoi( pLine + nTokenPos[12] );
417cdf0e10cSrcweir                 pFont->m_aGlobalMetricY.width
418cdf0e10cSrcweir                                     = atoi( pLine + nTokenPos[13] );
419cdf0e10cSrcweir                 pFont->m_aGlobalMetricY.height
420cdf0e10cSrcweir                                     = atoi( pLine + nTokenPos[14] );
421cdf0e10cSrcweir                 pFont->m_bUserOverride
422cdf0e10cSrcweir                                     = (atoi( pLine + nTokenPos[15] ) != 0);
423cdf0e10cSrcweir                 int nStyleTokenNr = 18;
424cdf0e10cSrcweir                 switch( eType )
425cdf0e10cSrcweir                 {
426cdf0e10cSrcweir                     case fonttype::TrueType:
427cdf0e10cSrcweir                         static_cast<PrintFontManager::TrueTypeFontFile*>(pFont)->m_nTypeFlags = atoi( pLine + nTokenPos[18] );
428cdf0e10cSrcweir                         static_cast<PrintFontManager::TrueTypeFontFile*>(pFont)->m_nCollectionEntry = nCollEntry;
429cdf0e10cSrcweir                         static_cast<PrintFontManager::TrueTypeFontFile*>(pFont)->m_nDirectory = nDir;
430cdf0e10cSrcweir                         static_cast<PrintFontManager::TrueTypeFontFile*>(pFont)->m_aFontFile = aFile;
431cdf0e10cSrcweir                         nStyleTokenNr++;
432cdf0e10cSrcweir                         break;
433cdf0e10cSrcweir                     case fonttype::Type1:
434cdf0e10cSrcweir                     {
435cdf0e10cSrcweir                         int nTokLen = (nTokens > 19 ) ? nTokenPos[19]-nTokenPos[18]-1 : nLen - nTokenPos[18];
436cdf0e10cSrcweir                         static_cast<PrintFontManager::Type1FontFile*>(pFont)->m_aMetricFile = OString( pLine + nTokenPos[18], nTokLen );
437cdf0e10cSrcweir                         static_cast<PrintFontManager::Type1FontFile*>(pFont)->m_nDirectory = nDir;
438cdf0e10cSrcweir                         static_cast<PrintFontManager::Type1FontFile*>(pFont)->m_aFontFile = aFile;
439cdf0e10cSrcweir                         nStyleTokenNr++;
440cdf0e10cSrcweir                     }
441cdf0e10cSrcweir                     break;
442cdf0e10cSrcweir                     case fonttype::Builtin:
443cdf0e10cSrcweir                         static_cast<PrintFontManager::BuiltinFont*>(pFont)->m_nDirectory = nDir;
444cdf0e10cSrcweir                         static_cast<PrintFontManager::BuiltinFont*>(pFont)->m_aMetricFile = aFile;
445cdf0e10cSrcweir                         break;
446cdf0e10cSrcweir                     default: break;
447cdf0e10cSrcweir                 }
448cdf0e10cSrcweir                 if( nTokens > nStyleTokenNr )
449cdf0e10cSrcweir                     pFont->m_aStyleName = OUString::intern( pLine + nTokenPos[nStyleTokenNr],
450cdf0e10cSrcweir                                                             nLen - nTokenPos[nStyleTokenNr],
451cdf0e10cSrcweir                                                             RTL_TEXTENCODING_UTF8 );
452cdf0e10cSrcweir 
453cdf0e10cSrcweir                 bool bObsolete = false;
454cdf0e10cSrcweir                 if( bKeepOnlyUserOverridden )
455cdf0e10cSrcweir                 {
456cdf0e10cSrcweir                     if( pFont->m_bUserOverride )
457cdf0e10cSrcweir                     {
458cdf0e10cSrcweir                         ByteString aFilePath = rManager.getDirectory( nDir );
459cdf0e10cSrcweir                         aFilePath.Append( '/' );
460cdf0e10cSrcweir                         aFilePath.Append( ByteString(aFile) );
461cdf0e10cSrcweir                         struct stat aStat;
462cdf0e10cSrcweir                         if( stat( aFilePath.GetBuffer(), &aStat )   ||
463cdf0e10cSrcweir                             ! S_ISREG( aStat.st_mode )              ||
464cdf0e10cSrcweir                             aStat.st_size < 16 )
465cdf0e10cSrcweir                         {
466cdf0e10cSrcweir                             bObsolete = true;
467cdf0e10cSrcweir                         }
468cdf0e10cSrcweir                         #if OSL_DEBUG_LEVEL > 2
469cdf0e10cSrcweir                         else
470cdf0e10cSrcweir                             fprintf( stderr, "keeping file %s in outdated cache entry due to user override\n",
471cdf0e10cSrcweir                                      aFilePath.GetBuffer() );
472cdf0e10cSrcweir                         #endif
473cdf0e10cSrcweir                     }
474cdf0e10cSrcweir                     else
475cdf0e10cSrcweir                         bObsolete = true;
476cdf0e10cSrcweir                 }
477cdf0e10cSrcweir                 if( bObsolete )
478cdf0e10cSrcweir                 {
479cdf0e10cSrcweir                     m_bDoFlush = true;
480cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 2
481cdf0e10cSrcweir                     fprintf( stderr, "removing obsolete font %s\n", aFile.getStr() );
482cdf0e10cSrcweir #endif
483cdf0e10cSrcweir                     delete pFont;
484cdf0e10cSrcweir                     continue;
485cdf0e10cSrcweir                 }
486cdf0e10cSrcweir 
487cdf0e10cSrcweir                 FontCacheEntry& rEntry = (*pDir)[aFile].m_aEntry;
488cdf0e10cSrcweir                 rEntry.push_back( pFont );
489cdf0e10cSrcweir             }
490cdf0e10cSrcweir         }
491cdf0e10cSrcweir     } while( ! aStream.IsEof() );
492cdf0e10cSrcweir }
493cdf0e10cSrcweir 
494cdf0e10cSrcweir /*
495cdf0e10cSrcweir  *  FontCache::updateDirTimestamp
496cdf0e10cSrcweir  */
updateDirTimestamp(int nDirID)497cdf0e10cSrcweir void FontCache::updateDirTimestamp( int nDirID )
498cdf0e10cSrcweir {
499cdf0e10cSrcweir     PrintFontManager& rManager( PrintFontManager::get() );
500cdf0e10cSrcweir     const OString& rDir = rManager.getDirectory( nDirID );
501cdf0e10cSrcweir 
502cdf0e10cSrcweir     struct stat aStat;
503cdf0e10cSrcweir     if( ! stat( rDir.getStr(), &aStat )	)
504cdf0e10cSrcweir         m_aCache[ nDirID ].m_nTimestamp = (sal_Int64)aStat.st_mtime;
505cdf0e10cSrcweir }
506cdf0e10cSrcweir 
507cdf0e10cSrcweir 
508cdf0e10cSrcweir /*
509cdf0e10cSrcweir  *  FontCache::copyPrintFont
510cdf0e10cSrcweir  */
copyPrintFont(const PrintFontManager::PrintFont * pFrom,PrintFontManager::PrintFont * pTo) const511cdf0e10cSrcweir void FontCache::copyPrintFont( const PrintFontManager::PrintFont* pFrom, PrintFontManager::PrintFont* pTo ) const
512cdf0e10cSrcweir {
513cdf0e10cSrcweir     if( pFrom->m_eType != pTo->m_eType )
514cdf0e10cSrcweir         return;
515cdf0e10cSrcweir     switch( pFrom->m_eType )
516cdf0e10cSrcweir     {
517cdf0e10cSrcweir         case fonttype::TrueType:
518cdf0e10cSrcweir             static_cast<PrintFontManager::TrueTypeFontFile*>(pTo)->m_nDirectory = static_cast<const PrintFontManager::TrueTypeFontFile*>(pFrom)->m_nDirectory;
519cdf0e10cSrcweir             static_cast<PrintFontManager::TrueTypeFontFile*>(pTo)->m_aFontFile = static_cast<const PrintFontManager::TrueTypeFontFile*>(pFrom)->m_aFontFile;
520cdf0e10cSrcweir             static_cast<PrintFontManager::TrueTypeFontFile*>(pTo)->m_nCollectionEntry = static_cast<const PrintFontManager::TrueTypeFontFile*>(pFrom)->m_nCollectionEntry;
521cdf0e10cSrcweir             static_cast<PrintFontManager::TrueTypeFontFile*>(pTo)->m_nTypeFlags = static_cast<const PrintFontManager::TrueTypeFontFile*>(pFrom)->m_nTypeFlags;
522cdf0e10cSrcweir             break;
523cdf0e10cSrcweir         case fonttype::Type1:
524cdf0e10cSrcweir             static_cast<PrintFontManager::Type1FontFile*>(pTo)->m_nDirectory = static_cast<const PrintFontManager::Type1FontFile*>(pFrom)->m_nDirectory;
525cdf0e10cSrcweir             static_cast<PrintFontManager::Type1FontFile*>(pTo)->m_aFontFile = static_cast<const PrintFontManager::Type1FontFile*>(pFrom)->m_aFontFile;
526cdf0e10cSrcweir             static_cast<PrintFontManager::Type1FontFile*>(pTo)->m_aMetricFile = static_cast<const PrintFontManager::Type1FontFile*>(pFrom)->m_aMetricFile;
527cdf0e10cSrcweir             break;
528cdf0e10cSrcweir         case fonttype::Builtin:
529cdf0e10cSrcweir             static_cast<PrintFontManager::BuiltinFont*>(pTo)->m_nDirectory = static_cast<const PrintFontManager::BuiltinFont*>(pFrom)->m_nDirectory;
530cdf0e10cSrcweir             static_cast<PrintFontManager::BuiltinFont*>(pTo)->m_aMetricFile = static_cast<const PrintFontManager::BuiltinFont*>(pFrom)->m_aMetricFile;
531cdf0e10cSrcweir             break;
532cdf0e10cSrcweir         default: break;
533cdf0e10cSrcweir     }
534cdf0e10cSrcweir     pTo->m_nFamilyName		= pFrom->m_nFamilyName;
535cdf0e10cSrcweir     pTo->m_aStyleName       = pFrom->m_aStyleName;
536cdf0e10cSrcweir     pTo->m_aAliases			= pFrom->m_aAliases;
537cdf0e10cSrcweir     pTo->m_nPSName			= pFrom->m_nPSName;
538cdf0e10cSrcweir     pTo->m_eItalic			= pFrom->m_eItalic;
539cdf0e10cSrcweir     pTo->m_eWeight			= pFrom->m_eWeight;
540cdf0e10cSrcweir     pTo->m_eWidth			= pFrom->m_eWidth;
541cdf0e10cSrcweir     pTo->m_ePitch			= pFrom->m_ePitch;
542cdf0e10cSrcweir     pTo->m_aEncoding		= pFrom->m_aEncoding;
543cdf0e10cSrcweir     pTo->m_aGlobalMetricX	= pFrom->m_aGlobalMetricX;
544cdf0e10cSrcweir     pTo->m_aGlobalMetricY	= pFrom->m_aGlobalMetricY;
545cdf0e10cSrcweir     pTo->m_nAscend			= pFrom->m_nAscend;
546cdf0e10cSrcweir     pTo->m_nDescend			= pFrom->m_nDescend;
547cdf0e10cSrcweir     pTo->m_nLeading			= pFrom->m_nLeading;
548cdf0e10cSrcweir     pTo->m_nXMin			= pFrom->m_nXMin;
549cdf0e10cSrcweir     pTo->m_nYMin			= pFrom->m_nYMin;
550cdf0e10cSrcweir     pTo->m_nXMax			= pFrom->m_nXMax;
551cdf0e10cSrcweir     pTo->m_nYMax			= pFrom->m_nYMax;
552cdf0e10cSrcweir     pTo->m_bHaveVerticalSubstitutedGlyphs = pFrom->m_bHaveVerticalSubstitutedGlyphs;
553cdf0e10cSrcweir     pTo->m_bUserOverride    = pFrom->m_bUserOverride;
554cdf0e10cSrcweir }
555cdf0e10cSrcweir 
556cdf0e10cSrcweir /*
557cdf0e10cSrcweir  *  FontCache::equalsPrintFont
558cdf0e10cSrcweir  */
equalsPrintFont(const PrintFontManager::PrintFont * pLeft,PrintFontManager::PrintFont * pRight) const559cdf0e10cSrcweir bool FontCache::equalsPrintFont( const PrintFontManager::PrintFont* pLeft, PrintFontManager::PrintFont* pRight ) const
560cdf0e10cSrcweir {
561cdf0e10cSrcweir     if( pLeft->m_eType != pRight->m_eType )
562cdf0e10cSrcweir         return false;
563cdf0e10cSrcweir     switch( pLeft->m_eType )
564cdf0e10cSrcweir     {
565cdf0e10cSrcweir         case fonttype::TrueType:
566cdf0e10cSrcweir         {
567cdf0e10cSrcweir             const PrintFontManager::TrueTypeFontFile* pLT = static_cast<const PrintFontManager::TrueTypeFontFile*>(pLeft);
568cdf0e10cSrcweir             const PrintFontManager::TrueTypeFontFile* pRT = static_cast<const PrintFontManager::TrueTypeFontFile*>(pRight);
569cdf0e10cSrcweir             if( pRT->m_nDirectory		!= pLT->m_nDirectory		||
570cdf0e10cSrcweir                 pRT->m_aFontFile		!= pLT->m_aFontFile			||
571cdf0e10cSrcweir                 pRT->m_nCollectionEntry	!= pLT->m_nCollectionEntry	||
572cdf0e10cSrcweir                 pRT->m_nTypeFlags		!= pLT->m_nTypeFlags )
573cdf0e10cSrcweir                 return false;
574cdf0e10cSrcweir         }
575cdf0e10cSrcweir         break;
576cdf0e10cSrcweir         case fonttype::Type1:
577cdf0e10cSrcweir         {
578cdf0e10cSrcweir             const PrintFontManager::Type1FontFile* pLT = static_cast<const PrintFontManager::Type1FontFile*>(pLeft);
579cdf0e10cSrcweir             const PrintFontManager::Type1FontFile* pRT = static_cast<const PrintFontManager::Type1FontFile*>(pRight);
580cdf0e10cSrcweir             if( pRT->m_nDirectory		!= pLT->m_nDirectory		||
581cdf0e10cSrcweir                 pRT->m_aFontFile		!= pLT->m_aFontFile			||
582cdf0e10cSrcweir                 pRT->m_aMetricFile		!= pLT->m_aMetricFile )
583cdf0e10cSrcweir                 return false;
584cdf0e10cSrcweir         }
585cdf0e10cSrcweir         break;
586cdf0e10cSrcweir         case fonttype::Builtin:
587cdf0e10cSrcweir         {
588cdf0e10cSrcweir             const PrintFontManager::BuiltinFont* pLT = static_cast<const PrintFontManager::BuiltinFont*>(pLeft);
589cdf0e10cSrcweir             const PrintFontManager::BuiltinFont* pRT = static_cast<const PrintFontManager::BuiltinFont*>(pRight);
590cdf0e10cSrcweir             if( pRT->m_nDirectory		!= pLT->m_nDirectory		||
591cdf0e10cSrcweir                 pRT->m_aMetricFile		!= pLT->m_aMetricFile )
592cdf0e10cSrcweir                 return false;
593cdf0e10cSrcweir         }
594cdf0e10cSrcweir         break;
595cdf0e10cSrcweir         default: break;
596cdf0e10cSrcweir     }
597cdf0e10cSrcweir     if( pRight->m_nFamilyName		!= pLeft->m_nFamilyName		||
598cdf0e10cSrcweir         pRight->m_aStyleName        != pLeft->m_aStyleName      ||
599cdf0e10cSrcweir         pRight->m_nPSName			!= pLeft->m_nPSName			||
600cdf0e10cSrcweir         pRight->m_eItalic			!= pLeft->m_eItalic			||
601cdf0e10cSrcweir         pRight->m_eWeight			!= pLeft->m_eWeight			||
602cdf0e10cSrcweir         pRight->m_eWidth			!= pLeft->m_eWidth			||
603cdf0e10cSrcweir         pRight->m_ePitch			!= pLeft->m_ePitch			||
604cdf0e10cSrcweir         pRight->m_aEncoding			!= pLeft->m_aEncoding		||
605cdf0e10cSrcweir         pRight->m_aGlobalMetricX	!= pLeft->m_aGlobalMetricX	||
606cdf0e10cSrcweir         pRight->m_aGlobalMetricY	!= pLeft->m_aGlobalMetricY	||
607cdf0e10cSrcweir         pRight->m_nAscend			!= pLeft->m_nAscend			||
608cdf0e10cSrcweir         pRight->m_nDescend			!= pLeft->m_nDescend		||
609cdf0e10cSrcweir         pRight->m_nLeading			!= pLeft->m_nLeading		||
610cdf0e10cSrcweir         pRight->m_nXMin				!= pLeft->m_nXMin			||
611cdf0e10cSrcweir         pRight->m_nYMin				!= pLeft->m_nYMin			||
612cdf0e10cSrcweir         pRight->m_nXMax				!= pLeft->m_nXMax			||
613cdf0e10cSrcweir         pRight->m_nYMax				!= pLeft->m_nYMax			||
614cdf0e10cSrcweir         pRight->m_bHaveVerticalSubstitutedGlyphs != pLeft->m_bHaveVerticalSubstitutedGlyphs ||
615cdf0e10cSrcweir         pRight->m_bUserOverride     != pLeft->m_bUserOverride
616cdf0e10cSrcweir         )
617cdf0e10cSrcweir         return false;
618cdf0e10cSrcweir     std::list< int >::const_iterator lit, rit;
619cdf0e10cSrcweir     for( lit = pLeft->m_aAliases.begin(), rit = pRight->m_aAliases.begin();
620cdf0e10cSrcweir          lit != pLeft->m_aAliases.end() && rit != pRight->m_aAliases.end() && (*lit) == (*rit);
621cdf0e10cSrcweir          ++lit, ++rit )
622cdf0e10cSrcweir         ;
623cdf0e10cSrcweir     return lit == pLeft->m_aAliases.end() && rit == pRight->m_aAliases.end();
624cdf0e10cSrcweir }
625cdf0e10cSrcweir 
626cdf0e10cSrcweir /*
627cdf0e10cSrcweir  *  FontCache::clonePrintFont
628cdf0e10cSrcweir  */
clonePrintFont(const PrintFontManager::PrintFont * pOldFont) const629cdf0e10cSrcweir PrintFontManager::PrintFont* FontCache::clonePrintFont( const PrintFontManager::PrintFont* pOldFont ) const
630cdf0e10cSrcweir {
631cdf0e10cSrcweir     PrintFontManager::PrintFont* pFont = NULL;
632cdf0e10cSrcweir     switch( pOldFont->m_eType )
633cdf0e10cSrcweir     {
634cdf0e10cSrcweir         case fonttype::TrueType:
635cdf0e10cSrcweir             pFont = new PrintFontManager::TrueTypeFontFile();
636cdf0e10cSrcweir             break;
637cdf0e10cSrcweir         case fonttype::Type1:
638cdf0e10cSrcweir             pFont = new PrintFontManager::Type1FontFile();
639cdf0e10cSrcweir             break;
640cdf0e10cSrcweir         case fonttype::Builtin:
641cdf0e10cSrcweir             pFont = new PrintFontManager::BuiltinFont();
642cdf0e10cSrcweir             break;
643cdf0e10cSrcweir         default: break;
644cdf0e10cSrcweir     }
645cdf0e10cSrcweir     if( pFont )
646cdf0e10cSrcweir     {
647cdf0e10cSrcweir         copyPrintFont( pOldFont, pFont );
648cdf0e10cSrcweir     }
649cdf0e10cSrcweir     return pFont;
650cdf0e10cSrcweir  }
651cdf0e10cSrcweir 
652cdf0e10cSrcweir /*
653cdf0e10cSrcweir  *  FontCache::getFontCacheFile
654cdf0e10cSrcweir  */
getFontCacheFile(int nDirID,const OString & rFile,list<PrintFontManager::PrintFont * > & rNewFonts) const655cdf0e10cSrcweir bool FontCache::getFontCacheFile( int nDirID, const OString& rFile, list< PrintFontManager::PrintFont* >& rNewFonts ) const
656cdf0e10cSrcweir {
657cdf0e10cSrcweir     bool bSuccess = false;
658cdf0e10cSrcweir 
659cdf0e10cSrcweir     FontCacheData::const_iterator dir = m_aCache.find( nDirID );
660cdf0e10cSrcweir     if( dir != m_aCache.end() )
661cdf0e10cSrcweir     {
662cdf0e10cSrcweir         FontDirMap::const_iterator entry = dir->second.m_aEntries.find( rFile );
663cdf0e10cSrcweir         if( entry != dir->second.m_aEntries.end() )
664cdf0e10cSrcweir         {
665cdf0e10cSrcweir             for( FontCacheEntry::const_iterator font = entry->second.m_aEntry.begin(); font != entry->second.m_aEntry.end(); ++font )
666cdf0e10cSrcweir             {
667cdf0e10cSrcweir                 bSuccess = true;
668cdf0e10cSrcweir                 PrintFontManager::PrintFont* pFont = clonePrintFont( *font );
669cdf0e10cSrcweir                 rNewFonts.push_back( pFont );
670cdf0e10cSrcweir             }
671cdf0e10cSrcweir         }
672cdf0e10cSrcweir     }
673cdf0e10cSrcweir     return bSuccess;
674cdf0e10cSrcweir }
675cdf0e10cSrcweir 
676cdf0e10cSrcweir /*
677cdf0e10cSrcweir  *  FontCache::updateFontCacheEntry
678cdf0e10cSrcweir  */
updateFontCacheEntry(const PrintFontManager::PrintFont * pFont,bool bFlush)679cdf0e10cSrcweir void FontCache::updateFontCacheEntry( const PrintFontManager::PrintFont* pFont, bool bFlush )
680cdf0e10cSrcweir {
681cdf0e10cSrcweir     PrintFontManager& rManager( PrintFontManager::get() );
682cdf0e10cSrcweir 
683cdf0e10cSrcweir     OString aFile;
684cdf0e10cSrcweir     int nDirID = 0;
685cdf0e10cSrcweir     switch( pFont->m_eType )
686cdf0e10cSrcweir     {
687cdf0e10cSrcweir         case fonttype::TrueType:
688cdf0e10cSrcweir             nDirID = static_cast<const PrintFontManager::TrueTypeFontFile*>(pFont)->m_nDirectory;
689cdf0e10cSrcweir             aFile = static_cast<const PrintFontManager::TrueTypeFontFile*>(pFont)->m_aFontFile;
690cdf0e10cSrcweir             break;
691cdf0e10cSrcweir         case fonttype::Type1:
692cdf0e10cSrcweir             nDirID = static_cast<const PrintFontManager::Type1FontFile*>(pFont)->m_nDirectory;
693cdf0e10cSrcweir             aFile = static_cast<const PrintFontManager::Type1FontFile*>(pFont)->m_aFontFile;
694cdf0e10cSrcweir             break;
695cdf0e10cSrcweir         case fonttype::Builtin:
696cdf0e10cSrcweir             nDirID = static_cast<const PrintFontManager::BuiltinFont*>(pFont)->m_nDirectory;
697cdf0e10cSrcweir             aFile = static_cast<const PrintFontManager::BuiltinFont*>(pFont)->m_aMetricFile;
698cdf0e10cSrcweir             break;
699cdf0e10cSrcweir         default:
700cdf0e10cSrcweir             return;
701cdf0e10cSrcweir     }
702cdf0e10cSrcweir     FontCacheData::const_iterator dir = m_aCache.find( nDirID );
703cdf0e10cSrcweir     FontDirMap::const_iterator entry;
704cdf0e10cSrcweir     FontCacheEntry::const_iterator font;
705cdf0e10cSrcweir     PrintFontManager::PrintFont* pCacheFont = NULL;
706cdf0e10cSrcweir 
707cdf0e10cSrcweir     if( dir != m_aCache.end() )
708cdf0e10cSrcweir     {
709cdf0e10cSrcweir         entry = dir->second.m_aEntries.find( aFile );
710cdf0e10cSrcweir         if( entry != dir->second.m_aEntries.end() )
711cdf0e10cSrcweir         {
712cdf0e10cSrcweir             for( font = entry->second.m_aEntry.begin(); font != entry->second.m_aEntry.end(); ++font )
713cdf0e10cSrcweir             {
714cdf0e10cSrcweir                 if( (*font)->m_eType == pFont->m_eType &&
715cdf0e10cSrcweir                     ( (*font)->m_eType != fonttype::TrueType ||
716cdf0e10cSrcweir                       static_cast<const PrintFontManager::TrueTypeFontFile*>(*font)->m_nCollectionEntry == static_cast<const PrintFontManager::TrueTypeFontFile*>(pFont)->m_nCollectionEntry
717cdf0e10cSrcweir                       ) )
718cdf0e10cSrcweir                     break;
719cdf0e10cSrcweir             }
720cdf0e10cSrcweir             if( font != entry->second.m_aEntry.end() )
721cdf0e10cSrcweir                 pCacheFont = *font;
722cdf0e10cSrcweir         }
723cdf0e10cSrcweir     }
724cdf0e10cSrcweir     else
725cdf0e10cSrcweir         createCacheDir( nDirID );
726cdf0e10cSrcweir 
727cdf0e10cSrcweir     if( pCacheFont )
728cdf0e10cSrcweir     {
729cdf0e10cSrcweir         if( ! equalsPrintFont( pFont, pCacheFont ) )
730cdf0e10cSrcweir         {
731cdf0e10cSrcweir             copyPrintFont( pFont, pCacheFont );
732cdf0e10cSrcweir             m_bDoFlush = true;
733cdf0e10cSrcweir         }
734cdf0e10cSrcweir     }
735cdf0e10cSrcweir     else
736cdf0e10cSrcweir     {
737cdf0e10cSrcweir         pCacheFont = clonePrintFont( pFont );
738cdf0e10cSrcweir         m_aCache[nDirID].m_aEntries[aFile].m_aEntry.push_back( pCacheFont );
739cdf0e10cSrcweir 
740cdf0e10cSrcweir         ByteString aPath = rManager.getDirectory( nDirID );
741cdf0e10cSrcweir         aPath.Append( '/' );
742cdf0e10cSrcweir         aPath.Append( ByteString( aFile ) );
743cdf0e10cSrcweir         m_bDoFlush = true;
744cdf0e10cSrcweir     }
745cdf0e10cSrcweir     if( bFlush )
746cdf0e10cSrcweir         flush();
747cdf0e10cSrcweir }
748cdf0e10cSrcweir 
749cdf0e10cSrcweir /*
750cdf0e10cSrcweir  *  FontCache::listDirectory
751cdf0e10cSrcweir  */
listDirectory(const OString & rDir,std::list<PrintFontManager::PrintFont * > & rNewFonts) const752cdf0e10cSrcweir bool FontCache::listDirectory( const OString& rDir, std::list< PrintFontManager::PrintFont* >& rNewFonts ) const
753cdf0e10cSrcweir {
754cdf0e10cSrcweir     PrintFontManager& rManager( PrintFontManager::get() );
755cdf0e10cSrcweir     int nDirID = rManager.getDirectoryAtom( rDir );
756cdf0e10cSrcweir     FontCacheData::const_iterator dir = m_aCache.find( nDirID );
757cdf0e10cSrcweir     bool bFound = (dir != m_aCache.end());
758cdf0e10cSrcweir 
759cdf0e10cSrcweir     if( bFound && !dir->second.m_bNoFiles )
760cdf0e10cSrcweir     {
761cdf0e10cSrcweir         for( FontDirMap::const_iterator file = dir->second.m_aEntries.begin(); file != dir->second.m_aEntries.end(); ++file )
762cdf0e10cSrcweir         {
763cdf0e10cSrcweir             for( FontCacheEntry::const_iterator font = file->second.m_aEntry.begin(); font != file->second.m_aEntry.end(); ++font )
764cdf0e10cSrcweir             {
765cdf0e10cSrcweir                 PrintFontManager::PrintFont* pFont = clonePrintFont( *font );
766cdf0e10cSrcweir                 rNewFonts.push_back( pFont );
767cdf0e10cSrcweir             }
768cdf0e10cSrcweir         }
769cdf0e10cSrcweir     }
770cdf0e10cSrcweir     return bFound;
771cdf0e10cSrcweir }
772cdf0e10cSrcweir 
773cdf0e10cSrcweir /*
774cdf0e10cSrcweir  *  FontCache::listDirectory
775cdf0e10cSrcweir  */
scanAdditionalFiles(const OString & rDir)776cdf0e10cSrcweir bool FontCache::scanAdditionalFiles( const OString& rDir )
777cdf0e10cSrcweir {
778cdf0e10cSrcweir     PrintFontManager& rManager( PrintFontManager::get() );
779cdf0e10cSrcweir     int nDirID = rManager.getDirectoryAtom( rDir );
780cdf0e10cSrcweir     FontCacheData::const_iterator dir = m_aCache.find( nDirID );
781cdf0e10cSrcweir     bool bFound = (dir != m_aCache.end());
782cdf0e10cSrcweir 
783cdf0e10cSrcweir     return (bFound && dir->second.m_bUserOverrideOnly);
784cdf0e10cSrcweir }
785cdf0e10cSrcweir 
786cdf0e10cSrcweir /*
787cdf0e10cSrcweir  *  FontCache::createCacheDir
788cdf0e10cSrcweir  */
createCacheDir(int nDirID)789cdf0e10cSrcweir void FontCache::createCacheDir( int nDirID )
790cdf0e10cSrcweir {
791cdf0e10cSrcweir     PrintFontManager& rManager( PrintFontManager::get() );
792cdf0e10cSrcweir 
793cdf0e10cSrcweir     const OString& rDir = rManager.getDirectory( nDirID );
794cdf0e10cSrcweir     struct stat aStat;
795cdf0e10cSrcweir     if( ! stat( rDir.getStr(), &aStat ) )
796cdf0e10cSrcweir         m_aCache[nDirID].m_nTimestamp = (sal_Int64)aStat.st_mtime;
797cdf0e10cSrcweir }
798cdf0e10cSrcweir 
799cdf0e10cSrcweir /*
800cdf0e10cSrcweir  *  FontCache::markEmptyDir
801cdf0e10cSrcweir  */
markEmptyDir(int nDirID,bool bNoFiles)802cdf0e10cSrcweir void FontCache::markEmptyDir( int nDirID, bool bNoFiles )
803cdf0e10cSrcweir {
804cdf0e10cSrcweir     createCacheDir( nDirID );
805cdf0e10cSrcweir     m_aCache[nDirID].m_bNoFiles = bNoFiles;
806cdf0e10cSrcweir     m_bDoFlush = true;
807cdf0e10cSrcweir }
808