X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/2b5f62a0b2db198609b45dec622a018dae37008e..af4d748440f97aa6e37ab44dfc3fd14b7f42868e:/src/x11/font.cpp diff --git a/src/x11/font.cpp b/src/x11/font.cpp index 8cd3bba65c..0855e067a3 100644 --- a/src/x11/font.cpp +++ b/src/x11/font.cpp @@ -9,6 +9,9 @@ // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// +// for compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + // ============================================================================ // declarations // ============================================================================ @@ -17,10 +20,6 @@ // headers // ---------------------------------------------------------------------------- -#ifdef __GNUG__ - #pragma implementation "font.h" -#endif - #ifdef __VMS #pragma message disable nosimpint #include "wx/vms_x_fix.h" @@ -30,14 +29,18 @@ #pragma message enable nosimpint #endif -#include "wx/defs.h" -#include "wx/string.h" #include "wx/font.h" -#include "wx/gdicmn.h" -#include "wx/utils.h" // for wxGetDisplay() + +#ifndef WX_PRECOMP + #include "wx/string.h" + #include "wx/utils.h" // for wxGetDisplay() + #include "wx/settings.h" + #include "wx/gdicmn.h" +#endif + #include "wx/fontutil.h" // for wxNativeFontInfo #include "wx/tokenzr.h" -#include "wx/settings.h" +#include "wx/fontenum.h" #include "wx/x11/private.h" @@ -63,7 +66,7 @@ class wxXFont : public wxObject { public: wxXFont(); - ~wxXFont(); + virtual ~wxXFont(); WXFontStructPtr m_fontStruct; // XFontStruct WXDisplay* m_display; // XDisplay @@ -79,10 +82,10 @@ wxXFont::wxXFont() wxXFont::~wxXFont() { - // TODO: why does freeing the font produce a segv??? - // Note that XFreeFont wasn't called in wxWin 1.68 either. - // XFontStruct* fontStruct = (XFontStruct*) m_fontStruct; - // XFreeFont((Display*) m_display, fontStruct); + // Freeing the font used to produce a segv, but + // appears to be OK now (bug fix in X11?) + XFontStruct* fontStruct = (XFontStruct*) m_fontStruct; + XFreeFont((Display*) m_display, fontStruct); } #endif @@ -90,7 +93,7 @@ wxXFont::~wxXFont() // wxFontRefData // ---------------------------------------------------------------------------- -class wxFontRefData: public wxObjectRefData +class wxFontRefData: public wxGDIRefData { friend class wxFont; @@ -99,16 +102,16 @@ public: int family = wxDEFAULT, int style = wxDEFAULT, int weight = wxDEFAULT, - bool underlined = FALSE, + bool underlined = false, const wxString& faceName = wxEmptyString, wxFontEncoding encoding = wxFONTENCODING_DEFAULT); // copy cstr wxFontRefData(const wxFontRefData& data); - + // from XFLD wxFontRefData(const wxString& fontname); - + // dstr virtual ~wxFontRefData(); @@ -119,15 +122,15 @@ public: void SetStyle(int style); void SetWeight(int weight); void SetUnderlined(bool underlined); - void SetFaceName(const wxString& facename); + bool SetFaceName(const wxString& facename); void SetEncoding(wxFontEncoding encoding); - void SetNoAntiAliasing( bool no = TRUE ) { m_noAA = no; } - bool GetNoAntiAliasing() { return m_noAA; } - + void SetNoAntiAliasing( bool no = true ) { m_noAA = no; } + bool GetNoAntiAliasing() const { return m_noAA; } + // and this one also modifies all the other font data fields void SetNativeFontInfo(const wxNativeFontInfo& info); - + protected: // common part of all ctors void Init(int size, @@ -140,7 +143,7 @@ protected: // set all fields from (already initialized and valid) m_nativeFontInfo void InitFromNative(); - + // font attributes int m_pointSize; int m_family; @@ -152,7 +155,7 @@ protected: bool m_noAA; // No anti-aliasing wxNativeFontInfo m_nativeFontInfo; - + void ClearX11Fonts(); #if wxUSE_UNICODE @@ -162,6 +165,8 @@ protected: #endif }; +#define M_FONTDATA ((wxFontRefData*)m_refData) + // ---------------------------------------------------------------------------- // wxFontRefData // ---------------------------------------------------------------------------- @@ -182,42 +187,52 @@ void wxFontRefData::Init(int pointSize, m_style = style == wxDEFAULT ? wxFONTSTYLE_NORMAL : style; m_weight = weight == wxDEFAULT ? wxFONTWEIGHT_NORMAL : weight; - // and here, do we really want to forbid creation of the font of the size - // 90 (the value of wxDEFAULT)?? - m_pointSize = pointSize == wxDEFAULT || pointSize == -1 - ? wxDEFAULT_FONT_SIZE - : pointSize; - m_underlined = underlined; m_encoding = encoding; - + #if wxUSE_UNICODE + if ( m_nativeFontInfo.description ) + pango_font_description_free(m_nativeFontInfo.description); + // Create native font info m_nativeFontInfo.description = pango_font_description_new(); - // And set its values - switch (m_family) + // if a face name is specified, use it if it's available, otherwise use + // just the family + if ( faceName.empty() || !wxFontEnumerator::IsValidFacename(faceName) ) { - case wxFONTFAMILY_MODERN: - case wxFONTFAMILY_TELETYPE: - pango_font_description_set_family( m_nativeFontInfo.description, "monospace" ); - break; - case wxFONTFAMILY_SWISS: - pango_font_description_set_family( m_nativeFontInfo.description, "serif" ); - break; - default: - pango_font_description_set_family( m_nativeFontInfo.description, "sans" ); - break; + // TODO: scan system for valid fonts matching the given family instead + // of hardcoding them here + switch ( m_family ) + { + case wxFONTFAMILY_TELETYPE: + m_faceName = wxT("monospace"); + break; + + case wxFONTFAMILY_ROMAN: + m_faceName = wxT("serif"); + break; + + default: + m_faceName = wxT("sans"); + } } - SetStyle( m_style ); - SetPointSize( m_pointSize ); - SetWeight( m_weight ); -#endif + else // specified face name is available, use it + { + m_faceName = faceName; + } + + m_nativeFontInfo.SetFaceName(m_faceName); + m_nativeFontInfo.SetWeight((wxFontWeight)m_weight); + m_nativeFontInfo.SetStyle((wxFontStyle)m_style); +#endif // wxUSE_UNICODE + + SetPointSize(pointSize); } void wxFontRefData::InitFromNative() { - m_noAA = FALSE; + m_noAA = false; #if wxUSE_UNICODE // Get native info @@ -241,23 +256,27 @@ void wxFontRefData::InitFromNative() break; } +// Not defined in some Pango versions +#define wxPANGO_WEIGHT_SEMIBOLD 600 + switch (pango_font_description_get_weight( desc )) { case PANGO_WEIGHT_ULTRALIGHT: - m_weight = wxFONTWEIGHT_LIGHT; - break; case PANGO_WEIGHT_LIGHT: m_weight = wxFONTWEIGHT_LIGHT; break; + + default: + wxFAIL_MSG(_T("unknown Pango font weight")); + // fall through + case PANGO_WEIGHT_NORMAL: m_weight = wxFONTWEIGHT_NORMAL; break; + + case wxPANGO_WEIGHT_SEMIBOLD: case PANGO_WEIGHT_BOLD: - m_weight = wxFONTWEIGHT_BOLD; - break; case PANGO_WEIGHT_ULTRABOLD: - m_weight = wxFONTWEIGHT_BOLD; - break; case PANGO_WEIGHT_HEAVY: m_weight = wxFONTWEIGHT_BOLD; break; @@ -277,7 +296,7 @@ void wxFontRefData::InitFromNative() } // Pango description are never underlined (?) - m_underlined = FALSE; + m_underlined = false; // Cannot we choose that m_encoding = wxFONTENCODING_SYSTEM; @@ -306,8 +325,8 @@ void wxFontRefData::InitFromNative() } } - switch ( wxToupper(*m_nativeFontInfo. - GetXFontComponent(wxXLFD_SLANT).c_str()) ) + switch ( wxToupper( m_nativeFontInfo. + GetXFontComponent(wxXLFD_SLANT)[0u]).GetValue() ) { case _T('I'): // italique m_style = wxFONTSTYLE_ITALIC; @@ -347,7 +366,7 @@ void wxFontRefData::InitFromNative() } // X fonts are never underlined... - m_underlined = FALSE; + m_underlined = false; // deal with font encoding wxString @@ -383,7 +402,7 @@ void wxFontRefData::InitFromNative() } wxFontRefData::wxFontRefData( const wxFontRefData& data ) - : wxObjectRefData() + : wxGDIRefData() { m_pointSize = data.m_pointSize; m_family = data.m_family; @@ -396,7 +415,7 @@ wxFontRefData::wxFontRefData( const wxFontRefData& data ) m_encoding = data.m_encoding; m_noAA = data.m_noAA; - + m_nativeFontInfo = data.m_nativeFontInfo; } @@ -424,12 +443,12 @@ void wxFontRefData::ClearX11Fonts() { #if wxUSE_UNICODE #else - wxNode* node = m_fonts.First(); + wxList::compatibility_iterator node = m_fonts.GetFirst(); while (node) { - wxXFont* f = (wxXFont*) node->Data(); + wxXFont* f = (wxXFont*) node->GetData(); delete f; - node = node->Next(); + node = node->GetNext(); } m_fonts.Clear(); #endif @@ -446,13 +465,12 @@ wxFontRefData::~wxFontRefData() void wxFontRefData::SetPointSize(int pointSize) { - m_pointSize = pointSize; + // NB: Pango doesn't support point sizes less than 1 + m_pointSize = pointSize == wxDEFAULT || pointSize < 1 ? wxDEFAULT_FONT_SIZE + : pointSize; #if wxUSE_UNICODE - // Get native info - PangoFontDescription *desc = m_nativeFontInfo.description; - - pango_font_description_set_size( desc, m_pointSize * PANGO_SCALE ); + m_nativeFontInfo.SetPointSize(m_pointSize); #endif } @@ -501,9 +519,10 @@ void wxFontRefData::SetUnderlined(bool underlined) // the XLFD doesn't have "underlined" field anyhow } -void wxFontRefData::SetFaceName(const wxString& facename) +bool wxFontRefData::SetFaceName(const wxString& facename) { m_faceName = facename; + return true; } void wxFontRefData::SetEncoding(wxFontEncoding encoding) @@ -526,14 +545,8 @@ void wxFontRefData::SetNativeFontInfo(const wxNativeFontInfo& info) // wxFont // ---------------------------------------------------------------------------- -void wxFont::Init() -{ -} - wxFont::wxFont(const wxNativeFontInfo& info) { - Init(); - #if wxUSE_UNICODE Create( info.GetPointSize(), info.GetFamily(), @@ -556,21 +569,21 @@ bool wxFont::Create(int pointSize, wxFontEncoding encoding) { UnRef(); - + m_refData = new wxFontRefData(pointSize, family, style, weight, underlined, faceName, encoding); - return TRUE; + return true; } -#if wxUSE_UNICODE -#else +#if !wxUSE_UNICODE + bool wxFont::Create(const wxString& fontname, wxFontEncoding enc) { if( !fontname ) { *this = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT); - return TRUE; + return true; } m_refData = new wxFontRefData(); @@ -663,16 +676,26 @@ bool wxFont::Create(const wxString& fontname, wxFontEncoding enc) } //else: unknown encoding - may be give a warning here? else - return FALSE; + return false; } - return TRUE; + return true; } -#endif +#endif // !wxUSE_UNICODE wxFont::~wxFont() { } +wxGDIRefData *wxFont::CreateGDIRefData() const +{ + return new wxFontRefData; +} + +wxGDIRefData *wxFont::CloneGDIRefData(const wxGDIRefData *data) const +{ + return new wxFontRefData(*wx_static_cast(const wxFontRefData *, data)); +} + // ---------------------------------------------------------------------------- // change the font attributes // ---------------------------------------------------------------------------- @@ -705,7 +728,7 @@ int wxFont::GetPointSize() const wxString wxFont::GetFaceName() const { - wxCHECK_MSG( Ok(), wxT(""), wxT("invalid font") ); + wxCHECK_MSG( Ok(), wxEmptyString, wxT("invalid font") ); return M_FONTDATA->m_faceName; } @@ -733,7 +756,7 @@ int wxFont::GetWeight() const bool wxFont::GetUnderlined() const { - wxCHECK_MSG( Ok(), FALSE, wxT("invalid font") ); + wxCHECK_MSG( Ok(), false, wxT("invalid font") ); return M_FONTDATA->m_underlined; } @@ -745,14 +768,14 @@ wxFontEncoding wxFont::GetEncoding() const return M_FONTDATA->m_encoding; } -bool wxFont::GetNoAntiAliasing() +bool wxFont::GetNoAntiAliasing() const { wxCHECK_MSG( Ok(), wxFONTENCODING_DEFAULT, wxT("invalid font") ); return M_FONTDATA->m_noAA; } -wxNativeFontInfo *wxFont::GetNativeFontInfo() const +const wxNativeFontInfo *wxFont::GetNativeFontInfo() const { wxCHECK_MSG( Ok(), (wxNativeFontInfo *)NULL, wxT("invalid font") ); @@ -762,17 +785,18 @@ wxNativeFontInfo *wxFont::GetNativeFontInfo() const GetInternalFont(); #endif - return new wxNativeFontInfo(M_FONTDATA->m_nativeFontInfo); + return &(M_FONTDATA->m_nativeFontInfo); } bool wxFont::IsFixedWidth() const { - wxCHECK_MSG( Ok(), FALSE, wxT("invalid font") ); + wxCHECK_MSG( Ok(), false, wxT("invalid font") ); #if wxUSE_UNICODE + return wxFontBase::IsFixedWidth(); #else // Robert, is this right? HasNativeFont doesn't exist. - if ( TRUE ) + if ( true ) // if ( M_FONTDATA->HasNativeFont() ) { // the monospace fonts are supposed to have "M" in the spacing field @@ -781,9 +805,10 @@ bool wxFont::IsFixedWidth() const return spacing.Upper() == _T('M'); } + // Unreaceable code for now + // return wxFontBase::IsFixedWidth(); #endif - return wxFontBase::IsFixedWidth(); } // ---------------------------------------------------------------------------- @@ -818,11 +843,12 @@ void wxFont::SetWeight(int weight) M_FONTDATA->SetWeight(weight); } -void wxFont::SetFaceName(const wxString& faceName) +bool wxFont::SetFaceName(const wxString& faceName) { Unshare(); - M_FONTDATA->SetFaceName(faceName); + return M_FONTDATA->SetFaceName(faceName) && + wxFontBase::SetFaceName(faceName); } void wxFont::SetUnderlined(bool underlined) @@ -839,7 +865,7 @@ void wxFont::SetEncoding(wxFontEncoding encoding) M_FONTDATA->SetEncoding(encoding); } -void wxFont::SetNativeFontInfo( const wxNativeFontInfo& info ) +void wxFont::DoSetNativeFontInfo( const wxNativeFontInfo& info ) { Unshare(); @@ -872,15 +898,20 @@ wxXFont* wxFont::GetInternalFont(double scale, WXDisplay* display) const int pointSize = (M_FONTDATA->m_pointSize * 10 * intScale) / 100; // search existing fonts first - wxNode* node = M_FONTDATA->m_fonts.First(); + wxList::compatibility_iterator node = M_FONTDATA->m_fonts.GetFirst(); while (node) { - wxXFont* f = (wxXFont*) node->Data(); + wxXFont* f = (wxXFont*) node->GetData(); if ((!display || (f->m_display == display)) && (f->m_scale == intScale)) return f; - node = node->Next(); + node = node->GetNext(); } + wxString xFontName = M_FONTDATA->m_nativeFontInfo.GetXFontName(); + if (xFontName == "-*-*-*-*-*--*-*-*-*-*-*-*-*") + // wxFont constructor not called with native font info parameter => take M_FONTDATA values + xFontName.Clear(); + // not found, create a new one XFontStruct *font = (XFontStruct *) wxLoadQueryNearestFont(pointSize, @@ -889,7 +920,8 @@ wxXFont* wxFont::GetInternalFont(double scale, WXDisplay* display) const M_FONTDATA->m_weight, M_FONTDATA->m_underlined, wxT(""), - M_FONTDATA->m_encoding); + M_FONTDATA->m_encoding, + & xFontName); if ( !font ) {