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