]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/fmapbase.cpp
fixing overrelease and out-of-bounds write, fixes #13725
[wxWidgets.git] / src / common / fmapbase.cpp
index fa6dcd0d65eb693774c2c590cea1f6861060ee82..5693f8c0adf939975b4368a8e5fb5c862fd8abc1 100644 (file)
@@ -1,12 +1,12 @@
 ///////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////
-// Name:        common/fmapbase.cpp
+// Name:        src/common/fmapbase.cpp
 // Purpose:     wxFontMapperBase class implementation
 // Author:      Vadim Zeitlin
 // Modified by:
 // Created:     21.06.2003 (extracted from common/fontmap.cpp)
 // RCS-ID:      $Id$
 // Copyright:   (c) 1999-2003 Vadim Zeitlin <vadim@wxwindows.org>
 // Purpose:     wxFontMapperBase class implementation
 // Author:      Vadim Zeitlin
 // Modified by:
 // Created:     21.06.2003 (extracted from common/fontmap.cpp)
 // RCS-ID:      $Id$
 // Copyright:   (c) 1999-2003 Vadim Zeitlin <vadim@wxwindows.org>
-// License:     wxWindows license
+// Licence:     wxWindows licence
 ///////////////////////////////////////////////////////////////////////////////
 
 // ============================================================================
 ///////////////////////////////////////////////////////////////////////////////
 
 // ============================================================================
     #include "wx/app.h"
     #include "wx/log.h"
     #include "wx/intl.h"
     #include "wx/app.h"
     #include "wx/log.h"
     #include "wx/intl.h"
+    #include "wx/module.h"
+    #include "wx/wxcrtvararg.h"
 #endif //WX_PRECOMP
 
 #endif //WX_PRECOMP
 
-#if defined(__WXMSW__)
-  #include  "wx/msw/private.h"  // includes windows.h for LOGFONT
-  #include  "wx/msw/winundef.h"
+#if defined(__WINDOWS__)
+    #include  "wx/msw/private.h"  // includes windows.h for LOGFONT
+    #include  "wx/msw/winundef.h"
 #endif
 
 #include "wx/fontmap.h"
 #include "wx/fmappriv.h"
 
 #include "wx/apptrait.h"
 #endif
 
 #include "wx/fontmap.h"
 #include "wx/fmappriv.h"
 
 #include "wx/apptrait.h"
-#include "wx/module.h"
 
 
-#if wxUSE_CONFIG
+// wxMemoryConfig uses wxFileConfig
+#if wxUSE_CONFIG && wxUSE_FILECONFIG
     #include "wx/config.h"
     #include "wx/memconf.h"
 #endif
     #include "wx/config.h"
     #include "wx/memconf.h"
 #endif
@@ -53,7 +55,7 @@
 // ----------------------------------------------------------------------------
 
 // encodings supported by GetEncodingDescription
 // ----------------------------------------------------------------------------
 
 // encodings supported by GetEncodingDescription
-static wxFontEncoding gs_encodings[] =
+static const wxFontEncoding gs_encodings[] =
 {
     wxFONTENCODING_ISO8859_1,
     wxFONTENCODING_ISO8859_2,
 {
     wxFONTENCODING_ISO8859_1,
     wxFONTENCODING_ISO8859_2,
@@ -71,6 +73,9 @@ static wxFontEncoding gs_encodings[] =
     wxFONTENCODING_ISO8859_14,
     wxFONTENCODING_ISO8859_15,
     wxFONTENCODING_KOI8,
     wxFONTENCODING_ISO8859_14,
     wxFONTENCODING_ISO8859_15,
     wxFONTENCODING_KOI8,
+    wxFONTENCODING_KOI8_U,
+    wxFONTENCODING_CP866,
+    wxFONTENCODING_CP874,
     wxFONTENCODING_CP932,
     wxFONTENCODING_CP936,
     wxFONTENCODING_CP949,
     wxFONTENCODING_CP932,
     wxFONTENCODING_CP936,
     wxFONTENCODING_CP949,
@@ -83,14 +88,63 @@ static wxFontEncoding gs_encodings[] =
     wxFONTENCODING_CP1255,
     wxFONTENCODING_CP1256,
     wxFONTENCODING_CP1257,
     wxFONTENCODING_CP1255,
     wxFONTENCODING_CP1256,
     wxFONTENCODING_CP1257,
+    wxFONTENCODING_CP1258,
+    wxFONTENCODING_CP1361,
     wxFONTENCODING_CP437,
     wxFONTENCODING_UTF7,
     wxFONTENCODING_UTF8,
     wxFONTENCODING_CP437,
     wxFONTENCODING_UTF7,
     wxFONTENCODING_UTF8,
+    wxFONTENCODING_UTF16BE,
+    wxFONTENCODING_UTF16LE,
+    wxFONTENCODING_UTF32BE,
+    wxFONTENCODING_UTF32LE,
     wxFONTENCODING_EUC_JP,
     wxFONTENCODING_EUC_JP,
+    wxFONTENCODING_DEFAULT,
+    wxFONTENCODING_ISO2022_JP,
+
+    wxFONTENCODING_MACROMAN,
+    wxFONTENCODING_MACJAPANESE,
+    wxFONTENCODING_MACCHINESETRAD,
+    wxFONTENCODING_MACKOREAN,
+    wxFONTENCODING_MACARABIC,
+    wxFONTENCODING_MACHEBREW,
+    wxFONTENCODING_MACGREEK,
+    wxFONTENCODING_MACCYRILLIC,
+    wxFONTENCODING_MACDEVANAGARI,
+    wxFONTENCODING_MACGURMUKHI,
+    wxFONTENCODING_MACGUJARATI,
+    wxFONTENCODING_MACORIYA,
+    wxFONTENCODING_MACBENGALI,
+    wxFONTENCODING_MACTAMIL,
+    wxFONTENCODING_MACTELUGU,
+    wxFONTENCODING_MACKANNADA,
+    wxFONTENCODING_MACMALAJALAM,
+    wxFONTENCODING_MACSINHALESE,
+    wxFONTENCODING_MACBURMESE,
+    wxFONTENCODING_MACKHMER,
+    wxFONTENCODING_MACTHAI,
+    wxFONTENCODING_MACLAOTIAN,
+    wxFONTENCODING_MACGEORGIAN,
+    wxFONTENCODING_MACARMENIAN,
+    wxFONTENCODING_MACCHINESESIMP,
+    wxFONTENCODING_MACTIBETAN,
+    wxFONTENCODING_MACMONGOLIAN,
+    wxFONTENCODING_MACETHIOPIC,
+    wxFONTENCODING_MACCENTRALEUR,
+    wxFONTENCODING_MACVIATNAMESE,
+    wxFONTENCODING_MACARABICEXT,
+    wxFONTENCODING_MACSYMBOL,
+    wxFONTENCODING_MACDINGBATS,
+    wxFONTENCODING_MACTURKISH,
+    wxFONTENCODING_MACCROATIAN,
+    wxFONTENCODING_MACICELANDIC,
+    wxFONTENCODING_MACROMANIAN,
+    wxFONTENCODING_MACCELTIC,
+    wxFONTENCODING_MACGAELIC,
+    wxFONTENCODING_MACKEYBOARD
 };
 
 // the descriptions for them
 };
 
 // the descriptions for them
-static const wxChar* gs_encodingDescs[] =
+static const char* const gs_encodingDescs[] =
 {
     wxTRANSLATE( "Western European (ISO-8859-1)" ),
     wxTRANSLATE( "Central European (ISO-8859-2)" ),
 {
     wxTRANSLATE( "Western European (ISO-8859-1)" ),
     wxTRANSLATE( "Central European (ISO-8859-2)" ),
@@ -108,10 +162,13 @@ static const wxChar* gs_encodingDescs[] =
     wxTRANSLATE( "Celtic (ISO-8859-14)" ),
     wxTRANSLATE( "Western European with Euro (ISO-8859-15)" ),
     wxTRANSLATE( "KOI8-R" ),
     wxTRANSLATE( "Celtic (ISO-8859-14)" ),
     wxTRANSLATE( "Western European with Euro (ISO-8859-15)" ),
     wxTRANSLATE( "KOI8-R" ),
-    wxTRANSLATE( "Windows Japanese (CP 932)" ),
-    wxTRANSLATE( "Windows Chinese Simplified (CP 936)" ),
+    wxTRANSLATE( "KOI8-U" ),
+    wxTRANSLATE( "Windows/DOS OEM Cyrillic (CP 866)" ),
+    wxTRANSLATE( "Windows Thai (CP 874)" ),
+    wxTRANSLATE( "Windows Japanese (CP 932) or Shift-JIS" ),
+    wxTRANSLATE( "Windows Chinese Simplified (CP 936) or GB-2312" ),
     wxTRANSLATE( "Windows Korean (CP 949)" ),
     wxTRANSLATE( "Windows Korean (CP 949)" ),
-    wxTRANSLATE( "Windows Chinese Traditional (CP 950)" ),
+    wxTRANSLATE( "Windows Chinese Traditional (CP 950) or Big-5" ),
     wxTRANSLATE( "Windows Central European (CP 1250)" ),
     wxTRANSLATE( "Windows Cyrillic (CP 1251)" ),
     wxTRANSLATE( "Windows Western European (CP 1252)" ),
     wxTRANSLATE( "Windows Central European (CP 1250)" ),
     wxTRANSLATE( "Windows Cyrillic (CP 1251)" ),
     wxTRANSLATE( "Windows Western European (CP 1252)" ),
@@ -120,52 +177,181 @@ static const wxChar* gs_encodingDescs[] =
     wxTRANSLATE( "Windows Hebrew (CP 1255)" ),
     wxTRANSLATE( "Windows Arabic (CP 1256)" ),
     wxTRANSLATE( "Windows Baltic (CP 1257)" ),
     wxTRANSLATE( "Windows Hebrew (CP 1255)" ),
     wxTRANSLATE( "Windows Arabic (CP 1256)" ),
     wxTRANSLATE( "Windows Baltic (CP 1257)" ),
+    wxTRANSLATE( "Windows Vietnamese (CP 1258)" ),
+    wxTRANSLATE( "Windows Johab (CP 1361)" ),
     wxTRANSLATE( "Windows/DOS OEM (CP 437)" ),
     wxTRANSLATE( "Unicode 7 bit (UTF-7)" ),
     wxTRANSLATE( "Unicode 8 bit (UTF-8)" ),
     wxTRANSLATE( "Windows/DOS OEM (CP 437)" ),
     wxTRANSLATE( "Unicode 7 bit (UTF-7)" ),
     wxTRANSLATE( "Unicode 8 bit (UTF-8)" ),
+#ifdef WORDS_BIGENDIAN
+    wxTRANSLATE( "Unicode 16 bit (UTF-16)" ),
+    wxTRANSLATE( "Unicode 16 bit Little Endian (UTF-16LE)" ),
+    wxTRANSLATE( "Unicode 32 bit (UTF-32)" ),
+    wxTRANSLATE( "Unicode 32 bit Little Endian (UTF-32LE)" ),
+#else // WORDS_BIGENDIAN
+    wxTRANSLATE( "Unicode 16 bit Big Endian (UTF-16BE)" ),
+    wxTRANSLATE( "Unicode 16 bit (UTF-16)" ),
+    wxTRANSLATE( "Unicode 32 bit Big Endian (UTF-32BE)" ),
+    wxTRANSLATE( "Unicode 32 bit (UTF-32)" ),
+#endif // WORDS_BIGENDIAN
     wxTRANSLATE( "Extended Unix Codepage for Japanese (EUC-JP)" ),
     wxTRANSLATE( "Extended Unix Codepage for Japanese (EUC-JP)" ),
+    wxTRANSLATE( "US-ASCII" ),
+    wxTRANSLATE( "ISO-2022-JP" ),
+
+    wxTRANSLATE( "MacRoman" ),
+    wxTRANSLATE( "MacJapanese" ),
+    wxTRANSLATE( "MacChineseTrad" ),
+    wxTRANSLATE( "MacKorean" ),
+    wxTRANSLATE( "MacArabic" ),
+    wxTRANSLATE( "MacHebrew" ),
+    wxTRANSLATE( "MacGreek" ),
+    wxTRANSLATE( "MacCyrillic" ),
+    wxTRANSLATE( "MacDevanagari" ),
+    wxTRANSLATE( "MacGurmukhi" ),
+    wxTRANSLATE( "MacGujarati" ),
+    wxTRANSLATE( "MacOriya" ),
+    wxTRANSLATE( "MacBengali" ),
+    wxTRANSLATE( "MacTamil" ),
+    wxTRANSLATE( "MacTelugu" ),
+    wxTRANSLATE( "MacKannada" ),
+    wxTRANSLATE( "MacMalayalam" ),
+    wxTRANSLATE( "MacSinhalese" ),
+    wxTRANSLATE( "MacBurmese" ),
+    wxTRANSLATE( "MacKhmer" ),
+    wxTRANSLATE( "MacThai" ),
+    wxTRANSLATE( "MacLaotian" ),
+    wxTRANSLATE( "MacGeorgian" ),
+    wxTRANSLATE( "MacArmenian" ),
+    wxTRANSLATE( "MacChineseSimp" ),
+    wxTRANSLATE( "MacTibetan" ),
+    wxTRANSLATE( "MacMongolian" ),
+    wxTRANSLATE( "MacEthiopic" ),
+    wxTRANSLATE( "MacCentralEurRoman" ),
+    wxTRANSLATE( "MacVietnamese" ),
+    wxTRANSLATE( "MacExtArabic" ),
+    wxTRANSLATE( "MacSymbol" ),
+    wxTRANSLATE( "MacDingbats" ),
+    wxTRANSLATE( "MacTurkish" ),
+    wxTRANSLATE( "MacCroatian" ),
+    wxTRANSLATE( "MacIcelandic" ),
+    wxTRANSLATE( "MacRomanian" ),
+    wxTRANSLATE( "MacCeltic" ),
+    wxTRANSLATE( "MacGaelic" ),
+    wxTRANSLATE( "MacKeyboardGlyphs" )
 };
 
 // and the internal names (these are not translated on purpose!)
 };
 
 // and the internal names (these are not translated on purpose!)
-static const wxChar* gs_encodingNames[] =
+static const wxChar* const gs_encodingNames[][9] =
 {
 {
-    wxT( "iso-8859-1" ),
-    wxT( "iso-8859-2" ),
-    wxT( "iso-8859-3" ),
-    wxT( "iso-8859-4" ),
-    wxT( "iso-8859-5" ),
-    wxT( "iso-8859-6" ),
-    wxT( "iso-8859-7" ),
-    wxT( "iso-8859-8" ),
-    wxT( "iso-8859-9" ),
-    wxT( "iso-8859-10" ),
-    wxT( "iso-8859-11" ),
-    wxT( "iso-8859-12" ),
-    wxT( "iso-8859-13" ),
-    wxT( "iso-8859-14" ),
-    wxT( "iso-8859-15" ),
-    wxT( "koi8-r" ),
-    wxT( "windows-932" ),
-    wxT( "windows-936" ),
-    wxT( "windows-949" ),
-    wxT( "windows-950" ),
-    wxT( "windows-1250" ),
-    wxT( "windows-1251" ),
-    wxT( "windows-1252" ),
-    wxT( "windows-1253" ),
-    wxT( "windows-1254" ),
-    wxT( "windows-1255" ),
-    wxT( "windows-1256" ),
-    wxT( "windows-1257" ),
-    wxT( "windows-437" ),
-    wxT( "utf-7" ),
-    wxT( "utf-8" ),
-    wxT( "euc-jp" ),
+    // names from the columns correspond to these OS:
+    //      Linux        Solaris and IRIX       HP-UX             AIX
+    { wxT("ISO-8859-1"),  wxT("ISO8859-1"),  wxT("iso88591"),  wxT("8859-1"), wxT("iso_8859_1"), NULL },
+    { wxT("ISO-8859-2"),  wxT("ISO8859-2"),  wxT("iso88592"),  wxT("8859-2"), NULL },
+    { wxT("ISO-8859-3"),  wxT("ISO8859-3"),  wxT("iso88593"),  wxT("8859-3"), NULL },
+    { wxT("ISO-8859-4"),  wxT("ISO8859-4"),  wxT("iso88594"),  wxT("8859-4"), NULL },
+    { wxT("ISO-8859-5"),  wxT("ISO8859-5"),  wxT("iso88595"),  wxT("8859-5"), NULL },
+    { wxT("ISO-8859-6"),  wxT("ISO8859-6"),  wxT("iso88596"),  wxT("8859-6"), NULL },
+    { wxT("ISO-8859-7"),  wxT("ISO8859-7"),  wxT("iso88597"),  wxT("8859-7"), NULL },
+    { wxT("ISO-8859-8"),  wxT("ISO8859-8"),  wxT("iso88598"),  wxT("8859-8"), NULL },
+    { wxT("ISO-8859-9"),  wxT("ISO8859-9"),  wxT("iso88599"),  wxT("8859-9"), NULL },
+    { wxT("ISO-8859-10"), wxT("ISO8859-10"), wxT("iso885910"), wxT("8859-10"), NULL },
+    { wxT("ISO-8859-11"), wxT("ISO8859-11"), wxT("iso885911"), wxT("8859-11"), NULL },
+    { wxT("ISO-8859-12"), wxT("ISO8859-12"), wxT("iso885912"), wxT("8859-12"), NULL },
+    { wxT("ISO-8859-13"), wxT("ISO8859-13"), wxT("iso885913"), wxT("8859-13"), NULL },
+    { wxT("ISO-8859-14"), wxT("ISO8859-14"), wxT("iso885914"), wxT("8859-14"), NULL },
+    { wxT("ISO-8859-15"), wxT("ISO8859-15"), wxT("iso885915"), wxT("8859-15"), NULL },
+
+    // although koi8-ru is not strictly speaking the same as koi8-r,
+    // they are similar enough to make mapping it to koi8 better than
+    // not recognizing it at all
+    { wxT( "KOI8-R" ), wxT( "KOI8-RU" ), NULL },
+    { wxT( "KOI8-U" ), NULL },
+
+    { wxT( "WINDOWS-866" ), wxT( "CP866" ), NULL },
+
+    { wxT( "WINDOWS-874" ), wxT( "CP874" ), wxT( "MS874" ), wxT( "IBM-874" ), NULL },
+    { wxT( "WINDOWS-932" ), wxT( "CP932" ), wxT( "MS932" ), wxT( "IBM-932" ), wxT( "SJIS" ), wxT( "SHIFT-JIS" ), wxT( "SHIFT_JIS" ), NULL },
+    { wxT( "WINDOWS-936" ), wxT( "CP936" ), wxT( "MS936" ), wxT( "IBM-936" ), wxT( "GB2312" ), wxT( "gbk" ),wxT( "GBK" ), NULL },
+    { wxT( "WINDOWS-949" ), wxT( "CP949" ), wxT( "MS949" ), wxT( "IBM-949" ), wxT( "EUC-KR" ), wxT( "eucKR" ), wxT( "euc_kr" ), NULL },
+    { wxT( "WINDOWS-950" ), wxT( "CP950" ), wxT( "MS950" ), wxT( "IBM-950" ), wxT( "BIG5" ), wxT( "BIG-5" ), wxT( "BIG-FIVE" ), NULL },
+    { wxT( "WINDOWS-1250" ),wxT( "CP1250" ),wxT( "MS1250" ),wxT( "IBM-1250" ),NULL },
+    { wxT( "WINDOWS-1251" ),wxT( "CP1251" ),wxT( "MS1251" ),wxT( "IBM-1251" ),NULL },
+    { wxT( "WINDOWS-1252" ),wxT( "CP1252" ),wxT( "MS1252" ),wxT( "IBM-1252" ),NULL },
+    { wxT( "WINDOWS-1253" ),wxT( "CP1253" ),wxT( "MS1253" ),wxT( "IBM-1253" ),NULL },
+    { wxT( "WINDOWS-1254" ),wxT( "CP1254" ),wxT( "MS1254" ),wxT( "IBM-1254" ),NULL },
+    { wxT( "WINDOWS-1255" ),wxT( "CP1255" ),wxT( "MS1255" ),wxT( "IBM-1255" ),NULL },
+    { wxT( "WINDOWS-1256" ),wxT( "CP1256" ),wxT( "MS1256" ),wxT( "IBM-1256" ),NULL },
+    { wxT( "WINDOWS-1257" ),wxT( "CP1257" ),wxT( "MS1257" ),wxT( "IBM-1257" ),NULL },
+    { wxT( "WINDOWS-1258" ),wxT( "CP1258" ),wxT( "MS1258" ),wxT( "IBM-1258" ),NULL },
+    { wxT( "WINDOWS-1361" ),wxT( "CP1361" ),wxT( "MS1361" ),wxT( "IBM-1361" ), wxT( "JOHAB" ), NULL },
+    { wxT( "WINDOWS-437" ), wxT( "CP437" ), wxT( "MS437" ), wxT( "IBM-437" ), NULL },
+
+    { wxT( "UTF-7" ), wxT("UTF7"), NULL },
+    { wxT( "UTF-8" ), wxT("UTF8"), NULL },
+#ifdef WORDS_BIGENDIAN
+    { wxT( "UTF-16BE" ), wxT("UTF16BE"), wxT("UCS-2BE"), wxT("UCS2BE"), wxT("UTF-16"), wxT("UTF16"), wxT("UCS-2"), wxT("UCS2"), NULL },
+    { wxT( "UTF-16LE" ), wxT("UTF16LE"), wxT("UCS-2LE"), wxT("UCS2LE"), NULL },
+    { wxT( "UTF-32BE" ), wxT("UTF32BE"), wxT("UCS-4BE" ), wxT("UTF-32"), wxT("UTF32"), wxT("UCS-4"), wxT("UCS4"), NULL },
+    { wxT( "UTF-32LE" ), wxT("UTF32LE"), wxT("UCS-4LE"), wxT("UCS4LE"), NULL },
+#else // WORDS_BIGENDIAN
+    { wxT("UTF-16BE"), wxT("UTF16BE"), wxT("UCS-2BE"), wxT("UCS2BE"), NULL },
+    { wxT("UTF-16LE"), wxT("UTF16LE"), wxT("UCS-2LE"), wxT("UTF-16"), wxT("UTF16"), wxT("UCS-2"), wxT("UCS2"), NULL },
+    { wxT("UTF-32BE"), wxT("UTF32BE"), wxT("UCS-4BE"), wxT("UCS4BE"), NULL },
+    { wxT("UTF-32LE"), wxT("UTF32LE"), wxT("UCS-4LE"), wxT("UCS4LE"), wxT("UTF-32"), wxT("UTF32"), wxT("UCS-4"), wxT("UCS4"), NULL },
+#endif // WORDS_BIGENDIAN
+
+    { wxT( "EUC-JP" ), wxT( "eucJP" ), wxT( "euc_jp" ), wxT( "IBM-eucJP" ), NULL },
+
+    // 646 is for Solaris, roman8 -- for HP-UX
+    { wxT( "US-ASCII" ), wxT( "ASCII" ), wxT("C"), wxT("POSIX"), wxT("ANSI_X3.4-1968"),
+      wxT("646"), wxT("roman8"), wxT( "" ), NULL },
+
+    { wxT( "ISO-2022-JP" ), NULL },
+
+
+    { wxT( "MacRoman" ), NULL },
+    { wxT( "MacJapanese" ), NULL },
+    { wxT( "MacChineseTrad" ), NULL },
+    { wxT( "MacKorean" ), NULL },
+    { wxT( "MacArabic" ), NULL },
+    { wxT( "MacHebrew" ), NULL },
+    { wxT( "MacGreek" ), NULL },
+    { wxT( "MacCyrillic" ), NULL },
+    { wxT( "MacDevanagari" ), NULL },
+    { wxT( "MacGurmukhi" ), NULL },
+    { wxT( "MacGujarati" ), NULL },
+    { wxT( "MacOriya" ), NULL },
+    { wxT( "MacBengali" ), NULL },
+    { wxT( "MacTamil" ), NULL },
+    { wxT( "MacTelugu" ), NULL },
+    { wxT( "MacKannada" ), NULL },
+    { wxT( "MacMalayalam" ), NULL },
+    { wxT( "MacSinhalese" ), NULL },
+    { wxT( "MacBurmese" ), NULL },
+    { wxT( "MacKhmer" ), NULL },
+    { wxT( "MacThai" ), NULL },
+    { wxT( "MacLaotian" ), NULL },
+    { wxT( "MacGeorgian" ), NULL },
+    { wxT( "MacArmenian" ), NULL },
+    { wxT( "MacChineseSimp" ), NULL },
+    { wxT( "MacTibetan" ), NULL },
+    { wxT( "MacMongolian" ), NULL },
+    { wxT( "MacEthiopic" ), NULL },
+    { wxT( "MacCentralEurRoman" ), NULL },
+    { wxT( "MacVietnamese" ), NULL },
+    { wxT( "MacExtArabic" ), NULL },
+    { wxT( "MacSymbol" ), NULL },
+    { wxT( "MacDingbats" ), NULL },
+    { wxT( "MacTurkish" ), NULL },
+    { wxT( "MacCroatian" ), NULL },
+    { wxT( "MacIcelandic" ), NULL },
+    { wxT( "MacRomanian" ), NULL },
+    { wxT( "MacCeltic" ), NULL },
+    { wxT( "MacGaelic" ), NULL },
+    { wxT( "MacKeyboardGlyphs" ), NULL }
 };
 
 };
 
-wxCOMPILE_TIME_ASSERT( WXSIZEOF(gs_encodingDescs) == WXSIZEOF(gs_encodings) &&
-                       WXSIZEOF(gs_encodingNames) == WXSIZEOF(gs_encodings),
-                       EncodingsArraysNotInSync );
+wxCOMPILE_TIME_ASSERT( WXSIZEOF(gs_encodingDescs) == WXSIZEOF(gs_encodings), EncodingsArraysNotInSync );
+wxCOMPILE_TIME_ASSERT( WXSIZEOF(gs_encodingNames) == WXSIZEOF(gs_encodings), EncodingsArraysNotInSync );
 
 // ----------------------------------------------------------------------------
 // private classes
 
 // ----------------------------------------------------------------------------
 // private classes
@@ -176,8 +362,25 @@ class wxFontMapperModule : public wxModule
 {
 public:
     wxFontMapperModule() : wxModule() { }
 {
 public:
     wxFontMapperModule() : wxModule() { }
-    virtual bool OnInit() { return TRUE; }
-    virtual void OnExit() { delete wxFontMapper::Set(NULL); }
+
+    virtual bool OnInit()
+    {
+        // a dummy wxFontMapperBase object could have been created during the
+        // program startup before wxApp was created, we have to delete it to
+        // allow creating the real font mapper next time it is needed now that
+        // we can create it (when the modules are initialized, wxApp object
+        // already exists)
+        wxFontMapperBase *fm = wxFontMapperBase::Get();
+        if ( fm && fm->IsDummy() )
+            wxFontMapperBase::Reset();
+
+        return true;
+    }
+
+    virtual void OnExit()
+    {
+        wxFontMapperBase::Reset();
+    }
 
     DECLARE_DYNAMIC_CLASS(wxFontMapperModule)
 };
 
     DECLARE_DYNAMIC_CLASS(wxFontMapperModule)
 };
@@ -197,22 +400,21 @@ wxFontMapper *wxFontMapperBase::sm_instance = NULL;
 
 wxFontMapperBase::wxFontMapperBase()
 {
 
 wxFontMapperBase::wxFontMapperBase()
 {
-#if wxUSE_CONFIG
-    m_config = NULL;
-    m_configIsDummy = FALSE;
+#if wxUSE_CONFIG && wxUSE_FILECONFIG
+    m_configDummy = NULL;
 #endif // wxUSE_CONFIG
 }
 
 wxFontMapperBase::~wxFontMapperBase()
 {
 #endif // wxUSE_CONFIG
 }
 
 wxFontMapperBase::~wxFontMapperBase()
 {
-#if wxUSE_CONFIG
-    if ( m_configIsDummy )
-        delete m_config;
+#if wxUSE_CONFIG && wxUSE_FILECONFIG
+    if ( m_configDummy )
+        delete m_configDummy;
 #endif // wxUSE_CONFIG
 }
 
 /* static */
 #endif // wxUSE_CONFIG
 }
 
 /* static */
-wxFontMapper *wxFontMapperBase::Get()
+wxFontMapperBase *wxFontMapperBase::Get()
 {
     if ( !sm_instance )
     {
 {
     if ( !sm_instance )
     {
@@ -222,7 +424,7 @@ wxFontMapper *wxFontMapperBase::Get()
             sm_instance = traits->CreateFontMapper();
 
             wxASSERT_MSG( sm_instance,
             sm_instance = traits->CreateFontMapper();
 
             wxASSERT_MSG( sm_instance,
-                            _T("wxAppTraits::CreateFontMapper() failed") );
+                            wxT("wxAppTraits::CreateFontMapper() failed") );
         }
 
         if ( !sm_instance )
         }
 
         if ( !sm_instance )
@@ -233,7 +435,7 @@ wxFontMapper *wxFontMapperBase::Get()
         }
     }
 
         }
     }
 
-    return sm_instance;
+    return (wxFontMapperBase*)sm_instance;
 }
 
 /* static */
 }
 
 /* static */
@@ -244,21 +446,39 @@ wxFontMapper *wxFontMapperBase::Set(wxFontMapper *mapper)
     return old;
 }
 
     return old;
 }
 
-#if wxUSE_CONFIG
+/* static */
+void wxFontMapperBase::Reset()
+{
+    if ( sm_instance )
+    {
+        // we need a cast as wxFontMapper is not fully declared here and so the
+        // compiler can't know that it derives from wxFontMapperBase (but
+        // run-time behaviour will be correct because the dtor is virtual)
+        delete (wxFontMapperBase *)sm_instance;
+        sm_instance = NULL;
+    }
+}
+
+#if wxUSE_CONFIG && wxUSE_FILECONFIG
 
 // ----------------------------------------------------------------------------
 // config usage customisation
 // ----------------------------------------------------------------------------
 
 
 // ----------------------------------------------------------------------------
 // config usage customisation
 // ----------------------------------------------------------------------------
 
+
+static wxString gs_defaultConfigPath(FONTMAPPER_ROOT_PATH);
+
 /* static */
 /* static */
-const wxChar *wxFontMapperBase::GetDefaultConfigPath()
+const wxString& wxFontMapperBase::GetDefaultConfigPath()
 {
 {
-    return FONTMAPPER_ROOT_PATH;
+    // NB: we return const wxString& and not wxString for compatibility
+    //     with 2.8 that returned const wxChar*
+    return gs_defaultConfigPath;
 }
 
 void wxFontMapperBase::SetConfigPath(const wxString& prefix)
 {
 }
 
 void wxFontMapperBase::SetConfigPath(const wxString& prefix)
 {
-    wxCHECK_RET( !prefix.IsEmpty() && prefix[0] == wxCONFIG_PATH_SEPARATOR,
+    wxCHECK_RET( !prefix.empty() && prefix[0] == wxCONFIG_PATH_SEPARATOR,
                  wxT("an absolute path should be given to wxFontMapper::SetConfigPath()") );
 
     m_configRootPath = prefix;
                  wxT("an absolute path should be given to wxFontMapper::SetConfigPath()") );
 
     m_configRootPath = prefix;
@@ -270,42 +490,23 @@ void wxFontMapperBase::SetConfigPath(const wxString& prefix)
 
 wxConfigBase *wxFontMapperBase::GetConfig()
 {
 
 wxConfigBase *wxFontMapperBase::GetConfig()
 {
-    if ( !m_config )
-    {
-        // try the default
-        m_config = wxConfig::Get(FALSE /*don't create on demand*/ );
-
-        if ( !m_config )
-        {
-            // we still want to have a config object because otherwise we would
-            // keep asking the user the same questions in the interactive mode,
-            // so create a dummy config which won't write to any files/registry
-            // but will allow us to remember the results of the questions at
-            // least during this run
-            m_config = new wxMemoryConfig;
-            m_configIsDummy = TRUE;
-            // VS: we can't call wxConfig::Set(m_config) here because that would
-            //     disable automatic wxConfig instance creation if this code was
-            //     called before wxApp::OnInit (this happens in wxGTK -- it sets
-            //     default wxFont encoding in wxApp::Initialize())
-        }
-    }
+    wxConfigBase *config = wxConfig::Get(false);
 
 
-    if ( m_configIsDummy && wxConfig::Get(FALSE) != NULL )
+    // If there is no global configuration, use an internal memory configuration
+    if ( !config )
     {
     {
-        // VS: in case we created dummy m_config (see above), we want to switch back
-        //     to the real one as soon as one becomes available.
-        delete m_config;
-        m_config = wxConfig::Get(FALSE);
-        m_configIsDummy = FALSE;
-        // FIXME: ideally, we should add keys from dummy config to the real one now,
+        if ( !m_configDummy )
+            m_configDummy = new wxMemoryConfig;
+        config = m_configDummy;
+
+        // FIXME: ideally, we should add keys from dummy config to a real one later,
         //        but it is a low-priority task because typical wxWin application
         //        either doesn't use wxConfig at all or creates wxConfig object in
         //        wxApp::OnInit(), before any real interaction with the user takes
         //        place...
     }
 
         //        but it is a low-priority task because typical wxWin application
         //        either doesn't use wxConfig at all or creates wxConfig object in
         //        wxApp::OnInit(), before any real interaction with the user takes
         //        place...
     }
 
-    return m_config;
+    return config;
 }
 
 const wxString& wxFontMapperBase::GetConfigPath()
 }
 
 const wxString& wxFontMapperBase::GetConfigPath()
@@ -327,12 +528,12 @@ bool wxFontMapperBase::ChangePath(const wxString& pathNew, wxString *pathOld)
 {
     wxConfigBase *config = GetConfig();
     if ( !config )
 {
     wxConfigBase *config = GetConfig();
     if ( !config )
-        return FALSE;
+        return false;
 
     *pathOld = config->GetPath();
 
     wxString path = GetConfigPath();
 
     *pathOld = config->GetPath();
 
     wxString path = GetConfigPath();
-    if ( path.IsEmpty() || path.Last() != wxCONFIG_PATH_SEPARATOR )
+    if ( path.empty() || path.Last() != wxCONFIG_PATH_SEPARATOR )
     {
         path += wxCONFIG_PATH_SEPARATOR;
     }
     {
         path += wxCONFIG_PATH_SEPARATOR;
     }
@@ -344,7 +545,7 @@ bool wxFontMapperBase::ChangePath(const wxString& pathNew, wxString *pathOld)
 
     config->SetPath(path);
 
 
     config->SetPath(path);
 
-    return TRUE;
+    return true;
 }
 
 void wxFontMapperBase::RestorePath(const wxString& pathOld)
 }
 
 void wxFontMapperBase::RestorePath(const wxString& pathOld)
@@ -352,6 +553,8 @@ void wxFontMapperBase::RestorePath(const wxString& pathOld)
     GetConfig()->SetPath(pathOld);
 }
 
     GetConfig()->SetPath(pathOld);
 }
 
+#endif
+
 // ----------------------------------------------------------------------------
 // charset/encoding correspondence
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
 // charset/encoding correspondence
 // ----------------------------------------------------------------------------
@@ -359,13 +562,27 @@ void wxFontMapperBase::RestorePath(const wxString& pathOld)
 wxFontEncoding
 wxFontMapperBase::CharsetToEncoding(const wxString& charset,
                                     bool WXUNUSED(interactive))
 wxFontEncoding
 wxFontMapperBase::CharsetToEncoding(const wxString& charset,
                                     bool WXUNUSED(interactive))
+{
+    int enc = NonInteractiveCharsetToEncoding(charset);
+    if ( enc == wxFONTENCODING_UNKNOWN )
+    {
+        // we should return wxFONTENCODING_SYSTEM from here for unknown
+        // encodings
+        enc = wxFONTENCODING_SYSTEM;
+    }
+
+    return (wxFontEncoding)enc;
+}
+
+int
+wxFontMapperBase::NonInteractiveCharsetToEncoding(const wxString& charset)
 {
     wxFontEncoding encoding = wxFONTENCODING_SYSTEM;
 
     // we're going to modify it, make a copy
     wxString cs = charset;
 
 {
     wxFontEncoding encoding = wxFONTENCODING_SYSTEM;
 
     // we're going to modify it, make a copy
     wxString cs = charset;
 
-#if wxUSE_CONFIG
+#if wxUSE_CONFIG && wxUSE_FILECONFIG
     // first try the user-defined settings
     wxFontMapperPathChanger path(this, FONTMAPPER_CHARSET_PATH);
     if ( path.IsOk() )
     // first try the user-defined settings
     wxFontMapperPathChanger path(this, FONTMAPPER_CHARSET_PATH);
     if ( path.IsOk() )
@@ -379,7 +596,7 @@ wxFontMapperBase::CharsetToEncoding(const wxString& charset,
             if ( value == wxFONTENCODING_UNKNOWN )
             {
                 // don't try to find it, in particular don't ask the user
             if ( value == wxFONTENCODING_UNKNOWN )
             {
                 // don't try to find it, in particular don't ask the user
-                return wxFONTENCODING_SYSTEM;
+                return value;
             }
 
             if ( value >= 0 && value <= wxFONTENCODING_MAX )
             }
 
             if ( value >= 0 && value <= wxFONTENCODING_MAX )
@@ -399,7 +616,7 @@ wxFontMapperBase::CharsetToEncoding(const wxString& charset,
             config->SetPath(FONTMAPPER_CHARSET_ALIAS_PATH);
 
             wxString alias = config->Read(charset);
             config->SetPath(FONTMAPPER_CHARSET_ALIAS_PATH);
 
             wxString alias = config->Read(charset);
-            if ( !!alias )
+            if ( !alias.empty() )
             {
                 // yes, we do - use it instead
                 cs = alias;
             {
                 // yes, we do - use it instead
                 cs = alias;
@@ -418,69 +635,34 @@ wxFontMapperBase::CharsetToEncoding(const wxString& charset,
         // discard the optional quotes
         if ( !cs.empty() )
         {
         // discard the optional quotes
         if ( !cs.empty() )
         {
-            if ( cs[0u] == _T('"') && cs.Last() == _T('"') )
+            if ( cs[0u] == wxT('"') && cs.Last() == wxT('"') )
             {
                 cs = wxString(cs.c_str(), cs.length() - 1);
             }
         }
 
             {
                 cs = wxString(cs.c_str(), cs.length() - 1);
             }
         }
 
-        cs.MakeUpper();
-
-        if ( cs.empty() || cs == _T("US-ASCII") )
+        for ( size_t i = 0; i < WXSIZEOF(gs_encodingNames); ++i )
         {
         {
-            encoding = wxFONTENCODING_DEFAULT;
-        }
-        else if ( cs == wxT("UTF-7") )
-        {
-            encoding = wxFONTENCODING_UTF7;
-        }
-        else if ( cs == wxT("UTF-8") )
-        {
-            encoding = wxFONTENCODING_UTF8;
-        }
-        else if ( cs == wxT("GB2312") )
-        {
-            encoding = wxFONTENCODING_GB2312;
-        }
-        else if ( cs == wxT("BIG5") )
-        {
-            encoding = wxFONTENCODING_BIG5;
-        }
-        else if ( cs == wxT("SJIS") ||
-                  cs == wxT("SHIFT_JIS") ||
-                  cs == wxT("SHIFT-JIS") )
-        {
-            encoding = wxFONTENCODING_SHIFT_JIS;
-        }
-        else if ( cs == wxT("EUC-JP") ||
-                  cs == wxT("EUC_JP") )
-        {
-            encoding = wxFONTENCODING_EUC_JP;
-        }
-        else if ( cs == wxT("KOI8-R") ||
-                  cs == wxT("KOI8-U") ||
-                  cs == wxT("KOI8-RU") )
-        {
-            // although koi8-ru is not strictly speaking the same as koi8-r,
-            // they are similar enough to make mapping it to koi8 better than
-            // not reckognizing it at all
-            encoding = wxFONTENCODING_KOI8;
+            for ( const wxChar* const* encName = gs_encodingNames[i]; *encName; ++encName )
+            {
+                if ( cs.CmpNoCase(*encName) == 0 )
+                    return gs_encodings[i];
+            }
         }
         }
-        else if ( cs.Left(3) == wxT("ISO") )
+
+        cs.MakeUpper();
+
+        if ( cs.Left(3) == wxT("ISO") )
         {
             // the dash is optional (or, to be exact, it is not, but
         {
             // the dash is optional (or, to be exact, it is not, but
-            // several brokenmails "forget" it)
+            // several broken programs "forget" it)
             const wxChar *p = cs.c_str() + 3;
             if ( *p == wxT('-') )
                 p++;
             const wxChar *p = cs.c_str() + 3;
             if ( *p == wxT('-') )
                 p++;
-                
-            // printf( "iso %s\n", (const char*) cs.ToAscii() );
 
             unsigned int value;
             if ( wxSscanf(p, wxT("8859-%u"), &value) == 1 )
             {
 
             unsigned int value;
             if ( wxSscanf(p, wxT("8859-%u"), &value) == 1 )
             {
-                // printf( "value %d\n", (int)value );
-   
                 // make it 0 based and check that it is strictly positive in
                 // the process (no such thing as iso8859-0 encoding)
                 if ( (value-- > 0) &&
                 // make it 0 based and check that it is strictly positive in
                 // the process (no such thing as iso8859-0 encoding)
                 if ( (value-- > 0) &&
@@ -496,12 +678,10 @@ wxFontMapperBase::CharsetToEncoding(const wxString& charset,
         else if ( cs.Left(4) == wxT("8859") )
         {
             const wxChar *p = cs.c_str();
         else if ( cs.Left(4) == wxT("8859") )
         {
             const wxChar *p = cs.c_str();
-            
+
             unsigned int value;
             if ( wxSscanf(p, wxT("8859-%u"), &value) == 1 )
             {
             unsigned int value;
             if ( wxSscanf(p, wxT("8859-%u"), &value) == 1 )
             {
-                // printf( "value %d\n", (int)value );
-   
                 // make it 0 based and check that it is strictly positive in
                 // the process (no such thing as iso8859-0 encoding)
                 if ( (value-- > 0) &&
                 // make it 0 based and check that it is strictly positive in
                 // the process (no such thing as iso8859-0 encoding)
                 if ( (value-- > 0) &&
@@ -536,7 +716,7 @@ wxFontMapperBase::CharsetToEncoding(const wxString& charset,
                 if ( *p == wxT('-') )
                     p++;
 
                 if ( *p == wxT('-') )
                     p++;
 
-                int value;
+                unsigned int value;
                 if ( wxSscanf(p, wxT("%u"), &value) == 1 )
                 {
                     if ( value >= 1250 )
                 if ( wxSscanf(p, wxT("%u"), &value) == 1 )
                 {
                     if ( value >= 1250 )
@@ -553,6 +733,14 @@ wxFontMapperBase::CharsetToEncoding(const wxString& charset,
 
                     switch ( value )
                     {
 
                     switch ( value )
                     {
+                        case 866:
+                            encoding = wxFONTENCODING_CP866;
+                            break;
+
+                        case 874:
+                            encoding = wxFONTENCODING_CP874;
+                            break;
+
                         case 932:
                             encoding = wxFONTENCODING_CP932;
                             break;
                         case 932:
                             encoding = wxFONTENCODING_CP932;
                             break;
@@ -568,6 +756,14 @@ wxFontMapperBase::CharsetToEncoding(const wxString& charset,
                         case 950:
                             encoding = wxFONTENCODING_CP950;
                             break;
                         case 950:
                             encoding = wxFONTENCODING_CP950;
                             break;
+
+                        case 1258:
+                            encoding = wxFONTENCODING_CP1258;
+                            break;
+
+                        case 1361:
+                            encoding = wxFONTENCODING_CP1361;
+                            break;
                     }
                 }
             }
                     }
                 }
             }
@@ -588,7 +784,7 @@ size_t wxFontMapperBase::GetSupportedEncodingsCount()
 wxFontEncoding wxFontMapperBase::GetEncoding(size_t n)
 {
     wxCHECK_MSG( n < WXSIZEOF(gs_encodings), wxFONTENCODING_SYSTEM,
 wxFontEncoding wxFontMapperBase::GetEncoding(size_t n)
 {
     wxCHECK_MSG( n < WXSIZEOF(gs_encodings), wxFONTENCODING_SYSTEM,
-                    _T("wxFontMapper::GetEncoding(): invalid index") );
+                    wxT("wxFontMapper::GetEncoding(): invalid index") );
 
     return gs_encodings[n];
 }
 
     return gs_encodings[n];
 }
@@ -631,7 +827,7 @@ wxString wxFontMapperBase::GetEncodingName(wxFontEncoding encoding)
     {
         if ( gs_encodings[i] == encoding )
         {
     {
         if ( gs_encodings[i] == encoding )
         {
-            return gs_encodingNames[i];
+            return gs_encodingNames[i][0];
         }
     }
 
         }
     }
 
@@ -641,7 +837,37 @@ wxString wxFontMapperBase::GetEncodingName(wxFontEncoding encoding)
     return str;
 }
 
     return str;
 }
 
-#endif // wxUSE_CONFIG
+/* static */
+const wxChar** wxFontMapperBase::GetAllEncodingNames(wxFontEncoding encoding)
+{
+    static const wxChar* const dummy[] = { NULL };
 
 
-#endif // wxUSE_FONTMAP
+    for ( size_t i = 0; i < WXSIZEOF(gs_encodingNames); i++ )
+    {
+        if ( gs_encodings[i] == encoding )
+        {
+            return const_cast<const wxChar**>(gs_encodingNames[i]);
+        }
+    }
+
+    return const_cast<const wxChar**>(dummy);
+}
+
+/* static */
+wxFontEncoding wxFontMapperBase::GetEncodingFromName(const wxString& name)
+{
+    const size_t count = WXSIZEOF(gs_encodingNames);
+
+    for ( size_t i = 0; i < count; i++ )
+    {
+        for ( const wxChar* const* encName = gs_encodingNames[i]; *encName; ++encName )
+        {
+            if ( name.CmpNoCase(*encName) == 0 )
+                return gs_encodings[i];
+        }
+    }
 
 
+    return wxFONTENCODING_MAX;
+}
+
+#endif // wxUSE_FONTMAP