fontutil.cpp
来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 1,420 行 · 第 1/3 页
CPP
1,420 行
/////////////////////////////////////////////////////////////////////////////
// Name: unix/fontutil.cpp
// Purpose: Font helper functions for X11 (GDK/X)
// Author: Vadim Zeitlin
// Modified by:
// Created: 05.11.99
// RCS-ID: $Id: fontutil.cpp,v 1.62.2.1 2006/02/13 00:24:55 VZ Exp $
// Copyright: (c) Vadim Zeitlin
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// ============================================================================
// declarations
// ============================================================================
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
#pragma implementation "fontutil.h"
#endif
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include "wx/font.h" // wxFont enums
#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"
extern GtkWidget *wxGetRootWindow();
#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
{
#if 0
// We seem to currently initialize only by string.
// In that case PANGO_FONT_MASK_WEIGHT is always set.
if (!(pango_font_description_get_set_fields(description) & PANGO_FONT_MASK_WEIGHT))
return wxFONTWEIGHT_NORMAL;
#endif
PangoWeight pango_weight = pango_font_description_get_weight( description );
// Until the API can be changed the following ranges of weight values are used:
// wxFONTWEIGHT_LIGHT: 100 .. 349 - range of 250
// wxFONTWEIGHT_NORMAL: 350 .. 599 - range of 250
// wxFONTWEIGHT_BOLD: 600 .. 900 - range of 301 (600 is "semibold" already)
if (pango_weight >= 600)
return wxFONTWEIGHT_BOLD;
if (pango_weight < 350)
return wxFONTWEIGHT_LIGHT;
return wxFONTWEIGHT_NORMAL;
}
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
{
wxFontFamily ret = wxFONTFAMILY_DEFAULT;
// note: not passing -1 as the 2nd parameter to g_ascii_strdown to work
// around a bug in the 64-bit glib shipped with solaris 10, -1 causes it
// to try to allocate 2^32 bytes.
const char *family_name = pango_font_description_get_family( description );
char *family_text = g_ascii_strdown( family_name, family_name ? strlen( family_name ) : 0 );
// Check for some common fonts, to salvage what we can from the current win32 centric wxFont API:
if (strncmp( family_text, "monospace", 9 ) == 0)
ret = wxFONTFAMILY_TELETYPE; // begins with "Monospace"
else if (strncmp( family_text, "courier", 7 ) == 0)
ret = wxFONTFAMILY_TELETYPE; // begins with "Courier"
#if defined(__WXGTK24__) || defined(HAVE_PANGO_FONT_FAMILY_IS_MONOSPACE)
else
#ifdef __WXGTK24__
if (!gtk_check_version(2,4,0))
#endif
{
PangoFontFamily **families;
PangoFontFamily *family = NULL;
int n_families;
pango_context_list_families(
#ifdef __WXGTK20__
gtk_widget_get_pango_context( wxGetRootWindow() ),
#else
wxTheApp->GetPangoContext(),
#endif
&families, &n_families);
for (int i = 0;i < n_families;++i)
{
if (g_ascii_strcasecmp(pango_font_family_get_name( families[i] ), pango_font_description_get_family( description )) == 0 )
{
family = families[i];
break;
}
}
g_free(families);
// Some gtk+ systems might query for a non-existing font from wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)
// on initialization, don't assert until wxSystemSettings::GetFont is checked for this - MR
// wxASSERT_MSG( family, wxT("wxNativeFontInfo::GetFamily() - No appropriate PangoFontFamily found for ::description") );
//BCI: Cache the wxFontFamily inside the class. Validate cache with
//BCI: g_ascii_strcasecmp(pango_font_description_get_family(description), pango_font_family_get_name(family)) == 0
if (family != NULL && pango_font_family_is_monospace( family ))
ret = wxFONTFAMILY_TELETYPE; // is deemed a monospace font by pango
}
#endif // gtk24 || HAVE_PANGO_FONT_FAMILY_IS_MONOSPACE
if (ret == wxFONTFAMILY_DEFAULT)
{
if (strstr( family_text, "sans" ) != NULL) // checked before serif, so that "* Sans Serif" fonts are detected correctly
ret = wxFONTFAMILY_SWISS; // contains "Sans"
else if (strstr( family_text, "serif" ) != NULL)
ret = wxFONTFAMILY_ROMAN; // contains "Serif"
else if (strncmp( family_text, "times", 5 ) == 0)
ret = wxFONTFAMILY_ROMAN; // begins with "Times"
else if (strncmp( family_text, "old", 3 ) == 0)
ret = wxFONTFAMILY_DECORATIVE; // Begins with "Old" - "Old English", "Old Town"
}
free(family_text);
return ret;
}
wxFontEncoding wxNativeFontInfo::GetEncoding() const
{
return wxFONTENCODING_SYSTEM;
}
void wxNativeFontInfo::SetPointSize(int pointsize)
{
pango_font_description_set_size( description, pointsize * PANGO_SCALE );
}
void wxNativeFontInfo::SetStyle(wxFontStyle style)
{
switch (style)
{
case wxFONTSTYLE_ITALIC:
pango_font_description_set_style( description, PANGO_STYLE_ITALIC );
break;
case wxFONTSTYLE_SLANT:
pango_font_description_set_style( description, PANGO_STYLE_OBLIQUE );
break;
default:
wxFAIL_MSG( _T("unknown font style") );
// fall through
case wxFONTSTYLE_NORMAL:
pango_font_description_set_style( description, PANGO_STYLE_NORMAL );
break;
}
}
void wxNativeFontInfo::SetWeight(wxFontWeight weight)
{
switch (weight)
{
case wxFONTWEIGHT_BOLD:
pango_font_description_set_weight(description, PANGO_WEIGHT_BOLD);
break;
case wxFONTWEIGHT_LIGHT:
pango_font_description_set_weight(description, PANGO_WEIGHT_LIGHT);
break;
default:
wxFAIL_MSG( _T("unknown font weight") );
// fall through
case wxFONTWEIGHT_NORMAL:
pango_font_description_set_weight(description, PANGO_WEIGHT_NORMAL);
}
}
void wxNativeFontInfo::SetUnderlined(bool WXUNUSED(underlined))
{
wxFAIL_MSG( _T("not implemented") );
}
void wxNativeFontInfo::SetFaceName(wxString facename)
{
pango_font_description_set_family( description, wxGTK_CONV(facename) );
}
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& WXUNUSED(s))
{
return FALSE;
}
wxString wxNativeEncodingInfo::ToString() const
{
return wxEmptyString;
}
bool wxTestFontEncoding(const wxNativeEncodingInfo& WXUNUSED(info))
{
return TRUE;
}
bool wxGetNativeFontEncoding(wxFontEncoding encoding,
wxNativeEncodingInfo *info)
{
info->facename.clear();
switch ( encoding )
{
// we *must* return true for default encodings as otherwise wxFontMapper
// considers that we can't load any font and aborts with wxLogFatalError!
case wxFONTENCODING_DEFAULT:
case wxFONTENCODING_SYSTEM:
info->encoding = wxFONTENCODING_SYSTEM;
return true;
case wxFONTENCODING_UTF8:
info->encoding = wxFONTENCODING_UTF8;
return true;
default:
// everything else must be converted to UTF-8
return false;
}
}
#else // GTK+ 1.x
#ifdef __X__
#ifdef __VMS__
#pragma message disable nosimpint
#endif
#include <X11/Xlib.h>
#ifdef __VMS__
#pragma message enable nosimpint
#endif
#include "wx/utils.h" // for wxGetDisplay()
#elif defined(__WXGTK__)
// we have to declare struct tm to avoid problems with first forward
// declaring it in C code (glib.h included from gdk.h does it) and then
// defining it when time.h is included from the headers below - this is
// known not to work at least with Sun CC 6.01
#include <time.h>
#include <gdk/gdk.h>
#endif
// ----------------------------------------------------------------------------
// private data
// ----------------------------------------------------------------------------
static wxHashTable *g_fontHash = (wxHashTable*) NULL;
// ----------------------------------------------------------------------------
// private functions
// ----------------------------------------------------------------------------
// define the functions to create and destroy native fonts for this toolkit
#ifdef __X__
wxNativeFont wxLoadFont(const wxString& fontSpec)
{
return XLoadQueryFont((Display *)wxGetDisplay(), fontSpec);
}
inline void wxFreeFont(wxNativeFont font)
{
XFreeFont((Display *)wxGetDisplay(), (XFontStruct *)font);
}
#elif defined(__WXGTK__)
wxNativeFont wxLoadFont(const wxString& 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)
{
gdk_font_unref(font);
}
#else
#error "Unknown GUI toolkit"
#endif
static bool wxTestFontSpec(const wxString& fontspec);
static wxNativeFont wxLoadQueryFont(int pointSize,
int family,
int style,
int weight,
bool underlined,
const wxString& facename,
const wxString& xregistry,
const wxString& xencoding,
wxString* xFontName);
// ============================================================================
// implementation
// ============================================================================
// ----------------------------------------------------------------------------
// wxNativeEncodingInfo
// ----------------------------------------------------------------------------
// convert to/from the string representation: format is
// encodingid;registry;encoding[;facename]
bool wxNativeEncodingInfo::FromString(const wxString& s)
{
// use ";", not "-" because it may be part of encoding name
wxStringTokenizer tokenizer(s, _T(";"));
wxString encid = tokenizer.GetNextToken();
long enc;
if ( !encid.ToLong(&enc) )
return FALSE;
encoding = (wxFontEncoding)enc;
xregistry = tokenizer.GetNextToken();
if ( !xregistry )
return FALSE;
xencoding = tokenizer.GetNextToken();
if ( !xencoding )
return FALSE;
// ok even if empty
facename = tokenizer.GetNextToken();
return TRUE;
}
wxString wxNativeEncodingInfo::ToString() const
{
wxString s;
s << (long)encoding << _T(';') << xregistry << _T(';') << xencoding;
if ( !!facename )
{
s << _T(';') << facename;
}
return s;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?