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