summaryrefslogtreecommitdiff
path: root/psprint
diff options
context:
space:
mode:
authorPhilipp Lohmann <pl@openoffice.org>2002-02-28 10:53:08 +0000
committerPhilipp Lohmann <pl@openoffice.org>2002-02-28 10:53:08 +0000
commit14f4a49266f5206260b5e9f0780913c56dd8d5a0 (patch)
treed7826f40446aaca5e75fe89657bc2bd2ec857ca7 /psprint
parentfd03488af96dd9234adbefad62e60bdb69511894 (diff)
#97829# #i1991# add font aliases
Diffstat (limited to 'psprint')
-rw-r--r--psprint/inc/psprint/fontcache.hxx99
-rw-r--r--psprint/inc/psprint/fontmanager.hxx46
-rw-r--r--psprint/source/fontmanager/fontcache.cxx587
-rw-r--r--psprint/source/fontmanager/fontmanager.cxx291
-rw-r--r--psprint/source/fontmanager/makefile.mk5
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"