]> git.saurik.com Git - wxWidgets.git/blame - src/unix/fontutil.cpp
(start of) wxCustomDataObject docs
[wxWidgets.git] / src / unix / fontutil.cpp
CommitLineData
7beba2fc
VZ
1/////////////////////////////////////////////////////////////////////////////
2// Name: unix/fontutil.cpp
3// Purpose: Font helper functions for X11 (GDK/X)
4// Author: Vadim Zeitlin
5// Modified by:
6// Created: 05.11.99
7// RCS-ID: $Id$
8// Copyright: (c) Vadim Zeitlin
9// Licence: wxWindows license
10/////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
20#ifdef __GNUG__
21 #pragma implementation "fontutil.h"
22#endif
23
24// For compilers that support precompilation, includes "wx.h".
25#include "wx/wxprec.h"
26
27#ifdef __BORLANDC__
28 #pragma hdrstop
29#endif
30
31#ifndef WX_PRECOMP
32#endif // PCH
33
34#include "wx/fontutil.h"
35#include "wx/fontmap.h"
36#include "wx/tokenzr.h"
37
38// ----------------------------------------------------------------------------
39// private functions
40// ----------------------------------------------------------------------------
41
42// define the functions to create and destroy native fonts for this toolkit
43#ifdef __X__
44 static inline wxNativeFont wxLoadFont(const wxString& fontSpec)
45 {
46 return XLoadQueryFont((Display *)wxGetDisplay(), fontSpec);
47 }
48
49 static inline void wxFreeFont(wxNativeFont font)
50 {
51 XFreeFont((Display *)wxGetDisplay(), font);
52 }
53#elif defined(__WXGTK__)
54 #include "gdk/gdk.h"
55
56 static inline wxNativeFont wxLoadFont(const wxString& fontSpec)
57 {
58 return gdk_font_load( wxConvertWX2MB(fontSpec) );
59 }
60
61 static inline void wxFreeFont(wxNativeFont font)
62 {
63 gdk_font_unref(font);
64 }
65#else
66 #error "Unknown GUI toolkit"
67#endif
68
69static bool wxTestFontSpec(const wxString& fontspec);
70
71static wxNativeFont wxLoadQueryFont(int pointSize,
72 int family,
73 int style,
74 int weight,
75 bool underlined,
76 const wxString& facename,
77 const wxString& xregistry,
78 const wxString& xencoding);
79
80// ============================================================================
81// implementation
82// ============================================================================
83
84// ----------------------------------------------------------------------------
85// wxNativeEncodingInfo
86// ----------------------------------------------------------------------------
87
88// convert to/from the string representation: format is
89// registry-encoding[-facename]
90bool wxNativeEncodingInfo::FromString(const wxString& s)
91{
92 wxStringTokenizer tokenizer(s, _T("-"));
93
94 xregistry = tokenizer.GetNextToken();
95 if ( !xregistry )
96 return FALSE;
97
98 xencoding = tokenizer.GetNextToken();
99 if ( !xencoding )
100 return FALSE;
101
102 // ok even if empty
103 facename = tokenizer.GetNextToken();
104
105 return TRUE;
106}
107
108wxString wxNativeEncodingInfo::ToString() const
109{
110 wxString s;
111 s << xregistry << _T('-') << xencoding;
112 if ( !!facename )
113 {
114 s << _T('-') << facename;
115 }
116
117 return s;
118}
119
120// ----------------------------------------------------------------------------
121// common functions
122// ----------------------------------------------------------------------------
123
124bool wxGetNativeFontEncoding(wxFontEncoding encoding,
125 wxNativeEncodingInfo *info)
126{
127 wxCHECK_MSG( info, FALSE, _T("bad pointer in wxGetNativeFontEncoding") );
128
129 if ( encoding == wxFONTENCODING_DEFAULT )
130 {
131 encoding = wxFont::GetDefaultEncoding();
132 }
133
134 switch ( encoding )
135 {
136 case wxFONTENCODING_ISO8859_1:
137 case wxFONTENCODING_ISO8859_2:
138 case wxFONTENCODING_ISO8859_3:
139 case wxFONTENCODING_ISO8859_4:
140 case wxFONTENCODING_ISO8859_5:
141 case wxFONTENCODING_ISO8859_6:
142 case wxFONTENCODING_ISO8859_7:
143 case wxFONTENCODING_ISO8859_8:
144 case wxFONTENCODING_ISO8859_9:
145 case wxFONTENCODING_ISO8859_10:
146 case wxFONTENCODING_ISO8859_11:
147 case wxFONTENCODING_ISO8859_13:
148 case wxFONTENCODING_ISO8859_14:
149 case wxFONTENCODING_ISO8859_15:
150 {
151 int cp = encoding - wxFONTENCODING_ISO8859_1 + 1;
152 info->xregistry = wxT("iso8859");
153 info->xencoding.Printf(wxT("%d"), cp);
154 }
155 break;
156
157 case wxFONTENCODING_KOI8:
158 info->xregistry = wxT("koi8");
159
160 // we don't make distinction between koi8-r and koi8-u (so far)
161 info->xencoding = wxT("*");
162 break;
163
164 case wxFONTENCODING_CP1250:
165 case wxFONTENCODING_CP1251:
166 case wxFONTENCODING_CP1252:
167 case wxFONTENCODING_CP1253:
168 case wxFONTENCODING_CP1254:
169 case wxFONTENCODING_CP1255:
170 case wxFONTENCODING_CP1256:
171 case wxFONTENCODING_CP1257:
172 {
173 int cp = encoding - wxFONTENCODING_CP1250 + 1250;
174 info->xregistry = wxT("microsoft");
175 info->xencoding.Printf(wxT("cp%d"), cp);
176 }
177 break;
178
179 case wxFONTENCODING_SYSTEM:
180 info->xregistry =
181 info->xencoding = wxT('*');
182 break;
183
184 default:
185 // don't know how to translate this encoding into X fontspec
186 return FALSE;
187 }
188
189 return TRUE;
190}
191
192bool wxTestFontEncoding(const wxNativeEncodingInfo& info)
193{
194 wxString fontspec;
195 fontspec.Printf(_T("-*-%s-*-*-*-*-*-*-*-*-*-*-%s-%s"),
196 !info.facename ? _T("*") : info.facename.c_str(),
197 info.xregistry.c_str(),
198 info.xencoding.c_str());
199
200 return wxTestFontSpec(fontspec);
201}
202
203// ----------------------------------------------------------------------------
204// X-specific functions
205// ----------------------------------------------------------------------------
206
207wxNativeFont wxLoadQueryNearestFont(int pointSize,
208 int family,
209 int style,
210 int weight,
211 bool underlined,
212 const wxString &facename,
213 wxFontEncoding encoding)
214{
215 // first determine the encoding - if the font doesn't exist at all in this
216 // encoding, it's useless to do all other approximations (i.e. size,
217 // family &c don't matter much)
218 wxNativeEncodingInfo info;
219 if ( !wxGetNativeFontEncoding(encoding, &info) ||
220 !wxTestFontEncoding(info) )
221 {
222 if ( !wxTheFontMapper->GetAltForEncoding(encoding, &info) )
223 {
224 // unspported encoding - replace it with the default
225 //
226 // NB: we can't just return 0 from here because wxGTK code doesn't
227 // check for it (i.e. it supposes that we'll always succeed),
228 // so it would provoke a crash
229 wxGetNativeFontEncoding(wxFONTENCODING_SYSTEM, &info);
230 }
231 }
232 //else: we have the correct xregistry/xencoding in info structure
233
234 wxNativeFont font = wxLoadQueryFont( pointSize, family, style, weight,
235 underlined, facename,
236 info.xregistry, info.xencoding );
237
238 if ( !font )
239 {
240 // search up and down by stepsize 10
241 int max_size = pointSize + 20 * (1 + (pointSize/180));
242 int min_size = pointSize - 20 * (1 + (pointSize/180));
243
244 int i;
245
246 // Search for smaller size (approx.)
247 for ( i = pointSize - 10; !font && i >= 10 && i >= min_size; i -= 10 )
248 {
249 font = wxLoadQueryFont(i, family, style, weight, underlined,
250 facename, info.xregistry, info.xencoding);
251 }
252
253 // Search for larger size (approx.)
254 for ( i = pointSize + 10; !font && i <= max_size; i += 10 )
255 {
256 font = wxLoadQueryFont(i, family, style, weight, underlined,
257 facename, info.xregistry, info.xencoding);
258 }
259
260 // Try default family
261 if ( !font && family != wxDEFAULT )
262 {
263 font = wxLoadQueryFont(pointSize, wxDEFAULT, style, weight,
264 underlined, facename,
265 info.xregistry, info.xencoding );
266 }
267
268 // Bogus font I
269 if ( !font )
270 {
271 font = wxLoadQueryFont(120, wxDEFAULT, wxNORMAL, wxNORMAL,
272 underlined, facename,
273 info.xregistry, info.xencoding);
274 }
275
276 // Bogus font II
277 if ( !font )
278 {
279 font = wxLoadQueryFont(120, wxDEFAULT, wxNORMAL, wxNORMAL,
280 underlined, wxEmptyString,
281 info.xregistry, info.xencoding);
282 }
283 }
284
285 return font;
286}
287
288// ----------------------------------------------------------------------------
289// private functions
290// ----------------------------------------------------------------------------
291
292// returns TRUE if there are any fonts matching this font spec
293static bool wxTestFontSpec(const wxString& fontspec)
294{
295 wxNativeFont test = wxLoadFont(fontspec);
296 if ( test )
297 {
298 wxFreeFont(test);
299
300 return TRUE;
301 }
302 else
303 {
304 return FALSE;
305 }
306}
307
308static wxNativeFont wxLoadQueryFont(int pointSize,
309 int family,
310 int style,
311 int weight,
312 bool WXUNUSED(underlined),
313 const wxString& facename,
314 const wxString& xregistry,
315 const wxString& xencoding)
316{
317 wxString xfamily;
318 switch (family)
319 {
320 case wxDECORATIVE: xfamily = wxT("lucida"); break;
321 case wxROMAN: xfamily = wxT("times"); break;
322 case wxMODERN: xfamily = wxT("courier"); break;
323 case wxSWISS: xfamily = wxT("helvetica"); break;
324 case wxTELETYPE: xfamily = wxT("lucidatypewriter"); break;
325 case wxSCRIPT: xfamily = wxT("utopia"); break;
326 default: xfamily = wxT("*");
327 }
328
329 wxString fontSpec;
330 if (!facename.IsEmpty())
331 {
332 fontSpec.Printf(wxT("-*-%s-*-*-normal-*-*-*-*-*-*-*-*-*"),
333 facename.c_str());
334
335 if ( wxTestFontSpec(fontSpec) )
336 {
337 xfamily = facename;
338 }
339 //else: no such family, use default one instead
340 }
341
342 wxString xstyle;
343 switch (style)
344 {
345 case wxITALIC: xstyle = wxT("i"); break;
346 case wxSLANT: xstyle = wxT("o"); break;
347 case wxNORMAL: xstyle = wxT("r"); break;
348 default: xstyle = wxT("*"); break;
349 }
350
351 wxString xweight;
352 switch (weight)
353 {
354 case wxBOLD:
355 {
356 fontSpec.Printf(wxT("-*-%s-bold-*-*-*-*-*-*-*-*-*-*-*"),
357 xfamily.c_str());
358 if ( wxTestFontSpec(fontSpec) )
359 {
360 xweight = wxT("bold");
361 break;
362 }
363 fontSpec.Printf(wxT("-*-%s-heavy-*-*-*-*-*-*-*-*-*-*-*"),
364 xfamily.c_str());
365 if ( wxTestFontSpec(fontSpec) )
366 {
367 xweight = wxT("heavy");
368 break;
369 }
370 fontSpec.Printf(wxT("-*-%s-extrabold-*-*-*-*-*-*-*-*-*-*-*"),
371 xfamily.c_str());
372 if ( wxTestFontSpec(fontSpec) )
373 {
374 xweight = wxT("extrabold");
375 break;
376 }
377 fontSpec.Printf(wxT("-*-%s-demibold-*-*-*-*-*-*-*-*-*-*-*"),
378 xfamily.c_str());
379 if ( wxTestFontSpec(fontSpec) )
380 {
381 xweight = wxT("demibold");
382 break;
383 }
384 fontSpec.Printf(wxT("-*-%s-black-*-*-*-*-*-*-*-*-*-*-*"),
385 xfamily.c_str());
386 if ( wxTestFontSpec(fontSpec) )
387 {
388 xweight = wxT("black");
389 break;
390 }
391 fontSpec.Printf(wxT("-*-%s-ultrablack-*-*-*-*-*-*-*-*-*-*-*"),
392 xfamily.c_str());
393 if ( wxTestFontSpec(fontSpec) )
394 {
395 xweight = wxT("ultrablack");
396 break;
397 }
398 }
399 break;
400 case wxLIGHT:
401 {
402 fontSpec.Printf(wxT("-*-%s-light-*-*-*-*-*-*-*-*-*-*-*"),
403 xfamily.c_str());
404 if ( wxTestFontSpec(fontSpec) )
405 {
406 xweight = wxT("light");
407 break;
408 }
409 fontSpec.Printf(wxT("-*-%s-thin-*-*-*-*-*-*-*-*-*-*-*"),
410 xfamily.c_str());
411 if ( wxTestFontSpec(fontSpec) )
412 {
413 xweight = wxT("thin");
414 break;
415 }
416 }
417 break;
418 case wxNORMAL:
419 {
420 fontSpec.Printf(wxT("-*-%s-medium-*-*-*-*-*-*-*-*-*-*-*"),
421 xfamily.c_str());
422 if ( wxTestFontSpec(fontSpec) )
423 {
424 xweight = wxT("medium");
425 break;
426 }
427 fontSpec.Printf(wxT("-*-%s-normal-*-*-*-*-*-*-*-*-*-*-*"),
428 xfamily.c_str());
429 if ( wxTestFontSpec(fontSpec) )
430 {
431 xweight = wxT("normal");
432 break;
433 }
434 fontSpec.Printf(wxT("-*-%s-regular-*-*-*-*-*-*-*-*-*-*-*"),
435 xfamily.c_str());
436 if ( wxTestFontSpec(fontSpec) )
437 {
438 xweight = wxT("regular");
439 break;
440 }
441 xweight = wxT("*");
442 }
443 break;
444 default: xweight = wxT("*"); break;
445 }
446
447 // construct the X font spec from our data
448 fontSpec.Printf(wxT("-*-%s-%s-%s-normal-*-*-%d-*-*-*-*-%s-%s"),
449 xfamily.c_str(), xweight.c_str(), xstyle.c_str(),
450 pointSize, xregistry.c_str(), xencoding.c_str());
451
452 return wxLoadFont(fontSpec);
453}
454