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