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