fontutil.cpp
来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 1,420 行 · 第 1/3 页
CPP
1,420 行
wxStringTokenizer tokenizer(*xFontName, _T("-"), wxTOKEN_RET_DELIMS);
wxString newFontName;
for(int i = 0; i < 8; i++)
newFontName += tokenizer.NextToken();
(void) tokenizer.NextToken();
newFontName += wxString::Format(wxT("%d-"), pointSize);
while(tokenizer.HasMoreTokens())
newFontName += tokenizer.GetNextToken();
font = wxLoadFont(newFontName);
if(font)
*xFontName = newFontName;
}
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, round; // counters
// 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 )
{
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, teststyle, testweight, underlined,
facename, info.xregistry, info.xencoding,
xFontName);
}
}
// Try default family
if ( !font && family != wxDEFAULT )
{
font = wxLoadQueryFont(pointSize, wxDEFAULT, style, weight,
underlined, facename,
info.xregistry, info.xencoding,
xFontName );
}
// ignore size, family, style and weight but try to find font with the
// given facename and encoding
if ( !font )
{
font = wxLoadQueryFont(120, wxDEFAULT, wxNORMAL, wxNORMAL,
underlined, facename,
info.xregistry, info.xencoding,
xFontName);
// ignore family as well
if ( !font )
{
font = wxLoadQueryFont(120, wxDEFAULT, wxNORMAL, wxNORMAL,
underlined, wxEmptyString,
info.xregistry, info.xencoding,
xFontName);
// if it still failed, try to get the font of any size but
// with the requested encoding: this can happen if the
// encoding is only available in one size which happens to be
// different from 120
if ( !font )
{
font = wxLoadQueryFont(-1, wxDEFAULT, wxNORMAL, wxNORMAL,
FALSE, wxEmptyString,
info.xregistry, info.xencoding,
xFontName);
// this should never happen as we had tested for it in the
// very beginning, but if it does, do return something non
// NULL or we'd crash in wxFont code
if ( !font )
{
wxFAIL_MSG( _T("this encoding should be available!") );
font = wxLoadQueryFont(-1,
wxDEFAULT, wxNORMAL, wxNORMAL,
FALSE, wxEmptyString,
_T("*"), _T("*"),
xFontName);
}
}
}
}
}
return font;
}
// ----------------------------------------------------------------------------
// private functions
// ----------------------------------------------------------------------------
// returns TRUE if there are any fonts matching this font spec
static bool wxTestFontSpec(const wxString& fontspec)
{
// some X servers will fail to load this font because there are too many
// matches so we must test explicitly for this
if ( fontspec == _T("-*-*-*-*-*-*-*-*-*-*-*-*-*-*") )
{
return TRUE;
}
wxNativeFont test = (wxNativeFont) g_fontHash->Get( fontspec );
if (test)
{
return TRUE;
}
test = wxLoadFont(fontspec);
g_fontHash->Put( fontspec, (wxObject*) test );
if ( test )
{
wxFreeFont(test);
return TRUE;
}
else
{
return FALSE;
}
}
static wxNativeFont wxLoadQueryFont(int pointSize,
int family,
int style,
int weight,
bool WXUNUSED(underlined),
const wxString& facename,
const wxString& xregistry,
const wxString& xencoding,
wxString* xFontName)
{
wxString xfamily;
switch (family)
{
case wxDECORATIVE: xfamily = wxT("lucida"); break;
case wxROMAN: xfamily = wxT("times"); break;
case wxMODERN: xfamily = wxT("courier"); break;
case wxSWISS: xfamily = wxT("helvetica"); break;
case wxTELETYPE: xfamily = wxT("lucidatypewriter"); break;
case wxSCRIPT: xfamily = wxT("utopia"); break;
default: xfamily = wxT("*");
}
#if wxUSE_NANOX
int xweight;
switch (weight)
{
case wxBOLD:
{
xweight = MWLF_WEIGHT_BOLD;
break;
}
case wxLIGHT:
{
xweight = MWLF_WEIGHT_LIGHT;
break;
}
case wxNORMAL:
{
xweight = MWLF_WEIGHT_NORMAL;
break;
}
default:
{
xweight = MWLF_WEIGHT_DEFAULT;
break;
}
}
GR_SCREEN_INFO screenInfo;
GrGetScreenInfo(& screenInfo);
int yPixelsPerCM = screenInfo.ydpcm;
// A point is 1/72 of an inch.
// An inch is 2.541 cm.
// 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.
int pixelHeight = (int) ( (((float)pointSize) / 720.0) * 2.541 * (float) yPixelsPerCM) ;
// An alternative: assume that the screen is 72 dpi.
//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;
logFont.lfEscapement = 0;
logFont.lfOrientation = 0;
logFont.lfWeight = xweight;
logFont.lfItalic = (style == wxNORMAL ? 0 : 1) ;
logFont.lfUnderline = 0;
logFont.lfStrikeOut = 0;
logFont.lfCharSet = MWLF_CHARSET_DEFAULT; // TODO: select appropriate one
logFont.lfOutPrecision = MWLF_TYPE_DEFAULT;
logFont.lfClipPrecision = 0; // Not used
logFont.lfRoman = (family == wxROMAN ? 1 : 0) ;
logFont.lfSerif = (family == wxSWISS ? 0 : 1) ;
logFont.lfSansSerif = !logFont.lfSerif ;
logFont.lfModern = (family == wxMODERN ? 1 : 0) ;
logFont.lfProportional = (family == wxTELETYPE ? 0 : 1) ;
logFont.lfOblique = 0;
logFont.lfSmallCaps = 0;
logFont.lfPitch = 0; // 0 = default
strcpy(logFont.lfFaceName, facename.c_str());
XFontStruct* fontInfo = (XFontStruct*) malloc(sizeof(XFontStruct));
fontInfo->fid = GrCreateFont((GR_CHAR*) facename.c_str(), pixelHeight, & logFont);
GrGetFontInfo(fontInfo->fid, & fontInfo->info);
return (wxNativeFont) fontInfo;
#else
wxString fontSpec;
if (!facename.IsEmpty())
{
fontSpec.Printf(wxT("-*-%s-*-*-normal-*-*-*-*-*-*-*-*-*"),
facename.c_str());
if ( wxTestFontSpec(fontSpec) )
{
xfamily = facename;
}
//else: no such family, use default one instead
}
wxString xstyle;
switch (style)
{
case wxSLANT:
fontSpec.Printf(wxT("-*-%s-*-o-*-*-*-*-*-*-*-*-*-*"),
xfamily.c_str());
if ( wxTestFontSpec(fontSpec) )
{
xstyle = wxT("o");
break;
}
// fall through - try wxITALIC now
case wxITALIC:
fontSpec.Printf(wxT("-*-%s-*-i-*-*-*-*-*-*-*-*-*-*"),
xfamily.c_str());
if ( wxTestFontSpec(fontSpec) )
{
xstyle = wxT("i");
}
else if ( style == wxITALIC ) // and not wxSLANT
{
// try wxSLANT
fontSpec.Printf(wxT("-*-%s-*-o-*-*-*-*-*-*-*-*-*-*"),
xfamily.c_str());
if ( wxTestFontSpec(fontSpec) )
{
xstyle = wxT("o");
}
else
{
// no italic, no slant - leave default
xstyle = wxT("*");
}
}
break;
default:
wxFAIL_MSG(_T("unknown font style"));
// fall back to normal
case wxNORMAL:
xstyle = wxT("r");
break;
}
wxString xweight;
switch (weight)
{
case wxBOLD:
{
fontSpec.Printf(wxT("-*-%s-bold-*-*-*-*-*-*-*-*-*-*-*"),
xfamily.c_str());
if ( wxTestFontSpec(fontSpec) )
{
xweight = wxT("bold");
break;
}
fontSpec.Printf(wxT("-*-%s-heavy-*-*-*-*-*-*-*-*-*-*-*"),
xfamily.c_str());
if ( wxTestFontSpec(fontSpec) )
{
xweight = wxT("heavy");
break;
}
fontSpec.Printf(wxT("-*-%s-extrabold-*-*-*-*-*-*-*-*-*-*-*"),
xfamily.c_str());
if ( wxTestFontSpec(fontSpec) )
{
xweight = wxT("extrabold");
break;
}
fontSpec.Printf(wxT("-*-%s-demibold-*-*-*-*-*-*-*-*-*-*-*"),
xfamily.c_str());
if ( wxTestFontSpec(fontSpec) )
{
xweight = wxT("demibold");
break;
}
fontSpec.Printf(wxT("-*-%s-black-*-*-*-*-*-*-*-*-*-*-*"),
xfamily.c_str());
if ( wxTestFontSpec(fontSpec) )
{
xweight = wxT("black");
break;
}
fontSpec.Printf(wxT("-*-%s-ultrablack-*-*-*-*-*-*-*-*-*-*-*"),
xfamily.c_str());
if ( wxTestFontSpec(fontSpec) )
{
xweight = wxT("ultrablack");
break;
}
}
break;
case wxLIGHT:
{
fontSpec.Printf(wxT("-*-%s-light-*-*-*-*-*-*-*-*-*-*-*"),
xfamily.c_str());
if ( wxTestFontSpec(fontSpec) )
{
xweight = wxT("light");
break;
}
fontSpec.Printf(wxT("-*-%s-thin-*-*-*-*-*-*-*-*-*-*-*"),
xfamily.c_str());
if ( wxTestFontSpec(fontSpec) )
{
xweight = wxT("thin");
break;
}
}
break;
case wxNORMAL:
{
fontSpec.Printf(wxT("-*-%s-medium-*-*-*-*-*-*-*-*-*-*-*"),
xfamily.c_str());
if ( wxTestFontSpec(fontSpec) )
{
xweight = wxT("medium");
break;
}
fontSpec.Printf(wxT("-*-%s-normal-*-*-*-*-*-*-*-*-*-*-*"),
xfamily.c_str());
if ( wxTestFontSpec(fontSpec) )
{
xweight = wxT("normal");
break;
}
fontSpec.Printf(wxT("-*-%s-regular-*-*-*-*-*-*-*-*-*-*-*"),
xfamily.c_str());
if ( wxTestFontSpec(fontSpec) )
{
xweight = wxT("regular");
break;
}
xweight = wxT("*");
}
break;
default: xweight = wxT("*"); break;
}
// if pointSize is -1, don't specify any
wxString sizeSpec;
if ( pointSize == -1 )
{
sizeSpec = _T('*');
}
else
{
sizeSpec.Printf(_T("%d"), pointSize);
}
// construct the X font spec from our data
fontSpec.Printf(wxT("-*-%s-%s-%s-normal-*-*-%s-*-*-*-*-%s-%s"),
xfamily.c_str(), xweight.c_str(), xstyle.c_str(),
sizeSpec.c_str(), xregistry.c_str(), xencoding.c_str());
if( xFontName )
*xFontName = fontSpec;
return wxLoadFont(fontSpec);
#endif
// wxUSE_NANOX
}
// ----------------------------------------------------------------------------
// wxFontModule
// ----------------------------------------------------------------------------
class wxFontModule : public wxModule
{
public:
bool OnInit();
void OnExit();
private:
DECLARE_DYNAMIC_CLASS(wxFontModule)
};
IMPLEMENT_DYNAMIC_CLASS(wxFontModule, wxModule)
bool wxFontModule::OnInit()
{
g_fontHash = new wxHashTable( wxKEY_STRING );
return TRUE;
}
void wxFontModule::OnExit()
{
delete g_fontHash;
g_fontHash = (wxHashTable *)NULL;
}
#endif // GTK 2.0/1.x
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?