LCOV - code coverage report
Current view: top level - libreoffice/vcl/generic/fontmanager - fontcache.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 353 416 84.9 %
Date: 2012-12-27 Functions: 13 14 92.9 %
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          20 : FontCache::FontCache()
      57             : {
      58          20 :     m_bDoFlush = false;
      59          20 :     m_aCacheFile = getOfficePath( UserPath );
      60          20 :     if( m_aCacheFile.Len() )
      61             :     {
      62          19 :         m_aCacheFile.AppendAscii( FONTCACHEFILE );
      63          19 :         read();
      64             :     }
      65          20 : }
      66             : 
      67             : /*
      68             :  *  FontCache destructor
      69             :  */
      70             : 
      71          40 : FontCache::~FontCache()
      72             : {
      73          20 :     clearCache();
      74          20 : }
      75             : 
      76             : /*
      77             :  *  FontCache::clearCache
      78             :  */
      79          20 : void FontCache::clearCache()
      80             : {
      81         579 :     for( FontCacheData::iterator dir_it = m_aCache.begin(); dir_it != m_aCache.end(); ++dir_it )
      82             :     {
      83        2739 :         for( FontDirMap::iterator entry_it = dir_it->second.m_aEntries.begin(); entry_it != dir_it->second.m_aEntries.end(); ++entry_it )
      84             :         {
      85        4460 :             for( FontCacheEntry::iterator font_it = entry_it->second.m_aEntry.begin(); font_it != entry_it->second.m_aEntry.end(); ++font_it )
      86        2280 :                 delete *font_it;
      87             :         }
      88             :     }
      89          20 :     m_aCache.clear();
      90          20 : }
      91             : 
      92             : /*
      93             :  *  FontCache::Commit
      94             :  */
      95             : 
      96          20 : void FontCache::flush()
      97             : {
      98          20 :     if( ! m_bDoFlush || ! m_aCacheFile.Len() )
      99             :         return;
     100             : 
     101           1 :     SvFileStream aStream;
     102           1 :     aStream.Open( m_aCacheFile, STREAM_WRITE | STREAM_TRUNC );
     103           1 :     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           1 :     aStream.SetLineDelimiter( LINEEND_LF );
     112           1 :     aStream.WriteLine(rtl::OString(RTL_CONSTASCII_STRINGPARAM(CACHE_MAGIC)));
     113             : 
     114           1 :     PrintFontManager& rManager( PrintFontManager::get() );
     115           1 :     MultiAtomProvider* pAtoms = rManager.m_pAtoms;
     116             : 
     117          29 :     for( FontCacheData::const_iterator dir_it = m_aCache.begin(); dir_it != m_aCache.end(); ++ dir_it )
     118             :     {
     119          28 :         const FontDirMap& rDir( dir_it->second.m_aEntries );
     120             : 
     121          28 :         rtl::OString aDirectory(rManager.getDirectory(dir_it->first));
     122             :         rtl::OStringBuffer aLine(
     123          28 :             RTL_CONSTASCII_STRINGPARAM("FontCacheDirectory:"));
     124          28 :         aLine.append(dir_it->second.m_nTimestamp);
     125          28 :         aLine.append(':');
     126          28 :         aLine.append(aDirectory);
     127          28 :         if( rDir.empty() && dir_it->second.m_bNoFiles )
     128           1 :             aLine.insert(0, RTL_CONSTASCII_STRINGPARAM("Empty"));
     129          28 :         aStream.WriteLine(aLine.makeStringAndClear());
     130             : 
     131         137 :         for( FontDirMap::const_iterator entry_it = rDir.begin(); entry_it != rDir.end(); ++entry_it )
     132             :         {
     133             :             // insert cache entries
     134         109 :             const FontCacheEntry& rEntry( entry_it->second.m_aEntry );
     135         109 :             if( rEntry.begin() == rEntry.end() )
     136           0 :                 continue;
     137             : 
     138         109 :             aLine.append(RTL_CONSTASCII_STRINGPARAM("File:"));
     139         109 :             aLine.append(entry_it->first);
     140         109 :             aStream.WriteLine(aLine.makeStringAndClear());
     141             : 
     142         109 :             int nEntrySize = entry_it->second.m_aEntry.size();
     143             :             // write: type;nfonts
     144         109 :             aLine.append(static_cast<sal_Int32>(rEntry.front()->m_eType));
     145         109 :             aLine.append(';');
     146         109 :             aLine.append(static_cast<sal_Int32>(nEntrySize));
     147         109 :             aStream.WriteLine(aLine.makeStringAndClear());
     148             : 
     149         109 :             sal_Int32 nSubEntry = 0;
     150         223 :             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         114 :                 if( nEntrySize > 1 )
     158           7 :                     nSubEntry = static_cast<const PrintFontManager::TrueTypeFontFile*>(*it)->m_nCollectionEntry;
     159             :                 else
     160         107 :                     nSubEntry = 0;
     161             : 
     162         114 :                 aLine.append(OUStringToOString(pAtoms->getString( ATOM_FAMILYNAME, (*it)->m_nFamilyName), RTL_TEXTENCODING_UTF8));
     163         124 :                 for( ::std::list< int >::const_iterator name_it = (*it)->m_aAliases.begin(); name_it != (*it)->m_aAliases.end(); ++name_it )
     164             :                 {
     165          10 :                     const OUString& rAdd( pAtoms->getString( ATOM_FAMILYNAME, *name_it ) );
     166          10 :                     if( !rAdd.isEmpty() )
     167             :                     {
     168          10 :                         aLine.append(';');
     169          10 :                         aLine.append(OUStringToOString(rAdd, RTL_TEXTENCODING_UTF8));
     170             :                     }
     171             :                 }
     172         114 :                 aStream.WriteLine(aLine.makeStringAndClear());
     173             : 
     174         114 :                 const OUString& rPSName( pAtoms->getString( ATOM_PSNAME, (*it)->m_nPSName ) );
     175         114 :                 aLine.append(nSubEntry);
     176         114 :                 aLine.append(';');
     177         114 :                 aLine.append(OUStringToOString(rPSName, RTL_TEXTENCODING_UTF8));
     178         114 :                 aLine.append(';');
     179         114 :                 aLine.append(static_cast<sal_Int32>((*it)->m_eItalic));
     180         114 :                 aLine.append(';');
     181         114 :                 aLine.append(static_cast<sal_Int32>((*it)->m_eWeight));
     182         114 :                 aLine.append(';');
     183         114 :                 aLine.append(static_cast<sal_Int32>((*it)->m_eWidth));
     184         114 :                 aLine.append(';');
     185         114 :                 aLine.append(static_cast<sal_Int32>((*it)->m_ePitch));
     186         114 :                 aLine.append(';');
     187         114 :                 aLine.append(static_cast<sal_Int32>((*it)->m_aEncoding));
     188         114 :                 aLine.append(';');
     189         114 :                 aLine.append(static_cast<sal_Int32>((*it)->m_nAscend));
     190         114 :                 aLine.append(';');
     191         114 :                 aLine.append(static_cast<sal_Int32>((*it)->m_nDescend));
     192         114 :                 aLine.append(';');
     193         114 :                 aLine.append(static_cast<sal_Int32>((*it)->m_nLeading));
     194         114 :                 aLine.append(';');
     195         114 :                 aLine.append((*it)->m_bHaveVerticalSubstitutedGlyphs ? '1' : '0');
     196         114 :                 aLine.append(';');
     197         114 :                 aLine.append(static_cast<sal_Int32>((*it)->m_aGlobalMetricX.width ));
     198         114 :                 aLine.append(';');
     199         114 :                 aLine.append(static_cast<sal_Int32>((*it)->m_aGlobalMetricX.height));
     200         114 :                 aLine.append(';');
     201         114 :                 aLine.append(static_cast<sal_Int32>((*it)->m_aGlobalMetricY.width ));
     202         114 :                 aLine.append(';');
     203         114 :                 aLine.append(static_cast<sal_Int32>((*it)->m_aGlobalMetricY.height));
     204         114 :                 aLine.append(';');
     205         114 :                 aLine.append((*it)->m_bUserOverride ? '1' : '0');
     206         114 :                 aLine.append(';');
     207         114 :                 aLine.append(static_cast<sal_Int32>(0));
     208         114 :                 aLine.append(';');
     209         114 :                 aLine.append(static_cast<sal_Int32>(0));
     210             : 
     211         114 :                 switch( (*it)->m_eType )
     212             :                 {
     213             :                     case fonttype::Type1:
     214          35 :                         aLine.append(';');
     215          35 :                         aLine.append(static_cast<const PrintFontManager::Type1FontFile*>(*it)->m_aMetricFile);
     216          35 :                         break;
     217             :                     case fonttype::TrueType:
     218          79 :                         aLine.append(';');
     219          79 :                         aLine.append(static_cast<sal_Int32>(static_cast<const PrintFontManager::TrueTypeFontFile*>(*it)->m_nTypeFlags));
     220          79 :                         break;
     221           0 :                     default: break;
     222             :                 }
     223         114 :                 if( !(*it)->m_aStyleName.isEmpty() )
     224             :                 {
     225         114 :                     aLine.append(';');
     226         114 :                     aLine.append(OUStringToOString((*it)->m_aStyleName, RTL_TEXTENCODING_UTF8));
     227             :                 }
     228         114 :                 aStream.WriteLine(aLine.makeStringAndClear());
     229             :             }
     230         109 :             aStream.WriteLine(rtl::OString());
     231             :         }
     232          28 :     }
     233           1 :     m_bDoFlush = false;
     234             : }
     235             : 
     236             : /*
     237             :  * FontCache::read
     238             :  */
     239             : 
     240          19 : void FontCache::read()
     241             : {
     242          19 :     PrintFontManager& rManager( PrintFontManager::get() );
     243          19 :     MultiAtomProvider* pAtoms = rManager.m_pAtoms;
     244             : 
     245          19 :     SvFileStream aStream( m_aCacheFile, STREAM_READ );
     246          19 :     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          18 :     OString aLine;
     256          18 :     aStream.ReadLine( aLine );
     257          18 :     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          18 :     int nDir = 0;
     266          18 :     FontDirMap* pDir = NULL;
     267          18 :     bool bKeepOnlyUserOverridden = false;
     268        4446 :     do
     269             :     {
     270        4446 :         aStream.ReadLine( aLine );
     271       16812 :         if( aLine.compareTo( RTL_CONSTASCII_STRINGPARAM( "FontCacheDirectory:" ) ) == 0 ||
     272       12366 :             aLine.compareTo( RTL_CONSTASCII_STRINGPARAM( "EmptyFontCacheDirectory:" ) ) == 0 )
     273             :         {
     274         504 :             bool bEmpty = (aLine.compareTo( RTL_CONSTASCII_STRINGPARAM ("Empty" ) ) == 0);
     275         504 :             sal_Int32 nSearchIndex = bEmpty ? 24 : 19;
     276             : 
     277         504 :             OString aDir;
     278         504 :             sal_Int64 nTimestamp = 0;
     279         504 :             sal_Int32 nTEnd = aLine.indexOf( ':', nSearchIndex );
     280         504 :             if( nTEnd != -1 )
     281             :             {
     282         504 :                 rtl::OString aTimeStamp = aLine.copy( nSearchIndex, nTEnd - nSearchIndex );
     283         504 :                 nTimestamp = aTimeStamp.toInt64();
     284         504 :                 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        1008 :             if( stat( aDir.getStr(), &aStat )               ||
     298         504 :                 ! 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         504 :                 nDir = rManager.getDirectoryAtom( aDir, true );
     309         504 :                 m_aCache[ nDir ].m_nTimestamp = (sal_Int64)aStat.st_mtime;
     310         504 :                 m_aCache[ nDir ].m_bNoFiles = bEmpty;
     311         504 :                 pDir = bEmpty ? NULL : &m_aCache[ nDir ].m_aEntries;
     312         504 :                 bKeepOnlyUserOverridden = ((sal_Int64)aStat.st_mtime != nTimestamp);
     313         504 :                 m_aCache[ nDir ].m_bUserOverrideOnly = bKeepOnlyUserOverridden;
     314         504 :             }
     315             :         }
     316        3942 :         else if( pDir && aLine.compareTo( RTL_CONSTASCII_STRINGPARAM( "File:" ) ) == 0 )
     317             :         {
     318        1962 :             OString aFile( aLine.copy( 5 ) );
     319        1962 :             aStream.ReadLine( aLine );
     320             : 
     321        1962 :             const char* pLine = aLine.getStr();
     322             : 
     323        1962 :             fonttype::type eType = (fonttype::type)atoi( pLine );
     324        1962 :             if( eType != fonttype::TrueType     &&
     325             :                 eType != fonttype::Type1        &&
     326             :                 eType != fonttype::Builtin
     327             :                 )
     328           0 :                 continue;
     329        5886 :             while( *pLine && *pLine != ';' )
     330        1962 :                 pLine++;
     331        1962 :             if( *pLine != ';' )
     332           0 :                 continue;
     333             : 
     334        1962 :             pLine++;
     335        1962 :             sal_Int32 nFonts = atoi( pLine );
     336        4014 :             for( int n = 0; n < nFonts; n++ )
     337             :             {
     338        2052 :                 aStream.ReadLine( aLine );
     339        2052 :                 pLine = aLine.getStr();
     340        2052 :                 int nLen = aLine.getLength();
     341             : 
     342        2052 :                 PrintFontManager::PrintFont* pFont = NULL;
     343        2052 :                 switch( eType )
     344             :                 {
     345             :                     case fonttype::TrueType:
     346        1422 :                         pFont = new PrintFontManager::TrueTypeFontFile();
     347        1422 :                         break;
     348             :                     case fonttype::Type1:
     349         630 :                         pFont = new PrintFontManager::Type1FontFile();
     350         630 :                         break;
     351             :                     case fonttype::Builtin:
     352           0 :                         pFont = new PrintFontManager::BuiltinFont();
     353           0 :                         break;
     354           0 :                     default: break;
     355             :                 }
     356             : 
     357             :                 sal_Int32 nIndex;
     358             : 
     359        2052 :                 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        2052 :                                                         sal_True );
     365        4284 :                 while( nIndex < nLen )
     366             :                 {
     367         180 :                     sal_Int32 nLastIndex = nIndex+1;
     368         180 :                     for( nIndex = nLastIndex ; nIndex < nLen && pLine[nIndex] != ';'; nIndex++ )
     369             :                         ;
     370         180 :                     if( nIndex - nLastIndex )
     371             :                     {
     372         180 :                         OUString aAlias( pLine+nLastIndex, nIndex-nLastIndex, RTL_TEXTENCODING_UTF8 );
     373         180 :                         pFont->m_aAliases.push_back( pAtoms->getAtom( ATOM_FAMILYNAME, aAlias, sal_True ) );
     374             :                     }
     375             :                 }
     376        2052 :                 aStream.ReadLine( aLine );
     377        2052 :                 pLine = aLine.getStr();
     378        2052 :                 nLen = aLine.getLength();
     379             : 
     380             :                 // get up to 20 token positions
     381        2052 :                 const int nMaxTokens = 20;
     382             :                 int nTokenPos[nMaxTokens];
     383        2052 :                 nTokenPos[0] = 0;
     384        2052 :                 int nTokens = 1;
     385      159732 :                 for( int i = 0; i < nLen; i++ )
     386             :                 {
     387      159732 :                     if( pLine[i] == ';' )
     388             :                     {
     389       38988 :                         nTokenPos[nTokens++] = i+1;
     390       38988 :                         if( nTokens == nMaxTokens )
     391        2052 :                             break;
     392             :                     }
     393             :                 }
     394        2052 :                 if( nTokens < 18 )
     395             :                 {
     396           0 :                     delete pFont;
     397           0 :                     continue;
     398             :                 }
     399        2052 :                 int nCollEntry      = atoi( pLine );
     400        2052 :                 pFont->m_nPSName    = pAtoms->getAtom( ATOM_PSNAME, OUString( pLine + nTokenPos[1], nTokenPos[2]-nTokenPos[1]-1, RTL_TEXTENCODING_UTF8 ), sal_True );
     401        2052 :                 pFont->m_eItalic    = (FontItalic)atoi( pLine+nTokenPos[2] );
     402        2052 :                 pFont->m_eWeight    = (FontWeight)atoi( pLine+nTokenPos[3] );
     403        2052 :                 pFont->m_eWidth     = (FontWidth)atoi( pLine+nTokenPos[4] );
     404        2052 :                 pFont->m_ePitch     = (FontPitch)atoi( pLine+nTokenPos[5] );
     405        2052 :                 pFont->m_aEncoding  = (rtl_TextEncoding)atoi( pLine+nTokenPos[6] );
     406        2052 :                 pFont->m_nAscend    = atoi( pLine + nTokenPos[7] );
     407        2052 :                 pFont->m_nDescend   = atoi( pLine + nTokenPos[8] );
     408        2052 :                 pFont->m_nLeading   = atoi( pLine + nTokenPos[9] );
     409             :                 pFont->m_bHaveVerticalSubstitutedGlyphs
     410        2052 :                                     = (atoi( pLine + nTokenPos[10] ) != 0);
     411             :                 pFont->m_aGlobalMetricX.width
     412        2052 :                                     = atoi( pLine + nTokenPos[11] );
     413             :                 pFont->m_aGlobalMetricX.height
     414        2052 :                                     = atoi( pLine + nTokenPos[12] );
     415             :                 pFont->m_aGlobalMetricY.width
     416        2052 :                                     = atoi( pLine + nTokenPos[13] );
     417             :                 pFont->m_aGlobalMetricY.height
     418        2052 :                                     = atoi( pLine + nTokenPos[14] );
     419             :                 pFont->m_bUserOverride
     420        2052 :                                     = (atoi( pLine + nTokenPos[15] ) != 0);
     421        2052 :                 int nStyleTokenNr = 18;
     422        2052 :                 switch( eType )
     423             :                 {
     424             :                     case fonttype::TrueType:
     425        1422 :                         static_cast<PrintFontManager::TrueTypeFontFile*>(pFont)->m_nTypeFlags = atoi( pLine + nTokenPos[18] );
     426        1422 :                         static_cast<PrintFontManager::TrueTypeFontFile*>(pFont)->m_nCollectionEntry = nCollEntry;
     427        1422 :                         static_cast<PrintFontManager::TrueTypeFontFile*>(pFont)->m_nDirectory = nDir;
     428        1422 :                         static_cast<PrintFontManager::TrueTypeFontFile*>(pFont)->m_aFontFile = aFile;
     429        1422 :                         nStyleTokenNr++;
     430        1422 :                         break;
     431             :                     case fonttype::Type1:
     432             :                     {
     433         630 :                         int nTokLen = (nTokens > 19 ) ? nTokenPos[19]-nTokenPos[18]-1 : nLen - nTokenPos[18];
     434         630 :                         static_cast<PrintFontManager::Type1FontFile*>(pFont)->m_aMetricFile = OString( pLine + nTokenPos[18], nTokLen );
     435         630 :                         static_cast<PrintFontManager::Type1FontFile*>(pFont)->m_nDirectory = nDir;
     436         630 :                         static_cast<PrintFontManager::Type1FontFile*>(pFont)->m_aFontFile = aFile;
     437         630 :                         nStyleTokenNr++;
     438             :                     }
     439         630 :                     break;
     440             :                     case fonttype::Builtin:
     441           0 :                         static_cast<PrintFontManager::BuiltinFont*>(pFont)->m_nDirectory = nDir;
     442           0 :                         static_cast<PrintFontManager::BuiltinFont*>(pFont)->m_aMetricFile = aFile;
     443           0 :                         break;
     444           0 :                     default: break;
     445             :                 }
     446        2052 :                 if( nTokens > nStyleTokenNr )
     447        2052 :                     pFont->m_aStyleName = OUString::intern( pLine + nTokenPos[nStyleTokenNr],
     448        2052 :                                                             nLen - nTokenPos[nStyleTokenNr],
     449        4104 :                                                             RTL_TEXTENCODING_UTF8 );
     450             : 
     451        2052 :                 bool bObsolete = false;
     452        2052 :                 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        2052 :                 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        2052 :                 FontCacheEntry& rEntry = (*pDir)[aFile].m_aEntry;
     485        2052 :                 rEntry.push_back( pFont );
     486        1962 :             }
     487             :         }
     488        4464 :     } while( ! aStream.IsEof() );
     489             : }
     490             : 
     491             : /*
     492             :  *  FontCache::copyPrintFont
     493             :  */
     494        2650 : void FontCache::copyPrintFont( const PrintFontManager::PrintFont* pFrom, PrintFontManager::PrintFont* pTo ) const
     495             : {
     496        2650 :     if( pFrom->m_eType != pTo->m_eType )
     497        2650 :         return;
     498        2650 :     switch( pFrom->m_eType )
     499             :     {
     500             :         case fonttype::TrueType:
     501        1950 :             static_cast<PrintFontManager::TrueTypeFontFile*>(pTo)->m_nDirectory = static_cast<const PrintFontManager::TrueTypeFontFile*>(pFrom)->m_nDirectory;
     502        1950 :             static_cast<PrintFontManager::TrueTypeFontFile*>(pTo)->m_aFontFile = static_cast<const PrintFontManager::TrueTypeFontFile*>(pFrom)->m_aFontFile;
     503        1950 :             static_cast<PrintFontManager::TrueTypeFontFile*>(pTo)->m_nCollectionEntry = static_cast<const PrintFontManager::TrueTypeFontFile*>(pFrom)->m_nCollectionEntry;
     504        1950 :             static_cast<PrintFontManager::TrueTypeFontFile*>(pTo)->m_nTypeFlags = static_cast<const PrintFontManager::TrueTypeFontFile*>(pFrom)->m_nTypeFlags;
     505        1950 :             break;
     506             :         case fonttype::Type1:
     507         700 :             static_cast<PrintFontManager::Type1FontFile*>(pTo)->m_nDirectory = static_cast<const PrintFontManager::Type1FontFile*>(pFrom)->m_nDirectory;
     508         700 :             static_cast<PrintFontManager::Type1FontFile*>(pTo)->m_aFontFile = static_cast<const PrintFontManager::Type1FontFile*>(pFrom)->m_aFontFile;
     509         700 :             static_cast<PrintFontManager::Type1FontFile*>(pTo)->m_aMetricFile = static_cast<const PrintFontManager::Type1FontFile*>(pFrom)->m_aMetricFile;
     510         700 :             break;
     511             :         case fonttype::Builtin:
     512           0 :             static_cast<PrintFontManager::BuiltinFont*>(pTo)->m_nDirectory = static_cast<const PrintFontManager::BuiltinFont*>(pFrom)->m_nDirectory;
     513           0 :             static_cast<PrintFontManager::BuiltinFont*>(pTo)->m_aMetricFile = static_cast<const PrintFontManager::BuiltinFont*>(pFrom)->m_aMetricFile;
     514           0 :             break;
     515           0 :         default: break;
     516             :     }
     517        2650 :     pTo->m_nFamilyName      = pFrom->m_nFamilyName;
     518        2650 :     pTo->m_aStyleName       = pFrom->m_aStyleName;
     519        2650 :     pTo->m_aAliases         = pFrom->m_aAliases;
     520        2650 :     pTo->m_nPSName          = pFrom->m_nPSName;
     521        2650 :     pTo->m_eItalic          = pFrom->m_eItalic;
     522        2650 :     pTo->m_eWeight          = pFrom->m_eWeight;
     523        2650 :     pTo->m_eWidth           = pFrom->m_eWidth;
     524        2650 :     pTo->m_ePitch           = pFrom->m_ePitch;
     525        2650 :     pTo->m_aEncoding        = pFrom->m_aEncoding;
     526        2650 :     pTo->m_aGlobalMetricX   = pFrom->m_aGlobalMetricX;
     527        2650 :     pTo->m_aGlobalMetricY   = pFrom->m_aGlobalMetricY;
     528        2650 :     pTo->m_nAscend          = pFrom->m_nAscend;
     529        2650 :     pTo->m_nDescend         = pFrom->m_nDescend;
     530        2650 :     pTo->m_nLeading         = pFrom->m_nLeading;
     531        2650 :     pTo->m_nXMin            = pFrom->m_nXMin;
     532        2650 :     pTo->m_nYMin            = pFrom->m_nYMin;
     533        2650 :     pTo->m_nXMax            = pFrom->m_nXMax;
     534        2650 :     pTo->m_nYMax            = pFrom->m_nYMax;
     535        2650 :     pTo->m_bHaveVerticalSubstitutedGlyphs = pFrom->m_bHaveVerticalSubstitutedGlyphs;
     536        2650 :     pTo->m_bUserOverride    = pFrom->m_bUserOverride;
     537             : }
     538             : 
     539             : /*
     540             :  *  FontCache::equalsPrintFont
     541             :  */
     542        2412 : bool FontCache::equalsPrintFont( const PrintFontManager::PrintFont* pLeft, PrintFontManager::PrintFont* pRight ) const
     543             : {
     544        2412 :     if( pLeft->m_eType != pRight->m_eType )
     545           0 :         return false;
     546        2412 :     switch( pLeft->m_eType )
     547             :     {
     548             :         case fonttype::TrueType:
     549             :         {
     550        1782 :             const PrintFontManager::TrueTypeFontFile* pLT = static_cast<const PrintFontManager::TrueTypeFontFile*>(pLeft);
     551        1782 :             const PrintFontManager::TrueTypeFontFile* pRT = static_cast<const PrintFontManager::TrueTypeFontFile*>(pRight);
     552        3564 :             if( pRT->m_nDirectory       != pLT->m_nDirectory        ||
     553        1782 :                 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        1782 :         break;
     559             :         case fonttype::Type1:
     560             :         {
     561         630 :             const PrintFontManager::Type1FontFile* pLT = static_cast<const PrintFontManager::Type1FontFile*>(pLeft);
     562         630 :             const PrintFontManager::Type1FontFile* pRT = static_cast<const PrintFontManager::Type1FontFile*>(pRight);
     563        1890 :             if( pRT->m_nDirectory       != pLT->m_nDirectory        ||
     564         630 :                 pRT->m_aFontFile        != pLT->m_aFontFile         ||
     565         630 :                 pRT->m_aMetricFile      != pLT->m_aMetricFile )
     566           0 :                 return false;
     567             :         }
     568         630 :         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        9628 :     if( pRight->m_nFamilyName       != pLeft->m_nFamilyName     ||
     581        2412 :         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        2402 :         pRight->m_aGlobalMetricX    != pLeft->m_aGlobalMetricX  ||
     589        2402 :         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        2402 :     std::list< int >::const_iterator lit, rit;
     602       12492 :     for( lit = pLeft->m_aAliases.begin(), rit = pRight->m_aAliases.begin();
     603       10090 :          lit != pLeft->m_aAliases.end() && rit != pRight->m_aAliases.end() && (*lit) == (*rit);
     604             :          ++lit, ++rit )
     605             :         ;
     606        2402 :     return lit == pLeft->m_aAliases.end() && rit == pRight->m_aAliases.end();
     607             : }
     608             : 
     609             : /*
     610             :  *  FontCache::clonePrintFont
     611             :  */
     612        2640 : PrintFontManager::PrintFont* FontCache::clonePrintFont( const PrintFontManager::PrintFont* pOldFont ) const
     613             : {
     614        2640 :     PrintFontManager::PrintFont* pFont = NULL;
     615        2640 :     switch( pOldFont->m_eType )
     616             :     {
     617             :         case fonttype::TrueType:
     618        1940 :             pFont = new PrintFontManager::TrueTypeFontFile();
     619        1940 :             break;
     620             :         case fonttype::Type1:
     621         700 :             pFont = new PrintFontManager::Type1FontFile();
     622         700 :             break;
     623             :         case fonttype::Builtin:
     624           0 :             pFont = new PrintFontManager::BuiltinFont();
     625           0 :             break;
     626           0 :         default: break;
     627             :     }
     628        2640 :     if( pFont )
     629             :     {
     630        2640 :         copyPrintFont( pOldFont, pFont );
     631             :     }
     632        2640 :     return pFont;
     633             :  }
     634             : 
     635             : /*
     636             :  *  FontCache::getFontCacheFile
     637             :  */
     638        2360 : bool FontCache::getFontCacheFile( int nDirID, const OString& rFile, list< PrintFontManager::PrintFont* >& rNewFonts ) const
     639             : {
     640        2360 :     bool bSuccess = false;
     641             : 
     642        2360 :     FontCacheData::const_iterator dir = m_aCache.find( nDirID );
     643        2360 :     if( dir != m_aCache.end() )
     644             :     {
     645        2226 :         FontDirMap::const_iterator entry = dir->second.m_aEntries.find( rFile );
     646        2226 :         if( entry != dir->second.m_aEntries.end() )
     647             :         {
     648        4474 :             for( FontCacheEntry::const_iterator font = entry->second.m_aEntry.begin(); font != entry->second.m_aEntry.end(); ++font )
     649             :             {
     650        2412 :                 bSuccess = true;
     651        2412 :                 PrintFontManager::PrintFont* pFont = clonePrintFont( *font );
     652        2412 :                 rNewFonts.push_back( pFont );
     653             :             }
     654             :         }
     655             :     }
     656        2360 :     return bSuccess;
     657             : }
     658             : 
     659             : /*
     660             :  *  FontCache::updateFontCacheEntry
     661             :  */
     662        2640 : void FontCache::updateFontCacheEntry( const PrintFontManager::PrintFont* pFont, bool bFlush )
     663             : {
     664        2640 :     OString aFile;
     665        2640 :     int nDirID = 0;
     666        2640 :     switch( pFont->m_eType )
     667             :     {
     668             :         case fonttype::TrueType:
     669        1940 :             nDirID = static_cast<const PrintFontManager::TrueTypeFontFile*>(pFont)->m_nDirectory;
     670        1940 :             aFile = static_cast<const PrintFontManager::TrueTypeFontFile*>(pFont)->m_aFontFile;
     671        1940 :             break;
     672             :         case fonttype::Type1:
     673         700 :             nDirID = static_cast<const PrintFontManager::Type1FontFile*>(pFont)->m_nDirectory;
     674         700 :             aFile = static_cast<const PrintFontManager::Type1FontFile*>(pFont)->m_aFontFile;
     675         700 :             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        2640 :             return;
     682             :     }
     683        2640 :     FontCacheData::const_iterator dir = m_aCache.find( nDirID );
     684        2640 :     FontDirMap::const_iterator entry;
     685        2640 :     FontCacheEntry::const_iterator font;
     686        2640 :     PrintFontManager::PrintFont* pCacheFont = NULL;
     687             : 
     688        2640 :     if( dir != m_aCache.end() )
     689             :     {
     690        2586 :         entry = dir->second.m_aEntries.find( aFile );
     691        2586 :         if( entry != dir->second.m_aEntries.end() )
     692             :         {
     693        3082 :             for( font = entry->second.m_aEntry.begin(); font != entry->second.m_aEntry.end(); ++font )
     694             :             {
     695        8586 :                 if( (*font)->m_eType == pFont->m_eType &&
     696        3072 :                     ( (*font)->m_eType != fonttype::TrueType ||
     697        2442 :                       static_cast<const PrintFontManager::TrueTypeFontFile*>(*font)->m_nCollectionEntry == static_cast<const PrintFontManager::TrueTypeFontFile*>(pFont)->m_nCollectionEntry
     698             :                       ) )
     699        2412 :                     break;
     700             :             }
     701        2422 :             if( font != entry->second.m_aEntry.end() )
     702        2412 :                 pCacheFont = *font;
     703             :         }
     704             :     }
     705             :     else
     706          54 :         createCacheDir( nDirID );
     707             : 
     708        2640 :     if( pCacheFont )
     709             :     {
     710        2412 :         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        2640 :     if( bFlush )
     723           0 :         flush();
     724             : }
     725             : 
     726             : /*
     727             :  *  FontCache::listDirectory
     728             :  */
     729          98 : bool FontCache::listDirectory( const OString& rDir, std::list< PrintFontManager::PrintFont* >& rNewFonts ) const
     730             : {
     731          98 :     PrintFontManager& rManager( PrintFontManager::get() );
     732          98 :     int nDirID = rManager.getDirectoryAtom( rDir );
     733          98 :     FontCacheData::const_iterator dir = m_aCache.find( nDirID );
     734          98 :     bool bFound = (dir != m_aCache.end());
     735             : 
     736          98 :     if( bFound && !dir->second.m_bNoFiles )
     737             :     {
     738           0 :         for( FontDirMap::const_iterator file = dir->second.m_aEntries.begin(); file != dir->second.m_aEntries.end(); ++file )
     739             :         {
     740           0 :             for( FontCacheEntry::const_iterator font = file->second.m_aEntry.begin(); font != file->second.m_aEntry.end(); ++font )
     741             :             {
     742           0 :                 PrintFontManager::PrintFont* pFont = clonePrintFont( *font );
     743           0 :                 rNewFonts.push_back( pFont );
     744             :             }
     745             :         }
     746             :     }
     747          98 :     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          55 : void FontCache::createCacheDir( int nDirID )
     767             : {
     768          55 :     PrintFontManager& rManager( PrintFontManager::get() );
     769             : 
     770          55 :     const OString& rDir = rManager.getDirectory( nDirID );
     771             :     struct stat aStat;
     772          55 :     if( ! stat( rDir.getStr(), &aStat ) )
     773          55 :         m_aCache[nDirID].m_nTimestamp = (sal_Int64)aStat.st_mtime;
     774          55 : }
     775             : 
     776             : /*
     777             :  *  FontCache::markEmptyDir
     778             :  */
     779           1 : void FontCache::markEmptyDir( int nDirID, bool bNoFiles )
     780             : {
     781           1 :     createCacheDir( nDirID );
     782           1 :     m_aCache[nDirID].m_bNoFiles = bNoFiles;
     783           1 :     m_bDoFlush = true;
     784           1 : }
     785             : 
     786             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10