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

Generated by: LCOV version 1.10