Remove wxConfig object caching (m_config), which solves dangling pointer problem...
[wxWidgets.git] / src / common / fmapbase.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: 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 // License: wxWindows license
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 #endif //WX_PRECOMP
34
35 #if defined(__WXMSW__)
36 #include "wx/msw/private.h" // includes windows.h for LOGFONT
37 #include "wx/msw/winundef.h"
38 #endif
39
40 #include "wx/fontmap.h"
41 #include "wx/fmappriv.h"
42
43 #include "wx/apptrait.h"
44 #include "wx/module.h"
45
46 // wxMemoryConfig uses wxFileConfig
47 #if wxUSE_CONFIG && wxUSE_FILECONFIG
48 #include "wx/config.h"
49 #include "wx/memconf.h"
50 #endif
51
52 // ----------------------------------------------------------------------------
53 // constants
54 // ----------------------------------------------------------------------------
55
56 // encodings supported by GetEncodingDescription
57 static wxFontEncoding gs_encodings[] =
58 {
59 wxFONTENCODING_ISO8859_1,
60 wxFONTENCODING_ISO8859_2,
61 wxFONTENCODING_ISO8859_3,
62 wxFONTENCODING_ISO8859_4,
63 wxFONTENCODING_ISO8859_5,
64 wxFONTENCODING_ISO8859_6,
65 wxFONTENCODING_ISO8859_7,
66 wxFONTENCODING_ISO8859_8,
67 wxFONTENCODING_ISO8859_9,
68 wxFONTENCODING_ISO8859_10,
69 wxFONTENCODING_ISO8859_11,
70 wxFONTENCODING_ISO8859_12,
71 wxFONTENCODING_ISO8859_13,
72 wxFONTENCODING_ISO8859_14,
73 wxFONTENCODING_ISO8859_15,
74 wxFONTENCODING_KOI8,
75 wxFONTENCODING_KOI8_U,
76 wxFONTENCODING_CP874,
77 wxFONTENCODING_CP932,
78 wxFONTENCODING_CP936,
79 wxFONTENCODING_CP949,
80 wxFONTENCODING_CP950,
81 wxFONTENCODING_CP1250,
82 wxFONTENCODING_CP1251,
83 wxFONTENCODING_CP1252,
84 wxFONTENCODING_CP1253,
85 wxFONTENCODING_CP1254,
86 wxFONTENCODING_CP1255,
87 wxFONTENCODING_CP1256,
88 wxFONTENCODING_CP1257,
89 wxFONTENCODING_CP437,
90 wxFONTENCODING_UTF7,
91 wxFONTENCODING_UTF8,
92 wxFONTENCODING_UTF16,
93 wxFONTENCODING_UTF16BE,
94 wxFONTENCODING_UTF16LE,
95 wxFONTENCODING_UTF32,
96 wxFONTENCODING_UTF32BE,
97 wxFONTENCODING_UTF32LE,
98 wxFONTENCODING_EUC_JP,
99 wxFONTENCODING_DEFAULT,
100 wxFONTENCODING_BIG5,
101 wxFONTENCODING_SHIFT_JIS,
102 wxFONTENCODING_GB2312,
103 };
104
105 // the descriptions for them
106 static const wxChar* gs_encodingDescs[] =
107 {
108 wxTRANSLATE( "Western European (ISO-8859-1)" ),
109 wxTRANSLATE( "Central European (ISO-8859-2)" ),
110 wxTRANSLATE( "Esperanto (ISO-8859-3)" ),
111 wxTRANSLATE( "Baltic (old) (ISO-8859-4)" ),
112 wxTRANSLATE( "Cyrillic (ISO-8859-5)" ),
113 wxTRANSLATE( "Arabic (ISO-8859-6)" ),
114 wxTRANSLATE( "Greek (ISO-8859-7)" ),
115 wxTRANSLATE( "Hebrew (ISO-8859-8)" ),
116 wxTRANSLATE( "Turkish (ISO-8859-9)" ),
117 wxTRANSLATE( "Nordic (ISO-8859-10)" ),
118 wxTRANSLATE( "Thai (ISO-8859-11)" ),
119 wxTRANSLATE( "Indian (ISO-8859-12)" ),
120 wxTRANSLATE( "Baltic (ISO-8859-13)" ),
121 wxTRANSLATE( "Celtic (ISO-8859-14)" ),
122 wxTRANSLATE( "Western European with Euro (ISO-8859-15)" ),
123 wxTRANSLATE( "KOI8-R" ),
124 wxTRANSLATE( "KOI8-U" ),
125 wxTRANSLATE( "Windows Thai (CP 874)" ),
126 wxTRANSLATE( "Windows Japanese (CP 932)" ),
127 wxTRANSLATE( "Windows Chinese Simplified (CP 936)" ),
128 wxTRANSLATE( "Windows Korean (CP 949)" ),
129 wxTRANSLATE( "Windows Chinese Traditional (CP 950)" ),
130 wxTRANSLATE( "Windows Central European (CP 1250)" ),
131 wxTRANSLATE( "Windows Cyrillic (CP 1251)" ),
132 wxTRANSLATE( "Windows Western European (CP 1252)" ),
133 wxTRANSLATE( "Windows Greek (CP 1253)" ),
134 wxTRANSLATE( "Windows Turkish (CP 1254)" ),
135 wxTRANSLATE( "Windows Hebrew (CP 1255)" ),
136 wxTRANSLATE( "Windows Arabic (CP 1256)" ),
137 wxTRANSLATE( "Windows Baltic (CP 1257)" ),
138 wxTRANSLATE( "Windows/DOS OEM (CP 437)" ),
139 wxTRANSLATE( "Unicode 7 bit (UTF-7)" ),
140 wxTRANSLATE( "Unicode 8 bit (UTF-8)" ),
141 wxTRANSLATE( "Unicode 16 bit (UTF-16)" ),
142 wxTRANSLATE( "Unicode 16 bit Big Endian (UTF-16BE)" ),
143 wxTRANSLATE( "Unicode 16 bit Little Endian (UTF-16LE)" ),
144 wxTRANSLATE( "Unicode 32 bit (UTF-32)" ),
145 wxTRANSLATE( "Unicode 32 bit Big Endian (UTF-32BE)" ),
146 wxTRANSLATE( "Unicode 32 bit Little Endian (UTF-32LE)" ),
147 wxTRANSLATE( "Extended Unix Codepage for Japanese (EUC-JP)" ),
148 wxTRANSLATE( "US-ASCII" ),
149 wxTRANSLATE( "BIG5" ),
150 wxTRANSLATE( "SHIFT-JIS" ),
151 wxTRANSLATE( "GB-2312" ),
152 };
153
154 // and the internal names (these are not translated on purpose!)
155 static const wxChar* gs_encodingNames[WXSIZEOF(gs_encodingDescs)][10] =
156 {
157 // names from the columns correspond to these OS:
158 // Linux Solaris and IRIX HP-UX AIX
159 { _T("ISO-8859-1"), _T("ISO8859-1"), _T("iso88591"), _T("8859-1"), wxT("iso_8859_1"), NULL },
160 { _T("ISO-8859-2"), _T("ISO8859-2"), _T("iso88592"), _T("8859-2"), NULL },
161 { _T("ISO-8859-3"), _T("ISO8859-3"), _T("iso88593"), _T("8859-3"), NULL },
162 { _T("ISO-8859-4"), _T("ISO8859-4"), _T("iso88594"), _T("8859-4"), NULL },
163 { _T("ISO-8859-5"), _T("ISO8859-5"), _T("iso88595"), _T("8859-5"), NULL },
164 { _T("ISO-8859-6"), _T("ISO8859-6"), _T("iso88596"), _T("8859-6"), NULL },
165 { _T("ISO-8859-7"), _T("ISO8859-7"), _T("iso88597"), _T("8859-7"), NULL },
166 { _T("ISO-8859-8"), _T("ISO8859-8"), _T("iso88598"), _T("8859-8"), NULL },
167 { _T("ISO-8859-9"), _T("ISO8859-9"), _T("iso88599"), _T("8859-9"), NULL },
168 { _T("ISO-8859-10"), _T("ISO8859-10"), _T("iso885910"), _T("8859-10"), NULL },
169 { _T("ISO-8859-11"), _T("ISO8859-11"), _T("iso885911"), _T("8859-11"), NULL },
170 { _T("ISO-8859-12"), _T("ISO8859-12"), _T("iso885912"), _T("8859-12"), NULL },
171 { _T("ISO-8859-13"), _T("ISO8859-13"), _T("iso885913"), _T("8859-13"), NULL },
172 { _T("ISO-8859-14"), _T("ISO8859-14"), _T("iso885914"), _T("8859-14"), NULL },
173 { _T("ISO-8859-15"), _T("ISO8859-15"), _T("iso885915"), _T("8859-15"), NULL },
174
175 // although koi8-ru is not strictly speaking the same as koi8-r,
176 // they are similar enough to make mapping it to koi8 better than
177 // not recognizing it at all
178 { wxT( "KOI8-R" ), wxT( "KOI8-RU" ), NULL },
179 { wxT( "KOI8-U" ), NULL },
180
181 { wxT( "WINDOWS-874" ), wxT( "CP-874" ), NULL },
182 { wxT( "WINDOWS-932" ), wxT( "CP-932" ), NULL },
183 { wxT( "WINDOWS-936" ), wxT( "CP-936" ), NULL },
184 { wxT( "WINDOWS-949" ), wxT( "CP-949" ), wxT( "EUC-KR" ), wxT( "eucKR" ), wxT( "euc_kr" ), NULL },
185 { wxT( "WINDOWS-950" ), wxT( "CP-950" ), NULL },
186 { wxT( "WINDOWS-1250" ),wxT( "CP-1250" ), NULL },
187 { wxT( "WINDOWS-1251" ),wxT( "CP-1251" ), NULL },
188 { wxT( "WINDOWS-1252" ),wxT( "CP-1252" ), wxT("IBM-1252"), NULL },
189 { wxT( "WINDOWS-1253" ),wxT( "CP-1253" ), NULL },
190 { wxT( "WINDOWS-1254" ),wxT( "CP-1254" ), NULL },
191 { wxT( "WINDOWS-1255" ),wxT( "CP-1255" ), NULL },
192 { wxT( "WINDOWS-1256" ),wxT( "CP-1256" ), NULL },
193 { wxT( "WINDOWS-1257" ),wxT( "CP-1257" ), NULL },
194 { wxT( "WINDOWS-437" ), wxT( "CP-437" ), NULL },
195
196 { wxT( "UTF-7" ), wxT("utf7"), NULL },
197 { wxT( "UTF-8" ), wxT("utf8"), NULL },
198 { wxT( "UTF-16" ), wxT("UCS-2"), wxT("UCS2"), NULL },
199 { wxT( "UTF-16BE" ), wxT("UCS-2BE"), NULL },
200 { wxT( "UTF-16LE" ), wxT("UCS-2LE"), NULL },
201 { wxT( "UTF-32" ), wxT( "UCS-4" ), wxT("UCS4"), NULL },
202 { wxT( "UTF-32BE" ), wxT( "UCS-4BE" ), NULL },
203 { wxT( "UTF-32LE" ), wxT( "UCS-4LE" ), NULL },
204
205 { wxT( "EUC-JP" ), wxT( "eucJP" ), wxT( "euc_jp" ), wxT( "IBM-eucJP" ), NULL },
206
207 // 646 is for Solaris, roman8 -- for HP-UX
208 { wxT( "US-ASCII" ), wxT( "ASCII" ), wxT("C"), wxT("POSIX"), wxT("ANSI_X3.4-1968"),
209 wxT("646"), wxT("roman8"), wxT( "" ), NULL },
210
211 { wxT( "BIG5" ), wxT("big5"), NULL },
212 { wxT( "SJIS" ), wxT( "SHIFT-JIS" ), wxT( "SHIFT_JIS" ), NULL },
213 { wxT( "GB2312" ), NULL },
214 };
215
216 wxCOMPILE_TIME_ASSERT( WXSIZEOF(gs_encodingDescs) == WXSIZEOF(gs_encodings), EncodingsArraysNotInSync );
217 wxCOMPILE_TIME_ASSERT( WXSIZEOF(gs_encodingNames) == WXSIZEOF(gs_encodings), EncodingsArraysNotInSync );
218
219 // ----------------------------------------------------------------------------
220 // private classes
221 // ----------------------------------------------------------------------------
222
223 // clean up the font mapper object
224 class wxFontMapperModule : public wxModule
225 {
226 public:
227 wxFontMapperModule() : wxModule() { }
228 virtual bool OnInit() { return true; }
229 virtual void OnExit() { delete (wxFontMapperBase*)wxFontMapperBase::Set(NULL); }
230
231 DECLARE_DYNAMIC_CLASS(wxFontMapperModule)
232 };
233
234 IMPLEMENT_DYNAMIC_CLASS(wxFontMapperModule, wxModule)
235
236
237 // ============================================================================
238 // wxFontMapperBase implementation
239 // ============================================================================
240
241 wxFontMapper *wxFontMapperBase::sm_instance = NULL;
242
243 // ----------------------------------------------------------------------------
244 // ctor and dtor
245 // ----------------------------------------------------------------------------
246
247 wxFontMapperBase::wxFontMapperBase()
248 {
249 #if wxUSE_CONFIG && wxUSE_FILECONFIG
250 m_configDummy = NULL;
251 #endif // wxUSE_CONFIG
252 }
253
254 wxFontMapperBase::~wxFontMapperBase()
255 {
256 #if wxUSE_CONFIG && wxUSE_FILECONFIG
257 if ( m_configDummy )
258 delete m_configDummy;
259 #endif // wxUSE_CONFIG
260 }
261
262 bool wxFontMapperBase::IsWxFontMapper()
263 { return false; }
264
265 /* static */
266 wxFontMapperBase *wxFontMapperBase::Get()
267 {
268 if ( !sm_instance )
269 {
270 wxAppTraits *traits = wxTheApp ? wxTheApp->GetTraits() : NULL;
271 if ( traits )
272 {
273 sm_instance = traits->CreateFontMapper();
274
275 wxASSERT_MSG( sm_instance,
276 _T("wxAppTraits::CreateFontMapper() failed") );
277 }
278
279 if ( !sm_instance )
280 {
281 // last resort: we must create something because the existing code
282 // relies on always having a valid font mapper object
283 sm_instance = (wxFontMapper *)new wxFontMapperBase;
284 }
285 }
286
287 return (wxFontMapperBase*)sm_instance;
288 }
289
290 /* static */
291 wxFontMapper *wxFontMapperBase::Set(wxFontMapper *mapper)
292 {
293 wxFontMapper *old = sm_instance;
294 sm_instance = mapper;
295 return old;
296 }
297
298 #if wxUSE_CONFIG && wxUSE_FILECONFIG
299
300 // ----------------------------------------------------------------------------
301 // config usage customisation
302 // ----------------------------------------------------------------------------
303
304 /* static */
305 const wxChar *wxFontMapperBase::GetDefaultConfigPath()
306 {
307 return FONTMAPPER_ROOT_PATH;
308 }
309
310 void wxFontMapperBase::SetConfigPath(const wxString& prefix)
311 {
312 wxCHECK_RET( !prefix.IsEmpty() && prefix[0] == wxCONFIG_PATH_SEPARATOR,
313 wxT("an absolute path should be given to wxFontMapper::SetConfigPath()") );
314
315 m_configRootPath = prefix;
316 }
317
318 // ----------------------------------------------------------------------------
319 // get config object and path for it
320 // ----------------------------------------------------------------------------
321
322 wxConfigBase *wxFontMapperBase::GetConfig()
323 {
324 wxConfigBase *config = wxConfig::Get(false);
325
326 // If there is no global configuration, use an internal memory configuration
327 if ( !config )
328 {
329 if ( !m_configDummy )
330 m_configDummy = new wxMemoryConfig;
331 config = m_configDummy;
332
333 // FIXME: ideally, we should add keys from dummy config to a real one later,
334 // but it is a low-priority task because typical wxWin application
335 // either doesn't use wxConfig at all or creates wxConfig object in
336 // wxApp::OnInit(), before any real interaction with the user takes
337 // place...
338 }
339
340 return config;
341 }
342
343 const wxString& wxFontMapperBase::GetConfigPath()
344 {
345 if ( !m_configRootPath )
346 {
347 // use the default
348 m_configRootPath = GetDefaultConfigPath();
349 }
350
351 return m_configRootPath;
352 }
353
354 // ----------------------------------------------------------------------------
355 // config helpers
356 // ----------------------------------------------------------------------------
357
358 bool wxFontMapperBase::ChangePath(const wxString& pathNew, wxString *pathOld)
359 {
360 wxConfigBase *config = GetConfig();
361 if ( !config )
362 return false;
363
364 *pathOld = config->GetPath();
365
366 wxString path = GetConfigPath();
367 if ( path.IsEmpty() || path.Last() != wxCONFIG_PATH_SEPARATOR )
368 {
369 path += wxCONFIG_PATH_SEPARATOR;
370 }
371
372 wxASSERT_MSG( !pathNew || (pathNew[0] != wxCONFIG_PATH_SEPARATOR),
373 wxT("should be a relative path") );
374
375 path += pathNew;
376
377 config->SetPath(path);
378
379 return true;
380 }
381
382 void wxFontMapperBase::RestorePath(const wxString& pathOld)
383 {
384 GetConfig()->SetPath(pathOld);
385 }
386
387 #endif
388
389 // ----------------------------------------------------------------------------
390 // charset/encoding correspondence
391 // ----------------------------------------------------------------------------
392
393 wxFontEncoding
394 wxFontMapperBase::CharsetToEncoding(const wxString& charset,
395 bool WXUNUSED(interactive))
396 {
397 int enc = NonInteractiveCharsetToEncoding(charset);
398 if ( enc == wxFONTENCODING_UNKNOWN )
399 {
400 // we should return wxFONTENCODING_SYSTEM from here for unknown
401 // encodings
402 enc = wxFONTENCODING_SYSTEM;
403 }
404
405 return (wxFontEncoding)enc;
406 }
407
408 int
409 wxFontMapperBase::NonInteractiveCharsetToEncoding(const wxString& charset)
410 {
411 wxFontEncoding encoding = wxFONTENCODING_SYSTEM;
412
413 // we're going to modify it, make a copy
414 wxString cs = charset;
415
416 #if wxUSE_CONFIG && wxUSE_FILECONFIG
417 // first try the user-defined settings
418 wxFontMapperPathChanger path(this, FONTMAPPER_CHARSET_PATH);
419 if ( path.IsOk() )
420 {
421 wxConfigBase *config = GetConfig();
422
423 // do we have an encoding for this charset?
424 long value = config->Read(charset, -1l);
425 if ( value != -1 )
426 {
427 if ( value == wxFONTENCODING_UNKNOWN )
428 {
429 // don't try to find it, in particular don't ask the user
430 return value;
431 }
432
433 if ( value >= 0 && value <= wxFONTENCODING_MAX )
434 {
435 encoding = (wxFontEncoding)value;
436 }
437 else
438 {
439 wxLogDebug(wxT("corrupted config data: invalid encoding %ld for charset '%s' ignored"),
440 value, charset.c_str());
441 }
442 }
443
444 if ( encoding == wxFONTENCODING_SYSTEM )
445 {
446 // may be we have an alias?
447 config->SetPath(FONTMAPPER_CHARSET_ALIAS_PATH);
448
449 wxString alias = config->Read(charset);
450 if ( !alias.IsEmpty() )
451 {
452 // yes, we do - use it instead
453 cs = alias;
454 }
455 }
456 }
457 #endif // wxUSE_CONFIG
458
459 // if didn't find it there, try to recognize it ourselves
460 if ( encoding == wxFONTENCODING_SYSTEM )
461 {
462 // trim any spaces
463 cs.Trim(true);
464 cs.Trim(false);
465
466 // discard the optional quotes
467 if ( !cs.empty() )
468 {
469 if ( cs[0u] == _T('"') && cs.Last() == _T('"') )
470 {
471 cs = wxString(cs.c_str(), cs.length() - 1);
472 }
473 }
474
475 for ( size_t i = 0; i < WXSIZEOF(gs_encodingNames); ++i )
476 {
477 for ( const wxChar** encName = gs_encodingNames[i]; *encName; ++encName )
478 {
479 if ( cs.CmpNoCase(*encName) == 0 )
480 return gs_encodings[i];
481 }
482 }
483
484 cs.MakeUpper();
485
486 if ( cs.Left(3) == wxT("ISO") )
487 {
488 // the dash is optional (or, to be exact, it is not, but
489 // several brokenmails "forget" it)
490 const wxChar *p = cs.c_str() + 3;
491 if ( *p == wxT('-') )
492 p++;
493
494 // printf( "iso %s\n", (const char*) cs.ToAscii() );
495
496 unsigned int value;
497 if ( wxSscanf(p, wxT("8859-%u"), &value) == 1 )
498 {
499 // printf( "value %d\n", (int)value );
500
501 // make it 0 based and check that it is strictly positive in
502 // the process (no such thing as iso8859-0 encoding)
503 if ( (value-- > 0) &&
504 (value < wxFONTENCODING_ISO8859_MAX -
505 wxFONTENCODING_ISO8859_1) )
506 {
507 // it's a valid ISO8859 encoding
508 value += wxFONTENCODING_ISO8859_1;
509 encoding = (wxFontEncoding)value;
510 }
511 }
512 }
513 else if ( cs.Left(4) == wxT("8859") )
514 {
515 const wxChar *p = cs.c_str();
516
517 unsigned int value;
518 if ( wxSscanf(p, wxT("8859-%u"), &value) == 1 )
519 {
520 // printf( "value %d\n", (int)value );
521
522 // make it 0 based and check that it is strictly positive in
523 // the process (no such thing as iso8859-0 encoding)
524 if ( (value-- > 0) &&
525 (value < wxFONTENCODING_ISO8859_MAX -
526 wxFONTENCODING_ISO8859_1) )
527 {
528 // it's a valid ISO8859 encoding
529 value += wxFONTENCODING_ISO8859_1;
530 encoding = (wxFontEncoding)value;
531 }
532 }
533 }
534 else // check for Windows charsets
535 {
536 size_t len;
537 if ( cs.Left(7) == wxT("WINDOWS") )
538 {
539 len = 7;
540 }
541 else if ( cs.Left(2) == wxT("CP") )
542 {
543 len = 2;
544 }
545 else // not a Windows encoding
546 {
547 len = 0;
548 }
549
550 if ( len )
551 {
552 const wxChar *p = cs.c_str() + len;
553 if ( *p == wxT('-') )
554 p++;
555
556 unsigned int value;
557 if ( wxSscanf(p, wxT("%u"), &value) == 1 )
558 {
559 if ( value >= 1250 )
560 {
561 value -= 1250;
562 if ( value < wxFONTENCODING_CP12_MAX -
563 wxFONTENCODING_CP1250 )
564 {
565 // a valid Windows code page
566 value += wxFONTENCODING_CP1250;
567 encoding = (wxFontEncoding)value;
568 }
569 }
570
571 switch ( value )
572 {
573 case 874:
574 encoding = wxFONTENCODING_CP874;
575 break;
576
577 case 932:
578 encoding = wxFONTENCODING_CP932;
579 break;
580
581 case 936:
582 encoding = wxFONTENCODING_CP936;
583 break;
584
585 case 949:
586 encoding = wxFONTENCODING_CP949;
587 break;
588
589 case 950:
590 encoding = wxFONTENCODING_CP950;
591 break;
592 }
593 }
594 }
595 }
596 //else: unknown
597 }
598
599 return encoding;
600 }
601
602 /* static */
603 size_t wxFontMapperBase::GetSupportedEncodingsCount()
604 {
605 return WXSIZEOF(gs_encodings);
606 }
607
608 /* static */
609 wxFontEncoding wxFontMapperBase::GetEncoding(size_t n)
610 {
611 wxCHECK_MSG( n < WXSIZEOF(gs_encodings), wxFONTENCODING_SYSTEM,
612 _T("wxFontMapper::GetEncoding(): invalid index") );
613
614 return gs_encodings[n];
615 }
616
617 /* static */
618 wxString wxFontMapperBase::GetEncodingDescription(wxFontEncoding encoding)
619 {
620 if ( encoding == wxFONTENCODING_DEFAULT )
621 {
622 return _("Default encoding");
623 }
624
625 const size_t count = WXSIZEOF(gs_encodingDescs);
626
627 for ( size_t i = 0; i < count; i++ )
628 {
629 if ( gs_encodings[i] == encoding )
630 {
631 return wxGetTranslation(gs_encodingDescs[i]);
632 }
633 }
634
635 wxString str;
636 str.Printf(_("Unknown encoding (%d)"), encoding);
637
638 return str;
639 }
640
641 /* static */
642 wxString wxFontMapperBase::GetEncodingName(wxFontEncoding encoding)
643 {
644 if ( encoding == wxFONTENCODING_DEFAULT )
645 {
646 return _("default");
647 }
648
649 const size_t count = WXSIZEOF(gs_encodingNames);
650
651 for ( size_t i = 0; i < count; i++ )
652 {
653 if ( gs_encodings[i] == encoding )
654 {
655 return gs_encodingNames[i][0];
656 }
657 }
658
659 wxString str;
660 str.Printf(_("unknown-%d"), encoding);
661
662 return str;
663 }
664
665 /* static */
666 const wxChar** wxFontMapperBase::GetAllEncodingNames(wxFontEncoding encoding)
667 {
668 static const wxChar* dummy[] = { NULL };
669
670 for ( size_t i = 0; i < WXSIZEOF(gs_encodingNames); i++ )
671 {
672 if ( gs_encodings[i] == encoding )
673 {
674 return gs_encodingNames[i];
675 }
676 }
677
678 return dummy;
679 }
680
681 /* static */
682 wxFontEncoding wxFontMapperBase::GetEncodingFromName(const wxString& name)
683 {
684 const size_t count = WXSIZEOF(gs_encodingNames);
685
686 for ( size_t i = 0; i < count; i++ )
687 {
688 for ( const wxChar** encName = gs_encodingNames[i]; *encName; ++encName )
689 {
690 if ( name.CmpNoCase(*encName) == 0 )
691 return gs_encodings[i];
692 }
693 }
694
695 return wxFONTENCODING_MAX;
696 }
697
698 #endif // wxUSE_FONTMAP
699