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