]> git.saurik.com Git - wxWidgets.git/blob - src/common/fmapbase.cpp
Allow retrieving the descent and external leading of empty strings.
[wxWidgets.git] / src / common / fmapbase.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/fmapbase.cpp
3 // Purpose: wxFontMapperBase class implementation
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 21.06.2003 (extracted from common/fontmap.cpp)
7 // RCS-ID: $Id$
8 // Copyright: (c) 1999-2003 Vadim Zeitlin <vadim@wxwindows.org>
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 // for compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
22
23 #ifdef __BORLANDC__
24 #pragma hdrstop
25 #endif
26
27 #if wxUSE_FONTMAP
28
29 #ifndef WX_PRECOMP
30 #include "wx/app.h"
31 #include "wx/log.h"
32 #include "wx/intl.h"
33 #include "wx/module.h"
34 #include "wx/wxcrtvararg.h"
35 #endif //WX_PRECOMP
36
37 #if defined(__WINDOWS__)
38 #include "wx/msw/private.h" // includes windows.h for LOGFONT
39 #include "wx/msw/winundef.h"
40 #endif
41
42 #include "wx/fontmap.h"
43 #include "wx/fmappriv.h"
44
45 #include "wx/apptrait.h"
46
47 // wxMemoryConfig uses wxFileConfig
48 #if wxUSE_CONFIG && wxUSE_FILECONFIG
49 #include "wx/config.h"
50 #include "wx/memconf.h"
51 #endif
52
53 // ----------------------------------------------------------------------------
54 // constants
55 // ----------------------------------------------------------------------------
56
57 // encodings supported by GetEncodingDescription
58 static const wxFontEncoding gs_encodings[] =
59 {
60 wxFONTENCODING_ISO8859_1,
61 wxFONTENCODING_ISO8859_2,
62 wxFONTENCODING_ISO8859_3,
63 wxFONTENCODING_ISO8859_4,
64 wxFONTENCODING_ISO8859_5,
65 wxFONTENCODING_ISO8859_6,
66 wxFONTENCODING_ISO8859_7,
67 wxFONTENCODING_ISO8859_8,
68 wxFONTENCODING_ISO8859_9,
69 wxFONTENCODING_ISO8859_10,
70 wxFONTENCODING_ISO8859_11,
71 wxFONTENCODING_ISO8859_12,
72 wxFONTENCODING_ISO8859_13,
73 wxFONTENCODING_ISO8859_14,
74 wxFONTENCODING_ISO8859_15,
75 wxFONTENCODING_KOI8,
76 wxFONTENCODING_KOI8_U,
77 wxFONTENCODING_CP866,
78 wxFONTENCODING_CP874,
79 wxFONTENCODING_CP932,
80 wxFONTENCODING_CP936,
81 wxFONTENCODING_CP949,
82 wxFONTENCODING_CP950,
83 wxFONTENCODING_CP1250,
84 wxFONTENCODING_CP1251,
85 wxFONTENCODING_CP1252,
86 wxFONTENCODING_CP1253,
87 wxFONTENCODING_CP1254,
88 wxFONTENCODING_CP1255,
89 wxFONTENCODING_CP1256,
90 wxFONTENCODING_CP1257,
91 wxFONTENCODING_CP1258,
92 wxFONTENCODING_CP1361,
93 wxFONTENCODING_CP437,
94 wxFONTENCODING_UTF7,
95 wxFONTENCODING_UTF8,
96 wxFONTENCODING_UTF16BE,
97 wxFONTENCODING_UTF16LE,
98 wxFONTENCODING_UTF32BE,
99 wxFONTENCODING_UTF32LE,
100 wxFONTENCODING_EUC_JP,
101 wxFONTENCODING_DEFAULT,
102 wxFONTENCODING_ISO2022_JP,
103
104 wxFONTENCODING_MACROMAN,
105 wxFONTENCODING_MACJAPANESE,
106 wxFONTENCODING_MACCHINESETRAD,
107 wxFONTENCODING_MACKOREAN,
108 wxFONTENCODING_MACARABIC,
109 wxFONTENCODING_MACHEBREW,
110 wxFONTENCODING_MACGREEK,
111 wxFONTENCODING_MACCYRILLIC,
112 wxFONTENCODING_MACDEVANAGARI,
113 wxFONTENCODING_MACGURMUKHI,
114 wxFONTENCODING_MACGUJARATI,
115 wxFONTENCODING_MACORIYA,
116 wxFONTENCODING_MACBENGALI,
117 wxFONTENCODING_MACTAMIL,
118 wxFONTENCODING_MACTELUGU,
119 wxFONTENCODING_MACKANNADA,
120 wxFONTENCODING_MACMALAJALAM,
121 wxFONTENCODING_MACSINHALESE,
122 wxFONTENCODING_MACBURMESE,
123 wxFONTENCODING_MACKHMER,
124 wxFONTENCODING_MACTHAI,
125 wxFONTENCODING_MACLAOTIAN,
126 wxFONTENCODING_MACGEORGIAN,
127 wxFONTENCODING_MACARMENIAN,
128 wxFONTENCODING_MACCHINESESIMP,
129 wxFONTENCODING_MACTIBETAN,
130 wxFONTENCODING_MACMONGOLIAN,
131 wxFONTENCODING_MACETHIOPIC,
132 wxFONTENCODING_MACCENTRALEUR,
133 wxFONTENCODING_MACVIATNAMESE,
134 wxFONTENCODING_MACARABICEXT,
135 wxFONTENCODING_MACSYMBOL,
136 wxFONTENCODING_MACDINGBATS,
137 wxFONTENCODING_MACTURKISH,
138 wxFONTENCODING_MACCROATIAN,
139 wxFONTENCODING_MACICELANDIC,
140 wxFONTENCODING_MACROMANIAN,
141 wxFONTENCODING_MACCELTIC,
142 wxFONTENCODING_MACGAELIC,
143 wxFONTENCODING_MACKEYBOARD
144 };
145
146 // the descriptions for them
147 static const char* const gs_encodingDescs[] =
148 {
149 wxTRANSLATE( "Western European (ISO-8859-1)" ),
150 wxTRANSLATE( "Central European (ISO-8859-2)" ),
151 wxTRANSLATE( "Esperanto (ISO-8859-3)" ),
152 wxTRANSLATE( "Baltic (old) (ISO-8859-4)" ),
153 wxTRANSLATE( "Cyrillic (ISO-8859-5)" ),
154 wxTRANSLATE( "Arabic (ISO-8859-6)" ),
155 wxTRANSLATE( "Greek (ISO-8859-7)" ),
156 wxTRANSLATE( "Hebrew (ISO-8859-8)" ),
157 wxTRANSLATE( "Turkish (ISO-8859-9)" ),
158 wxTRANSLATE( "Nordic (ISO-8859-10)" ),
159 wxTRANSLATE( "Thai (ISO-8859-11)" ),
160 wxTRANSLATE( "Indian (ISO-8859-12)" ),
161 wxTRANSLATE( "Baltic (ISO-8859-13)" ),
162 wxTRANSLATE( "Celtic (ISO-8859-14)" ),
163 wxTRANSLATE( "Western European with Euro (ISO-8859-15)" ),
164 wxTRANSLATE( "KOI8-R" ),
165 wxTRANSLATE( "KOI8-U" ),
166 wxTRANSLATE( "Windows/DOS OEM Cyrillic (CP 866)" ),
167 wxTRANSLATE( "Windows Thai (CP 874)" ),
168 wxTRANSLATE( "Windows Japanese (CP 932) or Shift-JIS" ),
169 wxTRANSLATE( "Windows Chinese Simplified (CP 936) or GB-2312" ),
170 wxTRANSLATE( "Windows Korean (CP 949)" ),
171 wxTRANSLATE( "Windows Chinese Traditional (CP 950) or Big-5" ),
172 wxTRANSLATE( "Windows Central European (CP 1250)" ),
173 wxTRANSLATE( "Windows Cyrillic (CP 1251)" ),
174 wxTRANSLATE( "Windows Western European (CP 1252)" ),
175 wxTRANSLATE( "Windows Greek (CP 1253)" ),
176 wxTRANSLATE( "Windows Turkish (CP 1254)" ),
177 wxTRANSLATE( "Windows Hebrew (CP 1255)" ),
178 wxTRANSLATE( "Windows Arabic (CP 1256)" ),
179 wxTRANSLATE( "Windows Baltic (CP 1257)" ),
180 wxTRANSLATE( "Windows Vietnamese (CP 1258)" ),
181 wxTRANSLATE( "Windows Johab (CP 1361)" ),
182 wxTRANSLATE( "Windows/DOS OEM (CP 437)" ),
183 wxTRANSLATE( "Unicode 7 bit (UTF-7)" ),
184 wxTRANSLATE( "Unicode 8 bit (UTF-8)" ),
185 #ifdef WORDS_BIGENDIAN
186 wxTRANSLATE( "Unicode 16 bit (UTF-16)" ),
187 wxTRANSLATE( "Unicode 16 bit Little Endian (UTF-16LE)" ),
188 wxTRANSLATE( "Unicode 32 bit (UTF-32)" ),
189 wxTRANSLATE( "Unicode 32 bit Little Endian (UTF-32LE)" ),
190 #else // WORDS_BIGENDIAN
191 wxTRANSLATE( "Unicode 16 bit Big Endian (UTF-16BE)" ),
192 wxTRANSLATE( "Unicode 16 bit (UTF-16)" ),
193 wxTRANSLATE( "Unicode 32 bit Big Endian (UTF-32BE)" ),
194 wxTRANSLATE( "Unicode 32 bit (UTF-32)" ),
195 #endif // WORDS_BIGENDIAN
196 wxTRANSLATE( "Extended Unix Codepage for Japanese (EUC-JP)" ),
197 wxTRANSLATE( "US-ASCII" ),
198 wxTRANSLATE( "ISO-2022-JP" ),
199
200 wxTRANSLATE( "MacRoman" ),
201 wxTRANSLATE( "MacJapanese" ),
202 wxTRANSLATE( "MacChineseTrad" ),
203 wxTRANSLATE( "MacKorean" ),
204 wxTRANSLATE( "MacArabic" ),
205 wxTRANSLATE( "MacHebrew" ),
206 wxTRANSLATE( "MacGreek" ),
207 wxTRANSLATE( "MacCyrillic" ),
208 wxTRANSLATE( "MacDevanagari" ),
209 wxTRANSLATE( "MacGurmukhi" ),
210 wxTRANSLATE( "MacGujarati" ),
211 wxTRANSLATE( "MacOriya" ),
212 wxTRANSLATE( "MacBengali" ),
213 wxTRANSLATE( "MacTamil" ),
214 wxTRANSLATE( "MacTelugu" ),
215 wxTRANSLATE( "MacKannada" ),
216 wxTRANSLATE( "MacMalayalam" ),
217 wxTRANSLATE( "MacSinhalese" ),
218 wxTRANSLATE( "MacBurmese" ),
219 wxTRANSLATE( "MacKhmer" ),
220 wxTRANSLATE( "MacThai" ),
221 wxTRANSLATE( "MacLaotian" ),
222 wxTRANSLATE( "MacGeorgian" ),
223 wxTRANSLATE( "MacArmenian" ),
224 wxTRANSLATE( "MacChineseSimp" ),
225 wxTRANSLATE( "MacTibetan" ),
226 wxTRANSLATE( "MacMongolian" ),
227 wxTRANSLATE( "MacEthiopic" ),
228 wxTRANSLATE( "MacCentralEurRoman" ),
229 wxTRANSLATE( "MacVietnamese" ),
230 wxTRANSLATE( "MacExtArabic" ),
231 wxTRANSLATE( "MacSymbol" ),
232 wxTRANSLATE( "MacDingbats" ),
233 wxTRANSLATE( "MacTurkish" ),
234 wxTRANSLATE( "MacCroatian" ),
235 wxTRANSLATE( "MacIcelandic" ),
236 wxTRANSLATE( "MacRomanian" ),
237 wxTRANSLATE( "MacCeltic" ),
238 wxTRANSLATE( "MacGaelic" ),
239 wxTRANSLATE( "MacKeyboardGlyphs" )
240 };
241
242 // and the internal names (these are not translated on purpose!)
243 static const wxChar* const gs_encodingNames[][9] =
244 {
245 // names from the columns correspond to these OS:
246 // Linux Solaris and IRIX HP-UX AIX
247 { wxT("ISO-8859-1"), wxT("ISO8859-1"), wxT("iso88591"), wxT("8859-1"), wxT("iso_8859_1"), NULL },
248 { wxT("ISO-8859-2"), wxT("ISO8859-2"), wxT("iso88592"), wxT("8859-2"), NULL },
249 { wxT("ISO-8859-3"), wxT("ISO8859-3"), wxT("iso88593"), wxT("8859-3"), NULL },
250 { wxT("ISO-8859-4"), wxT("ISO8859-4"), wxT("iso88594"), wxT("8859-4"), NULL },
251 { wxT("ISO-8859-5"), wxT("ISO8859-5"), wxT("iso88595"), wxT("8859-5"), NULL },
252 { wxT("ISO-8859-6"), wxT("ISO8859-6"), wxT("iso88596"), wxT("8859-6"), NULL },
253 { wxT("ISO-8859-7"), wxT("ISO8859-7"), wxT("iso88597"), wxT("8859-7"), NULL },
254 { wxT("ISO-8859-8"), wxT("ISO8859-8"), wxT("iso88598"), wxT("8859-8"), NULL },
255 { wxT("ISO-8859-9"), wxT("ISO8859-9"), wxT("iso88599"), wxT("8859-9"), NULL },
256 { wxT("ISO-8859-10"), wxT("ISO8859-10"), wxT("iso885910"), wxT("8859-10"), NULL },
257 { wxT("ISO-8859-11"), wxT("ISO8859-11"), wxT("iso885911"), wxT("8859-11"), NULL },
258 { wxT("ISO-8859-12"), wxT("ISO8859-12"), wxT("iso885912"), wxT("8859-12"), NULL },
259 { wxT("ISO-8859-13"), wxT("ISO8859-13"), wxT("iso885913"), wxT("8859-13"), NULL },
260 { wxT("ISO-8859-14"), wxT("ISO8859-14"), wxT("iso885914"), wxT("8859-14"), NULL },
261 { wxT("ISO-8859-15"), wxT("ISO8859-15"), wxT("iso885915"), wxT("8859-15"), NULL },
262
263 // although koi8-ru is not strictly speaking the same as koi8-r,
264 // they are similar enough to make mapping it to koi8 better than
265 // not recognizing it at all
266 { wxT( "KOI8-R" ), wxT( "KOI8-RU" ), NULL },
267 { wxT( "KOI8-U" ), NULL },
268
269 { wxT( "WINDOWS-866" ), wxT( "CP866" ), NULL },
270
271 { wxT( "WINDOWS-874" ), wxT( "CP874" ), wxT( "MS874" ), wxT( "IBM-874" ), NULL },
272 { wxT( "WINDOWS-932" ), wxT( "CP932" ), wxT( "MS932" ), wxT( "IBM-932" ), wxT( "SJIS" ), wxT( "SHIFT-JIS" ), wxT( "SHIFT_JIS" ), NULL },
273 { wxT( "WINDOWS-936" ), wxT( "CP936" ), wxT( "MS936" ), wxT( "IBM-936" ), wxT( "GB2312" ), wxT( "gbk" ),wxT( "GBK" ), NULL },
274 { wxT( "WINDOWS-949" ), wxT( "CP949" ), wxT( "MS949" ), wxT( "IBM-949" ), wxT( "EUC-KR" ), wxT( "eucKR" ), wxT( "euc_kr" ), NULL },
275 { wxT( "WINDOWS-950" ), wxT( "CP950" ), wxT( "MS950" ), wxT( "IBM-950" ), wxT( "BIG5" ), wxT( "BIG-5" ), wxT( "BIG-FIVE" ), NULL },
276 { wxT( "WINDOWS-1250" ),wxT( "CP1250" ),wxT( "MS1250" ),wxT( "IBM-1250" ),NULL },
277 { wxT( "WINDOWS-1251" ),wxT( "CP1251" ),wxT( "MS1251" ),wxT( "IBM-1251" ),NULL },
278 { wxT( "WINDOWS-1252" ),wxT( "CP1252" ),wxT( "MS1252" ),wxT( "IBM-1252" ),NULL },
279 { wxT( "WINDOWS-1253" ),wxT( "CP1253" ),wxT( "MS1253" ),wxT( "IBM-1253" ),NULL },
280 { wxT( "WINDOWS-1254" ),wxT( "CP1254" ),wxT( "MS1254" ),wxT( "IBM-1254" ),NULL },
281 { wxT( "WINDOWS-1255" ),wxT( "CP1255" ),wxT( "MS1255" ),wxT( "IBM-1255" ),NULL },
282 { wxT( "WINDOWS-1256" ),wxT( "CP1256" ),wxT( "MS1256" ),wxT( "IBM-1256" ),NULL },
283 { wxT( "WINDOWS-1257" ),wxT( "CP1257" ),wxT( "MS1257" ),wxT( "IBM-1257" ),NULL },
284 { wxT( "WINDOWS-1258" ),wxT( "CP1258" ),wxT( "MS1258" ),wxT( "IBM-1258" ),NULL },
285 { wxT( "WINDOWS-1361" ),wxT( "CP1361" ),wxT( "MS1361" ),wxT( "IBM-1361" ), wxT( "JOHAB" ), NULL },
286 { wxT( "WINDOWS-437" ), wxT( "CP437" ), wxT( "MS437" ), wxT( "IBM-437" ), NULL },
287
288 { wxT( "UTF-7" ), wxT("UTF7"), NULL },
289 { wxT( "UTF-8" ), wxT("UTF8"), NULL },
290 #ifdef WORDS_BIGENDIAN
291 { wxT( "UTF-16BE" ), wxT("UTF16BE"), wxT("UCS-2BE"), wxT("UCS2BE"), wxT("UTF-16"), wxT("UTF16"), wxT("UCS-2"), wxT("UCS2"), NULL },
292 { wxT( "UTF-16LE" ), wxT("UTF16LE"), wxT("UCS-2LE"), wxT("UCS2LE"), NULL },
293 { wxT( "UTF-32BE" ), wxT("UTF32BE"), wxT("UCS-4BE" ), wxT("UTF-32"), wxT("UTF32"), wxT("UCS-4"), wxT("UCS4"), NULL },
294 { wxT( "UTF-32LE" ), wxT("UTF32LE"), wxT("UCS-4LE"), wxT("UCS4LE"), NULL },
295 #else // WORDS_BIGENDIAN
296 { wxT("UTF-16BE"), wxT("UTF16BE"), wxT("UCS-2BE"), wxT("UCS2BE"), NULL },
297 { wxT("UTF-16LE"), wxT("UTF16LE"), wxT("UCS-2LE"), wxT("UTF-16"), wxT("UTF16"), wxT("UCS-2"), wxT("UCS2"), NULL },
298 { wxT("UTF-32BE"), wxT("UTF32BE"), wxT("UCS-4BE"), wxT("UCS4BE"), NULL },
299 { wxT("UTF-32LE"), wxT("UTF32LE"), wxT("UCS-4LE"), wxT("UCS4LE"), wxT("UTF-32"), wxT("UTF32"), wxT("UCS-4"), wxT("UCS4"), NULL },
300 #endif // WORDS_BIGENDIAN
301
302 { wxT( "EUC-JP" ), wxT( "eucJP" ), wxT( "euc_jp" ), wxT( "IBM-eucJP" ), NULL },
303
304 // 646 is for Solaris, roman8 -- for HP-UX
305 { wxT( "US-ASCII" ), wxT( "ASCII" ), wxT("C"), wxT("POSIX"), wxT("ANSI_X3.4-1968"),
306 wxT("646"), wxT("roman8"), wxT( "" ), NULL },
307
308 { wxT( "ISO-2022-JP" ), NULL },
309
310
311 { wxT( "MacRoman" ), NULL },
312 { wxT( "MacJapanese" ), NULL },
313 { wxT( "MacChineseTrad" ), NULL },
314 { wxT( "MacKorean" ), NULL },
315 { wxT( "MacArabic" ), NULL },
316 { wxT( "MacHebrew" ), NULL },
317 { wxT( "MacGreek" ), NULL },
318 { wxT( "MacCyrillic" ), NULL },
319 { wxT( "MacDevanagari" ), NULL },
320 { wxT( "MacGurmukhi" ), NULL },
321 { wxT( "MacGujarati" ), NULL },
322 { wxT( "MacOriya" ), NULL },
323 { wxT( "MacBengali" ), NULL },
324 { wxT( "MacTamil" ), NULL },
325 { wxT( "MacTelugu" ), NULL },
326 { wxT( "MacKannada" ), NULL },
327 { wxT( "MacMalayalam" ), NULL },
328 { wxT( "MacSinhalese" ), NULL },
329 { wxT( "MacBurmese" ), NULL },
330 { wxT( "MacKhmer" ), NULL },
331 { wxT( "MacThai" ), NULL },
332 { wxT( "MacLaotian" ), NULL },
333 { wxT( "MacGeorgian" ), NULL },
334 { wxT( "MacArmenian" ), NULL },
335 { wxT( "MacChineseSimp" ), NULL },
336 { wxT( "MacTibetan" ), NULL },
337 { wxT( "MacMongolian" ), NULL },
338 { wxT( "MacEthiopic" ), NULL },
339 { wxT( "MacCentralEurRoman" ), NULL },
340 { wxT( "MacVietnamese" ), NULL },
341 { wxT( "MacExtArabic" ), NULL },
342 { wxT( "MacSymbol" ), NULL },
343 { wxT( "MacDingbats" ), NULL },
344 { wxT( "MacTurkish" ), NULL },
345 { wxT( "MacCroatian" ), NULL },
346 { wxT( "MacIcelandic" ), NULL },
347 { wxT( "MacRomanian" ), NULL },
348 { wxT( "MacCeltic" ), NULL },
349 { wxT( "MacGaelic" ), NULL },
350 { wxT( "MacKeyboardGlyphs" ), NULL }
351 };
352
353 wxCOMPILE_TIME_ASSERT( WXSIZEOF(gs_encodingDescs) == WXSIZEOF(gs_encodings), EncodingsArraysNotInSync );
354 wxCOMPILE_TIME_ASSERT( WXSIZEOF(gs_encodingNames) == WXSIZEOF(gs_encodings), EncodingsArraysNotInSync );
355
356 // ----------------------------------------------------------------------------
357 // private classes
358 // ----------------------------------------------------------------------------
359
360 // clean up the font mapper object
361 class wxFontMapperModule : public wxModule
362 {
363 public:
364 wxFontMapperModule() : wxModule() { }
365
366 virtual bool OnInit()
367 {
368 // a dummy wxFontMapperBase object could have been created during the
369 // program startup before wxApp was created, we have to delete it to
370 // allow creating the real font mapper next time it is needed now that
371 // we can create it (when the modules are initialized, wxApp object
372 // already exists)
373 wxFontMapperBase *fm = wxFontMapperBase::Get();
374 if ( fm && fm->IsDummy() )
375 wxFontMapperBase::Reset();
376
377 return true;
378 }
379
380 virtual void OnExit()
381 {
382 wxFontMapperBase::Reset();
383 }
384
385 DECLARE_DYNAMIC_CLASS(wxFontMapperModule)
386 };
387
388 IMPLEMENT_DYNAMIC_CLASS(wxFontMapperModule, wxModule)
389
390
391 // ============================================================================
392 // wxFontMapperBase implementation
393 // ============================================================================
394
395 wxFontMapper *wxFontMapperBase::sm_instance = NULL;
396
397 // ----------------------------------------------------------------------------
398 // ctor and dtor
399 // ----------------------------------------------------------------------------
400
401 wxFontMapperBase::wxFontMapperBase()
402 {
403 #if wxUSE_CONFIG && wxUSE_FILECONFIG
404 m_configDummy = NULL;
405 #endif // wxUSE_CONFIG
406 }
407
408 wxFontMapperBase::~wxFontMapperBase()
409 {
410 #if wxUSE_CONFIG && wxUSE_FILECONFIG
411 if ( m_configDummy )
412 delete m_configDummy;
413 #endif // wxUSE_CONFIG
414 }
415
416 /* static */
417 wxFontMapperBase *wxFontMapperBase::Get()
418 {
419 if ( !sm_instance )
420 {
421 wxAppTraits *traits = wxTheApp ? wxTheApp->GetTraits() : NULL;
422 if ( traits )
423 {
424 sm_instance = traits->CreateFontMapper();
425
426 wxASSERT_MSG( sm_instance,
427 wxT("wxAppTraits::CreateFontMapper() failed") );
428 }
429
430 if ( !sm_instance )
431 {
432 // last resort: we must create something because the existing code
433 // relies on always having a valid font mapper object
434 sm_instance = (wxFontMapper *)new wxFontMapperBase;
435 }
436 }
437
438 return (wxFontMapperBase*)sm_instance;
439 }
440
441 /* static */
442 wxFontMapper *wxFontMapperBase::Set(wxFontMapper *mapper)
443 {
444 wxFontMapper *old = sm_instance;
445 sm_instance = mapper;
446 return old;
447 }
448
449 /* static */
450 void wxFontMapperBase::Reset()
451 {
452 if ( sm_instance )
453 {
454 // we need a cast as wxFontMapper is not fully declared here and so the
455 // compiler can't know that it derives from wxFontMapperBase (but
456 // run-time behaviour will be correct because the dtor is virtual)
457 delete (wxFontMapperBase *)sm_instance;
458 sm_instance = NULL;
459 }
460 }
461
462 #if wxUSE_CONFIG && wxUSE_FILECONFIG
463
464 // ----------------------------------------------------------------------------
465 // config usage customisation
466 // ----------------------------------------------------------------------------
467
468
469 static wxString gs_defaultConfigPath(FONTMAPPER_ROOT_PATH);
470
471 /* static */
472 const wxString& wxFontMapperBase::GetDefaultConfigPath()
473 {
474 // NB: we return const wxString& and not wxString for compatibility
475 // with 2.8 that returned const wxChar*
476 return gs_defaultConfigPath;
477 }
478
479 void wxFontMapperBase::SetConfigPath(const wxString& prefix)
480 {
481 wxCHECK_RET( !prefix.empty() && prefix[0] == wxCONFIG_PATH_SEPARATOR,
482 wxT("an absolute path should be given to wxFontMapper::SetConfigPath()") );
483
484 m_configRootPath = prefix;
485 }
486
487 // ----------------------------------------------------------------------------
488 // get config object and path for it
489 // ----------------------------------------------------------------------------
490
491 wxConfigBase *wxFontMapperBase::GetConfig()
492 {
493 wxConfigBase *config = wxConfig::Get(false);
494
495 // If there is no global configuration, use an internal memory configuration
496 if ( !config )
497 {
498 if ( !m_configDummy )
499 m_configDummy = new wxMemoryConfig;
500 config = m_configDummy;
501
502 // FIXME: ideally, we should add keys from dummy config to a real one later,
503 // but it is a low-priority task because typical wxWin application
504 // either doesn't use wxConfig at all or creates wxConfig object in
505 // wxApp::OnInit(), before any real interaction with the user takes
506 // place...
507 }
508
509 return config;
510 }
511
512 const wxString& wxFontMapperBase::GetConfigPath()
513 {
514 if ( !m_configRootPath )
515 {
516 // use the default
517 m_configRootPath = GetDefaultConfigPath();
518 }
519
520 return m_configRootPath;
521 }
522
523 // ----------------------------------------------------------------------------
524 // config helpers
525 // ----------------------------------------------------------------------------
526
527 bool wxFontMapperBase::ChangePath(const wxString& pathNew, wxString *pathOld)
528 {
529 wxConfigBase *config = GetConfig();
530 if ( !config )
531 return false;
532
533 *pathOld = config->GetPath();
534
535 wxString path = GetConfigPath();
536 if ( path.empty() || path.Last() != wxCONFIG_PATH_SEPARATOR )
537 {
538 path += wxCONFIG_PATH_SEPARATOR;
539 }
540
541 wxASSERT_MSG( !pathNew || (pathNew[0] != wxCONFIG_PATH_SEPARATOR),
542 wxT("should be a relative path") );
543
544 path += pathNew;
545
546 config->SetPath(path);
547
548 return true;
549 }
550
551 void wxFontMapperBase::RestorePath(const wxString& pathOld)
552 {
553 GetConfig()->SetPath(pathOld);
554 }
555
556 #endif
557
558 // ----------------------------------------------------------------------------
559 // charset/encoding correspondence
560 // ----------------------------------------------------------------------------
561
562 wxFontEncoding
563 wxFontMapperBase::CharsetToEncoding(const wxString& charset,
564 bool WXUNUSED(interactive))
565 {
566 int enc = NonInteractiveCharsetToEncoding(charset);
567 if ( enc == wxFONTENCODING_UNKNOWN )
568 {
569 // we should return wxFONTENCODING_SYSTEM from here for unknown
570 // encodings
571 enc = wxFONTENCODING_SYSTEM;
572 }
573
574 return (wxFontEncoding)enc;
575 }
576
577 int
578 wxFontMapperBase::NonInteractiveCharsetToEncoding(const wxString& charset)
579 {
580 wxFontEncoding encoding = wxFONTENCODING_SYSTEM;
581
582 // we're going to modify it, make a copy
583 wxString cs = charset;
584
585 #if wxUSE_CONFIG && wxUSE_FILECONFIG
586 // first try the user-defined settings
587 wxFontMapperPathChanger path(this, FONTMAPPER_CHARSET_PATH);
588 if ( path.IsOk() )
589 {
590 wxConfigBase *config = GetConfig();
591
592 // do we have an encoding for this charset?
593 long value = config->Read(charset, -1l);
594 if ( value != -1 )
595 {
596 if ( value == wxFONTENCODING_UNKNOWN )
597 {
598 // don't try to find it, in particular don't ask the user
599 return value;
600 }
601
602 if ( value >= 0 && value <= wxFONTENCODING_MAX )
603 {
604 encoding = (wxFontEncoding)value;
605 }
606 else
607 {
608 wxLogDebug(wxT("corrupted config data: invalid encoding %ld for charset '%s' ignored"),
609 value, charset.c_str());
610 }
611 }
612
613 if ( encoding == wxFONTENCODING_SYSTEM )
614 {
615 // may be we have an alias?
616 config->SetPath(FONTMAPPER_CHARSET_ALIAS_PATH);
617
618 wxString alias = config->Read(charset);
619 if ( !alias.empty() )
620 {
621 // yes, we do - use it instead
622 cs = alias;
623 }
624 }
625 }
626 #endif // wxUSE_CONFIG
627
628 // if didn't find it there, try to recognize it ourselves
629 if ( encoding == wxFONTENCODING_SYSTEM )
630 {
631 // trim any spaces
632 cs.Trim(true);
633 cs.Trim(false);
634
635 // discard the optional quotes
636 if ( !cs.empty() )
637 {
638 if ( cs[0u] == wxT('"') && cs.Last() == wxT('"') )
639 {
640 cs = wxString(cs.c_str(), cs.length() - 1);
641 }
642 }
643
644 for ( size_t i = 0; i < WXSIZEOF(gs_encodingNames); ++i )
645 {
646 for ( const wxChar* const* encName = gs_encodingNames[i]; *encName; ++encName )
647 {
648 if ( cs.CmpNoCase(*encName) == 0 )
649 return gs_encodings[i];
650 }
651 }
652
653 cs.MakeUpper();
654
655 if ( cs.Left(3) == wxT("ISO") )
656 {
657 // the dash is optional (or, to be exact, it is not, but
658 // several broken programs "forget" it)
659 const wxChar *p = cs.c_str() + 3;
660 if ( *p == wxT('-') )
661 p++;
662
663 unsigned int value;
664 if ( wxSscanf(p, wxT("8859-%u"), &value) == 1 )
665 {
666 // make it 0 based and check that it is strictly positive in
667 // the process (no such thing as iso8859-0 encoding)
668 if ( (value-- > 0) &&
669 (value < wxFONTENCODING_ISO8859_MAX -
670 wxFONTENCODING_ISO8859_1) )
671 {
672 // it's a valid ISO8859 encoding
673 value += wxFONTENCODING_ISO8859_1;
674 encoding = (wxFontEncoding)value;
675 }
676 }
677 }
678 else if ( cs.Left(4) == wxT("8859") )
679 {
680 const wxChar *p = cs.c_str();
681
682 unsigned int value;
683 if ( wxSscanf(p, wxT("8859-%u"), &value) == 1 )
684 {
685 // make it 0 based and check that it is strictly positive in
686 // the process (no such thing as iso8859-0 encoding)
687 if ( (value-- > 0) &&
688 (value < wxFONTENCODING_ISO8859_MAX -
689 wxFONTENCODING_ISO8859_1) )
690 {
691 // it's a valid ISO8859 encoding
692 value += wxFONTENCODING_ISO8859_1;
693 encoding = (wxFontEncoding)value;
694 }
695 }
696 }
697 else // check for Windows charsets
698 {
699 size_t len;
700 if ( cs.Left(7) == wxT("WINDOWS") )
701 {
702 len = 7;
703 }
704 else if ( cs.Left(2) == wxT("CP") )
705 {
706 len = 2;
707 }
708 else // not a Windows encoding
709 {
710 len = 0;
711 }
712
713 if ( len )
714 {
715 const wxChar *p = cs.c_str() + len;
716 if ( *p == wxT('-') )
717 p++;
718
719 unsigned int value;
720 if ( wxSscanf(p, wxT("%u"), &value) == 1 )
721 {
722 if ( value >= 1250 )
723 {
724 value -= 1250;
725 if ( value < wxFONTENCODING_CP12_MAX -
726 wxFONTENCODING_CP1250 )
727 {
728 // a valid Windows code page
729 value += wxFONTENCODING_CP1250;
730 encoding = (wxFontEncoding)value;
731 }
732 }
733
734 switch ( value )
735 {
736 case 866:
737 encoding = wxFONTENCODING_CP866;
738 break;
739
740 case 874:
741 encoding = wxFONTENCODING_CP874;
742 break;
743
744 case 932:
745 encoding = wxFONTENCODING_CP932;
746 break;
747
748 case 936:
749 encoding = wxFONTENCODING_CP936;
750 break;
751
752 case 949:
753 encoding = wxFONTENCODING_CP949;
754 break;
755
756 case 950:
757 encoding = wxFONTENCODING_CP950;
758 break;
759
760 case 1258:
761 encoding = wxFONTENCODING_CP1258;
762 break;
763
764 case 1361:
765 encoding = wxFONTENCODING_CP1361;
766 break;
767 }
768 }
769 }
770 }
771 //else: unknown
772 }
773
774 return encoding;
775 }
776
777 /* static */
778 size_t wxFontMapperBase::GetSupportedEncodingsCount()
779 {
780 return WXSIZEOF(gs_encodings);
781 }
782
783 /* static */
784 wxFontEncoding wxFontMapperBase::GetEncoding(size_t n)
785 {
786 wxCHECK_MSG( n < WXSIZEOF(gs_encodings), wxFONTENCODING_SYSTEM,
787 wxT("wxFontMapper::GetEncoding(): invalid index") );
788
789 return gs_encodings[n];
790 }
791
792 /* static */
793 wxString wxFontMapperBase::GetEncodingDescription(wxFontEncoding encoding)
794 {
795 if ( encoding == wxFONTENCODING_DEFAULT )
796 {
797 return _("Default encoding");
798 }
799
800 const size_t count = WXSIZEOF(gs_encodingDescs);
801
802 for ( size_t i = 0; i < count; i++ )
803 {
804 if ( gs_encodings[i] == encoding )
805 {
806 return wxGetTranslation(gs_encodingDescs[i]);
807 }
808 }
809
810 wxString str;
811 str.Printf(_("Unknown encoding (%d)"), encoding);
812
813 return str;
814 }
815
816 /* static */
817 wxString wxFontMapperBase::GetEncodingName(wxFontEncoding encoding)
818 {
819 if ( encoding == wxFONTENCODING_DEFAULT )
820 {
821 return _("default");
822 }
823
824 const size_t count = WXSIZEOF(gs_encodingNames);
825
826 for ( size_t i = 0; i < count; i++ )
827 {
828 if ( gs_encodings[i] == encoding )
829 {
830 return gs_encodingNames[i][0];
831 }
832 }
833
834 wxString str;
835 str.Printf(_("unknown-%d"), encoding);
836
837 return str;
838 }
839
840 /* static */
841 const wxChar** wxFontMapperBase::GetAllEncodingNames(wxFontEncoding encoding)
842 {
843 static const wxChar* const dummy[] = { NULL };
844
845 for ( size_t i = 0; i < WXSIZEOF(gs_encodingNames); i++ )
846 {
847 if ( gs_encodings[i] == encoding )
848 {
849 return const_cast<const wxChar**>(gs_encodingNames[i]);
850 }
851 }
852
853 return const_cast<const wxChar**>(dummy);
854 }
855
856 /* static */
857 wxFontEncoding wxFontMapperBase::GetEncodingFromName(const wxString& name)
858 {
859 const size_t count = WXSIZEOF(gs_encodingNames);
860
861 for ( size_t i = 0; i < count; i++ )
862 {
863 for ( const wxChar* const* encName = gs_encodingNames[i]; *encName; ++encName )
864 {
865 if ( name.CmpNoCase(*encName) == 0 )
866 return gs_encodings[i];
867 }
868 }
869
870 return wxFONTENCODING_MAX;
871 }
872
873 #endif // wxUSE_FONTMAP