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 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
21 #pragma implementation "fontenum.h"
24 // for compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
27 #include "wx/dynarray.h"
28 #include "wx/string.h"
32 #include "wx/fontmap.h"
33 #include "wx/fontenum.h"
34 #include "wx/fontutil.h"
35 #include "wx/encinfo.h"
37 // ----------------------------------------------------------------------------
39 // ----------------------------------------------------------------------------
43 #include "pango/pango.h"
47 extern GtkWidget
*wxGetRootWindow();
51 cmp_families (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 // I admit I don't yet understand encodings with Pango
60 bool wxFontEnumerator::EnumerateFacenames(wxFontEncoding encoding
,
65 OnFacename( wxT("monospace") );
69 PangoFontFamily
**families
= NULL
;
71 pango_context_list_families (
73 gtk_widget_get_pango_context( wxGetRootWindow() ),
75 wxTheApp
->GetPangoContext(),
77 &families
, &n_families
);
78 qsort (families
, n_families
, sizeof (PangoFontFamily
*), cmp_families
);
80 for (int i
=0; i
<n_families
; i
++)
82 const gchar
*name
= pango_font_family_get_name( families
[i
] );
84 wxString
tmp( name
, wxConvUTF8
);
92 bool wxFontEnumerator::EnumerateEncodings(const wxString
& family
)
101 #ifdef __VMS__ // Xlib.h for VMS is not (yet) compatible with C++
102 // The resulting warnings are switched off here
103 #pragma message disable nosimpint
105 #include <X11/Xlib.h>
107 #pragma message enable nosimpint
110 // ----------------------------------------------------------------------------
112 // ----------------------------------------------------------------------------
114 // create the list of all fonts with the given spacing and encoding
115 static char **CreateFontList(wxChar spacing
, wxFontEncoding encoding
,
118 // extract all font families from the given font list and call our
119 // OnFacename() for each of them
120 static bool ProcessFamiliesFromFontList(wxFontEnumerator
*This
,
125 // ----------------------------------------------------------------------------
127 // ----------------------------------------------------------------------------
129 // ============================================================================
131 // ============================================================================
133 // ----------------------------------------------------------------------------
135 // ----------------------------------------------------------------------------
138 static char **CreateFontList(wxChar spacing
,
139 wxFontEncoding encoding
,
142 wxNativeEncodingInfo info
;
143 wxGetNativeFontEncoding(encoding
, &info
);
146 if ( !wxTestFontEncoding(info
) )
148 // ask font mapper for a replacement
149 (void)wxFontMapper::Get()->GetAltForEncoding(encoding
, &info
);
151 #endif // wxUSE_FONTMAP
154 pattern
.Printf(wxT("-*-*-*-*-*-*-*-*-*-*-%c-*-%s-%s"),
156 info
.xregistry
.c_str(),
157 info
.xencoding
.c_str());
159 // get the list of all fonts
160 return XListFonts((Display
*)wxGetDisplay(), pattern
.mb_str(), 32767, nFonts
);
163 static bool ProcessFamiliesFromFontList(wxFontEnumerator
*This
,
168 wxRegEx
re(wxT("^(-[^-]*){14}$"), wxRE_NOSUB
);
169 #endif // wxUSE_REGEX
171 // extract the list of (unique) font families
172 wxSortedArrayString families
;
173 for ( int n
= 0; n
< nFonts
; n
++ )
175 char *font
= fonts
[n
];
177 if ( !re
.Matches(font
) )
178 #else // !wxUSE_REGEX
179 if ( !wxString(font
).Matches(wxT("-*-*-*-*-*-*-*-*-*-*-*-*-*-*")) )
180 #endif // wxUSE_REGEX/!wxUSE_REGEX
182 // it's not a full font name (probably an alias)
186 char *dash
= strchr(font
+ 1, '-');
187 char *family
= dash
+ 1;
188 dash
= strchr(family
, '-');
189 *dash
= '\0'; // !NULL because Matches() above succeeded
190 wxString
fam(family
);
192 if ( families
.Index(fam
) == wxNOT_FOUND
)
194 if ( !This
->OnFacename(fam
) )
210 // ----------------------------------------------------------------------------
212 // ----------------------------------------------------------------------------
214 bool wxFontEnumerator::EnumerateFacenames(wxFontEncoding encoding
,
223 if ( fixedWidthOnly
)
226 fonts
= CreateFontList(wxT('m'), encoding
, &nFonts
);
229 cont
= ProcessFamiliesFromFontList(this, fonts
, nFonts
);
231 XFreeFontNames(fonts
);
239 fonts
= CreateFontList(wxT('c'), encoding
, &nFonts
);
247 fonts
= CreateFontList(wxT('*'), encoding
, &nFonts
);
251 // it's ok if there are no fonts in given encoding - but it's not
252 // ok if there are no fonts at all
253 wxASSERT_MSG(encoding
!= wxFONTENCODING_SYSTEM
,
254 wxT("No fonts at all on this system?"));
260 (void)ProcessFamiliesFromFontList(this, fonts
, nFonts
);
262 XFreeFontNames(fonts
);
268 bool wxFontEnumerator::EnumerateEncodings(const wxString
& family
)
274 pattern
.Printf(wxT("-*-%s-*-*-*-*-*-*-*-*-*-*-*-*"),
275 family
.IsEmpty() ? wxT("*") : family
.c_str());
277 // get the list of all fonts
279 char **fonts
= XListFonts((Display
*)wxGetDisplay(), pattern
.mb_str(),
288 // extract the list of (unique) encodings
289 wxSortedArrayString encodings
;
290 for ( int n
= 0; n
< nFonts
; n
++ )
292 char *font
= fonts
[n
];
293 if ( !wxString(font
).Matches(wxT("-*-*-*-*-*-*-*-*-*-*-*-*-*-*")) )
295 // it's not a full font name (probably an alias)
299 // extract the family
300 char *dash
= strchr(font
+ 1, '-');
301 char *familyFont
= dash
+ 1;
302 dash
= strchr(familyFont
, '-');
303 *dash
= '\0'; // !NULL because Matches() above succeeded
305 if ( !family
.IsEmpty() && (family
!= familyFont
) )
307 // family doesn't match
311 // now extract the registry/encoding
312 char *p
= dash
+ 1; // just after the dash after family
313 dash
= strrchr(p
, '-');
315 wxString
registry(dash
+ 1);
318 dash
= strrchr(p
, '-');
319 wxString
encoding(dash
+ 1);
321 encoding
<< wxT('-') << registry
;
322 if ( encodings
.Index(encoding
) == wxNOT_FOUND
)
324 if ( !OnFontEncoding(familyFont
, encoding
) )
329 encodings
.Add(encoding
);
331 //else: already had this one
334 XFreeFontNames(fonts
);