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" 
  25 #include "wx/fontenum.h" 
  28     #include "wx/dynarray.h" 
  29     #include "wx/string.h" 
  35 #include "wx/fontmap.h" 
  36 #include "wx/fontutil.h" 
  37 #include "wx/encinfo.h" 
  39 // ---------------------------------------------------------------------------- 
  41 // ---------------------------------------------------------------------------- 
  45 #include "pango/pango.h" 
  49 extern GtkWidget 
*wxGetRootWindow(); 
  54 static int wxCMPFUNC_CONV
 
  55 wxCompareFamilies (const void *a
, const void *b
) 
  57   const char *a_name 
= pango_font_family_get_name (*(PangoFontFamily 
**)a
); 
  58   const char *b_name 
= pango_font_family_get_name (*(PangoFontFamily 
**)b
); 
  60   return g_utf8_collate (a_name
, b_name
); 
  64 bool wxFontEnumerator::EnumerateFacenames(wxFontEncoding encoding
, 
  67     if ( encoding 
!= wxFONTENCODING_SYSTEM 
&& encoding 
!= wxFONTENCODING_UTF8 
) 
  69         // Pango supports only UTF-8 encoding (and system means any, so we 
  74     PangoFontFamily 
**families 
= NULL
; 
  76     pango_context_list_families ( 
  78         gtk_widget_get_pango_context( wxGetRootWindow() ), 
  80         wxTheApp
->GetPangoContext(), 
  82         &families
, &n_families 
); 
  83     qsort (families
, n_families
, sizeof (PangoFontFamily 
*), wxCompareFamilies
); 
  85     for ( int i 
= 0; i 
< n_families
; i
++ ) 
  87 #if defined(__WXGTK20__) || defined(HAVE_PANGO_FONT_FAMILY_IS_MONOSPACE) 
  88         if ( !fixedWidthOnly 
|| 
  89             pango_font_family_is_monospace(families
[i
]) ) 
  92             const gchar 
*name 
= pango_font_family_get_name(families
[i
]); 
  93             OnFacename(wxString(name
, wxConvUTF8
)); 
 101 bool wxFontEnumerator::EnumerateEncodings(const wxString
& facename
) 
 103     return EnumerateEncodingsUTF8(facename
); 
 107 #else // !wxUSE_PANGO 
 109 #ifdef __VMS__ // Xlib.h for VMS is not (yet) compatible with C++ 
 110                // The resulting warnings are switched off here 
 111 #pragma message disable nosimpint 
 113 #include <X11/Xlib.h> 
 115 #pragma message enable nosimpint 
 118 // ---------------------------------------------------------------------------- 
 120 // ---------------------------------------------------------------------------- 
 122 // create the list of all fonts with the given spacing and encoding 
 123 static char **CreateFontList(wxChar spacing
, wxFontEncoding encoding
, 
 126 // extract all font families from the given font list and call our 
 127 // OnFacename() for each of them 
 128 static bool ProcessFamiliesFromFontList(wxFontEnumerator 
*This
, 
 133 // ---------------------------------------------------------------------------- 
 135 // ---------------------------------------------------------------------------- 
 137 // ============================================================================ 
 139 // ============================================================================ 
 141 // ---------------------------------------------------------------------------- 
 143 // ---------------------------------------------------------------------------- 
 146 static char **CreateFontList(wxChar spacing
, 
 147                              wxFontEncoding encoding
, 
 150     wxNativeEncodingInfo info
; 
 151     wxGetNativeFontEncoding(encoding
, &info
); 
 154     if ( !wxTestFontEncoding(info
) ) 
 156         // ask font mapper for a replacement 
 157         (void)wxFontMapper::Get()->GetAltForEncoding(encoding
, &info
); 
 159 #endif // wxUSE_FONTMAP 
 162     pattern
.Printf(wxT("-*-*-*-*-*-*-*-*-*-*-%c-*-%s-%s"), 
 164                    info
.xregistry
.c_str(), 
 165                    info
.xencoding
.c_str()); 
 167     // get the list of all fonts 
 168     return XListFonts((Display 
*)wxGetDisplay(), pattern
.mb_str(), 32767, nFonts
); 
 171 static bool ProcessFamiliesFromFontList(wxFontEnumerator 
*This
, 
 176     wxRegEx 
re(wxT("^(-[^-]*){14}$"), wxRE_NOSUB
); 
 177 #endif // wxUSE_REGEX 
 179     // extract the list of (unique) font families 
 180     wxSortedArrayString families
; 
 181     for ( int n 
= 0; n 
< nFonts
; n
++ ) 
 183         char *font 
= fonts
[n
]; 
 185         if ( !re
.Matches(font
) ) 
 186 #else // !wxUSE_REGEX 
 187         if ( !wxString(font
).Matches(wxT("-*-*-*-*-*-*-*-*-*-*-*-*-*-*")) ) 
 188 #endif // wxUSE_REGEX/!wxUSE_REGEX 
 190             // it's not a full font name (probably an alias) 
 194         // coverity[returned_null] 
 195         char *dash 
= strchr(font 
+ 1, '-'); 
 196         char *family 
= dash 
+ 1; 
 197         dash 
= strchr(family
, '-'); 
 198         *dash 
= '\0'; // !NULL because Matches() above succeeded 
 199         wxString 
fam(family
); 
 201         if ( families
.Index(fam
) == wxNOT_FOUND 
) 
 203             if ( !This
->OnFacename(fam
) ) 
 219 // ---------------------------------------------------------------------------- 
 221 // ---------------------------------------------------------------------------- 
 223 bool wxFontEnumerator::EnumerateFacenames(wxFontEncoding encoding
, 
 232     if ( fixedWidthOnly 
) 
 235         fonts 
= CreateFontList(wxT('m'), encoding
, &nFonts
); 
 238             cont 
= ProcessFamiliesFromFontList(this, fonts
, nFonts
); 
 240             XFreeFontNames(fonts
); 
 248         fonts 
= CreateFontList(wxT('c'), encoding
, &nFonts
); 
 256         fonts 
= CreateFontList(wxT('*'), encoding
, &nFonts
); 
 260             // it's ok if there are no fonts in given encoding - but it's not 
 261             // ok if there are no fonts at all 
 262             wxASSERT_MSG(encoding 
!= wxFONTENCODING_SYSTEM
, 
 263                          wxT("No fonts at all on this system?")); 
 269     (void)ProcessFamiliesFromFontList(this, fonts
, nFonts
); 
 271     XFreeFontNames(fonts
); 
 277 bool wxFontEnumerator::EnumerateEncodings(const wxString
& family
) 
 283     pattern
.Printf(wxT("-*-%s-*-*-*-*-*-*-*-*-*-*-*-*"), 
 284                    family
.empty() ? wxT("*") : family
.c_str()); 
 286     // get the list of all fonts 
 288     char **fonts 
= XListFonts((Display 
*)wxGetDisplay(), pattern
.mb_str(), 
 297     // extract the list of (unique) encodings 
 298     wxSortedArrayString encodings
; 
 299     for ( int n 
= 0; n 
< nFonts
; n
++ ) 
 301         char *font 
= fonts
[n
]; 
 302         if ( !wxString(font
).Matches(wxT("-*-*-*-*-*-*-*-*-*-*-*-*-*-*")) ) 
 304             // it's not a full font name (probably an alias) 
 308         // extract the family 
 309         char *dash 
= strchr(font 
+ 1, '-'); 
 310         char *familyFont 
= dash 
+ 1; 
 311         dash 
= strchr(familyFont
, '-'); 
 312         *dash 
= '\0'; // !NULL because Matches() above succeeded 
 314         if ( !family
.empty() && (family 
!= familyFont
) ) 
 316             // family doesn't match 
 320         // now extract the registry/encoding 
 321         char *p 
= dash 
+ 1; // just after the dash after family 
 322         dash 
= strrchr(p
, '-'); 
 324         wxString 
registry(dash 
+ 1); 
 327         dash 
= strrchr(p
, '-'); 
 328         wxString 
encoding(dash 
+ 1); 
 330         encoding 
<< wxT('-') << registry
; 
 331         if ( encodings
.Index(encoding
) == wxNOT_FOUND 
) 
 333             if ( !OnFontEncoding(familyFont
, encoding
) ) 
 338             encodings
.Add(encoding
); 
 340         //else: already had this one 
 343     XFreeFontNames(fonts
); 
 350 #endif // !wxUSE_PANGO 
 352 #endif // wxUSE_FONTENUM