// 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 == wxT("-*-*-*-*-*-*-*-*-*-*-*-*-*-*") ) { 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(float pointSize, wxFontFamily family, wxFontStyle style, int weight, bool WXUNUSED(underlined), const wxString& facename, const wxString& xregistry, const wxString& xencoding, wxString* xFontName) { #if wxUSE_NANOX int xweight; switch (weight) { case wxFONTWEIGHT_BOLD: { xweight = MWLF_WEIGHT_BOLD; break; } case wxFONTWEIGHT_LIGHT: { xweight = MWLF_WEIGHT_LIGHT; break; } case wxFONTWEIGHT_NORMAL: { 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 == wxFONTSTYLE_ITALIC ? 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 wxNativeFontInfo info; info.SetFractionalPointSize(pointSize); if ( !facename.empty() ) { info.SetFaceName(facename); if ( !wxTestFontSpec(info.GetXFontName()) ) { // No such face name, use just the family (we assume this will // never fail). info.SetFamily(family); } } else { info.SetFamily(family); } wxNativeFontInfo infoWithStyle(info); infoWithStyle.SetStyle(style); if ( wxTestFontSpec(infoWithStyle.GetXFontName()) ) info = infoWithStyle; wxNativeFontInfo infoWithWeight(info); infoWithWeight.SetNumericWeight(weight); if ( wxTestFontSpec(infoWithWeight.GetXFontName()) ) info = infoWithWeight; // construct the X font spec from our data wxString fontSpec; fontSpec.Printf("-*-%s-%s-%s-normal-*-*-%s-*-*-*-*-%s-%s", info.GetXFontComponent(wxXLFD_FAMILY), info.GetXFontComponent(wxXLFD_WEIGHT), info.GetXFontComponent(wxXLFD_SLANT), info.GetXFontComponent(wxXLFD_POINTSIZE), xregistry, xencoding); if( xFontName ) *xFontName = fontSpec; return wxLoadFont(fontSpec); #endif // wxUSE_NANOX }
GdkFont *wxFont::GetInternalFont( float scale ) const { GdkFont *font = NULL; wxCHECK_MSG( IsOk(), font, wxT("invalid font") ); long int_scale = long(scale * 100.0 + 0.5); // key for fontlist int point_scale = (int)((M_FONTDATA->m_pointSize * 10 * int_scale) / 100); wxScaledFontList& list = M_FONTDATA->m_scaled_xfonts; wxScaledFontList::iterator i = list.find(int_scale); if ( i != list.end() ) { font = i->second; } else // we don't have this font in this size yet { if (*this == wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT)) { font = GtkGetDefaultGuiFont(); } if ( !font ) { // do we have the XLFD? if ( int_scale == 100 && M_FONTDATA->HasNativeFont() ) { font = wxLoadFont(M_FONTDATA->m_nativeFontInfo.GetXFontName()); } // no XLFD of no exact match - try the approximate one now if ( !font ) { wxString xfontname; font = wxLoadQueryNearestFont( point_scale, M_FONTDATA->m_family, M_FONTDATA->m_style, M_FONTDATA->m_weight, M_FONTDATA->m_underlined, M_FONTDATA->m_faceName, M_FONTDATA->m_encoding, &xfontname); // NB: wxFont::GetNativeFontInfo relies on this // side-effect of GetInternalFont if ( int_scale == 100 ) M_FONTDATA->m_nativeFontInfo.SetXFontName(xfontname); } } if ( font ) { list[int_scale] = font; } } // it's quite useless to make it a wxCHECK because we're going to crash // anyhow... wxASSERT_MSG( font, wxT("could not load any font?") ); return font; }
wxNativeFont wxLoadQueryNearestFont(float pointSize, wxFontFamily family, wxFontStyle 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->empty() ) { // // Make sure point size is correct for scale factor. // wxStringTokenizer tokenizer(*xFontName, wxT("-"), 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; wxFontStyle teststyle = style; for ( round = 0; round < 3; round++ ) { // second round: use normal weight if ( round == 1 ) { if ( testweight != wxFONTWEIGHT_NORMAL ) { testweight = wxFONTWEIGHT_NORMAL; } else { ++round; // fall through to third round } } // third round: ... and use normal style if ( round == 2 ) { if ( teststyle != wxFONTSTYLE_NORMAL ) { teststyle = wxFONTSTYLE_NORMAL; } 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 != wxFONTFAMILY_DEFAULT ) { font = wxLoadQueryFont(pointSize, wxFONTFAMILY_DEFAULT, 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, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, underlined, facename, info.xregistry, info.xencoding, xFontName); // ignore family as well if ( !font ) { font = wxLoadQueryFont(120, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, 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, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, 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( wxT("this encoding should be available!") ); font = wxLoadQueryFont(-1, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxEmptyString, wxT("*"), wxT("*"), xFontName); } } } } } return font; }
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.empty()) { 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(wxT("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 = wxT('*'); } else { sizeSpec.Printf(wxT("%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 }