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

Generated by: LCOV version 1.10