From: Vadim Zeitlin Date: Fri, 5 Nov 1999 19:03:19 +0000 (+0000) Subject: 1. wxFontMapper almost finished X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/7beba2fc73283f5b750227459da57e66bcd475f5 1. wxFontMapper almost finished 2. font helper functions are now in separate files, not utilsunx.cpp git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@4376 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/distrib/msw/tmake/filelist.txt b/distrib/msw/tmake/filelist.txt index f79577b449..69562695d1 100644 --- a/distrib/msw/tmake/filelist.txt +++ b/distrib/msw/tmake/filelist.txt @@ -481,6 +481,7 @@ filedlg.h W filefn.h W filesys.h W font.h W +fontdlg.h W fontenum.h W fontmap.h W fontdlg.h W @@ -846,6 +847,7 @@ xpmhand.h 9 # disable.bmp 9 # wx.rc 9 +fontutil.h S execute.h S file.h P diff --git a/include/wx/app.h b/include/wx/app.h index bbec49fe08..ef73b134cf 100644 --- a/include/wx/app.h +++ b/include/wx/app.h @@ -100,7 +100,7 @@ public: // value of this method. // // Override: often. - virtual int OnExit() { return 0; } + virtual int OnExit(); // called when a fatal exception occurs, this function should take care // not to do anything which might provoke a nested exception! It may be diff --git a/include/wx/cmndata.h b/include/wx/cmndata.h index 82768cc4e3..408d3827b1 100644 --- a/include/wx/cmndata.h +++ b/include/wx/cmndata.h @@ -18,6 +18,7 @@ #include "wx/window.h" #include "wx/font.h" +#include "wx/fontutil.h" #include "wx/colour.h" #include "wx/gdicmn.h" @@ -55,7 +56,6 @@ class WXDLLEXPORT wxFontData: public wxObject DECLARE_DYNAMIC_CLASS(wxFontData) public: wxFontData(); - wxFontData(const wxFontData& fontData); ~wxFontData(); void SetAllowSymbols(bool flag) { allowSymbols = flag; } @@ -78,7 +78,13 @@ public: void SetRange(int minRange, int maxRange) { minSize = minRange; maxSize = maxRange; } - void operator=(const wxFontData& data); + // encoding info is split into 2 parts: the logical wxWin encoding + // (wxFontEncoding) and a structure containing the native parameters for + // it (wxNativeEncodingInfo) + wxFontEncoding GetEncoding() const { return m_encoding; } + void SetEncoding(wxFontEncoding encoding) { m_encoding = encoding; } + + wxNativeEncodingInfo& EncodingInfo() { return m_encodingInfo; } public: wxColour fontColour; @@ -89,6 +95,10 @@ public: wxFont chosenFont; int minSize; int maxSize; + +private: + wxFontEncoding m_encoding; + wxNativeEncodingInfo m_encodingInfo; }; #if wxUSE_PRINTING_ARCHITECTURE diff --git a/include/wx/font.h b/include/wx/font.h index 4e5a3a5404..cf30f6585d 100644 --- a/include/wx/font.h +++ b/include/wx/font.h @@ -27,6 +27,7 @@ // forward declarations // ---------------------------------------------------------------------------- +class WXDLLEXPORT wxFontData; class WXDLLEXPORT wxFontBase; class WXDLLEXPORT wxFont; diff --git a/include/wx/fontenum.h b/include/wx/fontenum.h index b6af566bb6..5b82956ddd 100644 --- a/include/wx/fontenum.h +++ b/include/wx/fontenum.h @@ -17,6 +17,8 @@ #pragma interface "fontenum.h" #endif +#include "wx/font.h" + // ---------------------------------------------------------------------------- // wxFontEnumerator enumerates all available fonts on the system or only the // fonts with given attributes diff --git a/include/wx/fontmap.h b/include/wx/fontmap.h index 7c2ee4ba85..0b86555b00 100644 --- a/include/wx/fontmap.h +++ b/include/wx/fontmap.h @@ -20,9 +20,8 @@ // headers // ---------------------------------------------------------------------------- -#include "wx/defs.h" // for wxDEFAULT &c - -#include "wx/font.h" // for wxFontEncoding +#include "wx/font.h" // for wxFont and wxFontEncoding +#include "wx/fontutil.h" // for wxNativeEncodingInfo class WXDLLEXPORT wxConfigBase; @@ -49,14 +48,38 @@ public: // virtual dtor for a base class virtual ~wxFontMapper(); + // find an alternative for the given encoding (which is supposed to not be + // available on this system). If successful, return TRUE and fill info + // structure with the parameters required to create the font, otherwise + // return FALSE + virtual bool GetAltForEncoding(wxFontEncoding encoding, + wxNativeEncodingInfo *info, + bool interactive = TRUE); + // returns the encoding for the given charset (in the form of RFC 2046) or // wxFONTENCODING_SYSTEM if couldn't decode it virtual wxFontEncoding CharsetToEncoding(const wxString& charset, bool interactive = TRUE); + // encoding names + // -------------- + + // return internal string identifier for the encoding (see also + // GetEncodingDescription()) + static wxString GetEncodingName(wxFontEncoding encoding); + + // return user-readable string describing the given encoding + // + // NB: hard-coded now, but might change later (read it from config?) + static wxString GetEncodingDescription(wxFontEncoding encoding); + // configure the appearance of the dialogs we may popup // ---------------------------------------------------- + // the parent window for modal dialogs + void SetDialogParent(wxWindow *parent) { m_windowParent = parent; } + + // the title for the dialogs (note that default is quite reasonable) void SetDialogTitle(const wxString& title) { m_titleDialog = title; } // functions which allow to configure the config object used: by default, @@ -94,6 +117,17 @@ protected: // restore the config path after use void RestorePath(const wxString& pathOld); + // GetAltForEncoding() helper: tests for the existence of the given + // encoding and saves the result in config if ok - this results in the + // following (desired) behaviour: when an unknown/unavailable encoding is + // requested for the first time, the user is asked about a replacement, + // but if he doesn't choose any and the default logic finds one, it will + // be saved in the config so that the user won't be asked about it any + // more + bool TestAltEncoding(const wxString& configEntry, + wxFontEncoding encReplacement, + wxNativeEncodingInfo *info); + // config object and path (in it) to use wxConfigBase *m_config; wxString m_configRootPath; @@ -103,6 +137,15 @@ protected: // the parent window for our dialogs wxWindow *m_windowParent; + + friend class wxFontMapperPathChanger; }; +// ---------------------------------------------------------------------------- +// global variables +// ---------------------------------------------------------------------------- + +// the default font mapper for wxWindows programs +WXDLLEXPORT_DATA(extern wxFontMapper *) wxTheFontMapper; + #endif // _WX_FONTMAPPER_H_ diff --git a/include/wx/fontutil.h b/include/wx/fontutil.h new file mode 100644 index 0000000000..a6b149d018 --- /dev/null +++ b/include/wx/fontutil.h @@ -0,0 +1,93 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: wx/fontutil.h +// Purpose: font-related helper functions +// Author: Vadim Zeitlin +// Modified by: +// Created: 05.11.99 +// RCS-ID: $Id$ +// Copyright: (c) wxWindows team +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +// General note: this header is private to wxWindows and is not supposed to be +// included by user code. The functions declared here are implemented in +// msw/fontutil.cpp for Windows, unix/fontutil.cpp for GTK/Motif &c. + +#ifndef _WX_FONTUTIL_H_ +#define _WX_FONTUTIL_H_ + +#ifdef __GNUG__ + #pragma interface "fontutil.h" +#endif + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + +#include "wx/font.h" // for wxFont and wxFontEncoding + +// for our purposes here, GDK and X are identical +#if defined(__WXGTK__) || defined(__X__) + #define _WX_X_FONTLIKE +#endif + +// ---------------------------------------------------------------------------- +// types +// ---------------------------------------------------------------------------- + +// This private structure specifies all the parameters needed to create a font +// with the given encoding on this platform. +// +// Under X, it contains the last 2 elements of the font specifications +// (registry and encoding). +// +// Under Windows, it contains a number which is one of predefined CHARSET_XXX +// values. +// +// Under all platforms it also contains a facename string which should be +// used, if not empty, to create fonts in this encoding (this is the only way +// to create a font of non-standard encoding (like KOI8) under Windows - the +// facename specifies the encoding then) + +struct wxNativeEncodingInfo +{ + wxString facename; // may be empty meaning "any" + +#if defined(__WXMSW__) + int charset; +#elif defined(_WX_X_FONTLIKE) + wxString xregistry, + xencoding; +#else + #error "Unsupported toolkit" +#endif + + // this struct is saved in config by wxFontMapper, so it should know to + // serialise itself (implemented in platform-specific code) + bool FromString(const wxString& s); + wxString ToString() const; +}; + +// ---------------------------------------------------------------------------- +// font-related functions (common) +// ---------------------------------------------------------------------------- + +// translate a wxFontEncoding into native encoding parameter (defined above), +// returning TRUE if an (exact) macth could be found, FALSE otherwise (without +// attempting any substitutions) +extern bool wxGetNativeFontEncoding(wxFontEncoding encoding, + wxNativeEncodingInfo *info); + +// test for the existence of the font described by this facename/encoding, +// return TRUE if such font(s) exist, FALSE otherwise +extern bool wxTestFontEncoding(const wxNativeEncodingInfo& info); + +// ---------------------------------------------------------------------------- +// font-related functions (X and GTK) +// ---------------------------------------------------------------------------- + +#ifdef _WX_X_FONTLIKE + #include "wx/unix/fontutil.h" +#endif // X || GDK + +#endif // _WX_FONTUTIL_H_ diff --git a/include/wx/gtk/font.h b/include/wx/gtk/font.h index 54e6d5da15..c3885bfa26 100644 --- a/include/wx/gtk/font.h +++ b/include/wx/gtk/font.h @@ -14,11 +14,7 @@ #pragma interface #endif -#include "wx/defs.h" -#include "wx/object.h" -#include "wx/string.h" #include "wx/hash.h" -#include "wx/gdiobj.h" // ---------------------------------------------------------------------------- // classes @@ -30,12 +26,6 @@ class wxWindow; class wxFont; -// ---------------------------------------------------------------------------- -// global variables -// ---------------------------------------------------------------------------- - -extern const wxChar* wxEmptyString; - // ---------------------------------------------------------------------------- // wxFont // ---------------------------------------------------------------------------- @@ -46,6 +36,7 @@ public: // ctors and such wxFont() { Init(); } wxFont(const wxFont& font) { Init(); Ref(font); } + wxFont(const wxString& fontname, const wxFontData& fontdata); // assignment wxFont& operator=(const wxFont& font); @@ -91,7 +82,6 @@ public: virtual void SetEncoding(wxFontEncoding encoding); // implementation from now on - wxFont( GdkFont* font, char *xFontName ); void Unshare(); GdkFont* GetInternalFont(float scale = 1.0) const; diff --git a/include/wx/gtk/fontdlg.h b/include/wx/gtk/fontdlg.h index 2d47916288..d6f157bc71 100644 --- a/include/wx/gtk/fontdlg.h +++ b/include/wx/gtk/fontdlg.h @@ -2,10 +2,10 @@ // Name: fontdlgg.h // Purpose: wxFontDialog // Author: Robert Roebling -// Created: +// Created: // RCS-ID: $Id$ // Copyright: (c) Robert Roebling -// Licence: wxWindows licence +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// #ifndef __GTK_FONTDLGH__ @@ -38,7 +38,7 @@ public: wxFontDialog( wxWindow *parent, wxFontData *data = (wxFontData *) NULL ); ~wxFontDialog(); - inline wxFontData& GetFontData() { return m_fontData; } + wxFontData& GetFontData() { return m_fontData; } //protected: wxFontData m_fontData; diff --git a/include/wx/gtk1/font.h b/include/wx/gtk1/font.h index 54e6d5da15..c3885bfa26 100644 --- a/include/wx/gtk1/font.h +++ b/include/wx/gtk1/font.h @@ -14,11 +14,7 @@ #pragma interface #endif -#include "wx/defs.h" -#include "wx/object.h" -#include "wx/string.h" #include "wx/hash.h" -#include "wx/gdiobj.h" // ---------------------------------------------------------------------------- // classes @@ -30,12 +26,6 @@ class wxWindow; class wxFont; -// ---------------------------------------------------------------------------- -// global variables -// ---------------------------------------------------------------------------- - -extern const wxChar* wxEmptyString; - // ---------------------------------------------------------------------------- // wxFont // ---------------------------------------------------------------------------- @@ -46,6 +36,7 @@ public: // ctors and such wxFont() { Init(); } wxFont(const wxFont& font) { Init(); Ref(font); } + wxFont(const wxString& fontname, const wxFontData& fontdata); // assignment wxFont& operator=(const wxFont& font); @@ -91,7 +82,6 @@ public: virtual void SetEncoding(wxFontEncoding encoding); // implementation from now on - wxFont( GdkFont* font, char *xFontName ); void Unshare(); GdkFont* GetInternalFont(float scale = 1.0) const; diff --git a/include/wx/gtk1/fontdlg.h b/include/wx/gtk1/fontdlg.h index 2d47916288..d6f157bc71 100644 --- a/include/wx/gtk1/fontdlg.h +++ b/include/wx/gtk1/fontdlg.h @@ -2,10 +2,10 @@ // Name: fontdlgg.h // Purpose: wxFontDialog // Author: Robert Roebling -// Created: +// Created: // RCS-ID: $Id$ // Copyright: (c) Robert Roebling -// Licence: wxWindows licence +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// #ifndef __GTK_FONTDLGH__ @@ -38,7 +38,7 @@ public: wxFontDialog( wxWindow *parent, wxFontData *data = (wxFontData *) NULL ); ~wxFontDialog(); - inline wxFontData& GetFontData() { return m_fontData; } + wxFontData& GetFontData() { return m_fontData; } //protected: wxFontData m_fontData; diff --git a/include/wx/unix/fontutil.h b/include/wx/unix/fontutil.h new file mode 100644 index 0000000000..6161a38e0f --- /dev/null +++ b/include/wx/unix/fontutil.h @@ -0,0 +1,32 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: wx/unix/fontutil.h +// Purpose: font-related helper functions for Unix/X11 +// Author: Vadim Zeitlin +// Modified by: +// Created: 05.11.99 +// RCS-ID: $Id$ +// Copyright: (c) wxWindows team +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_UNIX_FONTUTIL_H_ +#define _WX_UNIX_FONTUTIL_H_ + +#ifdef __X__ + typedef XFontStruct *wxNativeFont; +#elif defined(__WXGTK__) + typedef GdkFont *wxNativeFont; +#else + #error "Unsupported toolkit" +#endif + +// returns the handle of the nearest available font or 0 +extern wxNativeFont wxLoadQueryNearestFont(int pointSize, + int family, + int style, + int weight, + bool underlined, + const wxString &facename, + wxFontEncoding encoding); + +#endif // _WX_UNIX_FONTUTIL_H_ diff --git a/include/wx/utils.h b/include/wx/utils.h index 08e4575b57..312d644557 100644 --- a/include/wx/utils.h +++ b/include/wx/utils.h @@ -377,38 +377,6 @@ void wxAllocColor(Display *display,Colormap colormap,XColor *xcolor); #endif //__X__ -// ---------------------------------------------------------------------------- -// font-related functions (X and GTK) -// ---------------------------------------------------------------------------- - -#if defined(__X__) || defined(__WXGTK__) - -#ifdef __X__ - typedef XFontStruct *wxNativeFont; -#else // GDK - typedef GdkFont *wxNativeFont; -#endif - -#include "wx/font.h" // for wxFontEncoding - -// returns the handle of the nearest available font or 0 -extern wxNativeFont wxLoadQueryNearestFont(int pointSize, - int family, - int style, - int weight, - bool underlined, - const wxString &facename, - wxFontEncoding encoding); - -// fills xencoding and xregistry with the X font spec parts for the given -// encoding ('*' if encoding == wxFONTENCODING_SYSTEM) and returns TRUE if any -// fonts with this encoding exist or FALSE if it's unknown (it does *not* mean -// that they don't exist!) -extern bool wxGetXFontEncoding(wxFontEncoding encoding, - wxString *xencoding, wxString *xregistry); - -#endif // X || GTK - #endif // wxUSE_GUI #endif diff --git a/samples/font/font.cpp b/samples/font/font.cpp index 50e6985b24..acc320e270 100644 --- a/samples/font/font.cpp +++ b/samples/font/font.cpp @@ -95,8 +95,9 @@ public: void OnSize(wxSizeEvent& event); protected: - void DoEnumerateFamilies(bool fixedWidthOnly, - wxFontEncoding encoding = wxFONTENCODING_SYSTEM); + bool DoEnumerateFamilies(bool fixedWidthOnly, + wxFontEncoding encoding = wxFONTENCODING_SYSTEM, + bool silent = FALSE); void DoChangeFont(const wxFont& font, const wxColour& col = wxNullColour); @@ -268,7 +269,9 @@ void MyFrame::OnEnumerateEncodings(wxCommandEvent& WXUNUSED(event)) fontEnumerator.GetText().c_str()); } -void MyFrame::DoEnumerateFamilies(bool fixedWidthOnly, wxFontEncoding encoding) +bool MyFrame::DoEnumerateFamilies(bool fixedWidthOnly, + wxFontEncoding encoding, + bool silent) { class MyFontEnumerator : public wxFontEnumerator { @@ -301,8 +304,11 @@ void MyFrame::DoEnumerateFamilies(bool fixedWidthOnly, wxFontEncoding encoding) for ( n = 0; n < nFacenames; n++ ) facenames[n] = fontEnumerator.GetFacenames().Item(n); - n = wxGetSingleChoiceIndex("Choose a facename", "Font demo", - nFacenames, facenames, this); + if ( silent ) + n = 1; + else + n = wxGetSingleChoiceIndex("Choose a facename", "Font demo", + nFacenames, facenames, this); if ( n != -1 ) { wxFont font(14, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, @@ -312,11 +318,15 @@ void MyFrame::DoEnumerateFamilies(bool fixedWidthOnly, wxFontEncoding encoding) } delete [] facenames; + + return TRUE; } - else + else if ( !silent ) { wxLogWarning("No such fonts found."); } + + return FALSE; } void MyFrame::OnEnumerateFamiliesForEncoding(wxCommandEvent& WXUNUSED(event)) @@ -457,8 +467,7 @@ void MyFrame::OnViewMsg(wxCommandEvent& WXUNUSED(event)) } // ok, now get the corresponding encoding - wxFontMapper fontMapper; - wxFontEncoding fontenc = fontMapper.CharsetToEncoding(charset); + wxFontEncoding fontenc = wxTheFontMapper->CharsetToEncoding(charset); if ( fontenc == wxFONTENCODING_SYSTEM ) { wxLogError("Charset '%s' is unsupported.", charset.c_str()); @@ -466,9 +475,23 @@ void MyFrame::OnViewMsg(wxCommandEvent& WXUNUSED(event)) } // and now create the correct font - m_textctrl->LoadFile(filename); + if ( !DoEnumerateFamilies(FALSE, fontenc, TRUE /* silent */) ) + { + wxFont font(14, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, + wxFONTWEIGHT_NORMAL, FALSE /* !underlined */, + wxEmptyString /* facename */, fontenc); + if ( font.Ok() ) + { + DoChangeFont(font); + } + else + { + wxLogWarning("No fonts for encoding '%s' on this system.", + wxFontMapper::GetEncodingDescription(fontenc).c_str()); + } + } - DoEnumerateFamilies(FALSE, fontenc); + m_textctrl->LoadFile(filename); } void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event)) diff --git a/src/common/appcmn.cpp b/src/common/appcmn.cpp index d72316a6dd..ee097b6b70 100644 --- a/src/common/appcmn.cpp +++ b/src/common/appcmn.cpp @@ -34,6 +34,7 @@ #endif #include "wx/thread.h" +#include "wx/confbase.h" // =========================================================================== // implementation @@ -64,3 +65,13 @@ void wxAppBase::ProcessPendingEvents() } } +int wxAppBase::OnExit() +{ +#if wxUSE_CONFIG + // delete the config object if any (don't use Get() here, but Set() + // because Get() could create a new config object) + delete wxConfigBase::Set((wxConfigBase *) NULL); +#endif // wxUSE_CONFIG + + return 0; +} diff --git a/src/common/cmndata.cpp b/src/common/cmndata.cpp index 3d0f4aab6b..d5772633af 100644 --- a/src/common/cmndata.cpp +++ b/src/common/cmndata.cpp @@ -149,29 +149,14 @@ wxFontData::wxFontData() enableEffects = TRUE; minSize = 0; maxSize = 0; -} -wxFontData::wxFontData(const wxFontData& data) -{ - (*this) = data; + m_encoding = wxFONTENCODING_SYSTEM; } wxFontData::~wxFontData() { } -void wxFontData::operator=(const wxFontData& data) -{ - fontColour = data.fontColour; - showHelp = data.showHelp; - allowSymbols = data.allowSymbols; - enableEffects = data.enableEffects; - initialFont = data.initialFont; - chosenFont = data.chosenFont; - minSize = data.minSize; - maxSize = data.maxSize; -} - #if wxUSE_PRINTING_ARCHITECTURE // ---------------------------------------------------------------------------- // Print data diff --git a/src/common/fileconf.cpp b/src/common/fileconf.cpp index 6b33a83545..d26dd662c7 100644 --- a/src/common/fileconf.cpp +++ b/src/common/fileconf.cpp @@ -324,20 +324,21 @@ wxFileConfig::wxFileConfig(const wxString& appName, const wxString& vendorName, // if the path is not absolute, prepend the standard directory to it // UNLESS wxCONFIG_USE_RELATIVE_PATH style is set - if ( !(style & wxCONFIG_USE_RELATIVE_PATH) ){ - if ( !m_strLocalFile.IsEmpty() && !wxIsAbsolutePath(m_strLocalFile) ) - { - wxString strLocal = m_strLocalFile; - m_strLocalFile = GetLocalDir(); - m_strLocalFile << strLocal; - } - - if ( !m_strGlobalFile.IsEmpty() && !wxIsAbsolutePath(m_strGlobalFile) ) - { - wxString strGlobal = m_strGlobalFile; - m_strGlobalFile = GetGlobalDir(); - m_strGlobalFile << strGlobal; - } + if ( !(style & wxCONFIG_USE_RELATIVE_PATH) ) + { + if ( !m_strLocalFile.IsEmpty() && !wxIsAbsolutePath(m_strLocalFile) ) + { + wxString strLocal = m_strLocalFile; + m_strLocalFile = GetLocalDir(); + m_strLocalFile << strLocal; + } + + if ( !m_strGlobalFile.IsEmpty() && !wxIsAbsolutePath(m_strGlobalFile) ) + { + wxString strGlobal = m_strGlobalFile; + m_strGlobalFile = GetGlobalDir(); + m_strGlobalFile << strGlobal; + } } Init(); diff --git a/src/common/fontcmn.cpp b/src/common/fontcmn.cpp index ca1921a2bc..8a5e31d4dd 100644 --- a/src/common/fontcmn.cpp +++ b/src/common/fontcmn.cpp @@ -42,6 +42,7 @@ wxFontEncoding wxFontBase::ms_encodingDefault = wxFONTENCODING_SYSTEM; +/* static */ wxFont *wxFontBase::New(int size, int family, int style, diff --git a/src/common/fontmap.cpp b/src/common/fontmap.cpp index 081c2c5215..3222cf0f61 100644 --- a/src/common/fontmap.cpp +++ b/src/common/fontmap.cpp @@ -36,6 +36,9 @@ #include "wx/fontmap.h" #include "wx/config.h" + +#include "wx/msgdlg.h" +#include "wx/fontdlg.h" #include "wx/choicdlg.h" // ---------------------------------------------------------------------------- @@ -46,6 +49,132 @@ 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"); + +// encodings supported by GetEncodingDescription +static wxFontEncoding gs_encodings[] = +{ + wxFONTENCODING_ISO8859_1, + wxFONTENCODING_ISO8859_2, + wxFONTENCODING_ISO8859_3, + wxFONTENCODING_ISO8859_4, + wxFONTENCODING_ISO8859_5, + wxFONTENCODING_ISO8859_6, + wxFONTENCODING_ISO8859_7, + wxFONTENCODING_ISO8859_8, + wxFONTENCODING_ISO8859_9, + wxFONTENCODING_ISO8859_10, + wxFONTENCODING_ISO8859_11, + wxFONTENCODING_ISO8859_12, + wxFONTENCODING_ISO8859_13, + wxFONTENCODING_ISO8859_14, + wxFONTENCODING_ISO8859_15, + wxFONTENCODING_KOI8, + wxFONTENCODING_CP1250, + wxFONTENCODING_CP1251, + wxFONTENCODING_CP1252, + wxFONTENCODING_CP1253, + wxFONTENCODING_CP1254, + wxFONTENCODING_CP1255, + wxFONTENCODING_CP1256, + wxFONTENCODING_CP1257, +}; + +// the descriptions for them +static const wxChar* gs_encodingDescs[] = +{ + wxTRANSLATE( "West 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( "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( "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( "KOI8-R" ), + wxTRANSLATE( "Windows Latin 2 (CP 1250)" ), + wxTRANSLATE( "Windows Cyrillic (CP 1251)" ), + wxTRANSLATE( "Windows Latin 1 (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)" ), +}; + +// 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", +}; + +// ---------------------------------------------------------------------------- +// global data +// ---------------------------------------------------------------------------- + +// private object +static wxFontMapper gs_fontMapper; + +// and public pointer +wxFontMapper * WXDLLEXPORT wxTheFontMapper = &gs_fontMapper; + +// ---------------------------------------------------------------------------- +// private classes +// ---------------------------------------------------------------------------- + +// change the config path during the lifetime of this object +class wxFontMapperPathChanger +{ +public: + wxFontMapperPathChanger(wxFontMapper *fontMapper, const wxString& path) + { + m_fontMapper = fontMapper; + m_ok = m_fontMapper->ChangePath(path, &m_pathOld); + } + + bool IsOk() const { return m_ok; } + + ~wxFontMapperPathChanger() + { + if ( IsOk() ) + m_fontMapper->RestorePath(m_pathOld); + } + +private: + wxFontMapper *m_fontMapper; + bool m_ok; + wxString m_pathOld; +}; // ============================================================================ // implementation @@ -143,6 +272,52 @@ void wxFontMapper::RestorePath(const wxString& pathOld) // charset/encoding correspondence // ---------------------------------------------------------------------------- +/* static */ +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?") ); + + for ( size_t i = 0; i < count; i++ ) + { + if ( gs_encodings[i] == encoding ) + { + return wxGetTranslation(gs_encodingDescs[i]); + } + } + + wxString str; + str.Printf(_("Unknown encoding (%d)"), encoding); + + return str; +} + +/* static */ +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?") ); + + for ( size_t i = 0; i < count; i++ ) + { + if ( gs_encodings[i] == encoding ) + { + return wxGetTranslation(gs_encodingNames[i]); + } + } + + wxString str; + str.Printf(_("unknown-%d"), encoding); + + return str; +} + wxFontEncoding wxFontMapper::CharsetToEncoding(const wxString& charset, bool interactive) { @@ -255,65 +430,9 @@ wxFontEncoding wxFontMapper::CharsetToEncoding(const wxString& charset, "cannot be replaced"), charset.c_str()); // the list of choices - static wxFontEncoding encodings[] = - { - wxFONTENCODING_ISO8859_1, - wxFONTENCODING_ISO8859_2, - wxFONTENCODING_ISO8859_3, - wxFONTENCODING_ISO8859_4, - wxFONTENCODING_ISO8859_5, - wxFONTENCODING_ISO8859_6, - wxFONTENCODING_ISO8859_7, - wxFONTENCODING_ISO8859_8, - wxFONTENCODING_ISO8859_9, - wxFONTENCODING_ISO8859_10, - wxFONTENCODING_ISO8859_11, - wxFONTENCODING_ISO8859_12, - wxFONTENCODING_ISO8859_13, - wxFONTENCODING_ISO8859_14, - wxFONTENCODING_ISO8859_15, - wxFONTENCODING_KOI8, - wxFONTENCODING_CP1250, - wxFONTENCODING_CP1251, - wxFONTENCODING_CP1252, - wxFONTENCODING_CP1253, - wxFONTENCODING_CP1254, - wxFONTENCODING_CP1255, - wxFONTENCODING_CP1256, - wxFONTENCODING_CP1257, - }; - - static const wxChar* encodingNames[] = - { - "West European (ISO-8859-1/Latin 1)", - "Central European (ISO-8859-2/Latin 2)", - "Esperanto (ISO-8859-3)", - "Baltic (ISO-8859-4)", - "Cyrillic (Latin 5)", - "Arabic (ISO-8859-6)" - "Greek (ISO-8859-7)", - "Hebrew (ISO-8859-8)", - "Turkish (ISO-8859-9)", - "Baltic II (ISO-8859-10)", - "Thai (ISO-8859-11)", - "ISO-8859-12", - "ISO-8859-13", - "ISO-8859-14", - "West European new (ISO-8859-15/Latin 0)", - "KOI8-R", - "Windows Latin 2 (CP 1250)", - "Windows Cyrillic (CP 1251)", - "Windows Latin 1 (CP 1252)", - "Windows Greek (CP 1253)", - "Windows Turkish (CP 1254)", - "Windows Hebrew (CP 1255)", - "Windows Arabic (CP 1256)", - "Windows Baltic (CP 1257)", - }; - - size_t count = WXSIZEOF(encodingNames); - - wxASSERT_MSG( count == WXSIZEOF(encodings), + size_t count = WXSIZEOF(gs_encodingDescs); + + wxASSERT_MSG( count == WXSIZEOF(gs_encodings), _T("inconsitency detected - forgot to update one of " "the arrays?") ); @@ -321,7 +440,7 @@ wxFontEncoding wxFontMapper::CharsetToEncoding(const wxString& charset, for ( size_t n = 0; n < count; n++ ) { - encodingNamesTranslated[n] = wxGetTranslation(encodingNames[n]); + encodingNamesTranslated[n] = wxGetTranslation(gs_encodingDescs[n]); } // the parent window @@ -339,7 +458,9 @@ wxFontEncoding wxFontMapper::CharsetToEncoding(const wxString& charset, if ( n != -1 ) { - encoding = encodings[n]; + // TODO save the result in the config! + + encoding = gs_encodings[n]; } //else: cancelled } @@ -347,3 +468,186 @@ wxFontEncoding wxFontMapper::CharsetToEncoding(const wxString& charset, return encoding; } +// ---------------------------------------------------------------------------- +// support for unknown encodings: we maintain a map between the +// (platform-specific) strings identifying them and our wxFontEncodings they +// correspond to which is used by GetFontForEncoding() function +// ---------------------------------------------------------------------------- + +bool wxFontMapper::TestAltEncoding(const wxString& configEntry, + wxFontEncoding encReplacement, + wxNativeEncodingInfo *info) +{ + if ( wxGetNativeFontEncoding(encReplacement, info) && + wxTestFontEncoding(*info) ) + { + // remember the mapping in the config + wxFontMapperPathChanger path(this, FONTMAPPER_FONT_FROM_ENCODING_PATH); + + if ( path.IsOk() ) + { + GetConfig()->Write(configEntry, info->ToString()); + } + + return TRUE; + } + + return FALSE; +} + +bool wxFontMapper::GetAltForEncoding(wxFontEncoding encoding, + wxNativeEncodingInfo *info, + bool interactive) +{ + wxCHECK_MSG( info, FALSE, _T("bad pointer in GetAltForEncoding") ); + + wxString configEntry = GetEncodingName(encoding); + + // do we have a font spec for this encoding? + wxString pathOld; + if ( ChangePath(FONTMAPPER_FONT_FROM_ENCODING_PATH, &pathOld) ) + { + wxConfigBase *config = GetConfig(); + + wxString fontinfo = config->Read(configEntry); + + RestorePath(pathOld); + + if ( !!fontinfo ) + { + if ( info->FromString(fontinfo) ) + { + if ( wxTestFontEncoding(*info) ) + { + // ok, got something + return TRUE; + } + //else: no such fonts, look for something else + } + else + { + wxLogDebug(_T("corrupted config data: string '%s' is not " + "a valid font encoding info"), fontinfo.c_str()); + } + } + } + + // ask the user + if ( interactive ) + { + wxString title(m_titleDialog); + if ( !title ) + title << wxTheApp->GetAppName() << _(": unknown 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)?"), + GetEncodingDescription(encoding).c_str()); + + wxWindow *parent = m_windowParent; + if ( !parent ) + parent = wxTheApp->GetTopWindow(); + + if ( wxMessageBox(msg, title, + wxICON_QUESTION | wxYES_NO, parent) == wxYES ) + { + wxFontData data; + data.SetEncoding(encoding); + data.EncodingInfo() = *info; + wxFontDialog dialog(parent, &data); + if ( dialog.ShowModal() == wxID_OK ) + { + wxFontData retData = dialog.GetFontData(); + wxFont font = retData.GetChosenFont(); + + info->xregistry = retData.EncodingInfo().xregistry; + info->xencoding = retData.EncodingInfo().xencoding; + + // remember this in the config + if ( ChangePath(FONTMAPPER_FONT_FROM_ENCODING_PATH, &pathOld) ) + { + GetConfig()->Write(configEntry, info->ToString()); + + RestorePath(pathOld); + } + + return TRUE; + } + //else: the user canceled the font selection dialog + } + //else: the user doesn't want to select a font + } + //else: we're in non-interactive mode + + // now try the default mappings + switch ( encoding ) + { + 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) ) + return TRUE; + + break; + + case wxFONTENCODING_CP1253: + if ( TestAltEncoding(configEntry, wxFONTENCODING_ISO8859_7, info) ) + return TRUE; + + break; + + default: + // TODO add other mappings... + ; + } + + return FALSE; +} diff --git a/src/gtk/dcclient.cpp b/src/gtk/dcclient.cpp index fd0105435a..722c2a664e 100644 --- a/src/gtk/dcclient.cpp +++ b/src/gtk/dcclient.cpp @@ -813,12 +813,16 @@ void wxWindowDC::DoGetTextExtent(const wxString &string, wxCoord wxWindowDC::GetCharWidth() const { GdkFont *font = m_font.GetInternalFont( m_scaleY ); + wxCHECK_MSG( font, -1, _T("invalid font") ); + return wxCoord(gdk_string_width( font, "H" ) / m_scaleX); } wxCoord wxWindowDC::GetCharHeight() const { GdkFont *font = m_font.GetInternalFont( m_scaleY ); + wxCHECK_MSG( font, -1, _T("invalid font") ); + return wxCoord((font->ascent + font->descent) / m_scaleY); } diff --git a/src/gtk/dialog.cpp b/src/gtk/dialog.cpp index 156cd6f955..cef4cc3a70 100644 --- a/src/gtk/dialog.cpp +++ b/src/gtk/dialog.cpp @@ -168,16 +168,16 @@ gtk_dialog_realized_callback( GtkWidget *widget, wxDialog *win ) gtk_window_set_policy(GTK_WINDOW(win->m_widget), 1, 1, 1); /* set size hints */ - gint flag = 0; // GDK_HINT_POS; + gint flag = 0; // GDK_HINT_POS; if ((win->GetMinWidth() != -1) || (win->GetMinHeight() != -1)) flag |= GDK_HINT_MIN_SIZE; if ((win->GetMaxWidth() != -1) || (win->GetMaxHeight() != -1)) flag |= GDK_HINT_MAX_SIZE; if (flag) { gdk_window_set_hints( win->m_widget->window, - win->m_x, win->m_y, - win->GetMinWidth(), win->GetMinHeight(), - win->GetMaxWidth(), win->GetMaxHeight(), - flag ); + win->m_x, win->m_y, + win->GetMinWidth(), win->GetMinHeight(), + win->GetMaxWidth(), win->GetMaxHeight(), + flag ); } /* reset the icon */ @@ -262,7 +262,7 @@ bool wxDialog::Create( wxWindow *parent, !CreateBase( parent, id, pos, size, style, wxDefaultValidator, name )) { wxFAIL_MSG( wxT("wxDialog creation failed") ); - return FALSE; + return FALSE; } m_insertCallback = (wxInsertChildFunction) wxInsertChildInDialog; @@ -456,6 +456,7 @@ void wxDialog::DoSetSize( int x, int y, int width, int height, int sizeFlags ) int old_x = m_x; int old_y = m_y; + int old_width = m_width; int old_height = m_height; diff --git a/src/gtk/font.cpp b/src/gtk/font.cpp index 64ff18c4e8..c2e51daba6 100644 --- a/src/gtk/font.cpp +++ b/src/gtk/font.cpp @@ -20,6 +20,8 @@ #endif #include "wx/font.h" +#include "wx/fontutil.h" +#include "wx/cmndata.h" #include "wx/utils.h" #include "wx/log.h" #include "wx/gdicmn.h" @@ -122,7 +124,7 @@ wxFontRefData::wxFontRefData(int size, int family, int style, int weight, bool underlined, const wxString& faceName, wxFontEncoding encoding ) : m_scaled_xfonts(wxKEY_INTEGER) { - Init(size, family, style, weight, + Init(size, family, style, weight, underlined, faceName, encoding); } @@ -150,18 +152,16 @@ void wxFont::Init() wxTheFontList->Append( this ); } -wxFont::wxFont( GdkFont *WXUNUSED(font), char *xFontName ) +wxFont::wxFont( const wxString& fontname, const wxFontData& fontdata ) { - if (!xFontName) - return; - Init(); + wxCHECK_RET( !!fontname, _T("invalid font spec") ); + m_refData = new wxFontRefData(); wxString tmp; - wxString fontname( xFontName ); wxStringTokenizer tn( fontname, wxT("-") ); tn.GetNextToken(); // foundry @@ -177,7 +177,7 @@ wxFont::wxFont( GdkFont *WXUNUSED(font), char *xFontName ) if (tmp == wxT("LIGHT")) M_FONTDATA->m_weight = wxLIGHT; if (tmp == wxT("THIN")) M_FONTDATA->m_weight = wxLIGHT; - + tmp = tn.GetNextToken().MakeUpper(); // slant if (tmp == wxT("I")) M_FONTDATA->m_style = wxITALIC; if (tmp == wxT("O")) M_FONTDATA->m_style = wxITALIC; @@ -211,32 +211,36 @@ wxFont::wxFont( GdkFont *WXUNUSED(font), char *xFontName ) tn.GetNextToken(); // avg width // deal with font encoding - wxString registry = tn.GetNextToken().MakeUpper(), - encoding = tn.GetNextToken().MakeUpper(); - - if ( registry == _T("ISO8859") ) + M_FONTDATA->m_encoding = fontdata.GetEncoding(); + if ( M_FONTDATA->m_encoding == wxFONTENCODING_SYSTEM ) { - int cp; - if ( wxSscanf(encoding, wxT("%d"), &cp) == 1 ) + wxString registry = tn.GetNextToken().MakeUpper(), + encoding = tn.GetNextToken().MakeUpper(); + + if ( registry == _T("ISO8859") ) { - M_FONTDATA->m_encoding = - (wxFontEncoding)(wxFONTENCODING_ISO8859_1 + cp - 1); + int cp; + if ( wxSscanf(encoding, wxT("%d"), &cp) == 1 ) + { + M_FONTDATA->m_encoding = + (wxFontEncoding)(wxFONTENCODING_ISO8859_1 + cp - 1); + } } - } - else if ( registry == _T("MICROSOFT") ) - { - int cp; - if ( wxSscanf(encoding, wxT("cp125%d"), &cp) == 1 ) + else if ( registry == _T("MICROSOFT") ) { - M_FONTDATA->m_encoding = - (wxFontEncoding)(wxFONTENCODING_CP1250 + cp); + int cp; + if ( wxSscanf(encoding, wxT("cp125%d"), &cp) == 1 ) + { + M_FONTDATA->m_encoding = + (wxFontEncoding)(wxFONTENCODING_CP1250 + cp); + } } + else if ( registry == _T("KOI8") ) + { + M_FONTDATA->m_encoding = wxFONTENCODING_KOI8; + } + //else: unknown encoding - may be give a warning here? } - else if ( registry == _T("KOI8") ) - { - M_FONTDATA->m_encoding = wxFONTENCODING_KOI8; - } - //else: unknown encoding - may be give a warning here? } bool wxFont::Create( int pointSize, @@ -429,10 +433,9 @@ GdkFont *wxFont::GetInternalFont( float scale ) const M_FONTDATA->m_scaled_xfonts.Append( int_scale, (wxObject*)font ); } - if (!font) - { - wxLogError(wxT("could not load any font")); - } + // it's quite useless to make it a wxCHECK because we're going to crash + // anyhow... + wxASSERT_MSG( font, wxT("could not load any font?") ); return font; } diff --git a/src/gtk/fontdlg.cpp b/src/gtk/fontdlg.cpp index eaa998c383..b507f3e193 100644 --- a/src/gtk/fontdlg.cpp +++ b/src/gtk/fontdlg.cpp @@ -69,15 +69,53 @@ void gtk_fontdialog_ok_callback( GtkWidget *WXUNUSED(widget), wxFontDialog *dial } gchar *fontname = gtk_font_selection_dialog_get_font_name(fontdlg); - wxFont font( gfont, fontname ); + + // extract the relevant bits from it + wxString xregistry, xencoding; + char *dash = strrchr(fontname, '-'); // find the last dash + if ( dash ) + { + xencoding = dash + 1; + *dash = '\0'; + dash = strrchr(fontname, '-'); // the last before one + if ( dash ) + { + xregistry = dash + 1; + } + else + { + wxFAIL_MSG(_T("no registry in X font spec?")); + } + + // restore the dash we changed to NUL above + *(fontname + strlen(fontname)) = '-'; + } + else + { + wxFAIL_MSG(_T("no encoding in X font spec?")); + } + + // transfer the X registry/encoding to wxFontData - they are used by + // wxFontMapper after wxFontDialog returns + wxFontData& fontdata = dialog->m_fontData; + + // we ignore the facename here - should be enough to choose an arbitrary + // one if the registry/encoding are specified + // dialog->m_fontData.EncodingInfo().facename = xfamily; + fontdata.EncodingInfo().xregistry = xregistry; + fontdata.EncodingInfo().xencoding = xencoding; + + // pass fontdata to wxFont ctor so that it can get the encoding from there + // if it is already known (otherwise it will try to deduce it itself) + dialog->m_fontData.SetChosenFont( wxFont(fontname, fontdata) ); + g_free( fontname ); - dialog->m_fontData.SetChosenFont( font ); wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK); event.SetEventObject( dialog ); dialog->GetEventHandler()->ProcessEvent( event ); } -#endif // GTK+ 1.2 andlater only +#endif // GTK+ 1.2 and later only //----------------------------------------------------------------------------- // "clicked" for Cancel-button @@ -100,7 +138,8 @@ void gtk_fontdialog_cancel_callback( GtkWidget *WXUNUSED(w), wxFontDialog *dialo IMPLEMENT_DYNAMIC_CLASS(wxFontDialog,wxDialog) -wxFontDialog::wxFontDialog( wxWindow *parent, wxFontData *WXUNUSED(data) ) +wxFontDialog::wxFontDialog( wxWindow *parent, wxFontData *fontdata ) + : m_fontData(*fontdata) { m_needParent = FALSE; diff --git a/src/gtk/frame.cpp b/src/gtk/frame.cpp index 1cc37b1a92..369cb25161 100644 --- a/src/gtk/frame.cpp +++ b/src/gtk/frame.cpp @@ -85,7 +85,7 @@ static void gtk_frame_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation* (int)alloc->width, (int)alloc->height ); */ - + win->m_width = alloc->width; win->m_height = alloc->height; win->UpdateSize(); @@ -164,14 +164,14 @@ static void gtk_toolbar_detached_callback( GtkWidget *WXUNUSED(widget), GtkWidge // "configure_event" //----------------------------------------------------------------------------- -static gint +static gint #if (GTK_MINOR_VERSON > 0) gtk_frame_configure_callback( GtkWidget *WXUNUSED(widget), GdkEventConfigure *WXUNUSED(event), wxFrame *win ) #else gtk_frame_configure_callback( GtkWidget *WXUNUSED(widget), GdkEventConfigure *event, wxFrame *win ) #endif { - if (g_isIdle) + if (g_isIdle) wxapp_install_idle_handler(); if (!win->m_hasVMT) return FALSE; @@ -255,13 +255,13 @@ gtk_frame_realized_callback( GtkWidget *widget, wxFrame *win ) if ((win->GetMaxWidth() != -1) || (win->GetMaxHeight() != -1)) flag |= GDK_HINT_MAX_SIZE; if (flag) { - gdk_window_set_hints( win->m_widget->window, - win->m_x, win->m_y, - win->GetMinWidth(), win->GetMinHeight(), - win->GetMaxWidth(), win->GetMaxHeight(), - flag ); + gdk_window_set_hints( win->m_widget->window, + win->m_x, win->m_y, + win->GetMinWidth(), win->GetMinHeight(), + win->GetMaxWidth(), win->GetMaxHeight(), + flag ); } - + /* reset the icon */ if (win->m_icon != wxNullIcon) { @@ -300,7 +300,7 @@ gtk_frame_realized_callback( GtkWidget *widget, wxFrame *win ) static void wxInsertChildInFrame( wxFrame* parent, wxWindow* child ) { wxASSERT( GTK_IS_WIDGET(child->m_widget) ); - + if (!parent->m_insertInClientArea) { /* these are outside the client area */ @@ -397,7 +397,7 @@ bool wxFrame::Create( wxWindow *parent, wxWindowID id, const wxString &title, !CreateBase( parent, id, pos, size, style, wxDefaultValidator, name )) { wxFAIL_MSG( wxT("wxFrame creation failed") ); - return FALSE; + return FALSE; } m_title = title; @@ -530,6 +530,7 @@ void wxFrame::DoSetSize( int x, int y, int width, int height, int sizeFlags ) int old_x = m_x; int old_y = m_y; + int old_width = m_width; int old_height = m_height; @@ -693,7 +694,7 @@ void wxFrame::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y), int width, int height m_width = width; m_height = height; - + /* space occupied by m_frameToolBar and m_frameMenuBar */ int client_area_y_offset = 0; @@ -737,7 +738,7 @@ void wxFrame::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y), int width, int height #if wxUSE_TOOLBAR if ((m_frameToolBar) && - (m_frameToolBar->m_widget->parent == m_mainWidget)) + (m_frameToolBar->m_widget->parent == m_mainWidget)) { int xx = m_miniEdge; int yy = m_miniEdge + m_miniTitle; @@ -750,7 +751,7 @@ void wxFrame::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y), int width, int height } int ww = m_width - 2*m_miniEdge; int hh = m_frameToolBar->m_height; - if (m_toolBarDetached) hh = wxPLACE_HOLDER; + if (m_toolBarDetached) hh = wxPLACE_HOLDER; m_frameToolBar->m_x = xx; m_frameToolBar->m_y = yy; /* m_frameToolBar->m_height = hh; don't change the toolbar's reported size @@ -798,7 +799,7 @@ void wxFrame::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y), int width, int height m_sizeSet = TRUE; - + // send size event to frame wxSizeEvent event( wxSize(m_width,m_height), GetId() ); event.SetEventObject( this ); @@ -828,11 +829,11 @@ void wxFrame::OnInternalIdle() if (!m_sizeSet && GTK_WIDGET_REALIZED(m_wxwindow)) { GtkOnSize( m_x, m_y, m_width, m_height ); - - // we'll come back later + + // we'll come back later if (g_isIdle) wxapp_install_idle_handler(); - return; + return; } if (m_frameMenuBar) m_frameMenuBar->OnInternalIdle(); @@ -920,8 +921,8 @@ void wxFrame::SetMenuBar( wxMenuBar *menuBar ) gtk_signal_connect( GTK_OBJECT(menuBar->m_widget), "child_detached", GTK_SIGNAL_FUNC(gtk_menu_detached_callback), (gpointer)this ); } - - m_frameMenuBar->Show( TRUE ); + + m_frameMenuBar->Show( TRUE ); } } @@ -986,9 +987,9 @@ wxToolBar* wxFrame::OnCreateToolBar( long style, wxWindowID id, const wxString& return new wxToolBar( this, id, wxDefaultPosition, wxDefaultSize, style, name ); } -void wxFrame::SetToolBar(wxToolBar *toolbar) -{ - m_frameToolBar = toolbar; +void wxFrame::SetToolBar(wxToolBar *toolbar) +{ + m_frameToolBar = toolbar; if (m_frameToolBar) { /* insert into toolbar area if not already there */ @@ -996,10 +997,10 @@ void wxFrame::SetToolBar(wxToolBar *toolbar) (m_frameToolBar->m_widget->parent != m_mainWidget)) { GetChildren().DeleteObject( m_frameToolBar ); - - gtk_widget_reparent( m_frameToolBar->m_widget, m_mainWidget ); - UpdateSize(); - } + + gtk_widget_reparent( m_frameToolBar->m_widget, m_mainWidget ); + UpdateSize(); + } } } @@ -1113,25 +1114,25 @@ void wxFrame::SetIcon( const wxIcon &icon ) gdk_window_set_icon( m_widget->window, (GdkWindow *) NULL, icon.GetPixmap(), bm ); } -void wxFrame::Maximize(bool WXUNUSED(maximize)) +void wxFrame::Maximize(bool WXUNUSED(maximize)) { } -void wxFrame::Restore() +void wxFrame::Restore() { } -void wxFrame::Iconize( bool iconize ) -{ +void wxFrame::Iconize( bool iconize ) +{ if (iconize) { XIconifyWindow( GDK_WINDOW_XDISPLAY( m_widget->window ), - GDK_WINDOW_XWINDOW( m_widget->window ), - DefaultScreen( GDK_DISPLAY() ) ); + GDK_WINDOW_XWINDOW( m_widget->window ), + DefaultScreen( GDK_DISPLAY() ) ); } } -bool wxFrame::IsIconized() const -{ - return FALSE; +bool wxFrame::IsIconized() const +{ + return FALSE; } diff --git a/src/gtk1/dcclient.cpp b/src/gtk1/dcclient.cpp index fd0105435a..722c2a664e 100644 --- a/src/gtk1/dcclient.cpp +++ b/src/gtk1/dcclient.cpp @@ -813,12 +813,16 @@ void wxWindowDC::DoGetTextExtent(const wxString &string, wxCoord wxWindowDC::GetCharWidth() const { GdkFont *font = m_font.GetInternalFont( m_scaleY ); + wxCHECK_MSG( font, -1, _T("invalid font") ); + return wxCoord(gdk_string_width( font, "H" ) / m_scaleX); } wxCoord wxWindowDC::GetCharHeight() const { GdkFont *font = m_font.GetInternalFont( m_scaleY ); + wxCHECK_MSG( font, -1, _T("invalid font") ); + return wxCoord((font->ascent + font->descent) / m_scaleY); } diff --git a/src/gtk1/dialog.cpp b/src/gtk1/dialog.cpp index 156cd6f955..cef4cc3a70 100644 --- a/src/gtk1/dialog.cpp +++ b/src/gtk1/dialog.cpp @@ -168,16 +168,16 @@ gtk_dialog_realized_callback( GtkWidget *widget, wxDialog *win ) gtk_window_set_policy(GTK_WINDOW(win->m_widget), 1, 1, 1); /* set size hints */ - gint flag = 0; // GDK_HINT_POS; + gint flag = 0; // GDK_HINT_POS; if ((win->GetMinWidth() != -1) || (win->GetMinHeight() != -1)) flag |= GDK_HINT_MIN_SIZE; if ((win->GetMaxWidth() != -1) || (win->GetMaxHeight() != -1)) flag |= GDK_HINT_MAX_SIZE; if (flag) { gdk_window_set_hints( win->m_widget->window, - win->m_x, win->m_y, - win->GetMinWidth(), win->GetMinHeight(), - win->GetMaxWidth(), win->GetMaxHeight(), - flag ); + win->m_x, win->m_y, + win->GetMinWidth(), win->GetMinHeight(), + win->GetMaxWidth(), win->GetMaxHeight(), + flag ); } /* reset the icon */ @@ -262,7 +262,7 @@ bool wxDialog::Create( wxWindow *parent, !CreateBase( parent, id, pos, size, style, wxDefaultValidator, name )) { wxFAIL_MSG( wxT("wxDialog creation failed") ); - return FALSE; + return FALSE; } m_insertCallback = (wxInsertChildFunction) wxInsertChildInDialog; @@ -456,6 +456,7 @@ void wxDialog::DoSetSize( int x, int y, int width, int height, int sizeFlags ) int old_x = m_x; int old_y = m_y; + int old_width = m_width; int old_height = m_height; diff --git a/src/gtk1/font.cpp b/src/gtk1/font.cpp index 64ff18c4e8..c2e51daba6 100644 --- a/src/gtk1/font.cpp +++ b/src/gtk1/font.cpp @@ -20,6 +20,8 @@ #endif #include "wx/font.h" +#include "wx/fontutil.h" +#include "wx/cmndata.h" #include "wx/utils.h" #include "wx/log.h" #include "wx/gdicmn.h" @@ -122,7 +124,7 @@ wxFontRefData::wxFontRefData(int size, int family, int style, int weight, bool underlined, const wxString& faceName, wxFontEncoding encoding ) : m_scaled_xfonts(wxKEY_INTEGER) { - Init(size, family, style, weight, + Init(size, family, style, weight, underlined, faceName, encoding); } @@ -150,18 +152,16 @@ void wxFont::Init() wxTheFontList->Append( this ); } -wxFont::wxFont( GdkFont *WXUNUSED(font), char *xFontName ) +wxFont::wxFont( const wxString& fontname, const wxFontData& fontdata ) { - if (!xFontName) - return; - Init(); + wxCHECK_RET( !!fontname, _T("invalid font spec") ); + m_refData = new wxFontRefData(); wxString tmp; - wxString fontname( xFontName ); wxStringTokenizer tn( fontname, wxT("-") ); tn.GetNextToken(); // foundry @@ -177,7 +177,7 @@ wxFont::wxFont( GdkFont *WXUNUSED(font), char *xFontName ) if (tmp == wxT("LIGHT")) M_FONTDATA->m_weight = wxLIGHT; if (tmp == wxT("THIN")) M_FONTDATA->m_weight = wxLIGHT; - + tmp = tn.GetNextToken().MakeUpper(); // slant if (tmp == wxT("I")) M_FONTDATA->m_style = wxITALIC; if (tmp == wxT("O")) M_FONTDATA->m_style = wxITALIC; @@ -211,32 +211,36 @@ wxFont::wxFont( GdkFont *WXUNUSED(font), char *xFontName ) tn.GetNextToken(); // avg width // deal with font encoding - wxString registry = tn.GetNextToken().MakeUpper(), - encoding = tn.GetNextToken().MakeUpper(); - - if ( registry == _T("ISO8859") ) + M_FONTDATA->m_encoding = fontdata.GetEncoding(); + if ( M_FONTDATA->m_encoding == wxFONTENCODING_SYSTEM ) { - int cp; - if ( wxSscanf(encoding, wxT("%d"), &cp) == 1 ) + wxString registry = tn.GetNextToken().MakeUpper(), + encoding = tn.GetNextToken().MakeUpper(); + + if ( registry == _T("ISO8859") ) { - M_FONTDATA->m_encoding = - (wxFontEncoding)(wxFONTENCODING_ISO8859_1 + cp - 1); + int cp; + if ( wxSscanf(encoding, wxT("%d"), &cp) == 1 ) + { + M_FONTDATA->m_encoding = + (wxFontEncoding)(wxFONTENCODING_ISO8859_1 + cp - 1); + } } - } - else if ( registry == _T("MICROSOFT") ) - { - int cp; - if ( wxSscanf(encoding, wxT("cp125%d"), &cp) == 1 ) + else if ( registry == _T("MICROSOFT") ) { - M_FONTDATA->m_encoding = - (wxFontEncoding)(wxFONTENCODING_CP1250 + cp); + int cp; + if ( wxSscanf(encoding, wxT("cp125%d"), &cp) == 1 ) + { + M_FONTDATA->m_encoding = + (wxFontEncoding)(wxFONTENCODING_CP1250 + cp); + } } + else if ( registry == _T("KOI8") ) + { + M_FONTDATA->m_encoding = wxFONTENCODING_KOI8; + } + //else: unknown encoding - may be give a warning here? } - else if ( registry == _T("KOI8") ) - { - M_FONTDATA->m_encoding = wxFONTENCODING_KOI8; - } - //else: unknown encoding - may be give a warning here? } bool wxFont::Create( int pointSize, @@ -429,10 +433,9 @@ GdkFont *wxFont::GetInternalFont( float scale ) const M_FONTDATA->m_scaled_xfonts.Append( int_scale, (wxObject*)font ); } - if (!font) - { - wxLogError(wxT("could not load any font")); - } + // it's quite useless to make it a wxCHECK because we're going to crash + // anyhow... + wxASSERT_MSG( font, wxT("could not load any font?") ); return font; } diff --git a/src/gtk1/fontdlg.cpp b/src/gtk1/fontdlg.cpp index eaa998c383..b507f3e193 100644 --- a/src/gtk1/fontdlg.cpp +++ b/src/gtk1/fontdlg.cpp @@ -69,15 +69,53 @@ void gtk_fontdialog_ok_callback( GtkWidget *WXUNUSED(widget), wxFontDialog *dial } gchar *fontname = gtk_font_selection_dialog_get_font_name(fontdlg); - wxFont font( gfont, fontname ); + + // extract the relevant bits from it + wxString xregistry, xencoding; + char *dash = strrchr(fontname, '-'); // find the last dash + if ( dash ) + { + xencoding = dash + 1; + *dash = '\0'; + dash = strrchr(fontname, '-'); // the last before one + if ( dash ) + { + xregistry = dash + 1; + } + else + { + wxFAIL_MSG(_T("no registry in X font spec?")); + } + + // restore the dash we changed to NUL above + *(fontname + strlen(fontname)) = '-'; + } + else + { + wxFAIL_MSG(_T("no encoding in X font spec?")); + } + + // transfer the X registry/encoding to wxFontData - they are used by + // wxFontMapper after wxFontDialog returns + wxFontData& fontdata = dialog->m_fontData; + + // we ignore the facename here - should be enough to choose an arbitrary + // one if the registry/encoding are specified + // dialog->m_fontData.EncodingInfo().facename = xfamily; + fontdata.EncodingInfo().xregistry = xregistry; + fontdata.EncodingInfo().xencoding = xencoding; + + // pass fontdata to wxFont ctor so that it can get the encoding from there + // if it is already known (otherwise it will try to deduce it itself) + dialog->m_fontData.SetChosenFont( wxFont(fontname, fontdata) ); + g_free( fontname ); - dialog->m_fontData.SetChosenFont( font ); wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK); event.SetEventObject( dialog ); dialog->GetEventHandler()->ProcessEvent( event ); } -#endif // GTK+ 1.2 andlater only +#endif // GTK+ 1.2 and later only //----------------------------------------------------------------------------- // "clicked" for Cancel-button @@ -100,7 +138,8 @@ void gtk_fontdialog_cancel_callback( GtkWidget *WXUNUSED(w), wxFontDialog *dialo IMPLEMENT_DYNAMIC_CLASS(wxFontDialog,wxDialog) -wxFontDialog::wxFontDialog( wxWindow *parent, wxFontData *WXUNUSED(data) ) +wxFontDialog::wxFontDialog( wxWindow *parent, wxFontData *fontdata ) + : m_fontData(*fontdata) { m_needParent = FALSE; diff --git a/src/gtk1/frame.cpp b/src/gtk1/frame.cpp index 1cc37b1a92..369cb25161 100644 --- a/src/gtk1/frame.cpp +++ b/src/gtk1/frame.cpp @@ -85,7 +85,7 @@ static void gtk_frame_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation* (int)alloc->width, (int)alloc->height ); */ - + win->m_width = alloc->width; win->m_height = alloc->height; win->UpdateSize(); @@ -164,14 +164,14 @@ static void gtk_toolbar_detached_callback( GtkWidget *WXUNUSED(widget), GtkWidge // "configure_event" //----------------------------------------------------------------------------- -static gint +static gint #if (GTK_MINOR_VERSON > 0) gtk_frame_configure_callback( GtkWidget *WXUNUSED(widget), GdkEventConfigure *WXUNUSED(event), wxFrame *win ) #else gtk_frame_configure_callback( GtkWidget *WXUNUSED(widget), GdkEventConfigure *event, wxFrame *win ) #endif { - if (g_isIdle) + if (g_isIdle) wxapp_install_idle_handler(); if (!win->m_hasVMT) return FALSE; @@ -255,13 +255,13 @@ gtk_frame_realized_callback( GtkWidget *widget, wxFrame *win ) if ((win->GetMaxWidth() != -1) || (win->GetMaxHeight() != -1)) flag |= GDK_HINT_MAX_SIZE; if (flag) { - gdk_window_set_hints( win->m_widget->window, - win->m_x, win->m_y, - win->GetMinWidth(), win->GetMinHeight(), - win->GetMaxWidth(), win->GetMaxHeight(), - flag ); + gdk_window_set_hints( win->m_widget->window, + win->m_x, win->m_y, + win->GetMinWidth(), win->GetMinHeight(), + win->GetMaxWidth(), win->GetMaxHeight(), + flag ); } - + /* reset the icon */ if (win->m_icon != wxNullIcon) { @@ -300,7 +300,7 @@ gtk_frame_realized_callback( GtkWidget *widget, wxFrame *win ) static void wxInsertChildInFrame( wxFrame* parent, wxWindow* child ) { wxASSERT( GTK_IS_WIDGET(child->m_widget) ); - + if (!parent->m_insertInClientArea) { /* these are outside the client area */ @@ -397,7 +397,7 @@ bool wxFrame::Create( wxWindow *parent, wxWindowID id, const wxString &title, !CreateBase( parent, id, pos, size, style, wxDefaultValidator, name )) { wxFAIL_MSG( wxT("wxFrame creation failed") ); - return FALSE; + return FALSE; } m_title = title; @@ -530,6 +530,7 @@ void wxFrame::DoSetSize( int x, int y, int width, int height, int sizeFlags ) int old_x = m_x; int old_y = m_y; + int old_width = m_width; int old_height = m_height; @@ -693,7 +694,7 @@ void wxFrame::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y), int width, int height m_width = width; m_height = height; - + /* space occupied by m_frameToolBar and m_frameMenuBar */ int client_area_y_offset = 0; @@ -737,7 +738,7 @@ void wxFrame::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y), int width, int height #if wxUSE_TOOLBAR if ((m_frameToolBar) && - (m_frameToolBar->m_widget->parent == m_mainWidget)) + (m_frameToolBar->m_widget->parent == m_mainWidget)) { int xx = m_miniEdge; int yy = m_miniEdge + m_miniTitle; @@ -750,7 +751,7 @@ void wxFrame::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y), int width, int height } int ww = m_width - 2*m_miniEdge; int hh = m_frameToolBar->m_height; - if (m_toolBarDetached) hh = wxPLACE_HOLDER; + if (m_toolBarDetached) hh = wxPLACE_HOLDER; m_frameToolBar->m_x = xx; m_frameToolBar->m_y = yy; /* m_frameToolBar->m_height = hh; don't change the toolbar's reported size @@ -798,7 +799,7 @@ void wxFrame::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y), int width, int height m_sizeSet = TRUE; - + // send size event to frame wxSizeEvent event( wxSize(m_width,m_height), GetId() ); event.SetEventObject( this ); @@ -828,11 +829,11 @@ void wxFrame::OnInternalIdle() if (!m_sizeSet && GTK_WIDGET_REALIZED(m_wxwindow)) { GtkOnSize( m_x, m_y, m_width, m_height ); - - // we'll come back later + + // we'll come back later if (g_isIdle) wxapp_install_idle_handler(); - return; + return; } if (m_frameMenuBar) m_frameMenuBar->OnInternalIdle(); @@ -920,8 +921,8 @@ void wxFrame::SetMenuBar( wxMenuBar *menuBar ) gtk_signal_connect( GTK_OBJECT(menuBar->m_widget), "child_detached", GTK_SIGNAL_FUNC(gtk_menu_detached_callback), (gpointer)this ); } - - m_frameMenuBar->Show( TRUE ); + + m_frameMenuBar->Show( TRUE ); } } @@ -986,9 +987,9 @@ wxToolBar* wxFrame::OnCreateToolBar( long style, wxWindowID id, const wxString& return new wxToolBar( this, id, wxDefaultPosition, wxDefaultSize, style, name ); } -void wxFrame::SetToolBar(wxToolBar *toolbar) -{ - m_frameToolBar = toolbar; +void wxFrame::SetToolBar(wxToolBar *toolbar) +{ + m_frameToolBar = toolbar; if (m_frameToolBar) { /* insert into toolbar area if not already there */ @@ -996,10 +997,10 @@ void wxFrame::SetToolBar(wxToolBar *toolbar) (m_frameToolBar->m_widget->parent != m_mainWidget)) { GetChildren().DeleteObject( m_frameToolBar ); - - gtk_widget_reparent( m_frameToolBar->m_widget, m_mainWidget ); - UpdateSize(); - } + + gtk_widget_reparent( m_frameToolBar->m_widget, m_mainWidget ); + UpdateSize(); + } } } @@ -1113,25 +1114,25 @@ void wxFrame::SetIcon( const wxIcon &icon ) gdk_window_set_icon( m_widget->window, (GdkWindow *) NULL, icon.GetPixmap(), bm ); } -void wxFrame::Maximize(bool WXUNUSED(maximize)) +void wxFrame::Maximize(bool WXUNUSED(maximize)) { } -void wxFrame::Restore() +void wxFrame::Restore() { } -void wxFrame::Iconize( bool iconize ) -{ +void wxFrame::Iconize( bool iconize ) +{ if (iconize) { XIconifyWindow( GDK_WINDOW_XDISPLAY( m_widget->window ), - GDK_WINDOW_XWINDOW( m_widget->window ), - DefaultScreen( GDK_DISPLAY() ) ); + GDK_WINDOW_XWINDOW( m_widget->window ), + DefaultScreen( GDK_DISPLAY() ) ); } } -bool wxFrame::IsIconized() const -{ - return FALSE; +bool wxFrame::IsIconized() const +{ + return FALSE; } diff --git a/src/unix/fontenum.cpp b/src/unix/fontenum.cpp index 4ce2ced9d0..e8a9c18f75 100644 --- a/src/unix/fontenum.cpp +++ b/src/unix/fontenum.cpp @@ -27,6 +27,7 @@ #include "wx/utils.h" #include "wx/fontenum.h" +#include "wx/fontutil.h" #include @@ -61,12 +62,14 @@ static char **CreateFontList(wxChar spacing, wxFontEncoding encoding, int *nFonts) { - wxString xencoding, xregistry; - wxGetXFontEncoding(encoding, &xregistry, &xencoding); + wxNativeEncodingInfo info; + wxGetNativeFontEncoding(encoding, &info); wxString pattern; pattern.Printf(wxT("-*-*-*-*-*-*-*-*-*-*-%c-*-%s-%s"), - spacing, xregistry.c_str(), xencoding.c_str()); + spacing, + info.xregistry.c_str(), + info.xencoding.c_str()); // get the list of all fonts return XListFonts((Display *)wxGetDisplay(), pattern.mb_str(), 32767, nFonts); diff --git a/src/unix/fontutil.cpp b/src/unix/fontutil.cpp new file mode 100644 index 0000000000..c32a5acfbb --- /dev/null +++ b/src/unix/fontutil.cpp @@ -0,0 +1,454 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: unix/fontutil.cpp +// Purpose: Font helper functions for X11 (GDK/X) +// Author: Vadim Zeitlin +// Modified by: +// Created: 05.11.99 +// RCS-ID: $Id$ +// Copyright: (c) Vadim Zeitlin +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + +#ifdef __GNUG__ + #pragma implementation "fontutil.h" +#endif + +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#ifndef WX_PRECOMP +#endif // PCH + +#include "wx/fontutil.h" +#include "wx/fontmap.h" +#include "wx/tokenzr.h" + +// ---------------------------------------------------------------------------- +// private functions +// ---------------------------------------------------------------------------- + +// define the functions to create and destroy native fonts for this toolkit +#ifdef __X__ + static inline wxNativeFont wxLoadFont(const wxString& fontSpec) + { + return XLoadQueryFont((Display *)wxGetDisplay(), fontSpec); + } + + static inline void wxFreeFont(wxNativeFont font) + { + XFreeFont((Display *)wxGetDisplay(), font); + } +#elif defined(__WXGTK__) + #include "gdk/gdk.h" + + static inline wxNativeFont wxLoadFont(const wxString& fontSpec) + { + return gdk_font_load( wxConvertWX2MB(fontSpec) ); + } + + static inline void wxFreeFont(wxNativeFont font) + { + gdk_font_unref(font); + } +#else + #error "Unknown GUI toolkit" +#endif + +static bool wxTestFontSpec(const wxString& fontspec); + +static wxNativeFont wxLoadQueryFont(int pointSize, + int family, + int style, + int weight, + bool underlined, + const wxString& facename, + const wxString& xregistry, + const wxString& xencoding); + +// ============================================================================ +// implementation +// ============================================================================ + +// ---------------------------------------------------------------------------- +// wxNativeEncodingInfo +// ---------------------------------------------------------------------------- + +// convert to/from the string representation: format is +// registry-encoding[-facename] +bool wxNativeEncodingInfo::FromString(const wxString& s) +{ + wxStringTokenizer tokenizer(s, _T("-")); + + xregistry = tokenizer.GetNextToken(); + if ( !xregistry ) + return FALSE; + + xencoding = tokenizer.GetNextToken(); + if ( !xencoding ) + return FALSE; + + // ok even if empty + facename = tokenizer.GetNextToken(); + + return TRUE; +} + +wxString wxNativeEncodingInfo::ToString() const +{ + wxString s; + s << xregistry << _T('-') << xencoding; + if ( !!facename ) + { + s << _T('-') << facename; + } + + return s; +} + +// ---------------------------------------------------------------------------- +// common functions +// ---------------------------------------------------------------------------- + +bool wxGetNativeFontEncoding(wxFontEncoding encoding, + wxNativeEncodingInfo *info) +{ + wxCHECK_MSG( info, FALSE, _T("bad pointer in wxGetNativeFontEncoding") ); + + if ( encoding == wxFONTENCODING_DEFAULT ) + { + encoding = wxFont::GetDefaultEncoding(); + } + + switch ( encoding ) + { + case wxFONTENCODING_ISO8859_1: + case wxFONTENCODING_ISO8859_2: + case wxFONTENCODING_ISO8859_3: + case wxFONTENCODING_ISO8859_4: + case wxFONTENCODING_ISO8859_5: + case wxFONTENCODING_ISO8859_6: + case wxFONTENCODING_ISO8859_7: + case wxFONTENCODING_ISO8859_8: + case wxFONTENCODING_ISO8859_9: + case wxFONTENCODING_ISO8859_10: + case wxFONTENCODING_ISO8859_11: + case wxFONTENCODING_ISO8859_13: + case wxFONTENCODING_ISO8859_14: + case wxFONTENCODING_ISO8859_15: + { + int cp = encoding - wxFONTENCODING_ISO8859_1 + 1; + info->xregistry = wxT("iso8859"); + info->xencoding.Printf(wxT("%d"), cp); + } + break; + + case wxFONTENCODING_KOI8: + info->xregistry = wxT("koi8"); + + // we don't make distinction between koi8-r and koi8-u (so far) + info->xencoding = wxT("*"); + break; + + case wxFONTENCODING_CP1250: + case wxFONTENCODING_CP1251: + case wxFONTENCODING_CP1252: + case wxFONTENCODING_CP1253: + case wxFONTENCODING_CP1254: + case wxFONTENCODING_CP1255: + case wxFONTENCODING_CP1256: + case wxFONTENCODING_CP1257: + { + int cp = encoding - wxFONTENCODING_CP1250 + 1250; + info->xregistry = wxT("microsoft"); + info->xencoding.Printf(wxT("cp%d"), cp); + } + break; + + case wxFONTENCODING_SYSTEM: + info->xregistry = + info->xencoding = wxT('*'); + break; + + default: + // don't know how to translate this encoding into X fontspec + return FALSE; + } + + return TRUE; +} + +bool wxTestFontEncoding(const wxNativeEncodingInfo& info) +{ + wxString fontspec; + fontspec.Printf(_T("-*-%s-*-*-*-*-*-*-*-*-*-*-%s-%s"), + !info.facename ? _T("*") : info.facename.c_str(), + info.xregistry.c_str(), + info.xencoding.c_str()); + + return wxTestFontSpec(fontspec); +} + +// ---------------------------------------------------------------------------- +// X-specific functions +// ---------------------------------------------------------------------------- + +wxNativeFont wxLoadQueryNearestFont(int pointSize, + int family, + int style, + int weight, + bool underlined, + const wxString &facename, + wxFontEncoding encoding) +{ + // 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 ( !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, + underlined, facename, + info.xregistry, info.xencoding ); + + if ( !font ) + { + // 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; + + // Search for smaller size (approx.) + for ( i = pointSize - 10; !font && i >= 10 && i >= min_size; i -= 10 ) + { + font = wxLoadQueryFont(i, family, style, weight, underlined, + facename, info.xregistry, info.xencoding); + } + + // 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); + } + + // Try default family + if ( !font && family != wxDEFAULT ) + { + font = wxLoadQueryFont(pointSize, wxDEFAULT, style, weight, + underlined, facename, + info.xregistry, info.xencoding ); + } + + // Bogus font I + if ( !font ) + { + font = wxLoadQueryFont(120, wxDEFAULT, wxNORMAL, wxNORMAL, + underlined, facename, + info.xregistry, info.xencoding); + } + + // Bogus font II + if ( !font ) + { + font = wxLoadQueryFont(120, wxDEFAULT, wxNORMAL, wxNORMAL, + underlined, wxEmptyString, + info.xregistry, info.xencoding); + } + } + + return font; +} + +// ---------------------------------------------------------------------------- +// private functions +// ---------------------------------------------------------------------------- + +// returns TRUE if there are any fonts matching this font spec +static bool wxTestFontSpec(const wxString& fontspec) +{ + wxNativeFont test = wxLoadFont(fontspec); + if ( test ) + { + wxFreeFont(test); + + return TRUE; + } + else + { + return FALSE; + } +} + +static wxNativeFont wxLoadQueryFont(int pointSize, + int family, + int style, + int weight, + bool WXUNUSED(underlined), + const wxString& facename, + const wxString& xregistry, + const wxString& xencoding) +{ + 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("*"); + } + + wxString fontSpec; + if (!facename.IsEmpty()) + { + fontSpec.Printf(wxT("-*-%s-*-*-normal-*-*-*-*-*-*-*-*-*"), + facename.c_str()); + + if ( wxTestFontSpec(fontSpec) ) + { + xfamily = facename; + } + //else: no such family, use default one instead + } + + 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; + } + + wxString xweight; + switch (weight) + { + case wxBOLD: + { + fontSpec.Printf(wxT("-*-%s-bold-*-*-*-*-*-*-*-*-*-*-*"), + xfamily.c_str()); + if ( wxTestFontSpec(fontSpec) ) + { + xweight = wxT("bold"); + break; + } + fontSpec.Printf(wxT("-*-%s-heavy-*-*-*-*-*-*-*-*-*-*-*"), + xfamily.c_str()); + if ( wxTestFontSpec(fontSpec) ) + { + xweight = wxT("heavy"); + break; + } + fontSpec.Printf(wxT("-*-%s-extrabold-*-*-*-*-*-*-*-*-*-*-*"), + xfamily.c_str()); + if ( wxTestFontSpec(fontSpec) ) + { + xweight = wxT("extrabold"); + break; + } + fontSpec.Printf(wxT("-*-%s-demibold-*-*-*-*-*-*-*-*-*-*-*"), + xfamily.c_str()); + if ( wxTestFontSpec(fontSpec) ) + { + xweight = wxT("demibold"); + break; + } + fontSpec.Printf(wxT("-*-%s-black-*-*-*-*-*-*-*-*-*-*-*"), + xfamily.c_str()); + if ( wxTestFontSpec(fontSpec) ) + { + xweight = wxT("black"); + break; + } + fontSpec.Printf(wxT("-*-%s-ultrablack-*-*-*-*-*-*-*-*-*-*-*"), + xfamily.c_str()); + if ( wxTestFontSpec(fontSpec) ) + { + xweight = wxT("ultrablack"); + break; + } + } + break; + case wxLIGHT: + { + fontSpec.Printf(wxT("-*-%s-light-*-*-*-*-*-*-*-*-*-*-*"), + xfamily.c_str()); + if ( wxTestFontSpec(fontSpec) ) + { + xweight = wxT("light"); + break; + } + fontSpec.Printf(wxT("-*-%s-thin-*-*-*-*-*-*-*-*-*-*-*"), + xfamily.c_str()); + if ( wxTestFontSpec(fontSpec) ) + { + xweight = wxT("thin"); + break; + } + } + break; + case wxNORMAL: + { + fontSpec.Printf(wxT("-*-%s-medium-*-*-*-*-*-*-*-*-*-*-*"), + xfamily.c_str()); + if ( wxTestFontSpec(fontSpec) ) + { + xweight = wxT("medium"); + break; + } + fontSpec.Printf(wxT("-*-%s-normal-*-*-*-*-*-*-*-*-*-*-*"), + xfamily.c_str()); + if ( wxTestFontSpec(fontSpec) ) + { + xweight = wxT("normal"); + break; + } + fontSpec.Printf(wxT("-*-%s-regular-*-*-*-*-*-*-*-*-*-*-*"), + xfamily.c_str()); + if ( wxTestFontSpec(fontSpec) ) + { + xweight = wxT("regular"); + break; + } + xweight = wxT("*"); + } + break; + default: xweight = wxT("*"); break; + } + + // construct the X font spec from our data + fontSpec.Printf(wxT("-*-%s-%s-%s-normal-*-*-%d-*-*-*-*-%s-%s"), + xfamily.c_str(), xweight.c_str(), xstyle.c_str(), + pointSize, xregistry.c_str(), xencoding.c_str()); + + return wxLoadFont(fontSpec); +} + diff --git a/src/unix/utilsunx.cpp b/src/unix/utilsunx.cpp index d3e1dd7ba8..c4a312efbd 100644 --- a/src/unix/utilsunx.cpp +++ b/src/unix/utilsunx.cpp @@ -560,8 +560,6 @@ bool wxGetUserName(wxChar *buf, int sz) return FALSE; } -#if wxUSE_GUI - // ---------------------------------------------------------------------------- // error and debug output routines (deprecated, use wxLog) // ---------------------------------------------------------------------------- @@ -592,358 +590,3 @@ void wxFatalError( const wxString &msg, const wxString &title ) exit(3); // the same exit code as for abort() } -// ---------------------------------------------------------------------------- -// font-related functions -// ---------------------------------------------------------------------------- - -// define the functions to create and destroy native fonts for this toolkit -#ifdef __X__ - static inline wxNativeFont wxLoadFont(const wxString& fontSpec) - { - return XLoadQueryFont((Display *)wxGetDisplay(), fontSpec); - } - - static inline void wxFreeFont(wxNativeFont font) - { - XFreeFont((Display *)wxGetDisplay(), font); - } -#elif defined(__WXGTK__) - - #include "gdk/gdk.h" - - static inline wxNativeFont wxLoadFont(const wxString& fontSpec) - { - return gdk_font_load( wxConvertWX2MB(fontSpec) ); - } - - static inline void wxFreeFont(wxNativeFont font) - { - gdk_font_unref(font); - } -#else - #error "Unknown GUI toolkit" -#endif - -// returns TRUE if there are any fonts matching this font spec -static bool wxTestFontSpec(const wxString& fontspec) -{ - wxNativeFont test = wxLoadFont(fontspec); - if ( test ) - { - wxFreeFont(test); - - return TRUE; - } - else - { - return FALSE; - } -} - -// TODO encoding test logic should be moved to wxLoadQueryNearestFont() -static wxNativeFont wxLoadQueryFont(int pointSize, - int family, - int style, - int weight, - bool WXUNUSED(underlined), - const wxString &facename, - wxFontEncoding encoding ) -{ - 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("*"); - } - - wxString fontSpec; - if (!facename.IsEmpty()) - { - fontSpec.Printf(wxT("-*-%s-*-*-normal-*-*-*-*-*-*-*-*-*"), - facename.c_str()); - - if ( wxTestFontSpec(fontSpec) ) - { - xfamily = facename; - } - //else: no such family, use default one instead - } - - 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; - } - - wxString xweight; - switch (weight) - { - case wxBOLD: - { - fontSpec.Printf(wxT("-*-%s-bold-*-*-*-*-*-*-*-*-*-*-*"), - xfamily.c_str()); - if ( wxTestFontSpec(fontSpec) ) - { - xweight = wxT("bold"); - break; - } - fontSpec.Printf(wxT("-*-%s-heavy-*-*-*-*-*-*-*-*-*-*-*"), - xfamily.c_str()); - if ( wxTestFontSpec(fontSpec) ) - { - xweight = wxT("heavy"); - break; - } - fontSpec.Printf(wxT("-*-%s-extrabold-*-*-*-*-*-*-*-*-*-*-*"), - xfamily.c_str()); - if ( wxTestFontSpec(fontSpec) ) - { - xweight = wxT("extrabold"); - break; - } - fontSpec.Printf(wxT("-*-%s-demibold-*-*-*-*-*-*-*-*-*-*-*"), - xfamily.c_str()); - if ( wxTestFontSpec(fontSpec) ) - { - xweight = wxT("demibold"); - break; - } - fontSpec.Printf(wxT("-*-%s-black-*-*-*-*-*-*-*-*-*-*-*"), - xfamily.c_str()); - if ( wxTestFontSpec(fontSpec) ) - { - xweight = wxT("black"); - break; - } - fontSpec.Printf(wxT("-*-%s-ultrablack-*-*-*-*-*-*-*-*-*-*-*"), - xfamily.c_str()); - if ( wxTestFontSpec(fontSpec) ) - { - xweight = wxT("ultrablack"); - break; - } - } - break; - case wxLIGHT: - { - fontSpec.Printf(wxT("-*-%s-light-*-*-*-*-*-*-*-*-*-*-*"), - xfamily.c_str()); - if ( wxTestFontSpec(fontSpec) ) - { - xweight = wxT("light"); - break; - } - fontSpec.Printf(wxT("-*-%s-thin-*-*-*-*-*-*-*-*-*-*-*"), - xfamily.c_str()); - if ( wxTestFontSpec(fontSpec) ) - { - xweight = wxT("thin"); - break; - } - } - break; - case wxNORMAL: - { - fontSpec.Printf(wxT("-*-%s-medium-*-*-*-*-*-*-*-*-*-*-*"), - xfamily.c_str()); - if ( wxTestFontSpec(fontSpec) ) - { - xweight = wxT("medium"); - break; - } - fontSpec.Printf(wxT("-*-%s-normal-*-*-*-*-*-*-*-*-*-*-*"), - xfamily.c_str()); - if ( wxTestFontSpec(fontSpec) ) - { - xweight = wxT("normal"); - break; - } - fontSpec.Printf(wxT("-*-%s-regular-*-*-*-*-*-*-*-*-*-*-*"), - xfamily.c_str()); - if ( wxTestFontSpec(fontSpec) ) - { - xweight = wxT("regular"); - break; - } - xweight = wxT("*"); - } - break; - default: xweight = wxT("*"); break; - } - - wxString xregistry, xencoding; - if ( !wxGetXFontEncoding(encoding, &xregistry, &xencoding) ) - { - fontSpec.Printf(wxT("-*-*-*-*-*-*-*-*-*-*-*-*-%s-%s"), - xregistry.c_str(), xencoding.c_str()); - if ( !wxTestFontSpec(fontSpec) ) - { - // this encoding isn't available - what to do? - xregistry = - xencoding = wxT("*"); - } - } - - // construct the X font spec from our data - fontSpec.Printf(wxT("-*-%s-%s-%s-normal-*-*-%d-*-*-*-*-%s-%s"), - xfamily.c_str(), xweight.c_str(), xstyle.c_str(), - pointSize, xregistry.c_str(), xencoding.c_str()); - - return wxLoadFont(fontSpec); -} - -bool wxGetXFontEncoding(wxFontEncoding encoding, - wxString *pregistry, wxString *pencoding) -{ - wxCHECK_MSG( pencoding && pregistry, FALSE, wxT("bad pointer") ); - - wxString& xencoding = *pencoding; - wxString& xregistry = *pregistry; - - if ( encoding == wxFONTENCODING_DEFAULT ) - { - // use the apps default - encoding = wxFont::GetDefaultEncoding(); - } - - bool test = TRUE; // should we test for availability of encoding? - switch ( encoding ) - { - case wxFONTENCODING_ISO8859_1: - case wxFONTENCODING_ISO8859_2: - case wxFONTENCODING_ISO8859_3: - case wxFONTENCODING_ISO8859_4: - case wxFONTENCODING_ISO8859_5: - case wxFONTENCODING_ISO8859_6: - case wxFONTENCODING_ISO8859_7: - case wxFONTENCODING_ISO8859_8: - case wxFONTENCODING_ISO8859_9: - case wxFONTENCODING_ISO8859_10: - case wxFONTENCODING_ISO8859_11: - case wxFONTENCODING_ISO8859_13: - case wxFONTENCODING_ISO8859_14: - case wxFONTENCODING_ISO8859_15: - { - int cp = encoding - wxFONTENCODING_ISO8859_1 + 1; - xregistry = wxT("iso8859"); - xencoding.Printf(wxT("%d"), cp); - } - break; - - case wxFONTENCODING_KOI8: - xregistry = wxT("koi8"); - if ( wxTestFontSpec(wxT("-*-*-*-*-*-*-*-*-*-*-*-*-koi8-1")) ) - { - xencoding = wxT("1"); - - // test passed, no need to do it once more - test = FALSE; - } - else - { - xencoding = wxT("*"); - } - break; - - case wxFONTENCODING_CP1250: - case wxFONTENCODING_CP1251: - case wxFONTENCODING_CP1252: - { - int cp = encoding - wxFONTENCODING_CP1250 + 1250; - wxString fontSpec; - fontSpec.Printf(wxT("-*-*-*-*-*-*-*-*-*-*-*-*-microsoft-cp%d"), - cp); - if ( wxTestFontSpec(fontSpec) ) - { - xregistry = wxT("microsoft"); - xencoding.Printf(wxT("cp%d"), cp); - - // test passed, no need to do it once more - test = FALSE; - } - else - { - // fall back to LatinX - xregistry = wxT("iso8859"); - xencoding.Printf(wxT("%d"), cp - 1249); - } - } - break; - - case wxFONTENCODING_SYSTEM: - default: - test = FALSE; - xregistry = - xencoding = wxT("*"); - } - - return !test; -} - -wxNativeFont wxLoadQueryNearestFont(int pointSize, - int family, - int style, - int weight, - bool underlined, - const wxString &facename, - wxFontEncoding encoding) -{ - wxNativeFont font = wxLoadQueryFont( pointSize, family, style, weight, - underlined, facename, encoding ); - - if (!font) - { - // 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; - - // Search for smaller size (approx.) - for ( i = pointSize - 10; !font && i >= 10 && i >= min_size; i -= 10 ) - { - font = wxLoadQueryFont(i, family, style, weight, underlined, - facename, encoding ); - } - - // Search for larger size (approx.) - for ( i = pointSize + 10; !font && i <= max_size; i += 10 ) - { - font = wxLoadQueryFont( i, family, style, weight, underlined, - facename, encoding ); - } - - // Try default family - if ( !font && family != wxDEFAULT ) - { - font = wxLoadQueryFont( pointSize, wxDEFAULT, style, weight, - underlined, facename, encoding ); - } - - // Bogus font I - if ( !font ) - { - font = wxLoadQueryFont(120, wxDEFAULT, wxNORMAL, wxNORMAL, - underlined, facename, encoding ); - } - - // Bogus font II - if ( !font ) - { - font = wxLoadQueryFont(120, wxDEFAULT, wxNORMAL, wxNORMAL, - underlined, wxEmptyString, encoding ); - } - } - - return font; -} - -#endif // wxUSE_GUI