1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: common/fmapbase.cpp
3 // Purpose: wxFontMapperBase class implementation
4 // Author: Vadim Zeitlin
6 // Created: 21.06.2003 (extracted from common/fontmap.cpp)
8 // Copyright: (c) 1999-2003 Vadim Zeitlin <vadim@wxwindows.org>
9 // License: wxWindows license
10 ///////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 // for compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
35 #if defined(__WXMSW__)
36 #include "wx/msw/private.h" // includes windows.h for LOGFONT
37 #include "wx/msw/winundef.h"
40 #include "wx/fontmap.h"
41 #include "wx/fmappriv.h"
43 #include "wx/apptrait.h"
44 #include "wx/module.h"
46 // wxMemoryConfig uses wxFileConfig
47 #if wxUSE_CONFIG && wxUSE_FILECONFIG
48 #include "wx/config.h"
49 #include "wx/memconf.h"
52 // ----------------------------------------------------------------------------
54 // ----------------------------------------------------------------------------
56 // encodings supported by GetEncodingDescription
57 static wxFontEncoding gs_encodings
[] =
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
,
79 wxFONTENCODING_CP1250
,
80 wxFONTENCODING_CP1251
,
81 wxFONTENCODING_CP1252
,
82 wxFONTENCODING_CP1253
,
83 wxFONTENCODING_CP1254
,
84 wxFONTENCODING_CP1255
,
85 wxFONTENCODING_CP1256
,
86 wxFONTENCODING_CP1257
,
90 wxFONTENCODING_EUC_JP
,
93 // the descriptions for them
94 static const wxChar
* gs_encodingDescs
[] =
96 wxTRANSLATE( "Western European (ISO-8859-1)" ),
97 wxTRANSLATE( "Central European (ISO-8859-2)" ),
98 wxTRANSLATE( "Esperanto (ISO-8859-3)" ),
99 wxTRANSLATE( "Baltic (old) (ISO-8859-4)" ),
100 wxTRANSLATE( "Cyrillic (ISO-8859-5)" ),
101 wxTRANSLATE( "Arabic (ISO-8859-6)" ),
102 wxTRANSLATE( "Greek (ISO-8859-7)" ),
103 wxTRANSLATE( "Hebrew (ISO-8859-8)" ),
104 wxTRANSLATE( "Turkish (ISO-8859-9)" ),
105 wxTRANSLATE( "Nordic (ISO-8859-10)" ),
106 wxTRANSLATE( "Thai (ISO-8859-11)" ),
107 wxTRANSLATE( "Indian (ISO-8859-12)" ),
108 wxTRANSLATE( "Baltic (ISO-8859-13)" ),
109 wxTRANSLATE( "Celtic (ISO-8859-14)" ),
110 wxTRANSLATE( "Western European with Euro (ISO-8859-15)" ),
111 wxTRANSLATE( "KOI8-R" ),
112 wxTRANSLATE( "Windows Japanese (CP 932)" ),
113 wxTRANSLATE( "Windows Chinese Simplified (CP 936)" ),
114 wxTRANSLATE( "Windows Korean (CP 949)" ),
115 wxTRANSLATE( "Windows Chinese Traditional (CP 950)" ),
116 wxTRANSLATE( "Windows Central European (CP 1250)" ),
117 wxTRANSLATE( "Windows Cyrillic (CP 1251)" ),
118 wxTRANSLATE( "Windows Western European (CP 1252)" ),
119 wxTRANSLATE( "Windows Greek (CP 1253)" ),
120 wxTRANSLATE( "Windows Turkish (CP 1254)" ),
121 wxTRANSLATE( "Windows Hebrew (CP 1255)" ),
122 wxTRANSLATE( "Windows Arabic (CP 1256)" ),
123 wxTRANSLATE( "Windows Baltic (CP 1257)" ),
124 wxTRANSLATE( "Windows/DOS OEM (CP 437)" ),
125 wxTRANSLATE( "Unicode 7 bit (UTF-7)" ),
126 wxTRANSLATE( "Unicode 8 bit (UTF-8)" ),
127 wxTRANSLATE( "Extended Unix Codepage for Japanese (EUC-JP)" ),
130 // and the internal names (these are not translated on purpose!)
131 static const wxChar
* gs_encodingNames
[] =
142 wxT( "iso-8859-10" ),
143 wxT( "iso-8859-11" ),
144 wxT( "iso-8859-12" ),
145 wxT( "iso-8859-13" ),
146 wxT( "iso-8859-14" ),
147 wxT( "iso-8859-15" ),
149 wxT( "windows-932" ),
150 wxT( "windows-936" ),
151 wxT( "windows-949" ),
152 wxT( "windows-950" ),
153 wxT( "windows-1250" ),
154 wxT( "windows-1251" ),
155 wxT( "windows-1252" ),
156 wxT( "windows-1253" ),
157 wxT( "windows-1254" ),
158 wxT( "windows-1255" ),
159 wxT( "windows-1256" ),
160 wxT( "windows-1257" ),
161 wxT( "windows-437" ),
167 wxCOMPILE_TIME_ASSERT( WXSIZEOF(gs_encodingDescs
) == WXSIZEOF(gs_encodings
) &&
168 WXSIZEOF(gs_encodingNames
) == WXSIZEOF(gs_encodings
),
169 EncodingsArraysNotInSync
);
171 // ----------------------------------------------------------------------------
173 // ----------------------------------------------------------------------------
175 // clean up the font mapper object
176 class wxFontMapperModule
: public wxModule
179 wxFontMapperModule() : wxModule() { }
180 virtual bool OnInit() { return TRUE
; }
181 virtual void OnExit() { delete wxFontMapper::Set(NULL
); }
183 DECLARE_DYNAMIC_CLASS(wxFontMapperModule
)
186 IMPLEMENT_DYNAMIC_CLASS(wxFontMapperModule
, wxModule
)
189 // ============================================================================
190 // wxFontMapperBase implementation
191 // ============================================================================
193 wxFontMapper
*wxFontMapperBase::sm_instance
= NULL
;
195 // ----------------------------------------------------------------------------
197 // ----------------------------------------------------------------------------
199 wxFontMapperBase::wxFontMapperBase()
201 #if wxUSE_CONFIG && wxUSE_FILECONFIG
203 m_configIsDummy
= FALSE
;
204 #endif // wxUSE_CONFIG
207 wxFontMapperBase::~wxFontMapperBase()
209 #if wxUSE_CONFIG && wxUSE_FILECONFIG
210 if ( m_configIsDummy
)
212 #endif // wxUSE_CONFIG
216 wxFontMapper
*wxFontMapperBase::Get()
220 wxAppTraits
*traits
= wxTheApp
? wxTheApp
->GetTraits() : NULL
;
223 sm_instance
= traits
->CreateFontMapper();
225 wxASSERT_MSG( sm_instance
,
226 _T("wxAppTraits::CreateFontMapper() failed") );
231 // last resort: we must create something because the existing code
232 // relies on always having a valid font mapper object
233 sm_instance
= (wxFontMapper
*)new wxFontMapperBase
;
241 wxFontMapper
*wxFontMapperBase::Set(wxFontMapper
*mapper
)
243 wxFontMapper
*old
= sm_instance
;
244 sm_instance
= mapper
;
248 #if wxUSE_CONFIG && wxUSE_FILECONFIG
250 // ----------------------------------------------------------------------------
251 // config usage customisation
252 // ----------------------------------------------------------------------------
255 const wxChar
*wxFontMapperBase::GetDefaultConfigPath()
257 return FONTMAPPER_ROOT_PATH
;
260 void wxFontMapperBase::SetConfigPath(const wxString
& prefix
)
262 wxCHECK_RET( !prefix
.IsEmpty() && prefix
[0] == wxCONFIG_PATH_SEPARATOR
,
263 wxT("an absolute path should be given to wxFontMapper::SetConfigPath()") );
265 m_configRootPath
= prefix
;
268 // ----------------------------------------------------------------------------
269 // get config object and path for it
270 // ----------------------------------------------------------------------------
272 wxConfigBase
*wxFontMapperBase::GetConfig()
277 m_config
= wxConfig::Get(FALSE
/*don't create on demand*/ );
281 // we still want to have a config object because otherwise we would
282 // keep asking the user the same questions in the interactive mode,
283 // so create a dummy config which won't write to any files/registry
284 // but will allow us to remember the results of the questions at
285 // least during this run
286 m_config
= new wxMemoryConfig
;
287 m_configIsDummy
= TRUE
;
288 // VS: we can't call wxConfig::Set(m_config) here because that would
289 // disable automatic wxConfig instance creation if this code was
290 // called before wxApp::OnInit (this happens in wxGTK -- it sets
291 // default wxFont encoding in wxApp::Initialize())
295 if ( m_configIsDummy
&& wxConfig::Get(FALSE
) != NULL
)
297 // VS: in case we created dummy m_config (see above), we want to switch back
298 // to the real one as soon as one becomes available.
300 m_config
= wxConfig::Get(FALSE
);
301 m_configIsDummy
= FALSE
;
302 // FIXME: ideally, we should add keys from dummy config to the real one now,
303 // but it is a low-priority task because typical wxWin application
304 // either doesn't use wxConfig at all or creates wxConfig object in
305 // wxApp::OnInit(), before any real interaction with the user takes
312 const wxString
& wxFontMapperBase::GetConfigPath()
314 if ( !m_configRootPath
)
317 m_configRootPath
= GetDefaultConfigPath();
320 return m_configRootPath
;
323 // ----------------------------------------------------------------------------
325 // ----------------------------------------------------------------------------
327 bool wxFontMapperBase::ChangePath(const wxString
& pathNew
, wxString
*pathOld
)
329 wxConfigBase
*config
= GetConfig();
333 *pathOld
= config
->GetPath();
335 wxString path
= GetConfigPath();
336 if ( path
.IsEmpty() || path
.Last() != wxCONFIG_PATH_SEPARATOR
)
338 path
+= wxCONFIG_PATH_SEPARATOR
;
341 wxASSERT_MSG( !pathNew
|| (pathNew
[0] != wxCONFIG_PATH_SEPARATOR
),
342 wxT("should be a relative path") );
346 config
->SetPath(path
);
351 void wxFontMapperBase::RestorePath(const wxString
& pathOld
)
353 GetConfig()->SetPath(pathOld
);
356 // ----------------------------------------------------------------------------
357 // charset/encoding correspondence
358 // ----------------------------------------------------------------------------
361 wxFontMapperBase::CharsetToEncoding(const wxString
& charset
,
362 bool WXUNUSED(interactive
))
364 wxFontEncoding encoding
= wxFONTENCODING_SYSTEM
;
366 // we're going to modify it, make a copy
367 wxString cs
= charset
;
369 #if wxUSE_CONFIG && wxUSE_FILECONFIG
370 // first try the user-defined settings
371 wxFontMapperPathChanger
path(this, FONTMAPPER_CHARSET_PATH
);
374 wxConfigBase
*config
= GetConfig();
376 // do we have an encoding for this charset?
377 long value
= config
->Read(charset
, -1l);
380 if ( value
== wxFONTENCODING_UNKNOWN
)
382 // don't try to find it, in particular don't ask the user
383 return wxFONTENCODING_SYSTEM
;
386 if ( value
>= 0 && value
<= wxFONTENCODING_MAX
)
388 encoding
= (wxFontEncoding
)value
;
392 wxLogDebug(wxT("corrupted config data: invalid encoding %ld for charset '%s' ignored"),
393 value
, charset
.c_str());
397 if ( encoding
== wxFONTENCODING_SYSTEM
)
399 // may be we have an alias?
400 config
->SetPath(FONTMAPPER_CHARSET_ALIAS_PATH
);
402 wxString alias
= config
->Read(charset
);
405 // yes, we do - use it instead
410 #endif // wxUSE_CONFIG
412 // if didn't find it there, try to recognize it ourselves
413 if ( encoding
== wxFONTENCODING_SYSTEM
)
419 // discard the optional quotes
422 if ( cs
[0u] == _T('"') && cs
.Last() == _T('"') )
424 cs
= wxString(cs
.c_str(), cs
.length() - 1);
430 if ( cs
.empty() || cs
== _T("US-ASCII") )
432 encoding
= wxFONTENCODING_DEFAULT
;
434 else if ( cs
== wxT("UTF-7") )
436 encoding
= wxFONTENCODING_UTF7
;
438 else if ( cs
== wxT("UTF-8") )
440 encoding
= wxFONTENCODING_UTF8
;
442 else if ( cs
== wxT("GB2312") )
444 encoding
= wxFONTENCODING_GB2312
;
446 else if ( cs
== wxT("BIG5") )
448 encoding
= wxFONTENCODING_BIG5
;
450 else if ( cs
== wxT("SJIS") ||
451 cs
== wxT("SHIFT_JIS") ||
452 cs
== wxT("SHIFT-JIS") )
454 encoding
= wxFONTENCODING_SHIFT_JIS
;
456 else if ( cs
== wxT("EUC-JP") ||
457 cs
== wxT("EUC_JP") )
459 encoding
= wxFONTENCODING_EUC_JP
;
461 else if ( cs
== wxT("KOI8-R") ||
462 cs
== wxT("KOI8-U") ||
463 cs
== wxT("KOI8-RU") )
465 // although koi8-ru is not strictly speaking the same as koi8-r,
466 // they are similar enough to make mapping it to koi8 better than
467 // not reckognizing it at all
468 encoding
= wxFONTENCODING_KOI8
;
470 else if ( cs
.Left(3) == wxT("ISO") )
472 // the dash is optional (or, to be exact, it is not, but
473 // several brokenmails "forget" it)
474 const wxChar
*p
= cs
.c_str() + 3;
475 if ( *p
== wxT('-') )
478 // printf( "iso %s\n", (const char*) cs.ToAscii() );
481 if ( wxSscanf(p
, wxT("8859-%u"), &value
) == 1 )
483 // printf( "value %d\n", (int)value );
485 // make it 0 based and check that it is strictly positive in
486 // the process (no such thing as iso8859-0 encoding)
487 if ( (value
-- > 0) &&
488 (value
< wxFONTENCODING_ISO8859_MAX
-
489 wxFONTENCODING_ISO8859_1
) )
491 // it's a valid ISO8859 encoding
492 value
+= wxFONTENCODING_ISO8859_1
;
493 encoding
= (wxFontEncoding
)value
;
497 else if ( cs
.Left(4) == wxT("8859") )
499 const wxChar
*p
= cs
.c_str();
502 if ( wxSscanf(p
, wxT("8859-%u"), &value
) == 1 )
504 // printf( "value %d\n", (int)value );
506 // make it 0 based and check that it is strictly positive in
507 // the process (no such thing as iso8859-0 encoding)
508 if ( (value
-- > 0) &&
509 (value
< wxFONTENCODING_ISO8859_MAX
-
510 wxFONTENCODING_ISO8859_1
) )
512 // it's a valid ISO8859 encoding
513 value
+= wxFONTENCODING_ISO8859_1
;
514 encoding
= (wxFontEncoding
)value
;
518 else // check for Windows charsets
521 if ( cs
.Left(7) == wxT("WINDOWS") )
525 else if ( cs
.Left(2) == wxT("CP") )
529 else // not a Windows encoding
536 const wxChar
*p
= cs
.c_str() + len
;
537 if ( *p
== wxT('-') )
541 if ( wxSscanf(p
, wxT("%u"), &value
) == 1 )
546 if ( value
< wxFONTENCODING_CP12_MAX
-
547 wxFONTENCODING_CP1250
)
549 // a valid Windows code page
550 value
+= wxFONTENCODING_CP1250
;
551 encoding
= (wxFontEncoding
)value
;
558 encoding
= wxFONTENCODING_CP932
;
562 encoding
= wxFONTENCODING_CP936
;
566 encoding
= wxFONTENCODING_CP949
;
570 encoding
= wxFONTENCODING_CP950
;
583 size_t wxFontMapperBase::GetSupportedEncodingsCount()
585 return WXSIZEOF(gs_encodings
);
589 wxFontEncoding
wxFontMapperBase::GetEncoding(size_t n
)
591 wxCHECK_MSG( n
< WXSIZEOF(gs_encodings
), wxFONTENCODING_SYSTEM
,
592 _T("wxFontMapper::GetEncoding(): invalid index") );
594 return gs_encodings
[n
];
598 wxString
wxFontMapperBase::GetEncodingDescription(wxFontEncoding encoding
)
600 if ( encoding
== wxFONTENCODING_DEFAULT
)
602 return _("Default encoding");
605 const size_t count
= WXSIZEOF(gs_encodingDescs
);
607 for ( size_t i
= 0; i
< count
; i
++ )
609 if ( gs_encodings
[i
] == encoding
)
611 return wxGetTranslation(gs_encodingDescs
[i
]);
616 str
.Printf(_("Unknown encoding (%d)"), encoding
);
622 wxString
wxFontMapperBase::GetEncodingName(wxFontEncoding encoding
)
624 if ( encoding
== wxFONTENCODING_DEFAULT
)
629 const size_t count
= WXSIZEOF(gs_encodingNames
);
631 for ( size_t i
= 0; i
< count
; i
++ )
633 if ( gs_encodings
[i
] == encoding
)
635 return gs_encodingNames
[i
];
640 str
.Printf(_("unknown-%d"), encoding
);
645 #endif // wxUSE_CONFIG
647 #endif // wxUSE_FONTMAP