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