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();
52 extern "C" int wxCMPFUNC_CONV
53 wxCompareFamilies (const void *a
, const void *b
)
55 const char *a_name
= pango_font_family_get_name (*(PangoFontFamily
**)a
);
56 const char *b_name
= pango_font_family_get_name (*(PangoFontFamily
**)b
);
58 return g_utf8_collate (a_name
, b_name
);
61 bool wxFontEnumerator::EnumerateFacenames(wxFontEncoding encoding
,
64 if ( encoding
!= wxFONTENCODING_SYSTEM
&& encoding
!= wxFONTENCODING_UTF8
)
66 // Pango supports only UTF-8 encoding (and system means any, so we
71 #if defined(__WXGTK20__) || !defined(HAVE_PANGO_FONT_FAMILY_IS_MONOSPACE)
73 #if defined(__WXGTK24__)
74 && (gtk_check_version(2,4,0) != NULL
)
78 OnFacename( wxT("monospace") );
80 else // !fixedWidthOnly
81 #endif // __WXGTK20__ || !HAVE_PANGO_FONT_FAMILY_IS_MONOSPACE
83 PangoFontFamily
**families
= NULL
;
85 pango_context_list_families (
87 gtk_widget_get_pango_context( wxGetRootWindow() ),
89 wxTheApp
->GetPangoContext(),
91 &families
, &n_families
);
92 qsort (families
, n_families
, sizeof (PangoFontFamily
*), wxCompareFamilies
);
94 for (int i
=0; i
<n_families
; i
++)
96 #if defined(__WXGTK24__) || defined(HAVE_PANGO_FONT_FAMILY_IS_MONOSPACE)
97 if (!fixedWidthOnly
|| (
99 !gtk_check_version(2,4,0) &&
101 pango_font_family_is_monospace(families
[i
])
105 const gchar
*name
= pango_font_family_get_name(families
[i
]);
106 OnFacename(wxString(name
, wxConvUTF8
));
115 bool wxFontEnumerator::EnumerateEncodings(const wxString
& facename
)
117 return EnumerateEncodingsUTF8(facename
);
121 #else // !wxUSE_PANGO
123 #ifdef __VMS__ // Xlib.h for VMS is not (yet) compatible with C++
124 // The resulting warnings are switched off here
125 #pragma message disable nosimpint
127 #include <X11/Xlib.h>
129 #pragma message enable nosimpint
132 // ----------------------------------------------------------------------------
134 // ----------------------------------------------------------------------------
136 // create the list of all fonts with the given spacing and encoding
137 static char **CreateFontList(wxChar spacing
, wxFontEncoding encoding
,
140 // extract all font families from the given font list and call our
141 // OnFacename() for each of them
142 static bool ProcessFamiliesFromFontList(wxFontEnumerator
*This
,
147 // ----------------------------------------------------------------------------
149 // ----------------------------------------------------------------------------
151 // ============================================================================
153 // ============================================================================
155 // ----------------------------------------------------------------------------
157 // ----------------------------------------------------------------------------
160 static char **CreateFontList(wxChar spacing
,
161 wxFontEncoding encoding
,
164 wxNativeEncodingInfo info
;
165 wxGetNativeFontEncoding(encoding
, &info
);
168 if ( !wxTestFontEncoding(info
) )
170 // ask font mapper for a replacement
171 (void)wxFontMapper::Get()->GetAltForEncoding(encoding
, &info
);
173 #endif // wxUSE_FONTMAP
176 pattern
.Printf(wxT("-*-*-*-*-*-*-*-*-*-*-%c-*-%s-%s"),
178 info
.xregistry
.c_str(),
179 info
.xencoding
.c_str());
181 // get the list of all fonts
182 return XListFonts((Display
*)wxGetDisplay(), pattern
.mb_str(), 32767, nFonts
);
185 static bool ProcessFamiliesFromFontList(wxFontEnumerator
*This
,
190 wxRegEx
re(wxT("^(-[^-]*){14}$"), wxRE_NOSUB
);
191 #endif // wxUSE_REGEX
193 // extract the list of (unique) font families
194 wxSortedArrayString families
;
195 for ( int n
= 0; n
< nFonts
; n
++ )
197 char *font
= fonts
[n
];
199 if ( !re
.Matches(font
) )
200 #else // !wxUSE_REGEX
201 if ( !wxString(font
).Matches(wxT("-*-*-*-*-*-*-*-*-*-*-*-*-*-*")) )
202 #endif // wxUSE_REGEX/!wxUSE_REGEX
204 // it's not a full font name (probably an alias)
208 // coverity[returned_null]
209 char *dash
= strchr(font
+ 1, '-');
210 char *family
= dash
+ 1;
211 dash
= strchr(family
, '-');
212 *dash
= '\0'; // !NULL because Matches() above succeeded
213 wxString
fam(family
);
215 if ( families
.Index(fam
) == wxNOT_FOUND
)
217 if ( !This
->OnFacename(fam
) )
233 // ----------------------------------------------------------------------------
235 // ----------------------------------------------------------------------------
237 bool wxFontEnumerator::EnumerateFacenames(wxFontEncoding encoding
,
246 if ( fixedWidthOnly
)
249 fonts
= CreateFontList(wxT('m'), encoding
, &nFonts
);
252 cont
= ProcessFamiliesFromFontList(this, fonts
, nFonts
);
254 XFreeFontNames(fonts
);
262 fonts
= CreateFontList(wxT('c'), encoding
, &nFonts
);
270 fonts
= CreateFontList(wxT('*'), encoding
, &nFonts
);
274 // it's ok if there are no fonts in given encoding - but it's not
275 // ok if there are no fonts at all
276 wxASSERT_MSG(encoding
!= wxFONTENCODING_SYSTEM
,
277 wxT("No fonts at all on this system?"));
283 (void)ProcessFamiliesFromFontList(this, fonts
, nFonts
);
285 XFreeFontNames(fonts
);
291 bool wxFontEnumerator::EnumerateEncodings(const wxString
& family
)
297 pattern
.Printf(wxT("-*-%s-*-*-*-*-*-*-*-*-*-*-*-*"),
298 family
.empty() ? wxT("*") : family
.c_str());
300 // get the list of all fonts
302 char **fonts
= XListFonts((Display
*)wxGetDisplay(), pattern
.mb_str(),
311 // extract the list of (unique) encodings
312 wxSortedArrayString encodings
;
313 for ( int n
= 0; n
< nFonts
; n
++ )
315 char *font
= fonts
[n
];
316 if ( !wxString(font
).Matches(wxT("-*-*-*-*-*-*-*-*-*-*-*-*-*-*")) )
318 // it's not a full font name (probably an alias)
322 // extract the family
323 char *dash
= strchr(font
+ 1, '-');
324 char *familyFont
= dash
+ 1;
325 dash
= strchr(familyFont
, '-');
326 *dash
= '\0'; // !NULL because Matches() above succeeded
328 if ( !family
.empty() && (family
!= familyFont
) )
330 // family doesn't match
334 // now extract the registry/encoding
335 char *p
= dash
+ 1; // just after the dash after family
336 dash
= strrchr(p
, '-');
338 wxString
registry(dash
+ 1);
341 dash
= strrchr(p
, '-');
342 wxString
encoding(dash
+ 1);
344 encoding
<< wxT('-') << registry
;
345 if ( encodings
.Index(encoding
) == wxNOT_FOUND
)
347 if ( !OnFontEncoding(familyFont
, encoding
) )
352 encodings
.Add(encoding
);
354 //else: already had this one
357 XFreeFontNames(fonts
);
364 #endif // !wxUSE_PANGO
366 #endif // wxUSE_FONTENUM