// Although we don't use this function yet, but we must create it here. // first, for the prepare the unicode drawing support in wxUniv/x11 port. // If we use pango to draw the text, then we must set some attributes // for pango layout, such as "strikethrough" and "underline". bool wxFont::SetPangoAttrs(PangoLayout* layout) const { if ( !IsOk() || !(GetUnderlined() || GetStrikethrough()) ) return false; PangoAttrList* attrs = pango_attr_list_new(); PangoAttribute* a; if ( GetUnderlined() ) { a = pango_attr_underline_new(PANGO_UNDERLINE_SINGLE); pango_attr_list_insert(attrs, a); } if ( GetStrikethrough() ) { a = pango_attr_strikethrough_new(true); pango_attr_list_insert(attrs, a); } pango_layout_set_attributes(layout, attrs); pango_attr_list_unref(attrs); return true; }
bool wxFontBase::operator==(const wxFont& font) const { // either it is the same font, i.e. they share the same common data or they // have different ref datas but still describe the same font return IsSameAs(font) || ( Ok() == font.Ok() && GetPointSize() == font.GetPointSize() && // in wxGTK1 GetPixelSize() calls GetInternalFont() which uses // operator==() resulting in infinite recursion so we can't use it // in that port #if !defined(__WXGTK__) || defined(__WXGTK20__) GetPixelSize() == font.GetPixelSize() && #endif GetFamily() == font.GetFamily() && GetStyle() == font.GetStyle() && GetWeight() == font.GetWeight() && GetUnderlined() == font.GetUnderlined() && GetFaceName().IsSameAs(font.GetFaceName(), false) && GetEncoding() == font.GetEncoding() ); }
bool wxFont::GTKSetPangoAttrs(PangoLayout* layout) const { if (!IsOk() || !(GetUnderlined() || GetStrikethrough())) return false; PangoAttrList* attrs = pango_attr_list_new(); PangoAttribute* a; if (wx_pango_version_check(1,16,0)) { // a PangoLayout which has leading/trailing spaces with underlined font // is not correctly drawn by this pango version: Pango won't underline the spaces. // This can be a problem; e.g. wxHTML rendering of underlined text relies on // this behaviour. To workaround this problem, we use a special hack here // suggested by pango maintainer Behdad Esfahbod: we prepend and append two // empty space characters and give them a dummy colour attribute. // This will force Pango to underline the leading/trailing spaces, too. const char* text = pango_layout_get_text(layout); const size_t n = strlen(text); if ((n > 0 && text[0] == ' ') || (n > 1 && text[n - 1] == ' ')) { wxCharBuffer buf(n + 6); // copy the leading U+200C ZERO WIDTH NON-JOINER encoded in UTF8 format memcpy(buf.data(), "\342\200\214", 3); // copy the user string memcpy(buf.data() + 3, text, n); // copy the trailing U+200C ZERO WIDTH NON-JOINER encoded in UTF8 format memcpy(buf.data() + 3 + n, "\342\200\214", 3); pango_layout_set_text(layout, buf, n + 6); // Add dummy attributes (use colour as it's invisible anyhow for 0 // width spaces) to ensure that the spaces in the beginning/end of the // string are underlined too. a = pango_attr_foreground_new(0x0057, 0x52A9, 0xD614); a->start_index = 0; a->end_index = 3; pango_attr_list_insert(attrs, a); a = pango_attr_foreground_new(0x0057, 0x52A9, 0xD614); a->start_index = n + 3; a->end_index = n + 6; pango_attr_list_insert(attrs, a); } } if (GetUnderlined()) { a = pango_attr_underline_new(PANGO_UNDERLINE_SINGLE); pango_attr_list_insert(attrs, a); } if (GetStrikethrough()) { a = pango_attr_strikethrough_new(true); pango_attr_list_insert(attrs, a); } pango_layout_set_attributes(layout, attrs); pango_attr_list_unref(attrs); return true; }
// Find an existing, or create a new, XFontStruct // based on this wxFont and the given scale. Append the // font to list in the private data for future reference. wxXFont* wxFont::GetInternalFont(double scale, WXDisplay* display) const { if ( !Ok() ) return NULL; long intScale = long(scale * 100.0 + 0.5); // key for wxXFont int pointSize = (M_FONTDATA->m_pointSize * 10 * intScale) / 100; // search existing fonts first wxList::compatibility_iterator node = M_FONTDATA->m_fonts.GetFirst(); while (node) { wxXFont* f = (wxXFont*) node->GetData(); if ((!display || (f->m_display == display)) && (f->m_scale == intScale)) return f; node = node->GetNext(); } // not found, create a new one wxString xFontSpec; XFontStruct *font = (XFontStruct *) wxLoadQueryNearestFont(pointSize, M_FONTDATA->m_family, M_FONTDATA->m_style, M_FONTDATA->m_weight, M_FONTDATA->m_underlined, wxT(""), M_FONTDATA->m_encoding, &xFontSpec); if ( !font ) { wxFAIL_MSG( wxT("Could not allocate even a default font -- something is wrong.") ); return NULL; } wxXFont* f = new wxXFont; #if wxMOTIF_NEW_FONT_HANDLING XFreeFont( (Display*) display, font ); #else f->m_fontStruct = (WXFontStructPtr)font; #endif f->m_display = ( display ? display : wxGetDisplay() ); f->m_scale = intScale; #if wxMOTIF_USE_RENDER_TABLE XmRendition rendition; XmRenderTable renderTable; Arg args[5]; int count = 0; #if wxMOTIF_NEW_FONT_HANDLING char* fontSpec = wxStrdup(xFontSpec.mb_str()); XtSetArg( args[count], XmNfontName, fontSpec ); ++count; XtSetArg( args[count], XmNfontType, XmFONT_IS_FONTSET ); ++count; #else XtSetArg( args[count], XmNfont, font ); ++count; #endif XtSetArg( args[count], XmNunderlineType, GetUnderlined() ? XmSINGLE_LINE : XmNO_LINE ); ++count; rendition = XmRenditionCreate( XmGetXmDisplay( (Display*)f->m_display ), (XmStringTag)"", args, count ); renderTable = XmRenderTableAddRenditions( NULL, &rendition, 1, XmMERGE_REPLACE ); f->m_renderTable = (WXRenderTable)renderTable; f->m_rendition = (WXRendition)rendition; wxASSERT( f->m_renderTable != NULL ); #else // if !wxMOTIF_USE_RENDER_TABLE f->m_fontList = XmFontListCreate ((XFontStruct*) font, XmSTRING_DEFAULT_CHARSET); wxASSERT( f->m_fontList != NULL ); #endif M_FONTDATA->m_fonts.Append(f); return f; }
wxString wxNativeFontInfo::ToUserString() const { wxString desc; // first put the adjectives, if any - this is English-centric, of course, // but what else can we do? if ( GetUnderlined() ) { desc << _("underlined"); } switch ( GetWeight() ) { default: wxFAIL_MSG( _T("unknown font weight") ); // fall through case wxFONTWEIGHT_NORMAL: break; case wxFONTWEIGHT_LIGHT: desc << _(" light"); break; case wxFONTWEIGHT_BOLD: desc << _(" bold"); break; } switch ( GetStyle() ) { default: wxFAIL_MSG( _T("unknown font style") ); // fall through case wxFONTSTYLE_NORMAL: break; // we don't distinguish between the two for now anyhow... case wxFONTSTYLE_ITALIC: case wxFONTSTYLE_SLANT: desc << _(" italic"); break; } wxString face = GetFaceName(); if ( !face.empty() ) { desc << _T(' ') << face; } int size = GetPointSize(); if ( size != wxNORMAL_FONT->GetPointSize() ) { desc << _T(' ') << size; } #if wxUSE_FONTMAP wxFontEncoding enc = GetEncoding(); if ( enc != wxFONTENCODING_DEFAULT && enc != wxFONTENCODING_SYSTEM ) { desc << _T(' ') << wxFontMapper::GetEncodingName(enc); } #endif // wxUSE_FONTMAP return desc.Strip(wxString::both).MakeLower(); }
wxString wxNativeFontInfo::ToUserString() const { wxString desc; // first put the adjectives, if any - this is English-centric, of course, // but what else can we do? if ( GetUnderlined() ) { desc << _("underlined"); } switch ( GetWeight() ) { default: wxFAIL_MSG( wxT("unknown font weight") ); // fall through case wxFONTWEIGHT_NORMAL: break; case wxFONTWEIGHT_LIGHT: desc << _(" light"); break; case wxFONTWEIGHT_BOLD: desc << _(" bold"); break; } switch ( GetStyle() ) { default: wxFAIL_MSG( wxT("unknown font style") ); // fall through case wxFONTSTYLE_NORMAL: break; // we don't distinguish between the two for now anyhow... case wxFONTSTYLE_ITALIC: case wxFONTSTYLE_SLANT: desc << _(" italic"); break; } wxString face = GetFaceName(); if ( !face.empty() ) { if (face.Contains(' ') || face.Contains(';') || face.Contains(',')) { face.Replace("'", ""); // eventually remove quote characters: most systems do not // allow them in a facename anyway so this usually does nothing // make it possible for FromUserString() function to understand // that the different words which compose this facename are // not different adjectives or other data but rather all parts // of the facename desc << wxT(" '") << face << _("'"); } else desc << wxT(' ') << face; } else // no face name specified { // use the family wxString familyStr; switch ( GetFamily() ) { case wxFONTFAMILY_DECORATIVE: familyStr = "decorative"; break; case wxFONTFAMILY_ROMAN: familyStr = "roman"; break; case wxFONTFAMILY_SCRIPT: familyStr = "script"; break; case wxFONTFAMILY_SWISS: familyStr = "swiss"; break; case wxFONTFAMILY_MODERN: familyStr = "modern"; break; case wxFONTFAMILY_TELETYPE: familyStr = "teletype"; break; case wxFONTFAMILY_DEFAULT: case wxFONTFAMILY_UNKNOWN: break; default: wxFAIL_MSG( "unknown font family" ); } if ( !familyStr.empty() ) desc << " '" << familyStr << " family'"; } int size = GetPointSize(); if ( size != wxNORMAL_FONT->GetPointSize() ) { desc << wxT(' ') << size; } #if wxUSE_FONTMAP wxFontEncoding enc = GetEncoding(); if ( enc != wxFONTENCODING_DEFAULT && enc != wxFONTENCODING_SYSTEM ) { desc << wxT(' ') << wxFontMapper::GetEncodingName(enc); } #endif // wxUSE_FONTMAP return desc.Strip(wxString::both).MakeLower(); }