fontutil.cpp
来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 1,420 行 · 第 1/3 页
CPP
1,420 行
// ----------------------------------------------------------------------------
// 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
{
// 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
// ----------------------------------------------------------------------------
bool wxGetNativeFontEncoding(wxFontEncoding encoding,
wxNativeEncodingInfo *info)
{
wxCHECK_MSG( info, FALSE, _T("bad pointer in wxGetNativeFontEncoding") );
if ( encoding == wxFONTENCODING_DEFAULT )
{
encoding = wxFont::GetDefaultEncoding();
}
switch ( encoding )
{
case wxFONTENCODING_ISO8859_1:
case wxFONTENCODING_ISO8859_2:
case wxFONTENCODING_ISO8859_3:
case wxFONTENCODING_ISO8859_4:
case wxFONTENCODING_ISO8859_5:
case wxFONTENCODING_ISO8859_6:
case wxFONTENCODING_ISO8859_7:
case wxFONTENCODING_ISO8859_8:
case wxFONTENCODING_ISO8859_9:
case wxFONTENCODING_ISO8859_10:
case wxFONTENCODING_ISO8859_11:
case wxFONTENCODING_ISO8859_12:
case wxFONTENCODING_ISO8859_13:
case wxFONTENCODING_ISO8859_14:
case wxFONTENCODING_ISO8859_15:
{
int cp = encoding - wxFONTENCODING_ISO8859_1 + 1;
info->xregistry = wxT("iso8859");
info->xencoding.Printf(wxT("%d"), cp);
}
break;
case wxFONTENCODING_UTF8:
info->xregistry = wxT("iso10646");
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)
info->xencoding = wxT("*");
break;
case wxFONTENCODING_CP1250:
case wxFONTENCODING_CP1251:
case wxFONTENCODING_CP1252:
case wxFONTENCODING_CP1253:
case wxFONTENCODING_CP1254:
case wxFONTENCODING_CP1255:
case wxFONTENCODING_CP1256:
case wxFONTENCODING_CP1257:
{
int cp = encoding - wxFONTENCODING_CP1250 + 1250;
info->xregistry = wxT("microsoft");
info->xencoding.Printf(wxT("cp%d"), cp);
}
break;
case wxFONTENCODING_EUC_JP:
case wxFONTENCODING_SHIFT_JIS:
info->xregistry = "jis*";
info->xencoding = "*";
break;
case wxFONTENCODING_SYSTEM:
info->xregistry =
info->xencoding = wxT("*");
break;
default:
// don't know how to translate this encoding into X fontspec
return FALSE;
}
info->encoding = encoding;
return TRUE;
}
bool wxTestFontEncoding(const wxNativeEncodingInfo& info)
{
wxString fontspec;
fontspec.Printf(_T("-*-%s-*-*-*-*-*-*-*-*-*-*-%s-%s"),
!info.facename ? _T("*") : info.facename.c_str(),
info.xregistry.c_str(),
info.xencoding.c_str());
return wxTestFontSpec(fontspec);
}
// ----------------------------------------------------------------------------
// X-specific functions
// ----------------------------------------------------------------------------
wxNativeFont wxLoadQueryNearestFont(int pointSize,
int family,
int style,
int weight,
bool underlined,
const wxString &facename,
wxFontEncoding encoding,
wxString* xFontName)
{
if ( encoding == wxFONTENCODING_DEFAULT )
{
encoding = wxFont::GetDefaultEncoding();
}
// first determine the encoding - if the font doesn't exist at all in this
// encoding, it's useless to do all other approximations (i.e. size,
// family &c don't matter much)
wxNativeEncodingInfo info;
if ( encoding == wxFONTENCODING_SYSTEM )
{
// This will always work so we don't test to save time
wxGetNativeFontEncoding(wxFONTENCODING_SYSTEM, &info);
}
else
{
if ( !wxGetNativeFontEncoding(encoding, &info) ||
!wxTestFontEncoding(info) )
{
#if wxUSE_FONTMAP
if ( !wxFontMapper::Get()->GetAltForEncoding(encoding, &info) )
#endif // wxUSE_FONTMAP
{
// unspported encoding - replace it with the default
//
// NB: we can't just return 0 from here because wxGTK code doesn't
// check for it (i.e. it supposes that we'll always succeed),
// so it would provoke a crash
wxGetNativeFontEncoding(wxFONTENCODING_SYSTEM, &info);
}
}
}
// OK, we have the correct xregistry/xencoding in info structure
wxNativeFont font = 0;
// if we already have the X font name, try to use it
if( xFontName && !xFontName->IsEmpty() )
{
//
// Make sure point size is correct for scale factor.
//
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?