X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/7beba2fc73283f5b750227459da57e66bcd475f5..ccb220600d4a0cda7ecfc89269532476fe570c3c:/src/unix/fontutil.cpp diff --git a/src/unix/fontutil.cpp b/src/unix/fontutil.cpp index c32a5acfbb..3b3444b4ab 100644 --- a/src/unix/fontutil.cpp +++ b/src/unix/fontutil.cpp @@ -31,9 +31,39 @@ #ifndef WX_PRECOMP #endif // PCH +#ifdef __X__ + #ifdef __VMS__ + #pragma message disable nosimpint + #endif + + #include + + #ifdef __VMS__ + #pragma message enable nosimpint + #endif + + #include "wx/utils.h" // for wxGetDisplay() +#elif defined(__WXGTK__) + // we have to declare struct tm to avoid problems with first forward + // declaring it in C code (glib.h included from gdk.h does it) and then + // defining it when time.h is included from the headers below - this is + // known not to work at least with Sun CC 6.01 + #include + + #include +#endif + #include "wx/fontutil.h" #include "wx/fontmap.h" #include "wx/tokenzr.h" +#include "wx/hash.h" +#include "wx/module.h" + +// ---------------------------------------------------------------------------- +// private data +// ---------------------------------------------------------------------------- + +static wxHashTable *g_fontHash = (wxHashTable*) NULL; // ---------------------------------------------------------------------------- // private functions @@ -48,14 +78,12 @@ static inline void wxFreeFont(wxNativeFont font) { - XFreeFont((Display *)wxGetDisplay(), font); + XFreeFont((Display *)wxGetDisplay(), (XFontStruct *)font); } #elif defined(__WXGTK__) - #include "gdk/gdk.h" - static inline wxNativeFont wxLoadFont(const wxString& fontSpec) { - return gdk_font_load( wxConvertWX2MB(fontSpec) ); + return gdk_font_load( wxConvertWX2MB(fontSpec) ); } static inline void wxFreeFont(wxNativeFont font) @@ -75,7 +103,8 @@ static wxNativeFont wxLoadQueryFont(int pointSize, bool underlined, const wxString& facename, const wxString& xregistry, - const wxString& xencoding); + const wxString& xencoding, + wxString* xFontName); // ============================================================================ // implementation @@ -86,10 +115,17 @@ static wxNativeFont wxLoadQueryFont(int pointSize, // ---------------------------------------------------------------------------- // convert to/from the string representation: format is -// registry-encoding[-facename] +// encodingid;registry;encoding[;facename] bool wxNativeEncodingInfo::FromString(const wxString& s) { - wxStringTokenizer tokenizer(s, _T("-")); + // use ";", not "-" because it may be part of encoding name + wxStringTokenizer tokenizer(s, _T(";")); + + wxString encid = tokenizer.GetNextToken(); + long enc; + if ( !encid.ToLong(&enc) ) + return FALSE; + encoding = (wxFontEncoding)enc; xregistry = tokenizer.GetNextToken(); if ( !xregistry ) @@ -108,10 +144,10 @@ bool wxNativeEncodingInfo::FromString(const wxString& s) wxString wxNativeEncodingInfo::ToString() const { wxString s; - s << xregistry << _T('-') << xencoding; + s << (long)encoding << _T(';') << xregistry << _T(';') << xencoding; if ( !!facename ) { - s << _T('-') << facename; + s << _T(';') << facename; } return s; @@ -144,6 +180,7 @@ bool wxGetNativeFontEncoding(wxFontEncoding encoding, case wxFONTENCODING_ISO8859_9: case wxFONTENCODING_ISO8859_10: case wxFONTENCODING_ISO8859_11: + case wxFONTENCODING_ISO8859_12: case wxFONTENCODING_ISO8859_13: case wxFONTENCODING_ISO8859_14: case wxFONTENCODING_ISO8859_15: @@ -154,6 +191,13 @@ bool wxGetNativeFontEncoding(wxFontEncoding encoding, } break; + case wxFONTENCODING_UTF8: + // FIXME: this is probably false, but this is how they are called on + // my system and I don't know what the standard XFLD is (VZ) + info->xregistry = wxT("iso646.1991"); + info->xencoding = wxT("*"); + break; + case wxFONTENCODING_KOI8: info->xregistry = wxT("koi8"); @@ -178,7 +222,7 @@ bool wxGetNativeFontEncoding(wxFontEncoding encoding, case wxFONTENCODING_SYSTEM: info->xregistry = - info->xencoding = wxT('*'); + info->xencoding = wxT("*"); break; default: @@ -186,6 +230,8 @@ bool wxGetNativeFontEncoding(wxFontEncoding encoding, return FALSE; } + info->encoding = encoding; + return TRUE; } @@ -210,30 +256,73 @@ wxNativeFont wxLoadQueryNearestFont(int pointSize, int weight, bool underlined, const wxString &facename, - wxFontEncoding encoding) + wxFontEncoding encoding, + wxString* xFontName) { + if ( encoding == wxFONTENCODING_DEFAULT ) + { + encoding = wxFont::GetDefaultEncoding(); + } + // first determine the encoding - if the font doesn't exist at all in this // encoding, it's useless to do all other approximations (i.e. size, // family &c don't matter much) wxNativeEncodingInfo info; - if ( !wxGetNativeFontEncoding(encoding, &info) || - !wxTestFontEncoding(info) ) + if ( encoding == wxFONTENCODING_SYSTEM ) { - if ( !wxTheFontMapper->GetAltForEncoding(encoding, &info) ) + // This will always work so we don't test to save time + wxGetNativeFontEncoding(wxFONTENCODING_SYSTEM, &info); + } + else + { + if ( !wxGetNativeFontEncoding(encoding, &info) || + !wxTestFontEncoding(info) ) { - // unspported encoding - replace it with the default - // - // NB: we can't just return 0 from here because wxGTK code doesn't - // check for it (i.e. it supposes that we'll always succeed), - // so it would provoke a crash - wxGetNativeFontEncoding(wxFONTENCODING_SYSTEM, &info); + if ( !wxTheFontMapper->GetAltForEncoding(encoding, &info) ) + { + // unspported encoding - replace it with the default + // + // NB: we can't just return 0 from here because wxGTK code doesn't + // check for it (i.e. it supposes that we'll always succeed), + // so it would provoke a crash + wxGetNativeFontEncoding(wxFONTENCODING_SYSTEM, &info); + } } } - //else: we have the correct xregistry/xencoding in info structure - wxNativeFont font = wxLoadQueryFont( pointSize, family, style, weight, + // OK, we have the correct xregistry/xencoding in info structure + wxNativeFont font = 0; + + // if we already have the X font name, try to use it + if( xFontName && !xFontName->IsEmpty() ) + { + // + // Make sure point size is correct for scale factor. + // + wxStringTokenizer tokenizer(*xFontName, _T("-"), wxTOKEN_RET_DELIMS); + wxString newFontName; + + for(int i = 0; i < 8; i++) + newFontName += tokenizer.NextToken(); + + (void) tokenizer.NextToken(); + + newFontName += wxString::Format("%d-", pointSize); + + while(tokenizer.HasMoreTokens()) + newFontName += tokenizer.GetNextToken(); + + font = wxLoadFont(newFontName); + + if(font) + *xFontName = newFontName; + } + + if( !font ) + font = wxLoadQueryFont( pointSize, family, style, weight, underlined, facename, - info.xregistry, info.xencoding ); + info.xregistry, info.xencoding, + xFontName ); if ( !font ) { @@ -247,14 +336,16 @@ wxNativeFont wxLoadQueryNearestFont(int pointSize, for ( i = pointSize - 10; !font && i >= 10 && i >= min_size; i -= 10 ) { font = wxLoadQueryFont(i, family, style, weight, underlined, - facename, info.xregistry, info.xencoding); + facename, info.xregistry, info.xencoding, + xFontName); } // Search for larger size (approx.) for ( i = pointSize + 10; !font && i <= max_size; i += 10 ) { font = wxLoadQueryFont(i, family, style, weight, underlined, - facename, info.xregistry, info.xencoding); + facename, info.xregistry, info.xencoding, + xFontName); } // Try default family @@ -262,7 +353,8 @@ wxNativeFont wxLoadQueryNearestFont(int pointSize, { font = wxLoadQueryFont(pointSize, wxDEFAULT, style, weight, underlined, facename, - info.xregistry, info.xencoding ); + info.xregistry, info.xencoding, + xFontName ); } // Bogus font I @@ -270,7 +362,8 @@ wxNativeFont wxLoadQueryNearestFont(int pointSize, { font = wxLoadQueryFont(120, wxDEFAULT, wxNORMAL, wxNORMAL, underlined, facename, - info.xregistry, info.xencoding); + info.xregistry, info.xencoding, + xFontName); } // Bogus font II @@ -278,7 +371,8 @@ wxNativeFont wxLoadQueryNearestFont(int pointSize, { font = wxLoadQueryFont(120, wxDEFAULT, wxNORMAL, wxNORMAL, underlined, wxEmptyString, - info.xregistry, info.xencoding); + info.xregistry, info.xencoding, + xFontName); } } @@ -292,7 +386,22 @@ wxNativeFont wxLoadQueryNearestFont(int pointSize, // returns TRUE if there are any fonts matching this font spec static bool wxTestFontSpec(const wxString& fontspec) { - wxNativeFont test = wxLoadFont(fontspec); + // some X servers will fail to load this font because there are too many + // matches so we must test explicitly for this + if ( fontspec == _T("-*-*-*-*-*-*-*-*-*-*-*-*-*-*") ) + { + return TRUE; + } + + wxNativeFont test = (wxNativeFont) g_fontHash->Get( fontspec ); + if (test) + { + return TRUE; + } + + test = wxLoadFont(fontspec); + g_fontHash->Put( fontspec, (wxObject*) test ); + if ( test ) { wxFreeFont(test); @@ -312,7 +421,8 @@ static wxNativeFont wxLoadQueryFont(int pointSize, bool WXUNUSED(underlined), const wxString& facename, const wxString& xregistry, - const wxString& xencoding) + const wxString& xencoding, + wxString* xFontName) { wxString xfamily; switch (family) @@ -342,10 +452,47 @@ static wxNativeFont wxLoadQueryFont(int pointSize, wxString xstyle; switch (style) { - case wxITALIC: xstyle = wxT("i"); break; - case wxSLANT: xstyle = wxT("o"); break; - case wxNORMAL: xstyle = wxT("r"); break; - default: xstyle = wxT("*"); break; + case wxSLANT: + fontSpec.Printf(wxT("-*-%s-*-o-*-*-*-*-*-*-*-*-*-*"), + xfamily.c_str()); + if ( wxTestFontSpec(fontSpec) ) + { + xstyle = wxT("o"); + break; + } + // fall through - try wxITALIC now + + case wxITALIC: + fontSpec.Printf(wxT("-*-%s-*-i-*-*-*-*-*-*-*-*-*-*"), + xfamily.c_str()); + if ( wxTestFontSpec(fontSpec) ) + { + xstyle = wxT("i"); + } + else if ( style == wxITALIC ) // and not wxSLANT + { + // try wxSLANT + fontSpec.Printf(wxT("-*-%s-*-o-*-*-*-*-*-*-*-*-*-*"), + xfamily.c_str()); + if ( wxTestFontSpec(fontSpec) ) + { + xstyle = wxT("o"); + } + else + { + // no italic, no slant - leave default + xstyle = wxT("*"); + } + } + break; + + default: + wxFAIL_MSG(_T("unknown font style")); + // fall back to normal + + case wxNORMAL: + xstyle = wxT("r"); + break; } wxString xweight; @@ -449,6 +596,38 @@ static wxNativeFont wxLoadQueryFont(int pointSize, xfamily.c_str(), xweight.c_str(), xstyle.c_str(), pointSize, xregistry.c_str(), xencoding.c_str()); + if( xFontName ) + *xFontName = fontSpec; + return wxLoadFont(fontSpec); } +// ---------------------------------------------------------------------------- +// wxFontModule +// ---------------------------------------------------------------------------- + +class wxFontModule : public wxModule +{ +public: + bool OnInit(); + void OnExit(); + +private: + DECLARE_DYNAMIC_CLASS(wxFontModule) +}; + +IMPLEMENT_DYNAMIC_CLASS(wxFontModule, wxModule) + +bool wxFontModule::OnInit() +{ + g_fontHash = new wxHashTable( wxKEY_STRING ); + + return TRUE; +} + +void wxFontModule::OnExit() +{ + delete g_fontHash; + + g_fontHash = (wxHashTable *)NULL; +}