--- wxGTK-2.4.2/src/common/fontmap.cpp.orig 2004-09-08 04:37:45.000000000 +0900 +++ wxGTK-2.4.2/src/common/fontmap.cpp 2004-09-09 02:06:40.000000000 +0900 @@ -536,6 +536,7 @@ encoding = wxFONTENCODING_SHIFT_JIS; } else if ( cs == wxT("EUC-JP") || + cs == wxT("EUCJP") || cs == wxT("EUC_JP") ) { encoding = wxFONTENCODING_EUC_JP; --- wxGTK-2.4.2/src/unix/fontutil.cpp.orig 2004-09-09 02:05:56.000000000 +0900 +++ wxGTK-2.4.2/src/unix/fontutil.cpp 2004-09-09 02:11:51.000000000 +0900 @@ -210,14 +210,29 @@ #include #include + #include + #include "wx/utils.h" // for wxGetDisplay() #endif - // ---------------------------------------------------------------------------- // private data // ---------------------------------------------------------------------------- +class wxXCachedSingleName : public wxObject +{ + wxString m_fontspec; + +public: + wxXCachedSingleName(const wxString& fontspec) : m_fontspec(fontspec) { } + ~wxXCachedSingleName() { } + operator wxString () const + { + return m_fontspec; + } +}; + static wxHashTable *g_fontHash = (wxHashTable*) NULL; +static wxHashTable *g_singleFontHash = (wxHashTable*) NULL; // ---------------------------------------------------------------------------- // private functions @@ -240,6 +255,11 @@ return gdk_font_load( wxConvertWX2MB(fontSpec) ); } + wxNativeFont wxLoadFontSet(const wxString& fontSpec) + { + return gdk_fontset_load( wxConvertWX2MB(fontSpec) ); + } + inline void wxFreeFont(wxNativeFont font) { gdk_font_unref(font); @@ -260,6 +280,15 @@ const wxString& xencoding, wxString* xFontName); +static bool wxTrySingleFont(int pointSize, + int family, + int style, + int weight, + bool WXUNUSED(underlined), + const wxString& facename, + const wxString& charset, + wxString* xFontname); + // ============================================================================ // implementation // ============================================================================ @@ -695,6 +724,11 @@ } break; + case wxFONTENCODING_EUC_JP: + info->xregistry = wxT(""); // XXX: "" means fontset + info->xencoding = wxT("iso8859-1,jisx0208.1990-0,jisx0208.1983-0,jisx0201.1976-0"); + break; + case wxFONTENCODING_SYSTEM: info->xregistry = info->xencoding = wxT("*"); @@ -713,6 +747,9 @@ bool wxTestFontEncoding(const wxNativeEncodingInfo& info) { wxString fontspec; + if ( info.xregistry.IsEmpty() ) + // XXX: fontset. + return true; fontspec.Printf(_T("-*-%s-*-*-*-*-*-*-*-*-*-*-%s-%s"), !info.facename ? _T("*") : info.facename.c_str(), info.xregistry.c_str(), @@ -725,6 +762,113 @@ // X-specific functions // ---------------------------------------------------------------------------- +static bool wxTryNearestSingleFont(int pointSize, + int family, + int style, + int weight, + bool underlined, + const wxString& facename, + const wxString& charset, + wxString* xFontName) +{ + bool found = false; + + // search up and down by stepsize 10 + int max_size = pointSize + 20 * (1 + (pointSize/180)); + int min_size = pointSize - 20 * (1 + (pointSize/180)); + + int i, round; // counters + + // first round: search for equal, then for smaller and for larger size with the given weight and style + int testweight = weight; + int teststyle = style; + + for ( round = 0; round < 3; round++ ) + { + // second round: use normal weight + if ( round == 1 ) + { + if ( testweight != wxNORMAL ) + { + testweight = wxNORMAL; + } + else + { + ++round; // fall through to third round + } + } + + // third round: ... and use normal style + if ( round == 2 ) + { + if ( teststyle != wxNORMAL ) + { + teststyle = wxNORMAL; + } + else + { + break; + } + } + // Search for equal or smaller size (approx.) + for ( i = pointSize; !found && i >= 10 && i >= min_size; i -= 10 ) + { + found = wxTrySingleFont(i, family, teststyle, testweight, + underlined, facename, charset, xFontName); + } + + // Search for larger size (approx.) + for ( i = pointSize + 10; !found && i <= max_size; i += 10 ) + { + found = wxTrySingleFont(i, family, teststyle, testweight, + underlined, facename, charset, xFontName); + } + } + + // Try default family + if ( !found && family != wxDEFAULT ) + { + found = wxTrySingleFont(pointSize, wxDEFAULT, style, weight, + underlined, facename, charset, xFontName); + } + + // ignore size, family, style and weight but try to find font with the + // given facename and encoding + if ( !found ) + { + found = wxTrySingleFont(120, wxDEFAULT, wxNORMAL, wxNORMAL, + underlined, facename, charset, xFontName); + + // ignore family as well + if ( !found ) + { + found = wxTrySingleFont(120, wxDEFAULT, wxNORMAL, wxNORMAL, + underlined, wxEmptyString, + charset, xFontName); + + // if it still failed, try to get the font of any size but + // with the requested encoding: this can happen if the + // encoding is only available in one size which happens to be + // different from 120 + if ( !found ) + { + found = wxTrySingleFont(-1, wxDEFAULT, wxNORMAL, wxNORMAL, + FALSE, wxEmptyString, + charset, xFontName); + + // this should never happen as we had tested for it in the + // very beginning, but if it does, do return something non + // NULL or we'd crash in wxFont code + if ( !found ) + { + wxFAIL_MSG( _T("charset should be available!") ); + } + } + } + } + return found; +} + wxNativeFont wxLoadQueryNearestFont(int pointSize, int family, int style, @@ -770,6 +914,32 @@ // OK, we have the correct xregistry/xencoding in info structure wxNativeFont font = 0; + if ( info.xregistry.IsEmpty() ) { + // fontset + wxStringTokenizer tokenizer(info.xencoding, _T(",")); + wxString fontSetName, singleFont, charset; + bool found; + + while (tokenizer.HasMoreTokens()) { + charset = tokenizer.GetNextToken(); + found = wxTryNearestSingleFont(pointSize, family, style, weight, + underlined, facename, charset, + &singleFont); + if (found) { + if (!fontSetName.IsEmpty()) + fontSetName += _T(','); + fontSetName += singleFont; + } + } + wxNativeFont nf; + nf = wxLoadFontSet(fontSetName); + gdk_font_ref(nf); // XXX: cached permanently. + if (xFontName) + *xFontName = fontSetName; + + return nf; + } + // if we already have the X font name, try to use it if( xFontName && !xFontName->IsEmpty() ) { @@ -944,6 +1114,37 @@ } } +static bool wxFindSingleFont(const wxString& fontSpec, + wxString* fontFound) +{ + char **font_names; + int count; + wxXCachedSingleName *cached; + + cached = (wxXCachedSingleName *)g_singleFontHash->Get(fontSpec); + if (cached) { + if (((wxString)*cached).IsEmpty()) + return FALSE; + if (fontFound) + *fontFound = (wxString)*cached; + return TRUE; + } + font_names = XListFonts((Display *)wxGetDisplay(), + fontSpec.c_str(), + 1, &count); + if (font_names) + { + g_singleFontHash->Put(fontSpec, + (wxObject *)new wxXCachedSingleName(font_names[0])); + if (fontFound) + *fontFound = font_names[0]; + XFreeFontNames(font_names); + return TRUE; + } + g_singleFontHash->Put(fontSpec, (wxObject *)new wxXCachedSingleName("")); + return FALSE; +} + static wxNativeFont wxLoadQueryFont(int pointSize, int family, int style, @@ -1215,6 +1416,203 @@ // wxUSE_NANOX } +static bool wxTrySingleFont(int pointSize, + int family, + int style, + int weight, + bool WXUNUSED(underlined), + const wxString& facename, + const wxString& charset, + wxString* xFontName) +{ + wxString xfamily; + switch (family) + { + case wxDECORATIVE: xfamily = wxT("lucida"); break; + case wxROMAN: xfamily = wxT("times"); break; + case wxMODERN: xfamily = wxT("courier"); break; + case wxSWISS: xfamily = wxT("helvetica"); break; + case wxTELETYPE: xfamily = wxT("lucidatypewriter"); break; + case wxSCRIPT: xfamily = wxT("utopia"); break; + default: xfamily = wxT("*"); + } +#if wxUSE_NANOX +#else // GTK+1 + wxString fontSpec; + if (!facename.IsEmpty()) + { + fontSpec.Printf(wxT("-*-%s-*-*-normal-*-*-*-*-*-*-*-%s"), + facename.c_str(), charset.c_str()); + + if ( wxFindSingleFont(fontSpec, NULL) ) + { + xfamily = facename; + } + //else: no such family, use default one instead + } + + wxString xstyle; + switch (style) + { + case wxSLANT: + fontSpec.Printf(wxT("-*-%s-*-o-*-*-*-*-*-*-*-*-%s"), + xfamily.c_str(), charset.c_str()); + if ( wxFindSingleFont(fontSpec, NULL) ) + { + xstyle = wxT("o"); + break; + } + // fall through - try wxITALIC now + + case wxITALIC: + fontSpec.Printf(wxT("-*-%s-*-i-*-*-*-*-*-*-*-*-%s"), + xfamily.c_str(), charset.c_str()); + if ( wxFindSingleFont(fontSpec, NULL) ) + { + xstyle = wxT("i"); + } + else if ( style == wxITALIC ) // and not wxSLANT + { + // try wxSLANT + fontSpec.Printf(wxT("-*-%s-*-o-*-*-*-*-*-*-*-*-%s"), + xfamily.c_str(), charset.c_str()); + if ( wxFindSingleFont(fontSpec, NULL) ) + { + 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; + switch (weight) + { + case wxBOLD: + { + fontSpec.Printf(wxT("-*-%s-bold-*-*-*-*-*-*-*-*-*-%s"), + xfamily.c_str(), charset.c_str()); + if ( wxFindSingleFont(fontSpec, NULL) ) + { + xweight = wxT("bold"); + break; + } + fontSpec.Printf(wxT("-*-%s-heavy-*-*-*-*-*-*-*-*-*-%s"), + xfamily.c_str(), charset.c_str()); + if ( wxFindSingleFont(fontSpec, NULL) ) + { + xweight = wxT("heavy"); + break; + } + fontSpec.Printf(wxT("-*-%s-extrabold-*-*-*-*-*-*-*-*-*-%s"), + xfamily.c_str(), charset.c_str()); + if ( wxFindSingleFont(fontSpec, NULL) ) + { + xweight = wxT("extrabold"); + break; + } + fontSpec.Printf(wxT("-*-%s-demibold-*-*-*-*-*-*-*-*-*-%s"), + xfamily.c_str(), charset.c_str()); + if ( wxFindSingleFont(fontSpec, NULL) ) + { + xweight = wxT("demibold"); + break; + } + fontSpec.Printf(wxT("-*-%s-black-*-*-*-*-*-*-*-*-*-%s"), + xfamily.c_str(), charset.c_str()); + if ( wxFindSingleFont(fontSpec, NULL) ) + { + xweight = wxT("black"); + break; + } + fontSpec.Printf(wxT("-*-%s-ultrablack-*-*-*-*-*-*-*-*-*-%s"), + xfamily.c_str(), charset.c_str()); + if ( wxFindSingleFont(fontSpec, NULL) ) + { + xweight = wxT("ultrablack"); + break; + } + } + break; + case wxLIGHT: + { + fontSpec.Printf(wxT("-*-%s-light-*-*-*-*-*-*-*-*-*-%s"), + xfamily.c_str(), charset.c_str()); + if ( wxFindSingleFont(fontSpec, NULL) ) + { + xweight = wxT("light"); + break; + } + fontSpec.Printf(wxT("-*-%s-thin-*-*-*-*-*-*-*-*-*-%s"), + xfamily.c_str(), charset.c_str()); + if ( wxFindSingleFont(fontSpec, NULL) ) + { + xweight = wxT("thin"); + break; + } + } + break; + case wxNORMAL: + { + fontSpec.Printf(wxT("-*-%s-medium-*-*-*-*-*-*-*-*-*-%s"), + xfamily.c_str(), charset.c_str()); + if ( wxFindSingleFont(fontSpec, NULL) ) + { + xweight = wxT("medium"); + break; + } + fontSpec.Printf(wxT("-*-%s-normal-*-*-*-*-*-*-*-*-*-%s"), + xfamily.c_str(), charset.c_str()); + if ( wxFindSingleFont(fontSpec, NULL) ) + { + xweight = wxT("normal"); + break; + } + fontSpec.Printf(wxT("-*-%s-regular-*-*-*-*-*-*-*-*-*-%s"), + xfamily.c_str(), charset.c_str()); + if ( wxFindSingleFont(fontSpec, NULL) ) + { + xweight = wxT("regular"); + break; + } + xweight = wxT("*"); + } + break; + default: xweight = wxT("*"); break; + } + + // if pointSize is -1, don't specify any + wxString sizeSpec; + if ( pointSize == -1 ) + { + sizeSpec = _T('*'); + } + else + { + sizeSpec.Printf(_T("%d"), pointSize); + } + + // construct the X font spec from our data + fontSpec.Printf(wxT("-*-%s-%s-%s-normal-*-*-%s-*-*-*-*-%s"), + xfamily.c_str(), xweight.c_str(), xstyle.c_str(), + sizeSpec.c_str(), charset.c_str()); + + return wxFindSingleFont(fontSpec, xFontName); +#endif +} + // ---------------------------------------------------------------------------- // wxFontModule // ---------------------------------------------------------------------------- @@ -1234,6 +1632,7 @@ bool wxFontModule::OnInit() { g_fontHash = new wxHashTable( wxKEY_STRING ); + g_singleFontHash = new wxHashTable( wxKEY_STRING ); return TRUE; } @@ -1241,8 +1640,10 @@ void wxFontModule::OnExit() { delete g_fontHash; + delete g_singleFontHash; g_fontHash = (wxHashTable *)NULL; + g_singleFontHash = (wxHashTable *)NULL; } #endif // GTK 2.0/1.x --- wxGTK-2.4.2/src/gtk/tooltip.cpp.orig 2004-09-09 02:06:53.000000000 +0900 +++ wxGTK-2.4.2/src/gtk/tooltip.cpp 2004-09-09 02:22:05.000000000 +0900 @@ -76,6 +76,8 @@ g_style->fg[GTK_STATE_NORMAL] = ss_fg; g_style->bg[GTK_STATE_NORMAL] = ss_bg; + g_style->font = GtkGetDefaultGuiFont(); + gtk_widget_set_style( ss_tooltips->tip_window, g_style ); #else // GTK+ 1.0 gtk_tooltips_set_colors( ss_tooltips, &ss_bg, &ss_fg );