From 53f6aab75294c585e53e02b618a09dcb1dd97fb8 Mon Sep 17 00:00:00 2001
From: Vadim Zeitlin <vadim@wxwidgets.org>
Date: Mon, 14 Jan 2002 19:04:35 +0000
Subject: [PATCH] added wxFont::IsFixedWidth(), documented it and implemented
 for wxGTK/Motif

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@13570 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
---
 docs/latex/wx/font.tex |  7 +++++++
 include/wx/font.h      |  2 ++
 include/wx/fontutil.h  | 35 +++++++++++++++++++++++++++++++++--
 include/wx/gtk/font.h  |  4 ++++
 include/wx/gtk1/font.h |  4 ++++
 samples/font/font.cpp  | 32 +++++++++++++++++++++++---------
 src/common/fontcmn.cpp |  5 +++++
 src/gtk/font.cpp       | 20 ++++++++++++++++++++
 src/gtk1/font.cpp      | 20 ++++++++++++++++++++
 src/unix/fontutil.cpp  | 14 ++++++++++++++
 10 files changed, 132 insertions(+), 11 deletions(-)

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(),
+                        GetEncodingDescription(m_font.GetEncoding()).c_str());
+
+    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.GetWeightString().c_str(),
+                    m_font.IsFixedWidth() ? _T("yes") : _T("no"));
 
-    dc.DrawText(fontInfo, 5, 5);
+    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?
-- 
2.50.0

