1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_unotools.hxx" 30*cdf0e10cSrcweir #include <unotools/fontcfg.hxx> 31*cdf0e10cSrcweir #include <unotools/fontdefs.hxx> 32*cdf0e10cSrcweir #include <comphelper/processfactory.hxx> 33*cdf0e10cSrcweir #include <com/sun/star/uno/Any.hxx> 34*cdf0e10cSrcweir #include <com/sun/star/uno/Sequence.hxx> 35*cdf0e10cSrcweir #include <com/sun/star/beans/PropertyValue.hpp> 36*cdf0e10cSrcweir #include <unotools/configpathes.hxx> 37*cdf0e10cSrcweir #include <unotools/syslocale.hxx> 38*cdf0e10cSrcweir #include <rtl/ustrbuf.hxx> 39*cdf0e10cSrcweir #include <tools/debug.hxx> 40*cdf0e10cSrcweir 41*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 42*cdf0e10cSrcweir #include <stdio.h> 43*cdf0e10cSrcweir #endif 44*cdf0e10cSrcweir 45*cdf0e10cSrcweir #include <string.h> 46*cdf0e10cSrcweir #include <list> 47*cdf0e10cSrcweir #include <algorithm> 48*cdf0e10cSrcweir 49*cdf0e10cSrcweir #define DEFAULTFONT_CONFIGNODE "VCL/DefaultFonts" 50*cdf0e10cSrcweir #define SUBSTFONT_CONFIGNODE "VCL/FontSubstitutions" 51*cdf0e10cSrcweir 52*cdf0e10cSrcweir using namespace rtl; 53*cdf0e10cSrcweir using namespace utl; 54*cdf0e10cSrcweir using namespace com::sun::star::uno; 55*cdf0e10cSrcweir using namespace com::sun::star::lang; 56*cdf0e10cSrcweir using namespace com::sun::star::beans; 57*cdf0e10cSrcweir using namespace com::sun::star::container; 58*cdf0e10cSrcweir 59*cdf0e10cSrcweir static DefaultFontConfiguration* mpDefaultFontConfiguration = 0; 60*cdf0e10cSrcweir 61*cdf0e10cSrcweir static FontSubstConfiguration* mpFontSubstConfiguration = 0; 62*cdf0e10cSrcweir 63*cdf0e10cSrcweir /* 64*cdf0e10cSrcweir * DefaultFontConfiguration 65*cdf0e10cSrcweir */ 66*cdf0e10cSrcweir 67*cdf0e10cSrcweir static const char* getKeyType( int nKeyType ) 68*cdf0e10cSrcweir { 69*cdf0e10cSrcweir switch( nKeyType ) 70*cdf0e10cSrcweir { 71*cdf0e10cSrcweir case DEFAULTFONT_CJK_DISPLAY: return "CJK_DISPLAY"; 72*cdf0e10cSrcweir case DEFAULTFONT_CJK_HEADING: return "CJK_HEADING"; 73*cdf0e10cSrcweir case DEFAULTFONT_CJK_PRESENTATION: return "CJK_PRESENTATION"; 74*cdf0e10cSrcweir case DEFAULTFONT_CJK_SPREADSHEET: return "CJK_SPREADSHEET"; 75*cdf0e10cSrcweir case DEFAULTFONT_CJK_TEXT: return "CJK_TEXT"; 76*cdf0e10cSrcweir case DEFAULTFONT_CTL_DISPLAY: return "CTL_DISPLAY"; 77*cdf0e10cSrcweir case DEFAULTFONT_CTL_HEADING: return "CTL_HEADING"; 78*cdf0e10cSrcweir case DEFAULTFONT_CTL_PRESENTATION: return "CTL_PRESENTATION"; 79*cdf0e10cSrcweir case DEFAULTFONT_CTL_SPREADSHEET: return "CTL_SPREADSHEET"; 80*cdf0e10cSrcweir case DEFAULTFONT_CTL_TEXT: return "CTL_TEXT"; 81*cdf0e10cSrcweir case DEFAULTFONT_FIXED: return "FIXED"; 82*cdf0e10cSrcweir case DEFAULTFONT_LATIN_DISPLAY: return "LATIN_DISPLAY"; 83*cdf0e10cSrcweir case DEFAULTFONT_LATIN_FIXED: return "LATIN_FIXED"; 84*cdf0e10cSrcweir case DEFAULTFONT_LATIN_HEADING: return "LATIN_HEADING"; 85*cdf0e10cSrcweir case DEFAULTFONT_LATIN_PRESENTATION: return "LATIN_PRESENTATION"; 86*cdf0e10cSrcweir case DEFAULTFONT_LATIN_SPREADSHEET: return "LATIN_SPREADSHEET"; 87*cdf0e10cSrcweir case DEFAULTFONT_LATIN_TEXT: return "LATIN_TEXT"; 88*cdf0e10cSrcweir case DEFAULTFONT_SANS: return "SANS"; 89*cdf0e10cSrcweir case DEFAULTFONT_SANS_UNICODE: return "SANS_UNICODE"; 90*cdf0e10cSrcweir case DEFAULTFONT_SERIF: return "SERIF"; 91*cdf0e10cSrcweir case DEFAULTFONT_SYMBOL: return "SYMBOL"; 92*cdf0e10cSrcweir case DEFAULTFONT_UI_FIXED: return "UI_FIXED"; 93*cdf0e10cSrcweir case DEFAULTFONT_UI_SANS: return "UI_SANS"; 94*cdf0e10cSrcweir default: 95*cdf0e10cSrcweir DBG_ERROR( "unmatched type" ); 96*cdf0e10cSrcweir return ""; 97*cdf0e10cSrcweir } 98*cdf0e10cSrcweir } 99*cdf0e10cSrcweir 100*cdf0e10cSrcweir DefaultFontConfiguration* DefaultFontConfiguration::get() 101*cdf0e10cSrcweir { 102*cdf0e10cSrcweir if( !mpDefaultFontConfiguration ) 103*cdf0e10cSrcweir mpDefaultFontConfiguration = new DefaultFontConfiguration(); 104*cdf0e10cSrcweir return mpDefaultFontConfiguration; 105*cdf0e10cSrcweir } 106*cdf0e10cSrcweir 107*cdf0e10cSrcweir DefaultFontConfiguration::DefaultFontConfiguration() 108*cdf0e10cSrcweir { 109*cdf0e10cSrcweir try 110*cdf0e10cSrcweir { 111*cdf0e10cSrcweir // get service provider 112*cdf0e10cSrcweir Reference< XMultiServiceFactory > xSMgr( comphelper::getProcessServiceFactory() ); 113*cdf0e10cSrcweir // create configuration hierachical access name 114*cdf0e10cSrcweir if( xSMgr.is() ) 115*cdf0e10cSrcweir { 116*cdf0e10cSrcweir try 117*cdf0e10cSrcweir { 118*cdf0e10cSrcweir m_xConfigProvider = 119*cdf0e10cSrcweir Reference< XMultiServiceFactory >( 120*cdf0e10cSrcweir xSMgr->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( 121*cdf0e10cSrcweir "com.sun.star.configuration.ConfigurationProvider" ))), 122*cdf0e10cSrcweir UNO_QUERY ); 123*cdf0e10cSrcweir if( m_xConfigProvider.is() ) 124*cdf0e10cSrcweir { 125*cdf0e10cSrcweir Sequence< Any > aArgs(1); 126*cdf0e10cSrcweir PropertyValue aVal; 127*cdf0e10cSrcweir aVal.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" ) ); 128*cdf0e10cSrcweir aVal.Value <<= OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.VCL/DefaultFonts" ) ); 129*cdf0e10cSrcweir aArgs.getArray()[0] <<= aVal; 130*cdf0e10cSrcweir m_xConfigAccess = 131*cdf0e10cSrcweir Reference< XNameAccess >( 132*cdf0e10cSrcweir m_xConfigProvider->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( 133*cdf0e10cSrcweir "com.sun.star.configuration.ConfigurationAccess" )), 134*cdf0e10cSrcweir aArgs ), 135*cdf0e10cSrcweir UNO_QUERY ); 136*cdf0e10cSrcweir if( m_xConfigAccess.is() ) 137*cdf0e10cSrcweir { 138*cdf0e10cSrcweir Sequence< OUString > aLocales = m_xConfigAccess->getElementNames(); 139*cdf0e10cSrcweir // fill config hash with empty interfaces 140*cdf0e10cSrcweir int nLocales = aLocales.getLength(); 141*cdf0e10cSrcweir const OUString* pLocaleStrings = aLocales.getConstArray(); 142*cdf0e10cSrcweir Locale aLoc; 143*cdf0e10cSrcweir for( int i = 0; i < nLocales; i++ ) 144*cdf0e10cSrcweir { 145*cdf0e10cSrcweir sal_Int32 nIndex = 0; 146*cdf0e10cSrcweir aLoc.Language = pLocaleStrings[i].getToken( 0, sal_Unicode('-'), nIndex ).toAsciiLowerCase(); 147*cdf0e10cSrcweir if( nIndex != -1 ) 148*cdf0e10cSrcweir aLoc.Country = pLocaleStrings[i].getToken( 0, sal_Unicode('-'), nIndex ).toAsciiUpperCase(); 149*cdf0e10cSrcweir else 150*cdf0e10cSrcweir aLoc.Country = OUString(); 151*cdf0e10cSrcweir if( nIndex != -1 ) 152*cdf0e10cSrcweir aLoc.Variant = pLocaleStrings[i].getToken( 0, sal_Unicode('-'), nIndex ).toAsciiUpperCase(); 153*cdf0e10cSrcweir else 154*cdf0e10cSrcweir aLoc.Variant = OUString(); 155*cdf0e10cSrcweir m_aConfig[ aLoc ] = LocaleAccess(); 156*cdf0e10cSrcweir m_aConfig[ aLoc ].aConfigLocaleString = pLocaleStrings[i]; 157*cdf0e10cSrcweir } 158*cdf0e10cSrcweir } 159*cdf0e10cSrcweir } 160*cdf0e10cSrcweir } 161*cdf0e10cSrcweir catch( Exception& ) 162*cdf0e10cSrcweir { 163*cdf0e10cSrcweir // configuration is awry 164*cdf0e10cSrcweir m_xConfigProvider.clear(); 165*cdf0e10cSrcweir m_xConfigAccess.clear(); 166*cdf0e10cSrcweir } 167*cdf0e10cSrcweir } 168*cdf0e10cSrcweir } 169*cdf0e10cSrcweir catch( WrappedTargetException& ) 170*cdf0e10cSrcweir { 171*cdf0e10cSrcweir } 172*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 173*cdf0e10cSrcweir fprintf( stderr, "config provider: %s, config access: %s\n", 174*cdf0e10cSrcweir m_xConfigProvider.is() ? "true" : "false", 175*cdf0e10cSrcweir m_xConfigAccess.is() ? "true" : "false" 176*cdf0e10cSrcweir ); 177*cdf0e10cSrcweir #endif 178*cdf0e10cSrcweir } 179*cdf0e10cSrcweir 180*cdf0e10cSrcweir DefaultFontConfiguration::~DefaultFontConfiguration() 181*cdf0e10cSrcweir { 182*cdf0e10cSrcweir // release all nodes 183*cdf0e10cSrcweir m_aConfig.clear(); 184*cdf0e10cSrcweir // release top node 185*cdf0e10cSrcweir m_xConfigAccess.clear(); 186*cdf0e10cSrcweir // release config provider 187*cdf0e10cSrcweir m_xConfigProvider.clear(); 188*cdf0e10cSrcweir } 189*cdf0e10cSrcweir 190*cdf0e10cSrcweir OUString DefaultFontConfiguration::tryLocale( const Locale& rLocale, const OUString& rType ) const 191*cdf0e10cSrcweir { 192*cdf0e10cSrcweir OUString aRet; 193*cdf0e10cSrcweir 194*cdf0e10cSrcweir std::hash_map< Locale, LocaleAccess, LocaleHash >::const_iterator it = 195*cdf0e10cSrcweir m_aConfig.find( rLocale ); 196*cdf0e10cSrcweir if( it != m_aConfig.end() ) 197*cdf0e10cSrcweir { 198*cdf0e10cSrcweir if( !it->second.xAccess.is() ) 199*cdf0e10cSrcweir { 200*cdf0e10cSrcweir try 201*cdf0e10cSrcweir { 202*cdf0e10cSrcweir Reference< XNameAccess > xNode; 203*cdf0e10cSrcweir if ( m_xConfigAccess->hasByName( it->second.aConfigLocaleString ) ) 204*cdf0e10cSrcweir { 205*cdf0e10cSrcweir Any aAny = m_xConfigAccess->getByName( it->second.aConfigLocaleString ); 206*cdf0e10cSrcweir if( aAny >>= xNode ) 207*cdf0e10cSrcweir it->second.xAccess = xNode; 208*cdf0e10cSrcweir } 209*cdf0e10cSrcweir } 210*cdf0e10cSrcweir catch( NoSuchElementException ) 211*cdf0e10cSrcweir { 212*cdf0e10cSrcweir } 213*cdf0e10cSrcweir catch( WrappedTargetException ) 214*cdf0e10cSrcweir { 215*cdf0e10cSrcweir } 216*cdf0e10cSrcweir } 217*cdf0e10cSrcweir if( it->second.xAccess.is() ) 218*cdf0e10cSrcweir { 219*cdf0e10cSrcweir try 220*cdf0e10cSrcweir { 221*cdf0e10cSrcweir if ( it->second.xAccess->hasByName( rType ) ) 222*cdf0e10cSrcweir { 223*cdf0e10cSrcweir Any aAny = it->second.xAccess->getByName( rType ); 224*cdf0e10cSrcweir aAny >>= aRet; 225*cdf0e10cSrcweir } 226*cdf0e10cSrcweir } 227*cdf0e10cSrcweir catch( NoSuchElementException& ) 228*cdf0e10cSrcweir { 229*cdf0e10cSrcweir } 230*cdf0e10cSrcweir catch( WrappedTargetException& ) 231*cdf0e10cSrcweir { 232*cdf0e10cSrcweir } 233*cdf0e10cSrcweir } 234*cdf0e10cSrcweir } 235*cdf0e10cSrcweir 236*cdf0e10cSrcweir return aRet; 237*cdf0e10cSrcweir } 238*cdf0e10cSrcweir 239*cdf0e10cSrcweir OUString DefaultFontConfiguration::getDefaultFont( const Locale& rLocale, int nType ) const 240*cdf0e10cSrcweir { 241*cdf0e10cSrcweir Locale aLocale; 242*cdf0e10cSrcweir aLocale.Language = rLocale.Language.toAsciiLowerCase(); 243*cdf0e10cSrcweir aLocale.Country = rLocale.Country.toAsciiUpperCase(); 244*cdf0e10cSrcweir aLocale.Variant = rLocale.Variant.toAsciiUpperCase(); 245*cdf0e10cSrcweir 246*cdf0e10cSrcweir OUString aType = OUString::createFromAscii( getKeyType( nType ) ); 247*cdf0e10cSrcweir OUString aRet = tryLocale( aLocale, aType ); 248*cdf0e10cSrcweir if( ! aRet.getLength() && aLocale.Variant.getLength() ) 249*cdf0e10cSrcweir { 250*cdf0e10cSrcweir aLocale.Variant = OUString(); 251*cdf0e10cSrcweir aRet = tryLocale( aLocale, aType ); 252*cdf0e10cSrcweir } 253*cdf0e10cSrcweir if( ! aRet.getLength() && aLocale.Country.getLength() ) 254*cdf0e10cSrcweir { 255*cdf0e10cSrcweir aLocale.Country = OUString(); 256*cdf0e10cSrcweir aRet = tryLocale( aLocale, aType ); 257*cdf0e10cSrcweir } 258*cdf0e10cSrcweir if( ! aRet.getLength() ) 259*cdf0e10cSrcweir { 260*cdf0e10cSrcweir aLocale.Language = OUString( RTL_CONSTASCII_USTRINGPARAM( "en" ) ); 261*cdf0e10cSrcweir aRet = tryLocale( aLocale, aType ); 262*cdf0e10cSrcweir } 263*cdf0e10cSrcweir return aRet; 264*cdf0e10cSrcweir } 265*cdf0e10cSrcweir 266*cdf0e10cSrcweir OUString DefaultFontConfiguration::getUserInterfaceFont( const Locale& rLocale ) const 267*cdf0e10cSrcweir { 268*cdf0e10cSrcweir Locale aLocale = rLocale; 269*cdf0e10cSrcweir if( ! aLocale.Language.getLength() ) 270*cdf0e10cSrcweir aLocale = SvtSysLocale().GetUILocale(); 271*cdf0e10cSrcweir 272*cdf0e10cSrcweir OUString aUIFont = getDefaultFont( aLocale, DEFAULTFONT_UI_SANS ); 273*cdf0e10cSrcweir 274*cdf0e10cSrcweir if( aUIFont.getLength() ) 275*cdf0e10cSrcweir return aUIFont; 276*cdf0e10cSrcweir 277*cdf0e10cSrcweir // fallback mechanism (either no configuration or no entry in configuration 278*cdf0e10cSrcweir 279*cdf0e10cSrcweir #define FALLBACKFONT_UI_SANS "Andale Sans UI;Albany;Albany AMT;Tahoma;Arial Unicode MS;Arial;Nimbus Sans L;Bitstream Vera Sans;gnu-unifont;Interface User;Geneva;WarpSans;Dialog;Swiss;Lucida;Helvetica;Charcoal;Chicago;MS Sans Serif;Helv;Times;Times New Roman;Interface System" 280*cdf0e10cSrcweir #define FALLBACKFONT_UI_SANS_LATIN2 "Andale Sans UI;Albany;Albany AMT;Tahoma;Arial Unicode MS;Arial;Nimbus Sans L;Luxi Sans;Bitstream Vera Sans;Interface User;Geneva;WarpSans;Dialog;Swiss;Lucida;Helvetica;Charcoal;Chicago;MS Sans Serif;Helv;Times;Times New Roman;Interface System" 281*cdf0e10cSrcweir #define FALLBACKFONT_UI_SANS_ARABIC "Tahoma;Traditional Arabic;Simplified Arabic;Lucidasans;Lucida Sans;Supplement;Andale Sans UI;clearlyU;Interface User;Arial Unicode MS;Lucida Sans Unicode;WarpSans;Geneva;MS Sans Serif;Helv;Dialog;Albany;Lucida;Helvetica;Charcoal;Chicago;Arial;Helmet;Interface System;Sans Serif" 282*cdf0e10cSrcweir #define FALLBACKFONT_UI_SANS_THAI "OONaksit;Tahoma;Lucidasans;Arial Unicode MS" 283*cdf0e10cSrcweir #define FALLBACKFONT_UI_SANS_KOREAN "SunGulim;BaekmukGulim;Gulim;Roundgothic;Arial Unicode MS;Lucida Sans Unicode;gnu-unifont;Andale Sans UI" 284*cdf0e10cSrcweir #define FALLBACKFONT_UI_SANS_JAPANESE1 "HG-GothicB-Sun;Andale Sans UI;HG MhinchoLightJ" 285*cdf0e10cSrcweir #define FALLBACKFONT_UI_SANS_JAPANESE2 "Kochi Gothic;Gothic" 286*cdf0e10cSrcweir #define FALLBACKFONT_UI_SANS_CHINSIM "Andale Sans UI;Arial Unicode MS;ZYSong18030;AR PL SungtiL GB;AR PL KaitiM GB;SimSun;Lucida Sans Unicode;Fangsong;Hei;Song;Kai;Ming;gnu-unifont;Interface User;" 287*cdf0e10cSrcweir #define FALLBACKFONT_UI_SANS_CHINTRD "Andale Sans UI;Arial Unicode MS;AR PL Mingti2L Big5;AR PL KaitiM Big5;Kai;PMingLiU;MingLiU;Ming;Lucida Sans Unicode;gnu-unifont;Interface User;" 288*cdf0e10cSrcweir 289*cdf0e10cSrcweir // we need localized names for japanese fonts 290*cdf0e10cSrcweir static sal_Unicode const aMSGothic[] = { 0xFF2D, 0xFF33, ' ', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0, 0 }; 291*cdf0e10cSrcweir static sal_Unicode const aMSPGothic[] = { 0xFF2D, 0xFF33, ' ', 0xFF30, 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0, 0 }; 292*cdf0e10cSrcweir static sal_Unicode const aTLPGothic[] = { 0x0054, 0x004C, 0x0050, 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0, 0 }; 293*cdf0e10cSrcweir static sal_Unicode const aLXGothic[] = { 0x004C, 0x0058, 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0, 0 }; 294*cdf0e10cSrcweir static sal_Unicode const aKochiGothic[] = { 0x6771, 0x98A8, 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0, 0 }; 295*cdf0e10cSrcweir 296*cdf0e10cSrcweir String aFallBackJapaneseLocalized( RTL_CONSTASCII_USTRINGPARAM( "MS UI Gothic;" ) ); 297*cdf0e10cSrcweir aFallBackJapaneseLocalized += String( RTL_CONSTASCII_USTRINGPARAM( FALLBACKFONT_UI_SANS_JAPANESE1 ) ); 298*cdf0e10cSrcweir aFallBackJapaneseLocalized += String( aMSPGothic ); 299*cdf0e10cSrcweir aFallBackJapaneseLocalized += String(RTL_CONSTASCII_USTRINGPARAM( ";" ) ); 300*cdf0e10cSrcweir aFallBackJapaneseLocalized += String( aMSGothic ); 301*cdf0e10cSrcweir aFallBackJapaneseLocalized += String(RTL_CONSTASCII_USTRINGPARAM( ";" ) ); 302*cdf0e10cSrcweir aFallBackJapaneseLocalized += String( aTLPGothic ); 303*cdf0e10cSrcweir aFallBackJapaneseLocalized += String(RTL_CONSTASCII_USTRINGPARAM( ";" ) ); 304*cdf0e10cSrcweir aFallBackJapaneseLocalized += String( aLXGothic ); 305*cdf0e10cSrcweir aFallBackJapaneseLocalized += String(RTL_CONSTASCII_USTRINGPARAM( ";" ) ); 306*cdf0e10cSrcweir aFallBackJapaneseLocalized += String( aKochiGothic ); 307*cdf0e10cSrcweir aFallBackJapaneseLocalized += String(RTL_CONSTASCII_USTRINGPARAM( ";" ) ); 308*cdf0e10cSrcweir aFallBackJapaneseLocalized += String(RTL_CONSTASCII_USTRINGPARAM( FALLBACKFONT_UI_SANS_JAPANESE2 ) ); 309*cdf0e10cSrcweir static const OUString aFallBackJapanese( aFallBackJapaneseLocalized ); 310*cdf0e10cSrcweir static const OUString aFallback (RTL_CONSTASCII_USTRINGPARAM(FALLBACKFONT_UI_SANS)); 311*cdf0e10cSrcweir static const OUString aFallbackLatin2 (RTL_CONSTASCII_USTRINGPARAM(FALLBACKFONT_UI_SANS_LATIN2)); 312*cdf0e10cSrcweir static const OUString aFallBackArabic (RTL_CONSTASCII_USTRINGPARAM( FALLBACKFONT_UI_SANS_ARABIC ) ); 313*cdf0e10cSrcweir static const OUString aFallBackThai (RTL_CONSTASCII_USTRINGPARAM( FALLBACKFONT_UI_SANS_THAI ) ); 314*cdf0e10cSrcweir static const OUString aFallBackChineseSIM (RTL_CONSTASCII_USTRINGPARAM( FALLBACKFONT_UI_SANS_CHINSIM ) ); 315*cdf0e10cSrcweir static const OUString aFallBackChineseTRD (RTL_CONSTASCII_USTRINGPARAM( FALLBACKFONT_UI_SANS_CHINTRD ) ); 316*cdf0e10cSrcweir 317*cdf0e10cSrcweir // we need localized names for korean fonts 318*cdf0e10cSrcweir static sal_Unicode const aSunGulim[] = { 0xC36C, 0xAD74, 0xB9BC, 0 }; 319*cdf0e10cSrcweir static sal_Unicode const aBaekmukGulim[] = { 0xBC31, 0xBC35, 0xAD74, 0xB9BC, 0 }; 320*cdf0e10cSrcweir String aFallBackKoreanLocalized( aSunGulim ); 321*cdf0e10cSrcweir aFallBackKoreanLocalized += String(RTL_CONSTASCII_USTRINGPARAM( ";" ) ); 322*cdf0e10cSrcweir aFallBackKoreanLocalized += String( aBaekmukGulim ); 323*cdf0e10cSrcweir aFallBackKoreanLocalized += String(RTL_CONSTASCII_USTRINGPARAM( ";" ) ); 324*cdf0e10cSrcweir aFallBackKoreanLocalized += String(RTL_CONSTASCII_USTRINGPARAM( FALLBACKFONT_UI_SANS_KOREAN ) ); 325*cdf0e10cSrcweir static const OUString aFallBackKorean( aFallBackKoreanLocalized ); 326*cdf0e10cSrcweir 327*cdf0e10cSrcweir // optimize font list for some locales, as long as Andale Sans UI does not support them 328*cdf0e10cSrcweir if( aLocale.Language.equalsAscii( "ar" ) || 329*cdf0e10cSrcweir aLocale.Language.equalsAscii( "he" ) || 330*cdf0e10cSrcweir aLocale.Language.equalsAscii( "iw" ) ) 331*cdf0e10cSrcweir { 332*cdf0e10cSrcweir return aFallBackArabic; 333*cdf0e10cSrcweir } 334*cdf0e10cSrcweir else if( aLocale.Language.equalsAscii( "th" ) ) 335*cdf0e10cSrcweir { 336*cdf0e10cSrcweir return aFallBackThai; 337*cdf0e10cSrcweir } 338*cdf0e10cSrcweir else if( aLocale.Language.equalsAscii( "ko" ) ) 339*cdf0e10cSrcweir { 340*cdf0e10cSrcweir return aFallBackKorean; 341*cdf0e10cSrcweir } 342*cdf0e10cSrcweir else if( aLocale.Language.equalsAscii( "cs" ) || 343*cdf0e10cSrcweir aLocale.Language.equalsAscii( "hu" ) || 344*cdf0e10cSrcweir aLocale.Language.equalsAscii( "pl" ) || 345*cdf0e10cSrcweir aLocale.Language.equalsAscii( "ro" ) || 346*cdf0e10cSrcweir aLocale.Language.equalsAscii( "rm" ) || 347*cdf0e10cSrcweir aLocale.Language.equalsAscii( "hr" ) || 348*cdf0e10cSrcweir aLocale.Language.equalsAscii( "sk" ) || 349*cdf0e10cSrcweir aLocale.Language.equalsAscii( "sl" ) || 350*cdf0e10cSrcweir aLocale.Language.equalsAscii( "sb" ) ) 351*cdf0e10cSrcweir { 352*cdf0e10cSrcweir return aFallbackLatin2; 353*cdf0e10cSrcweir } 354*cdf0e10cSrcweir else if( aLocale.Language.equalsAscii( "zh" ) ) 355*cdf0e10cSrcweir { 356*cdf0e10cSrcweir if( ! aLocale.Country.equalsAscii( "cn" ) ) 357*cdf0e10cSrcweir return aFallBackChineseTRD; 358*cdf0e10cSrcweir else 359*cdf0e10cSrcweir return aFallBackChineseSIM; 360*cdf0e10cSrcweir } 361*cdf0e10cSrcweir else if( aLocale.Language.equalsAscii( "ja" ) ) 362*cdf0e10cSrcweir { 363*cdf0e10cSrcweir return aFallBackJapanese; 364*cdf0e10cSrcweir } 365*cdf0e10cSrcweir 366*cdf0e10cSrcweir return aFallback; 367*cdf0e10cSrcweir } 368*cdf0e10cSrcweir 369*cdf0e10cSrcweir // ------------------------------------------------------------------------------------ 370*cdf0e10cSrcweir 371*cdf0e10cSrcweir /* 372*cdf0e10cSrcweir * FontSubstConfigItem::get 373*cdf0e10cSrcweir */ 374*cdf0e10cSrcweir 375*cdf0e10cSrcweir FontSubstConfiguration* FontSubstConfiguration::get() 376*cdf0e10cSrcweir { 377*cdf0e10cSrcweir if( !mpFontSubstConfiguration ) 378*cdf0e10cSrcweir mpFontSubstConfiguration = new FontSubstConfiguration(); 379*cdf0e10cSrcweir return mpFontSubstConfiguration; 380*cdf0e10cSrcweir } 381*cdf0e10cSrcweir 382*cdf0e10cSrcweir /* 383*cdf0e10cSrcweir * FontSubstConfigItem::FontSubstConfigItem 384*cdf0e10cSrcweir */ 385*cdf0e10cSrcweir 386*cdf0e10cSrcweir FontSubstConfiguration::FontSubstConfiguration() : 387*cdf0e10cSrcweir maSubstHash( 300 ) 388*cdf0e10cSrcweir { 389*cdf0e10cSrcweir try 390*cdf0e10cSrcweir { 391*cdf0e10cSrcweir // get service provider 392*cdf0e10cSrcweir Reference< XMultiServiceFactory > xSMgr( comphelper::getProcessServiceFactory() ); 393*cdf0e10cSrcweir // create configuration hierachical access name 394*cdf0e10cSrcweir if( xSMgr.is() ) 395*cdf0e10cSrcweir { 396*cdf0e10cSrcweir try 397*cdf0e10cSrcweir { 398*cdf0e10cSrcweir m_xConfigProvider = 399*cdf0e10cSrcweir Reference< XMultiServiceFactory >( 400*cdf0e10cSrcweir xSMgr->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( 401*cdf0e10cSrcweir "com.sun.star.configuration.ConfigurationProvider" ))), 402*cdf0e10cSrcweir UNO_QUERY ); 403*cdf0e10cSrcweir if( m_xConfigProvider.is() ) 404*cdf0e10cSrcweir { 405*cdf0e10cSrcweir Sequence< Any > aArgs(1); 406*cdf0e10cSrcweir PropertyValue aVal; 407*cdf0e10cSrcweir aVal.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" ) ); 408*cdf0e10cSrcweir aVal.Value <<= OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.VCL/FontSubstitutions" ) ); 409*cdf0e10cSrcweir aArgs.getArray()[0] <<= aVal; 410*cdf0e10cSrcweir m_xConfigAccess = 411*cdf0e10cSrcweir Reference< XNameAccess >( 412*cdf0e10cSrcweir m_xConfigProvider->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( 413*cdf0e10cSrcweir "com.sun.star.configuration.ConfigurationAccess" )), 414*cdf0e10cSrcweir aArgs ), 415*cdf0e10cSrcweir UNO_QUERY ); 416*cdf0e10cSrcweir if( m_xConfigAccess.is() ) 417*cdf0e10cSrcweir { 418*cdf0e10cSrcweir Sequence< OUString > aLocales = m_xConfigAccess->getElementNames(); 419*cdf0e10cSrcweir // fill config hash with empty interfaces 420*cdf0e10cSrcweir int nLocales = aLocales.getLength(); 421*cdf0e10cSrcweir const OUString* pLocaleStrings = aLocales.getConstArray(); 422*cdf0e10cSrcweir Locale aLoc; 423*cdf0e10cSrcweir for( int i = 0; i < nLocales; i++ ) 424*cdf0e10cSrcweir { 425*cdf0e10cSrcweir sal_Int32 nIndex = 0; 426*cdf0e10cSrcweir aLoc.Language = pLocaleStrings[i].getToken( 0, sal_Unicode('-'), nIndex ).toAsciiLowerCase(); 427*cdf0e10cSrcweir if( nIndex != -1 ) 428*cdf0e10cSrcweir aLoc.Country = pLocaleStrings[i].getToken( 0, sal_Unicode('-'), nIndex ).toAsciiUpperCase(); 429*cdf0e10cSrcweir else 430*cdf0e10cSrcweir aLoc.Country = OUString(); 431*cdf0e10cSrcweir if( nIndex != -1 ) 432*cdf0e10cSrcweir aLoc.Variant = pLocaleStrings[i].getToken( 0, sal_Unicode('-'), nIndex ).toAsciiUpperCase(); 433*cdf0e10cSrcweir else 434*cdf0e10cSrcweir aLoc.Variant = OUString(); 435*cdf0e10cSrcweir m_aSubst[ aLoc ] = LocaleSubst(); 436*cdf0e10cSrcweir m_aSubst[ aLoc ].aConfigLocaleString = pLocaleStrings[i]; 437*cdf0e10cSrcweir } 438*cdf0e10cSrcweir } 439*cdf0e10cSrcweir } 440*cdf0e10cSrcweir } 441*cdf0e10cSrcweir catch( Exception& ) 442*cdf0e10cSrcweir { 443*cdf0e10cSrcweir // configuration is awry 444*cdf0e10cSrcweir m_xConfigProvider.clear(); 445*cdf0e10cSrcweir m_xConfigAccess.clear(); 446*cdf0e10cSrcweir } 447*cdf0e10cSrcweir } 448*cdf0e10cSrcweir } 449*cdf0e10cSrcweir catch( WrappedTargetException& ) 450*cdf0e10cSrcweir { 451*cdf0e10cSrcweir } 452*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 453*cdf0e10cSrcweir fprintf( stderr, "config provider: %s, config access: %s\n", 454*cdf0e10cSrcweir m_xConfigProvider.is() ? "true" : "false", 455*cdf0e10cSrcweir m_xConfigAccess.is() ? "true" : "false" 456*cdf0e10cSrcweir ); 457*cdf0e10cSrcweir #endif 458*cdf0e10cSrcweir } 459*cdf0e10cSrcweir 460*cdf0e10cSrcweir /* 461*cdf0e10cSrcweir * FontSubstConfigItem::~FontSubstConfigItem 462*cdf0e10cSrcweir */ 463*cdf0e10cSrcweir 464*cdf0e10cSrcweir FontSubstConfiguration::~FontSubstConfiguration() 465*cdf0e10cSrcweir { 466*cdf0e10cSrcweir // release config access 467*cdf0e10cSrcweir m_xConfigAccess.clear(); 468*cdf0e10cSrcweir // release config provider 469*cdf0e10cSrcweir m_xConfigProvider.clear(); 470*cdf0e10cSrcweir } 471*cdf0e10cSrcweir 472*cdf0e10cSrcweir /* 473*cdf0e10cSrcweir * FontSubstConfigItem::getMapName 474*cdf0e10cSrcweir */ 475*cdf0e10cSrcweir // ======================================================================= 476*cdf0e10cSrcweir 477*cdf0e10cSrcweir static const char* const aImplKillLeadingList[] = 478*cdf0e10cSrcweir { 479*cdf0e10cSrcweir "microsoft", 480*cdf0e10cSrcweir "monotype", 481*cdf0e10cSrcweir "linotype", 482*cdf0e10cSrcweir "baekmuk", 483*cdf0e10cSrcweir "adobe", 484*cdf0e10cSrcweir "nimbus", 485*cdf0e10cSrcweir "zycjk", 486*cdf0e10cSrcweir "itc", 487*cdf0e10cSrcweir "sun", 488*cdf0e10cSrcweir "amt", 489*cdf0e10cSrcweir "ms", 490*cdf0e10cSrcweir "mt", 491*cdf0e10cSrcweir "cg", 492*cdf0e10cSrcweir "hg", 493*cdf0e10cSrcweir "fz", 494*cdf0e10cSrcweir "ipa", 495*cdf0e10cSrcweir "sazanami", 496*cdf0e10cSrcweir "kochi", 497*cdf0e10cSrcweir NULL 498*cdf0e10cSrcweir }; 499*cdf0e10cSrcweir 500*cdf0e10cSrcweir // ----------------------------------------------------------------------- 501*cdf0e10cSrcweir 502*cdf0e10cSrcweir static const char* const aImplKillTrailingList[] = 503*cdf0e10cSrcweir { 504*cdf0e10cSrcweir "microsoft", 505*cdf0e10cSrcweir "monotype", 506*cdf0e10cSrcweir "linotype", 507*cdf0e10cSrcweir "adobe", 508*cdf0e10cSrcweir "nimbus", 509*cdf0e10cSrcweir "itc", 510*cdf0e10cSrcweir "sun", 511*cdf0e10cSrcweir "amt", 512*cdf0e10cSrcweir "ms", 513*cdf0e10cSrcweir "mt", 514*cdf0e10cSrcweir "clm", 515*cdf0e10cSrcweir // Scripts, for compatibility with older versions 516*cdf0e10cSrcweir "we", 517*cdf0e10cSrcweir "cyr", 518*cdf0e10cSrcweir "tur", 519*cdf0e10cSrcweir "wt", 520*cdf0e10cSrcweir "greek", 521*cdf0e10cSrcweir "wl", 522*cdf0e10cSrcweir // CJK extensions 523*cdf0e10cSrcweir "gb", 524*cdf0e10cSrcweir "big5", 525*cdf0e10cSrcweir "pro", 526*cdf0e10cSrcweir "z01", 527*cdf0e10cSrcweir "z02", 528*cdf0e10cSrcweir "z03", 529*cdf0e10cSrcweir "z13", 530*cdf0e10cSrcweir "b01", 531*cdf0e10cSrcweir "w3x12", 532*cdf0e10cSrcweir // Old Printer Fontnames 533*cdf0e10cSrcweir "5cpi", 534*cdf0e10cSrcweir "6cpi", 535*cdf0e10cSrcweir "7cpi", 536*cdf0e10cSrcweir "8cpi", 537*cdf0e10cSrcweir "9cpi", 538*cdf0e10cSrcweir "10cpi", 539*cdf0e10cSrcweir "11cpi", 540*cdf0e10cSrcweir "12cpi", 541*cdf0e10cSrcweir "13cpi", 542*cdf0e10cSrcweir "14cpi", 543*cdf0e10cSrcweir "15cpi", 544*cdf0e10cSrcweir "16cpi", 545*cdf0e10cSrcweir "18cpi", 546*cdf0e10cSrcweir "24cpi", 547*cdf0e10cSrcweir "scale", 548*cdf0e10cSrcweir "pc", 549*cdf0e10cSrcweir NULL 550*cdf0e10cSrcweir }; 551*cdf0e10cSrcweir 552*cdf0e10cSrcweir // ----------------------------------------------------------------------- 553*cdf0e10cSrcweir 554*cdf0e10cSrcweir static const char* const aImplKillTrailingWithExceptionsList[] = 555*cdf0e10cSrcweir { 556*cdf0e10cSrcweir "ce", "monospace", "oldface", NULL, 557*cdf0e10cSrcweir "ps", "caps", NULL, 558*cdf0e10cSrcweir NULL 559*cdf0e10cSrcweir }; 560*cdf0e10cSrcweir 561*cdf0e10cSrcweir // ----------------------------------------------------------------------- 562*cdf0e10cSrcweir 563*cdf0e10cSrcweir struct ImplFontAttrWeightSearchData 564*cdf0e10cSrcweir { 565*cdf0e10cSrcweir const char* mpStr; 566*cdf0e10cSrcweir FontWeight meWeight; 567*cdf0e10cSrcweir }; 568*cdf0e10cSrcweir 569*cdf0e10cSrcweir static ImplFontAttrWeightSearchData const aImplWeightAttrSearchList[] = 570*cdf0e10cSrcweir { 571*cdf0e10cSrcweir // the attribute names are ordered by "first match wins" 572*cdf0e10cSrcweir // e.g. "semilight" should wins over "semi" 573*cdf0e10cSrcweir { "extrablack", WEIGHT_BLACK }, 574*cdf0e10cSrcweir { "ultrablack", WEIGHT_BLACK }, 575*cdf0e10cSrcweir { "ultrabold", WEIGHT_ULTRABOLD }, 576*cdf0e10cSrcweir { "semibold", WEIGHT_SEMIBOLD }, 577*cdf0e10cSrcweir { "semilight", WEIGHT_SEMILIGHT }, 578*cdf0e10cSrcweir { "semi", WEIGHT_SEMIBOLD }, 579*cdf0e10cSrcweir { "demi", WEIGHT_SEMIBOLD }, 580*cdf0e10cSrcweir { "black", WEIGHT_BLACK }, 581*cdf0e10cSrcweir { "bold", WEIGHT_BOLD }, 582*cdf0e10cSrcweir { "heavy", WEIGHT_BLACK }, 583*cdf0e10cSrcweir { "ultralight", WEIGHT_ULTRALIGHT }, 584*cdf0e10cSrcweir { "light", WEIGHT_LIGHT }, 585*cdf0e10cSrcweir { "medium", WEIGHT_MEDIUM }, 586*cdf0e10cSrcweir { NULL, WEIGHT_DONTKNOW }, 587*cdf0e10cSrcweir }; 588*cdf0e10cSrcweir 589*cdf0e10cSrcweir // ----------------------------------------------------------------------- 590*cdf0e10cSrcweir 591*cdf0e10cSrcweir struct ImplFontAttrWidthSearchData 592*cdf0e10cSrcweir { 593*cdf0e10cSrcweir const char* mpStr; 594*cdf0e10cSrcweir FontWidth meWidth; 595*cdf0e10cSrcweir }; 596*cdf0e10cSrcweir 597*cdf0e10cSrcweir static ImplFontAttrWidthSearchData const aImplWidthAttrSearchList[] = 598*cdf0e10cSrcweir { 599*cdf0e10cSrcweir { "narrow", WIDTH_CONDENSED }, 600*cdf0e10cSrcweir { "semicondensed", WIDTH_SEMI_CONDENSED }, 601*cdf0e10cSrcweir { "ultracondensed", WIDTH_ULTRA_CONDENSED }, 602*cdf0e10cSrcweir { "semiexpanded", WIDTH_SEMI_EXPANDED }, 603*cdf0e10cSrcweir { "ultraexpanded", WIDTH_ULTRA_EXPANDED }, 604*cdf0e10cSrcweir { "expanded", WIDTH_EXPANDED }, 605*cdf0e10cSrcweir { "wide", WIDTH_ULTRA_EXPANDED }, 606*cdf0e10cSrcweir { "condensed", WIDTH_CONDENSED }, 607*cdf0e10cSrcweir { "cond", WIDTH_CONDENSED }, 608*cdf0e10cSrcweir { "cn", WIDTH_CONDENSED }, 609*cdf0e10cSrcweir { NULL, WIDTH_DONTKNOW }, 610*cdf0e10cSrcweir }; 611*cdf0e10cSrcweir 612*cdf0e10cSrcweir struct ImplFontAttrTypeSearchData 613*cdf0e10cSrcweir { 614*cdf0e10cSrcweir const char* mpStr; 615*cdf0e10cSrcweir sal_uLong mnType; 616*cdf0e10cSrcweir }; 617*cdf0e10cSrcweir 618*cdf0e10cSrcweir static ImplFontAttrTypeSearchData const aImplTypeAttrSearchList[] = 619*cdf0e10cSrcweir { 620*cdf0e10cSrcweir { "monotype", 0 }, 621*cdf0e10cSrcweir { "linotype", 0 }, 622*cdf0e10cSrcweir { "titling", IMPL_FONT_ATTR_TITLING }, 623*cdf0e10cSrcweir { "captitals", IMPL_FONT_ATTR_CAPITALS }, 624*cdf0e10cSrcweir { "captital", IMPL_FONT_ATTR_CAPITALS }, 625*cdf0e10cSrcweir { "caps", IMPL_FONT_ATTR_CAPITALS }, 626*cdf0e10cSrcweir { "italic", IMPL_FONT_ATTR_ITALIC }, 627*cdf0e10cSrcweir { "oblique", IMPL_FONT_ATTR_ITALIC }, 628*cdf0e10cSrcweir { "rounded", IMPL_FONT_ATTR_ROUNDED }, 629*cdf0e10cSrcweir { "outline", IMPL_FONT_ATTR_OUTLINE }, 630*cdf0e10cSrcweir { "shadow", IMPL_FONT_ATTR_SHADOW }, 631*cdf0e10cSrcweir { "handwriting", IMPL_FONT_ATTR_HANDWRITING | IMPL_FONT_ATTR_SCRIPT }, 632*cdf0e10cSrcweir { "hand", IMPL_FONT_ATTR_HANDWRITING | IMPL_FONT_ATTR_SCRIPT }, 633*cdf0e10cSrcweir { "signet", IMPL_FONT_ATTR_HANDWRITING | IMPL_FONT_ATTR_SCRIPT }, 634*cdf0e10cSrcweir { "script", IMPL_FONT_ATTR_BRUSHSCRIPT | IMPL_FONT_ATTR_SCRIPT }, 635*cdf0e10cSrcweir { "calligraphy", IMPL_FONT_ATTR_CHANCERY | IMPL_FONT_ATTR_SCRIPT }, 636*cdf0e10cSrcweir { "chancery", IMPL_FONT_ATTR_CHANCERY | IMPL_FONT_ATTR_SCRIPT }, 637*cdf0e10cSrcweir { "corsiva", IMPL_FONT_ATTR_CHANCERY | IMPL_FONT_ATTR_SCRIPT }, 638*cdf0e10cSrcweir { "gothic", IMPL_FONT_ATTR_SANSSERIF | IMPL_FONT_ATTR_GOTHIC }, 639*cdf0e10cSrcweir { "schoolbook", IMPL_FONT_ATTR_SERIF | IMPL_FONT_ATTR_SCHOOLBOOK }, 640*cdf0e10cSrcweir { "schlbk", IMPL_FONT_ATTR_SERIF | IMPL_FONT_ATTR_SCHOOLBOOK }, 641*cdf0e10cSrcweir { "typewriter", IMPL_FONT_ATTR_TYPEWRITER | IMPL_FONT_ATTR_FIXED }, 642*cdf0e10cSrcweir { "lineprinter", IMPL_FONT_ATTR_TYPEWRITER | IMPL_FONT_ATTR_FIXED }, 643*cdf0e10cSrcweir { "monospaced", IMPL_FONT_ATTR_FIXED }, 644*cdf0e10cSrcweir { "monospace", IMPL_FONT_ATTR_FIXED }, 645*cdf0e10cSrcweir { "mono", IMPL_FONT_ATTR_FIXED }, 646*cdf0e10cSrcweir { "fixed", IMPL_FONT_ATTR_FIXED }, 647*cdf0e10cSrcweir { "sansserif", IMPL_FONT_ATTR_SANSSERIF }, 648*cdf0e10cSrcweir { "sans", IMPL_FONT_ATTR_SANSSERIF }, 649*cdf0e10cSrcweir { "swiss", IMPL_FONT_ATTR_SANSSERIF }, 650*cdf0e10cSrcweir { "serif", IMPL_FONT_ATTR_SERIF }, 651*cdf0e10cSrcweir { "bright", IMPL_FONT_ATTR_SERIF }, 652*cdf0e10cSrcweir { "symbols", IMPL_FONT_ATTR_SYMBOL }, 653*cdf0e10cSrcweir { "symbol", IMPL_FONT_ATTR_SYMBOL }, 654*cdf0e10cSrcweir { "dingbats", IMPL_FONT_ATTR_SYMBOL }, 655*cdf0e10cSrcweir { "dings", IMPL_FONT_ATTR_SYMBOL }, 656*cdf0e10cSrcweir { "ding", IMPL_FONT_ATTR_SYMBOL }, 657*cdf0e10cSrcweir { "bats", IMPL_FONT_ATTR_SYMBOL }, 658*cdf0e10cSrcweir { "math", IMPL_FONT_ATTR_SYMBOL }, 659*cdf0e10cSrcweir { "oldstyle", IMPL_FONT_ATTR_OTHERSTYLE }, 660*cdf0e10cSrcweir { "oldface", IMPL_FONT_ATTR_OTHERSTYLE }, 661*cdf0e10cSrcweir { "old", IMPL_FONT_ATTR_OTHERSTYLE }, 662*cdf0e10cSrcweir { "new", 0 }, 663*cdf0e10cSrcweir { "modern", 0 }, 664*cdf0e10cSrcweir { "lucida", 0 }, 665*cdf0e10cSrcweir { "regular", 0 }, 666*cdf0e10cSrcweir { "extended", 0 }, 667*cdf0e10cSrcweir { "extra", IMPL_FONT_ATTR_OTHERSTYLE }, 668*cdf0e10cSrcweir { "ext", 0 }, 669*cdf0e10cSrcweir { "scalable", 0 }, 670*cdf0e10cSrcweir { "scale", 0 }, 671*cdf0e10cSrcweir { "nimbus", 0 }, 672*cdf0e10cSrcweir { "adobe", 0 }, 673*cdf0e10cSrcweir { "itc", 0 }, 674*cdf0e10cSrcweir { "amt", 0 }, 675*cdf0e10cSrcweir { "mt", 0 }, 676*cdf0e10cSrcweir { "ms", 0 }, 677*cdf0e10cSrcweir { "cpi", 0 }, 678*cdf0e10cSrcweir { "no", 0 }, 679*cdf0e10cSrcweir { NULL, 0 }, 680*cdf0e10cSrcweir }; 681*cdf0e10cSrcweir 682*cdf0e10cSrcweir // ----------------------------------------------------------------------- 683*cdf0e10cSrcweir 684*cdf0e10cSrcweir static bool ImplKillLeading( String& rName, const char* const* ppStr ) 685*cdf0e10cSrcweir { 686*cdf0e10cSrcweir for(; *ppStr; ++ppStr ) 687*cdf0e10cSrcweir { 688*cdf0e10cSrcweir const char* pStr = *ppStr; 689*cdf0e10cSrcweir const xub_Unicode* pNameStr = rName.GetBuffer(); 690*cdf0e10cSrcweir while ( (*pNameStr == (xub_Unicode)(unsigned char)*pStr) && *pStr ) 691*cdf0e10cSrcweir { 692*cdf0e10cSrcweir pNameStr++; 693*cdf0e10cSrcweir pStr++; 694*cdf0e10cSrcweir } 695*cdf0e10cSrcweir if ( !*pStr ) 696*cdf0e10cSrcweir { 697*cdf0e10cSrcweir xub_StrLen nLen = sal::static_int_cast<xub_StrLen>(pNameStr - rName.GetBuffer()); 698*cdf0e10cSrcweir rName.Erase( 0, nLen ); 699*cdf0e10cSrcweir return true; 700*cdf0e10cSrcweir } 701*cdf0e10cSrcweir } 702*cdf0e10cSrcweir 703*cdf0e10cSrcweir // special case for Baekmuk 704*cdf0e10cSrcweir // TODO: allow non-ASCII KillLeading list 705*cdf0e10cSrcweir const xub_Unicode* pNameStr = rName.GetBuffer(); 706*cdf0e10cSrcweir if( (pNameStr[0]==0xBC31) && (pNameStr[1]==0xBC35) ) 707*cdf0e10cSrcweir { 708*cdf0e10cSrcweir xub_StrLen nLen = (pNameStr[2]==0x0020) ? 3 : 2; 709*cdf0e10cSrcweir rName.Erase( 0, nLen ); 710*cdf0e10cSrcweir return true; 711*cdf0e10cSrcweir } 712*cdf0e10cSrcweir 713*cdf0e10cSrcweir return false; 714*cdf0e10cSrcweir } 715*cdf0e10cSrcweir 716*cdf0e10cSrcweir // ----------------------------------------------------------------------- 717*cdf0e10cSrcweir 718*cdf0e10cSrcweir static xub_StrLen ImplIsTrailing( const String& rName, const char* pStr ) 719*cdf0e10cSrcweir { 720*cdf0e10cSrcweir xub_StrLen nStrLen = static_cast<xub_StrLen>( strlen( pStr ) ); 721*cdf0e10cSrcweir if( nStrLen >= rName.Len() ) 722*cdf0e10cSrcweir return 0; 723*cdf0e10cSrcweir 724*cdf0e10cSrcweir const xub_Unicode* pEndName = rName.GetBuffer() + rName.Len(); 725*cdf0e10cSrcweir const sal_Unicode* pNameStr = pEndName - nStrLen; 726*cdf0e10cSrcweir do if( *(pNameStr++) != *(pStr++) ) 727*cdf0e10cSrcweir return 0; 728*cdf0e10cSrcweir while( *pStr ); 729*cdf0e10cSrcweir 730*cdf0e10cSrcweir return nStrLen; 731*cdf0e10cSrcweir } 732*cdf0e10cSrcweir 733*cdf0e10cSrcweir // ----------------------------------------------------------------------- 734*cdf0e10cSrcweir 735*cdf0e10cSrcweir static bool ImplKillTrailing( String& rName, const char* const* ppStr ) 736*cdf0e10cSrcweir { 737*cdf0e10cSrcweir for(; *ppStr; ++ppStr ) 738*cdf0e10cSrcweir { 739*cdf0e10cSrcweir xub_StrLen nTrailLen = ImplIsTrailing( rName, *ppStr ); 740*cdf0e10cSrcweir if( nTrailLen ) 741*cdf0e10cSrcweir { 742*cdf0e10cSrcweir rName.Erase( rName.Len()-nTrailLen ); 743*cdf0e10cSrcweir return true; 744*cdf0e10cSrcweir } 745*cdf0e10cSrcweir } 746*cdf0e10cSrcweir 747*cdf0e10cSrcweir return false; 748*cdf0e10cSrcweir } 749*cdf0e10cSrcweir 750*cdf0e10cSrcweir // ----------------------------------------------------------------------- 751*cdf0e10cSrcweir 752*cdf0e10cSrcweir static bool ImplKillTrailingWithExceptions( String& rName, const char* const* ppStr ) 753*cdf0e10cSrcweir { 754*cdf0e10cSrcweir for(; *ppStr; ++ppStr ) 755*cdf0e10cSrcweir { 756*cdf0e10cSrcweir xub_StrLen nTrailLen = ImplIsTrailing( rName, *ppStr ); 757*cdf0e10cSrcweir if( nTrailLen ) 758*cdf0e10cSrcweir { 759*cdf0e10cSrcweir // check string match against string exceptions 760*cdf0e10cSrcweir while( *++ppStr ) 761*cdf0e10cSrcweir if( ImplIsTrailing( rName, *ppStr ) ) 762*cdf0e10cSrcweir return false; 763*cdf0e10cSrcweir 764*cdf0e10cSrcweir rName.Erase( rName.Len()-nTrailLen ); 765*cdf0e10cSrcweir return true; 766*cdf0e10cSrcweir } 767*cdf0e10cSrcweir else 768*cdf0e10cSrcweir { 769*cdf0e10cSrcweir // skip exception strings 770*cdf0e10cSrcweir while( *++ppStr ) ; 771*cdf0e10cSrcweir } 772*cdf0e10cSrcweir } 773*cdf0e10cSrcweir 774*cdf0e10cSrcweir return false; 775*cdf0e10cSrcweir } 776*cdf0e10cSrcweir 777*cdf0e10cSrcweir // ----------------------------------------------------------------------- 778*cdf0e10cSrcweir 779*cdf0e10cSrcweir static sal_Bool ImplFindAndErase( String& rName, const char* pStr ) 780*cdf0e10cSrcweir { 781*cdf0e10cSrcweir xub_StrLen nPos = rName.SearchAscii( pStr ); 782*cdf0e10cSrcweir if ( nPos == STRING_NOTFOUND ) 783*cdf0e10cSrcweir return sal_False; 784*cdf0e10cSrcweir 785*cdf0e10cSrcweir const char* pTempStr = pStr; 786*cdf0e10cSrcweir while ( *pTempStr ) 787*cdf0e10cSrcweir pTempStr++; 788*cdf0e10cSrcweir rName.Erase( nPos, (xub_StrLen)(pTempStr-pStr) ); 789*cdf0e10cSrcweir return sal_True; 790*cdf0e10cSrcweir } 791*cdf0e10cSrcweir 792*cdf0e10cSrcweir // ======================================================================= 793*cdf0e10cSrcweir 794*cdf0e10cSrcweir void FontSubstConfiguration::getMapName( const String& rOrgName, String& rShortName, 795*cdf0e10cSrcweir String& rFamilyName, FontWeight& rWeight, FontWidth& rWidth, sal_uLong& rType ) 796*cdf0e10cSrcweir { 797*cdf0e10cSrcweir rShortName = rOrgName; 798*cdf0e10cSrcweir 799*cdf0e10cSrcweir // TODO: get rid of the crazy O(N*strlen) searches below 800*cdf0e10cSrcweir // they should be possible in O(strlen) 801*cdf0e10cSrcweir 802*cdf0e10cSrcweir // Kill leading vendor names and other unimportant data 803*cdf0e10cSrcweir ImplKillLeading( rShortName, aImplKillLeadingList ); 804*cdf0e10cSrcweir 805*cdf0e10cSrcweir // Kill trailing vendor names and other unimportant data 806*cdf0e10cSrcweir ImplKillTrailing( rShortName, aImplKillTrailingList ); 807*cdf0e10cSrcweir ImplKillTrailingWithExceptions( rShortName, aImplKillTrailingWithExceptionsList ); 808*cdf0e10cSrcweir 809*cdf0e10cSrcweir rFamilyName = rShortName; 810*cdf0e10cSrcweir 811*cdf0e10cSrcweir // Kill attributes from the name and update the data 812*cdf0e10cSrcweir // Weight 813*cdf0e10cSrcweir const ImplFontAttrWeightSearchData* pWeightList = aImplWeightAttrSearchList; 814*cdf0e10cSrcweir while ( pWeightList->mpStr ) 815*cdf0e10cSrcweir { 816*cdf0e10cSrcweir if ( ImplFindAndErase( rFamilyName, pWeightList->mpStr ) ) 817*cdf0e10cSrcweir { 818*cdf0e10cSrcweir if ( (rWeight == WEIGHT_DONTKNOW) || (rWeight == WEIGHT_NORMAL) ) 819*cdf0e10cSrcweir rWeight = pWeightList->meWeight; 820*cdf0e10cSrcweir break; 821*cdf0e10cSrcweir } 822*cdf0e10cSrcweir pWeightList++; 823*cdf0e10cSrcweir } 824*cdf0e10cSrcweir 825*cdf0e10cSrcweir // Width 826*cdf0e10cSrcweir const ImplFontAttrWidthSearchData* pWidthList = aImplWidthAttrSearchList; 827*cdf0e10cSrcweir while ( pWidthList->mpStr ) 828*cdf0e10cSrcweir { 829*cdf0e10cSrcweir if ( ImplFindAndErase( rFamilyName, pWidthList->mpStr ) ) 830*cdf0e10cSrcweir { 831*cdf0e10cSrcweir if ( (rWidth == WIDTH_DONTKNOW) || (rWidth == WIDTH_NORMAL) ) 832*cdf0e10cSrcweir rWidth = pWidthList->meWidth; 833*cdf0e10cSrcweir break; 834*cdf0e10cSrcweir } 835*cdf0e10cSrcweir pWidthList++; 836*cdf0e10cSrcweir } 837*cdf0e10cSrcweir 838*cdf0e10cSrcweir // Type 839*cdf0e10cSrcweir rType = 0; 840*cdf0e10cSrcweir const ImplFontAttrTypeSearchData* pTypeList = aImplTypeAttrSearchList; 841*cdf0e10cSrcweir while ( pTypeList->mpStr ) 842*cdf0e10cSrcweir { 843*cdf0e10cSrcweir if ( ImplFindAndErase( rFamilyName, pTypeList->mpStr ) ) 844*cdf0e10cSrcweir rType |= pTypeList->mnType; 845*cdf0e10cSrcweir pTypeList++; 846*cdf0e10cSrcweir } 847*cdf0e10cSrcweir 848*cdf0e10cSrcweir // Remove numbers 849*cdf0e10cSrcweir // TODO: also remove localized and fullwidth digits 850*cdf0e10cSrcweir xub_StrLen i = 0; 851*cdf0e10cSrcweir while ( i < rFamilyName.Len() ) 852*cdf0e10cSrcweir { 853*cdf0e10cSrcweir sal_Unicode c = rFamilyName.GetChar( i ); 854*cdf0e10cSrcweir if ( (c >= 0x0030) && (c <= 0x0039) ) 855*cdf0e10cSrcweir rFamilyName.Erase( i, 1 ); 856*cdf0e10cSrcweir else 857*cdf0e10cSrcweir i++; 858*cdf0e10cSrcweir } 859*cdf0e10cSrcweir } 860*cdf0e10cSrcweir 861*cdf0e10cSrcweir 862*cdf0e10cSrcweir struct StrictStringSort : public ::std::binary_function< const FontNameAttr&, const FontNameAttr&, bool > 863*cdf0e10cSrcweir { 864*cdf0e10cSrcweir bool operator()( const FontNameAttr& rLeft, const FontNameAttr& rRight ) 865*cdf0e10cSrcweir { return rLeft.Name.CompareTo( rRight.Name ) == COMPARE_LESS ; } 866*cdf0e10cSrcweir }; 867*cdf0e10cSrcweir 868*cdf0e10cSrcweir static const char* const pAttribNames[] = 869*cdf0e10cSrcweir { 870*cdf0e10cSrcweir "default", 871*cdf0e10cSrcweir "standard", 872*cdf0e10cSrcweir "normal", 873*cdf0e10cSrcweir "symbol", 874*cdf0e10cSrcweir "fixed", 875*cdf0e10cSrcweir "sansserif", 876*cdf0e10cSrcweir "serif", 877*cdf0e10cSrcweir "decorative", 878*cdf0e10cSrcweir "special", 879*cdf0e10cSrcweir "italic", 880*cdf0e10cSrcweir "title", 881*cdf0e10cSrcweir "capitals", 882*cdf0e10cSrcweir "cjk", 883*cdf0e10cSrcweir "cjk_jp", 884*cdf0e10cSrcweir "cjk_sc", 885*cdf0e10cSrcweir "cjk_tc", 886*cdf0e10cSrcweir "cjk_kr", 887*cdf0e10cSrcweir "ctl", 888*cdf0e10cSrcweir "nonelatin", 889*cdf0e10cSrcweir "full", 890*cdf0e10cSrcweir "outline", 891*cdf0e10cSrcweir "shadow", 892*cdf0e10cSrcweir "rounded", 893*cdf0e10cSrcweir "typewriter", 894*cdf0e10cSrcweir "script", 895*cdf0e10cSrcweir "handwriting", 896*cdf0e10cSrcweir "chancery", 897*cdf0e10cSrcweir "comic", 898*cdf0e10cSrcweir "brushscript", 899*cdf0e10cSrcweir "gothic", 900*cdf0e10cSrcweir "schoolbook", 901*cdf0e10cSrcweir "other" 902*cdf0e10cSrcweir }; 903*cdf0e10cSrcweir 904*cdf0e10cSrcweir struct enum_convert 905*cdf0e10cSrcweir { 906*cdf0e10cSrcweir const char* pName; 907*cdf0e10cSrcweir int nEnum; 908*cdf0e10cSrcweir }; 909*cdf0e10cSrcweir 910*cdf0e10cSrcweir 911*cdf0e10cSrcweir static const enum_convert pWeightNames[] = 912*cdf0e10cSrcweir { 913*cdf0e10cSrcweir { "normal", WEIGHT_NORMAL }, 914*cdf0e10cSrcweir { "medium", WEIGHT_MEDIUM }, 915*cdf0e10cSrcweir { "bold", WEIGHT_BOLD }, 916*cdf0e10cSrcweir { "black", WEIGHT_BLACK }, 917*cdf0e10cSrcweir { "semibold", WEIGHT_SEMIBOLD }, 918*cdf0e10cSrcweir { "light", WEIGHT_LIGHT }, 919*cdf0e10cSrcweir { "semilight", WEIGHT_SEMILIGHT }, 920*cdf0e10cSrcweir { "ultrabold", WEIGHT_ULTRABOLD }, 921*cdf0e10cSrcweir { "semi", WEIGHT_SEMIBOLD }, 922*cdf0e10cSrcweir { "demi", WEIGHT_SEMIBOLD }, 923*cdf0e10cSrcweir { "heavy", WEIGHT_BLACK }, 924*cdf0e10cSrcweir { "unknown", WEIGHT_DONTKNOW }, 925*cdf0e10cSrcweir { "thin", WEIGHT_THIN }, 926*cdf0e10cSrcweir { "ultralight", WEIGHT_ULTRALIGHT } 927*cdf0e10cSrcweir }; 928*cdf0e10cSrcweir 929*cdf0e10cSrcweir static const enum_convert pWidthNames[] = 930*cdf0e10cSrcweir { 931*cdf0e10cSrcweir { "normal", WIDTH_NORMAL }, 932*cdf0e10cSrcweir { "condensed", WIDTH_CONDENSED }, 933*cdf0e10cSrcweir { "expanded", WIDTH_EXPANDED }, 934*cdf0e10cSrcweir { "unknown", WIDTH_DONTKNOW }, 935*cdf0e10cSrcweir { "ultracondensed", WIDTH_ULTRA_CONDENSED }, 936*cdf0e10cSrcweir { "extracondensed", WIDTH_EXTRA_CONDENSED }, 937*cdf0e10cSrcweir { "semicondensed", WIDTH_SEMI_CONDENSED }, 938*cdf0e10cSrcweir { "semiexpanded", WIDTH_SEMI_EXPANDED }, 939*cdf0e10cSrcweir { "extraexpanded", WIDTH_EXTRA_EXPANDED }, 940*cdf0e10cSrcweir { "ultraexpanded", WIDTH_ULTRA_EXPANDED } 941*cdf0e10cSrcweir }; 942*cdf0e10cSrcweir 943*cdf0e10cSrcweir void FontSubstConfiguration::fillSubstVector( const com::sun::star::uno::Reference< XNameAccess > xFont, 944*cdf0e10cSrcweir const rtl::OUString& rType, 945*cdf0e10cSrcweir std::vector< String >& rSubstVector ) const 946*cdf0e10cSrcweir { 947*cdf0e10cSrcweir try 948*cdf0e10cSrcweir { 949*cdf0e10cSrcweir Any aAny = xFont->getByName( rType ); 950*cdf0e10cSrcweir if( aAny.getValueTypeClass() == TypeClass_STRING ) 951*cdf0e10cSrcweir { 952*cdf0e10cSrcweir const OUString* pLine = (const OUString*)aAny.getValue(); 953*cdf0e10cSrcweir sal_Int32 nIndex = 0; 954*cdf0e10cSrcweir sal_Int32 nLength = pLine->getLength(); 955*cdf0e10cSrcweir if( nLength ) 956*cdf0e10cSrcweir { 957*cdf0e10cSrcweir const sal_Unicode* pStr = pLine->getStr(); 958*cdf0e10cSrcweir sal_Int32 nTokens = 0; 959*cdf0e10cSrcweir // count tokens 960*cdf0e10cSrcweir while( nLength-- ) 961*cdf0e10cSrcweir { 962*cdf0e10cSrcweir if( *pStr++ == sal_Unicode(';') ) 963*cdf0e10cSrcweir nTokens++; 964*cdf0e10cSrcweir } 965*cdf0e10cSrcweir rSubstVector.clear(); 966*cdf0e10cSrcweir // optimize performance, heap fragmentation 967*cdf0e10cSrcweir rSubstVector.reserve( nTokens ); 968*cdf0e10cSrcweir while( nIndex != -1 ) 969*cdf0e10cSrcweir { 970*cdf0e10cSrcweir OUString aSubst( pLine->getToken( 0, ';', nIndex ) ); 971*cdf0e10cSrcweir if( aSubst.getLength() ) 972*cdf0e10cSrcweir { 973*cdf0e10cSrcweir UniqueSubstHash::iterator aEntry = maSubstHash.find( aSubst ); 974*cdf0e10cSrcweir if (aEntry != maSubstHash.end()) 975*cdf0e10cSrcweir aSubst = *aEntry; 976*cdf0e10cSrcweir else 977*cdf0e10cSrcweir maSubstHash.insert( aSubst ); 978*cdf0e10cSrcweir rSubstVector.push_back( aSubst ); 979*cdf0e10cSrcweir } 980*cdf0e10cSrcweir } 981*cdf0e10cSrcweir } 982*cdf0e10cSrcweir } 983*cdf0e10cSrcweir } 984*cdf0e10cSrcweir catch( NoSuchElementException ) 985*cdf0e10cSrcweir { 986*cdf0e10cSrcweir } 987*cdf0e10cSrcweir catch( WrappedTargetException ) 988*cdf0e10cSrcweir { 989*cdf0e10cSrcweir } 990*cdf0e10cSrcweir } 991*cdf0e10cSrcweir 992*cdf0e10cSrcweir FontWeight FontSubstConfiguration::getSubstWeight( const com::sun::star::uno::Reference< XNameAccess > xFont, 993*cdf0e10cSrcweir const rtl::OUString& rType ) const 994*cdf0e10cSrcweir { 995*cdf0e10cSrcweir int weight = -1; 996*cdf0e10cSrcweir try 997*cdf0e10cSrcweir { 998*cdf0e10cSrcweir Any aAny = xFont->getByName( rType ); 999*cdf0e10cSrcweir if( aAny.getValueTypeClass() == TypeClass_STRING ) 1000*cdf0e10cSrcweir { 1001*cdf0e10cSrcweir const OUString* pLine = (const OUString*)aAny.getValue(); 1002*cdf0e10cSrcweir if( pLine->getLength() ) 1003*cdf0e10cSrcweir { 1004*cdf0e10cSrcweir for( weight=sizeof(pWeightNames)/sizeof(pWeightNames[0])-1; weight >= 0; weight-- ) 1005*cdf0e10cSrcweir if( pLine->equalsIgnoreAsciiCaseAscii( pWeightNames[weight].pName ) ) 1006*cdf0e10cSrcweir break; 1007*cdf0e10cSrcweir } 1008*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 1009*cdf0e10cSrcweir if( weight < 0 ) 1010*cdf0e10cSrcweir fprintf( stderr, "Error: invalid weight %s\n", 1011*cdf0e10cSrcweir OUStringToOString( *pLine, RTL_TEXTENCODING_ASCII_US ).getStr() ); 1012*cdf0e10cSrcweir #endif 1013*cdf0e10cSrcweir } 1014*cdf0e10cSrcweir } 1015*cdf0e10cSrcweir catch( NoSuchElementException ) 1016*cdf0e10cSrcweir { 1017*cdf0e10cSrcweir } 1018*cdf0e10cSrcweir catch( WrappedTargetException ) 1019*cdf0e10cSrcweir { 1020*cdf0e10cSrcweir } 1021*cdf0e10cSrcweir return (FontWeight)( weight >= 0 ? pWeightNames[weight].nEnum : WEIGHT_DONTKNOW ); 1022*cdf0e10cSrcweir } 1023*cdf0e10cSrcweir 1024*cdf0e10cSrcweir FontWidth FontSubstConfiguration::getSubstWidth( const com::sun::star::uno::Reference< XNameAccess > xFont, 1025*cdf0e10cSrcweir const rtl::OUString& rType ) const 1026*cdf0e10cSrcweir { 1027*cdf0e10cSrcweir int width = -1; 1028*cdf0e10cSrcweir try 1029*cdf0e10cSrcweir { 1030*cdf0e10cSrcweir Any aAny = xFont->getByName( rType ); 1031*cdf0e10cSrcweir if( aAny.getValueTypeClass() == TypeClass_STRING ) 1032*cdf0e10cSrcweir { 1033*cdf0e10cSrcweir const OUString* pLine = (const OUString*)aAny.getValue(); 1034*cdf0e10cSrcweir if( pLine->getLength() ) 1035*cdf0e10cSrcweir { 1036*cdf0e10cSrcweir for( width=sizeof(pWidthNames)/sizeof(pWidthNames[0])-1; width >= 0; width-- ) 1037*cdf0e10cSrcweir if( pLine->equalsIgnoreAsciiCaseAscii( pWidthNames[width].pName ) ) 1038*cdf0e10cSrcweir break; 1039*cdf0e10cSrcweir } 1040*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 1041*cdf0e10cSrcweir if( width < 0 ) 1042*cdf0e10cSrcweir fprintf( stderr, "Error: invalid width %s\n", 1043*cdf0e10cSrcweir OUStringToOString( *pLine, RTL_TEXTENCODING_ASCII_US ).getStr() ); 1044*cdf0e10cSrcweir #endif 1045*cdf0e10cSrcweir } 1046*cdf0e10cSrcweir } 1047*cdf0e10cSrcweir catch( NoSuchElementException ) 1048*cdf0e10cSrcweir { 1049*cdf0e10cSrcweir } 1050*cdf0e10cSrcweir catch( WrappedTargetException ) 1051*cdf0e10cSrcweir { 1052*cdf0e10cSrcweir } 1053*cdf0e10cSrcweir return (FontWidth)( width >= 0 ? pWidthNames[width].nEnum : WIDTH_DONTKNOW ); 1054*cdf0e10cSrcweir } 1055*cdf0e10cSrcweir 1056*cdf0e10cSrcweir unsigned long FontSubstConfiguration::getSubstType( const com::sun::star::uno::Reference< XNameAccess > xFont, 1057*cdf0e10cSrcweir const rtl::OUString& rType ) const 1058*cdf0e10cSrcweir { 1059*cdf0e10cSrcweir unsigned long type = 0; 1060*cdf0e10cSrcweir try 1061*cdf0e10cSrcweir { 1062*cdf0e10cSrcweir Any aAny = xFont->getByName( rType ); 1063*cdf0e10cSrcweir if( aAny.getValueTypeClass() == TypeClass_STRING ) 1064*cdf0e10cSrcweir { 1065*cdf0e10cSrcweir const OUString* pLine = (const OUString*)aAny.getValue(); 1066*cdf0e10cSrcweir if( pLine->getLength() ) 1067*cdf0e10cSrcweir { 1068*cdf0e10cSrcweir sal_Int32 nIndex = 0; 1069*cdf0e10cSrcweir while( nIndex != -1 ) 1070*cdf0e10cSrcweir { 1071*cdf0e10cSrcweir String aToken( pLine->getToken( 0, ',', nIndex ) ); 1072*cdf0e10cSrcweir for( int k = 0; k < 32; k++ ) 1073*cdf0e10cSrcweir if( aToken.EqualsIgnoreCaseAscii( pAttribNames[k] ) ) 1074*cdf0e10cSrcweir { 1075*cdf0e10cSrcweir type |= 1 << k; 1076*cdf0e10cSrcweir break; 1077*cdf0e10cSrcweir } 1078*cdf0e10cSrcweir } 1079*cdf0e10cSrcweir } 1080*cdf0e10cSrcweir } 1081*cdf0e10cSrcweir } 1082*cdf0e10cSrcweir catch( NoSuchElementException ) 1083*cdf0e10cSrcweir { 1084*cdf0e10cSrcweir } 1085*cdf0e10cSrcweir catch( WrappedTargetException ) 1086*cdf0e10cSrcweir { 1087*cdf0e10cSrcweir } 1088*cdf0e10cSrcweir 1089*cdf0e10cSrcweir return type; 1090*cdf0e10cSrcweir } 1091*cdf0e10cSrcweir 1092*cdf0e10cSrcweir void FontSubstConfiguration::readLocaleSubst( const com::sun::star::lang::Locale& rLocale ) const 1093*cdf0e10cSrcweir { 1094*cdf0e10cSrcweir std::hash_map< Locale, LocaleSubst, LocaleHash >::const_iterator it = 1095*cdf0e10cSrcweir m_aSubst.find( rLocale ); 1096*cdf0e10cSrcweir if( it != m_aSubst.end() ) 1097*cdf0e10cSrcweir { 1098*cdf0e10cSrcweir if( ! it->second.bConfigRead ) 1099*cdf0e10cSrcweir { 1100*cdf0e10cSrcweir it->second.bConfigRead = true; 1101*cdf0e10cSrcweir Reference< XNameAccess > xNode; 1102*cdf0e10cSrcweir try 1103*cdf0e10cSrcweir { 1104*cdf0e10cSrcweir Any aAny = m_xConfigAccess->getByName( it->second.aConfigLocaleString ); 1105*cdf0e10cSrcweir aAny >>= xNode; 1106*cdf0e10cSrcweir } 1107*cdf0e10cSrcweir catch( NoSuchElementException ) 1108*cdf0e10cSrcweir { 1109*cdf0e10cSrcweir } 1110*cdf0e10cSrcweir catch( WrappedTargetException ) 1111*cdf0e10cSrcweir { 1112*cdf0e10cSrcweir } 1113*cdf0e10cSrcweir if( xNode.is() ) 1114*cdf0e10cSrcweir { 1115*cdf0e10cSrcweir Sequence< OUString > aFonts = xNode->getElementNames(); 1116*cdf0e10cSrcweir int nFonts = aFonts.getLength(); 1117*cdf0e10cSrcweir const OUString* pFontNames = aFonts.getConstArray(); 1118*cdf0e10cSrcweir // improve performance, heap fragmentation 1119*cdf0e10cSrcweir it->second.aSubstAttributes.reserve( nFonts ); 1120*cdf0e10cSrcweir 1121*cdf0e10cSrcweir // strings for subst retrieval, construct only once 1122*cdf0e10cSrcweir OUString aSubstFontsStr ( RTL_CONSTASCII_USTRINGPARAM( "SubstFonts" ) ); 1123*cdf0e10cSrcweir OUString aSubstFontsMSStr ( RTL_CONSTASCII_USTRINGPARAM( "SubstFontsMS" ) ); 1124*cdf0e10cSrcweir OUString aSubstFontsPSStr ( RTL_CONSTASCII_USTRINGPARAM( "SubstFontsPS" ) ); 1125*cdf0e10cSrcweir OUString aSubstFontsHTMLStr ( RTL_CONSTASCII_USTRINGPARAM( "SubstFontsHTML" ) ); 1126*cdf0e10cSrcweir OUString aSubstWeightStr ( RTL_CONSTASCII_USTRINGPARAM( "FontWeight" ) ); 1127*cdf0e10cSrcweir OUString aSubstWidthStr ( RTL_CONSTASCII_USTRINGPARAM( "FontWidth" ) ); 1128*cdf0e10cSrcweir OUString aSubstTypeStr ( RTL_CONSTASCII_USTRINGPARAM( "FontType" ) ); 1129*cdf0e10cSrcweir for( int i = 0; i < nFonts; i++ ) 1130*cdf0e10cSrcweir { 1131*cdf0e10cSrcweir Reference< XNameAccess > xFont; 1132*cdf0e10cSrcweir try 1133*cdf0e10cSrcweir { 1134*cdf0e10cSrcweir Any aAny = xNode->getByName( pFontNames[i] ); 1135*cdf0e10cSrcweir aAny >>= xFont; 1136*cdf0e10cSrcweir } 1137*cdf0e10cSrcweir catch( NoSuchElementException ) 1138*cdf0e10cSrcweir { 1139*cdf0e10cSrcweir } 1140*cdf0e10cSrcweir catch( WrappedTargetException ) 1141*cdf0e10cSrcweir { 1142*cdf0e10cSrcweir } 1143*cdf0e10cSrcweir if( ! xFont.is() ) 1144*cdf0e10cSrcweir { 1145*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 1146*cdf0e10cSrcweir fprintf( stderr, "did not get font attributes for %s\n", 1147*cdf0e10cSrcweir OUStringToOString( pFontNames[i], RTL_TEXTENCODING_UTF8 ).getStr() ); 1148*cdf0e10cSrcweir #endif 1149*cdf0e10cSrcweir continue; 1150*cdf0e10cSrcweir } 1151*cdf0e10cSrcweir 1152*cdf0e10cSrcweir FontNameAttr aAttr; 1153*cdf0e10cSrcweir // read subst attributes from config 1154*cdf0e10cSrcweir aAttr.Name = pFontNames[i]; 1155*cdf0e10cSrcweir fillSubstVector( xFont, aSubstFontsStr, aAttr.Substitutions ); 1156*cdf0e10cSrcweir fillSubstVector( xFont, aSubstFontsMSStr, aAttr.MSSubstitutions ); 1157*cdf0e10cSrcweir fillSubstVector( xFont, aSubstFontsPSStr, aAttr.PSSubstitutions ); 1158*cdf0e10cSrcweir fillSubstVector( xFont, aSubstFontsHTMLStr, aAttr.HTMLSubstitutions ); 1159*cdf0e10cSrcweir aAttr.Weight = getSubstWeight( xFont, aSubstWeightStr ); 1160*cdf0e10cSrcweir aAttr.Width = getSubstWidth( xFont, aSubstWidthStr ); 1161*cdf0e10cSrcweir aAttr.Type = getSubstType( xFont, aSubstTypeStr ); 1162*cdf0e10cSrcweir 1163*cdf0e10cSrcweir // finally insert this entry 1164*cdf0e10cSrcweir it->second.aSubstAttributes.push_back( aAttr ); 1165*cdf0e10cSrcweir } 1166*cdf0e10cSrcweir std::sort( it->second.aSubstAttributes.begin(), it->second.aSubstAttributes.end(), StrictStringSort() ); 1167*cdf0e10cSrcweir } 1168*cdf0e10cSrcweir } 1169*cdf0e10cSrcweir } 1170*cdf0e10cSrcweir } 1171*cdf0e10cSrcweir 1172*cdf0e10cSrcweir const FontNameAttr* FontSubstConfiguration::getSubstInfo( const String& rFontName, const Locale& rLocale ) const 1173*cdf0e10cSrcweir { 1174*cdf0e10cSrcweir if( !rFontName.Len() ) 1175*cdf0e10cSrcweir return NULL; 1176*cdf0e10cSrcweir 1177*cdf0e10cSrcweir // search if a (language dep.) replacement table for the given font exists 1178*cdf0e10cSrcweir // fallback is english 1179*cdf0e10cSrcweir String aSearchFont( rFontName ); 1180*cdf0e10cSrcweir aSearchFont.ToLowerAscii(); 1181*cdf0e10cSrcweir FontNameAttr aSearchAttr; 1182*cdf0e10cSrcweir aSearchAttr.Name = aSearchFont; 1183*cdf0e10cSrcweir 1184*cdf0e10cSrcweir Locale aLocale; 1185*cdf0e10cSrcweir aLocale.Language = rLocale.Language.toAsciiLowerCase(); 1186*cdf0e10cSrcweir aLocale.Country = rLocale.Country.toAsciiUpperCase(); 1187*cdf0e10cSrcweir aLocale.Variant = rLocale.Variant.toAsciiUpperCase(); 1188*cdf0e10cSrcweir 1189*cdf0e10cSrcweir if( ! aLocale.Language.getLength() ) 1190*cdf0e10cSrcweir aLocale = SvtSysLocale().GetUILocale(); 1191*cdf0e10cSrcweir 1192*cdf0e10cSrcweir while( aLocale.Language.getLength() ) 1193*cdf0e10cSrcweir { 1194*cdf0e10cSrcweir std::hash_map< Locale, LocaleSubst, LocaleHash >::const_iterator lang = m_aSubst.find( aLocale ); 1195*cdf0e10cSrcweir if( lang != m_aSubst.end() ) 1196*cdf0e10cSrcweir { 1197*cdf0e10cSrcweir if( ! lang->second.bConfigRead ) 1198*cdf0e10cSrcweir readLocaleSubst( aLocale ); 1199*cdf0e10cSrcweir // try to find an exact match 1200*cdf0e10cSrcweir // because the list is sorted this will also find fontnames of the form searchfontname* 1201*cdf0e10cSrcweir std::vector< FontNameAttr >::const_iterator it = ::std::lower_bound( lang->second.aSubstAttributes.begin(), lang->second.aSubstAttributes.end(), aSearchAttr, StrictStringSort() ); 1202*cdf0e10cSrcweir if( it != lang->second.aSubstAttributes.end()) 1203*cdf0e10cSrcweir { 1204*cdf0e10cSrcweir const FontNameAttr& rFoundAttr = *it; 1205*cdf0e10cSrcweir // a search for "abcblack" may match with an entry for "abc" 1206*cdf0e10cSrcweir // the reverse is not a good idea (e.g. #i112731# alba->albani) 1207*cdf0e10cSrcweir if( rFoundAttr.Name.Len() <= aSearchFont.Len() ) 1208*cdf0e10cSrcweir if( aSearchFont.CompareTo( rFoundAttr.Name, rFoundAttr.Name.Len() ) == COMPARE_EQUAL ) 1209*cdf0e10cSrcweir return &rFoundAttr; 1210*cdf0e10cSrcweir } 1211*cdf0e10cSrcweir } 1212*cdf0e10cSrcweir // gradually become more unspecific 1213*cdf0e10cSrcweir if( aLocale.Variant.getLength() ) 1214*cdf0e10cSrcweir aLocale.Variant = OUString(); 1215*cdf0e10cSrcweir else if( aLocale.Country.getLength() ) 1216*cdf0e10cSrcweir aLocale.Country = OUString(); 1217*cdf0e10cSrcweir else if( ! aLocale.Language.equalsAscii( "en" ) ) 1218*cdf0e10cSrcweir aLocale.Language = OUString( RTL_CONSTASCII_USTRINGPARAM( "en" ) ); 1219*cdf0e10cSrcweir else 1220*cdf0e10cSrcweir aLocale.Language = OUString(); 1221*cdf0e10cSrcweir } 1222*cdf0e10cSrcweir return NULL; 1223*cdf0e10cSrcweir } 1224*cdf0e10cSrcweir 1225