diff options
author | Philipp Lohmann <pl@openoffice.org> | 2002-02-28 10:53:08 +0000 |
---|---|---|
committer | Philipp Lohmann <pl@openoffice.org> | 2002-02-28 10:53:08 +0000 |
commit | 14f4a49266f5206260b5e9f0780913c56dd8d5a0 (patch) | |
tree | d7826f40446aaca5e75fe89657bc2bd2ec857ca7 /psprint | |
parent | fd03488af96dd9234adbefad62e60bdb69511894 (diff) |
#97829# #i1991# add font aliases
Diffstat (limited to 'psprint')
-rw-r--r-- | psprint/inc/psprint/fontcache.hxx | 99 | ||||
-rw-r--r-- | psprint/inc/psprint/fontmanager.hxx | 46 | ||||
-rw-r--r-- | psprint/source/fontmanager/fontcache.cxx | 587 | ||||
-rw-r--r-- | psprint/source/fontmanager/fontmanager.cxx | 291 | ||||
-rw-r--r-- | psprint/source/fontmanager/makefile.mk | 5 |
5 files changed, 876 insertions, 152 deletions
diff --git a/psprint/inc/psprint/fontcache.hxx b/psprint/inc/psprint/fontcache.hxx new file mode 100644 index 000000000000..9edc21527bc5 --- /dev/null +++ b/psprint/inc/psprint/fontcache.hxx @@ -0,0 +1,99 @@ +/************************************************************************* + * + * $RCSfile: fontcache.hxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: pl $ $Date: 2002-02-28 11:49:51 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _PSPRINT_FONTCACHE_HXX +#define _PSPRINT_FONTCACHE_HXX + +#ifndef _PSPRINT_FONTMANAGER_HXX_ +#include <psprint/fontmanager.hxx> +#endif + +#include <hash_map> + +namespace psp +{ + +class FontCache +{ + typedef ::std::list< PrintFontManager::PrintFont* > FontCacheEntry; + typedef ::std::hash_map< ::rtl::OString, FontCacheEntry, ::rtl::OStringHash > FontDirMap; + typedef ::std::hash_map< int, FontDirMap > FontCacheData; + FontCacheData m_aCache; + bool m_bDoFlush; + + void read( const ::rtl::OString& rPath ); + void clearCache(); + + void copyPrintFont( const PrintFontManager::PrintFont* pFrom, PrintFontManager::PrintFont* pTo ) const; + PrintFontManager::PrintFont* clonePrintFont( const PrintFontManager::PrintFont* pFont ) const; +public: + FontCache(); + ~FontCache(); + + bool getFontCacheFile( int nDirID, const ::rtl::OString& rDir, const ::rtl::OString& rFile, ::std::list< PrintFontManager::PrintFont* >& rNewFonts ); + void updateFontCacheEntry( const PrintFontManager::PrintFont*, bool bFlush ); + + void flush(); +}; + +} // namespace psp + +#endif // _PSPRINT_FONTCACHE_HXX diff --git a/psprint/inc/psprint/fontmanager.hxx b/psprint/inc/psprint/fontmanager.hxx index 1c36bb04bfe6..4987ae1ea98d 100644 --- a/psprint/inc/psprint/fontmanager.hxx +++ b/psprint/inc/psprint/fontmanager.hxx @@ -2,9 +2,9 @@ * * $RCSfile: fontmanager.hxx,v $ * - * $Revision: 1.10 $ + * $Revision: 1.11 $ * - * last change: $Author: hdu $ $Date: 2001-12-21 16:31:36 $ + * last change: $Author: pl $ $Date: 2002-02-28 11:49:51 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -68,6 +68,9 @@ #ifndef __SGI_STL_LIST #include <list> #endif +#ifndef __SGI_STL_SET +#include <set> +#endif #ifndef _PSPRINT_HELPER_HXX_ #include <psprint/helper.hxx> #endif @@ -173,25 +176,26 @@ enum type { struct FastPrintFontInfo { - fontID m_nID; // FontID - fonttype::type m_eType; + fontID m_nID; // FontID + fonttype::type m_eType; // font attributes - ::rtl::OUString m_aFamilyName; - family::type m_eFamilyStyle; - italic::type m_eItalic; - width::type m_eWidth; - weight::type m_eWeight; - pitch::type m_ePitch; - rtl_TextEncoding m_aEncoding; + ::rtl::OUString m_aFamilyName; + ::std::list< ::rtl::OUString > m_aAliases; + family::type m_eFamilyStyle; + italic::type m_eItalic; + width::type m_eWidth; + weight::type m_eWeight; + pitch::type m_ePitch; + rtl_TextEncoding m_aEncoding; }; struct PrintFontInfo : public FastPrintFontInfo { - int m_nAscend; - int m_nDescend; - int m_nLeading; - int m_nWidth; + int m_nAscend; + int m_nDescend; + int m_nLeading; + int m_nWidth; }; // the values are per thousand of the font size @@ -224,6 +228,7 @@ class PrintFontManager friend class TrueTypeFontFile; friend class Type1FontFile; friend class BuiltinFont; + friend class FontCache; struct PrintFontMetrics { @@ -258,6 +263,7 @@ class PrintFontManager // font attributes int m_nFamilyName; // atom + ::std::list< int > m_aAliases; int m_nPSName; // atom italic::type m_eItalic; width::type m_eWidth; @@ -326,6 +332,9 @@ class PrintFontManager ::std::list< ::rtl::OString > m_aFontDirectories; ::std::list< int > m_aPrivateFontDirectories; ::utl::MultiAtomProvider* m_pAtoms; + // for speeding up findFontFileID + ::std::hash_map< ::rtl::OString, ::std::set< fontID >, ::rtl::OStringHash > + m_aFontFileToFontID; ::std::hash_map< ::rtl::OString, int, ::rtl::OStringHash > m_aDirToAtom; @@ -339,6 +348,8 @@ class PrintFontManager ::std::hash_multimap< sal_Unicode, sal_uInt8 > m_aUnicodeToAdobecode; ::std::hash_multimap< sal_uInt8, sal_Unicode > m_aAdobecodeToUnicode; + mutable FontCache* m_pFontCache; + mutable bool m_bFlushFontCache; ::rtl::OString getAfmFile( PrintFont* pFont ) const; ::rtl::OString getFontFile( PrintFont* pFont ) const; @@ -347,7 +358,7 @@ class PrintFontManager bool analyzeFontFile( int nDirID, const ::rtl::OString& rFileName, bool bReadFile, const ::std::list< ::rtl::OString >& rXLFDs, ::std::list< PrintFont* >& rNewFonts ) const; ::rtl::OUString convertTrueTypeName( void* pNameRecord ) const; // actually a NameRecord* formt font subsetting code - ::rtl::OUString analyzeTrueTypeFamilyName( void* pTTFont ) const; // actually a TrueTypeFont* from font subsetting code + void analyzeTrueTypeFamilyName( void* pTTFont, ::std::list< ::rtl::OUString >& rnames ) const; // actually a TrueTypeFont* from font subsetting code bool analyzeTrueTypeFile( PrintFont* pFont ) const; // finds the FIRST id for this font file; there may be more // for TrueType collections @@ -409,6 +420,9 @@ public: // get a specific fonts style family family::type PrintFontManager::getFontFamilyType( fontID nFontID ) const; + // get a specific fonts family name aliases + void PrintFontManager::getFontFamilyAliases( fontID nFontID ) const; + // get a specific fonts type fonttype::type getFontType( fontID nFontID ) const { diff --git a/psprint/source/fontmanager/fontcache.cxx b/psprint/source/fontmanager/fontcache.cxx new file mode 100644 index 000000000000..6e654e4c043b --- /dev/null +++ b/psprint/source/fontmanager/fontcache.cxx @@ -0,0 +1,587 @@ +/************************************************************************* + * + * $RCSfile: fontcache.cxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: pl $ $Date: 2002-02-28 11:49:51 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#include <unistd.h> +#include <sys/stat.h> + +#include <psprint/fontcache.hxx> + +#ifndef _OSL_THREAD_H +#include <osl/thread.h> +#endif +#ifndef _UTL_ATOM_HXX_ +#include <unotools/atom.hxx> +#endif +#ifndef _STREAM_HXX +#include <tools/stream.hxx> +#endif + +using namespace std; +using namespace rtl; +using namespace psp; +using namespace utl; + +/* + * static helpers + */ + +/* + * FontCache constructor + */ + +FontCache::FontCache() +{ + String aPrinterPath( getPrinterPath() ); + String aPath; + xub_StrLen nIndex = 0; + rtl_TextEncoding aEnconding = osl_getThreadTextEncoding(); + + while( nIndex != STRING_NOTFOUND ) + { + aPath = aPrinterPath.GetToken( 0, ':', nIndex ); + read( ByteString( aPath, aEnconding ) ); + } + m_bDoFlush = false; +} + +/* + * FontCache destructor + */ + +FontCache::~FontCache() +{ + clearCache(); +} + +/* + * FontCache::clearCache + */ +void FontCache::clearCache() +{ + for( FontCacheData::iterator dir_it = m_aCache.begin(); dir_it != m_aCache.end(); ++dir_it ) + { + for( FontDirMap::iterator entry_it = dir_it->second.begin(); entry_it != dir_it->second.end(); ++entry_it ) + { + for( FontCacheEntry::iterator font_it = entry_it->second.begin(); font_it != entry_it->second.end(); ++font_it ) + delete *font_it; + } + } + m_aCache.clear(); +} + +/* + * FontCache::Commit + */ + +void FontCache::flush() +{ + if( ! m_bDoFlush ) + return; + + OUString aPrinterPath( getPrinterPath() ); + String aPath; + bool bHavePath = false; + sal_Int32 nIndex = 0; + SvFileStream aStream; + while( nIndex != STRING_NOTFOUND ) + { + aPath = aPrinterPath.getToken( 0, ':', nIndex ); + aPath.AppendAscii( "/pspfontcache" ); + aStream.Open( aPath, STREAM_READ | STREAM_WRITE ); + if( aStream.IsOpen() && aStream.IsWritable() ) + { + bHavePath = true; + break; + } + } + + if( ! bHavePath ) + return; + + aStream.SetLineDelimiter( LINEEND_LF ); + + PrintFontManager& rManager( PrintFontManager::get() ); + MultiAtomProvider* pAtoms = rManager.m_pAtoms; + + for( FontCacheData::const_iterator dir_it = m_aCache.begin(); dir_it != m_aCache.end(); ++ dir_it ) + { + ByteString aDirectory( rManager.getDirectory( dir_it->first ) ); + ByteString aLine( "FontCacheDirectory:" ); + aLine.Append( aDirectory ); + aStream.WriteLine( aLine ); + + const FontDirMap& rDir( dir_it->second ); + for( FontDirMap::const_iterator entry_it = rDir.begin(); entry_it != rDir.end(); ++entry_it ) + { + // insert cache entries + const FontCacheEntry& rEntry( entry_it->second ); + if( rEntry.begin() == rEntry.end() ) + continue; + + struct stat aStat; + ByteString aFileName( aDirectory ); + aFileName.Append( '/' ); + aFileName.Append( ByteString( entry_it->first ) ); + if( stat( aFileName.GetBuffer(), &aStat ) ) + continue; + + aLine = "File:"; + aLine.Append( ByteString( entry_it->first ) ); + aStream.WriteLine( aLine ); + + int nEntrySize = entry_it->second.size(); + // write: type;mtime;nfonts + aLine = ByteString::CreateFromInt32( rEntry.front()->m_eType ); + aLine.Append( ';' ); + aLine.Append( ByteString::CreateFromInt64( aStat.st_mtime ) ); + aLine.Append( ';' ); + aLine.Append( ByteString::CreateFromInt32( nEntrySize ) ); + aStream.WriteLine( aLine ); + + sal_Int32 nSubEntry = 0; + for( FontCacheEntry::const_iterator it = rEntry.begin(); it != rEntry.end(); ++it, nSubEntry++ ) + { + /* + * for each font entry write: + * name[;name[;name]] + * fontnr;PSName;italic;weight;width;pitch;encoding;ascend;descend;leading;vsubst;gxw;gxh;gyw;gyh[;{metricfile,typeflags}] + */ + if( nEntrySize > 1 ) + nSubEntry = static_cast<const PrintFontManager::TrueTypeFontFile*>(*it)->m_nCollectionEntry; + + aLine = OUStringToOString( pAtoms->getString( ATOM_FAMILYNAME, (*it)->m_nFamilyName ), RTL_TEXTENCODING_UTF8 ); + for( ::std::list< int >::const_iterator name_it = (*it)->m_aAliases.begin(); name_it != (*it)->m_aAliases.end(); ++name_it ) + { + const OUString& rAdd( pAtoms->getString( ATOM_FAMILYNAME, *name_it ) ); + if( rAdd.getLength() ) + { + aLine.Append( ';' ); + aLine.Append( ByteString( String( rAdd ), RTL_TEXTENCODING_UTF8 ) ); + } + } + aStream.WriteLine( aLine ); + + const OUString& rPSName( pAtoms->getString( ATOM_PSNAME, (*it)->m_nPSName ) ); + aLine = ByteString::CreateFromInt32( nSubEntry ); + aLine.Append( ';' ); + aLine.Append( ByteString( String( rPSName ), RTL_TEXTENCODING_UTF8 ) ); + aLine.Append( ';' ); + aLine.Append( ByteString::CreateFromInt32( (*it)->m_eItalic ) ); + aLine.Append( ';' ); + aLine.Append( ByteString::CreateFromInt32( (*it)->m_eWeight ) ); + aLine.Append( ';' ); + aLine.Append( ByteString::CreateFromInt32( (*it)->m_eWidth ) ); + aLine.Append( ';' ); + aLine.Append( ByteString::CreateFromInt32( (*it)->m_ePitch ) ); + aLine.Append( ';' ); + aLine.Append( ByteString::CreateFromInt32( (*it)->m_aEncoding ) ); + aLine.Append( ';' ); + aLine.Append( ByteString::CreateFromInt32( (*it)->m_nAscend ) ); + aLine.Append( ';' ); + aLine.Append( ByteString::CreateFromInt32( (*it)->m_nDescend ) ); + aLine.Append( ';' ); + aLine.Append( ByteString::CreateFromInt32( (*it)->m_nLeading ) ); + aLine.Append( ';' ); + aLine.Append( (*it)->m_bHaveVerticalSubstitutedGlyphs ? "1" : "0" ); + aLine.Append( ';' ); + aLine.Append( ByteString::CreateFromInt32( (*it)->m_aGlobalMetricX.width ) ); + aLine.Append( ';' ); + aLine.Append( ByteString::CreateFromInt32( (*it)->m_aGlobalMetricX.height ) ); + aLine.Append( ';' ); + aLine.Append( ByteString::CreateFromInt32( (*it)->m_aGlobalMetricY.width ) ); + aLine.Append( ';' ); + aLine.Append( ByteString::CreateFromInt32( (*it)->m_aGlobalMetricY.height ) ); + + switch( (*it)->m_eType ) + { + case fonttype::Type1: + aLine.Append( ';' ); + aLine.Append( ByteString( static_cast<const PrintFontManager::Type1FontFile*>(*it)->m_aMetricFile ) ); + break; + case fonttype::TrueType: + aLine.Append( ';' ); + aLine.Append( ByteString::CreateFromInt32( static_cast<const PrintFontManager::TrueTypeFontFile*>(*it)->m_nTypeFlags ) ); + break; + } + aStream.WriteLine( aLine ); + } + aStream.WriteLine( ByteString() ); + } + } + m_bDoFlush = false; +} + +/* + * FontCache::getValues + */ + +void FontCache::read( const OString& rPath ) +{ + String aFilePath( ByteString( rPath ), osl_getThreadTextEncoding() ); + aFilePath.AppendAscii( "/pspfontcache" ); + PrintFontManager& rManager( PrintFontManager::get() ); + MultiAtomProvider* pAtoms = rManager.m_pAtoms; + + SvFileStream aStream( aFilePath, STREAM_READ ); + if( ! aStream.IsOpen() ) + return; + + m_bDoFlush = true; + + ByteString aLine; + OString aDir( rPath ); + int nDir = rManager.getDirectoryAtom( aDir, true ); + FontDirMap* pDir = &m_aCache[ nDir ]; + xub_StrLen nIndex; + do + { + aStream.ReadLine( aLine ); + if( aLine.CompareTo( "FontCacheDirectory:", 19 ) == COMPARE_EQUAL ) + { + aDir = aLine.Copy( 19 ); + nDir = rManager.getDirectoryAtom( aDir, true ); + pDir = &m_aCache[ nDir ]; + } + else if( aLine.CompareTo( "File:", 5 ) == COMPARE_EQUAL ) + { + OString aFile( aLine.Copy( 5 ) ); + aStream.ReadLine( aLine ); + + nIndex = 0; + fonttype::type eType = (fonttype::type)aLine.GetToken( 0, ';', nIndex ).ToInt32(); + if( eType != fonttype::TrueType && + eType != fonttype::Type1 && + eType != fonttype::Builtin + ) + continue; + if( nIndex == STRING_NOTFOUND ) + continue; + + sal_Int64 nTime = aLine.GetToken( 0, ';', nIndex ).ToInt64(); + if( nIndex == STRING_NOTFOUND ) + continue; + + sal_Int32 nFonts = aLine.GetToken( 0, ';', nIndex ).ToInt32(); + + // check whether file is outdated + struct stat aStat; + ByteString aFileName( aDir ); + aFileName.Append( '/' ); + aFileName.Append( ByteString( aFile ) ); + if( stat( aFileName.GetBuffer(), &aStat ) + || nTime < (sal_Int64)aStat.st_mtime + || ! S_ISREG(aStat.st_mode) + ) + continue; + + for( int n = 0; n < nFonts; n++ ) + { + PrintFontManager::PrintFont* pFont = NULL; + switch( eType ) + { + case fonttype::TrueType: + pFont = new PrintFontManager::TrueTypeFontFile(); + break; + case fonttype::Type1: + pFont = new PrintFontManager::Type1FontFile(); + break; + case fonttype::Builtin: + pFont = new PrintFontManager::BuiltinFont(); + break; + } + aStream.ReadLine( aLine ); + nIndex = 0; + + pFont->m_nFamilyName = pAtoms->getAtom( ATOM_FAMILYNAME, + String( aLine.GetToken( 0, ';', nIndex ), RTL_TEXTENCODING_UTF8 ), + sal_True ); + while( nIndex != STRING_NOTFOUND ) + { + String aAlias( aLine.GetToken( 0, ';', nIndex ), RTL_TEXTENCODING_UTF8 ); + if( aAlias.Len() ) + pFont->m_aAliases.push_back( pAtoms->getAtom( ATOM_FAMILYNAME, aAlias, sal_True ) ); + } + +#define CHECKINDEX() if( nIndex == STRING_NOTFOUND ) { delete pFont; continue; } + aStream.ReadLine( aLine ); + nIndex = 0; + + int nCollEntry = aLine.GetToken( 0, ';', nIndex ).ToInt32(); + CHECKINDEX(); + pFont->m_nPSName = pAtoms->getAtom( ATOM_PSNAME, String( aLine.GetToken( 0, ';', nIndex ), RTL_TEXTENCODING_UTF8 ), sal_True ); + CHECKINDEX(); + pFont->m_eItalic = (italic::type)aLine.GetToken( 0, ';', nIndex ).ToInt32(); + CHECKINDEX(); + pFont->m_eWeight = (weight::type)aLine.GetToken( 0, ';', nIndex ).ToInt32(); + CHECKINDEX(); + pFont->m_eWidth = (width::type)aLine.GetToken( 0, ';', nIndex ).ToInt32(); + CHECKINDEX(); + pFont->m_ePitch = (pitch::type)aLine.GetToken( 0, ';', nIndex ).ToInt32(); + CHECKINDEX(); + pFont->m_aEncoding = (rtl_TextEncoding)aLine.GetToken( 0, ';', nIndex ).ToInt32(); + CHECKINDEX(); + pFont->m_nAscend = aLine.GetToken( 0, ';', nIndex ).ToInt32(); + CHECKINDEX(); + pFont->m_nDescend = aLine.GetToken( 0, ';', nIndex ).ToInt32(); + CHECKINDEX(); + pFont->m_nLeading = aLine.GetToken( 0, ';', nIndex ).ToInt32(); + CHECKINDEX(); + pFont->m_bHaveVerticalSubstitutedGlyphs = aLine.GetToken( 0, ';', nIndex ).CompareIgnoreCaseToAscii( "true" ) == COMPARE_EQUAL ? true : false; + CHECKINDEX(); + pFont->m_aGlobalMetricX.width = aLine.GetToken( 0, ';', nIndex ).ToInt32(); + CHECKINDEX(); + pFont->m_aGlobalMetricX.height = aLine.GetToken( 0, ';', nIndex ).ToInt32(); + CHECKINDEX(); + pFont->m_aGlobalMetricY.width = aLine.GetToken( 0, ';', nIndex ).ToInt32(); + CHECKINDEX(); + pFont->m_aGlobalMetricY.height = aLine.GetToken( 0, ';', nIndex ).ToInt32(); + + switch( eType ) + { + case fonttype::TrueType: + CHECKINDEX(); + static_cast<PrintFontManager::TrueTypeFontFile*>(pFont)->m_nTypeFlags = aLine.GetToken( 0, ';', nIndex ).ToInt32(); + static_cast<PrintFontManager::TrueTypeFontFile*>(pFont)->m_nCollectionEntry = nCollEntry; + static_cast<PrintFontManager::TrueTypeFontFile*>(pFont)->m_nDirectory = nDir; + static_cast<PrintFontManager::TrueTypeFontFile*>(pFont)->m_aFontFile = aFile; + break; + case fonttype::Type1: + { + CHECKINDEX(); + ByteString aMetricFile( aLine.GetToken( 0, ';', nIndex ) ); + static_cast<PrintFontManager::Type1FontFile*>(pFont)->m_aMetricFile = aMetricFile; + static_cast<PrintFontManager::Type1FontFile*>(pFont)->m_nDirectory = nDir; + static_cast<PrintFontManager::Type1FontFile*>(pFont)->m_aFontFile = aFile; + aFileName = aDir; + aFileName.Append( '/' ); + aFileName.Append( aMetricFile ); + if( stat( aFileName.GetBuffer(), &aStat ) || + ! S_ISREG( aStat.st_mode ) + ) + { + delete pFont; + continue; + } + } + break; + case fonttype::Builtin: + static_cast<PrintFontManager::BuiltinFont*>(pFont)->m_nDirectory = nDir; + static_cast<PrintFontManager::BuiltinFont*>(pFont)->m_aMetricFile = aFile; + break; + } + (*pDir)[ aFile ].push_back( pFont ); + } + } + } while( ! aStream.IsEof() ); +} + +/* + * FontCache::copyPrintFont + */ +void FontCache::copyPrintFont( const PrintFontManager::PrintFont* pFrom, PrintFontManager::PrintFont* pTo ) const +{ + if( pFrom->m_eType != pTo->m_eType ) + return; + switch( pFrom->m_eType ) + { + case fonttype::TrueType: + static_cast<PrintFontManager::TrueTypeFontFile*>(pTo)->m_nDirectory = static_cast<const PrintFontManager::TrueTypeFontFile*>(pFrom)->m_nDirectory; + static_cast<PrintFontManager::TrueTypeFontFile*>(pTo)->m_aFontFile = static_cast<const PrintFontManager::TrueTypeFontFile*>(pFrom)->m_aFontFile; + static_cast<PrintFontManager::TrueTypeFontFile*>(pTo)->m_nCollectionEntry = static_cast<const PrintFontManager::TrueTypeFontFile*>(pFrom)->m_nCollectionEntry; + static_cast<PrintFontManager::TrueTypeFontFile*>(pTo)->m_nTypeFlags = static_cast<const PrintFontManager::TrueTypeFontFile*>(pFrom)->m_nTypeFlags; + break; + case fonttype::Type1: + static_cast<PrintFontManager::Type1FontFile*>(pTo)->m_nDirectory = static_cast<const PrintFontManager::Type1FontFile*>(pFrom)->m_nDirectory; + static_cast<PrintFontManager::Type1FontFile*>(pTo)->m_aFontFile = static_cast<const PrintFontManager::Type1FontFile*>(pFrom)->m_aFontFile; + static_cast<PrintFontManager::Type1FontFile*>(pTo)->m_aMetricFile = static_cast<const PrintFontManager::Type1FontFile*>(pFrom)->m_aMetricFile; + break; + case fonttype::Builtin: + static_cast<PrintFontManager::BuiltinFont*>(pTo)->m_nDirectory = static_cast<const PrintFontManager::BuiltinFont*>(pFrom)->m_nDirectory; + static_cast<PrintFontManager::BuiltinFont*>(pTo)->m_aMetricFile = static_cast<const PrintFontManager::BuiltinFont*>(pFrom)->m_aMetricFile; + break; + } + pTo->m_nFamilyName = pFrom->m_nFamilyName; + pTo->m_aAliases = pFrom->m_aAliases; + pTo->m_nPSName = pFrom->m_nPSName; + pTo->m_eItalic = pFrom->m_eItalic; + pTo->m_eWidth = pFrom->m_eWidth; + pTo->m_ePitch = pFrom->m_ePitch; + pTo->m_aEncoding = pFrom->m_aEncoding; + pTo->m_aGlobalMetricX = pFrom->m_aGlobalMetricX; + pTo->m_aGlobalMetricY = pFrom->m_aGlobalMetricY; + pTo->m_nAscend = pFrom->m_nAscend; + pTo->m_nDescend = pFrom->m_nDescend; + pTo->m_nLeading = pFrom->m_nLeading; + pTo->m_bHaveVerticalSubstitutedGlyphs = pFrom->m_bHaveVerticalSubstitutedGlyphs; +} + +/* + * FontCache::clonePrintFont + */ +PrintFontManager::PrintFont* FontCache::clonePrintFont( const PrintFontManager::PrintFont* pOldFont ) const +{ + PrintFontManager::PrintFont* pFont = NULL; + switch( pOldFont->m_eType ) + { + case fonttype::TrueType: + pFont = new PrintFontManager::TrueTypeFontFile(); + break; + case fonttype::Type1: + pFont = new PrintFontManager::Type1FontFile(); + break; + case fonttype::Builtin: + pFont = new PrintFontManager::BuiltinFont(); + break; + } + if( pFont ) + { + copyPrintFont( pOldFont, pFont ); + } + return pFont; + } + +/* + * FontCache::getFontCacheFile + */ +bool FontCache::getFontCacheFile( int nDirID, const OString& rDir, const OString& rFile, list< PrintFontManager::PrintFont* >& rNewFonts ) +{ + bool bSuccess = false; + + FontCacheData::const_iterator dir = m_aCache.find( nDirID ); + if( dir == m_aCache.end() ) + read( rDir ); + dir = m_aCache.find( nDirID ); + if( dir != m_aCache.end() ) + { + FontDirMap::const_iterator entry = dir->second.find( rFile ); + if( entry != dir->second.end() ) + { + bSuccess = true; + for( list< PrintFontManager::PrintFont* >::const_iterator font = entry->second.begin(); font != entry->second.end(); ++font ) + { + PrintFontManager::PrintFont* pFont = clonePrintFont( *font ); + rNewFonts.push_back( pFont ); + } + } + } + return bSuccess; +} + +/* + * FontCache::updateFontCacheEntry + */ +void FontCache::updateFontCacheEntry( const PrintFontManager::PrintFont* pFont, bool bFlush ) +{ + PrintFontManager& rManager( PrintFontManager::get() ); + + OString aFile; + int nDirID = 0; + switch( pFont->m_eType ) + { + case fonttype::TrueType: + nDirID = static_cast<const PrintFontManager::TrueTypeFontFile*>(pFont)->m_nDirectory; + aFile = static_cast<const PrintFontManager::TrueTypeFontFile*>(pFont)->m_aFontFile; + break; + case fonttype::Type1: + nDirID = static_cast<const PrintFontManager::Type1FontFile*>(pFont)->m_nDirectory; + aFile = static_cast<const PrintFontManager::Type1FontFile*>(pFont)->m_aFontFile; + break; + case fonttype::Builtin: + nDirID = static_cast<const PrintFontManager::BuiltinFont*>(pFont)->m_nDirectory; + aFile = static_cast<const PrintFontManager::BuiltinFont*>(pFont)->m_aMetricFile; + break; + default: + return; + } + FontCacheData::const_iterator dir = m_aCache.find( nDirID ); + FontDirMap::const_iterator entry; + FontCacheEntry::const_iterator font; + PrintFontManager::PrintFont* pCacheFont = NULL; + + if( dir != m_aCache.end() ) + { + entry = dir->second.find( aFile ); + if( entry != dir->second.end() ) + { + for( font = entry->second.begin(); font != entry->second.end(); ++font ) + { + if( (*font)->m_eType == pFont->m_eType && + ( (*font)->m_eType != fonttype::TrueType || + static_cast<const PrintFontManager::TrueTypeFontFile*>(*font)->m_nCollectionEntry == static_cast<const PrintFontManager::TrueTypeFontFile*>(pFont)->m_nCollectionEntry + ) ) + break; + } + if( font != entry->second.end() ) + pCacheFont = *font; + } + } + + if( pCacheFont ) + copyPrintFont( pFont, pCacheFont ); + else + { + pCacheFont = clonePrintFont( pFont ); + m_aCache[nDirID][aFile].push_back( pCacheFont ); + } + m_bDoFlush = true; + if( bFlush ) + flush(); +} diff --git a/psprint/source/fontmanager/fontmanager.cxx b/psprint/source/fontmanager/fontmanager.cxx index 0b90d2acd8bc..65d1a9db81b6 100644 --- a/psprint/source/fontmanager/fontmanager.cxx +++ b/psprint/source/fontmanager/fontmanager.cxx @@ -2,9 +2,9 @@ * * $RCSfile: fontmanager.cxx,v $ * - * $Revision: 1.22 $ + * $Revision: 1.23 $ * - * last change: $Author: hdu $ $Date: 2001-12-21 16:31:11 $ + * last change: $Author: pl $ $Date: 2002-02-28 11:49:51 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -77,6 +77,9 @@ #ifndef _PSPRINT_FONTMANAGER_HXX_ #include <psprint/fontmanager.hxx> #endif +#ifndef _PSPRINT_FONTCACHE_HXX_ +#include <psprint/fontcache.hxx> +#endif #ifndef _URLOBJ_HXX #include <tools/urlobj.hxx> #endif @@ -129,6 +132,8 @@ #include <alloca.h> #endif +#include <set> + #include <adobeenc.tab> // get encoding table for AFM metrics #define PRINTER_METRICDIR "fontmetric" @@ -589,7 +594,7 @@ bool PrintFontManager::PrintFont::readAfmMetrics( const OString& rFileName, Mult m_nDescend = -pInfo->gfi->fontBBox.lly; // fallback to ascender, descender - // interestigly the BBox seems to describe Ascender and Descender better + // interesting: the BBox seems to describe Ascender and Descender better // as we understand it if( m_nAscend == 0 ) m_nAscend = pInfo->gfi->ascender; @@ -753,6 +758,7 @@ bool PrintFontManager::PrintFont::readAfmMetrics( const OString& rFileName, Mult m_pMetrics->m_bKernPairsQueried = true; freeFontInfo( pInfo ); + rManager.m_pFontCache->updateFontCacheEntry( this, rManager.m_bFlushFontCache ); return true; } @@ -783,7 +789,9 @@ PrintFontManager& PrintFontManager::get() PrintFontManager::PrintFontManager() : m_pAtoms( new MultiAtomProvider() ), m_nNextFontID( 1 ), - m_nNextDirAtom( 1 ) + m_nNextDirAtom( 1 ), + m_pFontCache( NULL ), + m_bFlushFontCache( true ) { for( int i = 0; i < sizeof( aAdobeCodes )/sizeof( aAdobeCodes[0] ); i++ ) { @@ -813,6 +821,8 @@ PrintFontManager::~PrintFontManager() for( ::std::hash_map< fontID, PrintFont* >::const_iterator it = m_aFonts.begin(); it != m_aFonts.end(); ++it ) delete (*it).second; delete m_pAtoms; + if( m_pFontCache ) + delete m_pFontCache; } // ------------------------------------------------------------------------- @@ -859,11 +869,15 @@ int PrintFontManager::addFontFile( const ::rtl::OString& rFileName, int nFaceNum { for( ::std::list< PrintFont* >::iterator it = aNewFonts.begin(); it != aNewFonts.end(); ++it ) + { m_aFonts[ nFontId = m_nNextFontID++ ] = *it; + m_aFontFileToFontID[ aName ].insert( nFontId ); + } } } return nFontId; } + // ------------------------------------------------------------------------- bool PrintFontManager::analyzeFontFile( int nDirID, const OString& rFontFile, bool bReadFile, const ::std::list<OString>& rXLFDs, ::std::list< PrintFontManager::PrintFont* >& rNewFonts ) const @@ -873,6 +887,9 @@ bool PrintFontManager::analyzeFontFile( int nDirID, const OString& rFontFile, bo OString aDir( getDirectory( nDirID ) ); + if( m_pFontCache->getFontCacheFile( nDirID, aDir, rFontFile, rNewFonts ) ) + return true; + ByteString aExt( rFontFile.copy( rFontFile.lastIndexOf( '.' )+1 ) ); if( aExt.EqualsIgnoreCaseAscii( "pfb" ) || aExt.EqualsIgnoreCaseAscii( "pfa" ) ) { @@ -912,20 +929,30 @@ bool PrintFontManager::analyzeFontFile( int nDirID, const OString& rFontFile, bo pFont->m_aFontFile = rFontFile; pFont->m_aMetricFile = aAfmFile; - if( bReadFile || ! rXLFDs.size() ) + if( rXLFDs.size() ) + getFontAttributesFromXLFD( pFont, rXLFDs.front() ); + else if( ! pFont->readAfmMetrics( getAfmFile( pFont ), m_pAtoms ) ) { - if( ! pFont->readAfmMetrics( getAfmFile( pFont ), m_pAtoms ) ) - { - delete pFont; - pFont = NULL; - } + delete pFont; + pFont = NULL; } - else - getFontAttributesFromXLFD( pFont, rXLFDs.front() ); if( pFont ) rNewFonts.push_back( pFont ); } } + else if( aExt.EqualsIgnoreCaseAscii( "afm" ) ) + { + ByteString aFilePath( aDir ); + aFilePath.Append( '/' ); + aFilePath.Append( ByteString( rFontFile ) ); + BuiltinFont* pFont = new BuiltinFont(); + pFont->m_nDirectory = nDirID; + pFont->m_aMetricFile = rFontFile; + if( pFont->readAfmMetrics( aFilePath, m_pAtoms ) ) + rNewFonts.push_back( pFont ); + else + delete pFont; + } else if( aExt.EqualsIgnoreCaseAscii( "ttf" ) ) { TrueTypeFontFile* pFont = new TrueTypeFontFile(); @@ -933,17 +960,15 @@ bool PrintFontManager::analyzeFontFile( int nDirID, const OString& rFontFile, bo pFont->m_aFontFile = rFontFile; pFont->m_nCollectionEntry = -1; - if( bReadFile || ! rXLFDs.size() ) + if( rXLFDs.size() ) + getFontAttributesFromXLFD( pFont, rXLFDs.front() ); + // need to read the font anyway to get aliases + if( ! analyzeTrueTypeFile( pFont ) ) { - if( ! analyzeTrueTypeFile( pFont ) ) - { - delete pFont; - pFont = NULL; - } + delete pFont; + pFont = NULL; } else - getFontAttributesFromXLFD( pFont, rXLFDs.front() ); - if( pFont ) rNewFonts.push_back( pFont ); } else if( aExt.EqualsIgnoreCaseAscii( "ttc" ) ) @@ -975,7 +1000,8 @@ bool PrintFontManager::analyzeFontFile( int nDirID, const OString& rFontFile, bo pFont->m_nDirectory = nDirID; pFont->m_aFontFile = rFontFile; pFont->m_nCollectionEntry = i; - getFontAttributesFromXLFD( pFont, aXLFD ); + if( aXLFD.getLength() ) + getFontAttributesFromXLFD( pFont, aXLFD ); if( ! analyzeTrueTypeFile( pFont ) ) { delete pFont; @@ -1013,29 +1039,42 @@ fontID PrintFontManager::findFontBuiltinID( int nPSNameAtom ) const fontID PrintFontManager::findFontFileID( int nDirID, const OString& rFontFile ) const { fontID nID = 0; - ::std::hash_map< int, PrintFont* >::const_iterator it; - for( it = m_aFonts.begin(); nID == 0 && it != m_aFonts.end(); ++it ) + + ::std::hash_map< OString, ::std::set< fontID >, OStringHash >::const_iterator set_it = m_aFontFileToFontID.find( rFontFile ); + if( set_it != m_aFontFileToFontID.end() ) { - switch( it->second->m_eType ) + for( ::std::set< fontID >::const_iterator font_it = set_it->second.begin(); font_it != set_it->second.end() && ! nID; ++font_it ) { - case fonttype::Type1: + ::std::hash_map< int, PrintFont* >::const_iterator it = m_aFonts.find( *font_it ); + if( it != m_aFonts.end() ) { - Type1FontFile* const pFont = static_cast< Type1FontFile* const >((*it).second); - if( pFont->m_nDirectory == nDirID && - pFont->m_aFontFile == rFontFile ) - nID = it->first; - } - break; - case fonttype::TrueType: - { - TrueTypeFontFile* const pFont = static_cast< TrueTypeFontFile* const >((*it).second); - if( pFont->m_nDirectory == nDirID && - pFont->m_aFontFile == rFontFile ) - nID = it->first; + switch( it->second->m_eType ) + { + case fonttype::Type1: + { + Type1FontFile* const pFont = static_cast< Type1FontFile* const >((*it).second); + if( pFont->m_nDirectory == nDirID && + pFont->m_aFontFile == rFontFile ) + nID = it->first; + } + break; + case fonttype::TrueType: + { + TrueTypeFontFile* const pFont = static_cast< TrueTypeFontFile* const >((*it).second); + if( pFont->m_nDirectory == nDirID && + pFont->m_aFontFile == rFontFile ) + nID = it->first; + } + break; + case fonttype::Builtin: + if( static_cast<const BuiltinFont*>((*it).second)->m_nDirectory == nDirID && + static_cast<const BuiltinFont*>((*it).second)->m_aMetricFile == rFontFile ) + nID = it->first; + break; + default: + break; + } } - break; - default: - break; } } return nID; @@ -1249,10 +1288,13 @@ OUString PrintFontManager::convertTrueTypeName( void* pRecord ) const // ------------------------------------------------------------------------- -OUString PrintFontManager::analyzeTrueTypeFamilyName( void* pTTFont ) const +void PrintFontManager::analyzeTrueTypeFamilyName( void* pTTFont, ::std::list< OUString >& rNames ) const { OUString aFamily; + rNames.clear(); + ::std::set< OUString > aSet; + NameRecord* pNameRecords = NULL; int nNameRecords = GetTTNameRecords( (TrueTypeFont*)pTTFont, &pNameRecords ); if( nNameRecords && pNameRecords ) @@ -1263,10 +1305,6 @@ OUString PrintFontManager::analyzeTrueTypeFamilyName( void* pTTFont ) const { if( pNameRecords[i].nameID != 1 ) continue; -#ifdef DEBUG - fprintf( stderr, " family: platform = %d, encoding = %d, language = 0x%.4x\n", pNameRecords[i].platformID, pNameRecords[i].encodingID, pNameRecords[i].languageID ); -#endif - int nMatch = -1; if( pNameRecords[i].platformID == 0 ) // Unicode nMatch = 4000; @@ -1283,18 +1321,24 @@ OUString PrintFontManager::analyzeTrueTypeFamilyName( void* pTTFont ) const else nMatch = 1000; } + OUString aName = convertTrueTypeName( pNameRecords + i ); + aSet.insert( aName ); if( nMatch > nLastMatch ) { nLastMatch = nMatch; - aFamily = convertTrueTypeName( pNameRecords + i ); -#ifdef DEBUG - fprintf( stderr, "taken\n" ); -#endif + aFamily = aName; } } DisposeNameRecords( pNameRecords, nNameRecords ); } - return aFamily; + if( aFamily.getLength() ) + { + rNames.push_front( aFamily ); + for( ::std::set< OUString >::const_iterator it = aSet.begin(); it != aSet.end(); ++it ) + if( *it != aFamily ) + rNames.push_back( *it ); + } + return; } // ------------------------------------------------------------------------- @@ -1312,20 +1356,32 @@ bool PrintFontManager::analyzeTrueTypeFile( PrintFont* pFont ) const TTGlobalFontInfo aInfo; GetTTGlobalFontInfo( pTTFont, & aInfo ); + ::std::list< OUString > aNames; + analyzeTrueTypeFamilyName( pTTFont, aNames ); + // set family name from XLFD if possible if( ! pFont->m_nFamilyName ) { -#ifdef DEBUG - fprintf( stderr, "font %s\n", pTTFontFile->m_aFontFile.getStr() ); -#endif - OUString aFamilyName( analyzeTrueTypeFamilyName( pTTFont ) ); - if( aFamilyName.getLength() ) - pFont->m_nFamilyName = m_pAtoms->getAtom( ATOM_FAMILYNAME, aFamilyName, sal_True ); + if( aNames.begin() != aNames.end() ) + { + pFont->m_nFamilyName = m_pAtoms->getAtom( ATOM_FAMILYNAME, aNames.front(), sal_True ); + aNames.pop_front(); + } else // poor font does not have a family name // name it to file name minus ".tt{f|c}" pFont->m_nFamilyName = m_pAtoms->getAtom( ATOM_FAMILYNAME, OStringToOUString( pTTFontFile->m_aFontFile.copy( 0, pTTFontFile->m_aFontFile.getLength()-4 ), aEncoding ), sal_True ); } + pFont->m_aAliases.clear(); + for( ::std::list< OUString >::iterator it = aNames.begin(); it != aNames.end(); ++it ) + { + if( it->getLength() ) + { + int nAlias = m_pAtoms->getAtom( ATOM_FAMILYNAME, *it, sal_True ); + if( nAlias != pFont->m_nFamilyName ) + pFont->m_aAliases.push_back( nAlias ); + } + } pFont->m_nPSName = m_pAtoms->getAtom( ATOM_PSNAME, String( ByteString( aInfo.psname ), aEncoding ), sal_True ); @@ -1399,9 +1455,6 @@ bool PrintFontManager::analyzeTrueTypeFile( PrintFont* pFont ) const // get type flags pTTFontFile->m_nTypeFlags = (unsigned int)aInfo.typeFlags; -#ifdef DEBUG - fprintf( stderr, "font %s has style flags %x\n", aFile.GetBuffer(), pTTFontFile->m_nTypeFlags ); -#endif // get vertical substitutions flag pFont->m_bHaveVerticalSubstitutedGlyphs = DoesVerticalSubstitution( pTTFont, 1 ); @@ -1414,6 +1467,9 @@ bool PrintFontManager::analyzeTrueTypeFile( PrintFont* pFont ) const fprintf( stderr, "could not OpenTTFont \"%s\"\n", aFile.GetBuffer() ); #endif + if( bSuccess ) + m_pFontCache->updateFontCacheEntry( pFont, m_bFlushFontCache ); + return bSuccess; } @@ -1477,6 +1533,23 @@ void PrintFontManager::initialize( void* pInitDisplay ) { long aDirEntBuffer[ (sizeof(struct dirent)+_PC_NAME_MAX)+1 ]; + if( ! m_pFontCache ) + { +#ifdef DEBUG + fprintf( stderr, "creating font cache ... " ); + clock_t aStart; + struct tms tms; + aStart = times( &tms ); +#endif + m_pFontCache = new FontCache(); +#ifdef DEBUG + clock_t aStop = times( &tms ); + fprintf( stderr, "done in %lf s\n", (double)(aStop - aStart)/(double)CLK_TCK ); +#endif + } + + m_bFlushFontCache = false; + // initialize may be called twice in the future { for( ::std::hash_map< fontID, PrintFont* >::const_iterator it = m_aFonts.begin(); it != m_aFonts.end(); ++it ) @@ -1597,10 +1670,10 @@ void PrintFontManager::initialize( void* pInitDisplay ) // read fonts.dir if possible ::std::hash_map< OString, ::std::list<OString>, OStringHash > aFontsDir; + int nDirID = getDirectoryAtom( aPath, true ); ByteString aGccDummy( aPath ); String aFontsDirPath( aGccDummy, aEncoding ); aFontsDirPath.AppendAscii( "/fonts.dir" ); - int nDirID = getDirectoryAtom( aPath, true ); SvFileStream aStream( aFontsDirPath, STREAM_READ ); if( aStream.IsOpen() ) { @@ -1622,6 +1695,11 @@ void PrintFontManager::initialize( void* pInitDisplay ) while( ! readdir_r( pDIR, (struct dirent*)aDirEntBuffer, &pEntry ) && pEntry ) { OString aFileName( pEntry->d_name ); + // ignore .afm files here + if( aFileName.getLength() > 3 && + aFileName.lastIndexOf( ".afm" ) == aFileName.getLength()-4 ) + continue; + struct stat aStat; ByteString aFilePath( aPath ); aFilePath.Append( '/' ); @@ -1647,11 +1725,9 @@ void PrintFontManager::initialize( void* pInitDisplay ) { fontID aFont = m_nNextFontID++; m_aFonts[ aFont ] = *it; + m_aFontFileToFontID[ aFileName ].insert( aFont ); if( bUpdateFont && isPrivateFontFile( aFont ) ) changeFontProperties( aFont, OStringToOUString( getXLFD( *it ), RTL_TEXTENCODING_UTF8 ) ); -#ifdef DEBUG - fprintf( stderr, "adding font \"%s\" from file \"%s/%s\"\n", OUStringToOString( m_pAtoms->getString( ATOM_FAMILYNAME, (*it)->m_nFamilyName ), RTL_TEXTENCODING_MS_1252 ).getStr(), aPath.getStr(), aFileName.getStr() ); -#endif } } } @@ -1668,6 +1744,7 @@ void PrintFontManager::initialize( void* pInitDisplay ) // part two - look for metrics for builtin printer fonts OString aPath( OUStringToOString( getPrinterPath(), aEncoding ) ); sal_Int32 nIndex = 0; + ::std::list< OString > aEmptyFontsDir; do { OString aDir( aPath.getToken( 0, ':', nIndex ) ); @@ -1676,22 +1753,15 @@ void PrintFontManager::initialize( void* pInitDisplay ) if( pDIR ) { struct dirent* pDirEntry = (struct dirent*)aDirEntBuffer; - OString aSysDir( aDir ); int nDirAtom = getDirectoryAtom( aDir, true ); // get cache information - aSysDir += "/builtincache"; - struct stat aStat; - time_t nCacheDate = 0; - if( ! stat( aSysDir.getStr(), &aStat ) ) - nCacheDate = aStat.st_mtime; - Config aCache( OStringToOUString( aSysDir, aEncoding ) ); - while( ! readdir_r( pDIR, (struct dirent*)aDirEntBuffer, &pDirEntry ) && pDirEntry ) { ByteString aFile( aDir ); aFile += '/'; aFile += pDirEntry->d_name; + struct stat aStat; if( ! stat( aFile.GetBuffer(), &aStat ) && S_ISREG( aStat.st_mode ) ) @@ -1700,74 +1770,21 @@ void PrintFontManager::initialize( void* pInitDisplay ) OString aExt( aFileName.copy( aFileName.lastIndexOf( '.' )+1 ) ); if( aExt.equalsIgnoreAsciiCase( "afm" ) ) { - BuiltinFont* pFont = new BuiltinFont; - pFont->m_nDirectory = nDirAtom; - pFont->m_aMetricFile = aFileName; - - // first try the cache - bool bWasCached = false; - if( aCache.HasGroup( aFileName ) ) - { - aCache.SetGroup( aFileName ); - if( aStat.st_mtime <= nCacheDate ) - { - bWasCached = true; - pFont->m_nFamilyName= m_pAtoms->getAtom( ATOM_FAMILYNAME, String( aCache.ReadKey( "FamilyName" ), RTL_TEXTENCODING_UTF8 ), sal_True ); - pFont->m_nPSName = m_pAtoms->getAtom( ATOM_PSNAME, String( aCache.ReadKey( "PSName" ), RTL_TEXTENCODING_UTF8 ), sal_True ); - pFont->m_eItalic = (italic::type)aCache.ReadKey( "Italic" ).ToInt32(); - pFont->m_eWidth = (width::type)aCache.ReadKey( "Width" ).ToInt32(); - pFont->m_ePitch = (pitch::type)aCache.ReadKey( "Pitch" ).ToInt32(); - pFont->m_eWeight = (weight::type)aCache.ReadKey( "Weight" ).ToInt32(); - pFont->m_aEncoding = (rtl_TextEncoding)aCache.ReadKey( "Encoding" ).ToInt32(); - pFont->m_nAscend = aCache.ReadKey( "Ascend" ).ToInt32(); - pFont->m_nDescend = aCache.ReadKey( "Descend" ).ToInt32(); - pFont->m_nLeading = aCache.ReadKey( "Leading" ).ToInt32(); - ByteString aValue = aCache.ReadKey( "GlobalMetrics" ); - pFont->m_aGlobalMetricX.width = aValue.GetToken( 0, ',' ).ToInt32(); - pFont->m_aGlobalMetricX.height = aValue.GetToken( 1, ',' ).ToInt32(); - pFont->m_aGlobalMetricY.width = aValue.GetToken( 2, ',' ).ToInt32(); - pFont->m_aGlobalMetricY.height = aValue.GetToken( 3, ',' ).ToInt32(); - m_aFonts[ m_nNextFontID++ ] = pFont; -#ifdef DEBUG - nBuiltinFonts++; -#endif - } - } + ::std::list< PrintFont* > aNewFonts; - if( ! bWasCached ) + analyzeFontFile( nDirAtom, aFileName, true, aEmptyFontsDir, aNewFonts ); + for( ::std::list< PrintFont* >::iterator it = aNewFonts.begin(); it != aNewFonts.end(); ++it ) { - if( pFont->readAfmMetrics( aFile, m_pAtoms ) && - findFontBuiltinID( pFont->m_nPSName ) == 0 - ) + if( findFontBuiltinID( (*it)->m_nPSName ) == 0 ) { - m_aFonts[ m_nNextFontID++ ] = pFont; + m_aFontFileToFontID[ aFileName ].insert( m_nNextFontID ); + m_aFonts[ m_nNextFontID++ ] = *it; #ifdef DEBUG nBuiltinFonts++; #endif - - // update the cache - aCache.SetGroup( aFileName ); - aCache.WriteKey( "FamilyName", ByteString( String( m_pAtoms->getString( ATOM_FAMILYNAME, pFont->m_nFamilyName ) ), RTL_TEXTENCODING_UTF8 ) ); - aCache.WriteKey( "PSName", ByteString( String( m_pAtoms->getString( ATOM_PSNAME, pFont->m_nPSName ) ), RTL_TEXTENCODING_UTF8 ) ); - aCache.WriteKey( "Italic", ByteString::CreateFromInt32( (int)pFont->m_eItalic ) ); - aCache.WriteKey( "Width", ByteString::CreateFromInt32( (int)pFont->m_eWidth ) ); - aCache.WriteKey( "Weight", ByteString::CreateFromInt32( (int)pFont->m_eWeight ) ); - aCache.WriteKey( "Pitch", ByteString::CreateFromInt32( (int)pFont->m_ePitch ) ); - aCache.WriteKey( "Encoding", ByteString::CreateFromInt32( (int)pFont->m_aEncoding ) ); - aCache.WriteKey( "Ascend", ByteString::CreateFromInt32( pFont->m_nAscend ) ); - aCache.WriteKey( "Descend", ByteString::CreateFromInt32( pFont->m_nDescend ) ); - aCache.WriteKey( "Leading", ByteString::CreateFromInt32( pFont->m_nLeading ) ); - ByteString aValue( ByteString::CreateFromInt32( pFont->m_aGlobalMetricX.width ) ); - aValue += ','; - aValue += ByteString::CreateFromInt32( pFont->m_aGlobalMetricX.height ); - aValue += ','; - aValue += ByteString::CreateFromInt32( pFont->m_aGlobalMetricY.width ); - aValue += ','; - aValue += ByteString::CreateFromInt32( pFont->m_aGlobalMetricY.height ); - aCache.WriteKey( "GlobalMetrics", aValue ); } else - delete pFont; + delete *it; } } } @@ -1801,6 +1818,9 @@ void PrintFontManager::initialize( void* pInitDisplay ) fprintf( stderr, "Step 2 took %lf seconds\n", (double)(aStep2 - aStep1)/(double)CLK_TCK ); fprintf( stderr, "Step 3 took %lf seconds\n", (double)(aStep3 - aStep2)/(double)CLK_TCK ); #endif + + m_bFlushFontCache = true; + m_pFontCache->flush(); } // ------------------------------------------------------------------------- @@ -1911,6 +1931,9 @@ void PrintFontManager::fillPrintFontInfo( PrintFont* pFont, FastPrintFontInfo& r rInfo.m_eWeight = pFont->m_eWeight; rInfo.m_ePitch = pFont->m_ePitch; rInfo.m_aEncoding = pFont->m_aEncoding; + rInfo.m_aAliases.clear(); + for( ::std::list< int >::iterator it = pFont->m_aAliases.begin(); it != pFont->m_aAliases.end(); ++it ) + rInfo.m_aAliases.push_back( m_pAtoms->getString( ATOM_FAMILYNAME, *it ) ); } // ------------------------------------------------------------------------- @@ -2303,9 +2326,6 @@ bool PrintFontManager::isFontDownloadingAllowed( fontID nFont ) const TTGlobalFontInfo aInfo; GetTTGlobalFontInfo( pTTFont, & aInfo ); pTTFontFile->m_nTypeFlags = (unsigned int)aInfo.typeFlags; -#ifdef DEBUG - fprintf( stderr, "font %s has style flags %x\n", aFile.GetBuffer(), pTTFontFile->m_nTypeFlags ); -#endif CloseTTFont( pTTFont ); } } @@ -2585,6 +2605,7 @@ int PrintFontManager::importFonts( const ::std::list< OString >& rFiles, bool bL { next = current; ++next; + m_aFontFileToFontID[ aFileName ].erase( current->first ); delete current->second; m_aFonts.erase( current ); current = next; @@ -2598,6 +2619,7 @@ int PrintFontManager::importFonts( const ::std::list< OString >& rFiles, bool bL nSuccess++; for( it = aNewFonts.begin(); it != aNewFonts.end(); ++it ) { + m_aFontFileToFontID[ aFileName ].insert( m_nNextFontID ); m_aFonts[ m_nNextFontID++ ] = *it; aLine = ByteString( aTo.GetName(), aEncoding ); aLine += ' '; @@ -2942,6 +2964,7 @@ bool PrintFontManager::removeFonts( const ::std::list< fontID >& rFonts ) { for( ::std::list< fontID >::iterator dup = aDuplicates.begin(); dup != aDuplicates.end(); ++dup ) { + m_aFontFileToFontID[ aFile ].erase( *dup ); PrintFont* pDup = m_aFonts[ *dup ]; m_aFonts.erase( *dup ); delete pDup; diff --git a/psprint/source/fontmanager/makefile.mk b/psprint/source/fontmanager/makefile.mk index abca93c6d523..4aecc71e766e 100644 --- a/psprint/source/fontmanager/makefile.mk +++ b/psprint/source/fontmanager/makefile.mk @@ -2,9 +2,9 @@ # # $RCSfile: makefile.mk,v $ # -# $Revision: 1.2 $ +# $Revision: 1.3 $ # -# last change: $Author: vg $ $Date: 2001-09-18 09:43:50 $ +# last change: $Author: pl $ $Date: 2002-02-28 11:49:51 $ # # The Contents of this file are made available subject to the terms of # either of the following licenses @@ -83,6 +83,7 @@ dummy: SLOFILES=\ $(SLO)$/fontmanager.obj \ + $(SLO)$/fontcache.obj \ $(SLO)$/parseAFM.obj .IF "$(OS)$(CPU)"=="SOLARISI" |