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 #include "wx/fontmap.h"
36 #include "wx/fmappriv.h"
38 #include "wx/apptrait.h"
39 #include "wx/module.h"
42 #include "wx/config.h"
43 #include "wx/memconf.h"
46 // ----------------------------------------------------------------------------
48 // ----------------------------------------------------------------------------
50 // encodings supported by GetEncodingDescription
51 static wxFontEncoding gs_encodings
[] =
53 wxFONTENCODING_ISO8859_1
,
54 wxFONTENCODING_ISO8859_2
,
55 wxFONTENCODING_ISO8859_3
,
56 wxFONTENCODING_ISO8859_4
,
57 wxFONTENCODING_ISO8859_5
,
58 wxFONTENCODING_ISO8859_6
,
59 wxFONTENCODING_ISO8859_7
,
60 wxFONTENCODING_ISO8859_8
,
61 wxFONTENCODING_ISO8859_9
,
62 wxFONTENCODING_ISO8859_10
,
63 wxFONTENCODING_ISO8859_11
,
64 wxFONTENCODING_ISO8859_12
,
65 wxFONTENCODING_ISO8859_13
,
66 wxFONTENCODING_ISO8859_14
,
67 wxFONTENCODING_ISO8859_15
,
73 wxFONTENCODING_CP1250
,
74 wxFONTENCODING_CP1251
,
75 wxFONTENCODING_CP1252
,
76 wxFONTENCODING_CP1253
,
77 wxFONTENCODING_CP1254
,
78 wxFONTENCODING_CP1255
,
79 wxFONTENCODING_CP1256
,
80 wxFONTENCODING_CP1257
,
84 wxFONTENCODING_EUC_JP
,
87 // the descriptions for them
88 static const wxChar
* gs_encodingDescs
[] =
90 wxTRANSLATE( "Western European (ISO-8859-1)" ),
91 wxTRANSLATE( "Central European (ISO-8859-2)" ),
92 wxTRANSLATE( "Esperanto (ISO-8859-3)" ),
93 wxTRANSLATE( "Baltic (old) (ISO-8859-4)" ),
94 wxTRANSLATE( "Cyrillic (ISO-8859-5)" ),
95 wxTRANSLATE( "Arabic (ISO-8859-6)" ),
96 wxTRANSLATE( "Greek (ISO-8859-7)" ),
97 wxTRANSLATE( "Hebrew (ISO-8859-8)" ),
98 wxTRANSLATE( "Turkish (ISO-8859-9)" ),
99 wxTRANSLATE( "Nordic (ISO-8859-10)" ),
100 wxTRANSLATE( "Thai (ISO-8859-11)" ),
101 wxTRANSLATE( "Indian (ISO-8859-12)" ),
102 wxTRANSLATE( "Baltic (ISO-8859-13)" ),
103 wxTRANSLATE( "Celtic (ISO-8859-14)" ),
104 wxTRANSLATE( "Western European with Euro (ISO-8859-15)" ),
105 wxTRANSLATE( "KOI8-R" ),
106 wxTRANSLATE( "Windows Japanese (CP 932)" ),
107 wxTRANSLATE( "Windows Chinese Simplified (CP 936)" ),
108 wxTRANSLATE( "Windows Korean (CP 949)" ),
109 wxTRANSLATE( "Windows Chinese Traditional (CP 950)" ),
110 wxTRANSLATE( "Windows Central European (CP 1250)" ),
111 wxTRANSLATE( "Windows Cyrillic (CP 1251)" ),
112 wxTRANSLATE( "Windows Western European (CP 1252)" ),
113 wxTRANSLATE( "Windows Greek (CP 1253)" ),
114 wxTRANSLATE( "Windows Turkish (CP 1254)" ),
115 wxTRANSLATE( "Windows Hebrew (CP 1255)" ),
116 wxTRANSLATE( "Windows Arabic (CP 1256)" ),
117 wxTRANSLATE( "Windows Baltic (CP 1257)" ),
118 wxTRANSLATE( "Windows/DOS OEM (CP 437)" ),
119 wxTRANSLATE( "Unicode 7 bit (UTF-7)" ),
120 wxTRANSLATE( "Unicode 8 bit (UTF-8)" ),
121 wxTRANSLATE( "Extended Unix Codepage for Japanese (EUC-JP)" ),
124 // and the internal names (these are not translated on purpose!)
125 static const wxChar
* gs_encodingNames
[] =
136 wxT( "iso-8859-10" ),
137 wxT( "iso-8859-11" ),
138 wxT( "iso-8859-12" ),
139 wxT( "iso-8859-13" ),
140 wxT( "iso-8859-14" ),
141 wxT( "iso-8859-15" ),
143 wxT( "windows-932" ),
144 wxT( "windows-936" ),
145 wxT( "windows-949" ),
146 wxT( "windows-950" ),
147 wxT( "windows-1250" ),
148 wxT( "windows-1251" ),
149 wxT( "windows-1252" ),
150 wxT( "windows-1253" ),
151 wxT( "windows-1254" ),
152 wxT( "windows-1255" ),
153 wxT( "windows-1256" ),
154 wxT( "windows-1257" ),
155 wxT( "windows-437" ),
161 wxCOMPILE_TIME_ASSERT( WXSIZEOF(gs_encodingDescs
) == WXSIZEOF(gs_encodings
) &&
162 WXSIZEOF(gs_encodingNames
) == WXSIZEOF(gs_encodings
),
163 EncodingsArraysNotInSync
);
165 // ----------------------------------------------------------------------------
167 // ----------------------------------------------------------------------------
169 // clean up the font mapper object
170 class wxFontMapperModule
: public wxModule
173 wxFontMapperModule() : wxModule() { }
174 virtual bool OnInit() { return TRUE
; }
175 virtual void OnExit() { delete wxFontMapper::Set(NULL
); }
177 DECLARE_DYNAMIC_CLASS(wxFontMapperModule
)
180 IMPLEMENT_DYNAMIC_CLASS(wxFontMapperModule
, wxModule
)
183 // ============================================================================
184 // wxFontMapperBase implementation
185 // ============================================================================
187 wxFontMapper
*wxFontMapperBase::sm_instance
= NULL
;
189 // ----------------------------------------------------------------------------
191 // ----------------------------------------------------------------------------
193 wxFontMapperBase::wxFontMapperBase()
197 m_configIsDummy
= FALSE
;
198 #endif // wxUSE_CONFIG
201 wxFontMapperBase::~wxFontMapperBase()
204 if ( m_configIsDummy
)
206 #endif // wxUSE_CONFIG
210 wxFontMapper
*wxFontMapperBase::Get()
214 wxAppTraits
*traits
= wxTheApp
? wxTheApp
->GetTraits() : NULL
;
217 sm_instance
= traits
->CreateFontMapper();
219 wxASSERT_MSG( sm_instance
,
220 _T("wxAppTraits::CreateFontMapper() failed") );
225 // last resort: we must create something because the existing code
226 // relies on always having a valid font mapper object
227 sm_instance
= (wxFontMapper
*)new wxFontMapperBase
;
235 wxFontMapper
*wxFontMapperBase::Set(wxFontMapper
*mapper
)
237 wxFontMapper
*old
= sm_instance
;
238 sm_instance
= mapper
;
244 // ----------------------------------------------------------------------------
245 // config usage customisation
246 // ----------------------------------------------------------------------------
249 const wxChar
*wxFontMapperBase::GetDefaultConfigPath()
251 return FONTMAPPER_ROOT_PATH
;
254 void wxFontMapperBase::SetConfigPath(const wxString
& prefix
)
256 wxCHECK_RET( !prefix
.IsEmpty() && prefix
[0] == wxCONFIG_PATH_SEPARATOR
,
257 wxT("an absolute path should be given to wxFontMapper::SetConfigPath()") );
259 m_configRootPath
= prefix
;
262 // ----------------------------------------------------------------------------
263 // get config object and path for it
264 // ----------------------------------------------------------------------------
266 wxConfigBase
*wxFontMapperBase::GetConfig()
271 m_config
= wxConfig::Get(FALSE
/*don't create on demand*/ );
275 // we still want to have a config object because otherwise we would
276 // keep asking the user the same questions in the interactive mode,
277 // so create a dummy config which won't write to any files/registry
278 // but will allow us to remember the results of the questions at
279 // least during this run
280 m_config
= new wxMemoryConfig
;
281 m_configIsDummy
= TRUE
;
282 // VS: we can't call wxConfig::Set(m_config) here because that would
283 // disable automatic wxConfig instance creation if this code was
284 // called before wxApp::OnInit (this happens in wxGTK -- it sets
285 // default wxFont encoding in wxApp::Initialize())
289 if ( m_configIsDummy
&& wxConfig::Get(FALSE
) != NULL
)
291 // VS: in case we created dummy m_config (see above), we want to switch back
292 // to the real one as soon as one becomes available.
294 m_config
= wxConfig::Get(FALSE
);
295 m_configIsDummy
= FALSE
;
296 // FIXME: ideally, we should add keys from dummy config to the real one now,
297 // but it is a low-priority task because typical wxWin application
298 // either doesn't use wxConfig at all or creates wxConfig object in
299 // wxApp::OnInit(), before any real interaction with the user takes
306 const wxString
& wxFontMapperBase::GetConfigPath()
308 if ( !m_configRootPath
)
311 m_configRootPath
= GetDefaultConfigPath();
314 return m_configRootPath
;
317 // ----------------------------------------------------------------------------
319 // ----------------------------------------------------------------------------
321 bool wxFontMapperBase::ChangePath(const wxString
& pathNew
, wxString
*pathOld
)
323 wxConfigBase
*config
= GetConfig();
327 *pathOld
= config
->GetPath();
329 wxString path
= GetConfigPath();
330 if ( path
.IsEmpty() || path
.Last() != wxCONFIG_PATH_SEPARATOR
)
332 path
+= wxCONFIG_PATH_SEPARATOR
;
335 wxASSERT_MSG( !pathNew
|| (pathNew
[0] != wxCONFIG_PATH_SEPARATOR
),
336 wxT("should be a relative path") );
340 config
->SetPath(path
);
345 void wxFontMapperBase::RestorePath(const wxString
& pathOld
)
347 GetConfig()->SetPath(pathOld
);
350 // ----------------------------------------------------------------------------
351 // charset/encoding correspondence
352 // ----------------------------------------------------------------------------
355 wxFontMapperBase::CharsetToEncoding(const wxString
& charset
,
356 bool WXUNUSED(interactive
))
358 wxFontEncoding encoding
= wxFONTENCODING_SYSTEM
;
360 // we're going to modify it, make a copy
361 wxString cs
= charset
;
364 // first try the user-defined settings
365 wxFontMapperPathChanger
path(this, FONTMAPPER_CHARSET_PATH
);
368 wxConfigBase
*config
= GetConfig();
370 // do we have an encoding for this charset?
371 long value
= config
->Read(charset
, -1l);
374 if ( value
== wxFONTENCODING_UNKNOWN
)
376 // don't try to find it, in particular don't ask the user
377 return wxFONTENCODING_SYSTEM
;
380 if ( value
>= 0 && value
<= wxFONTENCODING_MAX
)
382 encoding
= (wxFontEncoding
)value
;
386 wxLogDebug(wxT("corrupted config data: invalid encoding %ld for charset '%s' ignored"),
387 value
, charset
.c_str());
391 if ( encoding
== wxFONTENCODING_SYSTEM
)
393 // may be we have an alias?
394 config
->SetPath(FONTMAPPER_CHARSET_ALIAS_PATH
);
396 wxString alias
= config
->Read(charset
);
399 // yes, we do - use it instead
404 #endif // wxUSE_CONFIG
406 // if didn't find it there, try to recognize it ourselves
407 if ( encoding
== wxFONTENCODING_SYSTEM
)
413 // discard the optional quotes
416 if ( cs
[0u] == _T('"') && cs
.Last() == _T('"') )
418 cs
= wxString(cs
.c_str(), cs
.length() - 1);
424 if ( cs
.empty() || cs
== _T("US-ASCII") )
426 encoding
= wxFONTENCODING_DEFAULT
;
428 else if ( cs
== wxT("UTF-7") )
430 encoding
= wxFONTENCODING_UTF7
;
432 else if ( cs
== wxT("UTF-8") )
434 encoding
= wxFONTENCODING_UTF8
;
436 else if ( cs
== wxT("GB2312") )
438 encoding
= wxFONTENCODING_GB2312
;
440 else if ( cs
== wxT("BIG5") )
442 encoding
= wxFONTENCODING_BIG5
;
444 else if ( cs
== wxT("SJIS") ||
445 cs
== wxT("SHIFT_JIS") ||
446 cs
== wxT("SHIFT-JIS") )
448 encoding
= wxFONTENCODING_SHIFT_JIS
;
450 else if ( cs
== wxT("EUC-JP") ||
451 cs
== wxT("EUC_JP") )
453 encoding
= wxFONTENCODING_EUC_JP
;
455 else if ( cs
== wxT("KOI8-R") ||
456 cs
== wxT("KOI8-U") ||
457 cs
== wxT("KOI8-RU") )
459 // although koi8-ru is not strictly speaking the same as koi8-r,
460 // they are similar enough to make mapping it to koi8 better than
461 // not reckognizing it at all
462 encoding
= wxFONTENCODING_KOI8
;
464 else if ( cs
.Left(3) == wxT("ISO") )
466 // the dash is optional (or, to be exact, it is not, but
467 // several brokenmails "forget" it)
468 const wxChar
*p
= cs
.c_str() + 3;
469 if ( *p
== wxT('-') )
472 // printf( "iso %s\n", (const char*) cs.ToAscii() );
475 if ( wxSscanf(p
, wxT("8859-%u"), &value
) == 1 )
477 // printf( "value %d\n", (int)value );
479 // make it 0 based and check that it is strictly positive in
480 // the process (no such thing as iso8859-0 encoding)
481 if ( (value
-- > 0) &&
482 (value
< wxFONTENCODING_ISO8859_MAX
-
483 wxFONTENCODING_ISO8859_1
) )
485 // it's a valid ISO8859 encoding
486 value
+= wxFONTENCODING_ISO8859_1
;
487 encoding
= (wxFontEncoding
)value
;
491 else if ( cs
.Left(4) == wxT("8859") )
493 const wxChar
*p
= cs
.c_str();
496 if ( wxSscanf(p
, wxT("8859-%u"), &value
) == 1 )
498 // printf( "value %d\n", (int)value );
500 // make it 0 based and check that it is strictly positive in
501 // the process (no such thing as iso8859-0 encoding)
502 if ( (value
-- > 0) &&
503 (value
< wxFONTENCODING_ISO8859_MAX
-
504 wxFONTENCODING_ISO8859_1
) )
506 // it's a valid ISO8859 encoding
507 value
+= wxFONTENCODING_ISO8859_1
;
508 encoding
= (wxFontEncoding
)value
;
512 else // check for Windows charsets
515 if ( cs
.Left(7) == wxT("WINDOWS") )
519 else if ( cs
.Left(2) == wxT("CP") )
523 else // not a Windows encoding
530 const wxChar
*p
= cs
.c_str() + len
;
531 if ( *p
== wxT('-') )
535 if ( wxSscanf(p
, wxT("%u"), &value
) == 1 )
540 if ( value
< wxFONTENCODING_CP12_MAX
-
541 wxFONTENCODING_CP1250
)
543 // a valid Windows code page
544 value
+= wxFONTENCODING_CP1250
;
545 encoding
= (wxFontEncoding
)value
;
552 encoding
= wxFONTENCODING_CP932
;
556 encoding
= wxFONTENCODING_CP936
;
560 encoding
= wxFONTENCODING_CP949
;
564 encoding
= wxFONTENCODING_CP950
;
577 size_t wxFontMapperBase::GetSupportedEncodingsCount()
579 return WXSIZEOF(gs_encodings
);
583 wxFontEncoding
wxFontMapperBase::GetEncoding(size_t n
)
585 wxCHECK_MSG( n
< WXSIZEOF(gs_encodings
), wxFONTENCODING_SYSTEM
,
586 _T("wxFontMapper::GetEncoding(): invalid index") );
588 return gs_encodings
[n
];
592 wxString
wxFontMapperBase::GetEncodingDescription(wxFontEncoding encoding
)
594 if ( encoding
== wxFONTENCODING_DEFAULT
)
596 return _("Default encoding");
599 const size_t count
= WXSIZEOF(gs_encodingDescs
);
601 for ( size_t i
= 0; i
< count
; i
++ )
603 if ( gs_encodings
[i
] == encoding
)
605 return wxGetTranslation(gs_encodingDescs
[i
]);
610 str
.Printf(_("Unknown encoding (%d)"), encoding
);
616 wxString
wxFontMapperBase::GetEncodingName(wxFontEncoding encoding
)
618 if ( encoding
== wxFONTENCODING_DEFAULT
)
623 const size_t count
= WXSIZEOF(gs_encodingNames
);
625 for ( size_t i
= 0; i
< count
; i
++ )
627 if ( gs_encodings
[i
] == encoding
)
629 return gs_encodingNames
[i
];
634 str
.Printf(_("unknown-%d"), encoding
);
639 #endif // wxUSE_CONFIG
641 #endif // wxUSE_FONTMAP