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 // ----------------------------------------------------------------------------
21 #pragma implementation "fontenum.h"
25 #include "wx/dynarray.h"
26 #include "wx/string.h"
30 #include "wx/fontmap.h"
31 #include "wx/fontenum.h"
32 #include "wx/fontutil.h"
34 // ----------------------------------------------------------------------------
36 // ----------------------------------------------------------------------------
40 #include "wx/gtk/private.h"
42 extern GtkWidget
*wxGetRootWindow();
45 cmp_families (const void *a
, const void *b
)
47 const char *a_name
= pango_font_family_get_name (*(PangoFontFamily
**)a
);
48 const char *b_name
= pango_font_family_get_name (*(PangoFontFamily
**)b
);
50 return g_utf8_collate (a_name
, b_name
);
53 // I admit I don't yet understand encodings with Pango
54 bool wxFontEnumerator::EnumerateFacenames(wxFontEncoding encoding
,
59 OnFacename( wxT("monospace") );
63 PangoFontFamily
**families
= NULL
;
65 pango_context_list_families (
66 gtk_widget_get_pango_context( wxGetRootWindow() ),
67 &families
, &n_families
);
68 qsort (families
, n_families
, sizeof (PangoFontFamily
*), cmp_families
);
70 for (int i
=0; i
<n_families
; i
++)
72 const gchar
*name
= pango_font_family_get_name( families
[i
] );
74 wxString
tmp( name
, wxConvUTF8
);
82 bool wxFontEnumerator::EnumerateEncodings(const wxString
& family
)
91 #ifdef __VMS__ // Xlib.h for VMS is not (yet) compatible with C++
92 // The resulting warnings are switched off here
93 #pragma message disable nosimpint
97 #pragma message enable nosimpint
100 // ----------------------------------------------------------------------------
102 // ----------------------------------------------------------------------------
104 // create the list of all fonts with the given spacing and encoding
105 static char **CreateFontList(wxChar spacing
, wxFontEncoding encoding
,
108 // extract all font families from the given font list and call our
109 // OnFacename() for each of them
110 static bool ProcessFamiliesFromFontList(wxFontEnumerator
*This
,
115 // ----------------------------------------------------------------------------
117 // ----------------------------------------------------------------------------
119 // ============================================================================
121 // ============================================================================
123 // ----------------------------------------------------------------------------
125 // ----------------------------------------------------------------------------
128 static char **CreateFontList(wxChar spacing
,
129 wxFontEncoding encoding
,
132 wxNativeEncodingInfo info
;
133 wxGetNativeFontEncoding(encoding
, &info
);
136 if ( !wxTestFontEncoding(info
) )
138 // ask font mapper for a replacement
139 (void)wxFontMapper::Get()->GetAltForEncoding(encoding
, &info
);
141 #endif // wxUSE_FONTMAP
144 pattern
.Printf(wxT("-*-*-*-*-*-*-*-*-*-*-%c-*-%s-%s"),
146 info
.xregistry
.c_str(),
147 info
.xencoding
.c_str());
149 // get the list of all fonts
150 return XListFonts((Display
*)wxGetDisplay(), pattern
.mb_str(), 32767, nFonts
);
153 static bool ProcessFamiliesFromFontList(wxFontEnumerator
*This
,
158 wxRegEx
re(wxT("^(-[^-]*){14}$"), wxRE_NOSUB
);
159 #endif // wxUSE_REGEX
161 // extract the list of (unique) font families
162 wxSortedArrayString families
;
163 for ( int n
= 0; n
< nFonts
; n
++ )
165 char *font
= fonts
[n
];
167 if ( !re
.Matches(font
) )
168 #else // !wxUSE_REGEX
169 if ( !wxString(font
).Matches(wxT("-*-*-*-*-*-*-*-*-*-*-*-*-*-*")) )
170 #endif // wxUSE_REGEX/!wxUSE_REGEX
172 // it's not a full font name (probably an alias)
176 char *dash
= strchr(font
+ 1, '-');
177 char *family
= dash
+ 1;
178 dash
= strchr(family
, '-');
179 *dash
= '\0'; // !NULL because Matches() above succeeded
180 wxString
fam(family
);
182 if ( families
.Index(fam
) == wxNOT_FOUND
)
184 if ( !This
->OnFacename(fam
) )
200 // ----------------------------------------------------------------------------
202 // ----------------------------------------------------------------------------
204 bool wxFontEnumerator::EnumerateFacenames(wxFontEncoding encoding
,
213 if ( fixedWidthOnly
)
216 fonts
= CreateFontList(wxT('m'), encoding
, &nFonts
);
219 cont
= ProcessFamiliesFromFontList(this, fonts
, nFonts
);
221 XFreeFontNames(fonts
);
229 fonts
= CreateFontList(wxT('c'), encoding
, &nFonts
);
237 fonts
= CreateFontList(wxT('*'), encoding
, &nFonts
);
241 // it's ok if there are no fonts in given encoding - but it's not
242 // ok if there are no fonts at all
243 wxASSERT_MSG(encoding
!= wxFONTENCODING_SYSTEM
,
244 wxT("No fonts at all on this system?"));
250 (void)ProcessFamiliesFromFontList(this, fonts
, nFonts
);
252 XFreeFontNames(fonts
);
258 bool wxFontEnumerator::EnumerateEncodings(const wxString
& family
)
264 pattern
.Printf(wxT("-*-%s-*-*-*-*-*-*-*-*-*-*-*-*"),
265 family
.IsEmpty() ? wxT("*") : family
.c_str());
267 // get the list of all fonts
269 char **fonts
= XListFonts((Display
*)wxGetDisplay(), pattern
.mb_str(),
278 // extract the list of (unique) encodings
279 wxSortedArrayString encodings
;
280 for ( int n
= 0; n
< nFonts
; n
++ )
282 char *font
= fonts
[n
];
283 if ( !wxString(font
).Matches(wxT("-*-*-*-*-*-*-*-*-*-*-*-*-*-*")) )
285 // it's not a full font name (probably an alias)
289 // extract the family
290 char *dash
= strchr(font
+ 1, '-');
291 char *familyFont
= dash
+ 1;
292 dash
= strchr(familyFont
, '-');
293 *dash
= '\0'; // !NULL because Matches() above succeeded
295 if ( !family
.IsEmpty() && (family
!= familyFont
) )
297 // family doesn't match
301 // now extract the registry/encoding
302 char *p
= dash
+ 1; // just after the dash after family
303 dash
= strrchr(p
, '-');
305 wxString
registry(dash
+ 1);
308 dash
= strrchr(p
, '-');
309 wxString
encoding(dash
+ 1);
311 encoding
<< wxT('-') << registry
;
312 if ( encodings
.Index(encoding
) == wxNOT_FOUND
)
314 if ( !OnFontEncoding(familyFont
, encoding
) )
319 encodings
.Add(encoding
);
321 //else: already had this one
324 XFreeFontNames(fonts
);