X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/11c7d5b6d1cb54d5ffdc11d8ff092b41e225bfb6..4a377e137527eb7f4a26b9e3bc1cd88e8c108676:/src/common/fontmap.cpp?ds=sidebyside diff --git a/src/common/fontmap.cpp b/src/common/fontmap.cpp index b0a2aa7a24..d8390e983b 100644 --- a/src/common/fontmap.cpp +++ b/src/common/fontmap.cpp @@ -35,21 +35,32 @@ #endif // PCH #include "wx/fontmap.h" -#include "wx/config.h" -#include "wx/msgdlg.h" -#include "wx/fontdlg.h" -#include "wx/choicdlg.h" +#if wxUSE_CONFIG + #include "wx/config.h" + #include "wx/memconf.h" +#endif + +#if wxUSE_GUI + #include "wx/fontutil.h" + #include "wx/msgdlg.h" + #include "wx/fontdlg.h" + #include "wx/choicdlg.h" +#endif // wxUSE_GUI + +#include "wx/encconv.h" // ---------------------------------------------------------------------------- // constants // ---------------------------------------------------------------------------- // the config paths we use -static const char* FONTMAPPER_ROOT_PATH = _T("FontMapper"); -static const char* FONTMAPPER_CHARSET_PATH = _T("Charsets"); -static const char* FONTMAPPER_CHARSET_ALIAS_PATH = _T("Aliases"); -static const char* FONTMAPPER_FONT_FROM_ENCODING_PATH = _T("Encodings"); +static const wxChar* FONTMAPPER_ROOT_PATH = wxT("/wxWindows/FontMapper"); +static const wxChar* FONTMAPPER_CHARSET_PATH = wxT("Charsets"); +static const wxChar* FONTMAPPER_CHARSET_ALIAS_PATH = wxT("Aliases"); +#if wxUSE_GUI + static const wxChar* FONTMAPPER_FONT_FROM_ENCODING_PATH = wxT("Encodings"); +#endif // wxUSE_GUI // encodings supported by GetEncodingDescription static wxFontEncoding gs_encodings[] = @@ -78,64 +89,67 @@ static wxFontEncoding gs_encodings[] = wxFONTENCODING_CP1255, wxFONTENCODING_CP1256, wxFONTENCODING_CP1257, + wxFONTENCODING_CP437, }; // the descriptions for them static const wxChar* gs_encodingDescs[] = { - wxTRANSLATE( "West European (ISO-8859-1/Latin 1)" ), + wxTRANSLATE( "Western European (ISO-8859-1/Latin 1)" ), wxTRANSLATE( "Central European (ISO-8859-2/Latin 2)" ), wxTRANSLATE( "Esperanto (ISO-8859-3)" ), - wxTRANSLATE( "Baltic (ISO-8859-4)" ), + wxTRANSLATE( "Baltic (old) (ISO-8859-4)" ), wxTRANSLATE( "Cyrillic (Latin 5)" ), wxTRANSLATE( "Arabic (ISO-8859-6)" ), wxTRANSLATE( "Greek (ISO-8859-7)" ), wxTRANSLATE( "Hebrew (ISO-8859-8)" ), wxTRANSLATE( "Turkish (ISO-8859-9)" ), - wxTRANSLATE( "Baltic II (ISO-8859-10)" ), + wxTRANSLATE( "Nordic (ISO-8859-10)" ), wxTRANSLATE( "Thai (ISO-8859-11)" ), - wxTRANSLATE( "ISO-8859-12" ), - wxTRANSLATE( "ISO-8859-13" ), - wxTRANSLATE( "ISO-8859-14" ), - wxTRANSLATE( "West European new (ISO-8859-15/Latin 0)" ), + wxTRANSLATE( "Indian (ISO-8859-12)" ), + wxTRANSLATE( "Baltic (ISO-8859-13)" ), + wxTRANSLATE( "Celtic (ISO-8859-14)" ), + wxTRANSLATE( "Western European with Euro (ISO-8859-15/Latin 0)" ), wxTRANSLATE( "KOI8-R" ), - wxTRANSLATE( "Windows Latin 2 (CP 1250)" ), + wxTRANSLATE( "Windows Central European (CP 1250)" ), wxTRANSLATE( "Windows Cyrillic (CP 1251)" ), - wxTRANSLATE( "Windows Latin 1 (CP 1252)" ), + wxTRANSLATE( "Windows Western European (CP 1252)" ), wxTRANSLATE( "Windows Greek (CP 1253)" ), wxTRANSLATE( "Windows Turkish (CP 1254)" ), wxTRANSLATE( "Windows Hebrew (CP 1255)" ), wxTRANSLATE( "Windows Arabic (CP 1256)" ), wxTRANSLATE( "Windows Baltic (CP 1257)" ), + wxTRANSLATE( "Windows/DOS OEM (CP 437)" ), }; // and the internal names static const wxChar* gs_encodingNames[] = { - "iso8859-1", - "iso8859-2", - "iso8859-3", - "iso8859-4", - "iso8859-5", - "iso8859-6", - "iso8859-7", - "iso8859-8", - "iso8859-9", - "iso8859-10", - "iso8859-11", - "iso8859-12", - "iso8859-13", - "iso8859-14", - "iso8859-15", - "koi8-r", - "windows1250", - "windows1251", - "windows1252", - "windows1253", - "windows1254", - "windows1255", - "windows1256", - "windows1257", + wxT( "iso8859-1" ), + wxT( "iso8859-2" ), + wxT( "iso8859-3" ), + wxT( "iso8859-4" ), + wxT( "iso8859-5" ), + wxT( "iso8859-6" ), + wxT( "iso8859-7" ), + wxT( "iso8859-8" ), + wxT( "iso8859-9" ), + wxT( "iso8859-10" ), + wxT( "iso8859-11" ), + wxT( "iso8859-12" ), + wxT( "iso8859-13" ), + wxT( "iso8859-14" ), + wxT( "iso8859-15" ), + wxT( "koi8-r" ), + wxT( "windows1250" ), + wxT( "windows1251" ), + wxT( "windows1252" ), + wxT( "windows1253" ), + wxT( "windows1254" ), + wxT( "windows1255" ), + wxT( "windows1256" ), + wxT( "windows1257" ), + wxT( "windows437" ), }; // ---------------------------------------------------------------------------- @@ -146,7 +160,7 @@ static const wxChar* gs_encodingNames[] = static wxFontMapper gs_fontMapper; // and public pointer -wxFontMapper * WXDLLEXPORT wxTheFontMapper = &gs_fontMapper; +wxFontMapper * wxTheFontMapper = &gs_fontMapper; // ---------------------------------------------------------------------------- // private classes @@ -186,8 +200,13 @@ private: wxFontMapper::wxFontMapper() { +#if wxUSE_CONFIG m_config = NULL; +#endif // wxUSE_CONFIG + +#if wxUSE_GUI m_windowParent = NULL; +#endif // wxUSE_GUI } wxFontMapper::~wxFontMapper() @@ -198,6 +217,8 @@ wxFontMapper::~wxFontMapper() // customisation // ---------------------------------------------------------------------------- +#if wxUSE_CONFIG + /* static */ const wxChar *wxFontMapper::GetDefaultConfigPath() { return FONTMAPPER_ROOT_PATH; @@ -206,13 +227,11 @@ wxFontMapper::~wxFontMapper() void wxFontMapper::SetConfigPath(const wxString& prefix) { wxCHECK_RET( !prefix.IsEmpty() && prefix[0] == wxCONFIG_PATH_SEPARATOR, - _T("an absolute path should be given to " - "wxFontMapper::SetConfigPath()") ); + wxT("an absolute path should be given to wxFontMapper::SetConfigPath()") ); m_configRootPath = prefix; } - // ---------------------------------------------------------------------------- // get config object and path for it // ---------------------------------------------------------------------------- @@ -222,7 +241,18 @@ wxConfigBase *wxFontMapper::GetConfig() if ( !m_config ) { // try the default - m_config = wxConfig::Get(); + 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; + wxConfig::Set(m_config); + } } return m_config; @@ -238,9 +268,11 @@ const wxString& wxFontMapper::GetConfigPath() return m_configRootPath; } +#endif bool wxFontMapper::ChangePath(const wxString& pathNew, wxString *pathOld) { +#if wxUSE_CONFIG wxConfigBase *config = GetConfig(); if ( !config ) return FALSE; @@ -254,18 +286,24 @@ bool wxFontMapper::ChangePath(const wxString& pathNew, wxString *pathOld) } wxASSERT_MSG( !pathNew || (pathNew[0] != wxCONFIG_PATH_SEPARATOR), - _T("should be a relative path") ); + wxT("should be a relative path") ); path += pathNew; config->SetPath(path); return TRUE; +#else + return FALSE; +#endif } void wxFontMapper::RestorePath(const wxString& pathOld) { +#if wxUSE_CONFIG GetConfig()->SetPath(pathOld); +#else +#endif } // ---------------------------------------------------------------------------- @@ -278,8 +316,7 @@ wxString wxFontMapper::GetEncodingDescription(wxFontEncoding encoding) size_t count = WXSIZEOF(gs_encodingDescs); wxASSERT_MSG( count == WXSIZEOF(gs_encodings), - _T("inconsitency detected - forgot to update one of " - "the arrays?") ); + wxT("inconsitency detected - forgot to update one of the arrays?") ); for ( size_t i = 0; i < count; i++ ) { @@ -301,8 +338,7 @@ wxString wxFontMapper::GetEncodingName(wxFontEncoding encoding) size_t count = WXSIZEOF(gs_encodingNames); wxASSERT_MSG( count == WXSIZEOF(gs_encodings), - _T("inconsitency detected - forgot to update one of " - "the arrays?") ); + wxT("inconsistency detected - forgot to update one of the arrays?") ); for ( size_t i = 0; i < count; i++ ) { @@ -326,6 +362,7 @@ wxFontEncoding wxFontMapper::CharsetToEncoding(const wxString& charset, // we're going to modify it, make a copy wxString cs = charset; +#if wxUSE_CONFIG // first try the user-defined settings wxString pathOld; if ( ChangePath(FONTMAPPER_CHARSET_PATH, &pathOld) ) @@ -342,8 +379,8 @@ wxFontEncoding wxFontMapper::CharsetToEncoding(const wxString& charset, } else { - wxLogDebug(_T("corrupted config data - invalid encoding %ld " - "for charset '%s'"), value, charset.c_str()); + wxLogDebug(wxT("corrupted config data: invalid encoding %ld for charset '%s' ignored"), + value, charset.c_str()); } } @@ -362,26 +399,36 @@ wxFontEncoding wxFontMapper::CharsetToEncoding(const wxString& charset, RestorePath(pathOld); } +#endif // if didn't find it there, try to reckognise it ourselves if ( encoding == wxFONTENCODING_SYSTEM ) { + // discard the optional quotes + if ( !!cs ) + { + if ( cs[0u] == _T('"') && cs.Last() == _T('"') ) + { + cs = wxString(cs.c_str(), cs.length() - 1); + } + } + cs.MakeUpper(); - if ( !cs || cs == _T("US-ASCII") ) + if ( !cs || cs == wxT("US-ASCII") ) encoding = wxFONTENCODING_DEFAULT; - else if ( cs == _T("KOI8-R") || cs == _T("KOI8-U") ) + else if ( cs == wxT("KOI8-R") || cs == wxT("KOI8-U") ) encoding = wxFONTENCODING_KOI8; - else if ( cs.Left(3) == _T("ISO") ) + else if ( cs.Left(3) == wxT("ISO") ) { // the dash is optional (or, to be exact, it is not, but // several brokenmails "forget" it) const wxChar *p = cs.c_str() + 3; - if ( *p == _T('-') ) + if ( *p == wxT('-') ) p++; unsigned int value; - if ( wxSscanf(p, _T("8859-%u"), &value) == 1 ) + if ( wxSscanf(p, wxT("8859-%u"), &value) == 1 ) { if ( value < wxFONTENCODING_ISO8859_MAX - wxFONTENCODING_ISO8859_1 ) @@ -392,16 +439,16 @@ wxFontEncoding wxFontMapper::CharsetToEncoding(const wxString& charset, } } } - else if ( cs.Left(8) == _T("WINDOWS-") ) + else if ( cs.Left(8) == wxT("WINDOWS-") ) { int value; - if ( wxSscanf(cs.c_str() + 8, "%u", &value) == 1 ) + if ( wxSscanf(cs.c_str() + 8, wxT("%u"), &value) == 1 ) { if ( value >= 1250 ) { value -= 1250; if ( value < wxFONTENCODING_CP12_MAX - - wxFONTENCODING_CP1250 - 1 ) + wxFONTENCODING_CP1250 ) { // a valid Windows code page value += wxFONTENCODING_CP1250; @@ -413,6 +460,7 @@ wxFontEncoding wxFontMapper::CharsetToEncoding(const wxString& charset, //else: unknown } +#if wxUSE_GUI // if still no luck, ask the user - unless disabled if ( (encoding == wxFONTENCODING_SYSTEM) && interactive ) { @@ -425,16 +473,13 @@ wxFontEncoding wxFontMapper::CharsetToEncoding(const wxString& charset, // the message wxString msg; - msg.Printf(_("The charset '%s' is unknown. You may select another " - "charset to replace it with or choose [Cancel] if it " - "cannot be replaced"), charset.c_str()); + msg.Printf(_("The charset '%s' is unknown. You may select\nanother charset to replace it with or choose\n[Cancel] if it cannot be replaced"), charset.c_str()); // the list of choices size_t count = WXSIZEOF(gs_encodingDescs); wxASSERT_MSG( count == WXSIZEOF(gs_encodings), - _T("inconsitency detected - forgot to update one of " - "the arrays?") ); + wxT("inconsitency detected - forgot to update one of the arrays?") ); wxString *encodingNamesTranslated = new wxString[count]; @@ -458,12 +503,27 @@ wxFontEncoding wxFontMapper::CharsetToEncoding(const wxString& charset, if ( n != -1 ) { - // TODO save the result in the config! - encoding = gs_encodings[n]; + +#if wxUSE_CONFIG + // save the result in the config now + if ( ChangePath(FONTMAPPER_CHARSET_PATH, &pathOld) ) + { + wxConfigBase *config = GetConfig(); + + // remember the alt encoding for this charset + if ( !config->Write(charset, (long)encoding) ) + { + wxLogError(_("Failed to remember the encoding for the charset '%s'."), charset.c_str()); + } + + RestorePath(pathOld); + } +#endif // wxUSE_CONFIG } //else: cancelled } +#endif // wxUSE_GUI return encoding; } @@ -474,6 +534,8 @@ wxFontEncoding wxFontMapper::CharsetToEncoding(const wxString& charset, // correspond to which is used by GetFontForEncoding() function // ---------------------------------------------------------------------------- +#if wxUSE_GUI + bool wxFontMapper::TestAltEncoding(const wxString& configEntry, wxFontEncoding encReplacement, wxNativeEncodingInfo *info) @@ -481,6 +543,7 @@ bool wxFontMapper::TestAltEncoding(const wxString& configEntry, if ( wxGetNativeFontEncoding(encReplacement, info) && wxTestFontEncoding(*info) ) { +#if wxUSE_CONFIG // remember the mapping in the config wxFontMapperPathChanger path(this, FONTMAPPER_FONT_FROM_ENCODING_PATH); @@ -488,21 +551,76 @@ bool wxFontMapper::TestAltEncoding(const wxString& configEntry, { GetConfig()->Write(configEntry, info->ToString()); } - +#endif // wxUSE_CONFIG return TRUE; } return FALSE; } +#if wxUSE_GUI +class ReentrancyBlocker +{ +public: + ReentrancyBlocker(bool& b) : m_b(b) { m_b = TRUE; } + ~ReentrancyBlocker() { m_b = FALSE; } + +private: + bool& m_b; +}; +#endif + bool wxFontMapper::GetAltForEncoding(wxFontEncoding encoding, wxNativeEncodingInfo *info, + const wxString& facename, bool interactive) { - wxCHECK_MSG( info, FALSE, _T("bad pointer in GetAltForEncoding") ); +#if wxUSE_GUI + // we need a flag to prevent infinite recursion which happens, for + // example, when GetAltForEncoding() is called from an OnPaint() handler: + // in this case, wxYield() which is called from wxMessageBox() we use here + // will lead to another call of OnPaint() and hence to another call of + // GetAltForEncoding() - and it is impossible to catch this from the user + // code because we are called from wxFont ctor implicitly. + + // assume we're always called from the main thread, so that it is safe to + // use a static var + static bool s_inGetAltForEncoding = FALSE; + + if ( interactive && s_inGetAltForEncoding ) + return FALSE; + + ReentrancyBlocker blocker(s_inGetAltForEncoding); +#endif // wxUSE_GUI + + wxCHECK_MSG( info, FALSE, wxT("bad pointer in GetAltForEncoding") ); - wxString configEntry = GetEncodingName(encoding); + info->facename = facename; + if ( encoding == wxFONTENCODING_DEFAULT ) + { + encoding = wxFont::GetDefaultEncoding(); + } + + // if we failed to load the system default encoding, something is really + // wrong and we'd better stop now - otherwise we will go into endless + // recursion trying to create the font in the msg box with the error + // message + if ( encoding == wxFONTENCODING_SYSTEM ) + { + wxFatalError(_("can't load any font, aborting")); + + // wxFatalError doesn't return + } + + wxString configEntry, encName = GetEncodingName(encoding); + if ( !!facename ) + { + configEntry = facename + _T("_"); + } + configEntry += encName; + +#if wxUSE_CONFIG // do we have a font spec for this encoding? wxString pathOld; if ( ChangePath(FONTMAPPER_FONT_FROM_ENCODING_PATH, &pathOld) ) @@ -513,6 +631,12 @@ bool wxFontMapper::GetAltForEncoding(wxFontEncoding encoding, RestorePath(pathOld); + if ( !!fontinfo && !!facename ) + { + // we tried to find a match with facename - now try without it + fontinfo = config->Read(encName); + } + if ( !!fontinfo ) { if ( info->FromString(fontinfo) ) @@ -526,11 +650,12 @@ bool wxFontMapper::GetAltForEncoding(wxFontEncoding encoding, } else { - wxLogDebug(_T("corrupted config data: string '%s' is not " - "a valid font encoding info"), fontinfo.c_str()); + wxLogDebug(wxT("corrupted config data: string '%s' is not a valid font encoding info"), fontinfo.c_str()); } } + //else: there is no information in config about this encoding } +#endif // wxUSE_CONFIG // ask the user if ( interactive ) @@ -541,11 +666,7 @@ bool wxFontMapper::GetAltForEncoding(wxFontEncoding encoding, // the message wxString msg; - msg.Printf(_("The encoding '%s' is unknown.\n" - "Would you like to select a font to be used for this " - "encoding\n" - "(otherwise the text in this encoding will not be " - "shown correctly)?"), + msg.Printf(_("The encoding '%s' is unknown.\nWould you like to select a font to be used for this encoding\n(otherwise the text in this encoding will not be shown correctly)?"), GetEncodingDescription(encoding).c_str()); wxWindow *parent = m_windowParent; @@ -565,7 +686,9 @@ bool wxFontMapper::GetAltForEncoding(wxFontEncoding encoding, wxFont font = retData.GetChosenFont(); *info = retData.EncodingInfo(); + info->encoding = retData.GetEncoding(); +#if wxUSE_CONFIG // remember this in the config if ( ChangePath(FONTMAPPER_FONT_FROM_ENCODING_PATH, &pathOld) ) { @@ -573,6 +696,7 @@ bool wxFontMapper::GetAltForEncoding(wxFontEncoding encoding, RestorePath(pathOld); } +#endif return TRUE; } @@ -582,71 +706,44 @@ bool wxFontMapper::GetAltForEncoding(wxFontEncoding encoding, } //else: we're in non-interactive mode - // now try the default mappings - switch ( encoding ) + // now try the default mappings: + wxFontEncodingArray equiv = wxEncodingConverter::GetAllEquivalents(encoding); + size_t count = equiv.GetCount(); + if ( count ) { - case wxFONTENCODING_ISO8859_15: - // iso8859-15 is slightly modified iso8859-1 - if ( TestAltEncoding(configEntry, wxFONTENCODING_ISO8859_1, info) ) - return TRUE; - // fall through - - case wxFONTENCODING_ISO8859_1: - // iso8859-1 is identical to CP1252 - if ( TestAltEncoding(configEntry, wxFONTENCODING_CP1252, info) ) - return TRUE; - - break; - - case wxFONTENCODING_CP1252: - if ( TestAltEncoding(configEntry, wxFONTENCODING_ISO8859_1, info) ) - return TRUE; - - break; - - // iso8859-13 is quite similar to WinBaltic - case wxFONTENCODING_ISO8859_13: - if ( TestAltEncoding(configEntry, wxFONTENCODING_CP1257, info) ) - return TRUE; - - break; - - case wxFONTENCODING_CP1257: - if ( TestAltEncoding(configEntry, wxFONTENCODING_ISO8859_13, info) ) - return TRUE; - - break; - - // iso8859-8 is almost identical to WinHebrew - case wxFONTENCODING_ISO8859_8: - if ( TestAltEncoding(configEntry, wxFONTENCODING_CP1255, info) ) - return TRUE; - - break; - - case wxFONTENCODING_CP1255: - if ( TestAltEncoding(configEntry, wxFONTENCODING_ISO8859_8, info) ) - return TRUE; - - break; - - // and iso8859-7 is not too different from WinGreek - case wxFONTENCODING_ISO8859_7: - if ( TestAltEncoding(configEntry, wxFONTENCODING_CP1253, info) ) + for ( size_t i = (equiv[0] == encoding) ? 1 : 0; i < count; i++ ) + { + if ( TestAltEncoding(configEntry, equiv[i], info) ) return TRUE; + } + } - break; + return FALSE; +} - case wxFONTENCODING_CP1253: - if ( TestAltEncoding(configEntry, wxFONTENCODING_ISO8859_7, info) ) - return TRUE; +bool wxFontMapper::GetAltForEncoding(wxFontEncoding encoding, + wxFontEncoding *alt_encoding, + const wxString& facename, + bool interactive) +{ + wxNativeEncodingInfo info; + bool r = GetAltForEncoding(encoding, &info, facename, interactive); + *alt_encoding = info.encoding; + return r; +} - break; +bool wxFontMapper::IsEncodingAvailable(wxFontEncoding encoding, + const wxString& facename) +{ + wxNativeEncodingInfo info; - default: - // TODO add other mappings... - ; + if (wxGetNativeFontEncoding(encoding, &info)) + { + info.facename = facename; + return wxTestFontEncoding(info); } return FALSE; } + +#endif // wxUSE_GUI