1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/unix/fontenum.cpp
3 // Purpose: wxFontEnumerator class for X11/GDK
4 // Author: Vadim Zeitlin
7 // Copyright: (c) Vadim Zeitlin
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 // ============================================================================
13 // ============================================================================
15 // ----------------------------------------------------------------------------
17 // ----------------------------------------------------------------------------
19 // for compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
24 #include "wx/fontenum.h"
27 #include "wx/dynarray.h"
28 #include "wx/string.h"
34 #include "wx/fontmap.h"
35 #include "wx/fontutil.h"
36 #include "wx/encinfo.h"
38 // ----------------------------------------------------------------------------
40 // ----------------------------------------------------------------------------
44 #include "pango/pango.h"
48 extern GtkWidget
*wxGetRootWindow();
53 static int wxCMPFUNC_CONV
54 wxCompareFamilies (const void *a
, const void *b
)
56 const char *a_name
= pango_font_family_get_name (*(PangoFontFamily
**)a
);
57 const char *b_name
= pango_font_family_get_name (*(PangoFontFamily
**)b
);
59 return g_utf8_collate (a_name
, b_name
);
63 bool wxFontEnumerator::EnumerateFacenames(wxFontEncoding encoding
,
66 if ( encoding
!= wxFONTENCODING_SYSTEM
&& encoding
!= wxFONTENCODING_UTF8
)
68 // Pango supports only UTF-8 encoding (and system means any, so we
73 PangoFontFamily
**families
= NULL
;
75 pango_context_list_families (
77 gtk_widget_get_pango_context( wxGetRootWindow() ),
79 wxTheApp
->GetPangoContext(),
81 &families
, &n_families
);
82 qsort (families
, n_families
, sizeof (PangoFontFamily
*), wxCompareFamilies
);
84 for ( int i
= 0; i
< n_families
; i
++ )
86 #if defined(__WXGTK20__) || defined(HAVE_PANGO_FONT_FAMILY_IS_MONOSPACE)
87 if ( !fixedWidthOnly
||
88 pango_font_family_is_monospace(families
[i
]) )
91 const gchar
*name
= pango_font_family_get_name(families
[i
]);
92 OnFacename(wxString(name
, wxConvUTF8
));
100 bool wxFontEnumerator::EnumerateEncodings(const wxString
& facename
)
102 return EnumerateEncodingsUTF8(facename
);
106 #else // !wxUSE_PANGO
108 #ifdef __VMS__ // Xlib.h for VMS is not (yet) compatible with C++
109 // The resulting warnings are switched off here
110 #pragma message disable nosimpint
112 #include <X11/Xlib.h>
114 #pragma message enable nosimpint
117 // ----------------------------------------------------------------------------
119 // ----------------------------------------------------------------------------
121 // create the list of all fonts with the given spacing and encoding
122 static char **CreateFontList(wxChar spacing
, wxFontEncoding encoding
,
125 // extract all font families from the given font list and call our
126 // OnFacename() for each of them
127 static bool ProcessFamiliesFromFontList(wxFontEnumerator
*This
,
132 // ----------------------------------------------------------------------------
134 // ----------------------------------------------------------------------------
136 // ============================================================================
138 // ============================================================================
140 // ----------------------------------------------------------------------------
142 // ----------------------------------------------------------------------------
145 static char **CreateFontList(wxChar spacing
,
146 wxFontEncoding encoding
,
149 wxNativeEncodingInfo info
;
150 wxGetNativeFontEncoding(encoding
, &info
);
153 if ( !wxTestFontEncoding(info
) )
155 // ask font mapper for a replacement
156 (void)wxFontMapper::Get()->GetAltForEncoding(encoding
, &info
);
158 #endif // wxUSE_FONTMAP
161 pattern
.Printf(wxT("-*-*-*-*-*-*-*-*-*-*-%c-*-%s-%s"),
163 info
.xregistry
.c_str(),
164 info
.xencoding
.c_str());
166 // get the list of all fonts
167 return XListFonts((Display
*)wxGetDisplay(), pattern
.mb_str(), 32767, nFonts
);
170 static bool ProcessFamiliesFromFontList(wxFontEnumerator
*This
,
175 wxRegEx
re(wxT("^(-[^-]*){14}$"), wxRE_NOSUB
);
176 #endif // wxUSE_REGEX
178 // extract the list of (unique) font families
179 wxSortedArrayString families
;
180 for ( int n
= 0; n
< nFonts
; n
++ )
182 char *font
= fonts
[n
];
184 if ( !re
.Matches(font
) )
185 #else // !wxUSE_REGEX
186 if ( !wxString(font
).Matches(wxT("-*-*-*-*-*-*-*-*-*-*-*-*-*-*")) )
187 #endif // wxUSE_REGEX/!wxUSE_REGEX
189 // it's not a full font name (probably an alias)
193 // coverity[returned_null]
194 char *dash
= strchr(font
+ 1, '-');
195 char *family
= dash
+ 1;
196 dash
= strchr(family
, '-');
197 *dash
= '\0'; // !NULL because Matches() above succeeded
198 wxString
fam(family
);
200 if ( families
.Index(fam
) == wxNOT_FOUND
)
202 if ( !This
->OnFacename(fam
) )
218 // ----------------------------------------------------------------------------
220 // ----------------------------------------------------------------------------
222 bool wxFontEnumerator::EnumerateFacenames(wxFontEncoding encoding
,
231 if ( fixedWidthOnly
)
234 fonts
= CreateFontList(wxT('m'), encoding
, &nFonts
);
237 cont
= ProcessFamiliesFromFontList(this, fonts
, nFonts
);
239 XFreeFontNames(fonts
);
247 fonts
= CreateFontList(wxT('c'), encoding
, &nFonts
);
255 fonts
= CreateFontList(wxT('*'), encoding
, &nFonts
);
259 // it's ok if there are no fonts in given encoding - but it's not
260 // ok if there are no fonts at all
261 wxASSERT_MSG(encoding
!= wxFONTENCODING_SYSTEM
,
262 wxT("No fonts at all on this system?"));
268 (void)ProcessFamiliesFromFontList(this, fonts
, nFonts
);
270 XFreeFontNames(fonts
);
276 bool wxFontEnumerator::EnumerateEncodings(const wxString
& family
)
282 pattern
.Printf(wxT("-*-%s-*-*-*-*-*-*-*-*-*-*-*-*"),
283 family
.empty() ? wxT("*") : family
.c_str());
285 // get the list of all fonts
287 char **fonts
= XListFonts((Display
*)wxGetDisplay(), pattern
.mb_str(),
296 // extract the list of (unique) encodings
297 wxSortedArrayString encodings
;
298 for ( int n
= 0; n
< nFonts
; n
++ )
300 char *font
= fonts
[n
];
301 if ( !wxString(font
).Matches(wxT("-*-*-*-*-*-*-*-*-*-*-*-*-*-*")) )
303 // it's not a full font name (probably an alias)
307 // extract the family
308 char *dash
= strchr(font
+ 1, '-');
309 char *familyFont
= dash
+ 1;
310 dash
= strchr(familyFont
, '-');
311 *dash
= '\0'; // !NULL because Matches() above succeeded
313 if ( !family
.empty() && (family
!= familyFont
) )
315 // family doesn't match
319 // now extract the registry/encoding
320 char *p
= dash
+ 1; // just after the dash after family
321 dash
= strrchr(p
, '-');
323 wxString
registry(dash
+ 1);
326 dash
= strrchr(p
, '-');
327 wxString
encoding(dash
+ 1);
329 encoding
<< wxT('-') << registry
;
330 if ( encodings
.Index(encoding
) == wxNOT_FOUND
)
332 if ( !OnFontEncoding(familyFont
, encoding
) )
337 encodings
.Add(encoding
);
339 //else: already had this one
342 XFreeFontNames(fonts
);
349 #endif // !wxUSE_PANGO
351 #endif // wxUSE_FONTENUM