+// ----------------------------------------------------------------------------
+// wxNativeFontInfo
+// ----------------------------------------------------------------------------
+
+void wxNativeFontInfo::Init()
+{
+    m_isDefault = TRUE;
+}
+
+bool wxNativeFontInfo::FromString(const wxString& s)
+{
+    wxStringTokenizer tokenizer(s, _T(";"));
+
+    // check the version
+    wxString token = tokenizer.GetNextToken();
+    if ( token != _T('0') )
+        return FALSE;
+
+    xFontName = tokenizer.GetNextToken();
+
+    // this should be the end
+    if ( tokenizer.HasMoreTokens() )
+        return FALSE;
+
+    return FromXFontName(xFontName);
+}
+
+wxString wxNativeFontInfo::ToString() const
+{
+    // 0 is the version
+    return wxString::Format(_T("%d;%s"), 0, GetXFontName().c_str());
+}
+
+bool wxNativeFontInfo::FromUserString(const wxString& s)
+{
+    return FromXFontName(s);
+}
+
+wxString wxNativeFontInfo::ToUserString() const
+{
+    return GetXFontName();
+}
+
+bool wxNativeFontInfo::HasElements() const
+{
+    // we suppose that the foundry is never empty, so if it is it means that we
+    // had never parsed the XLFD
+    return !fontElements[0].empty();
+}
+
+wxString wxNativeFontInfo::GetXFontComponent(wxXLFDField field) const
+{
+    wxCHECK_MSG( field < wxXLFD_MAX, _T(""), _T("invalid XLFD field") );
+
+    if ( !HasElements() )
+    {
+        // 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?
+    wxStringTokenizer tokenizer(fontname, _T("-"));
+
+    // skip the leading, usually empty field (font name registry)
+    if ( !tokenizer.HasMoreTokens() )
+        return FALSE;
+
+    (void)tokenizer.GetNextToken();
+
+    for ( size_t n = 0; n < WXSIZEOF(fontElements); n++ )
+    {
+        if ( !tokenizer.HasMoreTokens() )
+        {
+            // not enough elements in the XLFD - or maybe an alias
+            return FALSE;
+        }
+
+        wxString field = tokenizer.GetNextToken();
+        if ( !field.empty() && field != _T('*') )
+        {
+            // we're really initialized now
+            m_isDefault = FALSE;
+        }
+
+        fontElements[n] = field;
+    }
+
+    // this should be all
+    if ( tokenizer.HasMoreTokens() )
+        return FALSE;
+
+    return TRUE;
+}
+
+wxString wxNativeFontInfo::GetXFontName() const
+{
+    if ( xFontName.empty() )
+    {
+        for ( size_t n = 0; n < WXSIZEOF(fontElements); n++ )
+        {
+            // replace the non specified elements with '*' except for the
+            // additional style which is usually just omitted
+            wxString elt = fontElements[n];
+            if ( elt.empty() && n != wxXLFD_ADDSTYLE )
+            {
+                elt = _T('*');
+            }
+
+            // const_cast
+            ((wxNativeFontInfo *)this)->xFontName << _T('-') << elt;
+        }
+    }
+
+    return xFontName;
+}
+
+void
+wxNativeFontInfo::SetXFontComponent(wxXLFDField field, const wxString& value)
+{
+    wxCHECK_RET( field < wxXLFD_MAX, _T("invalid XLFD field") );
+
+    // this class should be initialized with a valid font spec first and only
+    // then the fields may be modified!
+    wxASSERT_MSG( !IsDefault(), _T("can't modify an uninitialized XLFD") );
+
+    if ( !HasElements() )
+    {
+        // const_cast
+        if ( !((wxNativeFontInfo *)this)->FromXFontName(xFontName) )
+        {
+            wxFAIL_MSG( _T("can't set font element for invalid XLFD") );
+
+            return;
+        }
+    }
+
+    fontElements[field] = value;
+
+    // invalidate the XFLD, it doesn't correspond to the font elements any more
+    xFontName.clear();
+}
+
+void wxNativeFontInfo::SetXFontName(const wxString& xFontName_)
+{
+    // invalidate the font elements, GetXFontComponent() will reparse the XLFD
+    fontElements[0].clear();
+
+    xFontName = xFontName_;
+
+    m_isDefault = FALSE;
+}
+
+int wxNativeFontInfo::GetPointSize() const
+{
+    const wxString s = GetXFontComponent(wxXLFD_POINTSIZE);
+
+    // return -1 to indicate that the size is unknown
+    long l;
+    return s.ToLong(&l) ? l : -1;
+}
+
+wxFontStyle wxNativeFontInfo::GetStyle() const
+{
+    const wxString s = GetXFontComponent(wxXLFD_SLANT);
+
+    if ( s.length() != 1 )
+    {
+        // it is really unknown but we don't have any way to return it from
+        // here
+        return wxFONTSTYLE_NORMAL;
+    }
+
+    switch ( s[0] )
+    {
+        default:
+            // again, unknown but consider normal by default
+
+        case _T('r'):
+            return wxFONTSTYLE_NORMAL;
+
+        case _T('i'):
+            return wxFONTSTYLE_ITALIC;
+
+        case _T('o'):
+            return wxFONTSTYLE_SLANT;
+    }
+}
+
+wxFontWeight wxNativeFontInfo::GetWeight() const
+{
+    const wxString s = GetXFontComponent(wxXLFD_WEIGHT).MakeLower();
+    if ( s.find(_T("bold")) != wxString::npos || s == _T("black") )
+        return wxFONTWEIGHT_BOLD;
+    else if ( s == _T("light") )
+        return wxFONTWEIGHT_LIGHT;
+
+    return wxFONTWEIGHT_NORMAL;
+}
+
+bool wxNativeFontInfo::GetUnderlined() const
+{
+    // X fonts are never underlined
+    return FALSE;
+}
+
+wxString wxNativeFontInfo::GetFaceName() const
+{
+    // wxWindows facename probably more accurately corresponds to X family
+    return GetXFontComponent(wxXLFD_FAMILY);
+}
+
+wxFontFamily wxNativeFontInfo::GetFamily() const
+{
+    // and wxWindows family -- to X foundry, but we have to translate it to
+    // wxFontFamily somehow...
+    wxFAIL_MSG(_T("not implemented")); // GetXFontComponent(wxXLFD_FOUNDRY);
+
+    return wxFONTFAMILY_DEFAULT;
+}
+
+wxFontEncoding wxNativeFontInfo::GetEncoding() const
+{
+    // we already have the code for this but need to refactor it first
+    wxFAIL_MSG( _T("not implemented") );
+
+    return wxFONTENCODING_MAX;
+}
+
+void wxNativeFontInfo::SetPointSize(int pointsize)
+{
+    SetXFontComponent(wxXLFD_POINTSIZE, wxString::Format(_T("%d"), pointsize));
+}
+
+void wxNativeFontInfo::SetStyle(wxFontStyle style)
+{
+    wxString s;
+    switch ( style )
+    {
+        case wxFONTSTYLE_ITALIC:
+            s = _T('i');
+            break;
+
+        case wxFONTSTYLE_SLANT:
+            s = _T('o');
+            break;
+
+        case wxFONTSTYLE_NORMAL:
+            s = _T('r');
+
+        default:
+            wxFAIL_MSG( _T("unknown wxFontStyle in wxNativeFontInfo::SetStyle") );
+            return;
+    }
+
+    SetXFontComponent(wxXLFD_SLANT, s);
+}
+
+void wxNativeFontInfo::SetWeight(wxFontWeight weight)
+{
+    wxString s;
+    switch ( weight )
+    {
+        case wxFONTWEIGHT_BOLD:
+            s = _T("bold");
+            break;
+
+        case wxFONTWEIGHT_LIGHT:
+            s = _T("light");
+            break;
+
+        case wxFONTWEIGHT_NORMAL:
+            s = _T("medium");
+            break;
+
+        default:
+            wxFAIL_MSG( _T("unknown wxFontWeight in wxNativeFontInfo::SetWeight") );
+            return;
+    }
+
+    SetXFontComponent(wxXLFD_WEIGHT, s);
+}
+
+void wxNativeFontInfo::SetUnderlined(bool WXUNUSED(underlined))
+{
+    // can't do this under X
+}
+
+void wxNativeFontInfo::SetFaceName(wxString facename)
+{
+    SetXFontComponent(wxXLFD_FAMILY, facename);
+}
+
+void wxNativeFontInfo::SetFamily(wxFontFamily family)
+{
+    // wxFontFamily -> X foundry, anyone?
+    wxFAIL_MSG( _T("not implemented") );
+
+    // SetXFontComponent(wxXLFD_FOUNDRY, ...);
+}
+
+void wxNativeFontInfo::SetEncoding(wxFontEncoding encoding)
+{
+    wxNativeEncodingInfo info;
+    if ( wxGetNativeFontEncoding(encoding, &info) )
+    {
+        SetXFontComponent(wxXLFD_ENCODING, info.xencoding);
+        SetXFontComponent(wxXLFD_REGISTRY, info.xregistry);
+    }
+}
+