]> git.saurik.com Git - wxWidgets.git/blame - src/common/fmapbase.cpp
Let various AppendXXXColumn helplers return the column created within
[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
75ce4cb1
VS
340
341static wxString gs_defaultConfigPath(FONTMAPPER_ROOT_PATH);
342
e2478fde 343/* static */
75ce4cb1 344const wxString& wxFontMapperBase::GetDefaultConfigPath()
e2478fde 345{
75ce4cb1
VS
346 // NB: we return const wxString& and not wxString for compatibility
347 // with 2.8 that returned const wxChar*
348 return gs_defaultConfigPath;
e2478fde
VZ
349}
350
351void wxFontMapperBase::SetConfigPath(const wxString& prefix)
352{
02761f6c 353 wxCHECK_RET( !prefix.empty() && prefix[0] == wxCONFIG_PATH_SEPARATOR,
e2478fde
VZ
354 wxT("an absolute path should be given to wxFontMapper::SetConfigPath()") );
355
356 m_configRootPath = prefix;
357}
358
359// ----------------------------------------------------------------------------
360// get config object and path for it
361// ----------------------------------------------------------------------------
362
363wxConfigBase *wxFontMapperBase::GetConfig()
364{
5bbca8b0 365 wxConfigBase *config = wxConfig::Get(false);
e2478fde 366
5bbca8b0
KH
367 // If there is no global configuration, use an internal memory configuration
368 if ( !config )
e2478fde 369 {
5bbca8b0
KH
370 if ( !m_configDummy )
371 m_configDummy = new wxMemoryConfig;
372 config = m_configDummy;
373
374 // FIXME: ideally, we should add keys from dummy config to a real one later,
e2478fde
VZ
375 // but it is a low-priority task because typical wxWin application
376 // either doesn't use wxConfig at all or creates wxConfig object in
377 // wxApp::OnInit(), before any real interaction with the user takes
378 // place...
379 }
380
5bbca8b0 381 return config;
e2478fde
VZ
382}
383
384const wxString& wxFontMapperBase::GetConfigPath()
385{
386 if ( !m_configRootPath )
387 {
388 // use the default
389 m_configRootPath = GetDefaultConfigPath();
390 }
391
392 return m_configRootPath;
393}
394
395// ----------------------------------------------------------------------------
396// config helpers
397// ----------------------------------------------------------------------------
398
399bool wxFontMapperBase::ChangePath(const wxString& pathNew, wxString *pathOld)
400{
401 wxConfigBase *config = GetConfig();
402 if ( !config )
a62848fd 403 return false;
e2478fde
VZ
404
405 *pathOld = config->GetPath();
406
407 wxString path = GetConfigPath();
02761f6c 408 if ( path.empty() || path.Last() != wxCONFIG_PATH_SEPARATOR )
e2478fde
VZ
409 {
410 path += wxCONFIG_PATH_SEPARATOR;
411 }
412
413 wxASSERT_MSG( !pathNew || (pathNew[0] != wxCONFIG_PATH_SEPARATOR),
414 wxT("should be a relative path") );
415
416 path += pathNew;
417
418 config->SetPath(path);
419
a62848fd 420 return true;
e2478fde
VZ
421}
422
423void wxFontMapperBase::RestorePath(const wxString& pathOld)
424{
425 GetConfig()->SetPath(pathOld);
426}
427
f1c75e0f
JS
428#endif
429
e2478fde
VZ
430// ----------------------------------------------------------------------------
431// charset/encoding correspondence
432// ----------------------------------------------------------------------------
433
434wxFontEncoding
435wxFontMapperBase::CharsetToEncoding(const wxString& charset,
436 bool WXUNUSED(interactive))
4dc55027
VZ
437{
438 int enc = NonInteractiveCharsetToEncoding(charset);
439 if ( enc == wxFONTENCODING_UNKNOWN )
440 {
441 // we should return wxFONTENCODING_SYSTEM from here for unknown
442 // encodings
443 enc = wxFONTENCODING_SYSTEM;
444 }
445
446 return (wxFontEncoding)enc;
447}
448
449int
450wxFontMapperBase::NonInteractiveCharsetToEncoding(const wxString& charset)
e2478fde
VZ
451{
452 wxFontEncoding encoding = wxFONTENCODING_SYSTEM;
453
454 // we're going to modify it, make a copy
455 wxString cs = charset;
456
4676948b 457#if wxUSE_CONFIG && wxUSE_FILECONFIG
e2478fde
VZ
458 // first try the user-defined settings
459 wxFontMapperPathChanger path(this, FONTMAPPER_CHARSET_PATH);
460 if ( path.IsOk() )
461 {
462 wxConfigBase *config = GetConfig();
463
464 // do we have an encoding for this charset?
465 long value = config->Read(charset, -1l);
466 if ( value != -1 )
467 {
468 if ( value == wxFONTENCODING_UNKNOWN )
469 {
470 // don't try to find it, in particular don't ask the user
4dc55027 471 return value;
e2478fde
VZ
472 }
473
474 if ( value >= 0 && value <= wxFONTENCODING_MAX )
475 {
476 encoding = (wxFontEncoding)value;
477 }
478 else
479 {
480 wxLogDebug(wxT("corrupted config data: invalid encoding %ld for charset '%s' ignored"),
481 value, charset.c_str());
482 }
483 }
484
485 if ( encoding == wxFONTENCODING_SYSTEM )
486 {
487 // may be we have an alias?
488 config->SetPath(FONTMAPPER_CHARSET_ALIAS_PATH);
489
490 wxString alias = config->Read(charset);
02761f6c 491 if ( !alias.empty() )
e2478fde
VZ
492 {
493 // yes, we do - use it instead
494 cs = alias;
495 }
496 }
497 }
498#endif // wxUSE_CONFIG
499
500 // if didn't find it there, try to recognize it ourselves
501 if ( encoding == wxFONTENCODING_SYSTEM )
502 {
503 // trim any spaces
504 cs.Trim(true);
505 cs.Trim(false);
506
507 // discard the optional quotes
508 if ( !cs.empty() )
509 {
510 if ( cs[0u] == _T('"') && cs.Last() == _T('"') )
511 {
512 cs = wxString(cs.c_str(), cs.length() - 1);
513 }
514 }
515
9f7617ca
VZ
516 // check for known encoding name
517 const wxFontEncoding e = GetEncodingFromName(cs);
518 if ( e != wxFONTENCODING_MAX )
519 return e;
8b3eb85d 520
9f7617ca 521 // deal with general encoding names of the form FOO-xxx
8b3eb85d
VZ
522 cs.MakeUpper();
523
524 if ( cs.Left(3) == wxT("ISO") )
e2478fde 525 {
9f7617ca
VZ
526 // the dash is optional (or, to be exact, it is not, but many
527 // broken programs "forget" it in the output they generate)
e2478fde
VZ
528 const wxChar *p = cs.c_str() + 3;
529 if ( *p == wxT('-') )
530 p++;
a62848fd 531
e2478fde
VZ
532 unsigned int value;
533 if ( wxSscanf(p, wxT("8859-%u"), &value) == 1 )
534 {
e2478fde
VZ
535 // make it 0 based and check that it is strictly positive in
536 // the process (no such thing as iso8859-0 encoding)
537 if ( (value-- > 0) &&
538 (value < wxFONTENCODING_ISO8859_MAX -
539 wxFONTENCODING_ISO8859_1) )
540 {
541 // it's a valid ISO8859 encoding
542 value += wxFONTENCODING_ISO8859_1;
543 encoding = (wxFontEncoding)value;
544 }
545 }
546 }
547 else if ( cs.Left(4) == wxT("8859") )
548 {
549 const wxChar *p = cs.c_str();
a62848fd 550
e2478fde
VZ
551 unsigned int value;
552 if ( wxSscanf(p, wxT("8859-%u"), &value) == 1 )
553 {
e2478fde
VZ
554 // make it 0 based and check that it is strictly positive in
555 // the process (no such thing as iso8859-0 encoding)
556 if ( (value-- > 0) &&
557 (value < wxFONTENCODING_ISO8859_MAX -
558 wxFONTENCODING_ISO8859_1) )
559 {
560 // it's a valid ISO8859 encoding
561 value += wxFONTENCODING_ISO8859_1;
562 encoding = (wxFontEncoding)value;
563 }
564 }
565 }
566 else // check for Windows charsets
567 {
568 size_t len;
569 if ( cs.Left(7) == wxT("WINDOWS") )
570 {
571 len = 7;
572 }
573 else if ( cs.Left(2) == wxT("CP") )
574 {
575 len = 2;
576 }
577 else // not a Windows encoding
578 {
579 len = 0;
580 }
581
582 if ( len )
583 {
584 const wxChar *p = cs.c_str() + len;
585 if ( *p == wxT('-') )
586 p++;
587
17a1ebd1 588 unsigned int value;
e2478fde
VZ
589 if ( wxSscanf(p, wxT("%u"), &value) == 1 )
590 {
591 if ( value >= 1250 )
592 {
593 value -= 1250;
594 if ( value < wxFONTENCODING_CP12_MAX -
595 wxFONTENCODING_CP1250 )
596 {
597 // a valid Windows code page
598 value += wxFONTENCODING_CP1250;
599 encoding = (wxFontEncoding)value;
600 }
601 }
602
603 switch ( value )
604 {
c4b4f847
VZ
605 case 866:
606 encoding = wxFONTENCODING_CP866;
607 break;
608
3c832d58
DS
609 case 874:
610 encoding = wxFONTENCODING_CP874;
611 break;
612
e2478fde
VZ
613 case 932:
614 encoding = wxFONTENCODING_CP932;
615 break;
616
617 case 936:
618 encoding = wxFONTENCODING_CP936;
619 break;
620
621 case 949:
622 encoding = wxFONTENCODING_CP949;
623 break;
624
625 case 950:
626 encoding = wxFONTENCODING_CP950;
627 break;
628 }
629 }
630 }
631 }
632 //else: unknown
633 }
634
635 return encoding;
636}
637
638/* static */
639size_t wxFontMapperBase::GetSupportedEncodingsCount()
640{
641 return WXSIZEOF(gs_encodings);
642}
643
644/* static */
645wxFontEncoding wxFontMapperBase::GetEncoding(size_t n)
646{
647 wxCHECK_MSG( n < WXSIZEOF(gs_encodings), wxFONTENCODING_SYSTEM,
648 _T("wxFontMapper::GetEncoding(): invalid index") );
649
650 return gs_encodings[n];
651}
652
653/* static */
654wxString wxFontMapperBase::GetEncodingDescription(wxFontEncoding encoding)
655{
656 if ( encoding == wxFONTENCODING_DEFAULT )
657 {
658 return _("Default encoding");
659 }
660
661 const size_t count = WXSIZEOF(gs_encodingDescs);
662
663 for ( size_t i = 0; i < count; i++ )
664 {
665 if ( gs_encodings[i] == encoding )
666 {
667 return wxGetTranslation(gs_encodingDescs[i]);
668 }
669 }
670
671 wxString str;
672 str.Printf(_("Unknown encoding (%d)"), encoding);
673
674 return str;
675}
676
677/* static */
678wxString wxFontMapperBase::GetEncodingName(wxFontEncoding encoding)
679{
680 if ( encoding == wxFONTENCODING_DEFAULT )
681 {
682 return _("default");
683 }
684
685 const size_t count = WXSIZEOF(gs_encodingNames);
686
687 for ( size_t i = 0; i < count; i++ )
688 {
689 if ( gs_encodings[i] == encoding )
690 {
8b3eb85d 691 return gs_encodingNames[i][0];
e2478fde
VZ
692 }
693 }
694
695 wxString str;
696 str.Printf(_("unknown-%d"), encoding);
697
698 return str;
699}
700
8b3eb85d
VZ
701/* static */
702const wxChar** wxFontMapperBase::GetAllEncodingNames(wxFontEncoding encoding)
703{
704 static const wxChar* dummy[] = { NULL };
705
706 for ( size_t i = 0; i < WXSIZEOF(gs_encodingNames); i++ )
707 {
708 if ( gs_encodings[i] == encoding )
709 {
710 return gs_encodingNames[i];
711 }
712 }
713
714 return dummy;
715}
716
910b9fc5
VZ
717/* static */
718wxFontEncoding wxFontMapperBase::GetEncodingFromName(const wxString& name)
719{
720 const size_t count = WXSIZEOF(gs_encodingNames);
721
9f7617ca
VZ
722 // many charsets use hyphens in their names but some systems use the
723 // same names without hyphens (e.g. "UTF-8" and "UTF8" are both common)
724 // so to avoid bloating gs_encodingNames array too much recognize both
725 // versions with and without hyphens here
726 wxString nameNoHyphens(name);
727 if ( !nameNoHyphens.Replace(_T("-"), _T("")) )
728 {
729 // no replacement has been done, no need to compare twice
730 nameNoHyphens.clear();
731 }
732
733
910b9fc5
VZ
734 for ( size_t i = 0; i < count; i++ )
735 {
8b3eb85d 736 for ( const wxChar** encName = gs_encodingNames[i]; *encName; ++encName )
910b9fc5 737 {
9f7617ca
VZ
738 if ( name.CmpNoCase(*encName) == 0 ||
739 (!nameNoHyphens.empty() &&
740 nameNoHyphens.CmpNoCase(*encName) == 0) )
741 {
8b3eb85d 742 return gs_encodings[i];
9f7617ca 743 }
910b9fc5
VZ
744 }
745 }
746
910b9fc5
VZ
747 return wxFONTENCODING_MAX;
748}
749
e2478fde 750#endif // wxUSE_FONTMAP