LCOV - code coverage report
Current view: top level - vcl/generic/fontmanager - fontcache.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 366 414 88.4 %
Date: 2015-06-13 12:38:46 Functions: 12 13 92.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       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/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      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 .
      18             :  */
      19             : 
      20             : #include <cstdlib>
      21             : #include <cstring>
      22             : 
      23             : #include "fontcache.hxx"
      24             : 
      25             : #include "osl/thread.h"
      26             : 
      27             : #include "unotools/atom.hxx"
      28             : 
      29             : #include "tools/stream.hxx"
      30             : 
      31             : #include <rtl/strbuf.hxx>
      32             : 
      33             : #include <unistd.h>
      34             : #include <sys/stat.h>
      35             : 
      36             : #if OSL_DEBUG_LEVEL >1
      37             : #include <cstdio>
      38             : #endif
      39             : 
      40             : #define CACHE_MAGIC "LibreOffice PspFontCacheFile format 6"
      41             : 
      42             : using namespace std;
      43             : using namespace psp;
      44             : using namespace utl;
      45             : 
      46             : /*
      47             :  *  FontCache constructor
      48             :  */
      49             : 
      50         205 : FontCache::FontCache()
      51             : {
      52         205 :     m_bDoFlush = false;
      53         205 :     m_aCacheFile = getOfficePath( UserPath );
      54         205 :     if( !m_aCacheFile.isEmpty() )
      55             :     {
      56         205 :         m_aCacheFile += "/user/psprint/pspfontcache";
      57         205 :         read();
      58             :     }
      59         205 : }
      60             : 
      61             : /*
      62             :  *  FontCache destructor
      63             :  */
      64             : 
      65         410 : FontCache::~FontCache()
      66             : {
      67         205 :     clearCache();
      68         205 : }
      69             : 
      70             : /*
      71             :  *  FontCache::clearCache
      72             :  */
      73         205 : void FontCache::clearCache()
      74             : {
      75        2665 :     for( FontCacheData::iterator dir_it = m_aCache.begin(); dir_it != m_aCache.end(); ++dir_it )
      76             :     {
      77       50430 :         for( FontDirMap::iterator entry_it = dir_it->second.m_aEntries.begin(); entry_it != dir_it->second.m_aEntries.end(); ++entry_it )
      78             :         {
      79       96145 :             for( FontCacheEntry::iterator font_it = entry_it->second.m_aEntry.begin(); font_it != entry_it->second.m_aEntry.end(); ++font_it )
      80       48175 :                 delete *font_it;
      81             :         }
      82             :     }
      83         205 :     m_aCache.clear();
      84         205 : }
      85             : 
      86             : /*
      87             :  *  FontCache::Commit
      88             :  */
      89             : 
      90         205 : void FontCache::flush()
      91             : {
      92         205 :     if( ! m_bDoFlush || m_aCacheFile.isEmpty() )
      93         294 :         return;
      94             : 
      95          58 :     SvFileStream aStream;
      96          58 :     aStream.Open( m_aCacheFile, StreamMode::WRITE | StreamMode::TRUNC );
      97          58 :     if( ! (aStream.IsOpen() && aStream.IsWritable()) )
      98             :     {
      99             : #if OSL_DEBUG_LEVEL > 1
     100             :         fprintf( stderr, "FontCache::flush: opening cache file %s failed\n", OUStringToOString(m_aCacheFile, osl_getThreadTextEncoding()).getStr() );
     101             : #endif
     102           0 :         return;
     103             :     }
     104             : 
     105          58 :     aStream.SetLineDelimiter( LINEEND_LF );
     106          58 :     aStream.WriteLine( CACHE_MAGIC );
     107             : 
     108          58 :     PrintFontManager& rManager( PrintFontManager::get() );
     109          58 :     MultiAtomProvider* pAtoms = rManager.m_pAtoms;
     110             : 
     111         754 :     for( FontCacheData::const_iterator dir_it = m_aCache.begin(); dir_it != m_aCache.end(); ++ dir_it )
     112             :     {
     113         696 :         const FontDirMap& rDir( dir_it->second.m_aEntries );
     114             : 
     115         696 :         OString aDirectory(rManager.getDirectory(dir_it->first));
     116        1392 :         OStringBuffer aLine("FontCacheDirectory:");
     117         696 :         aLine.append(dir_it->second.m_nTimestamp);
     118         696 :         aLine.append(':');
     119         696 :         aLine.append(aDirectory);
     120         696 :         if( rDir.empty() && dir_it->second.m_bNoFiles )
     121           0 :             aLine.insert(0, "Empty");
     122         696 :         aStream.WriteLine(aLine.makeStringAndClear());
     123             : 
     124       14268 :         for( FontDirMap::const_iterator entry_it = rDir.begin(); entry_it != rDir.end(); ++entry_it )
     125             :         {
     126             :             // insert cache entries
     127       13572 :             const FontCacheEntry& rEntry( entry_it->second.m_aEntry );
     128       13572 :             if( rEntry.begin() == rEntry.end() )
     129           0 :                 continue;
     130             : 
     131       13572 :             aLine.append("File:");
     132       13572 :             aLine.append(entry_it->first);
     133       13572 :             aStream.WriteLine(aLine.makeStringAndClear());
     134             : 
     135       13572 :             int nEntrySize = entry_it->second.m_aEntry.size();
     136             :             // write: type;nfonts
     137       13572 :             aLine.append(static_cast<sal_Int32>(rEntry.front()->m_eType));
     138       13572 :             aLine.append(';');
     139       13572 :             aLine.append(static_cast<sal_Int32>(nEntrySize));
     140       13572 :             aStream.WriteLine(aLine.makeStringAndClear());
     141             : 
     142       13572 :             sal_Int32 nSubEntry = 0;
     143       27202 :             for( FontCacheEntry::const_iterator it = rEntry.begin(); it != rEntry.end(); ++it, nSubEntry++ )
     144             :             {
     145             :                 /*
     146             :                  *  for each font entry write:
     147             :                  *  name[;name[;name]]
     148             :                  *  fontnr;PSName;italic;weight;width;pitch;encoding;ascend;descend;leading;vsubst;gxw;gxh;gyw;gyh;useroverrride;embed;antialias[;{metricfile,typeflags}][;stylename]
     149             :                  */
     150       13630 :                 if( nEntrySize > 1 )
     151         116 :                     nSubEntry = static_cast<const PrintFontManager::TrueTypeFontFile*>(*it)->m_nCollectionEntry;
     152             :                 else
     153       13514 :                     nSubEntry = 0;
     154             : 
     155       13630 :                 aLine.append(OUStringToOString(pAtoms->getString( ATOM_FAMILYNAME, (*it)->m_nFamilyName), RTL_TEXTENCODING_UTF8));
     156       14036 :                 for( ::std::list< int >::const_iterator name_it = (*it)->m_aAliases.begin(); name_it != (*it)->m_aAliases.end(); ++name_it )
     157             :                 {
     158         406 :                     const OUString& rAdd( pAtoms->getString( ATOM_FAMILYNAME, *name_it ) );
     159         406 :                     if( !rAdd.isEmpty() )
     160             :                     {
     161         406 :                         aLine.append(';');
     162         406 :                         aLine.append(OUStringToOString(rAdd, RTL_TEXTENCODING_UTF8));
     163             :                     }
     164             :                 }
     165       13630 :                 aStream.WriteLine(aLine.makeStringAndClear());
     166             : 
     167       13630 :                 const OUString& rPSName( pAtoms->getString( ATOM_PSNAME, (*it)->m_nPSName ) );
     168       13630 :                 aLine.append(nSubEntry);
     169       13630 :                 aLine.append(';');
     170       13630 :                 aLine.append(OUStringToOString(rPSName, RTL_TEXTENCODING_UTF8));
     171       13630 :                 aLine.append(';');
     172       13630 :                 aLine.append(static_cast<sal_Int32>((*it)->m_eItalic));
     173       13630 :                 aLine.append(';');
     174       13630 :                 aLine.append(static_cast<sal_Int32>((*it)->m_eWeight));
     175       13630 :                 aLine.append(';');
     176       13630 :                 aLine.append(static_cast<sal_Int32>((*it)->m_eWidth));
     177       13630 :                 aLine.append(';');
     178       13630 :                 aLine.append(static_cast<sal_Int32>((*it)->m_ePitch));
     179       13630 :                 aLine.append(';');
     180       13630 :                 aLine.append(static_cast<sal_Int32>((*it)->m_aEncoding));
     181       13630 :                 aLine.append(';');
     182       13630 :                 aLine.append(static_cast<sal_Int32>((*it)->m_nAscend));
     183       13630 :                 aLine.append(';');
     184       13630 :                 aLine.append(static_cast<sal_Int32>((*it)->m_nDescend));
     185       13630 :                 aLine.append(';');
     186       13630 :                 aLine.append(static_cast<sal_Int32>((*it)->m_nLeading));
     187       13630 :                 aLine.append(';');
     188       13630 :                 aLine.append((*it)->m_bHaveVerticalSubstitutedGlyphs ? '1' : '0');
     189       13630 :                 aLine.append(';');
     190       13630 :                 aLine.append(static_cast<sal_Int32>((*it)->m_aGlobalMetricX.width ));
     191       13630 :                 aLine.append(';');
     192       13630 :                 aLine.append(static_cast<sal_Int32>((*it)->m_aGlobalMetricX.height));
     193       13630 :                 aLine.append(';');
     194       13630 :                 aLine.append(static_cast<sal_Int32>((*it)->m_aGlobalMetricY.width ));
     195       13630 :                 aLine.append(';');
     196       13630 :                 aLine.append(static_cast<sal_Int32>((*it)->m_aGlobalMetricY.height));
     197       13630 :                 aLine.append(';');
     198       13630 :                 aLine.append((*it)->m_bUserOverride ? '1' : '0');
     199       13630 :                 aLine.append(';');
     200       13630 :                 aLine.append(static_cast<sal_Int32>(0));
     201       13630 :                 aLine.append(';');
     202       13630 :                 aLine.append(static_cast<sal_Int32>(0));
     203             : 
     204       13630 :                 switch( (*it)->m_eType )
     205             :                 {
     206             :                     case fonttype::Type1:
     207        3654 :                         aLine.append(';');
     208        3654 :                         aLine.append(static_cast<const PrintFontManager::Type1FontFile*>(*it)->m_aMetricFile);
     209        3654 :                         break;
     210             :                     case fonttype::TrueType:
     211        9976 :                         aLine.append(';');
     212        9976 :                         aLine.append(static_cast<sal_Int32>(static_cast<const PrintFontManager::TrueTypeFontFile*>(*it)->m_nTypeFlags));
     213        9976 :                         break;
     214           0 :                     default: break;
     215             :                 }
     216       13630 :                 if( !(*it)->m_aStyleName.isEmpty() )
     217             :                 {
     218       13630 :                     aLine.append(';');
     219       13630 :                     aLine.append(OUStringToOString((*it)->m_aStyleName, RTL_TEXTENCODING_UTF8));
     220             :                 }
     221       13630 :                 aStream.WriteLine(aLine.makeStringAndClear());
     222             :             }
     223       13572 :             aStream.WriteLine(OString());
     224             :         }
     225         696 :     }
     226          58 :     m_bDoFlush = false;
     227             : }
     228             : 
     229             : /*
     230             :  * FontCache::read
     231             :  */
     232             : 
     233         205 : void FontCache::read()
     234             : {
     235         205 :     PrintFontManager& rManager( PrintFontManager::get() );
     236         205 :     MultiAtomProvider* pAtoms = rManager.m_pAtoms;
     237             : 
     238         205 :     SvFileStream aStream( m_aCacheFile, StreamMode::READ );
     239         205 :     if( ! aStream.IsOpen() )
     240             :     {
     241             : #if OSL_DEBUG_LEVEL > 1
     242             :         fprintf( stderr, "FontCache::read: opening cache file %s failed\n", OUStringToOString(m_aCacheFile, osl_getThreadTextEncoding()).getStr() );
     243             : #endif
     244          58 :         return;
     245             :     }
     246             : 
     247         294 :     OString aLine;
     248         147 :     aStream.ReadLine( aLine );
     249         147 :     if ( !(aLine == CACHE_MAGIC) )
     250             :     {
     251             :         #if OSL_DEBUG_LEVEL >1
     252             :         fprintf( stderr, "FontCache::read: cache file %s fails magic test\n", OUStringToOString(m_aCacheFile, osl_getThreadTextEncoding()).getStr() );
     253             :         #endif
     254           0 :         return;
     255             :     }
     256             : 
     257         147 :     int nDir = 0;
     258         147 :     FontDirMap* pDir = NULL;
     259         147 :     bool bKeepOnlyUserOverridden = false;
     260       70707 :     do
     261             :     {
     262       70707 :         aStream.ReadLine( aLine );
     263      139650 :         if( aLine.startsWith("FontCacheDirectory:") ||
     264       68943 :             aLine.startsWith("EmptyFontCacheDirectory:") )
     265             :         {
     266        1764 :             bool bEmpty = aLine.startsWith("Empty");
     267        1764 :             sal_Int32 nSearchIndex = bEmpty ? 24 : 19;
     268             : 
     269        1764 :             OString aDir;
     270        1764 :             sal_Int64 nTimestamp = 0;
     271        1764 :             sal_Int32 nTEnd = aLine.indexOf( ':', nSearchIndex );
     272        1764 :             if( nTEnd != -1 )
     273             :             {
     274        1764 :                 OString aTimeStamp = aLine.copy( nSearchIndex, nTEnd - nSearchIndex );
     275        1764 :                 nTimestamp = aTimeStamp.toInt64();
     276        1764 :                 aDir = aLine.copy( nTEnd+1 );
     277             :             }
     278             :             else
     279             :             {
     280             :                 // invalid format, remove
     281           0 :                 pDir = NULL;
     282           0 :                 nDir = 0;
     283           0 :                 m_bDoFlush = true;
     284           0 :                 continue;
     285             :             }
     286             : 
     287             :             // is the directory modified ?
     288             :             struct stat aStat;
     289        3528 :             if( stat( aDir.getStr(), &aStat )               ||
     290        1764 :                 ! S_ISDIR(aStat.st_mode) )
     291             :             {
     292             :                 // remove outdated cache data
     293           0 :                 pDir = NULL;
     294           0 :                 nDir = 0;
     295           0 :                 m_bDoFlush = true;
     296           0 :                 continue;
     297             :             }
     298             :             else
     299             :             {
     300        1764 :                 nDir = rManager.getDirectoryAtom( aDir, true );
     301        1764 :                 m_aCache[ nDir ].m_nTimestamp = (sal_Int64)aStat.st_mtime;
     302        1764 :                 m_aCache[ nDir ].m_bNoFiles = bEmpty;
     303        1764 :                 pDir = bEmpty ? NULL : &m_aCache[ nDir ].m_aEntries;
     304        1764 :                 bKeepOnlyUserOverridden = ((sal_Int64)aStat.st_mtime != nTimestamp);
     305        1764 :                 m_aCache[ nDir ].m_bUserOverrideOnly = bKeepOnlyUserOverridden;
     306        1764 :             }
     307             :         }
     308       68943 :         else if( pDir && aLine.startsWith("File:") )
     309             :         {
     310       34398 :             OString aFile( aLine.copy( 5 ) );
     311       34398 :             aStream.ReadLine( aLine );
     312             : 
     313       34398 :             const char* pLine = aLine.getStr();
     314             : 
     315       34398 :             fonttype::type eType = (fonttype::type)atoi( pLine );
     316       34398 :             if( eType != fonttype::TrueType     &&
     317             :                 eType != fonttype::Type1 )
     318           0 :                 continue;
     319      103194 :             while( *pLine && *pLine != ';' )
     320       34398 :                 pLine++;
     321       34398 :             if( *pLine != ';' )
     322           0 :                 continue;
     323             : 
     324       34398 :             pLine++;
     325       34398 :             sal_Int32 nFonts = atoi( pLine );
     326       68943 :             for( int n = 0; n < nFonts; n++ )
     327             :             {
     328       34545 :                 aStream.ReadLine( aLine );
     329       34545 :                 pLine = aLine.getStr();
     330       34545 :                 int nLen = aLine.getLength();
     331             : 
     332       34545 :                 PrintFontManager::PrintFont* pFont = NULL;
     333       34545 :                 switch( eType )
     334             :                 {
     335             :                     case fonttype::TrueType:
     336       25284 :                         pFont = new PrintFontManager::TrueTypeFontFile();
     337       25284 :                         break;
     338             :                     case fonttype::Type1:
     339        9261 :                         pFont = new PrintFontManager::Type1FontFile();
     340        9261 :                         break;
     341           0 :                     default: break;
     342             :                 }
     343             : 
     344             :                 sal_Int32 nIndex;
     345             : 
     346       34545 :                 for( nIndex = 0; nIndex < nLen && pLine[nIndex] != ';'; nIndex++ )
     347             :                     ;
     348             : 
     349             :                 pFont->m_nFamilyName = pAtoms->getAtom( ATOM_FAMILYNAME,
     350             :                                                         OUString( pLine, nIndex, RTL_TEXTENCODING_UTF8 ),
     351       34545 :                                                         true );
     352       70119 :                 while( nIndex < nLen )
     353             :                 {
     354        1029 :                     sal_Int32 nLastIndex = nIndex+1;
     355        1029 :                     for( nIndex = nLastIndex ; nIndex < nLen && pLine[nIndex] != ';'; nIndex++ )
     356             :                         ;
     357        1029 :                     if( nIndex - nLastIndex )
     358             :                     {
     359        1029 :                         OUString aAlias( pLine+nLastIndex, nIndex-nLastIndex, RTL_TEXTENCODING_UTF8 );
     360        1029 :                         pFont->m_aAliases.push_back( pAtoms->getAtom( ATOM_FAMILYNAME, aAlias, true ) );
     361             :                     }
     362             :                 }
     363       34545 :                 aStream.ReadLine( aLine );
     364       34545 :                 pLine = aLine.getStr();
     365       34545 :                 nLen = aLine.getLength();
     366             : 
     367             :                 // get up to 20 token positions
     368       34545 :                 const int nMaxTokens = 20;
     369             :                 int nTokenPos[nMaxTokens];
     370       34545 :                 nTokenPos[0] = 0;
     371       34545 :                 int nTokens = 1;
     372     2683779 :                 for( int i = 0; i < nLen; i++ )
     373             :                 {
     374     2683779 :                     if( pLine[i] == ';' )
     375             :                     {
     376      656355 :                         nTokenPos[nTokens++] = i+1;
     377      656355 :                         if( nTokens == nMaxTokens )
     378       34545 :                             break;
     379             :                     }
     380             :                 }
     381       34545 :                 if( nTokens < 18 )
     382             :                 {
     383           0 :                     delete pFont;
     384           0 :                     continue;
     385             :                 }
     386       34545 :                 int nCollEntry      = atoi( pLine );
     387       34545 :                 pFont->m_nPSName    = pAtoms->getAtom( ATOM_PSNAME, OUString( pLine + nTokenPos[1], nTokenPos[2]-nTokenPos[1]-1, RTL_TEXTENCODING_UTF8 ), true );
     388       34545 :                 pFont->m_eItalic    = (FontItalic)atoi( pLine+nTokenPos[2] );
     389       34545 :                 pFont->m_eWeight    = (FontWeight)atoi( pLine+nTokenPos[3] );
     390       34545 :                 pFont->m_eWidth     = (FontWidth)atoi( pLine+nTokenPos[4] );
     391       34545 :                 pFont->m_ePitch     = (FontPitch)atoi( pLine+nTokenPos[5] );
     392       34545 :                 pFont->m_aEncoding  = (rtl_TextEncoding)atoi( pLine+nTokenPos[6] );
     393       34545 :                 pFont->m_nAscend    = atoi( pLine + nTokenPos[7] );
     394       34545 :                 pFont->m_nDescend   = atoi( pLine + nTokenPos[8] );
     395       34545 :                 pFont->m_nLeading   = atoi( pLine + nTokenPos[9] );
     396             :                 pFont->m_bHaveVerticalSubstitutedGlyphs
     397       34545 :                                     = (atoi( pLine + nTokenPos[10] ) != 0);
     398             :                 pFont->m_aGlobalMetricX.width
     399       34545 :                                     = atoi( pLine + nTokenPos[11] );
     400             :                 pFont->m_aGlobalMetricX.height
     401       34545 :                                     = atoi( pLine + nTokenPos[12] );
     402             :                 pFont->m_aGlobalMetricY.width
     403       34545 :                                     = atoi( pLine + nTokenPos[13] );
     404             :                 pFont->m_aGlobalMetricY.height
     405       34545 :                                     = atoi( pLine + nTokenPos[14] );
     406             :                 pFont->m_bUserOverride
     407       34545 :                                     = (atoi( pLine + nTokenPos[15] ) != 0);
     408       34545 :                 int nStyleTokenNr = 18;
     409       34545 :                 switch( eType )
     410             :                 {
     411             :                     case fonttype::TrueType:
     412       25284 :                         static_cast<PrintFontManager::TrueTypeFontFile*>(pFont)->m_nTypeFlags = atoi( pLine + nTokenPos[18] );
     413       25284 :                         static_cast<PrintFontManager::TrueTypeFontFile*>(pFont)->m_nCollectionEntry = nCollEntry;
     414       25284 :                         static_cast<PrintFontManager::TrueTypeFontFile*>(pFont)->m_nDirectory = nDir;
     415       25284 :                         static_cast<PrintFontManager::TrueTypeFontFile*>(pFont)->m_aFontFile = aFile;
     416       25284 :                         nStyleTokenNr++;
     417       25284 :                         break;
     418             :                     case fonttype::Type1:
     419             :                     {
     420        9261 :                         int nTokLen = (nTokens > 19 ) ? nTokenPos[19]-nTokenPos[18]-1 : nLen - nTokenPos[18];
     421        9261 :                         static_cast<PrintFontManager::Type1FontFile*>(pFont)->m_aMetricFile = OString( pLine + nTokenPos[18], nTokLen );
     422        9261 :                         static_cast<PrintFontManager::Type1FontFile*>(pFont)->m_nDirectory = nDir;
     423        9261 :                         static_cast<PrintFontManager::Type1FontFile*>(pFont)->m_aFontFile = aFile;
     424        9261 :                         nStyleTokenNr++;
     425             :                     }
     426        9261 :                     break;
     427           0 :                     default: break;
     428             :                 }
     429       34545 :                 if( nTokens > nStyleTokenNr )
     430       69090 :                     pFont->m_aStyleName = OUString::intern( pLine + nTokenPos[nStyleTokenNr],
     431       34545 :                                                             nLen - nTokenPos[nStyleTokenNr],
     432       34545 :                                                             RTL_TEXTENCODING_UTF8 );
     433             : 
     434       34545 :                 bool bObsolete = false;
     435       34545 :                 if( bKeepOnlyUserOverridden )
     436             :                 {
     437           0 :                     if( pFont->m_bUserOverride )
     438             :                     {
     439           0 :                         OStringBuffer aFilePath(rManager.getDirectory(nDir));
     440           0 :                         aFilePath.append('/').append(aFile);
     441             :                         struct stat aStat;
     442           0 :                         if( stat( aFilePath.getStr(), &aStat )   ||
     443           0 :                             ! S_ISREG( aStat.st_mode )              ||
     444           0 :                             aStat.st_size < 16 )
     445             :                         {
     446           0 :                             bObsolete = true;
     447           0 :                         }
     448             :                         #if OSL_DEBUG_LEVEL > 2
     449             :                         else
     450             :                             fprintf( stderr, "keeping file %s in outdated cache entry due to user override\n",
     451             :                                      aFilePath.getStr() );
     452             :                         #endif
     453             :                     }
     454             :                     else
     455           0 :                         bObsolete = true;
     456             :                 }
     457       34545 :                 if( bObsolete )
     458             :                 {
     459           0 :                     m_bDoFlush = true;
     460             : #if OSL_DEBUG_LEVEL > 2
     461             :                     fprintf( stderr, "removing obsolete font %s\n", aFile.getStr() );
     462             : #endif
     463           0 :                     delete pFont;
     464           0 :                     continue;
     465             :                 }
     466             : 
     467       34545 :                 FontCacheEntry& rEntry = (*pDir)[aFile].m_aEntry;
     468       34545 :                 rEntry.push_back( pFont );
     469       34398 :             }
     470             :         }
     471       70854 :     } while( ! aStream.IsEof() );
     472             : }
     473             : 
     474             : /*
     475             :  *  FontCache::copyPrintFont
     476             :  */
     477       48643 : void FontCache::copyPrintFont( const PrintFontManager::PrintFont* pFrom, PrintFontManager::PrintFont* pTo )
     478             : {
     479       48643 :     if( pFrom->m_eType != pTo->m_eType )
     480       48643 :         return;
     481       48643 :     switch( pFrom->m_eType )
     482             :     {
     483             :         case fonttype::TrueType:
     484       35728 :             static_cast<PrintFontManager::TrueTypeFontFile*>(pTo)->m_nDirectory = static_cast<const PrintFontManager::TrueTypeFontFile*>(pFrom)->m_nDirectory;
     485       35728 :             static_cast<PrintFontManager::TrueTypeFontFile*>(pTo)->m_aFontFile = static_cast<const PrintFontManager::TrueTypeFontFile*>(pFrom)->m_aFontFile;
     486       35728 :             static_cast<PrintFontManager::TrueTypeFontFile*>(pTo)->m_nCollectionEntry = static_cast<const PrintFontManager::TrueTypeFontFile*>(pFrom)->m_nCollectionEntry;
     487       35728 :             static_cast<PrintFontManager::TrueTypeFontFile*>(pTo)->m_nTypeFlags = static_cast<const PrintFontManager::TrueTypeFontFile*>(pFrom)->m_nTypeFlags;
     488       35728 :             break;
     489             :         case fonttype::Type1:
     490       12915 :             static_cast<PrintFontManager::Type1FontFile*>(pTo)->m_nDirectory = static_cast<const PrintFontManager::Type1FontFile*>(pFrom)->m_nDirectory;
     491       12915 :             static_cast<PrintFontManager::Type1FontFile*>(pTo)->m_aFontFile = static_cast<const PrintFontManager::Type1FontFile*>(pFrom)->m_aFontFile;
     492       12915 :             static_cast<PrintFontManager::Type1FontFile*>(pTo)->m_aMetricFile = static_cast<const PrintFontManager::Type1FontFile*>(pFrom)->m_aMetricFile;
     493       12915 :             break;
     494           0 :         default: break;
     495             :     }
     496       48643 :     pTo->m_nFamilyName      = pFrom->m_nFamilyName;
     497       48643 :     pTo->m_aStyleName       = pFrom->m_aStyleName;
     498       48643 :     pTo->m_aAliases         = pFrom->m_aAliases;
     499       48643 :     pTo->m_nPSName          = pFrom->m_nPSName;
     500       48643 :     pTo->m_eItalic          = pFrom->m_eItalic;
     501       48643 :     pTo->m_eWeight          = pFrom->m_eWeight;
     502       48643 :     pTo->m_eWidth           = pFrom->m_eWidth;
     503       48643 :     pTo->m_ePitch           = pFrom->m_ePitch;
     504       48643 :     pTo->m_aEncoding        = pFrom->m_aEncoding;
     505       48643 :     pTo->m_aGlobalMetricX   = pFrom->m_aGlobalMetricX;
     506       48643 :     pTo->m_aGlobalMetricY   = pFrom->m_aGlobalMetricY;
     507       48643 :     pTo->m_nAscend          = pFrom->m_nAscend;
     508       48643 :     pTo->m_nDescend         = pFrom->m_nDescend;
     509       48643 :     pTo->m_nLeading         = pFrom->m_nLeading;
     510       48643 :     pTo->m_nXMin            = pFrom->m_nXMin;
     511       48643 :     pTo->m_nYMin            = pFrom->m_nYMin;
     512       48643 :     pTo->m_nXMax            = pFrom->m_nXMax;
     513       48643 :     pTo->m_nYMax            = pFrom->m_nYMax;
     514       48643 :     pTo->m_bHaveVerticalSubstitutedGlyphs = pFrom->m_bHaveVerticalSubstitutedGlyphs;
     515       48643 :     pTo->m_bUserOverride    = pFrom->m_bUserOverride;
     516             : }
     517             : 
     518             : /*
     519             :  *  FontCache::equalsPrintFont
     520             :  */
     521       34955 : bool FontCache::equalsPrintFont( const PrintFontManager::PrintFont* pLeft, PrintFontManager::PrintFont* pRight )
     522             : {
     523       34955 :     if( pLeft->m_eType != pRight->m_eType )
     524           0 :         return false;
     525       34955 :     switch( pLeft->m_eType )
     526             :     {
     527             :         case fonttype::TrueType:
     528             :         {
     529       25694 :             const PrintFontManager::TrueTypeFontFile* pLT = static_cast<const PrintFontManager::TrueTypeFontFile*>(pLeft);
     530       25694 :             const PrintFontManager::TrueTypeFontFile* pRT = static_cast<const PrintFontManager::TrueTypeFontFile*>(pRight);
     531       77082 :             if( pRT->m_nDirectory       != pLT->m_nDirectory        ||
     532       51388 :                 pRT->m_aFontFile        != pLT->m_aFontFile         ||
     533       77082 :                 pRT->m_nCollectionEntry != pLT->m_nCollectionEntry  ||
     534       25694 :                 pRT->m_nTypeFlags       != pLT->m_nTypeFlags )
     535           0 :                 return false;
     536             :         }
     537       25694 :         break;
     538             :         case fonttype::Type1:
     539             :         {
     540        9261 :             const PrintFontManager::Type1FontFile* pLT = static_cast<const PrintFontManager::Type1FontFile*>(pLeft);
     541        9261 :             const PrintFontManager::Type1FontFile* pRT = static_cast<const PrintFontManager::Type1FontFile*>(pRight);
     542       27783 :             if( pRT->m_nDirectory       != pLT->m_nDirectory        ||
     543       18522 :                 pRT->m_aFontFile        != pLT->m_aFontFile         ||
     544        9261 :                 pRT->m_aMetricFile      != pLT->m_aMetricFile )
     545           0 :                 return false;
     546             :         }
     547        9261 :         break;
     548           0 :         default: break;
     549             :     }
     550      104865 :     if( pRight->m_nFamilyName       != pLeft->m_nFamilyName     ||
     551       69852 :         pRight->m_aStyleName        != pLeft->m_aStyleName      ||
     552       69794 :         pRight->m_nPSName           != pLeft->m_nPSName         ||
     553       69794 :         pRight->m_eItalic           != pLeft->m_eItalic         ||
     554       69794 :         pRight->m_eWeight           != pLeft->m_eWeight         ||
     555       69794 :         pRight->m_eWidth            != pLeft->m_eWidth          ||
     556       69794 :         pRight->m_ePitch            != pLeft->m_ePitch          ||
     557       69794 :         pRight->m_aEncoding         != pLeft->m_aEncoding       ||
     558       69794 :         pRight->m_aGlobalMetricX    != pLeft->m_aGlobalMetricX  ||
     559       69794 :         pRight->m_aGlobalMetricY    != pLeft->m_aGlobalMetricY  ||
     560       69794 :         pRight->m_nAscend           != pLeft->m_nAscend         ||
     561       69794 :         pRight->m_nDescend          != pLeft->m_nDescend        ||
     562       69794 :         pRight->m_nLeading          != pLeft->m_nLeading        ||
     563       69794 :         pRight->m_nXMin             != pLeft->m_nXMin           ||
     564       69794 :         pRight->m_nYMin             != pLeft->m_nYMin           ||
     565       69794 :         pRight->m_nXMax             != pLeft->m_nXMax           ||
     566       69794 :         pRight->m_nYMax             != pLeft->m_nYMax           ||
     567      104749 :         pRight->m_bHaveVerticalSubstitutedGlyphs != pLeft->m_bHaveVerticalSubstitutedGlyphs ||
     568       34897 :         pRight->m_bUserOverride     != pLeft->m_bUserOverride
     569             :         )
     570          58 :         return false;
     571       34897 :     std::list< int >::const_iterator lit, rit;
     572      107453 :     for( lit = pLeft->m_aAliases.begin(), rit = pRight->m_aAliases.begin();
     573      108834 :          lit != pLeft->m_aAliases.end() && rit != pRight->m_aAliases.end() && (*lit) == (*rit);
     574             :          ++lit, ++rit )
     575             :         ;
     576       34897 :     return lit == pLeft->m_aAliases.end() && rit == pRight->m_aAliases.end();
     577             : }
     578             : 
     579             : /*
     580             :  *  FontCache::clonePrintFont
     581             :  */
     582       48585 : PrintFontManager::PrintFont* FontCache::clonePrintFont( const PrintFontManager::PrintFont* pOldFont )
     583             : {
     584       48585 :     PrintFontManager::PrintFont* pFont = NULL;
     585       48585 :     switch( pOldFont->m_eType )
     586             :     {
     587             :         case fonttype::TrueType:
     588       35670 :             pFont = new PrintFontManager::TrueTypeFontFile();
     589       35670 :             break;
     590             :         case fonttype::Type1:
     591       12915 :             pFont = new PrintFontManager::Type1FontFile();
     592       12915 :             break;
     593           0 :         default: break;
     594             :     }
     595       48585 :     if( pFont )
     596             :     {
     597       48585 :         copyPrintFont( pOldFont, pFont );
     598             :     }
     599       48585 :     return pFont;
     600             :  }
     601             : 
     602             : /*
     603             :  *  FontCache::getFontCacheFile
     604             :  */
     605       48380 : bool FontCache::getFontCacheFile( int nDirID, const OString& rFile, list< PrintFontManager::PrintFont* >& rNewFonts ) const
     606             : {
     607       48380 :     bool bSuccess = false;
     608             : 
     609       48380 :     FontCacheData::const_iterator dir = m_aCache.find( nDirID );
     610       48380 :     if( dir != m_aCache.end() )
     611             :     {
     612       47684 :         FontDirMap::const_iterator entry = dir->second.m_aEntries.find( rFile );
     613       47684 :         if( entry != dir->second.m_aEntries.end() )
     614             :         {
     615       69558 :             for( FontCacheEntry::const_iterator font = entry->second.m_aEntry.begin(); font != entry->second.m_aEntry.end(); ++font )
     616             :             {
     617       34955 :                 bSuccess = true;
     618       34955 :                 PrintFontManager::PrintFont* pFont = clonePrintFont( *font );
     619       34955 :                 rNewFonts.push_back( pFont );
     620             :             }
     621             :         }
     622             :     }
     623       48380 :     return bSuccess;
     624             : }
     625             : 
     626             : /*
     627             :  *  FontCache::updateFontCacheEntry
     628             :  */
     629       48585 : void FontCache::updateFontCacheEntry( const PrintFontManager::PrintFont* pFont, bool bFlush )
     630             : {
     631       48585 :     OString aFile;
     632       48585 :     int nDirID = 0;
     633       48585 :     switch( pFont->m_eType )
     634             :     {
     635             :         case fonttype::TrueType:
     636       35670 :             nDirID = static_cast<const PrintFontManager::TrueTypeFontFile*>(pFont)->m_nDirectory;
     637       35670 :             aFile = static_cast<const PrintFontManager::TrueTypeFontFile*>(pFont)->m_aFontFile;
     638       35670 :             break;
     639             :         case fonttype::Type1:
     640       12915 :             nDirID = static_cast<const PrintFontManager::Type1FontFile*>(pFont)->m_nDirectory;
     641       12915 :             aFile = static_cast<const PrintFontManager::Type1FontFile*>(pFont)->m_aFontFile;
     642       12915 :             break;
     643             :         default:
     644       48585 :             return;
     645             :     }
     646       48585 :     FontCacheData::const_iterator dir = m_aCache.find( nDirID );
     647       48585 :     FontDirMap::const_iterator entry;
     648       48585 :     FontCacheEntry::const_iterator font;
     649       48585 :     PrintFontManager::PrintFont* pCacheFont = NULL;
     650             : 
     651       48585 :     if( dir != m_aCache.end() )
     652             :     {
     653       47889 :         entry = dir->second.m_aEntries.find( aFile );
     654       47889 :         if( entry != dir->second.m_aEntries.end() )
     655             :         {
     656       35423 :             for( font = entry->second.m_aEntry.begin(); font != entry->second.m_aEntry.end(); ++font )
     657             :             {
     658      105685 :                 if( (*font)->m_eType == pFont->m_eType &&
     659       61469 :                     ( (*font)->m_eType != fonttype::TrueType ||
     660       26104 :                       static_cast<const PrintFontManager::TrueTypeFontFile*>(*font)->m_nCollectionEntry == static_cast<const PrintFontManager::TrueTypeFontFile*>(pFont)->m_nCollectionEntry
     661             :                       ) )
     662       34955 :                     break;
     663             :             }
     664       35013 :             if( font != entry->second.m_aEntry.end() )
     665       34955 :                 pCacheFont = *font;
     666             :         }
     667             :     }
     668             :     else
     669         696 :         createCacheDir( nDirID );
     670             : 
     671       48585 :     if( pCacheFont )
     672             :     {
     673       34955 :         if( ! equalsPrintFont( pFont, pCacheFont ) )
     674             :         {
     675          58 :             copyPrintFont( pFont, pCacheFont );
     676          58 :             m_bDoFlush = true;
     677             :         }
     678             :     }
     679             :     else
     680             :     {
     681       13630 :         pCacheFont = clonePrintFont( pFont );
     682       13630 :         m_aCache[nDirID].m_aEntries[aFile].m_aEntry.push_back( pCacheFont );
     683       13630 :         m_bDoFlush = true;
     684             :     }
     685       48585 :     if( bFlush )
     686           0 :         flush();
     687             : }
     688             : 
     689             : /*
     690             :  *  FontCache::listDirectory
     691             :  */
     692         410 : bool FontCache::listDirectory( const OString& rDir, std::list< PrintFontManager::PrintFont* >& rNewFonts ) const
     693             : {
     694         410 :     PrintFontManager& rManager( PrintFontManager::get() );
     695         410 :     int nDirID = rManager.getDirectoryAtom( rDir );
     696             : 
     697         410 :     FontCacheData::const_iterator dir = m_aCache.find( nDirID );
     698         410 :     bool bFound = (dir != m_aCache.end());
     699             : 
     700         410 :     if( bFound && !dir->second.m_bNoFiles )
     701             :     {
     702           0 :         for( FontDirMap::const_iterator file = dir->second.m_aEntries.begin(); file != dir->second.m_aEntries.end(); ++file )
     703             :         {
     704           0 :             for( FontCacheEntry::const_iterator font = file->second.m_aEntry.begin(); font != file->second.m_aEntry.end(); ++font )
     705             :             {
     706           0 :                 PrintFontManager::PrintFont* pFont = clonePrintFont( *font );
     707           0 :                 rNewFonts.push_back( pFont );
     708             :             }
     709             :         }
     710             :     }
     711         410 :     return bFound;
     712             : }
     713             : 
     714             : /*
     715             :  *  FontCache::listDirectory
     716             :  */
     717           0 : bool FontCache::scanAdditionalFiles( const OString& rDir )
     718             : {
     719           0 :     PrintFontManager& rManager( PrintFontManager::get() );
     720           0 :     int nDirID = rManager.getDirectoryAtom( rDir );
     721           0 :     FontCacheData::const_iterator dir = m_aCache.find( nDirID );
     722           0 :     bool bFound = (dir != m_aCache.end());
     723             : 
     724           0 :     return (bFound && dir->second.m_bUserOverrideOnly);
     725             : }
     726             : 
     727             : /*
     728             :  *  FontCache::createCacheDir
     729             :  */
     730         696 : void FontCache::createCacheDir( int nDirID )
     731             : {
     732         696 :     PrintFontManager& rManager( PrintFontManager::get() );
     733             : 
     734         696 :     const OString& rDir = rManager.getDirectory( nDirID );
     735             :     struct stat aStat;
     736         696 :     if( ! stat( rDir.getStr(), &aStat ) )
     737         696 :         m_aCache[nDirID].m_nTimestamp = (sal_Int64)aStat.st_mtime;
     738         696 : }
     739             : 
     740             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11