1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/unix/fontenum.cpp 
   3 // Purpose:     wxFontEnumerator class for X11/GDK 
   4 // Author:      Vadim Zeitlin 
   8 // Copyright:   (c) Vadim Zeitlin 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // ============================================================================ 
  14 // ============================================================================ 
  16 // ---------------------------------------------------------------------------- 
  18 // ---------------------------------------------------------------------------- 
  20 // for compilers that support precompilation, includes "wx.h". 
  21 #include "wx/wxprec.h" 
  23 #include "wx/fontenum.h" 
  26     #include "wx/dynarray.h" 
  27     #include "wx/string.h" 
  33 #include "wx/fontmap.h" 
  34 #include "wx/fontutil.h" 
  35 #include "wx/encinfo.h" 
  37 // ---------------------------------------------------------------------------- 
  39 // ---------------------------------------------------------------------------- 
  43 #include "pango/pango.h" 
  47 extern GtkWidget 
*wxGetRootWindow(); 
  50 extern "C" int wxCMPFUNC_CONV
 
  51 wxCompareFamilies (const void *a
, const void *b
) 
  53   const char *a_name 
= pango_font_family_get_name (*(PangoFontFamily 
**)a
); 
  54   const char *b_name 
= pango_font_family_get_name (*(PangoFontFamily 
**)b
); 
  56   return g_utf8_collate (a_name
, b_name
); 
  59 bool wxFontEnumerator::EnumerateFacenames(wxFontEncoding encoding
, 
  62     if ( encoding 
!= wxFONTENCODING_SYSTEM 
&& encoding 
!= wxFONTENCODING_UTF8 
) 
  64         // Pango supports only UTF-8 encoding (and system means any, so we 
  69 #if defined(__WXGTK20__) || !defined(HAVE_PANGO_FONT_FAMILY_IS_MONOSPACE) 
  71 #if defined(__WXGTK24__) 
  72         && (gtk_check_version(2,4,0) != NULL
) 
  76         OnFacename( wxT("monospace") ); 
  78     else // !fixedWidthOnly 
  79 #endif // __WXGTK20__ || !HAVE_PANGO_FONT_FAMILY_IS_MONOSPACE 
  81         PangoFontFamily 
**families 
= NULL
; 
  83         pango_context_list_families ( 
  85             gtk_widget_get_pango_context( wxGetRootWindow() ), 
  87             wxTheApp
->GetPangoContext(), 
  89             &families
, &n_families 
); 
  90         qsort (families
, n_families
, sizeof (PangoFontFamily 
*), wxCompareFamilies
); 
  92         for (int i
=0; i
<n_families
; i
++) 
  94 #if defined(__WXGTK24__) || defined(HAVE_PANGO_FONT_FAMILY_IS_MONOSPACE) 
  95             if (!fixedWidthOnly 
|| ( 
  97                 !gtk_check_version(2,4,0) && 
  99                 pango_font_family_is_monospace(families
[i
]) 
 103                 const gchar 
*name 
= pango_font_family_get_name(families
[i
]); 
 104                 OnFacename(wxString(name
, wxConvUTF8
)); 
 113 bool wxFontEnumerator::EnumerateEncodings(const wxString
& facename
) 
 115     // name of UTF-8 encoding: no need to use wxFontMapper for it as it's 
 116     // unlikely to change 
 117     const wxString 
utf8(_T("UTF-8")); 
 120     // all fonts are in UTF-8 only when using Pango 
 121     if ( !facename
.empty() ) 
 123         OnFontEncoding(facename
, utf8
); 
 127     // so enumerating all facenames supporting this encoding is the same as 
 128     // enumerating all facenames 
 129     const wxArrayString 
facenames(GetFacenames(wxFONTENCODING_UTF8
)); 
 130     const size_t count 
= facenames
.size(); 
 134     for ( size_t n 
= 0; n 
< count
; n
++ ) 
 136         OnFontEncoding(facenames
[n
], utf8
); 
 143 #else // !wxUSE_PANGO 
 145 #ifdef __VMS__ // Xlib.h for VMS is not (yet) compatible with C++ 
 146                // The resulting warnings are switched off here 
 147 #pragma message disable nosimpint 
 149 #include <X11/Xlib.h> 
 151 #pragma message enable nosimpint 
 154 // ---------------------------------------------------------------------------- 
 156 // ---------------------------------------------------------------------------- 
 158 // create the list of all fonts with the given spacing and encoding 
 159 static char **CreateFontList(wxChar spacing
, wxFontEncoding encoding
, 
 162 // extract all font families from the given font list and call our 
 163 // OnFacename() for each of them 
 164 static bool ProcessFamiliesFromFontList(wxFontEnumerator 
*This
, 
 169 // ---------------------------------------------------------------------------- 
 171 // ---------------------------------------------------------------------------- 
 173 // ============================================================================ 
 175 // ============================================================================ 
 177 // ---------------------------------------------------------------------------- 
 179 // ---------------------------------------------------------------------------- 
 182 static char **CreateFontList(wxChar spacing
, 
 183                              wxFontEncoding encoding
, 
 186     wxNativeEncodingInfo info
; 
 187     wxGetNativeFontEncoding(encoding
, &info
); 
 190     if ( !wxTestFontEncoding(info
) ) 
 192         // ask font mapper for a replacement 
 193         (void)wxFontMapper::Get()->GetAltForEncoding(encoding
, &info
); 
 195 #endif // wxUSE_FONTMAP 
 198     pattern
.Printf(wxT("-*-*-*-*-*-*-*-*-*-*-%c-*-%s-%s"), 
 200                    info
.xregistry
.c_str(), 
 201                    info
.xencoding
.c_str()); 
 203     // get the list of all fonts 
 204     return XListFonts((Display 
*)wxGetDisplay(), pattern
.mb_str(), 32767, nFonts
); 
 207 static bool ProcessFamiliesFromFontList(wxFontEnumerator 
*This
, 
 212     wxRegEx 
re(wxT("^(-[^-]*){14}$"), wxRE_NOSUB
); 
 213 #endif // wxUSE_REGEX 
 215     // extract the list of (unique) font families 
 216     wxSortedArrayString families
; 
 217     for ( int n 
= 0; n 
< nFonts
; n
++ ) 
 219         char *font 
= fonts
[n
]; 
 221         if ( !re
.Matches(font
) ) 
 222 #else // !wxUSE_REGEX 
 223         if ( !wxString(font
).Matches(wxT("-*-*-*-*-*-*-*-*-*-*-*-*-*-*")) ) 
 224 #endif // wxUSE_REGEX/!wxUSE_REGEX 
 226             // it's not a full font name (probably an alias) 
 230         // coverity[returned_null] 
 231         char *dash 
= strchr(font 
+ 1, '-'); 
 232         char *family 
= dash 
+ 1; 
 233         dash 
= strchr(family
, '-'); 
 234         *dash 
= '\0'; // !NULL because Matches() above succeeded 
 235         wxString 
fam(family
); 
 237         if ( families
.Index(fam
) == wxNOT_FOUND 
) 
 239             if ( !This
->OnFacename(fam
) ) 
 255 // ---------------------------------------------------------------------------- 
 257 // ---------------------------------------------------------------------------- 
 259 bool wxFontEnumerator::EnumerateFacenames(wxFontEncoding encoding
, 
 268     if ( fixedWidthOnly 
) 
 271         fonts 
= CreateFontList(wxT('m'), encoding
, &nFonts
); 
 274             cont 
= ProcessFamiliesFromFontList(this, fonts
, nFonts
); 
 276             XFreeFontNames(fonts
); 
 284         fonts 
= CreateFontList(wxT('c'), encoding
, &nFonts
); 
 292         fonts 
= CreateFontList(wxT('*'), encoding
, &nFonts
); 
 296             // it's ok if there are no fonts in given encoding - but it's not 
 297             // ok if there are no fonts at all 
 298             wxASSERT_MSG(encoding 
!= wxFONTENCODING_SYSTEM
, 
 299                          wxT("No fonts at all on this system?")); 
 305     (void)ProcessFamiliesFromFontList(this, fonts
, nFonts
); 
 307     XFreeFontNames(fonts
); 
 313 bool wxFontEnumerator::EnumerateEncodings(const wxString
& family
) 
 319     pattern
.Printf(wxT("-*-%s-*-*-*-*-*-*-*-*-*-*-*-*"), 
 320                    family
.empty() ? wxT("*") : family
.c_str()); 
 322     // get the list of all fonts 
 324     char **fonts 
= XListFonts((Display 
*)wxGetDisplay(), pattern
.mb_str(), 
 333     // extract the list of (unique) encodings 
 334     wxSortedArrayString encodings
; 
 335     for ( int n 
= 0; n 
< nFonts
; n
++ ) 
 337         char *font 
= fonts
[n
]; 
 338         if ( !wxString(font
).Matches(wxT("-*-*-*-*-*-*-*-*-*-*-*-*-*-*")) ) 
 340             // it's not a full font name (probably an alias) 
 344         // extract the family 
 345         char *dash 
= strchr(font 
+ 1, '-'); 
 346         char *familyFont 
= dash 
+ 1; 
 347         dash 
= strchr(familyFont
, '-'); 
 348         *dash 
= '\0'; // !NULL because Matches() above succeeded 
 350         if ( !family
.empty() && (family 
!= familyFont
) ) 
 352             // family doesn't match 
 356         // now extract the registry/encoding 
 357         char *p 
= dash 
+ 1; // just after the dash after family 
 358         dash 
= strrchr(p
, '-'); 
 360         wxString 
registry(dash 
+ 1); 
 363         dash 
= strrchr(p
, '-'); 
 364         wxString 
encoding(dash 
+ 1); 
 366         encoding 
<< wxT('-') << registry
; 
 367         if ( encodings
.Index(encoding
) == wxNOT_FOUND 
) 
 369             if ( !OnFontEncoding(familyFont
, encoding
) ) 
 374             encodings
.Add(encoding
); 
 376         //else: already had this one 
 379     XFreeFontNames(fonts
); 
 386 #endif // !wxUSE_PANGO