LCOV - code coverage report
Current view: top level - vcl/generic/fontmanager - fontcache.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 414 0.0 %
Date: 2014-04-14 Functions: 0 13 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10