1c82f2877SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3c82f2877SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4c82f2877SAndrew Rist * or more contributor license agreements. See the NOTICE file 5c82f2877SAndrew Rist * distributed with this work for additional information 6c82f2877SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7c82f2877SAndrew Rist * to you under the Apache License, Version 2.0 (the 8c82f2877SAndrew Rist * "License"); you may not use this file except in compliance 9c82f2877SAndrew Rist * with the License. You may obtain a copy of the License at 10c82f2877SAndrew Rist * 11c82f2877SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12c82f2877SAndrew Rist * 13c82f2877SAndrew Rist * Unless required by applicable law or agreed to in writing, 14c82f2877SAndrew Rist * software distributed under the License is distributed on an 15c82f2877SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16c82f2877SAndrew Rist * KIND, either express or implied. See the License for the 17c82f2877SAndrew Rist * specific language governing permissions and limitations 18c82f2877SAndrew Rist * under the License. 19c82f2877SAndrew Rist * 20c82f2877SAndrew Rist *************************************************************/ 21c82f2877SAndrew Rist 22c82f2877SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_vcl.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include <unistd.h> 28cdf0e10cSrcweir #include <sys/stat.h> 29cdf0e10cSrcweir #include <dirent.h> 30cdf0e10cSrcweir #include <stdlib.h> 31cdf0e10cSrcweir #include <osl/thread.h> 32cdf0e10cSrcweir 33cdf0e10cSrcweir #include "unotools/atom.hxx" 34cdf0e10cSrcweir 35cdf0e10cSrcweir #include "fontcache.hxx" 36cdf0e10cSrcweir #include "fontsubset.hxx" 37cdf0e10cSrcweir #include "impfont.hxx" 38cdf0e10cSrcweir #include "svdata.hxx" 39cdf0e10cSrcweir #include "salinst.hxx" 40cdf0e10cSrcweir #include "vcl/fontmanager.hxx" 41cdf0e10cSrcweir #include "vcl/strhelper.hxx" 42cdf0e10cSrcweir #include "vcl/ppdparser.hxx" 43cdf0e10cSrcweir 44cdf0e10cSrcweir #include "tools/urlobj.hxx" 45cdf0e10cSrcweir #include "tools/stream.hxx" 46cdf0e10cSrcweir #include "tools/debug.hxx" 47cdf0e10cSrcweir #include "tools/config.hxx" 48cdf0e10cSrcweir 49cdf0e10cSrcweir #include "osl/file.hxx" 50cdf0e10cSrcweir #include "osl/process.h" 51cdf0e10cSrcweir 52cdf0e10cSrcweir #include "rtl/tencinfo.h" 53cdf0e10cSrcweir #include "rtl/ustrbuf.hxx" 54cdf0e10cSrcweir #include "rtl/strbuf.hxx" 55cdf0e10cSrcweir 56cdf0e10cSrcweir #include "i18npool/mslangid.hxx" 57cdf0e10cSrcweir 58cdf0e10cSrcweir 59cdf0e10cSrcweir #include "parseAFM.hxx" 60cdf0e10cSrcweir #include "sft.hxx" 61cdf0e10cSrcweir 62cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 63cdf0e10cSrcweir #include <sys/times.h> 64cdf0e10cSrcweir #include <stdio.h> 65cdf0e10cSrcweir #endif 66cdf0e10cSrcweir 67cdf0e10cSrcweir #include "sal/alloca.h" 68cdf0e10cSrcweir 69cdf0e10cSrcweir #include <set> 70cdf0e10cSrcweir #include <hash_set> 71cdf0e10cSrcweir #include <algorithm> 72cdf0e10cSrcweir 73cdf0e10cSrcweir #include "adobeenc.tab" // get encoding table for AFM metrics 74cdf0e10cSrcweir 75cdf0e10cSrcweir #ifdef CALLGRIND_COMPILE 76cdf0e10cSrcweir #include <valgrind/callgrind.h> 77cdf0e10cSrcweir #endif 78cdf0e10cSrcweir 79cdf0e10cSrcweir #include "comphelper/processfactory.hxx" 80cdf0e10cSrcweir #include "com/sun/star/beans/XMaterialHolder.hpp" 81cdf0e10cSrcweir #include "com/sun/star/beans/NamedValue.hpp" 82cdf0e10cSrcweir 83cdf0e10cSrcweir #define PRINTER_METRICDIR "fontmetric" 84cdf0e10cSrcweir 85cdf0e10cSrcweir namespace { 86cdf0e10cSrcweir 87cdf0e10cSrcweir namespace css = com::sun::star; 88cdf0e10cSrcweir 89cdf0e10cSrcweir } 90cdf0e10cSrcweir 91cdf0e10cSrcweir using namespace vcl; 92cdf0e10cSrcweir using namespace utl; 93cdf0e10cSrcweir using namespace psp; 94cdf0e10cSrcweir using namespace osl; 95cdf0e10cSrcweir using namespace rtl; 96cdf0e10cSrcweir using namespace com::sun::star::uno; 97cdf0e10cSrcweir using namespace com::sun::star::beans; 98cdf0e10cSrcweir using namespace com::sun::star::lang; 99cdf0e10cSrcweir 100cdf0e10cSrcweir /* 101cdf0e10cSrcweir * static helpers 102cdf0e10cSrcweir */ 103cdf0e10cSrcweir 104cdf0e10cSrcweir inline sal_uInt16 getUInt16BE( const sal_uInt8*& pBuffer ) 105cdf0e10cSrcweir { 106cdf0e10cSrcweir sal_uInt16 nRet = (sal_uInt16)pBuffer[1] | 107cdf0e10cSrcweir (((sal_uInt16)pBuffer[0]) << 8); 108cdf0e10cSrcweir pBuffer+=2; 109cdf0e10cSrcweir return nRet; 110cdf0e10cSrcweir } 111cdf0e10cSrcweir 112cdf0e10cSrcweir inline sal_uInt32 getUInt32BE( const sal_uInt8*& pBuffer ) 113cdf0e10cSrcweir { 114cdf0e10cSrcweir sal_uInt32 nRet = (((sal_uInt32)pBuffer[0]) << 24) | 115cdf0e10cSrcweir (((sal_uInt32)pBuffer[1]) << 16) | 116cdf0e10cSrcweir (((sal_uInt32)pBuffer[2]) << 8) | 117cdf0e10cSrcweir (((sal_uInt32)pBuffer[3]) ); 118cdf0e10cSrcweir pBuffer += 4; 119cdf0e10cSrcweir return nRet; 120cdf0e10cSrcweir } 121cdf0e10cSrcweir 122cdf0e10cSrcweir static italic::type parseItalic( const ByteString& rItalic ) 123cdf0e10cSrcweir { 124cdf0e10cSrcweir italic::type eItalic = italic::Unknown; 125cdf0e10cSrcweir if( rItalic.EqualsIgnoreCaseAscii( "i" ) ) 126cdf0e10cSrcweir eItalic = italic::Italic; 127cdf0e10cSrcweir else if( rItalic.EqualsIgnoreCaseAscii( "o" ) ) 128cdf0e10cSrcweir eItalic = italic::Oblique; 129cdf0e10cSrcweir else 130cdf0e10cSrcweir eItalic = italic::Upright; 131cdf0e10cSrcweir return eItalic; 132cdf0e10cSrcweir } 133cdf0e10cSrcweir 134cdf0e10cSrcweir // ------------------------------------------------------------------------- 135cdf0e10cSrcweir 136cdf0e10cSrcweir static weight::type parseWeight( const ByteString& rWeight ) 137cdf0e10cSrcweir { 138cdf0e10cSrcweir weight::type eWeight = weight::Unknown; 139cdf0e10cSrcweir if( rWeight.Search( "bold" ) != STRING_NOTFOUND ) 140cdf0e10cSrcweir { 141cdf0e10cSrcweir if( rWeight.Search( "emi" ) != STRING_NOTFOUND ) // semi, demi 142cdf0e10cSrcweir eWeight = weight::SemiBold; 143cdf0e10cSrcweir else if( rWeight.Search( "ultra" ) != STRING_NOTFOUND ) 144cdf0e10cSrcweir eWeight = weight::UltraBold; 145cdf0e10cSrcweir else 146cdf0e10cSrcweir eWeight = weight::Bold; 147cdf0e10cSrcweir } 148cdf0e10cSrcweir else if( rWeight.Search( "heavy" ) != STRING_NOTFOUND ) 149cdf0e10cSrcweir eWeight = weight::Bold; 150cdf0e10cSrcweir else if( rWeight.Search( "light" ) != STRING_NOTFOUND ) 151cdf0e10cSrcweir { 152cdf0e10cSrcweir if( rWeight.Search( "emi" ) != STRING_NOTFOUND ) // semi, demi 153cdf0e10cSrcweir eWeight = weight::SemiLight; 154cdf0e10cSrcweir else if( rWeight.Search( "ultra" ) != STRING_NOTFOUND ) 155cdf0e10cSrcweir eWeight = weight::UltraLight; 156cdf0e10cSrcweir else 157cdf0e10cSrcweir eWeight = weight::Light; 158cdf0e10cSrcweir } 159cdf0e10cSrcweir else if( rWeight.Search( "black" ) != STRING_NOTFOUND ) 160cdf0e10cSrcweir eWeight = weight::Black; 161cdf0e10cSrcweir else if( rWeight.Equals( "demi" ) ) 162cdf0e10cSrcweir eWeight = weight::SemiBold; 163cdf0e10cSrcweir else if( rWeight.Equals( "book" ) || 164cdf0e10cSrcweir rWeight.Equals( "semicondensed" ) ) 165cdf0e10cSrcweir eWeight = weight::Light; 166cdf0e10cSrcweir else if( rWeight.Equals( "medium" ) || rWeight.Equals( "roman" ) ) 167cdf0e10cSrcweir eWeight = weight::Medium; 168cdf0e10cSrcweir else 169cdf0e10cSrcweir eWeight = weight::Normal; 170cdf0e10cSrcweir return eWeight; 171cdf0e10cSrcweir } 172cdf0e10cSrcweir 173cdf0e10cSrcweir // ------------------------------------------------------------------------- 174cdf0e10cSrcweir 175cdf0e10cSrcweir static width::type parseWidth( const ByteString& rWidth ) 176cdf0e10cSrcweir { 177cdf0e10cSrcweir width::type eWidth = width::Unknown; 178cdf0e10cSrcweir if( rWidth.Equals( "bold" ) || 179cdf0e10cSrcweir rWidth.Equals( "semiexpanded" ) ) 180cdf0e10cSrcweir eWidth = width::SemiExpanded; 181cdf0e10cSrcweir else if( rWidth.Equals( "condensed" ) || 182cdf0e10cSrcweir rWidth.Equals( "narrow" ) ) 183cdf0e10cSrcweir eWidth = width::Condensed; 184cdf0e10cSrcweir else if( rWidth.Equals( "double wide" ) || 185cdf0e10cSrcweir rWidth.Equals( "extraexpanded" ) || 186cdf0e10cSrcweir rWidth.Equals( "ultraexpanded" ) ) 187cdf0e10cSrcweir eWidth = width::UltraExpanded; 188cdf0e10cSrcweir else if( rWidth.Equals( "expanded" ) || 189cdf0e10cSrcweir rWidth.Equals( "wide" ) ) 190cdf0e10cSrcweir eWidth = width::Expanded; 191cdf0e10cSrcweir else if( rWidth.Equals( "extracondensed" ) ) 192cdf0e10cSrcweir eWidth = width::ExtraCondensed; 193cdf0e10cSrcweir else if( rWidth.Equals( "semicondensed" ) ) 194cdf0e10cSrcweir eWidth = width::SemiCondensed; 195cdf0e10cSrcweir else if( rWidth.Equals( "ultracondensed" ) ) 196cdf0e10cSrcweir eWidth = width::UltraCondensed; 197cdf0e10cSrcweir else 198cdf0e10cSrcweir eWidth = width::Normal; 199cdf0e10cSrcweir 200cdf0e10cSrcweir return eWidth; 201cdf0e10cSrcweir } 202cdf0e10cSrcweir 203cdf0e10cSrcweir // ------------------------------------------------------------------------- 204cdf0e10cSrcweir bool PrintFontManager::XLFDEntry::operator<(const PrintFontManager::XLFDEntry& rRight) const 205cdf0e10cSrcweir { 206cdf0e10cSrcweir sal_Int32 nCmp = 0; 207cdf0e10cSrcweir if( (nMask & MaskFamily) && (rRight.nMask & MaskFamily) ) 208cdf0e10cSrcweir { 209cdf0e10cSrcweir nCmp = rtl_str_compareIgnoreAsciiCase_WithLength( aFamily.pData->buffer, 210cdf0e10cSrcweir aFamily.pData->length, 211cdf0e10cSrcweir rRight.aFamily.pData->buffer, 212cdf0e10cSrcweir rRight.aFamily.pData->length ); 213cdf0e10cSrcweir if( nCmp != 0 ) 214cdf0e10cSrcweir return nCmp < 0; 215cdf0e10cSrcweir } 216cdf0e10cSrcweir 217cdf0e10cSrcweir if( (nMask & MaskFoundry) && (rRight.nMask & MaskFoundry) ) 218cdf0e10cSrcweir { 219cdf0e10cSrcweir nCmp = rtl_str_compareIgnoreAsciiCase_WithLength( aFoundry.pData->buffer, 220cdf0e10cSrcweir aFoundry.pData->length, 221cdf0e10cSrcweir rRight.aFoundry.pData->buffer, 222cdf0e10cSrcweir rRight.aFoundry.pData->length ); 223cdf0e10cSrcweir if( nCmp != 0 ) 224cdf0e10cSrcweir return nCmp < 0; 225cdf0e10cSrcweir } 226cdf0e10cSrcweir 227cdf0e10cSrcweir if( (nMask & MaskItalic) && (rRight.nMask & MaskItalic) ) 228cdf0e10cSrcweir { 229cdf0e10cSrcweir if( eItalic != rRight.eItalic ) 230cdf0e10cSrcweir return (int)eItalic < (int)rRight.eItalic; 231cdf0e10cSrcweir } 232cdf0e10cSrcweir 233cdf0e10cSrcweir if( (nMask & MaskWeight) && (rRight.nMask & MaskWeight) ) 234cdf0e10cSrcweir { 235cdf0e10cSrcweir if( eWeight != rRight.eWeight ) 236cdf0e10cSrcweir return (int)eWeight < (int)rRight.eWeight; 237cdf0e10cSrcweir } 238cdf0e10cSrcweir 239cdf0e10cSrcweir if( (nMask & MaskWidth) && (rRight.nMask & MaskWidth) ) 240cdf0e10cSrcweir { 241cdf0e10cSrcweir if( eWidth != rRight.eWidth ) 242cdf0e10cSrcweir return (int)eWidth < (int)rRight.eWidth; 243cdf0e10cSrcweir } 244cdf0e10cSrcweir 245cdf0e10cSrcweir if( (nMask & MaskPitch) && (rRight.nMask & MaskPitch) ) 246cdf0e10cSrcweir { 247cdf0e10cSrcweir if( ePitch != rRight.ePitch ) 248cdf0e10cSrcweir return (int)ePitch < (int)rRight.ePitch; 249cdf0e10cSrcweir } 250cdf0e10cSrcweir 251cdf0e10cSrcweir if( (nMask & MaskAddStyle) && (rRight.nMask & MaskAddStyle) ) 252cdf0e10cSrcweir { 253cdf0e10cSrcweir nCmp = rtl_str_compareIgnoreAsciiCase_WithLength( aAddStyle.pData->buffer, 254cdf0e10cSrcweir aAddStyle.pData->length, 255cdf0e10cSrcweir rRight.aAddStyle.pData->buffer, 256cdf0e10cSrcweir rRight.aAddStyle.pData->length ); 257cdf0e10cSrcweir if( nCmp != 0 ) 258cdf0e10cSrcweir return nCmp < 0; 259cdf0e10cSrcweir } 260cdf0e10cSrcweir 261cdf0e10cSrcweir if( (nMask & MaskEncoding) && (rRight.nMask & MaskEncoding) ) 262cdf0e10cSrcweir { 263cdf0e10cSrcweir if( aEncoding != rRight.aEncoding ) 264cdf0e10cSrcweir return aEncoding < rRight.aEncoding; 265cdf0e10cSrcweir } 266cdf0e10cSrcweir 267cdf0e10cSrcweir return false; 268cdf0e10cSrcweir } 269cdf0e10cSrcweir 270cdf0e10cSrcweir bool PrintFontManager::XLFDEntry::operator==(const PrintFontManager::XLFDEntry& rRight) const 271cdf0e10cSrcweir { 272cdf0e10cSrcweir sal_Int32 nCmp = 0; 273cdf0e10cSrcweir if( (nMask & MaskFamily) && (rRight.nMask & MaskFamily) ) 274cdf0e10cSrcweir { 275cdf0e10cSrcweir nCmp = rtl_str_compareIgnoreAsciiCase_WithLength( aFamily.pData->buffer, 276cdf0e10cSrcweir aFamily.pData->length, 277cdf0e10cSrcweir rRight.aFamily.pData->buffer, 278cdf0e10cSrcweir rRight.aFamily.pData->length ); 279cdf0e10cSrcweir if( nCmp != 0 ) 280cdf0e10cSrcweir return false; 281cdf0e10cSrcweir } 282cdf0e10cSrcweir 283cdf0e10cSrcweir if( (nMask & MaskFoundry) && (rRight.nMask & MaskFoundry) ) 284cdf0e10cSrcweir { 285cdf0e10cSrcweir nCmp = rtl_str_compareIgnoreAsciiCase_WithLength( aFoundry.pData->buffer, 286cdf0e10cSrcweir aFoundry.pData->length, 287cdf0e10cSrcweir rRight.aFoundry.pData->buffer, 288cdf0e10cSrcweir rRight.aFoundry.pData->length ); 289cdf0e10cSrcweir if( nCmp != 0 ) 290cdf0e10cSrcweir return false; 291cdf0e10cSrcweir } 292cdf0e10cSrcweir 293cdf0e10cSrcweir if( (nMask & MaskItalic) && (rRight.nMask & MaskItalic) ) 294cdf0e10cSrcweir { 295cdf0e10cSrcweir if( eItalic != rRight.eItalic ) 296cdf0e10cSrcweir return false; 297cdf0e10cSrcweir } 298cdf0e10cSrcweir 299cdf0e10cSrcweir if( (nMask & MaskWeight) && (rRight.nMask & MaskWeight) ) 300cdf0e10cSrcweir { 301cdf0e10cSrcweir if( eWeight != rRight.eWeight ) 302cdf0e10cSrcweir return false; 303cdf0e10cSrcweir } 304cdf0e10cSrcweir 305cdf0e10cSrcweir if( (nMask & MaskWidth) && (rRight.nMask & MaskWidth) ) 306cdf0e10cSrcweir { 307cdf0e10cSrcweir if( eWidth != rRight.eWidth ) 308cdf0e10cSrcweir return false; 309cdf0e10cSrcweir } 310cdf0e10cSrcweir 311cdf0e10cSrcweir if( (nMask & MaskPitch) && (rRight.nMask & MaskPitch) ) 312cdf0e10cSrcweir { 313cdf0e10cSrcweir if( ePitch != rRight.ePitch ) 314cdf0e10cSrcweir return false; 315cdf0e10cSrcweir } 316cdf0e10cSrcweir 317cdf0e10cSrcweir if( (nMask & MaskAddStyle) && (rRight.nMask & MaskAddStyle) ) 318cdf0e10cSrcweir { 319cdf0e10cSrcweir nCmp = rtl_str_compareIgnoreAsciiCase_WithLength( aAddStyle.pData->buffer, 320cdf0e10cSrcweir aAddStyle.pData->length, 321cdf0e10cSrcweir rRight.aAddStyle.pData->buffer, 322cdf0e10cSrcweir rRight.aAddStyle.pData->length ); 323cdf0e10cSrcweir if( nCmp != 0 ) 324cdf0e10cSrcweir return false; 325cdf0e10cSrcweir } 326cdf0e10cSrcweir 327cdf0e10cSrcweir if( (nMask & MaskEncoding) && (rRight.nMask & MaskEncoding) ) 328cdf0e10cSrcweir { 329cdf0e10cSrcweir if( aEncoding != rRight.aEncoding ) 330cdf0e10cSrcweir return false; 331cdf0e10cSrcweir } 332cdf0e10cSrcweir 333cdf0e10cSrcweir return true; 334cdf0e10cSrcweir } 335cdf0e10cSrcweir 336cdf0e10cSrcweir /* 337cdf0e10cSrcweir * PrintFont implementations 338cdf0e10cSrcweir */ 339cdf0e10cSrcweir PrintFontManager::PrintFont::PrintFont( fonttype::type eType ) : 340cdf0e10cSrcweir m_eType( eType ), 341cdf0e10cSrcweir m_nFamilyName( 0 ), 342cdf0e10cSrcweir m_nPSName( 0 ), 343cdf0e10cSrcweir m_eItalic( italic::Unknown ), 344cdf0e10cSrcweir m_eWidth( width::Unknown ), 345cdf0e10cSrcweir m_eWeight( weight::Unknown ), 346cdf0e10cSrcweir m_ePitch( pitch::Unknown ), 347cdf0e10cSrcweir m_aEncoding( RTL_TEXTENCODING_DONTKNOW ), 348cdf0e10cSrcweir m_bFontEncodingOnly( false ), 349cdf0e10cSrcweir m_pMetrics( NULL ), 350cdf0e10cSrcweir m_nAscend( 0 ), 351cdf0e10cSrcweir m_nDescend( 0 ), 352cdf0e10cSrcweir m_nLeading( 0 ), 353cdf0e10cSrcweir m_nXMin( 0 ), 354cdf0e10cSrcweir m_nYMin( 0 ), 355cdf0e10cSrcweir m_nXMax( 0 ), 356cdf0e10cSrcweir m_nYMax( 0 ), 357cdf0e10cSrcweir m_bHaveVerticalSubstitutedGlyphs( false ), 358cdf0e10cSrcweir m_bUserOverride( false ) 359cdf0e10cSrcweir { 360cdf0e10cSrcweir } 361cdf0e10cSrcweir 362cdf0e10cSrcweir // ------------------------------------------------------------------------- 363cdf0e10cSrcweir 364cdf0e10cSrcweir PrintFontManager::PrintFont::~PrintFont() 365cdf0e10cSrcweir { 366cdf0e10cSrcweir if( m_pMetrics ) 367cdf0e10cSrcweir delete m_pMetrics; 368cdf0e10cSrcweir } 369cdf0e10cSrcweir 370cdf0e10cSrcweir // ------------------------------------------------------------------------- 371cdf0e10cSrcweir 372cdf0e10cSrcweir PrintFontManager::Type1FontFile::~Type1FontFile() 373cdf0e10cSrcweir { 374cdf0e10cSrcweir } 375cdf0e10cSrcweir 376cdf0e10cSrcweir // ------------------------------------------------------------------------- 377cdf0e10cSrcweir 378cdf0e10cSrcweir PrintFontManager::TrueTypeFontFile::TrueTypeFontFile() 379cdf0e10cSrcweir : PrintFont( fonttype::TrueType ) 380cdf0e10cSrcweir , m_nDirectory( 0 ) 381cdf0e10cSrcweir , m_nCollectionEntry(-1) 382cdf0e10cSrcweir , m_nTypeFlags( TYPEFLAG_INVALID ) 383cdf0e10cSrcweir {} 384cdf0e10cSrcweir 385cdf0e10cSrcweir // ------------------------------------------------------------------------- 386cdf0e10cSrcweir 387cdf0e10cSrcweir PrintFontManager::TrueTypeFontFile::~TrueTypeFontFile() 388cdf0e10cSrcweir { 389cdf0e10cSrcweir } 390cdf0e10cSrcweir 391cdf0e10cSrcweir // ------------------------------------------------------------------------- 392cdf0e10cSrcweir 393cdf0e10cSrcweir PrintFontManager::BuiltinFont::~BuiltinFont() 394cdf0e10cSrcweir { 395cdf0e10cSrcweir } 396cdf0e10cSrcweir 397cdf0e10cSrcweir // ------------------------------------------------------------------------- 398cdf0e10cSrcweir 399cdf0e10cSrcweir bool PrintFontManager::Type1FontFile::queryMetricPage( int /*nPage*/, MultiAtomProvider* pProvider ) 400cdf0e10cSrcweir { 401cdf0e10cSrcweir return readAfmMetrics( PrintFontManager::get().getAfmFile( this ), pProvider, false, false ); 402cdf0e10cSrcweir } 403cdf0e10cSrcweir 404cdf0e10cSrcweir // ------------------------------------------------------------------------- 405cdf0e10cSrcweir 406cdf0e10cSrcweir bool PrintFontManager::BuiltinFont::queryMetricPage( int /*nPage*/, MultiAtomProvider* pProvider ) 407cdf0e10cSrcweir { 408cdf0e10cSrcweir return readAfmMetrics( PrintFontManager::get().getAfmFile( this ), pProvider, false, false ); 409cdf0e10cSrcweir } 410cdf0e10cSrcweir 411cdf0e10cSrcweir // ------------------------------------------------------------------------- 412cdf0e10cSrcweir 413cdf0e10cSrcweir bool PrintFontManager::TrueTypeFontFile::queryMetricPage( int nPage, MultiAtomProvider* pProvider ) 414cdf0e10cSrcweir { 415cdf0e10cSrcweir bool bSuccess = false; 416cdf0e10cSrcweir 417cdf0e10cSrcweir ByteString aFile( PrintFontManager::get().getFontFile( this ) ); 418cdf0e10cSrcweir 419cdf0e10cSrcweir TrueTypeFont* pTTFont = NULL; 420cdf0e10cSrcweir 421cdf0e10cSrcweir if( OpenTTFontFile( aFile.GetBuffer(), m_nCollectionEntry < 0 ? 0 : m_nCollectionEntry, &pTTFont ) == SF_OK ) 422cdf0e10cSrcweir { 423cdf0e10cSrcweir if( ! m_pMetrics ) 424cdf0e10cSrcweir { 425cdf0e10cSrcweir m_pMetrics = new PrintFontMetrics; 426cdf0e10cSrcweir memset (m_pMetrics->m_aPages, 0, sizeof(m_pMetrics->m_aPages)); 427cdf0e10cSrcweir } 428cdf0e10cSrcweir m_pMetrics->m_aPages[ nPage/8 ] |= (1 << ( nPage & 7 )); 429cdf0e10cSrcweir int i; 430cdf0e10cSrcweir sal_uInt16 table[256], table_vert[256]; 431cdf0e10cSrcweir 432cdf0e10cSrcweir for( i = 0; i < 256; i++ ) 433cdf0e10cSrcweir table[ i ] = 256*nPage + i; 434cdf0e10cSrcweir 435cdf0e10cSrcweir int nCharacters = nPage < 255 ? 256 : 254; 436cdf0e10cSrcweir MapString( pTTFont, table, nCharacters, NULL, 0 ); 437cdf0e10cSrcweir TTSimpleGlyphMetrics* pMetrics = GetTTSimpleCharMetrics( pTTFont, nPage*256, nCharacters, 0 ); 438cdf0e10cSrcweir if( pMetrics ) 439cdf0e10cSrcweir { 440cdf0e10cSrcweir for( i = 0; i < nCharacters; i++ ) 441cdf0e10cSrcweir { 442cdf0e10cSrcweir if( table[i] ) 443cdf0e10cSrcweir { 444cdf0e10cSrcweir CharacterMetric& rChar = m_pMetrics->m_aMetrics[ nPage*256 + i ]; 445cdf0e10cSrcweir rChar.width = pMetrics[ i ].adv; 446cdf0e10cSrcweir rChar.height = m_aGlobalMetricX.height; 447cdf0e10cSrcweir } 448cdf0e10cSrcweir } 449cdf0e10cSrcweir 450cdf0e10cSrcweir free( pMetrics ); 451cdf0e10cSrcweir } 452cdf0e10cSrcweir 453cdf0e10cSrcweir for( i = 0; i < 256; i++ ) 454cdf0e10cSrcweir table_vert[ i ] = 256*nPage + i; 455cdf0e10cSrcweir MapString( pTTFont, table_vert, nCharacters, NULL, 1 ); 456cdf0e10cSrcweir pMetrics = GetTTSimpleCharMetrics( pTTFont, nPage*256, nCharacters, 1 ); 457cdf0e10cSrcweir if( pMetrics ) 458cdf0e10cSrcweir { 459cdf0e10cSrcweir for( i = 0; i < nCharacters; i++ ) 460cdf0e10cSrcweir { 461cdf0e10cSrcweir if( table_vert[i] ) 462cdf0e10cSrcweir { 463cdf0e10cSrcweir CharacterMetric& rChar = m_pMetrics->m_aMetrics[ nPage*256 + i + ( 1 << 16 ) ]; 464cdf0e10cSrcweir rChar.width = m_aGlobalMetricY.width; 465cdf0e10cSrcweir rChar.height = pMetrics[ i ].adv; 466cdf0e10cSrcweir if( table_vert[i] != table[i] ) 467cdf0e10cSrcweir m_pMetrics->m_bVerticalSubstitutions[ nPage*256 + i ] = 1; 468cdf0e10cSrcweir } 469cdf0e10cSrcweir } 470cdf0e10cSrcweir free( pMetrics ); 471cdf0e10cSrcweir } 472cdf0e10cSrcweir 473cdf0e10cSrcweir if( ! m_pMetrics->m_bKernPairsQueried ) 474cdf0e10cSrcweir { 475cdf0e10cSrcweir m_pMetrics->m_bKernPairsQueried = true; 476cdf0e10cSrcweir // this is really a hack 477cdf0e10cSrcweir // in future MapString/KernGlyphs should be used 478cdf0e10cSrcweir // but vcl is not in a state where that could be used 479cdf0e10cSrcweir // so currently we get kernpairs by accessing the raw data 480cdf0e10cSrcweir struct _TrueTypeFont* pImplTTFont = (struct _TrueTypeFont*)pTTFont; 481cdf0e10cSrcweir 482cdf0e10cSrcweir //----------------------------------------------------------------- 483cdf0e10cSrcweir // Kerning: KT_MICROSOFT 484cdf0e10cSrcweir //----------------------------------------------------------------- 485cdf0e10cSrcweir if( pImplTTFont->nkern && pImplTTFont->kerntype == KT_MICROSOFT ) 486cdf0e10cSrcweir { 487cdf0e10cSrcweir // create a glyph -> character mapping 488cdf0e10cSrcweir ::std::hash_map< sal_uInt16, sal_Unicode > aGlyphMap; 489cdf0e10cSrcweir ::std::hash_map< sal_uInt16, sal_Unicode >::iterator left, right; 490cdf0e10cSrcweir for( i = 21; i < 0xfffd; i++ ) 491cdf0e10cSrcweir { 492cdf0e10cSrcweir sal_uInt16 nGlyph = MapChar( pTTFont, (sal_Unicode)i, 0 ); // kerning for horz only 493cdf0e10cSrcweir if( nGlyph != 0 ) 494cdf0e10cSrcweir aGlyphMap[ nGlyph ] = (sal_Unicode)i; 495cdf0e10cSrcweir } 496cdf0e10cSrcweir 497cdf0e10cSrcweir 498cdf0e10cSrcweir KernPair aPair; 499cdf0e10cSrcweir for( i = 0; i < (int)pImplTTFont->nkern; i++ ) 500cdf0e10cSrcweir { 501cdf0e10cSrcweir const sal_uInt8* pTable = pImplTTFont->kerntables[i]; 502cdf0e10cSrcweir 503cdf0e10cSrcweir /*sal_uInt16 nVersion =*/ getUInt16BE( pTable ); 504cdf0e10cSrcweir /*sal_uInt16 nLength =*/ getUInt16BE( pTable ); 505cdf0e10cSrcweir sal_uInt16 nCoverage = getUInt16BE( pTable ); 506cdf0e10cSrcweir 507cdf0e10cSrcweir aPair.kern_x = 0; 508cdf0e10cSrcweir aPair.kern_y = 0; 509cdf0e10cSrcweir switch( nCoverage >> 8 ) 510cdf0e10cSrcweir { 511cdf0e10cSrcweir case 0: 512cdf0e10cSrcweir { 513cdf0e10cSrcweir sal_uInt16 nPairs = getUInt16BE( pTable ); 514cdf0e10cSrcweir pTable += 6; 515cdf0e10cSrcweir for( int n = 0; n < nPairs; n++ ) 516cdf0e10cSrcweir { 517cdf0e10cSrcweir sal_uInt16 nLeftGlyph = getUInt16BE( pTable ); 518cdf0e10cSrcweir sal_uInt16 nRightGlyph = getUInt16BE( pTable ); 519cdf0e10cSrcweir sal_Int16 nKern = (sal_Int16)getUInt16BE( pTable ); 520cdf0e10cSrcweir 521cdf0e10cSrcweir left = aGlyphMap.find( nLeftGlyph ); 522cdf0e10cSrcweir right = aGlyphMap.find( nRightGlyph ); 523cdf0e10cSrcweir if( left != aGlyphMap.end() && right != aGlyphMap.end() ) 524cdf0e10cSrcweir { 525cdf0e10cSrcweir aPair.first = left->second; 526cdf0e10cSrcweir aPair.second = right->second; 527cdf0e10cSrcweir switch( nCoverage & 1 ) 528cdf0e10cSrcweir { 529cdf0e10cSrcweir case 1: 530cdf0e10cSrcweir aPair.kern_x = (int)nKern * 1000 / pImplTTFont->unitsPerEm; 531cdf0e10cSrcweir m_pMetrics->m_aXKernPairs.push_back( aPair ); 532cdf0e10cSrcweir break; 533cdf0e10cSrcweir case 0: 534cdf0e10cSrcweir aPair.kern_y = (int)nKern * 1000 / pImplTTFont->unitsPerEm; 535cdf0e10cSrcweir m_pMetrics->m_aYKernPairs.push_back( aPair ); 536cdf0e10cSrcweir break; 537cdf0e10cSrcweir } 538cdf0e10cSrcweir } 539cdf0e10cSrcweir } 540cdf0e10cSrcweir } 541cdf0e10cSrcweir break; 542cdf0e10cSrcweir 543cdf0e10cSrcweir case 2: 544cdf0e10cSrcweir { 545cdf0e10cSrcweir const sal_uInt8* pSubTable = pTable; 546cdf0e10cSrcweir /*sal_uInt16 nRowWidth =*/ getUInt16BE( pTable ); 547cdf0e10cSrcweir sal_uInt16 nOfLeft = getUInt16BE( pTable ); 548cdf0e10cSrcweir sal_uInt16 nOfRight = getUInt16BE( pTable ); 549cdf0e10cSrcweir /*sal_uInt16 nOfArray =*/ getUInt16BE( pTable ); 550cdf0e10cSrcweir const sal_uInt8* pTmp = pSubTable + nOfLeft; 551cdf0e10cSrcweir sal_uInt16 nFirstLeft = getUInt16BE( pTmp ); 552cdf0e10cSrcweir sal_uInt16 nLastLeft = getUInt16BE( pTmp ) + nFirstLeft - 1; 553cdf0e10cSrcweir pTmp = pSubTable + nOfRight; 554cdf0e10cSrcweir sal_uInt16 nFirstRight = getUInt16BE( pTmp ); 555cdf0e10cSrcweir sal_uInt16 nLastRight = getUInt16BE( pTmp ) + nFirstRight -1; 556cdf0e10cSrcweir 557cdf0e10cSrcweir // int nPairs = (int)(nLastLeft-nFirstLeft+1)*(int)(nLastRight-nFirstRight+1); 558cdf0e10cSrcweir for( aPair.first = nFirstLeft; aPair.first < nLastLeft; aPair.first++ ) 559cdf0e10cSrcweir { 560cdf0e10cSrcweir for( aPair.second = 0; aPair.second < nLastRight; aPair.second++ ) 561cdf0e10cSrcweir { 562cdf0e10cSrcweir sal_Int16 nKern = (sal_Int16)getUInt16BE( pTmp ); 563cdf0e10cSrcweir switch( nCoverage & 1 ) 564cdf0e10cSrcweir { 565cdf0e10cSrcweir case 1: 566cdf0e10cSrcweir aPair.kern_x = (int)nKern * 1000 / pImplTTFont->unitsPerEm; 567cdf0e10cSrcweir m_pMetrics->m_aXKernPairs.push_back( aPair ); 568cdf0e10cSrcweir break; 569cdf0e10cSrcweir case 0: 570cdf0e10cSrcweir aPair.kern_y = (int)nKern * 1000 / pImplTTFont->unitsPerEm; 571cdf0e10cSrcweir m_pMetrics->m_aYKernPairs.push_back( aPair ); 572cdf0e10cSrcweir break; 573cdf0e10cSrcweir } 574cdf0e10cSrcweir } 575cdf0e10cSrcweir } 576cdf0e10cSrcweir } 577cdf0e10cSrcweir break; 578cdf0e10cSrcweir } 579cdf0e10cSrcweir } 580cdf0e10cSrcweir } 581cdf0e10cSrcweir 582cdf0e10cSrcweir //----------------------------------------------------------------- 583cdf0e10cSrcweir // Kerning: KT_APPLE_NEW 584cdf0e10cSrcweir //----------------------------------------------------------------- 585cdf0e10cSrcweir if( pImplTTFont->nkern && pImplTTFont->kerntype == KT_APPLE_NEW ) 586cdf0e10cSrcweir { 587cdf0e10cSrcweir // create a glyph -> character mapping 588cdf0e10cSrcweir ::std::hash_map< sal_uInt16, sal_Unicode > aGlyphMap; 589cdf0e10cSrcweir ::std::hash_map< sal_uInt16, sal_Unicode >::iterator left, right; 590cdf0e10cSrcweir for( i = 21; i < 0xfffd; i++ ) 591cdf0e10cSrcweir { 592cdf0e10cSrcweir sal_uInt16 nGlyph = MapChar( pTTFont, (sal_Unicode)i, 0 ); // kerning for horz only 593cdf0e10cSrcweir if( nGlyph != 0 ) 594cdf0e10cSrcweir aGlyphMap[ nGlyph ] = (sal_Unicode)i; 595cdf0e10cSrcweir } 596cdf0e10cSrcweir 597cdf0e10cSrcweir // Loop through each of the 'kern' subtables 598cdf0e10cSrcweir KernPair aPair; 599cdf0e10cSrcweir for( i = 0; (unsigned int)i < pImplTTFont->nkern; i++ ) 600cdf0e10cSrcweir { 601cdf0e10cSrcweir const sal_uInt8* pTable = pImplTTFont->kerntables[i]; 602cdf0e10cSrcweir 603cdf0e10cSrcweir /*sal_uInt32 nLength =*/ getUInt32BE( pTable ); 604cdf0e10cSrcweir sal_uInt16 nCoverage = getUInt16BE( pTable ); 605cdf0e10cSrcweir /*sal_uInt16 nTupleIndex =*/ getUInt16BE( pTable ); 606cdf0e10cSrcweir 607cdf0e10cSrcweir // Get kerning type 608cdf0e10cSrcweir // sal_Bool bKernVertical = nCoverage & 0x8000; 609cdf0e10cSrcweir // sal_Bool bKernCrossStream = nCoverage & 0x4000; 610cdf0e10cSrcweir // sal_Bool bKernVariation = nCoverage & 0x2000; 611cdf0e10cSrcweir 612cdf0e10cSrcweir // Kerning sub-table format, 0 through 3 613cdf0e10cSrcweir sal_uInt8 nSubTableFormat = nCoverage & 0x00FF; 614cdf0e10cSrcweir 615cdf0e10cSrcweir aPair.kern_x = 0; 616cdf0e10cSrcweir aPair.kern_y = 0; 617cdf0e10cSrcweir switch( nSubTableFormat ) 618cdf0e10cSrcweir { 619cdf0e10cSrcweir case 0: 620cdf0e10cSrcweir { 621cdf0e10cSrcweir // Grab the # of kern pairs but skip over the: 622cdf0e10cSrcweir // searchRange 623cdf0e10cSrcweir // entrySelector 624cdf0e10cSrcweir // rangeShift 625cdf0e10cSrcweir sal_uInt16 nPairs = getUInt16BE( pTable ); 626cdf0e10cSrcweir pTable += 6; 627cdf0e10cSrcweir 628cdf0e10cSrcweir for( int n = 0; n < nPairs; n++ ) 629cdf0e10cSrcweir { 630cdf0e10cSrcweir sal_uInt16 nLeftGlyph = getUInt16BE( pTable ); 631cdf0e10cSrcweir sal_uInt16 nRightGlyph = getUInt16BE( pTable ); 632cdf0e10cSrcweir sal_Int16 nKern = (sal_Int16)getUInt16BE( pTable ); 633cdf0e10cSrcweir 634cdf0e10cSrcweir left = aGlyphMap.find( nLeftGlyph ); 635cdf0e10cSrcweir right = aGlyphMap.find( nRightGlyph ); 636cdf0e10cSrcweir if( left != aGlyphMap.end() && right != aGlyphMap.end() ) 637cdf0e10cSrcweir { 638cdf0e10cSrcweir aPair.first = left->second; 639cdf0e10cSrcweir aPair.second = right->second; 640cdf0e10cSrcweir 641cdf0e10cSrcweir // Only support horizontal kerning for now 642cdf0e10cSrcweir aPair.kern_x = (int)nKern * 1000 / pImplTTFont->unitsPerEm; 643cdf0e10cSrcweir aPair.kern_y = 0; 644cdf0e10cSrcweir m_pMetrics->m_aXKernPairs.push_back( aPair ); 645cdf0e10cSrcweir 646cdf0e10cSrcweir /* switch( nCoverage & 1 ) 647cdf0e10cSrcweir { 648cdf0e10cSrcweir case 1: 649cdf0e10cSrcweir aPair.kern_x = (int)nKern * 1000 / pImplTTFont->unitsPerEm; 650cdf0e10cSrcweir m_pMetrics->m_aXKernPairs.push_back( aPair ); 651cdf0e10cSrcweir break; 652cdf0e10cSrcweir case 0: 653cdf0e10cSrcweir aPair.kern_y = (int)nKern * 1000 / pImplTTFont->unitsPerEm; 654cdf0e10cSrcweir m_pMetrics->m_aYKernPairs.push_back( aPair ); 655cdf0e10cSrcweir break; 656cdf0e10cSrcweir } 657cdf0e10cSrcweir */ 658cdf0e10cSrcweir } 659cdf0e10cSrcweir } 660cdf0e10cSrcweir } 661cdf0e10cSrcweir break; 662cdf0e10cSrcweir 663cdf0e10cSrcweir case 2: 664cdf0e10cSrcweir { 665cdf0e10cSrcweir const sal_uInt8* pSubTable = pTable; 666cdf0e10cSrcweir /*sal_uInt16 nRowWidth =*/ getUInt16BE( pTable ); 667cdf0e10cSrcweir sal_uInt16 nOfLeft = getUInt16BE( pTable ); 668cdf0e10cSrcweir sal_uInt16 nOfRight = getUInt16BE( pTable ); 669cdf0e10cSrcweir /*sal_uInt16 nOfArray =*/ getUInt16BE( pTable ); 670cdf0e10cSrcweir const sal_uInt8* pTmp = pSubTable + nOfLeft; 671cdf0e10cSrcweir sal_uInt16 nFirstLeft = getUInt16BE( pTmp ); 672cdf0e10cSrcweir sal_uInt16 nLastLeft = getUInt16BE( pTmp ) + nFirstLeft - 1; 673cdf0e10cSrcweir pTmp = pSubTable + nOfRight; 674cdf0e10cSrcweir sal_uInt16 nFirstRight = getUInt16BE( pTmp ); 675cdf0e10cSrcweir sal_uInt16 nLastRight = getUInt16BE( pTmp ) + nFirstRight -1; 676cdf0e10cSrcweir 677cdf0e10cSrcweir for( aPair.first = nFirstLeft; aPair.first < nLastLeft; aPair.first++ ) 678cdf0e10cSrcweir { 679cdf0e10cSrcweir for( aPair.second = 0; aPair.second < nLastRight; aPair.second++ ) 680cdf0e10cSrcweir { 681cdf0e10cSrcweir sal_Int16 nKern = (sal_Int16)getUInt16BE( pTmp ); 682cdf0e10cSrcweir switch( nCoverage & 1 ) 683cdf0e10cSrcweir { 684cdf0e10cSrcweir case 1: 685cdf0e10cSrcweir aPair.kern_x = (int)nKern * 1000 / pImplTTFont->unitsPerEm; 686cdf0e10cSrcweir m_pMetrics->m_aXKernPairs.push_back( aPair ); 687cdf0e10cSrcweir break; 688cdf0e10cSrcweir case 0: 689cdf0e10cSrcweir aPair.kern_y = (int)nKern * 1000 / pImplTTFont->unitsPerEm; 690cdf0e10cSrcweir m_pMetrics->m_aYKernPairs.push_back( aPair ); 691cdf0e10cSrcweir break; 692cdf0e10cSrcweir } 693cdf0e10cSrcweir } 694cdf0e10cSrcweir } 695cdf0e10cSrcweir } 696cdf0e10cSrcweir break; 697cdf0e10cSrcweir 698cdf0e10cSrcweir default: 699cdf0e10cSrcweir fprintf( stderr, "Found unsupported Apple-style kern subtable type %d.\n", nSubTableFormat ); 700cdf0e10cSrcweir break; 701cdf0e10cSrcweir } 702cdf0e10cSrcweir } 703cdf0e10cSrcweir } 704cdf0e10cSrcweir 705cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 706cdf0e10cSrcweir fprintf( stderr, "found %d/%d kern pairs for %s\n", 707cdf0e10cSrcweir m_pMetrics->m_aXKernPairs.size(), 708cdf0e10cSrcweir m_pMetrics->m_aYKernPairs.size(), 709cdf0e10cSrcweir OUStringToOString( pProvider->getString( ATOM_FAMILYNAME, m_nFamilyName ), RTL_TEXTENCODING_MS_1252 ).getStr() ); 710cdf0e10cSrcweir #else 711cdf0e10cSrcweir (void) pProvider; /* avoid warnings */ 712cdf0e10cSrcweir #endif 713cdf0e10cSrcweir } 714cdf0e10cSrcweir 715cdf0e10cSrcweir CloseTTFont( pTTFont ); 716cdf0e10cSrcweir bSuccess = true; 717cdf0e10cSrcweir } 718cdf0e10cSrcweir return bSuccess; 719cdf0e10cSrcweir } 720cdf0e10cSrcweir 721cdf0e10cSrcweir // ------------------------------------------------------------------------- 722cdf0e10cSrcweir 723cdf0e10cSrcweir /* #i73387# There seem to be fonts with a rather unwell chosen family name 724cdf0e10cSrcweir * consider e.g. "Helvetica Narrow" which defines its family as "Helvetica" 725cdf0e10cSrcweir * It can really only be distinguished by its PSName and FullName. Both of 726cdf0e10cSrcweir * which are not user presentable in OOo. So replace it by something sensible. 727cdf0e10cSrcweir * 728cdf0e10cSrcweir * If other fonts feature this behaviour, insert them to the map. 729cdf0e10cSrcweir */ 730cdf0e10cSrcweir static bool familyNameOverride( const OUString& i_rPSname, OUString& o_rFamilyName ) 731cdf0e10cSrcweir { 732cdf0e10cSrcweir static std::hash_map< OUString, OUString, OUStringHash > aPSNameToFamily( 16 ); 733cdf0e10cSrcweir if( aPSNameToFamily.empty() ) // initialization 734cdf0e10cSrcweir { 735cdf0e10cSrcweir aPSNameToFamily[ OUString( RTL_CONSTASCII_USTRINGPARAM( "Helvetica-Narrow" ) ) ] = 736cdf0e10cSrcweir OUString( RTL_CONSTASCII_USTRINGPARAM( "Helvetica Narrow" ) ); 737cdf0e10cSrcweir aPSNameToFamily[ OUString( RTL_CONSTASCII_USTRINGPARAM( "Helvetica-Narrow-Bold" ) ) ] = 738cdf0e10cSrcweir OUString( RTL_CONSTASCII_USTRINGPARAM( "Helvetica Narrow" ) ); 739cdf0e10cSrcweir aPSNameToFamily[ OUString( RTL_CONSTASCII_USTRINGPARAM( "Helvetica-Narrow-BoldOblique" ) ) ] = 740cdf0e10cSrcweir OUString( RTL_CONSTASCII_USTRINGPARAM( "Helvetica Narrow" ) ); 741cdf0e10cSrcweir aPSNameToFamily[ OUString( RTL_CONSTASCII_USTRINGPARAM( "Helvetica-Narrow-Oblique" ) ) ] = 742cdf0e10cSrcweir OUString( RTL_CONSTASCII_USTRINGPARAM( "Helvetica Narrow" ) ); 743cdf0e10cSrcweir } 744cdf0e10cSrcweir std::hash_map<OUString,OUString,OUStringHash>::const_iterator it = 745cdf0e10cSrcweir aPSNameToFamily.find( i_rPSname ); 746cdf0e10cSrcweir bool bReplaced = (it != aPSNameToFamily.end() ); 747cdf0e10cSrcweir if( bReplaced ) 748cdf0e10cSrcweir o_rFamilyName = it->second; 749cdf0e10cSrcweir return bReplaced; 750cdf0e10cSrcweir }; 751cdf0e10cSrcweir 752cdf0e10cSrcweir bool PrintFontManager::PrintFont::readAfmMetrics( const OString& rFileName, MultiAtomProvider* pProvider, bool bFillEncodingvector, bool bOnlyGlobalAttributes ) 753cdf0e10cSrcweir { 754cdf0e10cSrcweir PrintFontManager& rManager( PrintFontManager::get() ); 755cdf0e10cSrcweir 756cdf0e10cSrcweir int i; 757cdf0e10cSrcweir FontInfo* pInfo = NULL; 758cdf0e10cSrcweir parseFile( rFileName.getStr(), &pInfo, P_ALL ); 759cdf0e10cSrcweir if( ! pInfo || ! pInfo->numOfChars ) 760cdf0e10cSrcweir { 761cdf0e10cSrcweir if( pInfo ) 762cdf0e10cSrcweir freeFontInfo( pInfo ); 763cdf0e10cSrcweir return false; 764cdf0e10cSrcweir } 765cdf0e10cSrcweir 766cdf0e10cSrcweir m_aEncodingVector.clear(); 767cdf0e10cSrcweir // fill in global info 768cdf0e10cSrcweir 769cdf0e10cSrcweir // PSName 770cdf0e10cSrcweir OUString aPSName( OStringToOUString( pInfo->gfi->fontName, RTL_TEXTENCODING_ISO_8859_1 ) ); 771cdf0e10cSrcweir m_nPSName = pProvider->getAtom( ATOM_PSNAME, aPSName, sal_True ); 772cdf0e10cSrcweir 773cdf0e10cSrcweir // family name (if not already set) 774cdf0e10cSrcweir OUString aFamily; 775cdf0e10cSrcweir if( ! m_nFamilyName ) 776cdf0e10cSrcweir { 777cdf0e10cSrcweir aFamily = OStringToOUString( pInfo->gfi->familyName, RTL_TEXTENCODING_ISO_8859_1 ); 778cdf0e10cSrcweir if( ! aFamily.getLength() ) 779cdf0e10cSrcweir { 780cdf0e10cSrcweir aFamily = OStringToOUString( pInfo->gfi->fontName, RTL_TEXTENCODING_ISO_8859_1 ); 781cdf0e10cSrcweir sal_Int32 nIndex = 0; 782cdf0e10cSrcweir aFamily = aFamily.getToken( 0, '-', nIndex ); 783cdf0e10cSrcweir } 784cdf0e10cSrcweir familyNameOverride( aPSName, aFamily ); 785cdf0e10cSrcweir m_nFamilyName = pProvider->getAtom( ATOM_FAMILYNAME, aFamily, sal_True ); 786cdf0e10cSrcweir } 787cdf0e10cSrcweir else 788cdf0e10cSrcweir aFamily = pProvider->getString( ATOM_FAMILYNAME, m_nFamilyName ); 789cdf0e10cSrcweir 790cdf0e10cSrcweir // style name: if fullname begins with family name 791cdf0e10cSrcweir // interpret the rest of fullname as style 792cdf0e10cSrcweir if( ! m_aStyleName.getLength() && pInfo->gfi->fullName && *pInfo->gfi->fullName ) 793cdf0e10cSrcweir { 794cdf0e10cSrcweir OUString aFullName( OStringToOUString( pInfo->gfi->fullName, RTL_TEXTENCODING_ISO_8859_1 ) ); 795cdf0e10cSrcweir if( aFullName.indexOf( aFamily ) == 0 ) 796cdf0e10cSrcweir m_aStyleName = WhitespaceToSpace( aFullName.copy( aFamily.getLength() ) ); 797cdf0e10cSrcweir } 798cdf0e10cSrcweir 799cdf0e10cSrcweir // italic 800cdf0e10cSrcweir if( pInfo->gfi->italicAngle > 0 ) 801cdf0e10cSrcweir m_eItalic = italic::Oblique; 802cdf0e10cSrcweir else if( pInfo->gfi->italicAngle < 0 ) 803cdf0e10cSrcweir m_eItalic = italic::Italic; 804cdf0e10cSrcweir else 805cdf0e10cSrcweir m_eItalic = italic::Upright; 806cdf0e10cSrcweir 807cdf0e10cSrcweir // weight 808cdf0e10cSrcweir ByteString aLowerWeight( pInfo->gfi->weight ); 809cdf0e10cSrcweir aLowerWeight.ToLowerAscii(); 810cdf0e10cSrcweir m_eWeight = parseWeight( aLowerWeight ); 811cdf0e10cSrcweir 812cdf0e10cSrcweir // pitch 813cdf0e10cSrcweir m_ePitch = pInfo->gfi->isFixedPitch ? pitch::Fixed : pitch::Variable; 814cdf0e10cSrcweir 815cdf0e10cSrcweir // encoding - only set if unknown 816cdf0e10cSrcweir int nAdobeEncoding = 0; 817cdf0e10cSrcweir if( pInfo->gfi->encodingScheme ) 818cdf0e10cSrcweir { 819cdf0e10cSrcweir if( !strcmp( pInfo->gfi->encodingScheme, "AdobeStandardEncoding" ) ) 820cdf0e10cSrcweir nAdobeEncoding = 1; 821cdf0e10cSrcweir else if( !strcmp( pInfo->gfi->encodingScheme, "ISO10646-1" ) ) 822cdf0e10cSrcweir { 823cdf0e10cSrcweir nAdobeEncoding = 1; 824cdf0e10cSrcweir m_aEncoding = RTL_TEXTENCODING_UNICODE; 825cdf0e10cSrcweir } 826cdf0e10cSrcweir else if( !strcmp( pInfo->gfi->encodingScheme, "Symbol") ) 827cdf0e10cSrcweir nAdobeEncoding = 2; 828cdf0e10cSrcweir else if( !strcmp( pInfo->gfi->encodingScheme, "FontSpecific") ) 829cdf0e10cSrcweir nAdobeEncoding = 3; 830cdf0e10cSrcweir 831cdf0e10cSrcweir if( m_aEncoding == RTL_TEXTENCODING_DONTKNOW ) 832cdf0e10cSrcweir m_aEncoding = nAdobeEncoding == 1 ? 833cdf0e10cSrcweir RTL_TEXTENCODING_ADOBE_STANDARD : RTL_TEXTENCODING_SYMBOL; 834cdf0e10cSrcweir } 835cdf0e10cSrcweir else if( m_aEncoding == RTL_TEXTENCODING_DONTKNOW ) 836cdf0e10cSrcweir m_aEncoding = RTL_TEXTENCODING_ADOBE_STANDARD; 837cdf0e10cSrcweir 838cdf0e10cSrcweir // try to parse the font name and decide wether it might be a 839cdf0e10cSrcweir // japanese font. Who invented this PITA ? 840cdf0e10cSrcweir OUString aPSNameLastToken( aPSName.copy( aPSName.lastIndexOf( '-' )+1 ) ); 841cdf0e10cSrcweir if( ! aPSNameLastToken.compareToAscii( "H" ) || 842cdf0e10cSrcweir ! aPSNameLastToken.compareToAscii( "V" ) ) 843cdf0e10cSrcweir { 844cdf0e10cSrcweir static const char* pEncs[] = 845cdf0e10cSrcweir { 846cdf0e10cSrcweir "EUC", 847cdf0e10cSrcweir "RKSJ", 848cdf0e10cSrcweir "SJ" 849cdf0e10cSrcweir }; 850cdf0e10cSrcweir static const rtl_TextEncoding aEncs[] = 851cdf0e10cSrcweir { 852cdf0e10cSrcweir RTL_TEXTENCODING_EUC_JP, 853cdf0e10cSrcweir RTL_TEXTENCODING_SHIFT_JIS, 854cdf0e10cSrcweir RTL_TEXTENCODING_JIS_X_0208 855cdf0e10cSrcweir }; 856cdf0e10cSrcweir 857cdf0e10cSrcweir for( unsigned int enc = 0; enc < sizeof( aEncs )/sizeof(aEncs[0]) && m_aEncoding == RTL_TEXTENCODING_DONTKNOW; enc++ ) 858cdf0e10cSrcweir { 859cdf0e10cSrcweir sal_Int32 nIndex = 0, nOffset = 1; 860cdf0e10cSrcweir do 861cdf0e10cSrcweir { 862cdf0e10cSrcweir OUString aToken( aPSName.getToken( nOffset, '-', nIndex ) ); 863cdf0e10cSrcweir if( nIndex == -1 ) 864cdf0e10cSrcweir break; 865cdf0e10cSrcweir nOffset = 0; 866cdf0e10cSrcweir if( ! aToken.compareToAscii( pEncs[enc] ) ) 867cdf0e10cSrcweir { 868cdf0e10cSrcweir m_aEncoding = aEncs[ enc ]; 869cdf0e10cSrcweir m_bFontEncodingOnly = true; 870cdf0e10cSrcweir } 871cdf0e10cSrcweir } while( nIndex != -1 ); 872cdf0e10cSrcweir } 873cdf0e10cSrcweir 874cdf0e10cSrcweir // default is jis 875cdf0e10cSrcweir if( m_aEncoding == RTL_TEXTENCODING_DONTKNOW ) 876cdf0e10cSrcweir m_aEncoding = RTL_TEXTENCODING_JIS_X_0208; 877cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 878cdf0e10cSrcweir fprintf( stderr, "Encoding %d for %s\n", m_aEncoding, pInfo->gfi->fontName ); 879cdf0e10cSrcweir #endif 880cdf0e10cSrcweir } 881cdf0e10cSrcweir 882cdf0e10cSrcweir // hack for GB encoded builtin fonts posing as FontSpecific 883cdf0e10cSrcweir if( m_eType == fonttype::Builtin && ( nAdobeEncoding == 3 || nAdobeEncoding == 0 ) ) 884cdf0e10cSrcweir { 885cdf0e10cSrcweir int nLen = aFamily.getLength(); 886cdf0e10cSrcweir if( nLen > 2 && 887cdf0e10cSrcweir aFamily.getStr()[ nLen-2 ] == 'G' && 888cdf0e10cSrcweir aFamily.getStr()[ nLen-1 ] == 'B' && 889cdf0e10cSrcweir pInfo->numOfChars > 255 ) 890cdf0e10cSrcweir { 891cdf0e10cSrcweir m_aEncoding = RTL_TEXTENCODING_GBK; 892cdf0e10cSrcweir m_bFontEncodingOnly = true; 893cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 894cdf0e10cSrcweir fprintf( stderr, "found builtin font %s with GBK encoding\n", pInfo->gfi->fontName ); 895cdf0e10cSrcweir #endif 896cdf0e10cSrcweir } 897cdf0e10cSrcweir } 898cdf0e10cSrcweir 899cdf0e10cSrcweir // #i37313# check if Fontspecific is not rather some character encoding 900cdf0e10cSrcweir if( nAdobeEncoding == 3 && m_aEncoding == RTL_TEXTENCODING_SYMBOL ) 901cdf0e10cSrcweir { 902cdf0e10cSrcweir bool bYFound = false; 903cdf0e10cSrcweir bool bQFound = false; 904cdf0e10cSrcweir CharMetricInfo* pChar = pInfo->cmi; 905cdf0e10cSrcweir for( int j = 0; j < pInfo->numOfChars && ! (bYFound && bQFound); j++ ) 906cdf0e10cSrcweir { 907cdf0e10cSrcweir if( pChar[j].name ) 908cdf0e10cSrcweir { 909cdf0e10cSrcweir if( pChar[j].name[0] == 'Y' && pChar[j].name[1] == 0 ) 910cdf0e10cSrcweir bYFound = true; 911cdf0e10cSrcweir else if( pChar[j].name[0] == 'Q' && pChar[j].name[1] == 0 ) 912cdf0e10cSrcweir bQFound = true; 913cdf0e10cSrcweir } 914cdf0e10cSrcweir } 915cdf0e10cSrcweir if( bQFound && bYFound ) 916cdf0e10cSrcweir { 917cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 918cdf0e10cSrcweir fprintf( stderr, "setting FontSpecific font %s (file %s) to unicode\n", 919cdf0e10cSrcweir pInfo->gfi->fontName, 920cdf0e10cSrcweir rFileName.getStr() 921cdf0e10cSrcweir ); 922cdf0e10cSrcweir #endif 923cdf0e10cSrcweir nAdobeEncoding = 4; 924cdf0e10cSrcweir m_aEncoding = RTL_TEXTENCODING_UNICODE; 925cdf0e10cSrcweir bFillEncodingvector = false; // will be filled anyway, don't do the work twice 926cdf0e10cSrcweir } 927cdf0e10cSrcweir } 928cdf0e10cSrcweir 929cdf0e10cSrcweir // ascend 930cdf0e10cSrcweir m_nAscend = pInfo->gfi->fontBBox.ury; 931cdf0e10cSrcweir 932cdf0e10cSrcweir // descend 933cdf0e10cSrcweir // descends have opposite sign of our definition 934cdf0e10cSrcweir m_nDescend = -pInfo->gfi->fontBBox.lly; 935cdf0e10cSrcweir 936cdf0e10cSrcweir // fallback to ascender, descender 937cdf0e10cSrcweir // interesting: the BBox seems to describe Ascender and Descender better 938cdf0e10cSrcweir // as we understand it 939cdf0e10cSrcweir if( m_nAscend == 0 ) 940cdf0e10cSrcweir m_nAscend = pInfo->gfi->ascender; 941cdf0e10cSrcweir if( m_nDescend == 0) 942cdf0e10cSrcweir m_nDescend = -pInfo->gfi->descender; 943cdf0e10cSrcweir 944cdf0e10cSrcweir m_nLeading = m_nAscend + m_nDescend - 1000; 945cdf0e10cSrcweir 946cdf0e10cSrcweir if( m_pMetrics ) 947cdf0e10cSrcweir delete m_pMetrics; 948cdf0e10cSrcweir m_pMetrics = new PrintFontMetrics; 949cdf0e10cSrcweir // mark all pages as queried (or clear if only global font info queiried) 950cdf0e10cSrcweir memset( m_pMetrics->m_aPages, bOnlyGlobalAttributes ? 0 : 0xff, sizeof( m_pMetrics->m_aPages ) ); 951cdf0e10cSrcweir 952cdf0e10cSrcweir m_aGlobalMetricX.width = m_aGlobalMetricY.width = 953cdf0e10cSrcweir pInfo->gfi->charwidth ? pInfo->gfi->charwidth : pInfo->gfi->fontBBox.urx; 954cdf0e10cSrcweir m_aGlobalMetricX.height = m_aGlobalMetricY.height = 955cdf0e10cSrcweir pInfo->gfi->capHeight ? pInfo->gfi->capHeight : pInfo->gfi->fontBBox.ury; 956cdf0e10cSrcweir 957cdf0e10cSrcweir m_nXMin = pInfo->gfi->fontBBox.llx; 958cdf0e10cSrcweir m_nYMin = pInfo->gfi->fontBBox.lly; 959cdf0e10cSrcweir m_nXMax = pInfo->gfi->fontBBox.urx; 960cdf0e10cSrcweir m_nYMax = pInfo->gfi->fontBBox.ury; 961cdf0e10cSrcweir 962cdf0e10cSrcweir if( bFillEncodingvector || !bOnlyGlobalAttributes ) 963cdf0e10cSrcweir { 964cdf0e10cSrcweir // fill in character metrics 965cdf0e10cSrcweir 966cdf0e10cSrcweir // first transform the character codes to unicode 967cdf0e10cSrcweir // note: this only works with single byte encodings 968cdf0e10cSrcweir sal_Unicode* pUnicodes = (sal_Unicode*)alloca( pInfo->numOfChars * sizeof(sal_Unicode)); 969cdf0e10cSrcweir CharMetricInfo* pChar = pInfo->cmi; 970cdf0e10cSrcweir 971cdf0e10cSrcweir for( i = 0; i < pInfo->numOfChars; i++, pChar++ ) 972cdf0e10cSrcweir { 973cdf0e10cSrcweir if( nAdobeEncoding == 4 ) 974cdf0e10cSrcweir { 975cdf0e10cSrcweir if( pChar->name ) 976cdf0e10cSrcweir { 977cdf0e10cSrcweir pUnicodes[i] = 0; 978cdf0e10cSrcweir std::list< sal_Unicode > aCodes = rManager.getUnicodeFromAdobeName( pChar->name ); 979cdf0e10cSrcweir for( std::list< sal_Unicode >::const_iterator it = aCodes.begin(); it != aCodes.end(); ++it ) 980cdf0e10cSrcweir { 981cdf0e10cSrcweir if( *it != 0 ) 982cdf0e10cSrcweir { 983cdf0e10cSrcweir m_aEncodingVector[ *it ] = pChar->code; 984cdf0e10cSrcweir if( pChar->code == -1 ) 985cdf0e10cSrcweir m_aNonEncoded[ *it ] = pChar->name; 986cdf0e10cSrcweir if( ! pUnicodes[i] ) // map the first 987cdf0e10cSrcweir pUnicodes[i] = *it; 988cdf0e10cSrcweir } 989cdf0e10cSrcweir } 990cdf0e10cSrcweir } 991cdf0e10cSrcweir } 992cdf0e10cSrcweir else if( pChar->code != -1 ) 993cdf0e10cSrcweir { 994cdf0e10cSrcweir if( nAdobeEncoding == 3 && m_aEncoding == RTL_TEXTENCODING_SYMBOL ) 995cdf0e10cSrcweir { 996cdf0e10cSrcweir pUnicodes[i] = pChar->code + 0xf000; 997cdf0e10cSrcweir if( bFillEncodingvector ) 998cdf0e10cSrcweir m_aEncodingVector[ pUnicodes[i] ] = pChar->code; 999cdf0e10cSrcweir continue; 1000cdf0e10cSrcweir } 1001cdf0e10cSrcweir 1002cdf0e10cSrcweir if( m_aEncoding == RTL_TEXTENCODING_UNICODE ) 1003cdf0e10cSrcweir { 1004cdf0e10cSrcweir pUnicodes[i] = (sal_Unicode)pChar->code; 1005cdf0e10cSrcweir continue; 1006cdf0e10cSrcweir } 1007cdf0e10cSrcweir 1008cdf0e10cSrcweir ByteString aTranslate; 1009cdf0e10cSrcweir if( pChar->code & 0xff000000 ) 1010cdf0e10cSrcweir aTranslate += (char)(pChar->code >> 24 ); 1011cdf0e10cSrcweir if( pChar->code & 0xffff0000 ) 1012cdf0e10cSrcweir aTranslate += (char)((pChar->code & 0x00ff0000) >> 16 ); 1013cdf0e10cSrcweir if( pChar->code & 0xffffff00 ) 1014cdf0e10cSrcweir aTranslate += (char)((pChar->code & 0x0000ff00) >> 8 ); 1015cdf0e10cSrcweir aTranslate += (char)(pChar->code & 0xff); 1016cdf0e10cSrcweir String aUni( aTranslate, m_aEncoding ); 1017cdf0e10cSrcweir pUnicodes[i] = *aUni.GetBuffer(); 1018cdf0e10cSrcweir } 1019cdf0e10cSrcweir else 1020cdf0e10cSrcweir pUnicodes[i] = 0; 1021cdf0e10cSrcweir } 1022cdf0e10cSrcweir 1023cdf0e10cSrcweir // now fill in the character metrics 1024cdf0e10cSrcweir // parseAFM.cxx effectively only supports direction 0 (horizontal) 1025cdf0e10cSrcweir pChar = pInfo->cmi; 1026cdf0e10cSrcweir CharacterMetric aMetric; 1027cdf0e10cSrcweir for( i = 0; i < pInfo->numOfChars; i++, pChar++ ) 1028cdf0e10cSrcweir { 1029cdf0e10cSrcweir if( pChar->code == -1 && ! pChar->name ) 1030cdf0e10cSrcweir continue; 1031cdf0e10cSrcweir 1032cdf0e10cSrcweir if( bFillEncodingvector && pChar->name ) 1033cdf0e10cSrcweir { 1034cdf0e10cSrcweir std::list< sal_Unicode > aCodes = rManager.getUnicodeFromAdobeName( pChar->name ); 1035cdf0e10cSrcweir for( std::list< sal_Unicode >::const_iterator it = aCodes.begin(); it != aCodes.end(); ++it ) 1036cdf0e10cSrcweir { 1037cdf0e10cSrcweir if( *it != 0 ) 1038cdf0e10cSrcweir { 1039cdf0e10cSrcweir m_aEncodingVector[ *it ] = pChar->code; 1040cdf0e10cSrcweir if( pChar->code == -1 ) 1041cdf0e10cSrcweir m_aNonEncoded[ *it ] = pChar->name; 1042cdf0e10cSrcweir } 1043cdf0e10cSrcweir } 1044cdf0e10cSrcweir } 1045cdf0e10cSrcweir 1046cdf0e10cSrcweir aMetric.width = pChar->wx ? pChar->wx : pChar->charBBox.urx; 1047cdf0e10cSrcweir aMetric.height = pChar->wy ? pChar->wy : pChar->charBBox.ury - pChar->charBBox.lly; 1048cdf0e10cSrcweir if( aMetric.width == 0 && aMetric.height == 0 ) 1049cdf0e10cSrcweir // guess something for e.g. space 1050cdf0e10cSrcweir aMetric.width = m_aGlobalMetricX.width/4; 1051cdf0e10cSrcweir 1052cdf0e10cSrcweir if( ( nAdobeEncoding == 0 ) || 1053cdf0e10cSrcweir ( ( nAdobeEncoding == 3 ) && ( m_aEncoding != RTL_TEXTENCODING_SYMBOL ) ) ) 1054cdf0e10cSrcweir { 1055cdf0e10cSrcweir if( pChar->code != -1 ) 1056cdf0e10cSrcweir { 1057cdf0e10cSrcweir m_pMetrics->m_aMetrics[ pUnicodes[i] ] = aMetric; 1058cdf0e10cSrcweir if( bFillEncodingvector ) 1059cdf0e10cSrcweir m_aEncodingVector[ pUnicodes[i] ] = pChar->code; 1060cdf0e10cSrcweir } 1061cdf0e10cSrcweir else if( pChar->name ) 1062cdf0e10cSrcweir { 1063cdf0e10cSrcweir std::list< sal_Unicode > aCodes = rManager.getUnicodeFromAdobeName( pChar->name ); 1064cdf0e10cSrcweir for( std::list< sal_Unicode >::const_iterator it = aCodes.begin(); it != aCodes.end(); ++it ) 1065cdf0e10cSrcweir { 1066cdf0e10cSrcweir if( *it != 0 ) 1067cdf0e10cSrcweir m_pMetrics->m_aMetrics[ *it ] = aMetric; 1068cdf0e10cSrcweir } 1069cdf0e10cSrcweir } 1070cdf0e10cSrcweir } 1071cdf0e10cSrcweir else if( nAdobeEncoding == 1 || nAdobeEncoding == 2 || nAdobeEncoding == 4) 1072cdf0e10cSrcweir { 1073cdf0e10cSrcweir if( pChar->name ) 1074cdf0e10cSrcweir { 1075cdf0e10cSrcweir std::list< sal_Unicode > aCodes = rManager.getUnicodeFromAdobeName( pChar->name ); 1076cdf0e10cSrcweir for( std::list< sal_Unicode >::const_iterator it = aCodes.begin(); it != aCodes.end(); ++it ) 1077cdf0e10cSrcweir { 1078cdf0e10cSrcweir if( *it != 0 ) 1079cdf0e10cSrcweir m_pMetrics->m_aMetrics[ *it ] = aMetric; 1080cdf0e10cSrcweir } 1081cdf0e10cSrcweir } 1082cdf0e10cSrcweir else if( pChar->code != -1 ) 1083cdf0e10cSrcweir { 1084cdf0e10cSrcweir ::std::pair< ::std::hash_multimap< sal_uInt8, sal_Unicode >::const_iterator, 1085cdf0e10cSrcweir ::std::hash_multimap< sal_uInt8, sal_Unicode >::const_iterator > 1086cdf0e10cSrcweir aCodes = rManager.getUnicodeFromAdobeCode( pChar->code ); 1087cdf0e10cSrcweir while( aCodes.first != aCodes.second ) 1088cdf0e10cSrcweir { 1089cdf0e10cSrcweir if( (*aCodes.first).second != 0 ) 1090cdf0e10cSrcweir { 1091cdf0e10cSrcweir m_pMetrics->m_aMetrics[ (*aCodes.first).second ] = aMetric; 1092cdf0e10cSrcweir if( bFillEncodingvector ) 1093cdf0e10cSrcweir m_aEncodingVector[ (*aCodes.first).second ] = pChar->code; 1094cdf0e10cSrcweir } 1095cdf0e10cSrcweir ++aCodes.first; 1096cdf0e10cSrcweir } 1097cdf0e10cSrcweir } 1098cdf0e10cSrcweir } 1099cdf0e10cSrcweir else if( nAdobeEncoding == 3 ) 1100cdf0e10cSrcweir { 1101cdf0e10cSrcweir if( pChar->code != -1 ) 1102cdf0e10cSrcweir { 1103cdf0e10cSrcweir sal_Unicode code = 0xf000 + pChar->code; 1104cdf0e10cSrcweir m_pMetrics->m_aMetrics[ code ] = aMetric; 1105cdf0e10cSrcweir // maybe should try to find the name in the convtabs ? 1106cdf0e10cSrcweir if( bFillEncodingvector ) 1107cdf0e10cSrcweir m_aEncodingVector[ code ] = pChar->code; 1108cdf0e10cSrcweir } 1109cdf0e10cSrcweir } 1110cdf0e10cSrcweir } 1111cdf0e10cSrcweir 1112cdf0e10cSrcweir m_pMetrics->m_aXKernPairs.clear(); 1113cdf0e10cSrcweir m_pMetrics->m_aYKernPairs.clear(); 1114cdf0e10cSrcweir 1115cdf0e10cSrcweir // now fill in the kern pairs 1116cdf0e10cSrcweir // parseAFM.cxx effectively only supports direction 0 (horizontal) 1117cdf0e10cSrcweir PairKernData* pKern = pInfo->pkd; 1118cdf0e10cSrcweir KernPair aPair; 1119cdf0e10cSrcweir for( i = 0; i < pInfo->numOfPairs; i++, pKern++ ) 1120cdf0e10cSrcweir { 1121cdf0e10cSrcweir // #i37703# broken kern table 1122cdf0e10cSrcweir if( ! pKern->name1 || ! pKern->name2 ) 1123cdf0e10cSrcweir continue; 1124cdf0e10cSrcweir 1125cdf0e10cSrcweir aPair.first = 0; 1126cdf0e10cSrcweir aPair.second = 0; 1127cdf0e10cSrcweir // currently we have to find the adobe character names 1128cdf0e10cSrcweir // in the already parsed character metrics to find 1129cdf0e10cSrcweir // the corresponding UCS2 code which is a bit dangerous 1130cdf0e10cSrcweir // since the character names are not required 1131cdf0e10cSrcweir // in the metric descriptions 1132cdf0e10cSrcweir pChar = pInfo->cmi; 1133cdf0e10cSrcweir for( int j = 0; 1134cdf0e10cSrcweir j < pInfo->numOfChars && ( aPair.first == 0 || aPair.second == 0 ); 1135cdf0e10cSrcweir j++, pChar++ ) 1136cdf0e10cSrcweir { 1137cdf0e10cSrcweir if( pChar->code != -1 ) 1138cdf0e10cSrcweir { 1139cdf0e10cSrcweir if( ! strcmp( pKern->name1, pChar->name ? pChar->name : "" ) ) 1140cdf0e10cSrcweir aPair.first = pUnicodes[ j ]; 1141cdf0e10cSrcweir if( ! strcmp( pKern->name2, pChar->name ? pChar->name : "" ) ) 1142cdf0e10cSrcweir aPair.second = pUnicodes[ j ]; 1143cdf0e10cSrcweir } 1144cdf0e10cSrcweir } 1145cdf0e10cSrcweir if( aPair.first && aPair.second ) 1146cdf0e10cSrcweir { 1147cdf0e10cSrcweir aPair.kern_x = pKern->xamt; 1148cdf0e10cSrcweir aPair.kern_y = pKern->yamt; 1149cdf0e10cSrcweir m_pMetrics->m_aXKernPairs.push_back( aPair ); 1150cdf0e10cSrcweir } 1151cdf0e10cSrcweir } 1152cdf0e10cSrcweir m_pMetrics->m_bKernPairsQueried = true; 1153cdf0e10cSrcweir } 1154cdf0e10cSrcweir 1155cdf0e10cSrcweir freeFontInfo( pInfo ); 1156cdf0e10cSrcweir return true; 1157cdf0e10cSrcweir } 1158cdf0e10cSrcweir 1159cdf0e10cSrcweir // ------------------------------------------------------------------------- 1160cdf0e10cSrcweir 1161cdf0e10cSrcweir OString PrintFontManager::s_aEmptyOString; 1162cdf0e10cSrcweir 1163cdf0e10cSrcweir /* 1164cdf0e10cSrcweir * one instance only 1165cdf0e10cSrcweir */ 1166cdf0e10cSrcweir PrintFontManager& PrintFontManager::get() 1167cdf0e10cSrcweir { 1168cdf0e10cSrcweir static PrintFontManager* theManager = NULL; 1169cdf0e10cSrcweir if( ! theManager ) 1170cdf0e10cSrcweir { 1171cdf0e10cSrcweir theManager = new PrintFontManager(); 1172cdf0e10cSrcweir theManager->initialize(); 1173cdf0e10cSrcweir } 1174cdf0e10cSrcweir return *theManager; 1175cdf0e10cSrcweir } 1176cdf0e10cSrcweir 1177cdf0e10cSrcweir // ------------------------------------------------------------------------- 1178cdf0e10cSrcweir 1179cdf0e10cSrcweir /* 1180cdf0e10cSrcweir * the PrintFontManager 1181cdf0e10cSrcweir */ 1182cdf0e10cSrcweir 1183cdf0e10cSrcweir PrintFontManager::PrintFontManager() : 1184cdf0e10cSrcweir m_nNextFontID( 1 ), 1185cdf0e10cSrcweir m_pAtoms( new MultiAtomProvider() ), 1186cdf0e10cSrcweir m_nNextDirAtom( 1 ), 1187cdf0e10cSrcweir m_pFontCache( NULL ), 1188cdf0e10cSrcweir m_bFontconfigSuccess( false ) 1189cdf0e10cSrcweir { 1190cdf0e10cSrcweir for( unsigned int i = 0; i < sizeof( aAdobeCodes )/sizeof( aAdobeCodes[0] ); i++ ) 1191cdf0e10cSrcweir { 1192cdf0e10cSrcweir m_aUnicodeToAdobename.insert( ::std::hash_multimap< sal_Unicode, ::rtl::OString >::value_type( aAdobeCodes[i].aUnicode, aAdobeCodes[i].pAdobename ) ); 1193cdf0e10cSrcweir m_aAdobenameToUnicode.insert( ::std::hash_multimap< ::rtl::OString, sal_Unicode, ::rtl::OStringHash >::value_type( aAdobeCodes[i].pAdobename, aAdobeCodes[i].aUnicode ) ); 1194cdf0e10cSrcweir if( aAdobeCodes[i].aAdobeStandardCode ) 1195cdf0e10cSrcweir { 1196cdf0e10cSrcweir m_aUnicodeToAdobecode.insert( ::std::hash_multimap< sal_Unicode, sal_uInt8 >::value_type( aAdobeCodes[i].aUnicode, aAdobeCodes[i].aAdobeStandardCode ) ); 1197cdf0e10cSrcweir m_aAdobecodeToUnicode.insert( ::std::hash_multimap< sal_uInt8, sal_Unicode >::value_type( aAdobeCodes[i].aAdobeStandardCode, aAdobeCodes[i].aUnicode ) ); 1198cdf0e10cSrcweir } 1199cdf0e10cSrcweir #if 0 1200cdf0e10cSrcweir m_aUnicodeToAdobename[ aAdobeCodes[i].aUnicode ] = aAdobeCodes[i].pAdobename; 1201cdf0e10cSrcweir m_aAdobenameToUnicode[ aAdobeCodes[i].pAdobename ] = aAdobeCodes[i].aUnicode; 1202cdf0e10cSrcweir if( aAdobeCodes[i].aAdobeStandardCode ) 1203cdf0e10cSrcweir { 1204cdf0e10cSrcweir m_aUnicodeToAdobecode[ aAdobeCodes[i].aUnicode ] = aAdobeCodes[i].aAdobeStandardCode; 1205cdf0e10cSrcweir m_aAdobecodeToUnicode[ aAdobeCodes[i].aAdobeStandardCode ] = aAdobeCodes[i].aUnicode; 1206cdf0e10cSrcweir } 1207cdf0e10cSrcweir #endif 1208cdf0e10cSrcweir } 1209cdf0e10cSrcweir } 1210cdf0e10cSrcweir 1211cdf0e10cSrcweir // ------------------------------------------------------------------------- 1212cdf0e10cSrcweir 1213cdf0e10cSrcweir PrintFontManager::~PrintFontManager() 1214cdf0e10cSrcweir { 1215cdf0e10cSrcweir deinitFontconfig(); 1216cdf0e10cSrcweir for( ::std::hash_map< fontID, PrintFont* >::const_iterator it = m_aFonts.begin(); it != m_aFonts.end(); ++it ) 1217cdf0e10cSrcweir delete (*it).second; 1218cdf0e10cSrcweir delete m_pAtoms; 1219cdf0e10cSrcweir if( m_pFontCache ) 1220cdf0e10cSrcweir delete m_pFontCache; 1221cdf0e10cSrcweir } 1222cdf0e10cSrcweir 1223cdf0e10cSrcweir // ------------------------------------------------------------------------- 1224cdf0e10cSrcweir 1225cdf0e10cSrcweir const OString& PrintFontManager::getDirectory( int nAtom ) const 1226cdf0e10cSrcweir { 1227cdf0e10cSrcweir ::std::hash_map< int, OString >::const_iterator it( m_aAtomToDir.find( nAtom ) ); 1228cdf0e10cSrcweir return it != m_aAtomToDir.end() ? it->second : s_aEmptyOString; 1229cdf0e10cSrcweir } 1230cdf0e10cSrcweir 1231cdf0e10cSrcweir // ------------------------------------------------------------------------- 1232cdf0e10cSrcweir 1233cdf0e10cSrcweir int PrintFontManager::getDirectoryAtom( const OString& rDirectory, bool bCreate ) 1234cdf0e10cSrcweir { 1235cdf0e10cSrcweir int nAtom = 0; 1236cdf0e10cSrcweir ::std::hash_map< OString, int, OStringHash >::const_iterator it 1237cdf0e10cSrcweir ( m_aDirToAtom.find( rDirectory ) ); 1238cdf0e10cSrcweir if( it != m_aDirToAtom.end() ) 1239cdf0e10cSrcweir nAtom = it->second; 1240cdf0e10cSrcweir else if( bCreate ) 1241cdf0e10cSrcweir { 1242cdf0e10cSrcweir nAtom = m_nNextDirAtom++; 1243cdf0e10cSrcweir m_aDirToAtom[ rDirectory ] = nAtom; 1244cdf0e10cSrcweir m_aAtomToDir[ nAtom ] = rDirectory; 1245cdf0e10cSrcweir } 1246cdf0e10cSrcweir return nAtom; 1247cdf0e10cSrcweir } 1248cdf0e10cSrcweir 1249cdf0e10cSrcweir // ------------------------------------------------------------------------- 1250cdf0e10cSrcweir 1251cdf0e10cSrcweir int PrintFontManager::addFontFile( const ::rtl::OString& rFileName, int /*nFaceNum*/ ) 1252cdf0e10cSrcweir { 1253cdf0e10cSrcweir rtl_TextEncoding aEncoding = osl_getThreadTextEncoding(); 1254cdf0e10cSrcweir INetURLObject aPath( OStringToOUString( rFileName, aEncoding ), INET_PROT_FILE, INetURLObject::ENCODE_ALL ); 1255cdf0e10cSrcweir OString aName( OUStringToOString( aPath.GetName(), aEncoding ) ); 1256cdf0e10cSrcweir OString aDir( OUStringToOString( aPath.GetPath(), aEncoding ) ); 1257cdf0e10cSrcweir 1258cdf0e10cSrcweir int nDirID = getDirectoryAtom( aDir, true ); 1259cdf0e10cSrcweir fontID nFontId = findFontFileID( nDirID, aName ); 1260cdf0e10cSrcweir if( !nFontId ) 1261cdf0e10cSrcweir { 1262cdf0e10cSrcweir ::std::list< PrintFont* > aNewFonts; 1263cdf0e10cSrcweir if( analyzeFontFile( nDirID, aName, ::std::list<OString>(), aNewFonts ) ) 1264cdf0e10cSrcweir { 1265cdf0e10cSrcweir for( ::std::list< PrintFont* >::iterator it = aNewFonts.begin(); 1266cdf0e10cSrcweir it != aNewFonts.end(); ++it ) 1267cdf0e10cSrcweir { 1268cdf0e10cSrcweir m_aFonts[ nFontId = m_nNextFontID++ ] = *it; 1269cdf0e10cSrcweir m_aFontFileToFontID[ aName ].insert( nFontId ); 1270cdf0e10cSrcweir m_pFontCache->updateFontCacheEntry( *it, true ); 1271cdf0e10cSrcweir } 1272cdf0e10cSrcweir } 1273cdf0e10cSrcweir } 1274cdf0e10cSrcweir return nFontId; 1275cdf0e10cSrcweir } 1276cdf0e10cSrcweir 1277cdf0e10cSrcweir // ------------------------------------------------------------------------- 1278cdf0e10cSrcweir 1279cdf0e10cSrcweir bool PrintFontManager::analyzeFontFile( int nDirID, const OString& rFontFile, const ::std::list<OString>& rXLFDs, ::std::list< PrintFontManager::PrintFont* >& rNewFonts ) const 1280cdf0e10cSrcweir { 1281cdf0e10cSrcweir rNewFonts.clear(); 1282cdf0e10cSrcweir 1283cdf0e10cSrcweir OString aDir( getDirectory( nDirID ) ); 1284cdf0e10cSrcweir 1285cdf0e10cSrcweir OString aFullPath( aDir ); 1286cdf0e10cSrcweir aFullPath += "/"; 1287cdf0e10cSrcweir aFullPath += rFontFile; 1288cdf0e10cSrcweir 1289cdf0e10cSrcweir // #i1872# reject unreadable files 1290cdf0e10cSrcweir if( access( aFullPath.getStr(), R_OK ) ) 1291cdf0e10cSrcweir return false; 1292cdf0e10cSrcweir 1293cdf0e10cSrcweir ByteString aExt( rFontFile.copy( rFontFile.lastIndexOf( '.' )+1 ) ); 1294cdf0e10cSrcweir if( aExt.EqualsIgnoreCaseAscii( "pfb" ) || aExt.EqualsIgnoreCaseAscii( "pfa" ) ) 1295cdf0e10cSrcweir { 1296cdf0e10cSrcweir // check for corresponding afm metric 1297cdf0e10cSrcweir // first look for an adjacent file 1298cdf0e10cSrcweir static const char* pSuffix[] = { ".afm", ".AFM" }; 1299cdf0e10cSrcweir 1300cdf0e10cSrcweir for( unsigned int i = 0; i < sizeof(pSuffix)/sizeof(pSuffix[0]); i++ ) 1301cdf0e10cSrcweir { 1302cdf0e10cSrcweir ByteString aName( rFontFile ); 1303cdf0e10cSrcweir aName.Erase( aName.Len()-4 ); 1304cdf0e10cSrcweir aName.Append( pSuffix[i] ); 1305cdf0e10cSrcweir 1306cdf0e10cSrcweir ByteString aFilePath( aDir ); 1307cdf0e10cSrcweir aFilePath.Append( '/' ); 1308cdf0e10cSrcweir aFilePath.Append( aName ); 1309cdf0e10cSrcweir 1310cdf0e10cSrcweir ByteString aAfmFile; 1311cdf0e10cSrcweir if( access( aFilePath.GetBuffer(), R_OK ) ) 1312cdf0e10cSrcweir { 1313cdf0e10cSrcweir // try in subdirectory afm instead 1314cdf0e10cSrcweir aFilePath = aDir; 1315cdf0e10cSrcweir aFilePath.Append( "/afm/" ); 1316cdf0e10cSrcweir aFilePath.Append( aName ); 1317cdf0e10cSrcweir 1318cdf0e10cSrcweir if( ! access( aFilePath.GetBuffer(), R_OK ) ) 1319cdf0e10cSrcweir { 1320cdf0e10cSrcweir aAfmFile = "afm/"; 1321cdf0e10cSrcweir aAfmFile += aName; 1322cdf0e10cSrcweir } 1323cdf0e10cSrcweir } 1324cdf0e10cSrcweir else 1325cdf0e10cSrcweir aAfmFile = aName; 1326cdf0e10cSrcweir 1327cdf0e10cSrcweir if( aAfmFile.Len() ) 1328cdf0e10cSrcweir { 1329cdf0e10cSrcweir Type1FontFile* pFont = new Type1FontFile(); 1330cdf0e10cSrcweir pFont->m_nDirectory = nDirID; 1331cdf0e10cSrcweir 1332cdf0e10cSrcweir pFont->m_aFontFile = rFontFile; 1333cdf0e10cSrcweir pFont->m_aMetricFile = aAfmFile; 1334cdf0e10cSrcweir 1335cdf0e10cSrcweir if( ! pFont->readAfmMetrics( getAfmFile( pFont ), m_pAtoms, false, true ) ) 1336cdf0e10cSrcweir { 1337cdf0e10cSrcweir delete pFont; 1338cdf0e10cSrcweir pFont = NULL; 1339cdf0e10cSrcweir } 1340cdf0e10cSrcweir if( pFont && rXLFDs.size() ) 1341cdf0e10cSrcweir getFontAttributesFromXLFD( pFont, rXLFDs ); 1342cdf0e10cSrcweir if( pFont ) 1343cdf0e10cSrcweir rNewFonts.push_back( pFont ); 1344cdf0e10cSrcweir break; 1345cdf0e10cSrcweir } 1346cdf0e10cSrcweir } 1347cdf0e10cSrcweir } 1348cdf0e10cSrcweir else if( aExt.EqualsIgnoreCaseAscii( "afm" ) ) 1349cdf0e10cSrcweir { 1350cdf0e10cSrcweir ByteString aFilePath( aDir ); 1351cdf0e10cSrcweir aFilePath.Append( '/' ); 1352cdf0e10cSrcweir aFilePath.Append( ByteString( rFontFile ) ); 1353cdf0e10cSrcweir BuiltinFont* pFont = new BuiltinFont(); 1354cdf0e10cSrcweir pFont->m_nDirectory = nDirID; 1355cdf0e10cSrcweir pFont->m_aMetricFile = rFontFile; 1356cdf0e10cSrcweir if( pFont->readAfmMetrics( aFilePath, m_pAtoms, false, true ) ) 1357cdf0e10cSrcweir rNewFonts.push_back( pFont ); 1358cdf0e10cSrcweir else 1359cdf0e10cSrcweir delete pFont; 1360cdf0e10cSrcweir } 1361cdf0e10cSrcweir else if( aExt.EqualsIgnoreCaseAscii( "ttf" ) 1362cdf0e10cSrcweir || aExt.EqualsIgnoreCaseAscii( "tte" ) // #i33947# for Gaiji support 1363cdf0e10cSrcweir || aExt.EqualsIgnoreCaseAscii( "otf" ) ) // check for TTF- and PS-OpenType too 1364cdf0e10cSrcweir { 1365cdf0e10cSrcweir TrueTypeFontFile* pFont = new TrueTypeFontFile(); 1366cdf0e10cSrcweir pFont->m_nDirectory = nDirID; 1367cdf0e10cSrcweir pFont->m_aFontFile = rFontFile; 1368cdf0e10cSrcweir pFont->m_nCollectionEntry = -1; 1369cdf0e10cSrcweir 1370cdf0e10cSrcweir if( rXLFDs.size() ) 1371cdf0e10cSrcweir getFontAttributesFromXLFD( pFont, rXLFDs ); 1372cdf0e10cSrcweir // need to read the font anyway to get aliases inside the font file 1373cdf0e10cSrcweir if( ! analyzeTrueTypeFile( pFont ) ) 1374cdf0e10cSrcweir { 1375cdf0e10cSrcweir delete pFont; 1376cdf0e10cSrcweir pFont = NULL; 1377cdf0e10cSrcweir } 1378cdf0e10cSrcweir else 1379cdf0e10cSrcweir rNewFonts.push_back( pFont ); 1380cdf0e10cSrcweir } 1381cdf0e10cSrcweir else if( aExt.EqualsIgnoreCaseAscii( "ttc" ) ) 1382cdf0e10cSrcweir { 1383cdf0e10cSrcweir // get number of ttc entries 1384cdf0e10cSrcweir int nLength = CountTTCFonts( aFullPath.getStr() ); 1385cdf0e10cSrcweir if( nLength ) 1386cdf0e10cSrcweir { 1387cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 1388cdf0e10cSrcweir fprintf( stderr, "%s contains %d fonts\n", aFullPath.getStr(), nLength ); 1389cdf0e10cSrcweir #endif 1390cdf0e10cSrcweir for( int i = 0; i < nLength; i++ ) 1391cdf0e10cSrcweir { 1392cdf0e10cSrcweir TrueTypeFontFile* pFont = new TrueTypeFontFile(); 1393cdf0e10cSrcweir pFont->m_nDirectory = nDirID; 1394cdf0e10cSrcweir pFont->m_aFontFile = rFontFile; 1395cdf0e10cSrcweir pFont->m_nCollectionEntry = i; 1396cdf0e10cSrcweir if( nLength == 1 ) 1397cdf0e10cSrcweir getFontAttributesFromXLFD( pFont, rXLFDs ); 1398cdf0e10cSrcweir if( ! analyzeTrueTypeFile( pFont ) ) 1399cdf0e10cSrcweir { 1400cdf0e10cSrcweir delete pFont; 1401cdf0e10cSrcweir pFont = NULL; 1402cdf0e10cSrcweir } 1403cdf0e10cSrcweir else 1404cdf0e10cSrcweir rNewFonts.push_back( pFont ); 1405cdf0e10cSrcweir } 1406cdf0e10cSrcweir } 1407cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 1408cdf0e10cSrcweir else 1409cdf0e10cSrcweir fprintf( stderr, "CountTTCFonts( \"%s/%s\" ) failed\n", getDirectory(nDirID).getStr(), rFontFile.getStr() ); 1410cdf0e10cSrcweir #endif 1411cdf0e10cSrcweir } 1412cdf0e10cSrcweir return ! rNewFonts.empty(); 1413cdf0e10cSrcweir } 1414cdf0e10cSrcweir 1415cdf0e10cSrcweir // ------------------------------------------------------------------------- 1416cdf0e10cSrcweir 1417cdf0e10cSrcweir fontID PrintFontManager::findFontBuiltinID( int nPSNameAtom ) const 1418cdf0e10cSrcweir { 1419cdf0e10cSrcweir fontID nID = 0; 1420cdf0e10cSrcweir ::std::hash_map< fontID, PrintFont* >::const_iterator it; 1421cdf0e10cSrcweir for( it = m_aFonts.begin(); nID == 0 && it != m_aFonts.end(); ++it ) 1422cdf0e10cSrcweir { 1423cdf0e10cSrcweir if( it->second->m_eType == fonttype::Builtin && 1424cdf0e10cSrcweir it->second->m_nPSName == nPSNameAtom ) 1425cdf0e10cSrcweir nID = it->first; 1426cdf0e10cSrcweir } 1427cdf0e10cSrcweir return nID; 1428cdf0e10cSrcweir } 1429cdf0e10cSrcweir 1430cdf0e10cSrcweir // ------------------------------------------------------------------------- 1431cdf0e10cSrcweir 1432cdf0e10cSrcweir fontID PrintFontManager::findFontFileID( int nDirID, const OString& rFontFile ) const 1433cdf0e10cSrcweir { 1434cdf0e10cSrcweir fontID nID = 0; 1435cdf0e10cSrcweir 1436cdf0e10cSrcweir ::std::hash_map< OString, ::std::set< fontID >, OStringHash >::const_iterator set_it = m_aFontFileToFontID.find( rFontFile ); 1437cdf0e10cSrcweir if( set_it != m_aFontFileToFontID.end() ) 1438cdf0e10cSrcweir { 1439cdf0e10cSrcweir for( ::std::set< fontID >::const_iterator font_it = set_it->second.begin(); font_it != set_it->second.end() && ! nID; ++font_it ) 1440cdf0e10cSrcweir { 1441cdf0e10cSrcweir ::std::hash_map< fontID, PrintFont* >::const_iterator it = m_aFonts.find( *font_it ); 1442cdf0e10cSrcweir if( it != m_aFonts.end() ) 1443cdf0e10cSrcweir { 1444cdf0e10cSrcweir switch( it->second->m_eType ) 1445cdf0e10cSrcweir { 1446cdf0e10cSrcweir case fonttype::Type1: 1447cdf0e10cSrcweir { 1448cdf0e10cSrcweir Type1FontFile* const pFont = static_cast< Type1FontFile* const >((*it).second); 1449cdf0e10cSrcweir if( pFont->m_nDirectory == nDirID && 1450cdf0e10cSrcweir pFont->m_aFontFile == rFontFile ) 1451cdf0e10cSrcweir nID = it->first; 1452cdf0e10cSrcweir } 1453cdf0e10cSrcweir break; 1454cdf0e10cSrcweir case fonttype::TrueType: 1455cdf0e10cSrcweir { 1456cdf0e10cSrcweir TrueTypeFontFile* const pFont = static_cast< TrueTypeFontFile* const >((*it).second); 1457cdf0e10cSrcweir if( pFont->m_nDirectory == nDirID && 1458cdf0e10cSrcweir pFont->m_aFontFile == rFontFile ) 1459cdf0e10cSrcweir nID = it->first; 1460cdf0e10cSrcweir } 1461cdf0e10cSrcweir break; 1462cdf0e10cSrcweir case fonttype::Builtin: 1463cdf0e10cSrcweir if( static_cast<const BuiltinFont*>((*it).second)->m_nDirectory == nDirID && 1464cdf0e10cSrcweir static_cast<const BuiltinFont*>((*it).second)->m_aMetricFile == rFontFile ) 1465cdf0e10cSrcweir nID = it->first; 1466cdf0e10cSrcweir break; 1467cdf0e10cSrcweir default: 1468cdf0e10cSrcweir break; 1469cdf0e10cSrcweir } 1470cdf0e10cSrcweir } 1471cdf0e10cSrcweir } 1472cdf0e10cSrcweir } 1473cdf0e10cSrcweir return nID; 1474cdf0e10cSrcweir } 1475cdf0e10cSrcweir 1476cdf0e10cSrcweir // ------------------------------------------------------------------------- 1477cdf0e10cSrcweir 1478cdf0e10cSrcweir bool PrintFontManager::parseXLFD( const OString& rXLFD, XLFDEntry& rEntry ) 1479cdf0e10cSrcweir { 1480cdf0e10cSrcweir sal_Int32 nIndex = 0; 1481cdf0e10cSrcweir OString aFoundry = WhitespaceToSpace( rXLFD.getToken( 1, '-', nIndex ) ); 1482cdf0e10cSrcweir if( nIndex < 0 ) return false; 1483cdf0e10cSrcweir OString aFamilyXLFD = WhitespaceToSpace( rXLFD.getToken( 0, '-', nIndex ) ); 1484cdf0e10cSrcweir if( nIndex < 0 ) return false; 1485cdf0e10cSrcweir OString aWeight = rXLFD.getToken( 0, '-', nIndex ).toAsciiLowerCase(); 1486cdf0e10cSrcweir if( nIndex < 0 ) return false; 1487cdf0e10cSrcweir OString aSlant = rXLFD.getToken( 0, '-', nIndex ).toAsciiLowerCase(); 1488cdf0e10cSrcweir if( nIndex < 0 ) return false; 1489cdf0e10cSrcweir OString aWidth = rXLFD.getToken( 0, '-', nIndex ).toAsciiLowerCase(); 1490cdf0e10cSrcweir if( nIndex < 0 ) return false; 1491cdf0e10cSrcweir OString aAddStyle = rXLFD.getToken( 0, '-', nIndex ).toAsciiLowerCase(); 1492cdf0e10cSrcweir if( nIndex < 0 ) return false; 1493cdf0e10cSrcweir OString aPitch = rXLFD.getToken( 4, '-', nIndex ).toAsciiLowerCase(); 1494cdf0e10cSrcweir if( nIndex < 0 ) return false; 1495cdf0e10cSrcweir OString aRegEnc = WhitespaceToSpace( rXLFD.getToken( 1, '-', nIndex ).toAsciiLowerCase() ); 1496cdf0e10cSrcweir if( nIndex < 0 ) return false; 1497cdf0e10cSrcweir OString aEnc = WhitespaceToSpace( rXLFD.getToken( 0, '-', nIndex ).toAsciiLowerCase() ); 1498cdf0e10cSrcweir 1499cdf0e10cSrcweir // capitalize words 1500cdf0e10cSrcweir sal_Int32 nFamIndex = 0; 1501cdf0e10cSrcweir OStringBuffer aFamilyName; 1502cdf0e10cSrcweir while( nFamIndex >= 0 ) 1503cdf0e10cSrcweir { 1504cdf0e10cSrcweir OString aToken = aFamilyXLFD.getToken( 0, ' ', nFamIndex ); 1505cdf0e10cSrcweir sal_Char aFirst = aToken.toChar(); 1506cdf0e10cSrcweir if( aFirst >= 'a' && aFirst <= 'z' ) 1507cdf0e10cSrcweir aFirst = aFirst - 'a' + 'A'; 1508cdf0e10cSrcweir OStringBuffer aNewToken( aToken.getLength() ); 1509cdf0e10cSrcweir aNewToken.append( aToken ); 1510cdf0e10cSrcweir aNewToken.setCharAt( 0, aFirst ); 1511cdf0e10cSrcweir if( aFamilyName.getLength() > 0 ) 1512cdf0e10cSrcweir aFamilyName.append( ' ' ); 1513cdf0e10cSrcweir aFamilyName.append( aNewToken.makeStringAndClear() ); 1514cdf0e10cSrcweir } 1515cdf0e10cSrcweir 1516cdf0e10cSrcweir rEntry.aFoundry = aFoundry; 1517cdf0e10cSrcweir rEntry.aFamily = aFamilyName.makeStringAndClear(); 1518cdf0e10cSrcweir rEntry.aAddStyle = aAddStyle; 1519cdf0e10cSrcweir // evaluate weight 1520cdf0e10cSrcweir rEntry.eWeight = parseWeight( aWeight ); 1521cdf0e10cSrcweir // evaluate slant 1522cdf0e10cSrcweir rEntry.eItalic = parseItalic( aSlant ); 1523cdf0e10cSrcweir // evaluate width 1524cdf0e10cSrcweir rEntry.eWidth = parseWidth( aWidth ); 1525cdf0e10cSrcweir 1526cdf0e10cSrcweir // evaluate pitch 1527cdf0e10cSrcweir if( aPitch.toChar() == 'c' || aPitch.toChar() == 'm' ) 1528cdf0e10cSrcweir rEntry.ePitch = pitch::Fixed; 1529cdf0e10cSrcweir else 1530cdf0e10cSrcweir rEntry.ePitch = pitch::Variable; 1531cdf0e10cSrcweir 1532cdf0e10cSrcweir OString aToken = aEnc.toAsciiLowerCase(); 1533cdf0e10cSrcweir // get encoding 1534cdf0e10cSrcweir if( aAddStyle.indexOf( "symbol" ) != -1 ) 1535cdf0e10cSrcweir rEntry.aEncoding = RTL_TEXTENCODING_SYMBOL; 1536cdf0e10cSrcweir else 1537cdf0e10cSrcweir { 1538cdf0e10cSrcweir if( aToken.equals( "symbol" ) ) 1539cdf0e10cSrcweir rEntry.aEncoding = RTL_TEXTENCODING_SYMBOL; 1540cdf0e10cSrcweir else 1541cdf0e10cSrcweir { 1542cdf0e10cSrcweir OStringBuffer aCharset( aRegEnc.getLength() + aEnc.getLength() + 1 ); 1543cdf0e10cSrcweir aCharset.append( aRegEnc ); 1544cdf0e10cSrcweir aCharset.append( '-' ); 1545cdf0e10cSrcweir aCharset.append( aEnc ); 1546cdf0e10cSrcweir rEntry.aEncoding = rtl_getTextEncodingFromUnixCharset( aCharset.getStr() ); 1547cdf0e10cSrcweir } 1548cdf0e10cSrcweir } 1549cdf0e10cSrcweir 1550cdf0e10cSrcweir // set correct mask flags 1551cdf0e10cSrcweir rEntry.nMask = 0; 1552cdf0e10cSrcweir if( rEntry.aFoundry != "*" ) rEntry.nMask |= XLFDEntry::MaskFoundry; 1553cdf0e10cSrcweir if( rEntry.aFamily != "*" ) rEntry.nMask |= XLFDEntry::MaskFamily; 1554cdf0e10cSrcweir if( rEntry.aAddStyle != "*" ) rEntry.nMask |= XLFDEntry::MaskAddStyle; 1555cdf0e10cSrcweir if( aWeight != "*" ) rEntry.nMask |= XLFDEntry::MaskWeight; 1556cdf0e10cSrcweir if( aSlant != "*" ) rEntry.nMask |= XLFDEntry::MaskItalic; 1557cdf0e10cSrcweir if( aWidth != "*" ) rEntry.nMask |= XLFDEntry::MaskWidth; 1558cdf0e10cSrcweir if( aPitch != "*" ) rEntry.nMask |= XLFDEntry::MaskPitch; 1559cdf0e10cSrcweir if( aRegEnc != "*" && aEnc != "*" ) rEntry.nMask |= XLFDEntry::MaskEncoding; 1560cdf0e10cSrcweir 1561cdf0e10cSrcweir return true; 1562cdf0e10cSrcweir } 1563cdf0e10cSrcweir 1564cdf0e10cSrcweir // ------------------------------------------------------------------------- 1565cdf0e10cSrcweir 1566cdf0e10cSrcweir void PrintFontManager::parseXLFD_appendAliases( const std::list< OString >& rXLFDs, std::list< XLFDEntry >& rEntries ) const 1567cdf0e10cSrcweir { 1568cdf0e10cSrcweir for( std::list< OString >::const_iterator it = rXLFDs.begin(); it != rXLFDs.end(); ++it ) 1569cdf0e10cSrcweir { 1570cdf0e10cSrcweir XLFDEntry aEntry; 1571cdf0e10cSrcweir if( ! parseXLFD(*it, aEntry) ) 1572cdf0e10cSrcweir continue; 1573cdf0e10cSrcweir rEntries.push_back( aEntry ); 1574cdf0e10cSrcweir std::map< XLFDEntry, std::list< XLFDEntry > >::const_iterator alias_it = 1575cdf0e10cSrcweir m_aXLFD_Aliases.find( aEntry ); 1576cdf0e10cSrcweir if( alias_it != m_aXLFD_Aliases.end() ) 1577cdf0e10cSrcweir { 1578cdf0e10cSrcweir rEntries.insert( rEntries.end(), alias_it->second.begin(), alias_it->second.end() ); 1579cdf0e10cSrcweir } 1580cdf0e10cSrcweir } 1581cdf0e10cSrcweir } 1582cdf0e10cSrcweir 1583cdf0e10cSrcweir // ------------------------------------------------------------------------- 1584cdf0e10cSrcweir 1585cdf0e10cSrcweir void PrintFontManager::getFontAttributesFromXLFD( PrintFont* pFont, const std::list< OString >& rXLFDs ) const 1586cdf0e10cSrcweir { 1587cdf0e10cSrcweir bool bFamilyName = false; 1588cdf0e10cSrcweir 1589cdf0e10cSrcweir std::list< XLFDEntry > aXLFDs; 1590cdf0e10cSrcweir 1591cdf0e10cSrcweir parseXLFD_appendAliases( rXLFDs, aXLFDs ); 1592cdf0e10cSrcweir 1593cdf0e10cSrcweir for( std::list< XLFDEntry >::const_iterator it = aXLFDs.begin(); 1594cdf0e10cSrcweir it != aXLFDs.end(); ++it ) 1595cdf0e10cSrcweir { 1596cdf0e10cSrcweir // set family name or alias 1597cdf0e10cSrcweir int nFam = 1598cdf0e10cSrcweir m_pAtoms->getAtom( ATOM_FAMILYNAME, 1599cdf0e10cSrcweir OStringToOUString( it->aFamily, it->aAddStyle.indexOf( "utf8" ) != -1 ? RTL_TEXTENCODING_UTF8 : RTL_TEXTENCODING_ISO_8859_1 ), 1600cdf0e10cSrcweir sal_True ); 1601cdf0e10cSrcweir if( ! bFamilyName ) 1602cdf0e10cSrcweir { 1603cdf0e10cSrcweir bFamilyName = true; 1604cdf0e10cSrcweir pFont->m_nFamilyName = nFam; 1605cdf0e10cSrcweir switch( pFont->m_eType ) 1606cdf0e10cSrcweir { 1607cdf0e10cSrcweir case fonttype::Type1: 1608cdf0e10cSrcweir static_cast<Type1FontFile*>(pFont)->m_aXLFD = rXLFDs.front(); 1609cdf0e10cSrcweir break; 1610cdf0e10cSrcweir case fonttype::TrueType: 1611cdf0e10cSrcweir static_cast<TrueTypeFontFile*>(pFont)->m_aXLFD = rXLFDs.front(); 1612cdf0e10cSrcweir break; 1613cdf0e10cSrcweir default: 1614cdf0e10cSrcweir break; 1615cdf0e10cSrcweir } 1616cdf0e10cSrcweir } 1617cdf0e10cSrcweir else 1618cdf0e10cSrcweir { 1619cdf0e10cSrcweir // make sure that aliases are unique 1620cdf0e10cSrcweir if( nFam != pFont->m_nFamilyName ) 1621cdf0e10cSrcweir { 1622cdf0e10cSrcweir std::list< int >::const_iterator al_it; 1623cdf0e10cSrcweir for( al_it = pFont->m_aAliases.begin(); al_it != pFont->m_aAliases.end() && *al_it != nFam; ++al_it ) 1624cdf0e10cSrcweir ; 1625cdf0e10cSrcweir if( al_it == pFont->m_aAliases.end() ) 1626cdf0e10cSrcweir pFont->m_aAliases.push_back( nFam ); 1627cdf0e10cSrcweir 1628cdf0e10cSrcweir } 1629cdf0e10cSrcweir // for the rest of the attributes there can only be one value; 1630cdf0e10cSrcweir // we'll trust the first one 1631cdf0e10cSrcweir continue; 1632cdf0e10cSrcweir } 1633cdf0e10cSrcweir 1634cdf0e10cSrcweir // fill in weight 1635cdf0e10cSrcweir pFont->m_eWeight = it->eWeight; 1636cdf0e10cSrcweir // fill in slant 1637cdf0e10cSrcweir pFont->m_eItalic = it->eItalic; 1638cdf0e10cSrcweir // fill in width 1639cdf0e10cSrcweir pFont->m_eWidth = it->eWidth; 1640cdf0e10cSrcweir // fill in pitch 1641cdf0e10cSrcweir pFont->m_ePitch = it->ePitch; 1642cdf0e10cSrcweir // fill in encoding 1643cdf0e10cSrcweir pFont->m_aEncoding = it->aEncoding; 1644cdf0e10cSrcweir } 1645cdf0e10cSrcweir 1646cdf0e10cSrcweir // handle iso8859-1 as ms1252 to fill the "gap" starting at 0x80 1647cdf0e10cSrcweir if( pFont->m_aEncoding == RTL_TEXTENCODING_ISO_8859_1 ) 1648cdf0e10cSrcweir pFont->m_aEncoding = RTL_TEXTENCODING_MS_1252; 1649cdf0e10cSrcweir if( rXLFDs.begin() != rXLFDs.end() ) 1650cdf0e10cSrcweir { 1651cdf0e10cSrcweir switch( pFont->m_eType ) 1652cdf0e10cSrcweir { 1653cdf0e10cSrcweir case fonttype::Type1: 1654cdf0e10cSrcweir static_cast<Type1FontFile*>(pFont)->m_aXLFD = rXLFDs.front(); 1655cdf0e10cSrcweir break; 1656cdf0e10cSrcweir case fonttype::TrueType: 1657cdf0e10cSrcweir static_cast<TrueTypeFontFile*>(pFont)->m_aXLFD = rXLFDs.front(); 1658cdf0e10cSrcweir break; 1659cdf0e10cSrcweir default: break; 1660cdf0e10cSrcweir } 1661cdf0e10cSrcweir } 1662cdf0e10cSrcweir } 1663cdf0e10cSrcweir 1664cdf0e10cSrcweir // ------------------------------------------------------------------------- 1665cdf0e10cSrcweir 1666cdf0e10cSrcweir OString PrintFontManager::getXLFD( PrintFont* pFont ) const 1667cdf0e10cSrcweir { 1668cdf0e10cSrcweir if( pFont->m_eType == fonttype::Type1 ) 1669cdf0e10cSrcweir { 1670cdf0e10cSrcweir if( static_cast<Type1FontFile*>(pFont)->m_aXLFD.getLength() ) 1671cdf0e10cSrcweir return static_cast<Type1FontFile*>(pFont)->m_aXLFD; 1672cdf0e10cSrcweir } 1673cdf0e10cSrcweir if( pFont->m_eType == fonttype::TrueType ) 1674cdf0e10cSrcweir { 1675cdf0e10cSrcweir if( static_cast<TrueTypeFontFile*>(pFont)->m_aXLFD.getLength() ) 1676cdf0e10cSrcweir return static_cast<TrueTypeFontFile*>(pFont)->m_aXLFD; 1677cdf0e10cSrcweir } 1678cdf0e10cSrcweir 1679cdf0e10cSrcweir OStringBuffer aXLFD( 128 ); 1680cdf0e10cSrcweir 1681cdf0e10cSrcweir aXLFD.append( "-misc-" ); 1682cdf0e10cSrcweir ByteString aFamily( String( m_pAtoms->getString( ATOM_FAMILYNAME, pFont->m_nFamilyName ) ), RTL_TEXTENCODING_UTF8 ); 1683cdf0e10cSrcweir aFamily.SearchAndReplaceAll( '-',' ' ); 1684cdf0e10cSrcweir aFamily.SearchAndReplaceAll( '?',' ' ); 1685cdf0e10cSrcweir aFamily.SearchAndReplaceAll( '*',' ' ); 1686cdf0e10cSrcweir aXLFD.append( OString( aFamily ) ); 1687cdf0e10cSrcweir aXLFD.append( '-' ); 1688cdf0e10cSrcweir switch( pFont->m_eWeight ) 1689cdf0e10cSrcweir { 1690cdf0e10cSrcweir case weight::Thin: aXLFD.append("thin");break; 1691cdf0e10cSrcweir case weight::UltraLight: aXLFD.append("ultralight");break; 1692cdf0e10cSrcweir case weight::Light: aXLFD.append("light");break; 1693cdf0e10cSrcweir case weight::SemiLight: aXLFD.append("semilight");break; 1694cdf0e10cSrcweir case weight::Normal: aXLFD.append("normal");break; 1695cdf0e10cSrcweir case weight::Medium: aXLFD.append("medium");break; 1696cdf0e10cSrcweir case weight::SemiBold: aXLFD.append("semibold");break; 1697cdf0e10cSrcweir case weight::Bold: aXLFD.append("bold");break; 1698cdf0e10cSrcweir case weight::UltraBold: aXLFD.append("ultrabold");break; 1699cdf0e10cSrcweir case weight::Black: aXLFD.append("black");break; 1700cdf0e10cSrcweir default: break; 1701cdf0e10cSrcweir } 1702cdf0e10cSrcweir aXLFD.append('-'); 1703cdf0e10cSrcweir switch( pFont->m_eItalic ) 1704cdf0e10cSrcweir { 1705cdf0e10cSrcweir case italic::Upright: aXLFD.append('r');break; 1706cdf0e10cSrcweir case italic::Oblique: aXLFD.append('o');break; 1707cdf0e10cSrcweir case italic::Italic: aXLFD.append('i');break; 1708cdf0e10cSrcweir default: break; 1709cdf0e10cSrcweir } 1710cdf0e10cSrcweir aXLFD.append('-'); 1711cdf0e10cSrcweir switch( pFont->m_eWidth ) 1712cdf0e10cSrcweir { 1713cdf0e10cSrcweir case width::UltraCondensed: aXLFD.append("ultracondensed");break; 1714cdf0e10cSrcweir case width::ExtraCondensed: aXLFD.append("extracondensed");break; 1715cdf0e10cSrcweir case width::Condensed: aXLFD.append("condensed");break; 1716cdf0e10cSrcweir case width::SemiCondensed: aXLFD.append("semicondensed");break; 1717cdf0e10cSrcweir case width::Normal: aXLFD.append("normal");break; 1718cdf0e10cSrcweir case width::SemiExpanded: aXLFD.append("semiexpanded");break; 1719cdf0e10cSrcweir case width::Expanded: aXLFD.append("expanded");break; 1720cdf0e10cSrcweir case width::ExtraExpanded: aXLFD.append("extraexpanded");break; 1721cdf0e10cSrcweir case width::UltraExpanded: aXLFD.append("ultraexpanded");break; 1722cdf0e10cSrcweir default: break; 1723cdf0e10cSrcweir } 1724cdf0e10cSrcweir aXLFD.append("-utf8-0-0-0-0-"); 1725cdf0e10cSrcweir aXLFD.append( pFont->m_ePitch == pitch::Fixed ? "m" : "p" ); 1726cdf0e10cSrcweir aXLFD.append("-0-"); 1727cdf0e10cSrcweir const char* pEnc = rtl_getBestUnixCharsetFromTextEncoding( pFont->m_aEncoding ); 1728cdf0e10cSrcweir if( ! pEnc ) 1729cdf0e10cSrcweir { 1730cdf0e10cSrcweir if( pFont->m_aEncoding == RTL_TEXTENCODING_ADOBE_STANDARD ) 1731cdf0e10cSrcweir pEnc = "adobe-standard"; 1732cdf0e10cSrcweir else 1733cdf0e10cSrcweir pEnc = "iso8859-1"; 1734cdf0e10cSrcweir } 1735cdf0e10cSrcweir aXLFD .append( pEnc ); 1736cdf0e10cSrcweir 1737cdf0e10cSrcweir return aXLFD.makeStringAndClear(); 1738cdf0e10cSrcweir } 1739cdf0e10cSrcweir 1740cdf0e10cSrcweir // ------------------------------------------------------------------------- 1741cdf0e10cSrcweir 1742cdf0e10cSrcweir OUString PrintFontManager::convertTrueTypeName( void* pRecord ) const 1743cdf0e10cSrcweir { 1744cdf0e10cSrcweir NameRecord* pNameRecord = (NameRecord*)pRecord; 1745cdf0e10cSrcweir OUString aValue; 1746cdf0e10cSrcweir if( 1747cdf0e10cSrcweir ( pNameRecord->platformID == 3 && ( pNameRecord->encodingID == 0 || pNameRecord->encodingID == 1 ) ) // MS, Unicode 1748cdf0e10cSrcweir || 1749cdf0e10cSrcweir ( pNameRecord->platformID == 0 ) // Apple, Unicode 1750cdf0e10cSrcweir ) 1751cdf0e10cSrcweir { 1752cdf0e10cSrcweir OUStringBuffer aName( pNameRecord->slen/2 ); 1753cdf0e10cSrcweir const sal_uInt8* pNameBuffer = pNameRecord->sptr; 1754cdf0e10cSrcweir for(int n = 0; n < pNameRecord->slen/2; n++ ) 1755cdf0e10cSrcweir aName.append( (sal_Unicode)getUInt16BE( pNameBuffer ) ); 1756cdf0e10cSrcweir aValue = aName.makeStringAndClear(); 1757cdf0e10cSrcweir } 1758cdf0e10cSrcweir else if( pNameRecord->platformID == 3 ) 1759cdf0e10cSrcweir { 1760cdf0e10cSrcweir if( pNameRecord->encodingID >= 2 && pNameRecord->encodingID <= 6 ) 1761cdf0e10cSrcweir { 1762cdf0e10cSrcweir /* 1763cdf0e10cSrcweir * and now for a special kind of madness: 1764cdf0e10cSrcweir * some fonts encode their byte value string as BE uint16 1765cdf0e10cSrcweir * (leading to stray zero bytes in the string) 1766cdf0e10cSrcweir * while others code two bytes as a uint16 and swap to BE 1767cdf0e10cSrcweir */ 1768cdf0e10cSrcweir OStringBuffer aName; 1769cdf0e10cSrcweir const sal_uInt8* pNameBuffer = pNameRecord->sptr; 1770cdf0e10cSrcweir for(int n = 0; n < pNameRecord->slen/2; n++ ) 1771cdf0e10cSrcweir { 1772cdf0e10cSrcweir sal_Unicode aCode = (sal_Unicode)getUInt16BE( pNameBuffer ); 1773cdf0e10cSrcweir sal_Char aChar = aCode >> 8; 1774cdf0e10cSrcweir if( aChar ) 1775cdf0e10cSrcweir aName.append( aChar ); 1776cdf0e10cSrcweir aChar = aCode & 0x00ff; 1777cdf0e10cSrcweir if( aChar ) 1778cdf0e10cSrcweir aName.append( aChar ); 1779cdf0e10cSrcweir } 1780cdf0e10cSrcweir switch( pNameRecord->encodingID ) 1781cdf0e10cSrcweir { 1782cdf0e10cSrcweir case 2: 1783cdf0e10cSrcweir aValue = OStringToOUString( aName.makeStringAndClear(), RTL_TEXTENCODING_MS_932 ); 1784cdf0e10cSrcweir break; 1785cdf0e10cSrcweir case 3: 1786cdf0e10cSrcweir aValue = OStringToOUString( aName.makeStringAndClear(), RTL_TEXTENCODING_MS_936 ); 1787cdf0e10cSrcweir break; 1788cdf0e10cSrcweir case 4: 1789cdf0e10cSrcweir aValue = OStringToOUString( aName.makeStringAndClear(), RTL_TEXTENCODING_MS_950 ); 1790cdf0e10cSrcweir break; 1791cdf0e10cSrcweir case 5: 1792cdf0e10cSrcweir aValue = OStringToOUString( aName.makeStringAndClear(), RTL_TEXTENCODING_MS_949 ); 1793cdf0e10cSrcweir break; 1794cdf0e10cSrcweir case 6: 1795cdf0e10cSrcweir aValue = OStringToOUString( aName.makeStringAndClear(), RTL_TEXTENCODING_MS_1361 ); 1796cdf0e10cSrcweir break; 1797cdf0e10cSrcweir } 1798cdf0e10cSrcweir } 1799cdf0e10cSrcweir } 1800cdf0e10cSrcweir return aValue; 1801cdf0e10cSrcweir } 1802cdf0e10cSrcweir 1803cdf0e10cSrcweir // ------------------------------------------------------------------------- 1804cdf0e10cSrcweir 1805cdf0e10cSrcweir void PrintFontManager::analyzeTrueTypeFamilyName( void* pTTFont, ::std::list< OUString >& rNames ) const 1806cdf0e10cSrcweir { 1807cdf0e10cSrcweir OUString aFamily; 1808cdf0e10cSrcweir 1809cdf0e10cSrcweir rNames.clear(); 1810cdf0e10cSrcweir ::std::set< OUString > aSet; 1811cdf0e10cSrcweir 1812cdf0e10cSrcweir NameRecord* pNameRecords = NULL; 1813cdf0e10cSrcweir int nNameRecords = GetTTNameRecords( (TrueTypeFont*)pTTFont, &pNameRecords ); 1814cdf0e10cSrcweir if( nNameRecords && pNameRecords ) 1815cdf0e10cSrcweir { 1816cdf0e10cSrcweir LanguageType aLang = MsLangId::getSystemLanguage(); 1817cdf0e10cSrcweir int nLastMatch = -1; 1818cdf0e10cSrcweir for( int i = 0; i < nNameRecords; i++ ) 1819cdf0e10cSrcweir { 1820cdf0e10cSrcweir if( pNameRecords[i].nameID != 1 || pNameRecords[i].sptr == NULL ) 1821cdf0e10cSrcweir continue; 1822cdf0e10cSrcweir int nMatch = -1; 1823cdf0e10cSrcweir if( pNameRecords[i].platformID == 0 ) // Unicode 1824cdf0e10cSrcweir nMatch = 4000; 1825cdf0e10cSrcweir else if( pNameRecords[i].platformID == 3 ) 1826cdf0e10cSrcweir { 1827cdf0e10cSrcweir // this bases on the LanguageType actually being a Win LCID 1828cdf0e10cSrcweir if( pNameRecords[i].languageID == aLang ) 1829cdf0e10cSrcweir nMatch = 8000; 1830cdf0e10cSrcweir else if( pNameRecords[i].languageID == LANGUAGE_ENGLISH_US ) 1831cdf0e10cSrcweir nMatch = 2000; 1832cdf0e10cSrcweir else if( pNameRecords[i].languageID == LANGUAGE_ENGLISH || 1833cdf0e10cSrcweir pNameRecords[i].languageID == LANGUAGE_ENGLISH_UK ) 1834cdf0e10cSrcweir nMatch = 1500; 1835cdf0e10cSrcweir else 1836cdf0e10cSrcweir nMatch = 1000; 1837cdf0e10cSrcweir } 1838cdf0e10cSrcweir OUString aName = convertTrueTypeName( pNameRecords + i ); 1839cdf0e10cSrcweir aSet.insert( aName ); 1840cdf0e10cSrcweir if( nMatch > nLastMatch ) 1841cdf0e10cSrcweir { 1842cdf0e10cSrcweir nLastMatch = nMatch; 1843cdf0e10cSrcweir aFamily = aName; 1844cdf0e10cSrcweir } 1845cdf0e10cSrcweir } 1846cdf0e10cSrcweir DisposeNameRecords( pNameRecords, nNameRecords ); 1847cdf0e10cSrcweir } 1848cdf0e10cSrcweir if( aFamily.getLength() ) 1849cdf0e10cSrcweir { 1850cdf0e10cSrcweir rNames.push_front( aFamily ); 1851cdf0e10cSrcweir for( ::std::set< OUString >::const_iterator it = aSet.begin(); it != aSet.end(); ++it ) 1852cdf0e10cSrcweir if( *it != aFamily ) 1853cdf0e10cSrcweir rNames.push_back( *it ); 1854cdf0e10cSrcweir } 1855cdf0e10cSrcweir return; 1856cdf0e10cSrcweir } 1857cdf0e10cSrcweir 1858cdf0e10cSrcweir // ------------------------------------------------------------------------- 1859cdf0e10cSrcweir 1860cdf0e10cSrcweir bool PrintFontManager::analyzeTrueTypeFile( PrintFont* pFont ) const 1861cdf0e10cSrcweir { 1862cdf0e10cSrcweir bool bSuccess = false; 1863cdf0e10cSrcweir rtl_TextEncoding aEncoding = osl_getThreadTextEncoding(); 1864cdf0e10cSrcweir ByteString aFile = getFontFile( pFont ); 1865cdf0e10cSrcweir TrueTypeFont* pTTFont = NULL; 1866cdf0e10cSrcweir 1867cdf0e10cSrcweir TrueTypeFontFile* pTTFontFile = static_cast< TrueTypeFontFile* >(pFont); 1868cdf0e10cSrcweir if( OpenTTFontFile( aFile.GetBuffer(), pTTFontFile->m_nCollectionEntry < 0 ? 0 : pTTFontFile->m_nCollectionEntry, &pTTFont ) == SF_OK ) 1869cdf0e10cSrcweir { 1870cdf0e10cSrcweir TTGlobalFontInfo aInfo; 1871cdf0e10cSrcweir GetTTGlobalFontInfo( pTTFont, & aInfo ); 1872cdf0e10cSrcweir 1873cdf0e10cSrcweir ::std::list< OUString > aNames; 1874cdf0e10cSrcweir analyzeTrueTypeFamilyName( pTTFont, aNames ); 1875cdf0e10cSrcweir 1876cdf0e10cSrcweir // set family name from XLFD if possible 1877cdf0e10cSrcweir if( ! pFont->m_nFamilyName ) 1878cdf0e10cSrcweir { 1879cdf0e10cSrcweir if( aNames.begin() != aNames.end() ) 1880cdf0e10cSrcweir { 1881cdf0e10cSrcweir pFont->m_nFamilyName = m_pAtoms->getAtom( ATOM_FAMILYNAME, aNames.front(), sal_True ); 1882cdf0e10cSrcweir aNames.pop_front(); 1883cdf0e10cSrcweir } 1884cdf0e10cSrcweir else 1885cdf0e10cSrcweir { 1886cdf0e10cSrcweir sal_Int32 dotIndex; 1887cdf0e10cSrcweir 1888cdf0e10cSrcweir // poor font does not have a family name 1889cdf0e10cSrcweir // name it to file name minus the extension 1890cdf0e10cSrcweir dotIndex = pTTFontFile->m_aFontFile.lastIndexOf( '.' ); 1891cdf0e10cSrcweir if ( dotIndex == -1 ) 1892cdf0e10cSrcweir dotIndex = pTTFontFile->m_aFontFile.getLength(); 1893cdf0e10cSrcweir 1894cdf0e10cSrcweir pFont->m_nFamilyName = m_pAtoms->getAtom( ATOM_FAMILYNAME, OStringToOUString( pTTFontFile->m_aFontFile.copy( 0, dotIndex ), aEncoding ), sal_True ); 1895cdf0e10cSrcweir } 1896cdf0e10cSrcweir } 1897cdf0e10cSrcweir for( ::std::list< OUString >::iterator it = aNames.begin(); it != aNames.end(); ++it ) 1898cdf0e10cSrcweir { 1899cdf0e10cSrcweir if( it->getLength() ) 1900cdf0e10cSrcweir { 1901cdf0e10cSrcweir int nAlias = m_pAtoms->getAtom( ATOM_FAMILYNAME, *it, sal_True ); 1902cdf0e10cSrcweir if( nAlias != pFont->m_nFamilyName ) 1903cdf0e10cSrcweir { 1904cdf0e10cSrcweir std::list< int >::const_iterator al_it; 1905cdf0e10cSrcweir for( al_it = pFont->m_aAliases.begin(); al_it != pFont->m_aAliases.end() && *al_it != nAlias; ++al_it ) 1906cdf0e10cSrcweir ; 1907cdf0e10cSrcweir if( al_it == pFont->m_aAliases.end() ) 1908cdf0e10cSrcweir pFont->m_aAliases.push_back( nAlias ); 1909cdf0e10cSrcweir } 1910cdf0e10cSrcweir } 1911cdf0e10cSrcweir } 1912cdf0e10cSrcweir 1913cdf0e10cSrcweir if( aInfo.usubfamily ) 1914cdf0e10cSrcweir pFont->m_aStyleName = OUString( aInfo.usubfamily ); 1915cdf0e10cSrcweir 1916cdf0e10cSrcweir pFont->m_nPSName = m_pAtoms->getAtom( ATOM_PSNAME, String( ByteString( aInfo.psname ), aEncoding ), sal_True ); 1917cdf0e10cSrcweir switch( aInfo.weight ) 1918cdf0e10cSrcweir { 1919cdf0e10cSrcweir case FW_THIN: pFont->m_eWeight = weight::Thin; break; 1920cdf0e10cSrcweir case FW_EXTRALIGHT: pFont->m_eWeight = weight::UltraLight; break; 1921cdf0e10cSrcweir case FW_LIGHT: pFont->m_eWeight = weight::Light; break; 1922cdf0e10cSrcweir case FW_MEDIUM: pFont->m_eWeight = weight::Medium; break; 1923cdf0e10cSrcweir case FW_SEMIBOLD: pFont->m_eWeight = weight::SemiBold; break; 1924cdf0e10cSrcweir case FW_BOLD: pFont->m_eWeight = weight::Bold; break; 1925cdf0e10cSrcweir case FW_EXTRABOLD: pFont->m_eWeight = weight::UltraBold; break; 1926cdf0e10cSrcweir case FW_BLACK: pFont->m_eWeight = weight::Black; break; 1927cdf0e10cSrcweir 1928cdf0e10cSrcweir case FW_NORMAL: 1929cdf0e10cSrcweir default: pFont->m_eWeight = weight::Normal; break; 1930cdf0e10cSrcweir } 1931cdf0e10cSrcweir 1932cdf0e10cSrcweir switch( aInfo.width ) 1933cdf0e10cSrcweir { 1934cdf0e10cSrcweir case FWIDTH_ULTRA_CONDENSED: pFont->m_eWidth = width::UltraCondensed; break; 1935cdf0e10cSrcweir case FWIDTH_EXTRA_CONDENSED: pFont->m_eWidth = width::ExtraCondensed; break; 1936cdf0e10cSrcweir case FWIDTH_CONDENSED: pFont->m_eWidth = width::Condensed; break; 1937cdf0e10cSrcweir case FWIDTH_SEMI_CONDENSED: pFont->m_eWidth = width::SemiCondensed; break; 1938cdf0e10cSrcweir case FWIDTH_SEMI_EXPANDED: pFont->m_eWidth = width::SemiExpanded; break; 1939cdf0e10cSrcweir case FWIDTH_EXPANDED: pFont->m_eWidth = width::Expanded; break; 1940cdf0e10cSrcweir case FWIDTH_EXTRA_EXPANDED: pFont->m_eWidth = width::ExtraExpanded; break; 1941cdf0e10cSrcweir case FWIDTH_ULTRA_EXPANDED: pFont->m_eWidth = width::UltraExpanded; break; 1942cdf0e10cSrcweir 1943cdf0e10cSrcweir case FWIDTH_NORMAL: 1944cdf0e10cSrcweir default: pFont->m_eWidth = width::Normal; break; 1945cdf0e10cSrcweir } 1946cdf0e10cSrcweir 1947cdf0e10cSrcweir pFont->m_ePitch = aInfo.pitch ? pitch::Fixed : pitch::Variable; 1948cdf0e10cSrcweir pFont->m_eItalic = aInfo.italicAngle == 0 ? italic::Upright : ( aInfo.italicAngle < 0 ? italic::Italic : italic::Oblique ); 1949cdf0e10cSrcweir // #104264# there are fonts that set italic angle 0 although they are 1950cdf0e10cSrcweir // italic; use macstyle bit here 1951cdf0e10cSrcweir if( aInfo.italicAngle == 0 && (aInfo.macStyle & 2) ) 1952cdf0e10cSrcweir pFont->m_eItalic = italic::Italic; 1953cdf0e10cSrcweir 1954cdf0e10cSrcweir pFont->m_aEncoding = aInfo.symbolEncoded ? RTL_TEXTENCODING_SYMBOL : RTL_TEXTENCODING_UCS2; 1955cdf0e10cSrcweir 1956cdf0e10cSrcweir pFont->m_aGlobalMetricY.width = pFont->m_aGlobalMetricX.width = aInfo.xMax - aInfo.xMin; 1957cdf0e10cSrcweir pFont->m_aGlobalMetricY.height = pFont->m_aGlobalMetricX.height = aInfo.yMax - aInfo.yMin; 1958cdf0e10cSrcweir 1959cdf0e10cSrcweir if( aInfo.winAscent && aInfo.winDescent ) 1960cdf0e10cSrcweir { 1961cdf0e10cSrcweir pFont->m_nAscend = aInfo.winAscent; 1962cdf0e10cSrcweir pFont->m_nDescend = aInfo.winDescent; 1963cdf0e10cSrcweir pFont->m_nLeading = pFont->m_nAscend + pFont->m_nDescend - 1000; 1964cdf0e10cSrcweir } 1965cdf0e10cSrcweir else if( aInfo.typoAscender && aInfo.typoDescender ) 1966cdf0e10cSrcweir { 1967cdf0e10cSrcweir pFont->m_nLeading = aInfo.typoLineGap; 1968cdf0e10cSrcweir pFont->m_nAscend = aInfo.typoAscender; 1969cdf0e10cSrcweir pFont->m_nDescend = -aInfo.typoDescender; 1970cdf0e10cSrcweir } 1971cdf0e10cSrcweir else 1972cdf0e10cSrcweir { 1973cdf0e10cSrcweir pFont->m_nLeading = aInfo.linegap; 1974cdf0e10cSrcweir pFont->m_nAscend = aInfo.ascender; 1975cdf0e10cSrcweir pFont->m_nDescend = -aInfo.descender; 1976cdf0e10cSrcweir } 1977cdf0e10cSrcweir 1978cdf0e10cSrcweir // last try: font bounding box 1979cdf0e10cSrcweir if( pFont->m_nAscend == 0 ) 1980cdf0e10cSrcweir pFont->m_nAscend = aInfo.yMax; 1981cdf0e10cSrcweir if( pFont->m_nDescend == 0 ) 1982cdf0e10cSrcweir pFont->m_nDescend = -aInfo.yMin; 1983cdf0e10cSrcweir if( pFont->m_nLeading == 0 ) 1984cdf0e10cSrcweir pFont->m_nLeading = 15 * (pFont->m_nAscend+pFont->m_nDescend) / 100; 1985cdf0e10cSrcweir 1986cdf0e10cSrcweir if( pFont->m_nAscend ) 1987cdf0e10cSrcweir pFont->m_aGlobalMetricX.height = pFont->m_aGlobalMetricY.height = pFont->m_nAscend + pFont->m_nDescend; 1988cdf0e10cSrcweir 1989cdf0e10cSrcweir // get bounding box 1990cdf0e10cSrcweir pFont->m_nXMin = aInfo.xMin; 1991cdf0e10cSrcweir pFont->m_nYMin = aInfo.yMin; 1992cdf0e10cSrcweir pFont->m_nXMax = aInfo.xMax; 1993cdf0e10cSrcweir pFont->m_nYMax = aInfo.yMax; 1994cdf0e10cSrcweir 1995cdf0e10cSrcweir // get type flags 1996cdf0e10cSrcweir pTTFontFile->m_nTypeFlags = (unsigned int)aInfo.typeFlags; 1997cdf0e10cSrcweir 1998cdf0e10cSrcweir // get vertical substitutions flag 1999cdf0e10cSrcweir pFont->m_bHaveVerticalSubstitutedGlyphs = DoesVerticalSubstitution( pTTFont, 1 ); 2000cdf0e10cSrcweir 2001cdf0e10cSrcweir CloseTTFont( pTTFont ); 2002cdf0e10cSrcweir bSuccess = true; 2003cdf0e10cSrcweir } 2004cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 2005cdf0e10cSrcweir else 2006cdf0e10cSrcweir fprintf( stderr, "could not OpenTTFont \"%s\"\n", aFile.GetBuffer() ); 2007cdf0e10cSrcweir #endif 2008cdf0e10cSrcweir 2009cdf0e10cSrcweir return bSuccess; 2010cdf0e10cSrcweir } 2011cdf0e10cSrcweir 2012cdf0e10cSrcweir // ------------------------------------------------------------------------- 2013cdf0e10cSrcweir 2014cdf0e10cSrcweir void PrintFontManager::initFontsAlias() 2015cdf0e10cSrcweir { 2016cdf0e10cSrcweir m_aXLFD_Aliases.clear(); 2017cdf0e10cSrcweir rtl_TextEncoding aEnc = osl_getThreadTextEncoding(); 2018cdf0e10cSrcweir for( std::list< OString >::const_iterator dir_it = m_aFontDirectories.begin(); 2019cdf0e10cSrcweir dir_it != m_aFontDirectories.end(); ++dir_it ) 2020cdf0e10cSrcweir { 2021cdf0e10cSrcweir OStringBuffer aDirName(512); 2022cdf0e10cSrcweir aDirName.append( *dir_it ); 2023cdf0e10cSrcweir aDirName.append( "/fonts.alias" ); 2024cdf0e10cSrcweir SvFileStream aStream( OStringToOUString( aDirName.makeStringAndClear(), aEnc ), STREAM_READ ); 2025cdf0e10cSrcweir if( ! aStream.IsOpen() ) 2026cdf0e10cSrcweir continue; 2027cdf0e10cSrcweir 2028cdf0e10cSrcweir do 2029cdf0e10cSrcweir { 2030cdf0e10cSrcweir ByteString aLine; 2031cdf0e10cSrcweir aStream.ReadLine( aLine ); 2032cdf0e10cSrcweir 2033cdf0e10cSrcweir // get the alias and the pattern it gets translated to 2034cdf0e10cSrcweir ByteString aAlias = GetCommandLineToken( 0, aLine ); 2035cdf0e10cSrcweir ByteString aMap = GetCommandLineToken( 1, aLine ); 2036cdf0e10cSrcweir 2037cdf0e10cSrcweir // remove eventual quotes 2038cdf0e10cSrcweir aAlias.EraseLeadingChars( '"' ); 2039cdf0e10cSrcweir aAlias.EraseTrailingChars( '"' ); 2040cdf0e10cSrcweir aMap.EraseLeadingChars( '"' ); 2041cdf0e10cSrcweir aMap.EraseTrailingChars( '"' ); 2042cdf0e10cSrcweir 2043cdf0e10cSrcweir XLFDEntry aAliasEntry, aMapEntry; 2044cdf0e10cSrcweir parseXLFD( aAlias, aAliasEntry ); 2045cdf0e10cSrcweir parseXLFD( aMap, aMapEntry ); 2046cdf0e10cSrcweir 2047cdf0e10cSrcweir if( aAliasEntry.nMask && aMapEntry.nMask ) 2048cdf0e10cSrcweir m_aXLFD_Aliases[ aMapEntry ].push_back( aAliasEntry ); 2049cdf0e10cSrcweir } while( ! aStream.IsEof() ); 2050cdf0e10cSrcweir } 2051cdf0e10cSrcweir } 2052cdf0e10cSrcweir 2053cdf0e10cSrcweir // code stolen from vcl's RegisterFontSubstitutors() 2054cdf0e10cSrcweir // TODO: use that method once psprint gets merged into vcl 2055cdf0e10cSrcweir static bool AreFCSubstitutionsEnabled() 2056cdf0e10cSrcweir { 2057cdf0e10cSrcweir // init font substitution defaults 2058cdf0e10cSrcweir int nDisableBits = 0; 2059cdf0e10cSrcweir #ifdef SOLARIS 2060cdf0e10cSrcweir // TODO: check the OS version and fc-data maintenance level 2061cdf0e10cSrcweir nDisableBits = 1; // disable "font fallback" here on default 2062cdf0e10cSrcweir #endif 2063cdf0e10cSrcweir // apply the environment variable if any 2064cdf0e10cSrcweir const char* pEnvStr = ::getenv( "SAL_DISABLE_FC_SUBST" ); 2065cdf0e10cSrcweir if( pEnvStr ) 2066cdf0e10cSrcweir { 2067cdf0e10cSrcweir // 2068cdf0e10cSrcweir if( (*pEnvStr >= '0') && (*pEnvStr <= '9') ) 2069cdf0e10cSrcweir nDisableBits = (*pEnvStr - '0'); 2070cdf0e10cSrcweir else 2071cdf0e10cSrcweir nDisableBits = ~0U; // no specific bits set: disable all 2072cdf0e10cSrcweir } 2073cdf0e10cSrcweir 2074cdf0e10cSrcweir return ((nDisableBits & 3) == 0); 2075cdf0e10cSrcweir } 2076cdf0e10cSrcweir 2077cdf0e10cSrcweir void PrintFontManager::initialize() 2078cdf0e10cSrcweir { 2079cdf0e10cSrcweir #ifdef CALLGRIND_COMPILE 2080cdf0e10cSrcweir CALLGRIND_TOGGLE_COLLECT(); 2081cdf0e10cSrcweir CALLGRIND_ZERO_STATS(); 2082cdf0e10cSrcweir #endif 2083cdf0e10cSrcweir 2084cdf0e10cSrcweir long aDirEntBuffer[ (sizeof(struct dirent)+_PC_NAME_MAX)+1 ]; 2085cdf0e10cSrcweir 2086cdf0e10cSrcweir if( ! m_pFontCache ) 2087cdf0e10cSrcweir { 2088cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 2089cdf0e10cSrcweir fprintf( stderr, "creating font cache ... " ); 2090cdf0e10cSrcweir clock_t aStart; 2091cdf0e10cSrcweir struct tms tms; 2092cdf0e10cSrcweir aStart = times( &tms ); 2093cdf0e10cSrcweir #endif 2094cdf0e10cSrcweir m_pFontCache = new FontCache(); 2095cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 2096cdf0e10cSrcweir clock_t aStop = times( &tms ); 2097cdf0e10cSrcweir fprintf( stderr, "done in %lf s\n", (double)(aStop - aStart)/(double)sysconf( _SC_CLK_TCK ) ); 2098cdf0e10cSrcweir #endif 2099cdf0e10cSrcweir } 2100cdf0e10cSrcweir 2101cdf0e10cSrcweir // initialize may be called twice in the future 2102cdf0e10cSrcweir { 2103cdf0e10cSrcweir for( ::std::hash_map< fontID, PrintFont* >::const_iterator it = m_aFonts.begin(); it != m_aFonts.end(); ++it ) 2104cdf0e10cSrcweir delete (*it).second; 2105cdf0e10cSrcweir m_nNextFontID = 1; 2106cdf0e10cSrcweir m_aFonts.clear(); 2107cdf0e10cSrcweir m_aFontDirectories.clear(); 2108cdf0e10cSrcweir m_aPrivateFontDirectories.clear(); 2109cdf0e10cSrcweir m_aOverrideFonts.clear(); 2110cdf0e10cSrcweir } 2111cdf0e10cSrcweir 2112cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 2113cdf0e10cSrcweir clock_t aStart; 2114cdf0e10cSrcweir clock_t aStep1; 2115cdf0e10cSrcweir clock_t aStep2; 2116cdf0e10cSrcweir clock_t aStep3; 2117cdf0e10cSrcweir int nBuiltinFonts = 0; 2118cdf0e10cSrcweir int nCached = 0; 2119cdf0e10cSrcweir 2120cdf0e10cSrcweir struct tms tms; 2121cdf0e10cSrcweir 2122cdf0e10cSrcweir aStart = times( &tms ); 2123cdf0e10cSrcweir #endif 2124cdf0e10cSrcweir 2125cdf0e10cSrcweir // first try fontconfig 2126cdf0e10cSrcweir m_bFontconfigSuccess = initFontconfig(); 2127cdf0e10cSrcweir 2128cdf0e10cSrcweir // part one - look for downloadable fonts 2129cdf0e10cSrcweir rtl_TextEncoding aEncoding = osl_getThreadTextEncoding(); 2130cdf0e10cSrcweir const ::rtl::OUString &rSalPrivatePath = psp::getFontPath(); 2131cdf0e10cSrcweir 2132cdf0e10cSrcweir // search for the fonts in SAL_PRIVATE_FONTPATH first; those are 2133cdf0e10cSrcweir // the fonts installed with the office 2134cdf0e10cSrcweir if( rSalPrivatePath.getLength() ) 2135cdf0e10cSrcweir { 2136cdf0e10cSrcweir OString aPath = rtl::OUStringToOString( rSalPrivatePath, aEncoding ); 2137cdf0e10cSrcweir const bool bAreFCSubstitutionsEnabled = AreFCSubstitutionsEnabled(); 2138cdf0e10cSrcweir sal_Int32 nIndex = 0; 2139cdf0e10cSrcweir do 2140cdf0e10cSrcweir { 2141cdf0e10cSrcweir OString aToken = aPath.getToken( 0, ';', nIndex ); 2142cdf0e10cSrcweir normPath( aToken ); 2143cdf0e10cSrcweir // if registering an app-specific fontdir with fontconfig fails 2144cdf0e10cSrcweir // and fontconfig-based substitutions are enabled 2145cdf0e10cSrcweir // then trying to use these app-specific fonts doesn't make sense 2146cdf0e10cSrcweir if( m_bFontconfigSuccess && !addFontconfigDir( aToken ) ) 2147cdf0e10cSrcweir if( bAreFCSubstitutionsEnabled ) 2148cdf0e10cSrcweir continue; 2149cdf0e10cSrcweir m_aFontDirectories.push_back( aToken ); 2150cdf0e10cSrcweir m_aPrivateFontDirectories.push_back( getDirectoryAtom( aToken, true ) ); 2151cdf0e10cSrcweir } while( nIndex >= 0 ); 2152cdf0e10cSrcweir } 2153cdf0e10cSrcweir 2154cdf0e10cSrcweir // protect against duplicate paths 2155cdf0e10cSrcweir std::hash_map< OString, int, OStringHash > visited_dirs; 2156cdf0e10cSrcweir 2157cdf0e10cSrcweir // now that all global and local font dirs are known to fontconfig 2158cdf0e10cSrcweir // check that there are fonts actually managed by fontconfig 2159cdf0e10cSrcweir // also don't search directories that fontconfig already did 2160cdf0e10cSrcweir if( m_bFontconfigSuccess ) 2161cdf0e10cSrcweir m_bFontconfigSuccess = (countFontconfigFonts( visited_dirs ) > 0); 2162cdf0e10cSrcweir 2163cdf0e10cSrcweir // don't search through many directories fontconfig already told us about 2164cdf0e10cSrcweir if( ! m_bFontconfigSuccess ) 2165cdf0e10cSrcweir ImplGetSVData()->mpDefInst->FillFontPathList( m_aFontDirectories ); 2166cdf0e10cSrcweir 2167cdf0e10cSrcweir // fill XLFD aliases from fonts.alias files 2168cdf0e10cSrcweir initFontsAlias(); 2169cdf0e10cSrcweir 2170cdf0e10cSrcweir // search for font files in each path 2171cdf0e10cSrcweir std::list< OString >::iterator dir_it; 2172cdf0e10cSrcweir for( dir_it = m_aFontDirectories.begin(); dir_it != m_aFontDirectories.end(); ++dir_it ) 2173cdf0e10cSrcweir { 2174cdf0e10cSrcweir OString aPath( *dir_it ); 2175cdf0e10cSrcweir // see if we were here already 2176cdf0e10cSrcweir if( visited_dirs.find( aPath ) != visited_dirs.end() ) 2177cdf0e10cSrcweir continue; 2178cdf0e10cSrcweir visited_dirs[ aPath ] = 1; 2179cdf0e10cSrcweir 2180cdf0e10cSrcweir // there may be ":unscaled" directories (see XFree86) 2181cdf0e10cSrcweir // it should be safe to ignore them since they should not 2182cdf0e10cSrcweir // contain any of our recognizeable fonts 2183cdf0e10cSrcweir 2184cdf0e10cSrcweir // ask the font cache whether it handles this directory 2185cdf0e10cSrcweir std::list< PrintFont* > aCacheFonts; 2186cdf0e10cSrcweir if( m_pFontCache->listDirectory( aPath, aCacheFonts ) ) 2187cdf0e10cSrcweir { 2188cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 2189cdf0e10cSrcweir fprintf( stderr, "adding cache directory: %s\n", aPath.getStr() ); 2190cdf0e10cSrcweir #endif 2191cdf0e10cSrcweir for( ::std::list< PrintFont* >::iterator it = aCacheFonts.begin(); it != aCacheFonts.end(); ++it ) 2192cdf0e10cSrcweir { 2193cdf0e10cSrcweir fontID aFont = m_nNextFontID++; 2194cdf0e10cSrcweir m_aFonts[ aFont ] = *it; 2195cdf0e10cSrcweir if( (*it)->m_eType == fonttype::Type1 ) 2196cdf0e10cSrcweir m_aFontFileToFontID[ static_cast<Type1FontFile*>(*it)->m_aFontFile ].insert( aFont ); 2197cdf0e10cSrcweir else if( (*it)->m_eType == fonttype::TrueType ) 2198cdf0e10cSrcweir m_aFontFileToFontID[ static_cast<TrueTypeFontFile*>(*it)->m_aFontFile ].insert( aFont ); 2199cdf0e10cSrcweir else if( (*it)->m_eType == fonttype::Builtin ) 2200cdf0e10cSrcweir m_aFontFileToFontID[ static_cast<BuiltinFont*>(*it)->m_aMetricFile ].insert( aFont ); 2201cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 2202cdf0e10cSrcweir if( (*it)->m_eType == fonttype::Builtin ) 2203cdf0e10cSrcweir nBuiltinFonts++; 2204cdf0e10cSrcweir nCached++; 2205cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 2 2206cdf0e10cSrcweir fprintf( stderr, "adding cached font %d: \"%s\" from %s\n", aFont, 2207cdf0e10cSrcweir OUStringToOString( getFontFamily( aFont ), RTL_TEXTENCODING_MS_1252 ).getStr(), 2208cdf0e10cSrcweir getFontFileSysPath( aFont ).getStr() ); 2209cdf0e10cSrcweir #endif 2210cdf0e10cSrcweir #endif 2211cdf0e10cSrcweir } 2212cdf0e10cSrcweir if( ! m_pFontCache->scanAdditionalFiles( aPath ) ) 2213cdf0e10cSrcweir continue; 2214cdf0e10cSrcweir } 2215cdf0e10cSrcweir 2216cdf0e10cSrcweir DIR* pDIR = opendir( aPath.getStr() ); 2217cdf0e10cSrcweir struct dirent* pEntry = (struct dirent*)aDirEntBuffer; 2218cdf0e10cSrcweir if( pDIR ) 2219cdf0e10cSrcweir { 2220cdf0e10cSrcweir // read fonts.dir if possible 2221cdf0e10cSrcweir ::std::hash_map< OString, ::std::list<OString>, OStringHash > aFontsDir; 2222cdf0e10cSrcweir int nDirID = getDirectoryAtom( aPath, true ); 2223cdf0e10cSrcweir // #i38367# no fonts.dir in our own directories anymore 2224cdf0e10cSrcweir std::list< int >::const_iterator priv_dir; 2225cdf0e10cSrcweir for( priv_dir = m_aPrivateFontDirectories.begin(); 2226cdf0e10cSrcweir priv_dir != m_aPrivateFontDirectories.end() && *priv_dir != nDirID; 2227cdf0e10cSrcweir ++priv_dir ) 2228cdf0e10cSrcweir ; 2229cdf0e10cSrcweir 2230cdf0e10cSrcweir if( priv_dir == m_aPrivateFontDirectories.end() ) 2231cdf0e10cSrcweir { 2232cdf0e10cSrcweir ByteString aGccDummy( aPath ); 2233cdf0e10cSrcweir String aFontsDirPath( aGccDummy, aEncoding ); 2234cdf0e10cSrcweir aFontsDirPath.AppendAscii( "/fonts.dir" ); 2235cdf0e10cSrcweir SvFileStream aStream( aFontsDirPath, STREAM_READ ); 2236cdf0e10cSrcweir if( aStream.IsOpen() ) 2237cdf0e10cSrcweir { 2238cdf0e10cSrcweir ByteString aLine; 2239cdf0e10cSrcweir while( ! aStream.IsEof() ) 2240cdf0e10cSrcweir { 2241cdf0e10cSrcweir aStream.ReadLine( aLine ); 2242cdf0e10cSrcweir ByteString aFileName( GetCommandLineToken( 0, aLine ) ); 2243cdf0e10cSrcweir ByteString aXLFD( aLine.Copy( aFileName.Len() ) ); 2244cdf0e10cSrcweir if( aFileName.Len() && aXLFD.Len() ) 2245cdf0e10cSrcweir aFontsDir[ aFileName ].push_back(aXLFD); 2246cdf0e10cSrcweir } 2247cdf0e10cSrcweir } 2248cdf0e10cSrcweir } 2249cdf0e10cSrcweir 2250cdf0e10cSrcweir int nDirFonts = 0; 2251cdf0e10cSrcweir while( ! readdir_r( pDIR, (struct dirent*)aDirEntBuffer, &pEntry ) && pEntry ) 2252cdf0e10cSrcweir { 2253cdf0e10cSrcweir OString aFileName( pEntry->d_name ); 2254cdf0e10cSrcweir // ignore .afm files here 2255cdf0e10cSrcweir if( aFileName.getLength() > 3 && 2256cdf0e10cSrcweir aFileName.lastIndexOf( ".afm" ) == aFileName.getLength()-4 ) 2257cdf0e10cSrcweir continue; 2258cdf0e10cSrcweir 2259cdf0e10cSrcweir struct stat aStat; 2260cdf0e10cSrcweir ByteString aFilePath( aPath ); 2261cdf0e10cSrcweir aFilePath.Append( '/' ); 2262cdf0e10cSrcweir aFilePath.Append( ByteString( aFileName ) ); 2263cdf0e10cSrcweir if( ! stat( aFilePath.GetBuffer(), &aStat ) && 2264cdf0e10cSrcweir S_ISREG( aStat.st_mode ) ) 2265cdf0e10cSrcweir { 2266cdf0e10cSrcweir if( findFontFileID( nDirID, aFileName ) == 0 ) 2267cdf0e10cSrcweir { 2268cdf0e10cSrcweir ::std::list<OString> aXLFDs; 2269cdf0e10cSrcweir ::std::hash_map< OString, ::std::list<OString>, OStringHash >::const_iterator it = 2270cdf0e10cSrcweir aFontsDir.find( aFileName ); 2271cdf0e10cSrcweir if( it != aFontsDir.end() ) 2272cdf0e10cSrcweir aXLFDs = (*it).second; 2273cdf0e10cSrcweir 2274cdf0e10cSrcweir // fill in font attributes from XLFD rather 2275cdf0e10cSrcweir // than reading every file 2276cdf0e10cSrcweir ::std::list< PrintFont* > aNewFonts; 2277cdf0e10cSrcweir if( analyzeFontFile( nDirID, aFileName, aXLFDs, aNewFonts ) ) 2278cdf0e10cSrcweir { 2279cdf0e10cSrcweir for( ::std::list< PrintFont* >::iterator font_it = aNewFonts.begin(); font_it != aNewFonts.end(); ++font_it ) 2280cdf0e10cSrcweir { 2281cdf0e10cSrcweir fontID aFont = m_nNextFontID++; 2282cdf0e10cSrcweir m_aFonts[ aFont ] = *font_it; 2283cdf0e10cSrcweir m_aFontFileToFontID[ aFileName ].insert( aFont ); 2284cdf0e10cSrcweir m_pFontCache->updateFontCacheEntry( *font_it, false ); 2285cdf0e10cSrcweir nDirFonts++; 2286cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 2 2287cdf0e10cSrcweir fprintf( stderr, "adding font %d: \"%s\" from %s\n", aFont, 2288cdf0e10cSrcweir OUStringToOString( getFontFamily( aFont ), RTL_TEXTENCODING_MS_1252 ).getStr(), 2289cdf0e10cSrcweir getFontFileSysPath( aFont ).getStr() ); 2290cdf0e10cSrcweir #endif 2291cdf0e10cSrcweir } 2292cdf0e10cSrcweir } 2293cdf0e10cSrcweir } 2294cdf0e10cSrcweir } 2295cdf0e10cSrcweir } 2296cdf0e10cSrcweir closedir( pDIR ); 2297cdf0e10cSrcweir m_pFontCache->updateDirTimestamp( nDirID ); 2298cdf0e10cSrcweir if( ! nDirFonts ) 2299cdf0e10cSrcweir m_pFontCache->markEmptyDir( nDirID ); 2300cdf0e10cSrcweir } 2301cdf0e10cSrcweir } 2302cdf0e10cSrcweir 2303cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 2304cdf0e10cSrcweir aStep1 = times( &tms ); 2305cdf0e10cSrcweir #endif 2306cdf0e10cSrcweir 2307cdf0e10cSrcweir // part two - look for metrics for builtin printer fonts 2308cdf0e10cSrcweir std::list< OUString > aMetricDirs; 2309cdf0e10cSrcweir psp::getPrinterPathList( aMetricDirs, PRINTER_METRICDIR ); 2310cdf0e10cSrcweir 2311cdf0e10cSrcweir std::list< OString > aEmptyFontsDir; 2312cdf0e10cSrcweir for( std::list< OUString >::const_iterator met_dir_it = aMetricDirs.begin(); met_dir_it != aMetricDirs.end(); ++met_dir_it ) 2313cdf0e10cSrcweir { 2314cdf0e10cSrcweir OString aDir = OUStringToOString( *met_dir_it, aEncoding ); 2315cdf0e10cSrcweir 2316cdf0e10cSrcweir // ask the font cache whether it handles this directory 2317cdf0e10cSrcweir std::list< PrintFont* > aCacheFonts; 2318cdf0e10cSrcweir 2319cdf0e10cSrcweir if( m_pFontCache->listDirectory( aDir, aCacheFonts ) ) 2320cdf0e10cSrcweir { 2321cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 2322cdf0e10cSrcweir fprintf( stderr, "adding cache directory: %s\n", aDir.getStr() ); 2323cdf0e10cSrcweir #endif 2324cdf0e10cSrcweir for( ::std::list< PrintFont* >::iterator it = aCacheFonts.begin(); it != aCacheFonts.end(); ++it ) 2325cdf0e10cSrcweir { 2326cdf0e10cSrcweir fontID aFont = m_nNextFontID++; 2327cdf0e10cSrcweir m_aFonts[ aFont ] = *it; 2328cdf0e10cSrcweir if( (*it)->m_eType == fonttype::Type1 ) 2329cdf0e10cSrcweir m_aFontFileToFontID[ static_cast<Type1FontFile*>(*it)->m_aFontFile ].insert( aFont ); 2330cdf0e10cSrcweir else if( (*it)->m_eType == fonttype::TrueType ) 2331cdf0e10cSrcweir m_aFontFileToFontID[ static_cast<TrueTypeFontFile*>(*it)->m_aFontFile ].insert( aFont ); 2332cdf0e10cSrcweir else if( (*it)->m_eType == fonttype::Builtin ) 2333cdf0e10cSrcweir m_aFontFileToFontID[ static_cast<BuiltinFont*>(*it)->m_aMetricFile ].insert( aFont ); 2334cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 2335cdf0e10cSrcweir if( (*it)->m_eType == fonttype::Builtin ) 2336cdf0e10cSrcweir nBuiltinFonts++; 2337cdf0e10cSrcweir nCached++; 2338cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 2 2339cdf0e10cSrcweir fprintf( stderr, "adding cached font %d: \"%s\" from %s\n", aFont, 2340cdf0e10cSrcweir OUStringToOString( getFontFamily( aFont ), RTL_TEXTENCODING_MS_1252 ).getStr(), 2341cdf0e10cSrcweir getFontFileSysPath( aFont ).getStr() ); 2342cdf0e10cSrcweir #endif 2343cdf0e10cSrcweir #endif 2344cdf0e10cSrcweir } 2345cdf0e10cSrcweir continue; 2346cdf0e10cSrcweir } 2347cdf0e10cSrcweir 2348cdf0e10cSrcweir DIR* pDIR = opendir( aDir.getStr() ); 2349cdf0e10cSrcweir if( pDIR ) 2350cdf0e10cSrcweir { 2351cdf0e10cSrcweir struct dirent* pDirEntry = (struct dirent*)aDirEntBuffer; 2352cdf0e10cSrcweir int nDirID = getDirectoryAtom( aDir, true ); 2353cdf0e10cSrcweir int nDirFonts = 0; 2354cdf0e10cSrcweir 2355cdf0e10cSrcweir while( ! readdir_r( pDIR, (struct dirent*)aDirEntBuffer, &pDirEntry ) && pDirEntry ) 2356cdf0e10cSrcweir { 2357cdf0e10cSrcweir ByteString aFile( aDir ); 2358cdf0e10cSrcweir aFile += '/'; 2359cdf0e10cSrcweir aFile += pDirEntry->d_name; 2360cdf0e10cSrcweir struct stat aStat; 2361cdf0e10cSrcweir if( ! stat( aFile.GetBuffer(), &aStat ) 2362cdf0e10cSrcweir && S_ISREG( aStat.st_mode ) 2363cdf0e10cSrcweir ) 2364cdf0e10cSrcweir { 2365cdf0e10cSrcweir OString aFileName( pDirEntry->d_name, strlen( pDirEntry->d_name ) ); 2366cdf0e10cSrcweir OString aExt( aFileName.copy( aFileName.lastIndexOf( '.' )+1 ) ); 2367cdf0e10cSrcweir if( aExt.equalsIgnoreAsciiCase( "afm" ) ) 2368cdf0e10cSrcweir { 2369cdf0e10cSrcweir ::std::list< PrintFont* > aNewFonts; 2370cdf0e10cSrcweir 2371cdf0e10cSrcweir analyzeFontFile( nDirID, aFileName, aEmptyFontsDir, aNewFonts ); 2372cdf0e10cSrcweir for( ::std::list< PrintFont* >::iterator it = aNewFonts.begin(); it != aNewFonts.end(); ++it ) 2373cdf0e10cSrcweir { 2374cdf0e10cSrcweir if( findFontBuiltinID( (*it)->m_nPSName ) == 0 ) 2375cdf0e10cSrcweir { 2376cdf0e10cSrcweir m_aFontFileToFontID[ aFileName ].insert( m_nNextFontID ); 2377cdf0e10cSrcweir m_aFonts[ m_nNextFontID++ ] = *it; 2378cdf0e10cSrcweir m_pFontCache->updateFontCacheEntry( *it, false ); 2379cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 2 2380cdf0e10cSrcweir nBuiltinFonts++; 2381cdf0e10cSrcweir #endif 2382cdf0e10cSrcweir } 2383cdf0e10cSrcweir else 2384cdf0e10cSrcweir delete *it; 2385cdf0e10cSrcweir } 2386cdf0e10cSrcweir } 2387cdf0e10cSrcweir } 2388cdf0e10cSrcweir } 2389cdf0e10cSrcweir closedir( pDIR ); 2390cdf0e10cSrcweir if( ! nDirFonts ) 2391cdf0e10cSrcweir m_pFontCache->markEmptyDir( nDirID ); 2392cdf0e10cSrcweir } 2393cdf0e10cSrcweir } 2394cdf0e10cSrcweir 2395cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 2396cdf0e10cSrcweir aStep2 = times( &tms ); 2397cdf0e10cSrcweir #endif 2398cdf0e10cSrcweir 2399cdf0e10cSrcweir // part three - fill in family styles 2400cdf0e10cSrcweir ::std::hash_map< fontID, PrintFont* >::iterator font_it; 2401cdf0e10cSrcweir for (font_it = m_aFonts.begin(); font_it != m_aFonts.end(); ++font_it) 2402cdf0e10cSrcweir { 2403cdf0e10cSrcweir ::std::hash_map< int, family::type >::const_iterator it = 2404cdf0e10cSrcweir m_aFamilyTypes.find( font_it->second->m_nFamilyName ); 2405cdf0e10cSrcweir if (it != m_aFamilyTypes.end()) 2406cdf0e10cSrcweir continue; 2407cdf0e10cSrcweir const ::rtl::OUString& rFamily = 2408cdf0e10cSrcweir m_pAtoms->getString( ATOM_FAMILYNAME, font_it->second->m_nFamilyName); 2409cdf0e10cSrcweir family::type eType = matchFamilyName( rFamily ); 2410cdf0e10cSrcweir m_aFamilyTypes[ font_it->second->m_nFamilyName ] = eType; 2411cdf0e10cSrcweir } 2412cdf0e10cSrcweir 2413cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 2414cdf0e10cSrcweir aStep3 = times( &tms ); 2415cdf0e10cSrcweir fprintf( stderr, "PrintFontManager::initialize: collected %d fonts (%d builtin, %d cached)\n", m_aFonts.size(), nBuiltinFonts, nCached ); 2416cdf0e10cSrcweir double fTick = (double)sysconf( _SC_CLK_TCK ); 2417cdf0e10cSrcweir fprintf( stderr, "Step 1 took %lf seconds\n", (double)(aStep1 - aStart)/fTick ); 2418cdf0e10cSrcweir fprintf( stderr, "Step 2 took %lf seconds\n", (double)(aStep2 - aStep1)/fTick ); 2419cdf0e10cSrcweir fprintf( stderr, "Step 3 took %lf seconds\n", (double)(aStep3 - aStep2)/fTick ); 2420cdf0e10cSrcweir #endif 2421cdf0e10cSrcweir 2422cdf0e10cSrcweir m_pFontCache->flush(); 2423cdf0e10cSrcweir 2424cdf0e10cSrcweir #ifdef CALLGRIND_COMPILE 2425cdf0e10cSrcweir CALLGRIND_DUMP_STATS(); 2426cdf0e10cSrcweir CALLGRIND_TOGGLE_COLLECT(); 2427cdf0e10cSrcweir #endif 2428cdf0e10cSrcweir } 2429cdf0e10cSrcweir 2430cdf0e10cSrcweir // ------------------------------------------------------------------------- 2431cdf0e10cSrcweir inline bool 2432cdf0e10cSrcweir equalPitch (psp::pitch::type from, psp::pitch::type to) 2433cdf0e10cSrcweir { 2434cdf0e10cSrcweir return from == to; 2435cdf0e10cSrcweir } 2436cdf0e10cSrcweir 2437cdf0e10cSrcweir inline bool 2438cdf0e10cSrcweir equalWeight (psp::weight::type from, psp::weight::type to) 2439cdf0e10cSrcweir { 2440cdf0e10cSrcweir return from > to ? (from - to) <= 3 : (to - from) <= 3; 2441cdf0e10cSrcweir } 2442cdf0e10cSrcweir 2443cdf0e10cSrcweir inline bool 2444cdf0e10cSrcweir equalItalic (psp::italic::type from, psp::italic::type to) 2445cdf0e10cSrcweir { 2446cdf0e10cSrcweir if ( (from == psp::italic::Italic) || (from == psp::italic::Oblique) ) 2447cdf0e10cSrcweir return (to == psp::italic::Italic) || (to == psp::italic::Oblique); 2448cdf0e10cSrcweir return to == from; 2449cdf0e10cSrcweir } 2450cdf0e10cSrcweir inline bool 2451cdf0e10cSrcweir equalEncoding (rtl_TextEncoding from, rtl_TextEncoding to) 2452cdf0e10cSrcweir { 2453cdf0e10cSrcweir if ((from == RTL_TEXTENCODING_ISO_8859_1) || (from == RTL_TEXTENCODING_MS_1252)) 2454cdf0e10cSrcweir return (to == RTL_TEXTENCODING_ISO_8859_1) || (to == RTL_TEXTENCODING_MS_1252); 2455cdf0e10cSrcweir return from == to; 2456cdf0e10cSrcweir } 2457cdf0e10cSrcweir 2458cdf0e10cSrcweir namespace { 2459cdf0e10cSrcweir struct BuiltinFontIdentifier 2460cdf0e10cSrcweir { 2461cdf0e10cSrcweir OUString aFamily; 2462cdf0e10cSrcweir italic::type eItalic; 2463cdf0e10cSrcweir weight::type eWeight; 2464cdf0e10cSrcweir pitch::type ePitch; 2465cdf0e10cSrcweir rtl_TextEncoding aEncoding; 2466cdf0e10cSrcweir 2467cdf0e10cSrcweir BuiltinFontIdentifier( const OUString& rFam, 2468cdf0e10cSrcweir italic::type eIt, 2469cdf0e10cSrcweir weight::type eWg, 2470cdf0e10cSrcweir pitch::type ePt, 2471cdf0e10cSrcweir rtl_TextEncoding enc ) : 2472cdf0e10cSrcweir aFamily( rFam ), 2473cdf0e10cSrcweir eItalic( eIt ), 2474cdf0e10cSrcweir eWeight( eWg ), 2475cdf0e10cSrcweir ePitch( ePt ), 2476cdf0e10cSrcweir aEncoding( enc ) 2477cdf0e10cSrcweir {} 2478cdf0e10cSrcweir 2479cdf0e10cSrcweir bool operator==( const BuiltinFontIdentifier& rRight ) const 2480cdf0e10cSrcweir { 2481cdf0e10cSrcweir return equalItalic( eItalic, rRight.eItalic ) && 2482cdf0e10cSrcweir equalWeight( eWeight, rRight.eWeight ) && 2483cdf0e10cSrcweir equalPitch( ePitch, rRight.ePitch ) && 2484cdf0e10cSrcweir equalEncoding( aEncoding, rRight.aEncoding ) && 2485cdf0e10cSrcweir aFamily.equalsIgnoreAsciiCase( rRight.aFamily ); 2486cdf0e10cSrcweir } 2487cdf0e10cSrcweir }; 2488cdf0e10cSrcweir 2489cdf0e10cSrcweir struct BuiltinFontIdentifierHash 2490cdf0e10cSrcweir { 2491cdf0e10cSrcweir size_t operator()( const BuiltinFontIdentifier& rFont ) const 2492cdf0e10cSrcweir { 2493cdf0e10cSrcweir return rFont.aFamily.hashCode() ^ rFont.eItalic ^ rFont.eWeight ^ rFont.ePitch ^ rFont.aEncoding; 2494cdf0e10cSrcweir } 2495cdf0e10cSrcweir }; 2496cdf0e10cSrcweir } 2497cdf0e10cSrcweir 2498cdf0e10cSrcweir void PrintFontManager::getFontList( ::std::list< fontID >& rFontIDs, const PPDParser* pParser, bool bUseOverrideMetrics ) 2499cdf0e10cSrcweir { 2500cdf0e10cSrcweir rFontIDs.clear(); 2501cdf0e10cSrcweir std::hash_map< fontID, PrintFont* >::const_iterator it; 2502cdf0e10cSrcweir 2503cdf0e10cSrcweir /* 2504cdf0e10cSrcweir * Note: there are two easy steps making this faster: 2505cdf0e10cSrcweir * first: insert the printer builtins first, then the not builtins, 2506cdf0e10cSrcweir * if they do not match. 2507cdf0e10cSrcweir * drawback: this would change the sequence of fonts; this could have 2508cdf0e10cSrcweir * subtle, unknown consequences in vcl font matching 2509cdf0e10cSrcweir * second: instead of comparing attributes to see whether a softfont 2510cdf0e10cSrcweir * is duplicate to a builtin one could simply compare the PSName (which is 2511cdf0e10cSrcweir * supposed to be unique), which at this point is just an int. 2512cdf0e10cSrcweir * drawback: this could change which fonts are listed; especially TrueType 2513cdf0e10cSrcweir * fonts often have a rather dubious PSName, so this could change the 2514cdf0e10cSrcweir * font list not so subtle. 2515cdf0e10cSrcweir * Until getFontList for a printer becomes a performance issue (which is 2516cdf0e10cSrcweir * currently not the case), best stay with the current algorithm. 2517cdf0e10cSrcweir */ 2518cdf0e10cSrcweir 2519cdf0e10cSrcweir // fill sets of printer supported fonts 2520cdf0e10cSrcweir if( pParser ) 2521cdf0e10cSrcweir { 2522cdf0e10cSrcweir std::set<int> aBuiltinPSNames; 2523cdf0e10cSrcweir std::hash_set< BuiltinFontIdentifier, 2524cdf0e10cSrcweir BuiltinFontIdentifierHash 2525cdf0e10cSrcweir > aBuiltinFonts; 2526cdf0e10cSrcweir 2527cdf0e10cSrcweir std::map<int, fontID > aOverridePSNames; 2528cdf0e10cSrcweir if( bUseOverrideMetrics ) 2529cdf0e10cSrcweir { 2530cdf0e10cSrcweir readOverrideMetrics(); 2531cdf0e10cSrcweir for( std::vector<fontID>::const_iterator over = m_aOverrideFonts.begin(); 2532cdf0e10cSrcweir over != m_aOverrideFonts.end(); ++over ) 2533cdf0e10cSrcweir { 2534cdf0e10cSrcweir std::hash_map<fontID,PrintFont*>::const_iterator font_it = m_aFonts.find( *over ); 2535cdf0e10cSrcweir DBG_ASSERT( font_it != m_aFonts.end(), "override to nonexistant font" ); 2536cdf0e10cSrcweir if( font_it != m_aFonts.end() ) 2537cdf0e10cSrcweir aOverridePSNames[ font_it->second->m_nPSName ] = *over; 2538cdf0e10cSrcweir } 2539cdf0e10cSrcweir } 2540cdf0e10cSrcweir 2541cdf0e10cSrcweir int nFonts = pParser->getFonts(); 2542cdf0e10cSrcweir for( int i = 0; i < nFonts; i++ ) 2543cdf0e10cSrcweir aBuiltinPSNames.insert( m_pAtoms->getAtom( ATOM_PSNAME, pParser->getFont( i ) ) ); 2544cdf0e10cSrcweir for( it = m_aFonts.begin(); it != m_aFonts.end(); ++it ) 2545cdf0e10cSrcweir { 2546cdf0e10cSrcweir PrintFont* pFont = it->second; 2547cdf0e10cSrcweir if( it->second->m_eType == fonttype::Builtin && 2548cdf0e10cSrcweir aBuiltinPSNames.find( pFont->m_nPSName ) != aBuiltinPSNames.end() ) 2549cdf0e10cSrcweir { 2550cdf0e10cSrcweir bool bInsert = true; 2551cdf0e10cSrcweir if( bUseOverrideMetrics ) 2552cdf0e10cSrcweir { 2553cdf0e10cSrcweir // in override case only use the override fonts, not their counterparts 2554cdf0e10cSrcweir std::map<int,fontID>::const_iterator over = aOverridePSNames.find( pFont->m_nPSName ); 2555cdf0e10cSrcweir if( over != aOverridePSNames.end() && over->second != it->first ) 2556cdf0e10cSrcweir bInsert = false; 2557cdf0e10cSrcweir } 2558cdf0e10cSrcweir else 2559cdf0e10cSrcweir { 2560cdf0e10cSrcweir // do not insert override fonts in non override case 2561cdf0e10cSrcweir if( std::find( m_aOverrideFonts.begin(), m_aOverrideFonts.end(), it->first ) != m_aOverrideFonts.end() ) 2562cdf0e10cSrcweir bInsert = false; 2563cdf0e10cSrcweir } 2564cdf0e10cSrcweir if( bInsert ) 2565cdf0e10cSrcweir { 2566cdf0e10cSrcweir aBuiltinFonts.insert( BuiltinFontIdentifier( 2567cdf0e10cSrcweir m_pAtoms->getString( ATOM_FAMILYNAME, pFont->m_nFamilyName ), 2568cdf0e10cSrcweir pFont->m_eItalic, 2569cdf0e10cSrcweir pFont->m_eWeight, 2570cdf0e10cSrcweir pFont->m_ePitch, 2571cdf0e10cSrcweir pFont->m_aEncoding 2572cdf0e10cSrcweir ) ); 2573cdf0e10cSrcweir } 2574cdf0e10cSrcweir } 2575cdf0e10cSrcweir } 2576cdf0e10cSrcweir for( it = m_aFonts.begin(); it != m_aFonts.end(); ++it ) 2577cdf0e10cSrcweir { 2578cdf0e10cSrcweir PrintFont* pFont = it->second; 2579cdf0e10cSrcweir if( it->second->m_eType == fonttype::Builtin ) 2580cdf0e10cSrcweir { 2581cdf0e10cSrcweir if( aBuiltinPSNames.find( pFont->m_nPSName ) != aBuiltinPSNames.end() ) 2582cdf0e10cSrcweir { 2583cdf0e10cSrcweir bool bInsert = true; 2584cdf0e10cSrcweir if( bUseOverrideMetrics ) 2585cdf0e10cSrcweir { 2586cdf0e10cSrcweir // in override case only use the override fonts, not their counterparts 2587cdf0e10cSrcweir std::map<int,fontID>::const_iterator over = aOverridePSNames.find( pFont->m_nPSName ); 2588cdf0e10cSrcweir if( over != aOverridePSNames.end() && over->second != it->first ) 2589cdf0e10cSrcweir bInsert = false; 2590cdf0e10cSrcweir } 2591cdf0e10cSrcweir else 2592cdf0e10cSrcweir { 2593cdf0e10cSrcweir // do not insert override fonts in non override case 2594cdf0e10cSrcweir if( std::find( m_aOverrideFonts.begin(), m_aOverrideFonts.end(), it->first ) != m_aOverrideFonts.end() ) 2595cdf0e10cSrcweir bInsert = false; 2596cdf0e10cSrcweir } 2597cdf0e10cSrcweir if( bInsert ) 2598cdf0e10cSrcweir rFontIDs.push_back( it->first ); 2599cdf0e10cSrcweir } 2600cdf0e10cSrcweir } 2601cdf0e10cSrcweir else if( aBuiltinFonts.find( BuiltinFontIdentifier( 2602cdf0e10cSrcweir m_pAtoms->getString( ATOM_FAMILYNAME, pFont->m_nFamilyName ), 2603cdf0e10cSrcweir pFont->m_eItalic, 2604cdf0e10cSrcweir pFont->m_eWeight, 2605cdf0e10cSrcweir pFont->m_ePitch, 2606cdf0e10cSrcweir pFont->m_aEncoding 2607cdf0e10cSrcweir ) ) == aBuiltinFonts.end() ) 2608cdf0e10cSrcweir { 2609cdf0e10cSrcweir rFontIDs.push_back( it->first ); 2610cdf0e10cSrcweir } 2611cdf0e10cSrcweir } 2612cdf0e10cSrcweir } 2613cdf0e10cSrcweir else // no specific printer 2614cdf0e10cSrcweir { 2615cdf0e10cSrcweir for( it = m_aFonts.begin(); it != m_aFonts.end(); ++it ) 2616cdf0e10cSrcweir rFontIDs.push_back( it->first ); 2617cdf0e10cSrcweir } 2618cdf0e10cSrcweir } 2619cdf0e10cSrcweir 2620cdf0e10cSrcweir // ------------------------------------------------------------------------- 2621cdf0e10cSrcweir 2622cdf0e10cSrcweir void PrintFontManager::fillPrintFontInfo( PrintFont* pFont, FastPrintFontInfo& rInfo ) const 2623cdf0e10cSrcweir { 2624cdf0e10cSrcweir ::std::hash_map< int, family::type >::const_iterator style_it = 2625cdf0e10cSrcweir m_aFamilyTypes.find( pFont->m_nFamilyName ); 2626cdf0e10cSrcweir rInfo.m_eType = pFont->m_eType; 2627cdf0e10cSrcweir rInfo.m_aFamilyName = m_pAtoms->getString( ATOM_FAMILYNAME, pFont->m_nFamilyName ); 2628cdf0e10cSrcweir rInfo.m_aStyleName = pFont->m_aStyleName; 2629cdf0e10cSrcweir rInfo.m_eFamilyStyle = style_it != m_aFamilyTypes.end() ? style_it->second : family::Unknown; 2630cdf0e10cSrcweir rInfo.m_eItalic = pFont->m_eItalic; 2631cdf0e10cSrcweir rInfo.m_eWidth = pFont->m_eWidth; 2632cdf0e10cSrcweir rInfo.m_eWeight = pFont->m_eWeight; 2633cdf0e10cSrcweir rInfo.m_ePitch = pFont->m_ePitch; 2634cdf0e10cSrcweir rInfo.m_aEncoding = pFont->m_aEncoding; 2635cdf0e10cSrcweir 2636cdf0e10cSrcweir rInfo.m_bEmbeddable = (pFont->m_eType == fonttype::Type1); 2637cdf0e10cSrcweir rInfo.m_bSubsettable = (pFont->m_eType == fonttype::TrueType); // TODO: rename to SfntType 2638cdf0e10cSrcweir 2639cdf0e10cSrcweir rInfo.m_aAliases.clear(); 2640cdf0e10cSrcweir for( ::std::list< int >::iterator it = pFont->m_aAliases.begin(); it != pFont->m_aAliases.end(); ++it ) 2641cdf0e10cSrcweir rInfo.m_aAliases.push_back( m_pAtoms->getString( ATOM_FAMILYNAME, *it ) ); 2642cdf0e10cSrcweir } 2643cdf0e10cSrcweir 2644cdf0e10cSrcweir // ------------------------------------------------------------------------- 2645cdf0e10cSrcweir 2646cdf0e10cSrcweir void PrintFontManager::fillPrintFontInfo( PrintFont* pFont, PrintFontInfo& rInfo ) const 2647cdf0e10cSrcweir { 2648cdf0e10cSrcweir if( ( pFont->m_nAscend == 0 && pFont->m_nDescend == 0 ) || 2649cdf0e10cSrcweir ! pFont->m_pMetrics || pFont->m_pMetrics->isEmpty() 2650cdf0e10cSrcweir ) 2651cdf0e10cSrcweir { 2652cdf0e10cSrcweir // might be a truetype font not analyzed or type1 without metrics read 2653cdf0e10cSrcweir if( pFont->m_eType == fonttype::Type1 ) 2654cdf0e10cSrcweir pFont->readAfmMetrics( getAfmFile( pFont ), m_pAtoms, false, false ); 2655cdf0e10cSrcweir else if( pFont->m_eType == fonttype::TrueType ) 2656cdf0e10cSrcweir analyzeTrueTypeFile( pFont ); 2657cdf0e10cSrcweir } 2658cdf0e10cSrcweir 2659cdf0e10cSrcweir fillPrintFontInfo( pFont, static_cast< FastPrintFontInfo& >( rInfo ) ); 2660cdf0e10cSrcweir 2661cdf0e10cSrcweir rInfo.m_nAscend = pFont->m_nAscend; 2662cdf0e10cSrcweir rInfo.m_nDescend = pFont->m_nDescend; 2663cdf0e10cSrcweir rInfo.m_nLeading = pFont->m_nLeading; 2664cdf0e10cSrcweir rInfo.m_nWidth = pFont->m_aGlobalMetricX.width < pFont->m_aGlobalMetricY.width ? pFont->m_aGlobalMetricY.width : pFont->m_aGlobalMetricX.width; 2665cdf0e10cSrcweir } 2666cdf0e10cSrcweir 2667cdf0e10cSrcweir // ------------------------------------------------------------------------- 2668cdf0e10cSrcweir 2669cdf0e10cSrcweir void PrintFontManager::getFontListWithInfo( ::std::list< PrintFontInfo >& rFonts, const PPDParser* pParser, bool bUseOverrideMetrics ) 2670cdf0e10cSrcweir { 2671cdf0e10cSrcweir rFonts.clear(); 2672cdf0e10cSrcweir ::std::list< fontID > aFontList; 2673cdf0e10cSrcweir getFontList( aFontList, pParser, bUseOverrideMetrics ); 2674cdf0e10cSrcweir 2675cdf0e10cSrcweir ::std::list< fontID >::iterator it; 2676cdf0e10cSrcweir for( it = aFontList.begin(); it != aFontList.end(); ++it ) 2677cdf0e10cSrcweir { 2678cdf0e10cSrcweir PrintFontInfo aInfo; 2679cdf0e10cSrcweir aInfo.m_nID = *it; 2680cdf0e10cSrcweir fillPrintFontInfo( getFont( *it ), aInfo ); 2681cdf0e10cSrcweir rFonts.push_back( aInfo ); 2682cdf0e10cSrcweir } 2683cdf0e10cSrcweir } 2684cdf0e10cSrcweir 2685cdf0e10cSrcweir // ------------------------------------------------------------------------- 2686cdf0e10cSrcweir 2687cdf0e10cSrcweir void PrintFontManager::getFontListWithFastInfo( ::std::list< FastPrintFontInfo >& rFonts, const PPDParser* pParser, bool bUseOverrideMetrics ) 2688cdf0e10cSrcweir { 2689cdf0e10cSrcweir rFonts.clear(); 2690cdf0e10cSrcweir ::std::list< fontID > aFontList; 2691cdf0e10cSrcweir getFontList( aFontList, pParser, bUseOverrideMetrics ); 2692cdf0e10cSrcweir 2693cdf0e10cSrcweir ::std::list< fontID >::iterator it; 2694cdf0e10cSrcweir for( it = aFontList.begin(); it != aFontList.end(); ++it ) 2695cdf0e10cSrcweir { 2696cdf0e10cSrcweir FastPrintFontInfo aInfo; 2697cdf0e10cSrcweir aInfo.m_nID = *it; 2698cdf0e10cSrcweir fillPrintFontInfo( getFont( *it ), aInfo ); 2699cdf0e10cSrcweir rFonts.push_back( aInfo ); 2700cdf0e10cSrcweir } 2701cdf0e10cSrcweir } 2702cdf0e10cSrcweir 2703cdf0e10cSrcweir // ------------------------------------------------------------------------- 2704cdf0e10cSrcweir 2705cdf0e10cSrcweir bool PrintFontManager::getFontInfo( fontID nFontID, PrintFontInfo& rInfo ) const 2706cdf0e10cSrcweir { 2707cdf0e10cSrcweir PrintFont* pFont = getFont( nFontID ); 2708cdf0e10cSrcweir if( pFont ) 2709cdf0e10cSrcweir { 2710cdf0e10cSrcweir rInfo.m_nID = nFontID; 2711cdf0e10cSrcweir fillPrintFontInfo( pFont, rInfo ); 2712cdf0e10cSrcweir } 2713cdf0e10cSrcweir return pFont ? true : false; 2714cdf0e10cSrcweir } 2715cdf0e10cSrcweir 2716cdf0e10cSrcweir // ------------------------------------------------------------------------- 2717cdf0e10cSrcweir 2718cdf0e10cSrcweir bool PrintFontManager::getFontFastInfo( fontID nFontID, FastPrintFontInfo& rInfo ) const 2719cdf0e10cSrcweir { 2720cdf0e10cSrcweir PrintFont* pFont = getFont( nFontID ); 2721cdf0e10cSrcweir if( pFont ) 2722cdf0e10cSrcweir { 2723cdf0e10cSrcweir rInfo.m_nID = nFontID; 2724cdf0e10cSrcweir fillPrintFontInfo( pFont, rInfo ); 2725cdf0e10cSrcweir } 2726cdf0e10cSrcweir return pFont ? true : false; 2727cdf0e10cSrcweir } 2728cdf0e10cSrcweir 2729cdf0e10cSrcweir // ------------------------------------------------------------------------- 2730cdf0e10cSrcweir 2731cdf0e10cSrcweir bool PrintFontManager::getFontBoundingBox( fontID nFontID, int& xMin, int& yMin, int& xMax, int& yMax ) 2732cdf0e10cSrcweir { 2733cdf0e10cSrcweir bool bSuccess = false; 2734cdf0e10cSrcweir PrintFont* pFont = getFont( nFontID ); 2735cdf0e10cSrcweir if( pFont ) 2736cdf0e10cSrcweir { 2737cdf0e10cSrcweir if( pFont->m_nXMin == 0 && pFont->m_nYMin == 0 && pFont->m_nXMax == 0 && pFont->m_nYMax == 0 ) 2738cdf0e10cSrcweir { 2739cdf0e10cSrcweir // might be a truetype font not analyzed or type1 without metrics read 2740cdf0e10cSrcweir if( pFont->m_eType == fonttype::Type1 || pFont->m_eType == fonttype::Builtin ) 2741cdf0e10cSrcweir pFont->readAfmMetrics( getAfmFile( pFont ), m_pAtoms, false, true ); 2742cdf0e10cSrcweir else if( pFont->m_eType == fonttype::TrueType ) 2743cdf0e10cSrcweir analyzeTrueTypeFile( pFont ); 2744cdf0e10cSrcweir } 2745cdf0e10cSrcweir bSuccess = true; 2746cdf0e10cSrcweir xMin = pFont->m_nXMin; 2747cdf0e10cSrcweir yMin = pFont->m_nYMin; 2748cdf0e10cSrcweir xMax = pFont->m_nXMax; 2749cdf0e10cSrcweir yMax = pFont->m_nYMax; 2750cdf0e10cSrcweir } 2751cdf0e10cSrcweir return bSuccess; 2752cdf0e10cSrcweir } 2753cdf0e10cSrcweir 2754cdf0e10cSrcweir // ------------------------------------------------------------------------- 2755cdf0e10cSrcweir 2756cdf0e10cSrcweir int PrintFontManager::getFontFaceNumber( fontID nFontID ) const 2757cdf0e10cSrcweir { 2758cdf0e10cSrcweir int nRet = -1; 2759cdf0e10cSrcweir PrintFont* pFont = getFont( nFontID ); 2760cdf0e10cSrcweir if( pFont && pFont->m_eType == fonttype::TrueType ) 2761cdf0e10cSrcweir nRet = static_cast< TrueTypeFontFile* >(pFont)->m_nCollectionEntry; 2762cdf0e10cSrcweir return nRet; 2763cdf0e10cSrcweir } 2764cdf0e10cSrcweir 2765cdf0e10cSrcweir // ------------------------------------------------------------------------- 2766cdf0e10cSrcweir 2767cdf0e10cSrcweir 2768cdf0e10cSrcweir family::type PrintFontManager::matchFamilyName( const ::rtl::OUString& rFamily ) const 2769cdf0e10cSrcweir { 2770cdf0e10cSrcweir typedef struct { 2771cdf0e10cSrcweir const char* mpName; 2772cdf0e10cSrcweir sal_uInt16 mnLength; 2773cdf0e10cSrcweir family::type meType; 2774cdf0e10cSrcweir } family_t; 2775cdf0e10cSrcweir 2776cdf0e10cSrcweir #define InitializeClass( p, a ) p, sizeof(p) - 1, a 2777cdf0e10cSrcweir const family_t pFamilyMatch[] = { 2778cdf0e10cSrcweir { InitializeClass( "arial", family::Swiss ) }, 2779cdf0e10cSrcweir { InitializeClass( "arioso", family::Script ) }, 2780cdf0e10cSrcweir { InitializeClass( "avant garde", family::Swiss ) }, 2781cdf0e10cSrcweir { InitializeClass( "avantgarde", family::Swiss ) }, 2782cdf0e10cSrcweir { InitializeClass( "bembo", family::Roman ) }, 2783cdf0e10cSrcweir { InitializeClass( "bookman", family::Roman ) }, 2784cdf0e10cSrcweir { InitializeClass( "conga", family::Roman ) }, 2785cdf0e10cSrcweir { InitializeClass( "courier", family::Modern ) }, 2786cdf0e10cSrcweir { InitializeClass( "curl", family::Script ) }, 2787cdf0e10cSrcweir { InitializeClass( "fixed", family::Modern ) }, 2788cdf0e10cSrcweir { InitializeClass( "gill", family::Swiss ) }, 2789cdf0e10cSrcweir { InitializeClass( "helmet", family::Modern ) }, 2790cdf0e10cSrcweir { InitializeClass( "helvetica", family::Swiss ) }, 2791cdf0e10cSrcweir { InitializeClass( "international", family::Modern ) }, 2792cdf0e10cSrcweir { InitializeClass( "lucida", family::Swiss ) }, 2793cdf0e10cSrcweir { InitializeClass( "new century schoolbook", family::Roman ) }, 2794cdf0e10cSrcweir { InitializeClass( "palatino", family::Roman ) }, 2795cdf0e10cSrcweir { InitializeClass( "roman", family::Roman ) }, 2796cdf0e10cSrcweir { InitializeClass( "sans serif", family::Swiss ) }, 2797cdf0e10cSrcweir { InitializeClass( "sansserif", family::Swiss ) }, 2798cdf0e10cSrcweir { InitializeClass( "serf", family::Roman ) }, 2799cdf0e10cSrcweir { InitializeClass( "serif", family::Roman ) }, 2800cdf0e10cSrcweir { InitializeClass( "times", family::Roman ) }, 2801cdf0e10cSrcweir { InitializeClass( "utopia", family::Roman ) }, 2802cdf0e10cSrcweir { InitializeClass( "zapf chancery", family::Script ) }, 2803cdf0e10cSrcweir { InitializeClass( "zapfchancery", family::Script ) } 2804cdf0e10cSrcweir }; 2805cdf0e10cSrcweir 2806cdf0e10cSrcweir rtl::OString aFamily = rtl::OUStringToOString( rFamily, RTL_TEXTENCODING_ASCII_US ); 2807cdf0e10cSrcweir sal_uInt32 nLower = 0; 2808cdf0e10cSrcweir sal_uInt32 nUpper = sizeof(pFamilyMatch) / sizeof(pFamilyMatch[0]); 2809cdf0e10cSrcweir 2810cdf0e10cSrcweir while( nLower < nUpper ) 2811cdf0e10cSrcweir { 2812cdf0e10cSrcweir sal_uInt32 nCurrent = (nLower + nUpper) / 2; 2813cdf0e10cSrcweir const family_t* pHaystack = pFamilyMatch + nCurrent; 2814cdf0e10cSrcweir sal_Int32 nComparison = 2815cdf0e10cSrcweir rtl_str_compareIgnoreAsciiCase_WithLength 2816cdf0e10cSrcweir ( 2817cdf0e10cSrcweir aFamily.getStr(), aFamily.getLength(), 2818cdf0e10cSrcweir pHaystack->mpName, pHaystack->mnLength 2819cdf0e10cSrcweir ); 2820cdf0e10cSrcweir 2821cdf0e10cSrcweir if( nComparison < 0 ) 2822cdf0e10cSrcweir nUpper = nCurrent; 2823cdf0e10cSrcweir else 2824cdf0e10cSrcweir if( nComparison > 0 ) 2825cdf0e10cSrcweir nLower = nCurrent + 1; 2826cdf0e10cSrcweir else 2827cdf0e10cSrcweir return pHaystack->meType; 2828cdf0e10cSrcweir } 2829cdf0e10cSrcweir 2830cdf0e10cSrcweir return family::Unknown; 2831cdf0e10cSrcweir } 2832cdf0e10cSrcweir 2833cdf0e10cSrcweir // ------------------------------------------------------------------------- 2834cdf0e10cSrcweir 2835cdf0e10cSrcweir family::type PrintFontManager::getFontFamilyType( fontID nFontID ) const 2836cdf0e10cSrcweir { 2837cdf0e10cSrcweir PrintFont* pFont = getFont( nFontID ); 2838cdf0e10cSrcweir if( !pFont ) 2839cdf0e10cSrcweir return family::Unknown; 2840cdf0e10cSrcweir 2841cdf0e10cSrcweir ::std::hash_map< int, family::type >::const_iterator it = 2842cdf0e10cSrcweir m_aFamilyTypes.find( pFont->m_nFamilyName ); 2843cdf0e10cSrcweir return (it != m_aFamilyTypes.end()) ? it->second : family::Unknown; 2844cdf0e10cSrcweir } 2845cdf0e10cSrcweir 2846cdf0e10cSrcweir 2847cdf0e10cSrcweir // ------------------------------------------------------------------------- 2848cdf0e10cSrcweir 2849cdf0e10cSrcweir const ::rtl::OUString& PrintFontManager::getFontFamily( fontID nFontID ) const 2850cdf0e10cSrcweir { 2851cdf0e10cSrcweir PrintFont* pFont = getFont( nFontID ); 2852cdf0e10cSrcweir return m_pAtoms->getString( ATOM_FAMILYNAME, pFont ? pFont->m_nFamilyName : INVALID_ATOM ); 2853cdf0e10cSrcweir } 2854cdf0e10cSrcweir 2855cdf0e10cSrcweir // ------------------------------------------------------------------------- 2856cdf0e10cSrcweir 2857cdf0e10cSrcweir OString PrintFontManager::getAfmFile( PrintFont* pFont ) const 2858cdf0e10cSrcweir { 2859cdf0e10cSrcweir OString aMetricPath; 2860cdf0e10cSrcweir if( pFont ) 2861cdf0e10cSrcweir { 2862cdf0e10cSrcweir switch( pFont->m_eType ) 2863cdf0e10cSrcweir { 2864cdf0e10cSrcweir case fonttype::Type1: 2865cdf0e10cSrcweir { 2866cdf0e10cSrcweir Type1FontFile* pPSFont = static_cast< Type1FontFile* >(pFont); 2867cdf0e10cSrcweir aMetricPath = getDirectory( pPSFont->m_nDirectory ); 2868cdf0e10cSrcweir aMetricPath += "/"; 2869cdf0e10cSrcweir aMetricPath += pPSFont->m_aMetricFile; 2870cdf0e10cSrcweir } 2871cdf0e10cSrcweir break; 2872cdf0e10cSrcweir case fonttype::Builtin: 2873cdf0e10cSrcweir { 2874cdf0e10cSrcweir BuiltinFont* pBuiltinFont = static_cast< BuiltinFont* >(pFont); 2875cdf0e10cSrcweir aMetricPath = getDirectory( pBuiltinFont->m_nDirectory ); 2876cdf0e10cSrcweir aMetricPath += "/"; 2877cdf0e10cSrcweir aMetricPath += pBuiltinFont->m_aMetricFile; 2878cdf0e10cSrcweir } 2879cdf0e10cSrcweir break; 2880cdf0e10cSrcweir default: break; 2881cdf0e10cSrcweir } 2882cdf0e10cSrcweir } 2883cdf0e10cSrcweir return aMetricPath; 2884cdf0e10cSrcweir } 2885cdf0e10cSrcweir 2886cdf0e10cSrcweir // ------------------------------------------------------------------------- 2887cdf0e10cSrcweir 2888cdf0e10cSrcweir OString PrintFontManager::getFontFile( PrintFont* pFont ) const 2889cdf0e10cSrcweir { 2890cdf0e10cSrcweir OString aPath; 2891cdf0e10cSrcweir 2892cdf0e10cSrcweir if( pFont && pFont->m_eType == fonttype::Type1 ) 2893cdf0e10cSrcweir { 2894cdf0e10cSrcweir Type1FontFile* pPSFont = static_cast< Type1FontFile* >(pFont); 2895cdf0e10cSrcweir ::std::hash_map< int, OString >::const_iterator it = m_aAtomToDir.find( pPSFont->m_nDirectory ); 2896cdf0e10cSrcweir aPath = it->second; 2897cdf0e10cSrcweir aPath += "/"; 2898cdf0e10cSrcweir aPath += pPSFont->m_aFontFile; 2899cdf0e10cSrcweir } 2900cdf0e10cSrcweir else if( pFont && pFont->m_eType == fonttype::TrueType ) 2901cdf0e10cSrcweir { 2902cdf0e10cSrcweir TrueTypeFontFile* pTTFont = static_cast< TrueTypeFontFile* >(pFont); 2903cdf0e10cSrcweir ::std::hash_map< int, OString >::const_iterator it = m_aAtomToDir.find( pTTFont->m_nDirectory ); 2904cdf0e10cSrcweir aPath = it->second; 2905cdf0e10cSrcweir aPath += "/"; 2906cdf0e10cSrcweir aPath += pTTFont->m_aFontFile; 2907cdf0e10cSrcweir } 2908cdf0e10cSrcweir return aPath; 2909cdf0e10cSrcweir } 2910cdf0e10cSrcweir 2911cdf0e10cSrcweir // ------------------------------------------------------------------------- 2912cdf0e10cSrcweir 2913cdf0e10cSrcweir const ::rtl::OUString& PrintFontManager::getPSName( fontID nFontID ) const 2914cdf0e10cSrcweir { 2915cdf0e10cSrcweir PrintFont* pFont = getFont( nFontID ); 2916cdf0e10cSrcweir if( pFont && pFont->m_nPSName == 0 ) 2917cdf0e10cSrcweir { 2918cdf0e10cSrcweir if( pFont->m_eType == fonttype::TrueType ) 2919cdf0e10cSrcweir analyzeTrueTypeFile( pFont ); 2920cdf0e10cSrcweir } 2921cdf0e10cSrcweir 2922cdf0e10cSrcweir return m_pAtoms->getString( ATOM_PSNAME, pFont ? pFont->m_nPSName : INVALID_ATOM ); 2923cdf0e10cSrcweir } 2924cdf0e10cSrcweir 2925cdf0e10cSrcweir // ------------------------------------------------------------------------- 2926cdf0e10cSrcweir 2927cdf0e10cSrcweir const CharacterMetric& PrintFontManager::getGlobalFontMetric( fontID nFontID, bool bHorizontal ) const 2928cdf0e10cSrcweir { 2929cdf0e10cSrcweir static CharacterMetric aMetric; 2930cdf0e10cSrcweir PrintFont* pFont = getFont( nFontID ); 2931cdf0e10cSrcweir return pFont ? ( bHorizontal ? pFont->m_aGlobalMetricX : pFont->m_aGlobalMetricY ) : aMetric; 2932cdf0e10cSrcweir } 2933cdf0e10cSrcweir 2934cdf0e10cSrcweir // ------------------------------------------------------------------------- 2935cdf0e10cSrcweir 2936cdf0e10cSrcweir int PrintFontManager::getFontAscend( fontID nFontID ) const 2937cdf0e10cSrcweir { 2938cdf0e10cSrcweir PrintFont* pFont = getFont( nFontID ); 2939cdf0e10cSrcweir if( pFont->m_nAscend == 0 && pFont->m_nDescend == 0 ) 2940cdf0e10cSrcweir { 2941cdf0e10cSrcweir // might be a truetype font not yet analyzed 2942cdf0e10cSrcweir if( pFont->m_eType == fonttype::TrueType ) 2943cdf0e10cSrcweir analyzeTrueTypeFile( pFont ); 2944cdf0e10cSrcweir else if( pFont->m_eType == fonttype::Type1 || pFont->m_eType == fonttype::Builtin ) 2945cdf0e10cSrcweir pFont->readAfmMetrics( getAfmFile( pFont ), m_pAtoms, false, true ); 2946cdf0e10cSrcweir } 2947cdf0e10cSrcweir return pFont->m_nAscend; 2948cdf0e10cSrcweir } 2949cdf0e10cSrcweir 2950cdf0e10cSrcweir // ------------------------------------------------------------------------- 2951cdf0e10cSrcweir 2952cdf0e10cSrcweir int PrintFontManager::getFontDescend( fontID nFontID ) const 2953cdf0e10cSrcweir { 2954cdf0e10cSrcweir PrintFont* pFont = getFont( nFontID ); 2955cdf0e10cSrcweir if( pFont->m_nAscend == 0 && pFont->m_nDescend == 0 ) 2956cdf0e10cSrcweir { 2957cdf0e10cSrcweir // might be a truetype font not yet analyzed 2958cdf0e10cSrcweir if( pFont->m_eType == fonttype::TrueType ) 2959cdf0e10cSrcweir analyzeTrueTypeFile( pFont ); 2960cdf0e10cSrcweir else if( pFont->m_eType == fonttype::Type1 || pFont->m_eType == fonttype::Builtin ) 2961cdf0e10cSrcweir pFont->readAfmMetrics( getAfmFile( pFont ), m_pAtoms, false, true ); 2962cdf0e10cSrcweir } 2963cdf0e10cSrcweir return pFont->m_nDescend; 2964cdf0e10cSrcweir } 2965cdf0e10cSrcweir 2966cdf0e10cSrcweir // ------------------------------------------------------------------------- 2967cdf0e10cSrcweir 2968cdf0e10cSrcweir int PrintFontManager::getFontLeading( fontID nFontID ) const 2969cdf0e10cSrcweir { 2970cdf0e10cSrcweir PrintFont* pFont = getFont( nFontID ); 2971cdf0e10cSrcweir if( pFont->m_nAscend == 0 && pFont->m_nDescend == 0 ) 2972cdf0e10cSrcweir { 2973cdf0e10cSrcweir // might be a truetype font not yet analyzed 2974cdf0e10cSrcweir if( pFont->m_eType == fonttype::TrueType ) 2975cdf0e10cSrcweir analyzeTrueTypeFile( pFont ); 2976cdf0e10cSrcweir } 2977cdf0e10cSrcweir return pFont->m_nLeading; 2978cdf0e10cSrcweir } 2979cdf0e10cSrcweir 2980cdf0e10cSrcweir // ------------------------------------------------------------------------- 2981cdf0e10cSrcweir 2982cdf0e10cSrcweir bool PrintFontManager::hasVerticalSubstitutions( fontID nFontID ) const 2983cdf0e10cSrcweir { 2984cdf0e10cSrcweir PrintFont* pFont = getFont( nFontID ); 2985cdf0e10cSrcweir if( pFont->m_nAscend == 0 && pFont->m_nDescend == 0 ) 2986cdf0e10cSrcweir { 2987cdf0e10cSrcweir // might be a truetype font not yet analyzed 2988cdf0e10cSrcweir if( pFont->m_eType == fonttype::TrueType ) 2989cdf0e10cSrcweir analyzeTrueTypeFile( pFont ); 2990cdf0e10cSrcweir } 2991cdf0e10cSrcweir return pFont->m_bHaveVerticalSubstitutedGlyphs; 2992cdf0e10cSrcweir } 2993cdf0e10cSrcweir 2994cdf0e10cSrcweir // ------------------------------------------------------------------------- 2995cdf0e10cSrcweir 2996cdf0e10cSrcweir void PrintFontManager::hasVerticalSubstitutions( fontID nFontID, 2997cdf0e10cSrcweir const sal_Unicode* pCharacters, int nCharacters, bool* pHasSubst ) const 2998cdf0e10cSrcweir { 2999cdf0e10cSrcweir PrintFont* pFont = getFont( nFontID ); 3000cdf0e10cSrcweir if( pFont->m_nAscend == 0 && pFont->m_nDescend == 0 ) 3001cdf0e10cSrcweir { 3002cdf0e10cSrcweir // might be a truetype font not yet analyzed 3003cdf0e10cSrcweir if( pFont->m_eType == fonttype::TrueType ) 3004cdf0e10cSrcweir analyzeTrueTypeFile( pFont ); 3005cdf0e10cSrcweir } 3006cdf0e10cSrcweir 3007cdf0e10cSrcweir if( ! pFont->m_bHaveVerticalSubstitutedGlyphs ) 3008cdf0e10cSrcweir memset( pHasSubst, 0, sizeof(bool)*nCharacters ); 3009cdf0e10cSrcweir else 3010cdf0e10cSrcweir { 3011cdf0e10cSrcweir for( int i = 0; i < nCharacters; i++ ) 3012cdf0e10cSrcweir { 3013cdf0e10cSrcweir sal_Unicode code = pCharacters[i]; 3014cdf0e10cSrcweir if( ! pFont->m_pMetrics || 3015cdf0e10cSrcweir ! ( pFont->m_pMetrics->m_aPages[ code >> 11 ] & ( 1 << ( ( code >> 8 ) & 7 ) ) ) ) 3016cdf0e10cSrcweir pFont->queryMetricPage( code >> 8, m_pAtoms ); 3017cdf0e10cSrcweir ::std::hash_map< sal_Unicode, bool >::const_iterator it = pFont->m_pMetrics->m_bVerticalSubstitutions.find( code ); 3018cdf0e10cSrcweir pHasSubst[i] = it != pFont->m_pMetrics->m_bVerticalSubstitutions.end(); 3019cdf0e10cSrcweir } 3020cdf0e10cSrcweir } 3021cdf0e10cSrcweir } 3022cdf0e10cSrcweir 3023cdf0e10cSrcweir // ------------------------------------------------------------------------- 3024cdf0e10cSrcweir 3025cdf0e10cSrcweir OUString PrintFontManager::getFontXLFD( fontID nFontID ) const 3026cdf0e10cSrcweir { 3027cdf0e10cSrcweir PrintFont* pFont = getFont( nFontID ); 3028cdf0e10cSrcweir OUString aRet; 3029cdf0e10cSrcweir if( pFont ) 3030cdf0e10cSrcweir { 3031cdf0e10cSrcweir ByteString aXLFD( getXLFD( pFont ) ); 3032cdf0e10cSrcweir rtl_TextEncoding aEncoding = aXLFD.GetToken( 6, '-' ).Search( "utf8" ) != STRING_NOTFOUND ? RTL_TEXTENCODING_UTF8 : RTL_TEXTENCODING_ISO_8859_1; 3033cdf0e10cSrcweir aRet = OStringToOUString( aXLFD, aEncoding ); 3034cdf0e10cSrcweir } 3035cdf0e10cSrcweir return aRet; 3036cdf0e10cSrcweir } 3037cdf0e10cSrcweir 3038cdf0e10cSrcweir // ------------------------------------------------------------------------- 3039cdf0e10cSrcweir 3040cdf0e10cSrcweir const ::std::list< KernPair >& PrintFontManager::getKernPairs( fontID nFontID, bool bVertical ) const 3041cdf0e10cSrcweir { 3042cdf0e10cSrcweir static ::std::list< KernPair > aEmpty; 3043cdf0e10cSrcweir 3044cdf0e10cSrcweir PrintFont* pFont = getFont( nFontID ); 3045cdf0e10cSrcweir if( ! pFont ) 3046cdf0e10cSrcweir return aEmpty; 3047cdf0e10cSrcweir 3048cdf0e10cSrcweir if( ! pFont->m_pMetrics || ! pFont->m_pMetrics->m_bKernPairsQueried ) 3049cdf0e10cSrcweir pFont->queryMetricPage( 0, m_pAtoms ); 3050cdf0e10cSrcweir if( ! pFont->m_pMetrics || ! pFont->m_pMetrics->m_bKernPairsQueried ) 3051cdf0e10cSrcweir return aEmpty; 3052cdf0e10cSrcweir return bVertical ? pFont->m_pMetrics->m_aYKernPairs : pFont->m_pMetrics->m_aXKernPairs; 3053cdf0e10cSrcweir } 3054cdf0e10cSrcweir 3055cdf0e10cSrcweir // ------------------------------------------------------------------------- 3056cdf0e10cSrcweir 3057cdf0e10cSrcweir bool PrintFontManager::isFontDownloadingAllowed( fontID nFont ) const 3058cdf0e10cSrcweir { 3059cdf0e10cSrcweir static const char* pEnable = getenv( "PSPRINT_ENABLE_TTF_COPYRIGHTAWARENESS" ); 3060cdf0e10cSrcweir bool bRet = true; 3061cdf0e10cSrcweir 3062cdf0e10cSrcweir if( pEnable && *pEnable ) 3063cdf0e10cSrcweir { 3064cdf0e10cSrcweir PrintFont* pFont = getFont( nFont ); 3065cdf0e10cSrcweir if( pFont && pFont->m_eType == fonttype::TrueType ) 3066cdf0e10cSrcweir { 3067cdf0e10cSrcweir TrueTypeFontFile* pTTFontFile = static_cast<TrueTypeFontFile*>(pFont); 3068cdf0e10cSrcweir if( pTTFontFile->m_nTypeFlags & TYPEFLAG_INVALID ) 3069cdf0e10cSrcweir { 3070cdf0e10cSrcweir TrueTypeFont* pTTFont = NULL; 3071cdf0e10cSrcweir ByteString aFile = getFontFile( pFont ); 3072cdf0e10cSrcweir if( OpenTTFontFile( aFile.GetBuffer(), pTTFontFile->m_nCollectionEntry < 0 ? 0 : pTTFontFile->m_nCollectionEntry, &pTTFont ) == SF_OK ) 3073cdf0e10cSrcweir { 3074cdf0e10cSrcweir // get type flags 3075cdf0e10cSrcweir TTGlobalFontInfo aInfo; 3076cdf0e10cSrcweir GetTTGlobalFontInfo( pTTFont, & aInfo ); 3077cdf0e10cSrcweir pTTFontFile->m_nTypeFlags = (unsigned int)aInfo.typeFlags; 3078cdf0e10cSrcweir CloseTTFont( pTTFont ); 3079cdf0e10cSrcweir } 3080cdf0e10cSrcweir } 3081cdf0e10cSrcweir 3082cdf0e10cSrcweir unsigned int nCopyrightFlags = pTTFontFile->m_nTypeFlags & TYPEFLAG_COPYRIGHT_MASK; 3083cdf0e10cSrcweir 3084cdf0e10cSrcweir // font embedding is allowed if either 3085cdf0e10cSrcweir // no restriction at all (bit 1 clear) 3086cdf0e10cSrcweir // printing allowed (bit 1 set, bit 2 set ) 3087cdf0e10cSrcweir bRet = ! ( nCopyrightFlags & 0x02 ) || ( nCopyrightFlags & 0x04 ); 3088cdf0e10cSrcweir } 3089cdf0e10cSrcweir } 3090cdf0e10cSrcweir return bRet; 3091cdf0e10cSrcweir } 3092cdf0e10cSrcweir 3093cdf0e10cSrcweir // ------------------------------------------------------------------------- 3094cdf0e10cSrcweir 3095cdf0e10cSrcweir bool PrintFontManager::getMetrics( fontID nFontID, const sal_Unicode* pString, int nLen, CharacterMetric* pArray, bool bVertical ) const 3096cdf0e10cSrcweir { 3097cdf0e10cSrcweir PrintFont* pFont = getFont( nFontID ); 3098cdf0e10cSrcweir if( ! pFont ) 3099cdf0e10cSrcweir return false; 3100cdf0e10cSrcweir 3101cdf0e10cSrcweir if( ( pFont->m_nAscend == 0 && pFont->m_nDescend == 0 ) 3102cdf0e10cSrcweir || ! pFont->m_pMetrics || pFont->m_pMetrics->isEmpty() 3103cdf0e10cSrcweir ) 3104cdf0e10cSrcweir { 3105cdf0e10cSrcweir // might be a font not yet analyzed 3106cdf0e10cSrcweir if( pFont->m_eType == fonttype::Type1 || pFont->m_eType == fonttype::Builtin ) 3107cdf0e10cSrcweir pFont->readAfmMetrics( getAfmFile( pFont ), m_pAtoms, false, false ); 3108cdf0e10cSrcweir else if( pFont->m_eType == fonttype::TrueType ) 3109cdf0e10cSrcweir analyzeTrueTypeFile( pFont ); 3110cdf0e10cSrcweir } 3111cdf0e10cSrcweir 3112cdf0e10cSrcweir for( int i = 0; i < nLen; i++ ) 3113cdf0e10cSrcweir { 3114cdf0e10cSrcweir if( ! pFont->m_pMetrics || 3115cdf0e10cSrcweir ! ( pFont->m_pMetrics->m_aPages[ pString[i] >> 11 ] & ( 1 << ( ( pString[i] >> 8 ) & 7 ) ) ) ) 3116cdf0e10cSrcweir pFont->queryMetricPage( pString[i] >> 8, m_pAtoms ); 3117cdf0e10cSrcweir pArray[i].width = pArray[i].height = -1; 3118cdf0e10cSrcweir if( pFont->m_pMetrics ) 3119cdf0e10cSrcweir { 3120cdf0e10cSrcweir int effectiveCode = pString[i]; 3121cdf0e10cSrcweir effectiveCode |= bVertical ? 1 << 16 : 0; 3122cdf0e10cSrcweir ::std::hash_map< int, CharacterMetric >::const_iterator it = 3123cdf0e10cSrcweir pFont->m_pMetrics->m_aMetrics.find( effectiveCode ); 3124cdf0e10cSrcweir // if no vertical metrics are available assume rotated horizontal metrics 3125cdf0e10cSrcweir if( bVertical && (it == pFont->m_pMetrics->m_aMetrics.end()) ) 3126cdf0e10cSrcweir it = pFont->m_pMetrics->m_aMetrics.find( pString[i] ); 3127cdf0e10cSrcweir // the character metrics are in it->second 3128cdf0e10cSrcweir if( it != pFont->m_pMetrics->m_aMetrics.end() ) 3129cdf0e10cSrcweir pArray[ i ] = it->second; 3130cdf0e10cSrcweir } 3131cdf0e10cSrcweir } 3132cdf0e10cSrcweir 3133cdf0e10cSrcweir return true; 3134cdf0e10cSrcweir } 3135cdf0e10cSrcweir 3136cdf0e10cSrcweir // ------------------------------------------------------------------------- 3137cdf0e10cSrcweir 3138cdf0e10cSrcweir bool PrintFontManager::getMetrics( fontID nFontID, sal_Unicode minCharacter, sal_Unicode maxCharacter, CharacterMetric* pArray, bool bVertical ) const 3139cdf0e10cSrcweir { 3140cdf0e10cSrcweir PrintFont* pFont = getFont( nFontID ); 3141cdf0e10cSrcweir if( ! pFont ) 3142cdf0e10cSrcweir return false; 3143cdf0e10cSrcweir 3144cdf0e10cSrcweir if( ( pFont->m_nAscend == 0 && pFont->m_nDescend == 0 ) 3145cdf0e10cSrcweir || ! pFont->m_pMetrics || pFont->m_pMetrics->isEmpty() 3146cdf0e10cSrcweir ) 3147cdf0e10cSrcweir { 3148cdf0e10cSrcweir // might be a font not yet analyzed 3149cdf0e10cSrcweir if( pFont->m_eType == fonttype::Type1 || pFont->m_eType == fonttype::Builtin ) 3150cdf0e10cSrcweir pFont->readAfmMetrics( getAfmFile( pFont ), m_pAtoms, false, false ); 3151cdf0e10cSrcweir else if( pFont->m_eType == fonttype::TrueType ) 3152cdf0e10cSrcweir analyzeTrueTypeFile( pFont ); 3153cdf0e10cSrcweir } 3154cdf0e10cSrcweir 3155cdf0e10cSrcweir sal_Unicode code = minCharacter; 3156cdf0e10cSrcweir do 3157cdf0e10cSrcweir { 3158cdf0e10cSrcweir if( ! pFont->m_pMetrics || 3159cdf0e10cSrcweir ! ( pFont->m_pMetrics->m_aPages[ code >> 11 ] & ( 1 << ( ( code >> 8 ) & 7 ) ) ) ) 3160cdf0e10cSrcweir pFont->queryMetricPage( code >> 8, m_pAtoms ); 3161cdf0e10cSrcweir pArray[ code - minCharacter ].width = -1; 3162cdf0e10cSrcweir pArray[ code - minCharacter ].height = -1; 3163cdf0e10cSrcweir if( pFont->m_pMetrics ) 3164cdf0e10cSrcweir { 3165cdf0e10cSrcweir int effectiveCode = code; 3166cdf0e10cSrcweir effectiveCode |= bVertical ? 1 << 16 : 0; 3167cdf0e10cSrcweir ::std::hash_map< int, CharacterMetric >::const_iterator it = 3168cdf0e10cSrcweir pFont->m_pMetrics->m_aMetrics.find( effectiveCode ); 3169cdf0e10cSrcweir // if no vertical metrics are available assume rotated horizontal metrics 3170cdf0e10cSrcweir if( bVertical && (it == pFont->m_pMetrics->m_aMetrics.end()) ) 3171cdf0e10cSrcweir it = pFont->m_pMetrics->m_aMetrics.find( code ); 3172cdf0e10cSrcweir // the character metrics are in it->second 3173cdf0e10cSrcweir if( it != pFont->m_pMetrics->m_aMetrics.end() ) 3174cdf0e10cSrcweir pArray[ code - minCharacter ] = it->second; 3175cdf0e10cSrcweir } 3176cdf0e10cSrcweir } while( code++ != maxCharacter ); 3177cdf0e10cSrcweir 3178cdf0e10cSrcweir return true; 3179cdf0e10cSrcweir } 3180cdf0e10cSrcweir 3181cdf0e10cSrcweir // ------------------------------------------------------------------------- 3182cdf0e10cSrcweir 3183cdf0e10cSrcweir static bool createWriteablePath( const ByteString& rPath ) 3184cdf0e10cSrcweir { 3185cdf0e10cSrcweir bool bSuccess = false; 3186cdf0e10cSrcweir 3187cdf0e10cSrcweir if( access( rPath.GetBuffer(), W_OK ) ) 3188cdf0e10cSrcweir { 3189cdf0e10cSrcweir int nPos = rPath.SearchBackward( '/' ); 3190cdf0e10cSrcweir if( nPos != STRING_NOTFOUND ) 3191cdf0e10cSrcweir while( nPos > 0 && rPath.GetChar( nPos ) == '/' ) 3192cdf0e10cSrcweir nPos--; 3193cdf0e10cSrcweir 3194cdf0e10cSrcweir if( nPos != STRING_NOTFOUND && nPos != 0 && createWriteablePath( rPath.Copy( 0, nPos+1 ) ) ) 3195cdf0e10cSrcweir { 3196cdf0e10cSrcweir bSuccess = mkdir( rPath.GetBuffer(), 0777 ) ? false : true; 3197cdf0e10cSrcweir } 3198cdf0e10cSrcweir } 3199cdf0e10cSrcweir else 3200cdf0e10cSrcweir bSuccess = true; 3201cdf0e10cSrcweir 3202cdf0e10cSrcweir return bSuccess; 3203cdf0e10cSrcweir } 3204cdf0e10cSrcweir 3205cdf0e10cSrcweir 3206cdf0e10cSrcweir // ------------------------------------------------------------------------- 3207cdf0e10cSrcweir 3208cdf0e10cSrcweir int PrintFontManager::importFonts( const ::std::list< OString >& rFiles, bool bLinkOnly, ImportFontCallback* pCallback ) 3209cdf0e10cSrcweir { 3210cdf0e10cSrcweir int nSuccess = 0; 3211cdf0e10cSrcweir 3212cdf0e10cSrcweir // find a directory with write access 3213cdf0e10cSrcweir rtl_TextEncoding aEncoding = osl_getThreadTextEncoding(); 3214cdf0e10cSrcweir bool bCanWrite = false; 3215cdf0e10cSrcweir int nDirID = 0; 3216cdf0e10cSrcweir INetURLObject aDir; 3217cdf0e10cSrcweir for( ::std::list< int >::const_iterator dir_it = m_aPrivateFontDirectories.begin(); 3218cdf0e10cSrcweir ! bCanWrite && dir_it != m_aPrivateFontDirectories.end(); ++dir_it ) 3219cdf0e10cSrcweir { 3220cdf0e10cSrcweir // check if we can create files in that directory 3221cdf0e10cSrcweir ByteString aDirPath = getDirectory( *dir_it ); 3222cdf0e10cSrcweir if( createWriteablePath( aDirPath ) ) 3223cdf0e10cSrcweir { 3224cdf0e10cSrcweir aDir = INetURLObject( OStringToOUString( aDirPath, aEncoding ), INET_PROT_FILE, INetURLObject::ENCODE_ALL ); 3225cdf0e10cSrcweir nDirID = *dir_it; 3226cdf0e10cSrcweir bCanWrite = true; 3227cdf0e10cSrcweir } 3228cdf0e10cSrcweir } 3229cdf0e10cSrcweir if( bCanWrite ) 3230cdf0e10cSrcweir { 3231cdf0e10cSrcweir for( ::std::list< OString >::const_iterator font_it = rFiles.begin(); 3232cdf0e10cSrcweir font_it != rFiles.end(); ++font_it ) 3233cdf0e10cSrcweir { 3234cdf0e10cSrcweir INetURLObject aFrom( OStringToOUString( *font_it, aEncoding ), INET_PROT_FILE, INetURLObject::ENCODE_ALL ); 3235cdf0e10cSrcweir INetURLObject aTo( aDir ); 3236cdf0e10cSrcweir aTo.Append( aFrom.GetName() ); 3237cdf0e10cSrcweir 3238cdf0e10cSrcweir if( pCallback ) 3239cdf0e10cSrcweir pCallback->progress( aTo.PathToFileName() ); 3240cdf0e10cSrcweir 3241cdf0e10cSrcweir if( pCallback && pCallback->isCanceled() ) 3242cdf0e10cSrcweir break; 3243cdf0e10cSrcweir 3244cdf0e10cSrcweir if( ! access( ByteString( String(aTo.PathToFileName()), aEncoding ).GetBuffer(), F_OK ) ) 3245cdf0e10cSrcweir { 3246cdf0e10cSrcweir if( ! ( pCallback ? pCallback->queryOverwriteFile( aTo.PathToFileName() ) : false ) ) 3247cdf0e10cSrcweir continue; 3248cdf0e10cSrcweir } 3249cdf0e10cSrcweir // look for afm if necessary 3250cdf0e10cSrcweir OUString aAfmCopied; 3251cdf0e10cSrcweir FileBase::RC nError; 3252cdf0e10cSrcweir if( aFrom.getExtension().equalsIgnoreAsciiCaseAscii( "pfa" ) || 3253cdf0e10cSrcweir aFrom.getExtension().equalsIgnoreAsciiCaseAscii( "pfb" ) ) 3254cdf0e10cSrcweir { 3255cdf0e10cSrcweir INetURLObject aFromAfm( aFrom ); 3256cdf0e10cSrcweir aFromAfm.setExtension( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "afm" ) ) ); 3257cdf0e10cSrcweir if( access( ByteString( String(aFromAfm.PathToFileName()), aEncoding ).GetBuffer(), F_OK ) ) 3258cdf0e10cSrcweir { 3259cdf0e10cSrcweir aFromAfm.setExtension( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AFM" ) ) ); 3260cdf0e10cSrcweir if( access( ByteString( String(aFromAfm.PathToFileName()), aEncoding ).GetBuffer(), F_OK ) ) 3261cdf0e10cSrcweir { 3262cdf0e10cSrcweir aFromAfm.removeSegment(); 3263cdf0e10cSrcweir aFromAfm.Append( String( RTL_CONSTASCII_USTRINGPARAM( "afm" ) ) ); 3264cdf0e10cSrcweir aFromAfm.Append( aTo.GetName() ); 3265cdf0e10cSrcweir aFromAfm.setExtension( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "afm" ) ) ); 3266cdf0e10cSrcweir if( access( ByteString( String(aFromAfm.PathToFileName()), aEncoding ).GetBuffer(), F_OK ) ) 3267cdf0e10cSrcweir { 3268cdf0e10cSrcweir aFromAfm.setExtension( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AFM" ) ) ); 3269cdf0e10cSrcweir if( access( ByteString( String(aFromAfm.PathToFileName()), aEncoding ).GetBuffer(), F_OK ) ) 3270cdf0e10cSrcweir { 3271cdf0e10cSrcweir // give up 3272cdf0e10cSrcweir if( pCallback ) 3273cdf0e10cSrcweir pCallback->importFontFailed( aTo.PathToFileName(), ImportFontCallback::NoAfmMetric ); 3274cdf0e10cSrcweir continue; 3275cdf0e10cSrcweir } 3276cdf0e10cSrcweir } 3277cdf0e10cSrcweir } 3278cdf0e10cSrcweir } 3279cdf0e10cSrcweir INetURLObject aToAfm( aTo ); 3280cdf0e10cSrcweir aToAfm.setExtension( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "afm" ) ) ); 3281cdf0e10cSrcweir OUString aFromPath, aToPath; 3282cdf0e10cSrcweir if( bLinkOnly ) 3283cdf0e10cSrcweir { 3284cdf0e10cSrcweir ByteString aLinkFromPath( String(aFromAfm.PathToFileName()), 3285cdf0e10cSrcweir aEncoding ); 3286cdf0e10cSrcweir ByteString aLinkToPath( String(aToAfm.PathToFileName()), 3287cdf0e10cSrcweir aEncoding ); 3288cdf0e10cSrcweir nError = (FileBase::RC)symlink( aLinkFromPath.GetBuffer(), aLinkToPath.GetBuffer() ); 3289cdf0e10cSrcweir } 3290cdf0e10cSrcweir else 3291cdf0e10cSrcweir nError = File::copy( aFromAfm.GetMainURL(INetURLObject::DECODE_TO_IURI), aToAfm.GetMainURL(INetURLObject::DECODE_TO_IURI) ); 3292cdf0e10cSrcweir if( nError ) 3293cdf0e10cSrcweir { 3294cdf0e10cSrcweir if( pCallback ) 3295cdf0e10cSrcweir pCallback->importFontFailed( aTo.PathToFileName(), ImportFontCallback::AfmCopyFailed ); 3296cdf0e10cSrcweir continue; 3297cdf0e10cSrcweir } 3298cdf0e10cSrcweir aAfmCopied = aToPath; 3299cdf0e10cSrcweir } 3300cdf0e10cSrcweir if( bLinkOnly ) 3301cdf0e10cSrcweir { 3302cdf0e10cSrcweir ByteString aFromPath( String(aFrom.PathToFileName()), 3303cdf0e10cSrcweir aEncoding ); 3304cdf0e10cSrcweir ByteString aToPath( String(aTo.PathToFileName()), aEncoding ); 3305cdf0e10cSrcweir nError = (FileBase::RC)symlink( aFromPath.GetBuffer(), 3306cdf0e10cSrcweir aToPath.GetBuffer() ); 3307cdf0e10cSrcweir } 3308cdf0e10cSrcweir else 3309cdf0e10cSrcweir nError = File::copy( aFrom.GetMainURL(INetURLObject::DECODE_TO_IURI), aTo.GetMainURL(INetURLObject::DECODE_TO_IURI) ); 3310cdf0e10cSrcweir // copy font file 3311cdf0e10cSrcweir if( nError ) 3312cdf0e10cSrcweir { 3313cdf0e10cSrcweir if( aAfmCopied.getLength() ) 3314cdf0e10cSrcweir File::remove( aAfmCopied ); 3315cdf0e10cSrcweir if( pCallback ) 3316cdf0e10cSrcweir pCallback->importFontFailed( aTo.PathToFileName(), ImportFontCallback::FontCopyFailed ); 3317cdf0e10cSrcweir continue; 3318cdf0e10cSrcweir } 3319cdf0e10cSrcweir 3320cdf0e10cSrcweir ::std::list< PrintFont* > aNewFonts; 3321cdf0e10cSrcweir ::std::list< PrintFont* >::iterator it; 3322cdf0e10cSrcweir if( analyzeFontFile( nDirID, OUStringToOString( aTo.GetName(), aEncoding ), ::std::list<OString>(), aNewFonts ) ) 3323cdf0e10cSrcweir { 3324cdf0e10cSrcweir // remove all fonts for the same file 3325cdf0e10cSrcweir // discarding their font ids 3326cdf0e10cSrcweir ::std::hash_map< fontID, PrintFont* >::iterator current, next; 3327cdf0e10cSrcweir current = m_aFonts.begin(); 3328cdf0e10cSrcweir OString aFileName( OUStringToOString( aTo.GetName(), aEncoding ) ); 3329cdf0e10cSrcweir while( current != m_aFonts.end() ) 3330cdf0e10cSrcweir { 3331cdf0e10cSrcweir bool bRemove = false; 3332cdf0e10cSrcweir switch( current->second->m_eType ) 3333cdf0e10cSrcweir { 3334cdf0e10cSrcweir case fonttype::Type1: 3335cdf0e10cSrcweir if( static_cast<Type1FontFile*>(current->second)->m_aFontFile == aFileName ) 3336cdf0e10cSrcweir bRemove = true; 3337cdf0e10cSrcweir break; 3338cdf0e10cSrcweir case fonttype::TrueType: 3339cdf0e10cSrcweir if( static_cast<TrueTypeFontFile*>(current->second)->m_aFontFile == aFileName ) 3340cdf0e10cSrcweir bRemove = true; 3341cdf0e10cSrcweir break; 3342cdf0e10cSrcweir default: break; 3343cdf0e10cSrcweir } 3344cdf0e10cSrcweir if( bRemove ) 3345cdf0e10cSrcweir { 3346cdf0e10cSrcweir next = current; 3347cdf0e10cSrcweir ++next; 3348cdf0e10cSrcweir m_aFontFileToFontID[ aFileName ].erase( current->first ); 3349cdf0e10cSrcweir delete current->second; 3350cdf0e10cSrcweir m_aFonts.erase( current ); 3351cdf0e10cSrcweir current = next; 3352cdf0e10cSrcweir } 3353cdf0e10cSrcweir else 3354cdf0e10cSrcweir ++current; 3355cdf0e10cSrcweir } 3356cdf0e10cSrcweir 3357cdf0e10cSrcweir DBG_ASSERT( !findFontFileID( nDirID, aFileName ), "not all fonts removed for file" ); 3358cdf0e10cSrcweir 3359cdf0e10cSrcweir nSuccess++; 3360cdf0e10cSrcweir for( it = aNewFonts.begin(); it != aNewFonts.end(); ++it ) 3361cdf0e10cSrcweir { 3362cdf0e10cSrcweir m_aFontFileToFontID[ aFileName ].insert( m_nNextFontID ); 3363cdf0e10cSrcweir m_aFonts[ m_nNextFontID++ ] = *it; 3364cdf0e10cSrcweir m_pFontCache->updateFontCacheEntry( *it, false ); 3365cdf0e10cSrcweir } 3366cdf0e10cSrcweir } 3367cdf0e10cSrcweir } 3368cdf0e10cSrcweir 3369cdf0e10cSrcweir m_pFontCache->updateDirTimestamp( nDirID ); 3370cdf0e10cSrcweir m_pFontCache->flush(); 3371cdf0e10cSrcweir } 3372cdf0e10cSrcweir else if( pCallback ) 3373cdf0e10cSrcweir pCallback->importFontsFailed( ImportFontCallback::NoWritableDirectory ); 3374cdf0e10cSrcweir 3375cdf0e10cSrcweir return nSuccess; 3376cdf0e10cSrcweir } 3377cdf0e10cSrcweir 3378cdf0e10cSrcweir // ------------------------------------------------------------------------- 3379cdf0e10cSrcweir 3380cdf0e10cSrcweir bool PrintFontManager::checkImportPossible() const 3381cdf0e10cSrcweir { 3382cdf0e10cSrcweir bool bSuccess = false; 3383cdf0e10cSrcweir 3384cdf0e10cSrcweir // find a directory with write access 3385cdf0e10cSrcweir ByteString aDir; 3386cdf0e10cSrcweir for( std::list< int >::const_iterator dir_it = m_aPrivateFontDirectories.begin(); 3387cdf0e10cSrcweir dir_it != m_aPrivateFontDirectories.end(); ++dir_it ) 3388cdf0e10cSrcweir { 3389cdf0e10cSrcweir aDir = getDirectory( *dir_it ); 3390cdf0e10cSrcweir if( createWriteablePath( aDir ) ) 3391cdf0e10cSrcweir { 3392cdf0e10cSrcweir bSuccess = true; 3393cdf0e10cSrcweir break; 3394cdf0e10cSrcweir } 3395cdf0e10cSrcweir } 3396cdf0e10cSrcweir 3397cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 3398cdf0e10cSrcweir if( bSuccess ) 3399cdf0e10cSrcweir fprintf( stderr, "found writable %s\n", aDir.GetBuffer() ); 3400cdf0e10cSrcweir #endif 3401cdf0e10cSrcweir 3402cdf0e10cSrcweir return bSuccess; 3403cdf0e10cSrcweir } 3404cdf0e10cSrcweir 3405cdf0e10cSrcweir // ------------------------------------------------------------------------- 3406cdf0e10cSrcweir 3407cdf0e10cSrcweir bool PrintFontManager::checkChangeFontPropertiesPossible( fontID /*nFontID*/ ) const 3408cdf0e10cSrcweir { 3409cdf0e10cSrcweir // since font properties are changed in the font cache file only nowadays 3410cdf0e10cSrcweir // they can always be changed 3411cdf0e10cSrcweir return true; 3412cdf0e10cSrcweir } 3413cdf0e10cSrcweir 3414cdf0e10cSrcweir // ------------------------------------------------------------------------- 3415cdf0e10cSrcweir 3416cdf0e10cSrcweir bool PrintFontManager::changeFontProperties( fontID nFontID, const ::rtl::OUString& rXLFD ) 3417cdf0e10cSrcweir { 3418cdf0e10cSrcweir ByteString aXLFD( OUStringToOString( rXLFD, RTL_TEXTENCODING_UTF8 ) ); 3419cdf0e10cSrcweir ByteString aAddStyle = aXLFD.GetToken( '-', 6 ); 3420cdf0e10cSrcweir if( aAddStyle.Search( "utf8" ) == STRING_NOTFOUND ) 3421cdf0e10cSrcweir { 3422cdf0e10cSrcweir aAddStyle.Append( aAddStyle.Len() ? ";utf8" : "utf8" ); 3423cdf0e10cSrcweir aXLFD.SetToken( 6, ';', aAddStyle ); 3424cdf0e10cSrcweir } 3425cdf0e10cSrcweir PrintFont* pFont = getFont( nFontID ); 3426cdf0e10cSrcweir std::list< OString > aDummyList; 3427cdf0e10cSrcweir aDummyList.push_back( aXLFD ); 3428cdf0e10cSrcweir getFontAttributesFromXLFD( pFont, aDummyList ); 3429cdf0e10cSrcweir pFont->m_bUserOverride = true; 3430cdf0e10cSrcweir m_pFontCache->updateFontCacheEntry( pFont, true ); 3431cdf0e10cSrcweir 3432cdf0e10cSrcweir return true; 3433cdf0e10cSrcweir } 3434cdf0e10cSrcweir 3435cdf0e10cSrcweir // ------------------------------------------------------------------------- 3436cdf0e10cSrcweir 3437cdf0e10cSrcweir bool PrintFontManager:: 3438cdf0e10cSrcweir getImportableFontProperties( 3439cdf0e10cSrcweir const OString& rFile, 3440cdf0e10cSrcweir ::std::list< FastPrintFontInfo >& rFontProps 3441cdf0e10cSrcweir ) 3442cdf0e10cSrcweir { 3443cdf0e10cSrcweir rFontProps.clear(); 3444cdf0e10cSrcweir int nIndex = rFile.lastIndexOf( '/' ); 3445cdf0e10cSrcweir OString aDir, aFile( rFile.copy( nIndex+1 ) ); 3446cdf0e10cSrcweir if( nIndex != -1 ) 3447cdf0e10cSrcweir aDir = rFile.copy( 0, nIndex ); 3448cdf0e10cSrcweir int nDirID = getDirectoryAtom( aDir, true ); 3449cdf0e10cSrcweir ::std::list< PrintFont* > aFonts; 3450cdf0e10cSrcweir bool bRet = analyzeFontFile( nDirID, aFile, ::std::list<OString>(), aFonts ); 3451cdf0e10cSrcweir while( aFonts.begin() != aFonts.end() ) 3452cdf0e10cSrcweir { 3453cdf0e10cSrcweir PrintFont* pFont = aFonts.front(); 3454cdf0e10cSrcweir aFonts.pop_front(); 3455cdf0e10cSrcweir FastPrintFontInfo aInfo; 3456cdf0e10cSrcweir fillPrintFontInfo( pFont, aInfo ); 3457cdf0e10cSrcweir rFontProps.push_back( aInfo ); 3458cdf0e10cSrcweir delete pFont; 3459cdf0e10cSrcweir } 3460cdf0e10cSrcweir return bRet; 3461cdf0e10cSrcweir } 3462cdf0e10cSrcweir 3463cdf0e10cSrcweir // ------------------------------------------------------------------------- 3464cdf0e10cSrcweir 3465cdf0e10cSrcweir bool PrintFontManager::getFileDuplicates( fontID nFont, ::std::list< fontID >& rFonts ) const 3466cdf0e10cSrcweir { 3467cdf0e10cSrcweir bool bRet = false; 3468cdf0e10cSrcweir 3469cdf0e10cSrcweir rFonts.clear(); 3470cdf0e10cSrcweir 3471cdf0e10cSrcweir PrintFont* pSearchFont = getFont( nFont ); 3472cdf0e10cSrcweir if( ! pSearchFont || 3473cdf0e10cSrcweir pSearchFont->m_eType != fonttype::TrueType || 3474cdf0e10cSrcweir static_cast<TrueTypeFontFile*>(pSearchFont)->m_nCollectionEntry == -1 3475cdf0e10cSrcweir ) 3476cdf0e10cSrcweir return false; 3477cdf0e10cSrcweir 3478cdf0e10cSrcweir OString aFile( getFontFileSysPath( nFont ) ); 3479cdf0e10cSrcweir if( ! aFile.getLength() ) 3480cdf0e10cSrcweir return false; 3481cdf0e10cSrcweir 3482cdf0e10cSrcweir for( ::std::hash_map< fontID, PrintFont* >::const_iterator it = m_aFonts.begin(); it != m_aFonts.end(); ++it ) 3483cdf0e10cSrcweir { 3484cdf0e10cSrcweir if( nFont != it->first ) 3485cdf0e10cSrcweir { 3486cdf0e10cSrcweir OString aCompFile( getFontFile( it->second ) ); 3487cdf0e10cSrcweir if( aCompFile == aFile ) 3488cdf0e10cSrcweir { 3489cdf0e10cSrcweir rFonts.push_back( it->first ); 3490cdf0e10cSrcweir bRet = true; 3491cdf0e10cSrcweir } 3492cdf0e10cSrcweir } 3493cdf0e10cSrcweir } 3494cdf0e10cSrcweir return bRet; 3495cdf0e10cSrcweir } 3496cdf0e10cSrcweir 3497cdf0e10cSrcweir // ------------------------------------------------------------------------- 3498cdf0e10cSrcweir 3499cdf0e10cSrcweir bool PrintFontManager::removeFonts( const ::std::list< fontID >& rFonts ) 3500cdf0e10cSrcweir { 3501cdf0e10cSrcweir bool bRet = true; 3502cdf0e10cSrcweir ::std::list< fontID > aDuplicates; 3503cdf0e10cSrcweir for( ::std::list< fontID >::const_iterator it = rFonts.begin(); it != rFonts.end(); ++it ) 3504cdf0e10cSrcweir { 3505cdf0e10cSrcweir ::std::hash_map< fontID, PrintFont* >::const_iterator haveFont = m_aFonts.find( *it ); 3506cdf0e10cSrcweir if( haveFont == m_aFonts.end() ) 3507cdf0e10cSrcweir continue; 3508cdf0e10cSrcweir 3509cdf0e10cSrcweir PrintFont* pFont = haveFont->second; 3510cdf0e10cSrcweir bool bRemoveDuplicates = getFileDuplicates( *it, aDuplicates ); 3511cdf0e10cSrcweir ByteString aFile( getFontFile( pFont ) ); 3512cdf0e10cSrcweir if( aFile.Len() ) 3513cdf0e10cSrcweir { 3514cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 3515cdf0e10cSrcweir fprintf( stderr, "try unlink( \"%s\" ) ... ", aFile.GetBuffer() ); 3516cdf0e10cSrcweir #endif 3517cdf0e10cSrcweir if( unlink( aFile.GetBuffer() ) ) 3518cdf0e10cSrcweir { 3519cdf0e10cSrcweir bRet = false; 3520cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 3521cdf0e10cSrcweir fprintf( stderr, "failed\n" ); 3522cdf0e10cSrcweir #endif 3523cdf0e10cSrcweir continue; 3524cdf0e10cSrcweir } 3525cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 3526cdf0e10cSrcweir fprintf( stderr, "succeeded\n" ); 3527cdf0e10cSrcweir #endif 3528cdf0e10cSrcweir OString aAfm( getAfmFile( pFont ) ); 3529cdf0e10cSrcweir if( aAfm.getLength() ) 3530cdf0e10cSrcweir { 3531cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 3532cdf0e10cSrcweir fprintf( stderr, "unlink( \"%s\" )\n", aAfm.getStr() ); 3533cdf0e10cSrcweir #endif 3534cdf0e10cSrcweir unlink( aAfm.getStr() ); 3535cdf0e10cSrcweir } 3536cdf0e10cSrcweir m_aFonts.erase( *it ); 3537cdf0e10cSrcweir delete pFont; 3538cdf0e10cSrcweir if( bRemoveDuplicates ) 3539cdf0e10cSrcweir { 3540cdf0e10cSrcweir for( ::std::list< fontID >::iterator dup = aDuplicates.begin(); dup != aDuplicates.end(); ++dup ) 3541cdf0e10cSrcweir { 3542cdf0e10cSrcweir m_aFontFileToFontID[ aFile ].erase( *dup ); 3543cdf0e10cSrcweir PrintFont* pDup = m_aFonts[ *dup ]; 3544cdf0e10cSrcweir m_aFonts.erase( *dup ); 3545cdf0e10cSrcweir delete pDup; 3546cdf0e10cSrcweir } 3547cdf0e10cSrcweir } 3548cdf0e10cSrcweir } 3549cdf0e10cSrcweir } 3550cdf0e10cSrcweir return bRet; 3551cdf0e10cSrcweir } 3552cdf0e10cSrcweir 3553cdf0e10cSrcweir // ------------------------------------------------------------------------- 3554cdf0e10cSrcweir 3555cdf0e10cSrcweir bool PrintFontManager::isPrivateFontFile( fontID nFont ) const 3556cdf0e10cSrcweir { 3557cdf0e10cSrcweir bool bRet = false; 3558cdf0e10cSrcweir int nDirID = -1; 3559cdf0e10cSrcweir PrintFont* pFont = getFont( nFont ); 3560cdf0e10cSrcweir if( pFont ) 3561cdf0e10cSrcweir { 3562cdf0e10cSrcweir switch( pFont->m_eType ) 3563cdf0e10cSrcweir { 3564cdf0e10cSrcweir case fonttype::Type1: nDirID = static_cast< Type1FontFile* >(pFont)->m_nDirectory;break; 3565cdf0e10cSrcweir case fonttype::TrueType: nDirID = static_cast< TrueTypeFontFile* >(pFont)->m_nDirectory;break; 3566cdf0e10cSrcweir default: break; 3567cdf0e10cSrcweir } 3568cdf0e10cSrcweir } 3569cdf0e10cSrcweir if( nDirID != -1 ) 3570cdf0e10cSrcweir { 3571cdf0e10cSrcweir for( ::std::list< int >::const_iterator it = m_aPrivateFontDirectories.begin(); it != m_aPrivateFontDirectories.end(); ++it ) 3572cdf0e10cSrcweir { 3573cdf0e10cSrcweir if( nDirID == *it ) 3574cdf0e10cSrcweir { 3575cdf0e10cSrcweir bRet = true; 3576cdf0e10cSrcweir break; 3577cdf0e10cSrcweir } 3578cdf0e10cSrcweir } 3579cdf0e10cSrcweir } 3580cdf0e10cSrcweir return bRet; 3581cdf0e10cSrcweir } 3582cdf0e10cSrcweir 3583cdf0e10cSrcweir // ------------------------------------------------------------------------- 3584cdf0e10cSrcweir 3585cdf0e10cSrcweir bool PrintFontManager::getAlternativeFamilyNames( fontID nFont, ::std::list< OUString >& rNames ) const 3586cdf0e10cSrcweir { 3587cdf0e10cSrcweir rNames.clear(); 3588cdf0e10cSrcweir 3589cdf0e10cSrcweir PrintFont* pFont = getFont( nFont ); 3590cdf0e10cSrcweir if( pFont && pFont->m_eType == fonttype::TrueType ) 3591cdf0e10cSrcweir { 3592cdf0e10cSrcweir TrueTypeFontFile* pTTFontFile = static_cast< TrueTypeFontFile* >(pFont); 3593cdf0e10cSrcweir ByteString aFile( getFontFile( pFont ) ); 3594cdf0e10cSrcweir TrueTypeFont* pTTFont; 3595cdf0e10cSrcweir if( OpenTTFontFile( aFile.GetBuffer(), pTTFontFile->m_nCollectionEntry < 0 ? 0 : pTTFontFile->m_nCollectionEntry, &pTTFont ) == SF_OK ) 3596cdf0e10cSrcweir { 3597cdf0e10cSrcweir NameRecord* pNameRecords = NULL; 3598cdf0e10cSrcweir int nNameRecords = GetTTNameRecords( pTTFont, &pNameRecords ); 3599cdf0e10cSrcweir for( int i = 0; i < nNameRecords; i++ ) 3600cdf0e10cSrcweir { 3601cdf0e10cSrcweir if( pNameRecords[i].nameID != 1 ) // family name 3602cdf0e10cSrcweir continue; 3603cdf0e10cSrcweir 3604cdf0e10cSrcweir OUString aFamily( convertTrueTypeName( pNameRecords+i ) ); 3605cdf0e10cSrcweir if( aFamily.getLength() 3606cdf0e10cSrcweir && 3607cdf0e10cSrcweir m_pAtoms->getAtom( ATOM_FAMILYNAME, aFamily, sal_True ) != pFont->m_nFamilyName 3608cdf0e10cSrcweir ) 3609cdf0e10cSrcweir { 3610cdf0e10cSrcweir rNames.push_back( aFamily ); 3611cdf0e10cSrcweir } 3612cdf0e10cSrcweir } 3613cdf0e10cSrcweir 3614cdf0e10cSrcweir if( nNameRecords ) 3615cdf0e10cSrcweir DisposeNameRecords( pNameRecords, nNameRecords ); 3616cdf0e10cSrcweir CloseTTFont( pTTFont ); 3617cdf0e10cSrcweir } 3618cdf0e10cSrcweir } 3619cdf0e10cSrcweir return rNames.begin() != rNames.end(); 3620cdf0e10cSrcweir } 3621cdf0e10cSrcweir 3622cdf0e10cSrcweir // ------------------------------------------------------------------------- 3623cdf0e10cSrcweir 3624cdf0e10cSrcweir // TODO: move most of this stuff into the central font-subsetting code 3625cdf0e10cSrcweir bool PrintFontManager::createFontSubset( 3626cdf0e10cSrcweir FontSubsetInfo& rInfo, 3627cdf0e10cSrcweir fontID nFont, 3628cdf0e10cSrcweir const OUString& rOutFile, 3629*248a599fSHerbert Dürr sal_GlyphId* pGlyphIds, 3630cdf0e10cSrcweir sal_uInt8* pNewEncoding, 3631cdf0e10cSrcweir sal_Int32* pWidths, 3632cdf0e10cSrcweir int nGlyphs, 3633cdf0e10cSrcweir bool bVertical 3634cdf0e10cSrcweir ) 3635cdf0e10cSrcweir { 3636cdf0e10cSrcweir PrintFont* pFont = getFont( nFont ); 3637cdf0e10cSrcweir if( !pFont ) 3638cdf0e10cSrcweir return false; 3639cdf0e10cSrcweir 3640cdf0e10cSrcweir switch( pFont->m_eType ) 3641cdf0e10cSrcweir { 3642cdf0e10cSrcweir case psp::fonttype::TrueType: rInfo.m_nFontType = FontSubsetInfo::SFNT_TTF; break; 3643cdf0e10cSrcweir case psp::fonttype::Type1: rInfo.m_nFontType = FontSubsetInfo::ANY_TYPE1; break; 3644cdf0e10cSrcweir default: 3645cdf0e10cSrcweir return false; 3646cdf0e10cSrcweir } 3647cdf0e10cSrcweir // TODO: remove when Type1 subsetting gets implemented 3648cdf0e10cSrcweir if( pFont->m_eType != fonttype::TrueType ) 3649cdf0e10cSrcweir return false; 3650cdf0e10cSrcweir 3651cdf0e10cSrcweir // reshuffle array of requested glyphs to make sure glyph0==notdef 3652cdf0e10cSrcweir sal_uInt8 pEnc[256]; 3653cdf0e10cSrcweir sal_uInt16 pGID[256]; 3654cdf0e10cSrcweir sal_uInt8 pOldIndex[256]; 3655cdf0e10cSrcweir memset( pEnc, 0, sizeof( pEnc ) ); 3656cdf0e10cSrcweir memset( pGID, 0, sizeof( pGID ) ); 3657cdf0e10cSrcweir memset( pOldIndex, 0, sizeof( pOldIndex ) ); 3658cdf0e10cSrcweir if( nGlyphs > 256 ) 3659cdf0e10cSrcweir return false; 3660cdf0e10cSrcweir int nChar = 1; 3661cdf0e10cSrcweir for( int i = 0; i < nGlyphs; i++ ) 3662cdf0e10cSrcweir { 3663cdf0e10cSrcweir if( pNewEncoding[i] == 0 ) 3664cdf0e10cSrcweir { 3665cdf0e10cSrcweir pOldIndex[ 0 ] = i; 3666cdf0e10cSrcweir } 3667cdf0e10cSrcweir else 3668cdf0e10cSrcweir { 3669*248a599fSHerbert Dürr DBG_ASSERT( !(pGlyphIds[i] & 0x007f0000), "overlong glyph id" ); 3670cdf0e10cSrcweir DBG_ASSERT( (int)pNewEncoding[i] < nGlyphs, "encoding wrong" ); 3671cdf0e10cSrcweir DBG_ASSERT( pEnc[pNewEncoding[i]] == 0 && pGID[pNewEncoding[i]] == 0, "duplicate encoded glyph" ); 3672cdf0e10cSrcweir pEnc[ pNewEncoding[i] ] = pNewEncoding[i]; 3673*248a599fSHerbert Dürr pGID[ pNewEncoding[i] ] = (sal_uInt16)pGlyphIds[ i ]; 3674cdf0e10cSrcweir pOldIndex[ pNewEncoding[i] ] = i; 3675cdf0e10cSrcweir nChar++; 3676cdf0e10cSrcweir } 3677cdf0e10cSrcweir } 3678cdf0e10cSrcweir nGlyphs = nChar; // either input value or increased by one 3679cdf0e10cSrcweir 3680cdf0e10cSrcweir // prepare system name for read access for subset source file 3681cdf0e10cSrcweir // TODO: since this file is usually already mmapped there is no need to open it again 3682cdf0e10cSrcweir const ByteString aFromFile = getFontFile( pFont ); 3683cdf0e10cSrcweir 3684cdf0e10cSrcweir TrueTypeFont* pTTFont = NULL; // TODO: rename to SfntFont 3685cdf0e10cSrcweir TrueTypeFontFile* pTTFontFile = static_cast< TrueTypeFontFile* >(pFont); 3686cdf0e10cSrcweir if( OpenTTFontFile( aFromFile.GetBuffer(), pTTFontFile->m_nCollectionEntry < 0 ? 0 : pTTFontFile->m_nCollectionEntry, &pTTFont ) != SF_OK ) 3687cdf0e10cSrcweir return false; 3688cdf0e10cSrcweir 3689cdf0e10cSrcweir // prepare system name for write access for subset file target 3690cdf0e10cSrcweir OUString aSysPath; 3691cdf0e10cSrcweir if( osl_File_E_None != osl_getSystemPathFromFileURL( rOutFile.pData, &aSysPath.pData ) ) 3692cdf0e10cSrcweir return false; 3693cdf0e10cSrcweir const rtl_TextEncoding aEncoding = osl_getThreadTextEncoding(); 3694cdf0e10cSrcweir const ByteString aToFile( OUStringToOString( aSysPath, aEncoding ) ); 3695cdf0e10cSrcweir 3696cdf0e10cSrcweir // do CFF subsetting if possible 3697cdf0e10cSrcweir int nCffLength = 0; 3698cdf0e10cSrcweir const sal_uInt8* pCffBytes = NULL; 3699cdf0e10cSrcweir if( GetSfntTable( pTTFont, O_CFF, &pCffBytes, &nCffLength ) ) 3700cdf0e10cSrcweir { 3701cdf0e10cSrcweir rInfo.LoadFont( FontSubsetInfo::CFF_FONT, pCffBytes, nCffLength ); 3702cdf0e10cSrcweir #if 1 // TODO: remove 16bit->long conversion when related methods handle non-16bit glyphids 3703*248a599fSHerbert Dürr sal_GlyphId aRequestedGlyphIds[256]; 3704cdf0e10cSrcweir for( int i = 0; i < nGlyphs; ++i ) 3705*248a599fSHerbert Dürr aRequestedGlyphIds[i] = pGID[i]; 3706cdf0e10cSrcweir #endif 3707cdf0e10cSrcweir // create subset file at requested path 3708cdf0e10cSrcweir FILE* pOutFile = fopen( aToFile.GetBuffer(), "wb" ); 3709cdf0e10cSrcweir // create font subset 3710cdf0e10cSrcweir const char* pGlyphSetName = NULL; // TODO: better name? 3711cdf0e10cSrcweir const bool bOK = rInfo.CreateFontSubset( 3712cdf0e10cSrcweir FontSubsetInfo::TYPE1_PFB, 3713cdf0e10cSrcweir pOutFile, pGlyphSetName, 3714*248a599fSHerbert Dürr aRequestedGlyphIds, pEnc, nGlyphs, pWidths ); 3715cdf0e10cSrcweir fclose( pOutFile ); 3716cdf0e10cSrcweir // cleanup before early return 3717cdf0e10cSrcweir CloseTTFont( pTTFont ); 3718cdf0e10cSrcweir return bOK; 3719cdf0e10cSrcweir } 3720cdf0e10cSrcweir 3721cdf0e10cSrcweir // do TTF->Type42 or Type3 subsetting 3722cdf0e10cSrcweir // fill in font info 3723cdf0e10cSrcweir psp::PrintFontInfo aFontInfo; 3724cdf0e10cSrcweir if( ! getFontInfo( nFont, aFontInfo ) ) 3725cdf0e10cSrcweir return false; 3726cdf0e10cSrcweir 3727cdf0e10cSrcweir rInfo.m_nAscent = aFontInfo.m_nAscend; 3728cdf0e10cSrcweir rInfo.m_nDescent = aFontInfo.m_nDescend; 3729cdf0e10cSrcweir rInfo.m_aPSName = getPSName( nFont ); 3730cdf0e10cSrcweir 3731cdf0e10cSrcweir int xMin, yMin, xMax, yMax; 3732cdf0e10cSrcweir getFontBoundingBox( nFont, xMin, yMin, xMax, yMax ); 3733cdf0e10cSrcweir rInfo.m_aFontBBox = Rectangle( Point( xMin, yMin ), Size( xMax-xMin, yMax-yMin ) ); 3734cdf0e10cSrcweir rInfo.m_nCapHeight = yMax; // Well ... 3735cdf0e10cSrcweir 3736cdf0e10cSrcweir // fill in glyph advance widths 3737cdf0e10cSrcweir TTSimpleGlyphMetrics* pMetrics = GetTTSimpleGlyphMetrics( pTTFont, 3738cdf0e10cSrcweir pGID, 3739cdf0e10cSrcweir nGlyphs, 3740cdf0e10cSrcweir bVertical ? 1 : 0 ); 3741cdf0e10cSrcweir if( pMetrics ) 3742cdf0e10cSrcweir { 3743cdf0e10cSrcweir for( int i = 0; i < nGlyphs; i++ ) 3744cdf0e10cSrcweir pWidths[pOldIndex[i]] = pMetrics[i].adv; 3745cdf0e10cSrcweir free( pMetrics ); 3746cdf0e10cSrcweir } 3747cdf0e10cSrcweir else 3748cdf0e10cSrcweir { 3749cdf0e10cSrcweir CloseTTFont( pTTFont ); 3750cdf0e10cSrcweir return false; 3751cdf0e10cSrcweir } 3752cdf0e10cSrcweir 3753cdf0e10cSrcweir bool bSuccess = ( SF_OK == CreateTTFromTTGlyphs( pTTFont, 3754cdf0e10cSrcweir aToFile.GetBuffer(), 3755cdf0e10cSrcweir pGID, 3756cdf0e10cSrcweir pEnc, 3757cdf0e10cSrcweir nGlyphs, 3758cdf0e10cSrcweir 0, 3759cdf0e10cSrcweir NULL, 3760cdf0e10cSrcweir 0 ) ); 3761cdf0e10cSrcweir CloseTTFont( pTTFont ); 3762cdf0e10cSrcweir 3763cdf0e10cSrcweir return bSuccess; 3764cdf0e10cSrcweir } 3765cdf0e10cSrcweir 3766cdf0e10cSrcweir void PrintFontManager::getGlyphWidths( fontID nFont, 3767cdf0e10cSrcweir bool bVertical, 3768cdf0e10cSrcweir std::vector< sal_Int32 >& rWidths, 3769cdf0e10cSrcweir std::map< sal_Unicode, sal_uInt32 >& rUnicodeEnc ) 3770cdf0e10cSrcweir { 3771cdf0e10cSrcweir PrintFont* pFont = getFont( nFont ); 3772cdf0e10cSrcweir if( !pFont || 3773cdf0e10cSrcweir (pFont->m_eType != fonttype::TrueType && pFont->m_eType != fonttype::Type1) ) 3774cdf0e10cSrcweir return; 3775cdf0e10cSrcweir if( pFont->m_eType == fonttype::TrueType ) 3776cdf0e10cSrcweir { 3777cdf0e10cSrcweir TrueTypeFont* pTTFont = NULL; 3778cdf0e10cSrcweir TrueTypeFontFile* pTTFontFile = static_cast< TrueTypeFontFile* >(pFont); 3779cdf0e10cSrcweir ByteString aFromFile = getFontFile( pFont ); 3780cdf0e10cSrcweir if( OpenTTFontFile( aFromFile.GetBuffer(), pTTFontFile->m_nCollectionEntry < 0 ? 0 : pTTFontFile->m_nCollectionEntry, &pTTFont ) != SF_OK ) 3781cdf0e10cSrcweir return; 3782cdf0e10cSrcweir int nGlyphs = GetTTGlyphCount( pTTFont ); 3783cdf0e10cSrcweir if( nGlyphs > 0 ) 3784cdf0e10cSrcweir { 3785cdf0e10cSrcweir rWidths.resize(nGlyphs); 3786cdf0e10cSrcweir std::vector<sal_uInt16> aGlyphIds(nGlyphs); 3787cdf0e10cSrcweir for( int i = 0; i < nGlyphs; i++ ) 3788cdf0e10cSrcweir aGlyphIds[i] = sal_uInt16(i); 3789cdf0e10cSrcweir TTSimpleGlyphMetrics* pMetrics = GetTTSimpleGlyphMetrics( pTTFont, 3790cdf0e10cSrcweir &aGlyphIds[0], 3791cdf0e10cSrcweir nGlyphs, 3792cdf0e10cSrcweir bVertical ? 1 : 0 ); 3793cdf0e10cSrcweir if( pMetrics ) 3794cdf0e10cSrcweir { 3795cdf0e10cSrcweir for( int i = 0; i< nGlyphs; i++ ) 3796cdf0e10cSrcweir rWidths[i] = pMetrics[i].adv; 3797cdf0e10cSrcweir free( pMetrics ); 3798cdf0e10cSrcweir rUnicodeEnc.clear(); 3799cdf0e10cSrcweir } 3800cdf0e10cSrcweir 3801cdf0e10cSrcweir // fill the unicode map 3802cdf0e10cSrcweir // TODO: isn't this map already available elsewhere in the fontmanager? 3803cdf0e10cSrcweir const sal_uInt8* pCmapData = NULL; 3804cdf0e10cSrcweir int nCmapSize = 0; 3805cdf0e10cSrcweir if( GetSfntTable( pTTFont, O_cmap, &pCmapData, &nCmapSize ) ) 3806cdf0e10cSrcweir { 3807cdf0e10cSrcweir CmapResult aCmapResult; 3808cdf0e10cSrcweir if( ParseCMAP( pCmapData, nCmapSize, aCmapResult ) ) 3809cdf0e10cSrcweir { 3810cdf0e10cSrcweir const ImplFontCharMap aCharMap( aCmapResult ); 3811cdf0e10cSrcweir for( sal_uInt32 cOld = 0;;) 3812cdf0e10cSrcweir { 3813cdf0e10cSrcweir // get next unicode covered by font 3814cdf0e10cSrcweir const sal_uInt32 c = aCharMap.GetNextChar( cOld ); 3815cdf0e10cSrcweir if( c == cOld ) 3816cdf0e10cSrcweir break; 3817cdf0e10cSrcweir cOld = c; 3818cdf0e10cSrcweir #if 1 // TODO: remove when sal_Unicode covers all of unicode 3819cdf0e10cSrcweir if( c > (sal_Unicode)~0 ) 3820cdf0e10cSrcweir break; 3821cdf0e10cSrcweir #endif 3822cdf0e10cSrcweir // get the matching glyph index 3823*248a599fSHerbert Dürr const sal_GlyphId aGlyphId = aCharMap.GetGlyphIndex( c ); 3824cdf0e10cSrcweir // update the requested map 3825*248a599fSHerbert Dürr rUnicodeEnc[ (sal_Unicode)c ] = aGlyphId; 3826cdf0e10cSrcweir } 3827cdf0e10cSrcweir } 3828cdf0e10cSrcweir } 3829cdf0e10cSrcweir } 3830cdf0e10cSrcweir CloseTTFont( pTTFont ); 3831cdf0e10cSrcweir } 3832cdf0e10cSrcweir else if( pFont->m_eType == fonttype::Type1 ) 3833cdf0e10cSrcweir { 3834cdf0e10cSrcweir if( ! pFont->m_aEncodingVector.size() ) 3835cdf0e10cSrcweir pFont->readAfmMetrics( getAfmFile( pFont ), m_pAtoms, true, true ); 3836cdf0e10cSrcweir if( pFont->m_pMetrics ) 3837cdf0e10cSrcweir { 3838cdf0e10cSrcweir rUnicodeEnc.clear(); 3839cdf0e10cSrcweir rWidths.clear(); 3840cdf0e10cSrcweir rWidths.reserve( pFont->m_pMetrics->m_aMetrics.size() ); 3841cdf0e10cSrcweir for( std::hash_map< int, CharacterMetric >::const_iterator it = 3842cdf0e10cSrcweir pFont->m_pMetrics->m_aMetrics.begin(); 3843cdf0e10cSrcweir it != pFont->m_pMetrics->m_aMetrics.end(); ++it ) 3844cdf0e10cSrcweir { 3845cdf0e10cSrcweir if( (it->first & 0x00010000) == 0 || bVertical ) 3846cdf0e10cSrcweir { 3847cdf0e10cSrcweir rUnicodeEnc[ sal_Unicode(it->first & 0x0000ffff) ] = sal_uInt32(rWidths.size()); 3848cdf0e10cSrcweir rWidths.push_back( it->second.width ); 3849cdf0e10cSrcweir } 3850cdf0e10cSrcweir } 3851cdf0e10cSrcweir } 3852cdf0e10cSrcweir } 3853cdf0e10cSrcweir } 3854cdf0e10cSrcweir 3855cdf0e10cSrcweir // ------------------------------------------------------------------------- 3856cdf0e10cSrcweir 3857cdf0e10cSrcweir const std::map< sal_Unicode, sal_Int32 >* PrintFontManager::getEncodingMap( fontID nFont, const std::map< sal_Unicode, rtl::OString >** pNonEncoded ) const 3858cdf0e10cSrcweir { 3859cdf0e10cSrcweir PrintFont* pFont = getFont( nFont ); 3860cdf0e10cSrcweir if( !pFont || 3861cdf0e10cSrcweir (pFont->m_eType != fonttype::Type1 && pFont->m_eType != fonttype::Builtin) 3862cdf0e10cSrcweir ) 3863cdf0e10cSrcweir return NULL; 3864cdf0e10cSrcweir 3865cdf0e10cSrcweir if( ! pFont->m_aEncodingVector.size() ) 3866cdf0e10cSrcweir pFont->readAfmMetrics( getAfmFile( pFont ), m_pAtoms, true, true ); 3867cdf0e10cSrcweir 3868cdf0e10cSrcweir if( pNonEncoded ) 3869cdf0e10cSrcweir *pNonEncoded = pFont->m_aNonEncoded.size() ? &pFont->m_aNonEncoded : NULL; 3870cdf0e10cSrcweir 3871cdf0e10cSrcweir return pFont->m_aEncodingVector.size() ? &pFont->m_aEncodingVector : NULL; 3872cdf0e10cSrcweir } 3873cdf0e10cSrcweir 3874cdf0e10cSrcweir // ------------------------------------------------------------------------- 3875cdf0e10cSrcweir 3876cdf0e10cSrcweir std::list< OString > PrintFontManager::getAdobeNameFromUnicode( sal_Unicode aChar ) const 3877cdf0e10cSrcweir { 3878cdf0e10cSrcweir std::pair< std::hash_multimap< sal_Unicode, rtl::OString >::const_iterator, 3879cdf0e10cSrcweir std::hash_multimap< sal_Unicode, rtl::OString >::const_iterator > range 3880cdf0e10cSrcweir = m_aUnicodeToAdobename.equal_range( aChar ); 3881cdf0e10cSrcweir 3882cdf0e10cSrcweir std::list< OString > aRet; 3883cdf0e10cSrcweir for( ; range.first != range.second; ++range.first ) 3884cdf0e10cSrcweir aRet.push_back( range.first->second ); 3885cdf0e10cSrcweir 3886cdf0e10cSrcweir if( aRet.begin() == aRet.end() && aChar != 0 ) 3887cdf0e10cSrcweir { 3888cdf0e10cSrcweir sal_Char aBuf[8]; 3889cdf0e10cSrcweir sal_Int32 nChars = snprintf( (char*)aBuf, sizeof( aBuf ), "uni%.4hX", aChar ); 3890cdf0e10cSrcweir aRet.push_back( OString( aBuf, nChars ) ); 3891cdf0e10cSrcweir } 3892cdf0e10cSrcweir 3893cdf0e10cSrcweir return aRet; 3894cdf0e10cSrcweir } 3895cdf0e10cSrcweir 3896cdf0e10cSrcweir // ------------------------------------------------------------------------- 3897cdf0e10cSrcweir std::list< sal_Unicode > PrintFontManager::getUnicodeFromAdobeName( const rtl::OString& rName ) const 3898cdf0e10cSrcweir { 3899cdf0e10cSrcweir std::pair< std::hash_multimap< rtl::OString, sal_Unicode, rtl::OStringHash >::const_iterator, 3900cdf0e10cSrcweir std::hash_multimap< rtl::OString, sal_Unicode, rtl::OStringHash >::const_iterator > range 3901cdf0e10cSrcweir = m_aAdobenameToUnicode.equal_range( rName ); 3902cdf0e10cSrcweir 3903cdf0e10cSrcweir std::list< sal_Unicode > aRet; 3904cdf0e10cSrcweir for( ; range.first != range.second; ++range.first ) 3905cdf0e10cSrcweir aRet.push_back( range.first->second ); 3906cdf0e10cSrcweir 3907cdf0e10cSrcweir if( aRet.begin() == aRet.end() ) 3908cdf0e10cSrcweir { 3909cdf0e10cSrcweir if( rName.getLength() == 7 && rName.indexOf( "uni" ) == 0 ) 3910cdf0e10cSrcweir { 3911cdf0e10cSrcweir sal_Unicode aCode = (sal_Unicode)rName.copy( 3 ).toInt32( 16 ); 3912cdf0e10cSrcweir aRet.push_back( aCode ); 3913cdf0e10cSrcweir } 3914cdf0e10cSrcweir } 3915cdf0e10cSrcweir 3916cdf0e10cSrcweir return aRet; 3917cdf0e10cSrcweir } 3918cdf0e10cSrcweir 3919cdf0e10cSrcweir // ------------------------------------------------------------------------- 3920cdf0e10cSrcweir namespace 3921cdf0e10cSrcweir { 3922cdf0e10cSrcweir OUString getString( const Any& rAny ) 3923cdf0e10cSrcweir { 3924cdf0e10cSrcweir OUString aStr; 3925cdf0e10cSrcweir rAny >>= aStr; 3926cdf0e10cSrcweir return aStr; 3927cdf0e10cSrcweir } 3928cdf0e10cSrcweir bool getBool( const Any& rAny ) 3929cdf0e10cSrcweir { 3930cdf0e10cSrcweir sal_Bool bBool = sal_False; 3931cdf0e10cSrcweir rAny >>= bBool; 3932cdf0e10cSrcweir return static_cast<bool>(bBool); 3933cdf0e10cSrcweir } 3934cdf0e10cSrcweir sal_Int32 getInt( const Any& rAny ) 3935cdf0e10cSrcweir { 3936cdf0e10cSrcweir sal_Int32 n = 0; 3937cdf0e10cSrcweir rAny >>= n; 3938cdf0e10cSrcweir return n; 3939cdf0e10cSrcweir } 3940cdf0e10cSrcweir } 3941cdf0e10cSrcweir bool PrintFontManager::readOverrideMetrics() 3942cdf0e10cSrcweir { 3943cdf0e10cSrcweir if( ! m_aOverrideFonts.empty() ) 3944cdf0e10cSrcweir return false; 3945cdf0e10cSrcweir 3946cdf0e10cSrcweir css::uno::Reference< XMultiServiceFactory > xFact( comphelper::getProcessServiceFactory() ); 3947cdf0e10cSrcweir if( !xFact.is() ) 3948cdf0e10cSrcweir return false; 3949cdf0e10cSrcweir css::uno::Reference< XMaterialHolder > xMat( 3950cdf0e10cSrcweir xFact->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.psprint.CompatMetricOverride" ) ) ), 3951cdf0e10cSrcweir UNO_QUERY ); 3952cdf0e10cSrcweir if( !xMat.is() ) 3953cdf0e10cSrcweir return false; 3954cdf0e10cSrcweir 3955cdf0e10cSrcweir Any aAny( xMat->getMaterial() ); 3956cdf0e10cSrcweir Sequence< Any > aOverrideFonts; 3957cdf0e10cSrcweir if( ! (aAny >>= aOverrideFonts ) ) 3958cdf0e10cSrcweir return false; 3959cdf0e10cSrcweir sal_Int32 nFonts = aOverrideFonts.getLength(); 3960cdf0e10cSrcweir for( sal_Int32 i = 0; i < nFonts; i++ ) 3961cdf0e10cSrcweir { 3962cdf0e10cSrcweir Sequence< NamedValue > aMetrics; 3963cdf0e10cSrcweir if( ! (aOverrideFonts.getConstArray()[i] >>= aMetrics) ) 3964cdf0e10cSrcweir continue; 3965cdf0e10cSrcweir BuiltinFont* pFont = new BuiltinFont(); 3966cdf0e10cSrcweir pFont->m_nDirectory = 0; 3967cdf0e10cSrcweir pFont->m_bUserOverride = false; 3968cdf0e10cSrcweir pFont->m_pMetrics = new PrintFontMetrics; 3969cdf0e10cSrcweir memset( pFont->m_pMetrics->m_aPages, 0xff, sizeof( pFont->m_pMetrics->m_aPages ) ); 3970cdf0e10cSrcweir pFont->m_pMetrics->m_bKernPairsQueried = true; 3971cdf0e10cSrcweir sal_Int32 nProps = aMetrics.getLength(); 3972cdf0e10cSrcweir const NamedValue* pProps = aMetrics.getConstArray(); 3973cdf0e10cSrcweir for( sal_Int32 n = 0; n < nProps; n++ ) 3974cdf0e10cSrcweir { 3975cdf0e10cSrcweir if( pProps[n].Name.equalsAscii( "FamilyName" ) ) 3976cdf0e10cSrcweir pFont->m_nFamilyName = m_pAtoms->getAtom( ATOM_FAMILYNAME, 3977cdf0e10cSrcweir getString(pProps[n].Value), 3978cdf0e10cSrcweir sal_True ); 3979cdf0e10cSrcweir else if( pProps[n].Name.equalsAscii( "PSName" ) ) 3980cdf0e10cSrcweir pFont->m_nPSName = m_pAtoms->getAtom( ATOM_PSNAME, 3981cdf0e10cSrcweir getString(pProps[n].Value), 3982cdf0e10cSrcweir sal_True ); 3983cdf0e10cSrcweir else if( pProps[n].Name.equalsAscii( "StyleName" ) ) 3984cdf0e10cSrcweir pFont->m_aStyleName = getString(pProps[n].Value); 3985cdf0e10cSrcweir else if( pProps[n].Name.equalsAscii( "Italic" ) ) 3986cdf0e10cSrcweir pFont->m_eItalic = static_cast<italic::type>(getInt(pProps[n].Value)); 3987cdf0e10cSrcweir else if( pProps[n].Name.equalsAscii( "Width" ) ) 3988cdf0e10cSrcweir pFont->m_eWidth = static_cast<width::type>(getInt(pProps[n].Value)); 3989cdf0e10cSrcweir else if( pProps[n].Name.equalsAscii( "Weight" ) ) 3990cdf0e10cSrcweir pFont->m_eWeight = static_cast<weight::type>(getInt(pProps[n].Value)); 3991cdf0e10cSrcweir else if( pProps[n].Name.equalsAscii( "Pitch" ) ) 3992cdf0e10cSrcweir pFont->m_ePitch = static_cast<pitch::type>(getInt(pProps[n].Value)); 3993cdf0e10cSrcweir else if( pProps[n].Name.equalsAscii( "Encoding" ) ) 3994cdf0e10cSrcweir pFont->m_aEncoding = static_cast<rtl_TextEncoding>(getInt(pProps[n].Value)); 3995cdf0e10cSrcweir else if( pProps[n].Name.equalsAscii( "FontEncodingOnly" ) ) 3996cdf0e10cSrcweir pFont->m_bFontEncodingOnly = getBool(pProps[n].Value); 3997cdf0e10cSrcweir else if( pProps[n].Name.equalsAscii( "GlobalMetricXWidth" ) ) 3998cdf0e10cSrcweir pFont->m_aGlobalMetricX.width = getInt(pProps[n].Value); 3999cdf0e10cSrcweir else if( pProps[n].Name.equalsAscii( "GlobalMetricXHeight" ) ) 4000cdf0e10cSrcweir pFont->m_aGlobalMetricX.height = getInt(pProps[n].Value); 4001cdf0e10cSrcweir else if( pProps[n].Name.equalsAscii( "GlobalMetricYWidth" ) ) 4002cdf0e10cSrcweir pFont->m_aGlobalMetricY.width = getInt(pProps[n].Value); 4003cdf0e10cSrcweir else if( pProps[n].Name.equalsAscii( "GlobalMetricYHeight" ) ) 4004cdf0e10cSrcweir pFont->m_aGlobalMetricY.height = getInt(pProps[n].Value); 4005cdf0e10cSrcweir else if( pProps[n].Name.equalsAscii( "Ascend" ) ) 4006cdf0e10cSrcweir pFont->m_nAscend = getInt(pProps[n].Value); 4007cdf0e10cSrcweir else if( pProps[n].Name.equalsAscii( "Descend" ) ) 4008cdf0e10cSrcweir pFont->m_nDescend = getInt(pProps[n].Value); 4009cdf0e10cSrcweir else if( pProps[n].Name.equalsAscii( "Leading" ) ) 4010cdf0e10cSrcweir pFont->m_nLeading = getInt(pProps[n].Value); 4011cdf0e10cSrcweir else if( pProps[n].Name.equalsAscii( "XMin" ) ) 4012cdf0e10cSrcweir pFont->m_nXMin = getInt(pProps[n].Value); 4013cdf0e10cSrcweir else if( pProps[n].Name.equalsAscii( "YMin" ) ) 4014cdf0e10cSrcweir pFont->m_nYMin = getInt(pProps[n].Value); 4015cdf0e10cSrcweir else if( pProps[n].Name.equalsAscii( "XMax" ) ) 4016cdf0e10cSrcweir pFont->m_nXMax = getInt(pProps[n].Value); 4017cdf0e10cSrcweir else if( pProps[n].Name.equalsAscii( "YMax" ) ) 4018cdf0e10cSrcweir pFont->m_nYMax = getInt(pProps[n].Value); 4019cdf0e10cSrcweir else if( pProps[n].Name.equalsAscii( "VerticalSubstitutes" ) ) 4020cdf0e10cSrcweir pFont->m_bHaveVerticalSubstitutedGlyphs = getBool(pProps[n].Value); 4021cdf0e10cSrcweir else if( pProps[n].Name.equalsAscii( "EncodingVector" ) ) 4022cdf0e10cSrcweir { 4023cdf0e10cSrcweir Sequence< NamedValue > aEncoding; 4024cdf0e10cSrcweir pProps[n].Value >>= aEncoding; 4025cdf0e10cSrcweir sal_Int32 nEnc = aEncoding.getLength(); 4026cdf0e10cSrcweir const NamedValue* pEnc = aEncoding.getConstArray(); 4027cdf0e10cSrcweir for( sal_Int32 m = 0; m < nEnc; m++ ) 4028cdf0e10cSrcweir { 4029cdf0e10cSrcweir sal_Unicode cCode = *pEnc[m].Name.getStr(); 4030cdf0e10cSrcweir sal_Int32 nGlyph = getInt(pEnc[m].Value); 4031cdf0e10cSrcweir pFont->m_aEncodingVector[ cCode ] = nGlyph; 4032cdf0e10cSrcweir } 4033cdf0e10cSrcweir } 4034cdf0e10cSrcweir else if( pProps[n].Name.equalsAscii( "NonEncoded" ) ) 4035cdf0e10cSrcweir { 4036cdf0e10cSrcweir Sequence< NamedValue > aEncoding; 4037cdf0e10cSrcweir pProps[n].Value >>= aEncoding; 4038cdf0e10cSrcweir sal_Int32 nEnc = aEncoding.getLength(); 4039cdf0e10cSrcweir const NamedValue* pEnc = aEncoding.getConstArray(); 4040cdf0e10cSrcweir for( sal_Int32 m = 0; m < nEnc; m++ ) 4041cdf0e10cSrcweir { 4042cdf0e10cSrcweir sal_Unicode cCode = *pEnc[m].Name.getStr(); 4043cdf0e10cSrcweir OUString aGlyphName( getString(pEnc[m].Value) ); 4044cdf0e10cSrcweir pFont->m_aNonEncoded[ cCode ] = OUStringToOString(aGlyphName,RTL_TEXTENCODING_ASCII_US); 4045cdf0e10cSrcweir } 4046cdf0e10cSrcweir } 4047cdf0e10cSrcweir else if( pProps[n].Name.equalsAscii( "CharacterMetrics" ) ) 4048cdf0e10cSrcweir { 4049cdf0e10cSrcweir // fill pFont->m_pMetrics->m_aMetrics 4050cdf0e10cSrcweir // expect triples of int: int -> CharacterMetric.{ width, height } 4051cdf0e10cSrcweir Sequence< sal_Int32 > aSeq; 4052cdf0e10cSrcweir pProps[n].Value >>= aSeq; 4053cdf0e10cSrcweir sal_Int32 nInts = aSeq.getLength(); 4054cdf0e10cSrcweir const sal_Int32* pInts = aSeq.getConstArray(); 4055cdf0e10cSrcweir for( sal_Int32 m = 0; m < nInts; m+=3 ) 4056cdf0e10cSrcweir { 4057cdf0e10cSrcweir pFont->m_pMetrics->m_aMetrics[ pInts[m] ].width = static_cast<short int>(pInts[m+1]); 4058cdf0e10cSrcweir pFont->m_pMetrics->m_aMetrics[ pInts[m] ].height = static_cast<short int>(pInts[m+2]); 4059cdf0e10cSrcweir } 4060cdf0e10cSrcweir } 4061cdf0e10cSrcweir else if( pProps[n].Name.equalsAscii( "XKernPairs" ) ) 4062cdf0e10cSrcweir { 4063cdf0e10cSrcweir // fill pFont->m_pMetrics->m_aXKernPairs 4064cdf0e10cSrcweir // expection name: <unicode1><unicode2> value: ((height << 16)| width) 4065cdf0e10cSrcweir Sequence< NamedValue > aKern; 4066cdf0e10cSrcweir pProps[n].Value >>= aKern; 4067cdf0e10cSrcweir KernPair aPair; 4068cdf0e10cSrcweir const NamedValue* pVals = aKern.getConstArray(); 4069cdf0e10cSrcweir int nPairs = aKern.getLength(); 4070cdf0e10cSrcweir for( int m = 0; m < nPairs; m++ ) 4071cdf0e10cSrcweir { 4072cdf0e10cSrcweir if( pVals[m].Name.getLength() == 2 ) 4073cdf0e10cSrcweir { 4074cdf0e10cSrcweir aPair.first = pVals[m].Name.getStr()[0]; 4075cdf0e10cSrcweir aPair.second = pVals[m].Name.getStr()[1]; 4076cdf0e10cSrcweir sal_Int32 nKern = getInt( pVals[m].Value ); 4077cdf0e10cSrcweir aPair.kern_x = static_cast<short int>(nKern & 0xffff); 4078cdf0e10cSrcweir aPair.kern_y = static_cast<short int>((sal_uInt32(nKern) >> 16) & 0xffff); 4079cdf0e10cSrcweir pFont->m_pMetrics->m_aXKernPairs.push_back( aPair ); 4080cdf0e10cSrcweir } 4081cdf0e10cSrcweir } 4082cdf0e10cSrcweir } 4083cdf0e10cSrcweir } 4084cdf0e10cSrcweir // sanity check 4085cdf0e10cSrcweir if( pFont->m_nPSName && 4086cdf0e10cSrcweir pFont->m_nFamilyName && 4087cdf0e10cSrcweir ! pFont->m_pMetrics->m_aMetrics.empty() ) 4088cdf0e10cSrcweir { 4089cdf0e10cSrcweir m_aOverrideFonts.push_back( m_nNextFontID ); 4090cdf0e10cSrcweir m_aFonts[ m_nNextFontID++ ] = pFont; 4091cdf0e10cSrcweir } 4092cdf0e10cSrcweir else 4093cdf0e10cSrcweir { 4094cdf0e10cSrcweir DBG_ASSERT( 0, "override font failed" ); 4095cdf0e10cSrcweir delete pFont; 4096cdf0e10cSrcweir } 4097cdf0e10cSrcweir } 4098cdf0e10cSrcweir 4099cdf0e10cSrcweir return true; 4100cdf0e10cSrcweir } 4101