// Created: 05.11.99
// RCS-ID: $Id$
// Copyright: (c) Vadim Zeitlin
-// Licence: wxWindows license
+// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// ============================================================================
// headers
// ----------------------------------------------------------------------------
-#ifdef __GNUG__
+#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
#pragma implementation "fontutil.h"
#endif
#endif
#ifndef WX_PRECOMP
+ #include "wx/encinfo.h"
#endif // PCH
+#include "wx/fontutil.h"
+#include "wx/fontmap.h"
+#include "wx/tokenzr.h"
+#include "wx/hash.h"
+#include "wx/module.h"
+
+#if wxUSE_PANGO
+
+#include "pango/pango.h"
+
+#ifdef __WXGTK20__
+#include "wx/gtk/private.h"
+#else
+#include "wx/x11/private.h"
+#endif
+
+// ----------------------------------------------------------------------------
+// wxNativeFontInfo
+// ----------------------------------------------------------------------------
+
+void wxNativeFontInfo::Init()
+{
+ description = NULL;
+}
+
+void
+wxNativeFontInfo::Init(const wxNativeFontInfo& info)
+{
+ if (info.description)
+ description = pango_font_description_copy(info.description);
+ else
+ description = NULL;
+}
+
+void wxNativeFontInfo::Free()
+{
+ if (description)
+ pango_font_description_free(description);
+}
+
+int wxNativeFontInfo::GetPointSize() const
+{
+ return pango_font_description_get_size( description ) / PANGO_SCALE;
+}
+
+wxFontStyle wxNativeFontInfo::GetStyle() const
+{
+ wxFontStyle m_style = wxFONTSTYLE_NORMAL;
+
+ switch (pango_font_description_get_style( description ))
+ {
+ case PANGO_STYLE_NORMAL:
+ m_style = wxFONTSTYLE_NORMAL;
+ break;
+ case PANGO_STYLE_ITALIC:
+ m_style = wxFONTSTYLE_ITALIC;
+ break;
+ case PANGO_STYLE_OBLIQUE:
+ m_style = wxFONTSTYLE_SLANT;
+ break;
+ }
+
+ return m_style;
+}
+
+wxFontWeight wxNativeFontInfo::GetWeight() const
+{
+ wxFontWeight m_weight = wxFONTWEIGHT_NORMAL;
+
+ switch (pango_font_description_get_weight( description ))
+ {
+ case PANGO_WEIGHT_ULTRALIGHT:
+ m_weight = wxFONTWEIGHT_LIGHT;
+ break;
+ case PANGO_WEIGHT_LIGHT:
+ m_weight = wxFONTWEIGHT_LIGHT;
+ break;
+ case PANGO_WEIGHT_NORMAL:
+ m_weight = wxFONTWEIGHT_NORMAL;
+ break;
+ 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;
+ }
+
+ return m_weight;
+}
+
+bool wxNativeFontInfo::GetUnderlined() const
+{
+ return FALSE;
+}
+
+wxString wxNativeFontInfo::GetFaceName() const
+{
+ wxString tmp = wxGTK_CONV_BACK( pango_font_description_get_family( description ) );
+
+ return tmp;
+}
+
+wxFontFamily wxNativeFontInfo::GetFamily() const
+{
+ return wxFONTFAMILY_SWISS;
+}
+
+wxFontEncoding wxNativeFontInfo::GetEncoding() const
+{
+ return wxFONTENCODING_SYSTEM;
+}
+
+
+void wxNativeFontInfo::SetPointSize(int WXUNUSED(pointsize))
+{
+ wxFAIL_MSG( _T("not implemented") );
+}
+
+void wxNativeFontInfo::SetStyle(wxFontStyle WXUNUSED(style))
+{
+ wxFAIL_MSG( _T("not implemented") );
+}
+
+void wxNativeFontInfo::SetWeight(wxFontWeight WXUNUSED(weight))
+{
+ wxFAIL_MSG( _T("not implemented") );
+}
+
+void wxNativeFontInfo::SetUnderlined(bool WXUNUSED(underlined))
+{
+ wxFAIL_MSG( _T("not implemented") );
+}
+
+void wxNativeFontInfo::SetFaceName(wxString WXUNUSED(facename))
+{
+ wxFAIL_MSG( _T("not implemented") );
+}
+
+void wxNativeFontInfo::SetFamily(wxFontFamily WXUNUSED(family))
+{
+ wxFAIL_MSG( _T("not implemented") );
+}
+
+void wxNativeFontInfo::SetEncoding(wxFontEncoding WXUNUSED(encoding))
+{
+ wxFAIL_MSG( _T("not implemented") );
+}
+
+
+
+bool wxNativeFontInfo::FromString(const wxString& s)
+{
+ if (description)
+ pango_font_description_free( description );
+
+ description = pango_font_description_from_string( wxGTK_CONV( s ) );
+
+ return TRUE;
+}
+
+wxString wxNativeFontInfo::ToString() const
+{
+ char *str = pango_font_description_to_string( description );
+ wxString tmp = wxGTK_CONV_BACK( str );
+ g_free( str );
+
+ return tmp;
+}
+
+bool wxNativeFontInfo::FromUserString(const wxString& s)
+{
+ return FromString( s );
+}
+
+wxString wxNativeFontInfo::ToUserString() const
+{
+ return ToString();
+}
+
+// ----------------------------------------------------------------------------
+// wxNativeEncodingInfo
+// ----------------------------------------------------------------------------
+
+bool wxNativeEncodingInfo::FromString(const wxString& s)
+{
+ return FALSE;
+}
+
+wxString wxNativeEncodingInfo::ToString() const
+{
+ return wxEmptyString;
+}
+
+bool wxTestFontEncoding(const wxNativeEncodingInfo& info)
+{
+ return TRUE;
+}
+
+bool wxGetNativeFontEncoding(wxFontEncoding encoding,
+ wxNativeEncodingInfo *info)
+{
+ // we *must* return true for default encoding as otherwise wxFontMapper
+ // considers that we can't load any font and aborts with wxLogFatalError!
+ if ( encoding == wxFONTENCODING_SYSTEM )
+ {
+ info->facename.clear();
+ info->encoding = wxFONTENCODING_SYSTEM;
+ }
+
+ // pretend that we support everything, it's better than to always return
+ // false as the old code did
+ return true;
+}
+
+#else // GTK+ 1.x
+
#ifdef __X__
#ifdef __VMS__
#pragma message disable nosimpint
#include <gdk/gdk.h>
#endif
-#include "wx/fontutil.h"
-#include "wx/fontmap.h"
-#include "wx/tokenzr.h"
-#include "wx/hash.h"
-#include "wx/module.h"
// ----------------------------------------------------------------------------
// private data
#elif defined(__WXGTK__)
wxNativeFont wxLoadFont(const wxString& fontSpec)
{
- return gdk_font_load( wxConvertWX2MB(fontSpec) );
+ // VZ: we should use gdk_fontset_load() instead of gdk_font_load()
+ // here to be able to display Japanese fonts correctly (at least
+ // this is what people report) but unfortunately doing it results
+ // in tons of warnings when using GTK with "normal" European
+ // languages and so we can't always do it and I don't know enough
+ // to determine when should this be done... (FIXME)
+ return gdk_font_load( wxConvertWX2MB(fontSpec) );
}
inline void wxFreeFont(wxNativeFont font)
return FALSE;
}
- fontElements[n] = tokenizer.GetNextToken();
+ wxString field = tokenizer.GetNextToken();
+ if ( !field.empty() && field != _T('*') )
+ {
+ // we're really initialized now
+ m_isDefault = FALSE;
+ }
+
+ fontElements[n] = field;
}
// this should be all
- return !tokenizer.HasMoreTokens();
+ if ( tokenizer.HasMoreTokens() )
+ return FALSE;
+
+ return TRUE;
}
wxString wxNativeFontInfo::GetXFontName() const
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
+{
+ // wxWidgets facename probably more accurately corresponds to X family
+ return GetXFontComponent(wxXLFD_FAMILY);
+}
+
+wxFontFamily wxNativeFontInfo::GetFamily() const
+{
+ // and wxWidgets 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);
+ }
+}
+
// ----------------------------------------------------------------------------
// common functions
// ----------------------------------------------------------------------------
info->xencoding = wxT("*");
break;
+ case wxFONTENCODING_GB2312:
+ info->xregistry = wxT("GB2312"); // or the otherway round?
+ info->xencoding = wxT("*");
+ break;
+
case wxFONTENCODING_KOI8:
+ case wxFONTENCODING_KOI8_U:
info->xregistry = wxT("koi8");
// we don't make distinction between koi8-r, koi8-u and koi8-ru (so far)
!wxTestFontEncoding(info) )
{
#if wxUSE_FONTMAP
- if ( !wxTheFontMapper->GetAltForEncoding(encoding, &info) )
+ if ( !wxFontMapper::Get()->GetAltForEncoding(encoding, &info) )
#endif // wxUSE_FONTMAP
{
// unspported encoding - replace it with the default
(void) tokenizer.NextToken();
- newFontName += wxString::Format("%d-", pointSize);
+ newFontName += wxString::Format(wxT("%d-"), pointSize);
while(tokenizer.HasMoreTokens())
newFontName += tokenizer.GetNextToken();
*xFontName = newFontName;
}
- // try to load exactly the font requested first
- if( !font )
- {
- font = wxLoadQueryFont( pointSize, family, style, weight,
- underlined, facename,
- info.xregistry, info.xencoding,
- xFontName );
- }
-
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;
+ int i, round; // counters
- // Search for smaller size (approx.)
- for ( i = pointSize - 10; !font && i >= 10 && i >= min_size; i -= 10 )
+ // first round: search for equal, then for smaller and for larger size with the given weight and style
+ int testweight = weight;
+ int teststyle = style;
+
+ for ( round = 0; round < 3; round++ )
+ {
+ // second round: use normal weight
+ if ( round == 1 )
{
- font = wxLoadQueryFont(i, family, style, weight, underlined,
+ if ( testweight != wxNORMAL )
+ {
+ testweight = wxNORMAL;
+ }
+ else
+ {
+ ++round; // fall through to third round
+ }
+ }
+
+ // third round: ... and use normal style
+ if ( round == 2 )
+ {
+ if ( teststyle != wxNORMAL )
+ {
+ teststyle = wxNORMAL;
+ }
+ else
+ {
+ break;
+ }
+ }
+ // Search for equal or smaller size (approx.)
+ for ( i = pointSize; !font && i >= 10 && i >= min_size; i -= 10 )
+ {
+ font = wxLoadQueryFont(i, family, teststyle, testweight, underlined,
facename, info.xregistry, info.xencoding,
xFontName);
}
// Search for larger size (approx.)
for ( i = pointSize + 10; !font && i <= max_size; i += 10 )
{
- font = wxLoadQueryFont(i, family, style, weight, underlined,
+ font = wxLoadQueryFont(i, family, teststyle, testweight, underlined,
facename, info.xregistry, info.xencoding,
xFontName);
+ }
}
// Try default family
int yPixelsPerCM = screenInfo.ydpcm;
- // A point is 1/20 of an inch.
+ // A point is 1/72 of an inch.
// An inch is 2.541 cm.
- // So pixelHeight = (pointSize / 20) (inches) * 2.541 (for cm) * yPixelsPerCM (for pixels)
+ // So pixelHeight = (pointSize / 72) (inches) * 2.541 (for cm) * yPixelsPerCM (for pixels)
// In fact pointSize is 10 * the normal point size so
// divide by 10.
- // I don't know why this is necessary, but otherwise fonts
- // are just too big.
- float fudgeFactor = 0.6 ;
- int pixelHeight = (int) ( (((float)pointSize) / 200.0) * 2.541 * (float) yPixelsPerCM * fudgeFactor) ;
+ int pixelHeight = (int) ( (((float)pointSize) / 720.0) * 2.541 * (float) yPixelsPerCM) ;
// An alternative: assume that the screen is 72 dpi.
- // This gets a similar result to above (pre-fudge factor)
- //int pixelHeight = (int) (((float)pointSize / 200.0) * 72.0) ;
-
+ //int pixelHeight = (int) (((float)pointSize / 720.0) * 72.0) ;
+ //int pixelHeight = (int) ((float)pointSize / 10.0) ;
+
GR_LOGFONT logFont;
logFont.lfHeight = pixelHeight;
logFont.lfWidth = 0;
fontInfo->fid = GrCreateFont((GR_CHAR*) facename.c_str(), pixelHeight, & logFont);
GrGetFontInfo(fontInfo->fid, & fontInfo->info);
return (wxNativeFont) fontInfo;
-
+
#else
wxString fontSpec;
if (!facename.IsEmpty())
// if pointSize is -1, don't specify any
wxString sizeSpec;
- if ( fontSpec == -1 )
+ if ( pointSize == -1 )
{
sizeSpec = _T('*');
}
g_fontHash = (wxHashTable *)NULL;
}
+
+#endif // GTK 2.0/1.x
+