diff --git a/docs/latex/wx/font.tex b/docs/latex/wx/font.tex index 7fa1453b5a..64be90e3c7 100644 --- a/docs/latex/wx/font.tex +++ b/docs/latex/wx/font.tex @@ -174,6 +174,13 @@ the application should try to clean up all fonts itself. This is because wxWindows cannot know if a pointer to the font object is stored in an application data structure, and there is a risk of double deletion. +\membersection{wxFont::IsFixedWidth}\label{wxfontisfixedwidth} + +\constfunc{bool}{IsFixedWidth}{\void} + +Returns {\tt TRUE} if the font is a fixed width (or monospaced) font, +{\tt FALSE} if it is a proportional one or font is invalid. + \membersection{wxFont::GetDefaultEncoding}\label{wxfontgetdefaultencoding} \func{static wxFontEncoding}{GetDefaultEncoding}{\void} diff --git a/include/wx/font.h b/include/wx/font.h index 7eac1f1dc5..eb507cfd24 100644 --- a/include/wx/font.h +++ b/include/wx/font.h @@ -113,6 +113,8 @@ public: virtual wxFontEncoding GetEncoding() const = 0; virtual wxNativeFontInfo *GetNativeFontInfo() const; + virtual bool IsFixedWidth() const; + wxString GetNativeFontInfoDesc() const; wxString GetNativeFontInfoUserDesc() const; diff --git a/include/wx/fontutil.h b/include/wx/fontutil.h index ad966ea606..8305e1417a 100644 --- a/include/wx/fontutil.h +++ b/include/wx/fontutil.h @@ -31,6 +31,30 @@ #include "wx/msw/winundef.h" #endif +#if defined(_WX_X_FONTLIKE) + +// the symbolic names for the XLFD fields (with examples for their value) +enum wxXLFDField +{ + wxXLFD_FOUNDRY, // adobe + wxXLFD_FAMILY, // courier, times, ... + wxXLFD_WEIGHT, // black, bold, demibold, medium, regular, light + wxXLFD_SLANT, // r/i/o (roman/italique/oblique) + wxXLFD_SETWIDTH, // condensed, expanded, ... + wxXLFD_ADDSTYLE, // whatever - usually nothing + wxXLFD_PIXELSIZE, // size in pixels + wxXLFD_POINTSIZE, // size in points + wxXLFD_RESX, // 72, 75, 100, ... + wxXLFD_RESY, + wxXLFD_SPACING, // m/p/c (monospaced/proportional/character cell) + wxXLFD_AVGWIDTH, // average width in 1/10 pixels + wxXLFD_REGISTRY, // iso8859, rawin, koi8, ... + wxXLFD_ENCODING, // 1, r, r, ... + wxXLFD_MAX +}; + +#endif // _WX_X_FONTLIKE + // ---------------------------------------------------------------------------- // types // ---------------------------------------------------------------------------- @@ -45,10 +69,14 @@ // further it might make sense to make it a real class with virtual methods struct WXDLLEXPORT wxNativeFontInfo { -#if defined(__WXGTK__) || defined(__WXMOTIF__) +#if defined(_WX_X_FONTLIKE) + // the fonts array can't be accessed directly as we only parse the + // xFontName when needed +private: // the components of the XLFD - wxString fontElements[14]; + wxString fontElements[wxXLFD_MAX]; +public: // the full XLFD wxString xFontName; @@ -57,6 +85,9 @@ struct WXDLLEXPORT wxNativeFontInfo // generate an XLFD using the fontElements wxString GetXFontName() const; + + // get the given XFLD component + wxString GetXFontComponent(wxXLFDField field) const; #elif defined(__WXMSW__) LOGFONT lf; #elif defined(__WXPM__) diff --git a/include/wx/gtk/font.h b/include/wx/gtk/font.h index 0a2bfbb095..de17523e9f 100644 --- a/include/wx/gtk/font.h +++ b/include/wx/gtk/font.h @@ -86,6 +86,7 @@ public: virtual bool GetUnderlined() const; virtual wxFontEncoding GetEncoding() const; virtual wxNativeFontInfo *GetNativeFontInfo() const; + virtual bool IsFixedWidth() const; virtual void SetPointSize( int pointSize ); virtual void SetFamily( int family ); @@ -107,6 +108,9 @@ protected: // common part of all ctors void Init(); + // do we have the XFLD for this font (or just wxWin description)? + inline bool HasNativeFont() const; + private: DECLARE_DYNAMIC_CLASS(wxFont) }; diff --git a/include/wx/gtk1/font.h b/include/wx/gtk1/font.h index 0a2bfbb095..de17523e9f 100644 --- a/include/wx/gtk1/font.h +++ b/include/wx/gtk1/font.h @@ -86,6 +86,7 @@ public: virtual bool GetUnderlined() const; virtual wxFontEncoding GetEncoding() const; virtual wxNativeFontInfo *GetNativeFontInfo() const; + virtual bool IsFixedWidth() const; virtual void SetPointSize( int pointSize ); virtual void SetFamily( int family ); @@ -107,6 +108,9 @@ protected: // common part of all ctors void Init(); + // do we have the XFLD for this font (or just wxWin description)? + inline bool HasNativeFont() const; + private: DECLARE_DYNAMIC_CLASS(wxFont) }; diff --git a/samples/font/font.cpp b/samples/font/font.cpp index a88746d28e..69e2621c5b 100644 --- a/samples/font/font.cpp +++ b/samples/font/font.cpp @@ -180,7 +180,7 @@ bool MyApp::OnInit() { // Create the main application window MyFrame *frame = new MyFrame("Font wxWindows demo", - wxPoint(50, 50), wxSize(450, 340)); + wxPoint(50, 50), wxSize(600, 400)); // Show it and tell the application that it's our main window frame->Show(TRUE); @@ -625,28 +625,42 @@ void MyCanvas::OnPaint( wxPaintEvent &WXUNUSED(event) ) dc.SetBackground(wxBrush(wxT("white"), wxSOLID)); dc.Clear(); + // one text line height + wxCoord hLine = dc.GetCharHeight(); + + // the current text origin + wxCoord x = 5, + y = 5; + // output the font name/info wxString fontInfo; - fontInfo.Printf(wxT("Font size is %d points, family is %s, encoding is '%s', style %s, weight %s"), + fontInfo.Printf(wxT("Font size is %d points, family: %s, encoding: %s"), m_font.GetPointSize(), m_font.GetFamilyString().c_str(), wxTheFontMapper-> - GetEncodingDescription(m_font.GetEncoding()).c_str(), - m_font.GetStyleString().c_str(), - m_font.GetWeightString().c_str()); + GetEncodingDescription(m_font.GetEncoding()).c_str()); - dc.DrawText(fontInfo, 5, 5); + dc.DrawText(fontInfo, x, y); + y += hLine; + + fontInfo.Printf(wxT("Style: %s, weight: %s, fixed width: %s"), + m_font.GetStyleString().c_str(), + m_font.GetWeightString().c_str(), + m_font.IsFixedWidth() ? _T("yes") : _T("no")); + + dc.DrawText(fontInfo, x, y); + y += hLine; if ( m_font.Ok() ) { wxString fontDesc = m_font.GetNativeFontInfoUserDesc(); fontInfo.Printf(wxT("Native font info: %s"), fontDesc.c_str()); - dc.DrawText(fontInfo, 5, 5 + dc.GetCharHeight()); + + dc.DrawText(fontInfo, x, y); + y += hLine; } - // the origin for our table - int x = 5, - y = dc.GetCharHeight() * (2 + 1); + y += hLine; // prepare to draw the font dc.SetFont(m_font); diff --git a/src/common/fontcmn.cpp b/src/common/fontcmn.cpp index b8a4497f8b..320d37935e 100644 --- a/src/common/fontcmn.cpp +++ b/src/common/fontcmn.cpp @@ -82,6 +82,11 @@ wxFont *wxFontBase::New(const wxString& strNativeFontDesc) return New(fontInfo); } +bool wxFontBase::IsFixedWidth() const +{ + return GetFamily() == wxFONTFAMILY_TELETYPE; +} + wxNativeFontInfo *wxFontBase::GetNativeFontInfo() const { #ifdef wxNO_NATIVE_FONTINFO diff --git a/src/gtk/font.cpp b/src/gtk/font.cpp index d1239aba25..940b38d81a 100644 --- a/src/gtk/font.cpp +++ b/src/gtk/font.cpp @@ -307,6 +307,11 @@ wxFont::~wxFont() // accessors // ---------------------------------------------------------------------------- +bool wxFont::HasNativeFont() const +{ + return !M_FONTDATA->m_nativeFontInfo.xFontName.empty(); +} + int wxFont::GetPointSize() const { wxCHECK_MSG( Ok(), 0, wxT("invalid font") ); @@ -367,6 +372,21 @@ wxNativeFontInfo *wxFont::GetNativeFontInfo() const return new wxNativeFontInfo(M_FONTDATA->m_nativeFontInfo); } +bool wxFont::IsFixedWidth() const +{ + wxCHECK_MSG( Ok(), FALSE, wxT("invalid font") ); + + if ( HasNativeFont() ) + { + // the monospace fonts are supposed to have "M" in the spacing field + wxString spacing = M_FONTDATA-> + m_nativeFontInfo.GetXFontComponent(wxXLFD_SPACING); + + return spacing.Upper() == _T('M'); + } + + return wxFontBase::IsFixedWidth(); +} // ---------------------------------------------------------------------------- // change font attributes diff --git a/src/gtk1/font.cpp b/src/gtk1/font.cpp index d1239aba25..940b38d81a 100644 --- a/src/gtk1/font.cpp +++ b/src/gtk1/font.cpp @@ -307,6 +307,11 @@ wxFont::~wxFont() // accessors // ---------------------------------------------------------------------------- +bool wxFont::HasNativeFont() const +{ + return !M_FONTDATA->m_nativeFontInfo.xFontName.empty(); +} + int wxFont::GetPointSize() const { wxCHECK_MSG( Ok(), 0, wxT("invalid font") ); @@ -367,6 +372,21 @@ wxNativeFontInfo *wxFont::GetNativeFontInfo() const return new wxNativeFontInfo(M_FONTDATA->m_nativeFontInfo); } +bool wxFont::IsFixedWidth() const +{ + wxCHECK_MSG( Ok(), FALSE, wxT("invalid font") ); + + if ( HasNativeFont() ) + { + // the monospace fonts are supposed to have "M" in the spacing field + wxString spacing = M_FONTDATA-> + m_nativeFontInfo.GetXFontComponent(wxXLFD_SPACING); + + return spacing.Upper() == _T('M'); + } + + return wxFontBase::IsFixedWidth(); +} // ---------------------------------------------------------------------------- // change font attributes diff --git a/src/unix/fontutil.cpp b/src/unix/fontutil.cpp index 0da307c8d5..27c2de464a 100644 --- a/src/unix/fontutil.cpp +++ b/src/unix/fontutil.cpp @@ -196,6 +196,20 @@ wxString wxNativeFontInfo::ToUserString() const return GetXFontName(); } +wxString wxNativeFontInfo::GetXFontComponent(wxXLFDField field) const +{ + wxCHECK_MSG( field < wxXLFD_MAX, _T(""), _T("invalid XLFD field") ); + + if ( fontElements[0].empty() ) + { + // const_cast + if ( !((wxNativeFontInfo *)this)->FromXFontName(xFontName) ) + return _T(""); + } + + return fontElements[field]; +} + bool wxNativeFontInfo::FromXFontName(const wxString& fontname) { // TODO: we should be able to handle the font aliases here, but how?