]> git.saurik.com Git - wxWidgets.git/blob - src/common/fmapbase.cpp
implement button support for pre-XP systems (or with themes disabled); using only...
[wxWidgets.git] / src / common / fmapbase.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/fmapbase.cpp
3 // Purpose: wxFontMapperBase class implementation
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 21.06.2003 (extracted from common/fontmap.cpp)
7 // RCS-ID: $Id$
8 // Copyright: (c) 1999-2003 Vadim Zeitlin <vadim@wxwindows.org>
9 // License: wxWindows license
10 ///////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 // for compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
22
23 #ifdef __BORLANDC__
24 #pragma hdrstop
25 #endif
26
27 #if wxUSE_FONTMAP
28
29 #ifndef WX_PRECOMP
30 #include "wx/app.h"
31 #include "wx/log.h"
32 #include "wx/intl.h"
33 #include "wx/module.h"
34 #include "wx/wxcrtvararg.h"
35 #endif //WX_PRECOMP
36
37 #if defined(__WXMSW__)
38 #include "wx/msw/private.h" // includes windows.h for LOGFONT
39 #include "wx/msw/winundef.h"
40 #endif
41
42 #include "wx/fontmap.h"
43 #include "wx/fmappriv.h"
44
45 #include "wx/apptrait.h"
46
47 // wxMemoryConfig uses wxFileConfig
48 #if wxUSE_CONFIG && wxUSE_FILECONFIG
49 #include "wx/config.h"
50 #include "wx/memconf.h"
51 #endif
52
53 // ----------------------------------------------------------------------------
54 // constants
55 // ----------------------------------------------------------------------------
56
57 // encodings supported by GetEncodingDescription
58 static 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,
76 wxFONTENCODING_KOI8_U,
77 wxFONTENCODING_CP874,
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,
93 wxFONTENCODING_UTF16BE,
94 wxFONTENCODING_UTF16LE,
95 wxFONTENCODING_UTF32BE,
96 wxFONTENCODING_UTF32LE,
97 wxFONTENCODING_EUC_JP,
98 wxFONTENCODING_DEFAULT,
99 wxFONTENCODING_BIG5,
100 wxFONTENCODING_SHIFT_JIS,
101 wxFONTENCODING_GB2312,
102 wxFONTENCODING_ISO2022_JP,
103
104 wxFONTENCODING_MACROMAN,
105 wxFONTENCODING_MACJAPANESE,
106 wxFONTENCODING_MACCHINESETRAD,
107 wxFONTENCODING_MACKOREAN,
108 wxFONTENCODING_MACARABIC,
109 wxFONTENCODING_MACHEBREW,
110 wxFONTENCODING_MACGREEK,
111 wxFONTENCODING_MACCYRILLIC,
112 wxFONTENCODING_MACDEVANAGARI,
113 wxFONTENCODING_MACGURMUKHI,
114 wxFONTENCODING_MACGUJARATI,
115 wxFONTENCODING_MACORIYA,
116 wxFONTENCODING_MACBENGALI,
117 wxFONTENCODING_MACTAMIL,
118 wxFONTENCODING_MACTELUGU,
119 wxFONTENCODING_MACKANNADA,
120 wxFONTENCODING_MACMALAJALAM,
121 wxFONTENCODING_MACSINHALESE,
122 wxFONTENCODING_MACBURMESE,
123 wxFONTENCODING_MACKHMER,
124 wxFONTENCODING_MACTHAI,
125 wxFONTENCODING_MACLAOTIAN,
126 wxFONTENCODING_MACGEORGIAN,
127 wxFONTENCODING_MACARMENIAN,
128 wxFONTENCODING_MACCHINESESIMP,
129 wxFONTENCODING_MACTIBETAN,
130 wxFONTENCODING_MACMONGOLIAN,
131 wxFONTENCODING_MACETHIOPIC,
132 wxFONTENCODING_MACCENTRALEUR,
133 wxFONTENCODING_MACVIATNAMESE,
134 wxFONTENCODING_MACARABICEXT,
135 wxFONTENCODING_MACSYMBOL,
136 wxFONTENCODING_MACDINGBATS,
137 wxFONTENCODING_MACTURKISH,
138 wxFONTENCODING_MACCROATIAN,
139 wxFONTENCODING_MACICELANDIC,
140 wxFONTENCODING_MACROMANIAN,
141 wxFONTENCODING_MACCELTIC,
142 wxFONTENCODING_MACGAELIC,
143 wxFONTENCODING_MACKEYBOARD
144 };
145
146 // the descriptions for them
147 static const char* gs_encodingDescs[] =
148 {
149 wxTRANSLATE( "Western European (ISO-8859-1)" ),
150 wxTRANSLATE( "Central European (ISO-8859-2)" ),
151 wxTRANSLATE( "Esperanto (ISO-8859-3)" ),
152 wxTRANSLATE( "Baltic (old) (ISO-8859-4)" ),
153 wxTRANSLATE( "Cyrillic (ISO-8859-5)" ),
154 wxTRANSLATE( "Arabic (ISO-8859-6)" ),
155 wxTRANSLATE( "Greek (ISO-8859-7)" ),
156 wxTRANSLATE( "Hebrew (ISO-8859-8)" ),
157 wxTRANSLATE( "Turkish (ISO-8859-9)" ),
158 wxTRANSLATE( "Nordic (ISO-8859-10)" ),
159 wxTRANSLATE( "Thai (ISO-8859-11)" ),
160 wxTRANSLATE( "Indian (ISO-8859-12)" ),
161 wxTRANSLATE( "Baltic (ISO-8859-13)" ),
162 wxTRANSLATE( "Celtic (ISO-8859-14)" ),
163 wxTRANSLATE( "Western European with Euro (ISO-8859-15)" ),
164 wxTRANSLATE( "KOI8-R" ),
165 wxTRANSLATE( "KOI8-U" ),
166 wxTRANSLATE( "Windows Thai (CP 874)" ),
167 wxTRANSLATE( "Windows Japanese (CP 932)" ),
168 wxTRANSLATE( "Windows Chinese Simplified (CP 936)" ),
169 wxTRANSLATE( "Windows Korean (CP 949)" ),
170 wxTRANSLATE( "Windows Chinese Traditional (CP 950)" ),
171 wxTRANSLATE( "Windows Central European (CP 1250)" ),
172 wxTRANSLATE( "Windows Cyrillic (CP 1251)" ),
173 wxTRANSLATE( "Windows Western European (CP 1252)" ),
174 wxTRANSLATE( "Windows Greek (CP 1253)" ),
175 wxTRANSLATE( "Windows Turkish (CP 1254)" ),
176 wxTRANSLATE( "Windows Hebrew (CP 1255)" ),
177 wxTRANSLATE( "Windows Arabic (CP 1256)" ),
178 wxTRANSLATE( "Windows Baltic (CP 1257)" ),
179 wxTRANSLATE( "Windows/DOS OEM (CP 437)" ),
180 wxTRANSLATE( "Unicode 7 bit (UTF-7)" ),
181 wxTRANSLATE( "Unicode 8 bit (UTF-8)" ),
182 #ifdef WORDS_BIGENDIAN
183 wxTRANSLATE( "Unicode 16 bit (UTF-16)" ),
184 wxTRANSLATE( "Unicode 16 bit Little Endian (UTF-16LE)" ),
185 wxTRANSLATE( "Unicode 32 bit (UTF-32)" ),
186 wxTRANSLATE( "Unicode 32 bit Little Endian (UTF-32LE)" ),
187 #else // WORDS_BIGENDIAN
188 wxTRANSLATE( "Unicode 16 bit Big Endian (UTF-16BE)" ),
189 wxTRANSLATE( "Unicode 16 bit (UTF-16)" ),
190 wxTRANSLATE( "Unicode 32 bit Big Endian (UTF-32BE)" ),
191 wxTRANSLATE( "Unicode 32 bit (UTF-32)" ),
192 #endif // WORDS_BIGENDIAN
193 wxTRANSLATE( "Extended Unix Codepage for Japanese (EUC-JP)" ),
194 wxTRANSLATE( "US-ASCII" ),
195 wxTRANSLATE( "BIG5" ),
196 wxTRANSLATE( "SHIFT-JIS" ),
197 wxTRANSLATE( "GB-2312" ),
198 wxTRANSLATE( "ISO-2022-JP" ),
199
200 wxTRANSLATE( "MacRoman" ),
201 wxTRANSLATE( "MacJapanese" ),
202 wxTRANSLATE( "MacChineseTrad" ),
203 wxTRANSLATE( "MacKorean" ),
204 wxTRANSLATE( "MacArabic" ),
205 wxTRANSLATE( "MacHebrew" ),
206 wxTRANSLATE( "MacGreek" ),
207 wxTRANSLATE( "MacCyrillic" ),
208 wxTRANSLATE( "MacDevanagari" ),
209 wxTRANSLATE( "MacGurmukhi" ),
210 wxTRANSLATE( "MacGujarati" ),
211 wxTRANSLATE( "MacOriya" ),
212 wxTRANSLATE( "MacBengali" ),
213 wxTRANSLATE( "MacTamil" ),
214 wxTRANSLATE( "MacTelugu" ),
215 wxTRANSLATE( "MacKannada" ),
216 wxTRANSLATE( "MacMalayalam" ),
217 wxTRANSLATE( "MacSinhalese" ),
218 wxTRANSLATE( "MacBurmese" ),
219 wxTRANSLATE( "MacKhmer" ),
220 wxTRANSLATE( "MacThai" ),
221 wxTRANSLATE( "MacLaotian" ),
222 wxTRANSLATE( "MacGeorgian" ),
223 wxTRANSLATE( "MacArmenian" ),
224 wxTRANSLATE( "MacChineseSimp" ),
225 wxTRANSLATE( "MacTibetan" ),
226 wxTRANSLATE( "MacMongolian" ),
227 wxTRANSLATE( "MacEthiopic" ),
228 wxTRANSLATE( "MacCentralEurRoman" ),
229 wxTRANSLATE( "MacVietnamese" ),
230 wxTRANSLATE( "MacExtArabic" ),
231 wxTRANSLATE( "MacSymbol" ),
232 wxTRANSLATE( "MacDingbats" ),
233 wxTRANSLATE( "MacTurkish" ),
234 wxTRANSLATE( "MacCroatian" ),
235 wxTRANSLATE( "MacIcelandic" ),
236 wxTRANSLATE( "MacRomanian" ),
237 wxTRANSLATE( "MacCeltic" ),
238 wxTRANSLATE( "MacGaelic" ),
239 wxTRANSLATE( "MacKeyboardGlyphs" )
240 };
241
242 // and the internal names (these are not translated on purpose!)
243 static const wxChar* gs_encodingNames[WXSIZEOF(gs_encodingDescs)][9] =
244 {
245 // names from the columns correspond to these OS:
246 // Linux Solaris and IRIX HP-UX AIX
247 { _T("ISO-8859-1"), _T("ISO8859-1"), _T("iso88591"), _T("8859-1"), wxT("iso_8859_1"), NULL },
248 { _T("ISO-8859-2"), _T("ISO8859-2"), _T("iso88592"), _T("8859-2"), NULL },
249 { _T("ISO-8859-3"), _T("ISO8859-3"), _T("iso88593"), _T("8859-3"), NULL },
250 { _T("ISO-8859-4"), _T("ISO8859-4"), _T("iso88594"), _T("8859-4"), NULL },
251 { _T("ISO-8859-5"), _T("ISO8859-5"), _T("iso88595"), _T("8859-5"), NULL },
252 { _T("ISO-8859-6"), _T("ISO8859-6"), _T("iso88596"), _T("8859-6"), NULL },
253 { _T("ISO-8859-7"), _T("ISO8859-7"), _T("iso88597"), _T("8859-7"), NULL },
254 { _T("ISO-8859-8"), _T("ISO8859-8"), _T("iso88598"), _T("8859-8"), NULL },
255 { _T("ISO-8859-9"), _T("ISO8859-9"), _T("iso88599"), _T("8859-9"), NULL },
256 { _T("ISO-8859-10"), _T("ISO8859-10"), _T("iso885910"), _T("8859-10"), NULL },
257 { _T("ISO-8859-11"), _T("ISO8859-11"), _T("iso885911"), _T("8859-11"), NULL },
258 { _T("ISO-8859-12"), _T("ISO8859-12"), _T("iso885912"), _T("8859-12"), NULL },
259 { _T("ISO-8859-13"), _T("ISO8859-13"), _T("iso885913"), _T("8859-13"), NULL },
260 { _T("ISO-8859-14"), _T("ISO8859-14"), _T("iso885914"), _T("8859-14"), NULL },
261 { _T("ISO-8859-15"), _T("ISO8859-15"), _T("iso885915"), _T("8859-15"), NULL },
262
263 // although koi8-ru is not strictly speaking the same as koi8-r,
264 // they are similar enough to make mapping it to koi8 better than
265 // not recognizing it at all
266 { wxT( "KOI8-R" ), wxT( "KOI8-RU" ), NULL },
267 { wxT( "KOI8-U" ), NULL },
268
269 { wxT( "WINDOWS-874" ), wxT( "CP874" ), wxT( "MS874" ), wxT( "IBM-874" ), NULL },
270 { wxT( "WINDOWS-932" ), wxT( "CP932" ), wxT( "MS932" ), wxT( "IBM-932" ), NULL },
271 { wxT( "WINDOWS-936" ), wxT( "CP936" ), wxT( "MS936" ), wxT( "IBM-936" ), NULL },
272 { wxT( "WINDOWS-949" ), wxT( "CP949" ), wxT( "MS949" ), wxT( "IBM-949" ), wxT( "EUC-KR" ), wxT( "eucKR" ), wxT( "euc_kr" ), NULL },
273 { wxT( "WINDOWS-950" ), wxT( "CP950" ), wxT( "MS950" ), wxT( "IBM-950" ), NULL },
274 { wxT( "WINDOWS-1250" ),wxT( "CP1250" ),wxT( "MS1250" ),wxT( "IBM-1250" ),NULL },
275 { wxT( "WINDOWS-1251" ),wxT( "CP1251" ),wxT( "MS1251" ),wxT( "IBM-1251" ),NULL },
276 { wxT( "WINDOWS-1252" ),wxT( "CP1252" ),wxT( "MS1252" ),wxT( "IBM-1252" ),NULL },
277 { wxT( "WINDOWS-1253" ),wxT( "CP1253" ),wxT( "MS1253" ),wxT( "IBM-1253" ),NULL },
278 { wxT( "WINDOWS-1254" ),wxT( "CP1254" ),wxT( "MS1254" ),wxT( "IBM-1254" ),NULL },
279 { wxT( "WINDOWS-1255" ),wxT( "CP1255" ),wxT( "MS1255" ),wxT( "IBM-1255" ),NULL },
280 { wxT( "WINDOWS-1256" ),wxT( "CP1256" ),wxT( "MS1256" ),wxT( "IBM-1256" ),NULL },
281 { wxT( "WINDOWS-1257" ),wxT( "CP1257" ),wxT( "MS1257" ),wxT( "IBM-1257" ),NULL },
282 { wxT( "WINDOWS-437" ), wxT( "CP437" ), wxT( "MS437" ), wxT( "IBM-437" ), NULL },
283
284 { wxT( "UTF-7" ), wxT("UTF7"), NULL },
285 { wxT( "UTF-8" ), wxT("UTF8"), NULL },
286 #ifdef WORDS_BIGENDIAN
287 { wxT( "UTF-16BE" ), wxT("UTF16BE"), wxT("UCS-2BE"), wxT("UCS2BE"), wxT("UTF-16"), wxT("UTF16"), wxT("UCS-2"), wxT("UCS2"), NULL },
288 { wxT( "UTF-16LE" ), wxT("UTF16LE"), wxT("UCS-2LE"), wxT("UCS2LE"), NULL },
289 { wxT( "UTF-32BE" ), wxT("UTF32BE"), wxT("UCS-4BE" ), wxT("UTF-32"), wxT("UTF32"), wxT("UCS-4"), wxT("UCS4"), NULL },
290 { wxT( "UTF-32LE" ), wxT("UTF32LE"), wxT("UCS-4LE"), wxT("UCS4LE"), NULL },
291 #else // WORDS_BIGENDIAN
292 { wxT("UTF-16BE"), wxT("UTF16BE"), wxT("UCS-2BE"), wxT("UCS2BE"), NULL },
293 { wxT("UTF-16LE"), wxT("UTF16LE"), wxT("UCS-2LE"), wxT("UTF-16"), wxT("UTF16"), wxT("UCS-2"), wxT("UCS2"), NULL },
294 { wxT("UTF-32BE"), wxT("UTF32BE"), wxT("UCS-4BE"), wxT("UCS4BE"), NULL },
295 { wxT("UTF-32LE"), wxT("UTF32LE"), wxT("UCS-4LE"), wxT("UCS4LE"), wxT("UTF-32"), wxT("UTF32"), wxT("UCS-4"), wxT("UCS4"), NULL },
296 #endif // WORDS_BIGENDIAN
297
298 { wxT( "EUC-JP" ), wxT( "eucJP" ), wxT( "euc_jp" ), wxT( "IBM-eucJP" ), NULL },
299
300 // 646 is for Solaris, roman8 -- for HP-UX
301 { wxT( "US-ASCII" ), wxT( "ASCII" ), wxT("C"), wxT("POSIX"), wxT("ANSI_X3.4-1968"),
302 wxT("646"), wxT("roman8"), wxT( "" ), NULL },
303
304 { wxT( "BIG5" ), wxT("big5"), NULL },
305 { wxT( "SJIS" ), wxT( "SHIFT-JIS" ), wxT( "SHIFT_JIS" ), NULL },
306 { wxT( "GB2312" ), NULL },
307 { wxT( "ISO-2022-JP" ), NULL },
308
309
310 { wxT( "MacRoman" ), NULL },
311 { wxT( "MacJapanese" ), NULL },
312 { wxT( "MacChineseTrad" ), NULL },
313 { wxT( "MacKorean" ), NULL },
314 { wxT( "MacArabic" ), NULL },
315 { wxT( "MacHebrew" ), NULL },
316 { wxT( "MacGreek" ), NULL },
317 { wxT( "MacCyrillic" ), NULL },
318 { wxT( "MacDevanagari" ), NULL },
319 { wxT( "MacGurmukhi" ), NULL },
320 { wxT( "MacGujarati" ), NULL },
321 { wxT( "MacOriya" ), NULL },
322 { wxT( "MacBengali" ), NULL },
323 { wxT( "MacTamil" ), NULL },
324 { wxT( "MacTelugu" ), NULL },
325 { wxT( "MacKannada" ), NULL },
326 { wxT( "MacMalayalam" ), NULL },
327 { wxT( "MacSinhalese" ), NULL },
328 { wxT( "MacBurmese" ), NULL },
329 { wxT( "MacKhmer" ), NULL },
330 { wxT( "MacThai" ), NULL },
331 { wxT( "MacLaotian" ), NULL },
332 { wxT( "MacGeorgian" ), NULL },
333 { wxT( "MacArmenian" ), NULL },
334 { wxT( "MacChineseSimp" ), NULL },
335 { wxT( "MacTibetan" ), NULL },
336 { wxT( "MacMongolian" ), NULL },
337 { wxT( "MacEthiopic" ), NULL },
338 { wxT( "MacCentralEurRoman" ), NULL },
339 { wxT( "MacVietnamese" ), NULL },
340 { wxT( "MacExtArabic" ), NULL },
341 { wxT( "MacSymbol" ), NULL },
342 { wxT( "MacDingbats" ), NULL },
343 { wxT( "MacTurkish" ), NULL },
344 { wxT( "MacCroatian" ), NULL },
345 { wxT( "MacIcelandic" ), NULL },
346 { wxT( "MacRomanian" ), NULL },
347 { wxT( "MacCeltic" ), NULL },
348 { wxT( "MacGaelic" ), NULL },
349 { wxT( "MacKeyboardGlyphs" ), NULL }
350 };
351
352 wxCOMPILE_TIME_ASSERT( WXSIZEOF(gs_encodingDescs) == WXSIZEOF(gs_encodings), EncodingsArraysNotInSync );
353 wxCOMPILE_TIME_ASSERT( WXSIZEOF(gs_encodingNames) == WXSIZEOF(gs_encodings), EncodingsArraysNotInSync );
354
355 // ----------------------------------------------------------------------------
356 // private classes
357 // ----------------------------------------------------------------------------
358
359 // clean up the font mapper object
360 class wxFontMapperModule : public wxModule
361 {
362 public:
363 wxFontMapperModule() : wxModule() { }
364
365 virtual bool OnInit()
366 {
367 // a dummy wxFontMapperBase object could have been created during the
368 // program startup before wxApp was created, we have to delete it to
369 // allow creating the real font mapper next time it is needed now that
370 // we can create it (when the modules are initialized, wxApp object
371 // already exists)
372 wxFontMapperBase *fm = wxFontMapperBase::Get();
373 if ( fm && fm->IsDummy() )
374 wxFontMapperBase::Reset();
375
376 return true;
377 }
378
379 virtual void OnExit()
380 {
381 wxFontMapperBase::Reset();
382 }
383
384 DECLARE_DYNAMIC_CLASS(wxFontMapperModule)
385 };
386
387 IMPLEMENT_DYNAMIC_CLASS(wxFontMapperModule, wxModule)
388
389
390 // ============================================================================
391 // wxFontMapperBase implementation
392 // ============================================================================
393
394 wxFontMapper *wxFontMapperBase::sm_instance = NULL;
395
396 // ----------------------------------------------------------------------------
397 // ctor and dtor
398 // ----------------------------------------------------------------------------
399
400 wxFontMapperBase::wxFontMapperBase()
401 {
402 #if wxUSE_CONFIG && wxUSE_FILECONFIG
403 m_configDummy = NULL;
404 #endif // wxUSE_CONFIG
405 }
406
407 wxFontMapperBase::~wxFontMapperBase()
408 {
409 #if wxUSE_CONFIG && wxUSE_FILECONFIG
410 if ( m_configDummy )
411 delete m_configDummy;
412 #endif // wxUSE_CONFIG
413 }
414
415 /* static */
416 wxFontMapperBase *wxFontMapperBase::Get()
417 {
418 if ( !sm_instance )
419 {
420 wxAppTraits *traits = wxTheApp ? wxTheApp->GetTraits() : NULL;
421 if ( traits )
422 {
423 sm_instance = traits->CreateFontMapper();
424
425 wxASSERT_MSG( sm_instance,
426 _T("wxAppTraits::CreateFontMapper() failed") );
427 }
428
429 if ( !sm_instance )
430 {
431 // last resort: we must create something because the existing code
432 // relies on always having a valid font mapper object
433 sm_instance = (wxFontMapper *)new wxFontMapperBase;
434 }
435 }
436
437 return (wxFontMapperBase*)sm_instance;
438 }
439
440 /* static */
441 wxFontMapper *wxFontMapperBase::Set(wxFontMapper *mapper)
442 {
443 wxFontMapper *old = sm_instance;
444 sm_instance = mapper;
445 return old;
446 }
447
448 /* static */
449 void wxFontMapperBase::Reset()
450 {
451 if ( sm_instance )
452 {
453 // we need a cast as wxFontMapper is not fully declared here and so the
454 // compiler can't know that it derives from wxFontMapperBase (but
455 // run-time behaviour will be correct because the dtor is virtual)
456 delete (wxFontMapperBase *)sm_instance;
457 sm_instance = NULL;
458 }
459 }
460
461 #if wxUSE_CONFIG && wxUSE_FILECONFIG
462
463 // ----------------------------------------------------------------------------
464 // config usage customisation
465 // ----------------------------------------------------------------------------
466
467
468 static wxString gs_defaultConfigPath(FONTMAPPER_ROOT_PATH);
469
470 /* static */
471 const wxString& wxFontMapperBase::GetDefaultConfigPath()
472 {
473 // NB: we return const wxString& and not wxString for compatibility
474 // with 2.8 that returned const wxChar*
475 return gs_defaultConfigPath;
476 }
477
478 void wxFontMapperBase::SetConfigPath(const wxString& prefix)
479 {
480 wxCHECK_RET( !prefix.empty() && prefix[0] == wxCONFIG_PATH_SEPARATOR,
481 wxT("an absolute path should be given to wxFontMapper::SetConfigPath()") );
482
483 m_configRootPath = prefix;
484 }
485
486 // ----------------------------------------------------------------------------
487 // get config object and path for it
488 // ----------------------------------------------------------------------------
489
490 wxConfigBase *wxFontMapperBase::GetConfig()
491 {
492 wxConfigBase *config = wxConfig::Get(false);
493
494 // If there is no global configuration, use an internal memory configuration
495 if ( !config )
496 {
497 if ( !m_configDummy )
498 m_configDummy = new wxMemoryConfig;
499 config = m_configDummy;
500
501 // FIXME: ideally, we should add keys from dummy config to a real one later,
502 // but it is a low-priority task because typical wxWin application
503 // either doesn't use wxConfig at all or creates wxConfig object in
504 // wxApp::OnInit(), before any real interaction with the user takes
505 // place...
506 }
507
508 return config;
509 }
510
511 const wxString& wxFontMapperBase::GetConfigPath()
512 {
513 if ( !m_configRootPath )
514 {
515 // use the default
516 m_configRootPath = GetDefaultConfigPath();
517 }
518
519 return m_configRootPath;
520 }
521
522 // ----------------------------------------------------------------------------
523 // config helpers
524 // ----------------------------------------------------------------------------
525
526 bool wxFontMapperBase::ChangePath(const wxString& pathNew, wxString *pathOld)
527 {
528 wxConfigBase *config = GetConfig();
529 if ( !config )
530 return false;
531
532 *pathOld = config->GetPath();
533
534 wxString path = GetConfigPath();
535 if ( path.empty() || path.Last() != wxCONFIG_PATH_SEPARATOR )
536 {
537 path += wxCONFIG_PATH_SEPARATOR;
538 }
539
540 wxASSERT_MSG( !pathNew || (pathNew[0] != wxCONFIG_PATH_SEPARATOR),
541 wxT("should be a relative path") );
542
543 path += pathNew;
544
545 config->SetPath(path);
546
547 return true;
548 }
549
550 void wxFontMapperBase::RestorePath(const wxString& pathOld)
551 {
552 GetConfig()->SetPath(pathOld);
553 }
554
555 #endif
556
557 // ----------------------------------------------------------------------------
558 // charset/encoding correspondence
559 // ----------------------------------------------------------------------------
560
561 wxFontEncoding
562 wxFontMapperBase::CharsetToEncoding(const wxString& charset,
563 bool WXUNUSED(interactive))
564 {
565 int enc = NonInteractiveCharsetToEncoding(charset);
566 if ( enc == wxFONTENCODING_UNKNOWN )
567 {
568 // we should return wxFONTENCODING_SYSTEM from here for unknown
569 // encodings
570 enc = wxFONTENCODING_SYSTEM;
571 }
572
573 return (wxFontEncoding)enc;
574 }
575
576 int
577 wxFontMapperBase::NonInteractiveCharsetToEncoding(const wxString& charset)
578 {
579 wxFontEncoding encoding = wxFONTENCODING_SYSTEM;
580
581 // we're going to modify it, make a copy
582 wxString cs = charset;
583
584 #if wxUSE_CONFIG && wxUSE_FILECONFIG
585 // first try the user-defined settings
586 wxFontMapperPathChanger path(this, FONTMAPPER_CHARSET_PATH);
587 if ( path.IsOk() )
588 {
589 wxConfigBase *config = GetConfig();
590
591 // do we have an encoding for this charset?
592 long value = config->Read(charset, -1l);
593 if ( value != -1 )
594 {
595 if ( value == wxFONTENCODING_UNKNOWN )
596 {
597 // don't try to find it, in particular don't ask the user
598 return value;
599 }
600
601 if ( value >= 0 && value <= wxFONTENCODING_MAX )
602 {
603 encoding = (wxFontEncoding)value;
604 }
605 else
606 {
607 wxLogDebug(wxT("corrupted config data: invalid encoding %ld for charset '%s' ignored"),
608 value, charset.c_str());
609 }
610 }
611
612 if ( encoding == wxFONTENCODING_SYSTEM )
613 {
614 // may be we have an alias?
615 config->SetPath(FONTMAPPER_CHARSET_ALIAS_PATH);
616
617 wxString alias = config->Read(charset);
618 if ( !alias.empty() )
619 {
620 // yes, we do - use it instead
621 cs = alias;
622 }
623 }
624 }
625 #endif // wxUSE_CONFIG
626
627 // if didn't find it there, try to recognize it ourselves
628 if ( encoding == wxFONTENCODING_SYSTEM )
629 {
630 // trim any spaces
631 cs.Trim(true);
632 cs.Trim(false);
633
634 // discard the optional quotes
635 if ( !cs.empty() )
636 {
637 if ( cs[0u] == _T('"') && cs.Last() == _T('"') )
638 {
639 cs = wxString(cs.c_str(), cs.length() - 1);
640 }
641 }
642
643 for ( size_t i = 0; i < WXSIZEOF(gs_encodingNames); ++i )
644 {
645 for ( const wxChar** encName = gs_encodingNames[i]; *encName; ++encName )
646 {
647 if ( cs.CmpNoCase(*encName) == 0 )
648 return gs_encodings[i];
649 }
650 }
651
652 cs.MakeUpper();
653
654 if ( cs.Left(3) == wxT("ISO") )
655 {
656 // the dash is optional (or, to be exact, it is not, but
657 // several broken programs "forget" it)
658 const wxChar *p = cs.c_str() + 3;
659 if ( *p == wxT('-') )
660 p++;
661
662 unsigned int value;
663 if ( wxSscanf(p, wxT("8859-%u"), &value) == 1 )
664 {
665 // make it 0 based and check that it is strictly positive in
666 // the process (no such thing as iso8859-0 encoding)
667 if ( (value-- > 0) &&
668 (value < wxFONTENCODING_ISO8859_MAX -
669 wxFONTENCODING_ISO8859_1) )
670 {
671 // it's a valid ISO8859 encoding
672 value += wxFONTENCODING_ISO8859_1;
673 encoding = (wxFontEncoding)value;
674 }
675 }
676 }
677 else if ( cs.Left(4) == wxT("8859") )
678 {
679 const wxChar *p = cs.c_str();
680
681 unsigned int value;
682 if ( wxSscanf(p, wxT("8859-%u"), &value) == 1 )
683 {
684 // make it 0 based and check that it is strictly positive in
685 // the process (no such thing as iso8859-0 encoding)
686 if ( (value-- > 0) &&
687 (value < wxFONTENCODING_ISO8859_MAX -
688 wxFONTENCODING_ISO8859_1) )
689 {
690 // it's a valid ISO8859 encoding
691 value += wxFONTENCODING_ISO8859_1;
692 encoding = (wxFontEncoding)value;
693 }
694 }
695 }
696 else // check for Windows charsets
697 {
698 size_t len;
699 if ( cs.Left(7) == wxT("WINDOWS") )
700 {
701 len = 7;
702 }
703 else if ( cs.Left(2) == wxT("CP") )
704 {
705 len = 2;
706 }
707 else // not a Windows encoding
708 {
709 len = 0;
710 }
711
712 if ( len )
713 {
714 const wxChar *p = cs.c_str() + len;
715 if ( *p == wxT('-') )
716 p++;
717
718 unsigned int value;
719 if ( wxSscanf(p, wxT("%u"), &value) == 1 )
720 {
721 if ( value >= 1250 )
722 {
723 value -= 1250;
724 if ( value < wxFONTENCODING_CP12_MAX -
725 wxFONTENCODING_CP1250 )
726 {
727 // a valid Windows code page
728 value += wxFONTENCODING_CP1250;
729 encoding = (wxFontEncoding)value;
730 }
731 }
732
733 switch ( value )
734 {
735 case 866:
736 encoding = wxFONTENCODING_CP866;
737 break;
738
739 case 874:
740 encoding = wxFONTENCODING_CP874;
741 break;
742
743 case 932:
744 encoding = wxFONTENCODING_CP932;
745 break;
746
747 case 936:
748 encoding = wxFONTENCODING_CP936;
749 break;
750
751 case 949:
752 encoding = wxFONTENCODING_CP949;
753 break;
754
755 case 950:
756 encoding = wxFONTENCODING_CP950;
757 break;
758 }
759 }
760 }
761 }
762 //else: unknown
763 }
764
765 return encoding;
766 }
767
768 /* static */
769 size_t wxFontMapperBase::GetSupportedEncodingsCount()
770 {
771 return WXSIZEOF(gs_encodings);
772 }
773
774 /* static */
775 wxFontEncoding wxFontMapperBase::GetEncoding(size_t n)
776 {
777 wxCHECK_MSG( n < WXSIZEOF(gs_encodings), wxFONTENCODING_SYSTEM,
778 _T("wxFontMapper::GetEncoding(): invalid index") );
779
780 return gs_encodings[n];
781 }
782
783 /* static */
784 wxString wxFontMapperBase::GetEncodingDescription(wxFontEncoding encoding)
785 {
786 if ( encoding == wxFONTENCODING_DEFAULT )
787 {
788 return _("Default encoding");
789 }
790
791 const size_t count = WXSIZEOF(gs_encodingDescs);
792
793 for ( size_t i = 0; i < count; i++ )
794 {
795 if ( gs_encodings[i] == encoding )
796 {
797 return wxGetTranslation(gs_encodingDescs[i]);
798 }
799 }
800
801 wxString str;
802 str.Printf(_("Unknown encoding (%d)"), encoding);
803
804 return str;
805 }
806
807 /* static */
808 wxString wxFontMapperBase::GetEncodingName(wxFontEncoding encoding)
809 {
810 if ( encoding == wxFONTENCODING_DEFAULT )
811 {
812 return _("default");
813 }
814
815 const size_t count = WXSIZEOF(gs_encodingNames);
816
817 for ( size_t i = 0; i < count; i++ )
818 {
819 if ( gs_encodings[i] == encoding )
820 {
821 return gs_encodingNames[i][0];
822 }
823 }
824
825 wxString str;
826 str.Printf(_("unknown-%d"), encoding);
827
828 return str;
829 }
830
831 /* static */
832 const wxChar** wxFontMapperBase::GetAllEncodingNames(wxFontEncoding encoding)
833 {
834 static const wxChar* dummy[] = { NULL };
835
836 for ( size_t i = 0; i < WXSIZEOF(gs_encodingNames); i++ )
837 {
838 if ( gs_encodings[i] == encoding )
839 {
840 return gs_encodingNames[i];
841 }
842 }
843
844 return dummy;
845 }
846
847 /* static */
848 wxFontEncoding wxFontMapperBase::GetEncodingFromName(const wxString& name)
849 {
850 const size_t count = WXSIZEOF(gs_encodingNames);
851
852 for ( size_t i = 0; i < count; i++ )
853 {
854 for ( const wxChar** encName = gs_encodingNames[i]; *encName; ++encName )
855 {
856 if ( name.CmpNoCase(*encName) == 0 )
857 return gs_encodings[i];
858 }
859 }
860
861 return wxFONTENCODING_MAX;
862 }
863
864 #endif // wxUSE_FONTMAP