]> git.saurik.com Git - wxWidgets.git/blame - src/unix/fontutil.cpp
checking that a wxWindow is of run-time type wxWindow is hopefully useless
[wxWidgets.git] / src / unix / fontutil.cpp
CommitLineData
7beba2fc 1/////////////////////////////////////////////////////////////////////////////
55034339 2// Name: src/unix/fontutil.cpp
7beba2fc
VZ
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
65571936 9// Licence: wxWindows licence
7beba2fc
VZ
10/////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
7beba2fc
VZ
20// For compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
24 #pragma hdrstop
25#endif
26
d48d1eae
WS
27#include "wx/fontutil.h"
28
7beba2fc 29#ifndef WX_PRECOMP
d48d1eae 30 #include "wx/app.h"
0f6858b6 31 #include "wx/font.h" // wxFont enums
e4ffab29 32 #include "wx/encinfo.h"
32d4c30a 33 #include "wx/hash.h"
de6185e2 34 #include "wx/utils.h" // for wxGetDisplay()
02761f6c 35 #include "wx/module.h"
7beba2fc
VZ
36#endif // PCH
37
db16cab4
RR
38#include "wx/fontmap.h"
39#include "wx/tokenzr.h"
85ab460e 40#include "wx/fontenum.h"
db16cab4 41
2b5f62a0
VZ
42#if wxUSE_PANGO
43
44#include "pango/pango.h"
db16cab4 45
2b5f62a0 46#ifdef __WXGTK20__
29131e8a
VZ
47 #include "wx/gtk/private.h"
48 extern GtkWidget *wxGetRootWindow();
49
50 #define wxPANGO_CONV wxGTK_CONV_SYS
2b5f62a0 51#else
29131e8a
VZ
52 #include "wx/x11/private.h"
53 #include "wx/gtk/private/string.h"
54
55 #define wxPANGO_CONV(s) (wxConvUTF8.cWX2MB((s)))
2b5f62a0 56#endif
db16cab4
RR
57
58// ----------------------------------------------------------------------------
59// wxNativeFontInfo
60// ----------------------------------------------------------------------------
61
62void wxNativeFontInfo::Init()
63{
64 description = NULL;
65}
66
23afe648
VZ
67void
68wxNativeFontInfo::Init(const wxNativeFontInfo& info)
fdf7514a
VS
69{
70 if (info.description)
71 description = pango_font_description_copy(info.description);
72 else
82680055 73 description = NULL;
fdf7514a
VS
74}
75
82680055 76void wxNativeFontInfo::Free()
fdf7514a
VS
77{
78 if (description)
79 pango_font_description_free(description);
80}
81
db16cab4
RR
82int wxNativeFontInfo::GetPointSize() const
83{
84 return pango_font_description_get_size( description ) / PANGO_SCALE;
85}
86
87wxFontStyle wxNativeFontInfo::GetStyle() const
88{
89 wxFontStyle m_style = wxFONTSTYLE_NORMAL;
90
91 switch (pango_font_description_get_style( description ))
92 {
93 case PANGO_STYLE_NORMAL:
94 m_style = wxFONTSTYLE_NORMAL;
95 break;
96 case PANGO_STYLE_ITALIC:
97 m_style = wxFONTSTYLE_ITALIC;
98 break;
99 case PANGO_STYLE_OBLIQUE:
100 m_style = wxFONTSTYLE_SLANT;
101 break;
102 }
2b5f62a0 103
db16cab4
RR
104 return m_style;
105}
106
107wxFontWeight wxNativeFontInfo::GetWeight() const
108{
0f6858b6
RR
109#if 0
110 // We seem to currently initialize only by string.
111 // In that case PANGO_FONT_MASK_WEIGHT is always set.
112 if (!(pango_font_description_get_set_fields(description) & PANGO_FONT_MASK_WEIGHT))
113 return wxFONTWEIGHT_NORMAL;
114#endif
db16cab4 115
0f6858b6
RR
116 PangoWeight pango_weight = pango_font_description_get_weight( description );
117
118 // Until the API can be changed the following ranges of weight values are used:
119 // wxFONTWEIGHT_LIGHT: 100 .. 349 - range of 250
120 // wxFONTWEIGHT_NORMAL: 350 .. 599 - range of 250
121 // wxFONTWEIGHT_BOLD: 600 .. 900 - range of 301 (600 is "semibold" already)
122
123 if (pango_weight >= 600)
124 return wxFONTWEIGHT_BOLD;
125
126 if (pango_weight < 350)
127 return wxFONTWEIGHT_LIGHT;
2b5f62a0 128
0f6858b6 129 return wxFONTWEIGHT_NORMAL;
db16cab4
RR
130}
131
132bool wxNativeFontInfo::GetUnderlined() const
133{
55034339 134 return false;
db16cab4
RR
135}
136
137wxString wxNativeFontInfo::GetFaceName() const
138{
139 wxString tmp = wxGTK_CONV_BACK( pango_font_description_get_family( description ) );
2b5f62a0 140
db16cab4
RR
141 return tmp;
142}
143
144wxFontFamily wxNativeFontInfo::GetFamily() const
145{
b67d14be 146 wxFontFamily ret = wxFONTFAMILY_DEFAULT;
34a35823
MW
147 // note: not passing -1 as the 2nd parameter to g_ascii_strdown to work
148 // around a bug in the 64-bit glib shipped with solaris 10, -1 causes it
149 // to try to allocate 2^32 bytes.
150 const char *family_name = pango_font_description_get_family( description );
23f4f495
VZ
151 if ( !family_name )
152 return ret;
153
8361f92b
VZ
154 wxGtkString family_text(g_ascii_strdown(family_name, strlen(family_name)));
155
b67d14be
MR
156 // Check for some common fonts, to salvage what we can from the current win32 centric wxFont API:
157 if (strncmp( family_text, "monospace", 9 ) == 0)
158 ret = wxFONTFAMILY_TELETYPE; // begins with "Monospace"
159 else if (strncmp( family_text, "courier", 7 ) == 0)
160 ret = wxFONTFAMILY_TELETYPE; // begins with "Courier"
c42f011e 161#if defined(__WXGTK24__) || defined(HAVE_PANGO_FONT_FAMILY_IS_MONOSPACE)
b67d14be 162 else
c42f011e
MR
163#ifdef __WXGTK24__
164 if (!gtk_check_version(2,4,0))
165#endif
b67d14be
MR
166 {
167 PangoFontFamily **families;
b20cb045 168 PangoFontFamily *family = NULL;
b67d14be
MR
169 int n_families;
170 pango_context_list_families(
38d446db 171#ifdef __WXGTK20__
b67d14be 172 gtk_widget_get_pango_context( wxGetRootWindow() ),
38d446db 173#else
b67d14be 174 wxTheApp->GetPangoContext(),
38d446db 175#endif
b67d14be 176 &families, &n_families);
38d446db 177
b67d14be 178 for (int i = 0;i < n_families;++i)
38d446db 179 {
b67d14be
MR
180 if (g_ascii_strcasecmp(pango_font_family_get_name( families[i] ), pango_font_description_get_family( description )) == 0 )
181 {
182 family = families[i];
183 break;
184 }
38d446db 185 }
38d446db 186
b67d14be 187 g_free(families);
38d446db 188
3c542a4d
MR
189 // Some gtk+ systems might query for a non-existing font from wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)
190 // on initialization, don't assert until wxSystemSettings::GetFont is checked for this - MR
191 // wxASSERT_MSG( family, wxT("wxNativeFontInfo::GetFamily() - No appropriate PangoFontFamily found for ::description") );
38d446db 192
b67d14be
MR
193 //BCI: Cache the wxFontFamily inside the class. Validate cache with
194 //BCI: g_ascii_strcasecmp(pango_font_description_get_family(description), pango_font_family_get_name(family)) == 0
38d446db 195
b20cb045 196 if (family != NULL && pango_font_family_is_monospace( family ))
b67d14be
MR
197 ret = wxFONTFAMILY_TELETYPE; // is deemed a monospace font by pango
198 }
c42f011e 199#endif // gtk24 || HAVE_PANGO_FONT_FAMILY_IS_MONOSPACE
38d446db 200
b67d14be
MR
201 if (ret == wxFONTFAMILY_DEFAULT)
202 {
203 if (strstr( family_text, "sans" ) != NULL) // checked before serif, so that "* Sans Serif" fonts are detected correctly
204 ret = wxFONTFAMILY_SWISS; // contains "Sans"
205 else if (strstr( family_text, "serif" ) != NULL)
206 ret = wxFONTFAMILY_ROMAN; // contains "Serif"
207 else if (strncmp( family_text, "times", 5 ) == 0)
208 ret = wxFONTFAMILY_ROMAN; // begins with "Times"
209 else if (strncmp( family_text, "old", 3 ) == 0)
210 ret = wxFONTFAMILY_DECORATIVE; // Begins with "Old" - "Old English", "Old Town"
211 }
212
b67d14be 213 return ret;
db16cab4
RR
214}
215
216wxFontEncoding wxNativeFontInfo::GetEncoding() const
217{
218 return wxFONTENCODING_SYSTEM;
219}
220
3398cf2c 221
8a15e8ba 222void wxNativeFontInfo::SetPointSize(int pointsize)
3398cf2c 223{
8a15e8ba 224 pango_font_description_set_size( description, pointsize * PANGO_SCALE );
3398cf2c
VZ
225}
226
7533ba25 227void wxNativeFontInfo::SetStyle(wxFontStyle style)
3398cf2c 228{
7533ba25
MR
229 switch (style)
230 {
231 case wxFONTSTYLE_ITALIC:
232 pango_font_description_set_style( description, PANGO_STYLE_ITALIC );
233 break;
234 case wxFONTSTYLE_SLANT:
235 pango_font_description_set_style( description, PANGO_STYLE_OBLIQUE );
236 break;
237 default:
238 wxFAIL_MSG( _T("unknown font style") );
239 // fall through
240 case wxFONTSTYLE_NORMAL:
241 pango_font_description_set_style( description, PANGO_STYLE_NORMAL );
242 break;
243 }
3398cf2c
VZ
244}
245
7533ba25 246void wxNativeFontInfo::SetWeight(wxFontWeight weight)
3398cf2c 247{
7533ba25
MR
248 switch (weight)
249 {
250 case wxFONTWEIGHT_BOLD:
251 pango_font_description_set_weight(description, PANGO_WEIGHT_BOLD);
252 break;
253 case wxFONTWEIGHT_LIGHT:
254 pango_font_description_set_weight(description, PANGO_WEIGHT_LIGHT);
255 break;
256 default:
257 wxFAIL_MSG( _T("unknown font weight") );
258 // fall through
259 case wxFONTWEIGHT_NORMAL:
260 pango_font_description_set_weight(description, PANGO_WEIGHT_NORMAL);
261 }
3398cf2c
VZ
262}
263
264void wxNativeFontInfo::SetUnderlined(bool WXUNUSED(underlined))
265{
266 wxFAIL_MSG( _T("not implemented") );
267}
268
85ab460e 269bool wxNativeFontInfo::SetFaceName(const wxString& facename)
3398cf2c 270{
29131e8a 271 pango_font_description_set_family(description, wxPANGO_CONV(facename));
85ab460e 272 return true;
3398cf2c
VZ
273}
274
275void wxNativeFontInfo::SetFamily(wxFontFamily WXUNUSED(family))
276{
277 wxFAIL_MSG( _T("not implemented") );
278}
279
280void wxNativeFontInfo::SetEncoding(wxFontEncoding WXUNUSED(encoding))
281{
282 wxFAIL_MSG( _T("not implemented") );
283}
284
285
286
db16cab4
RR
287bool wxNativeFontInfo::FromString(const wxString& s)
288{
289 if (description)
290 pango_font_description_free( description );
291
7c55c50e
VZ
292 // there is a bug in at least pango <= 1.13 which makes it (or its backends)
293 // segfault for very big point sizes and for negative point sizes.
294 // To workaround that bug for pango <= 1.13
295 // (see http://bugzilla.gnome.org/show_bug.cgi?id=340229)
296 // we do the check on the size here using same (arbitrary) limits used by
297 // pango > 1.13. Note that the segfault could happen also for pointsize
298 // smaller than this limit !!
299 wxString str(s);
300 const size_t pos = str.find_last_of(_T(" "));
301 double size;
302 if ( pos != wxString::npos && wxString(str, pos + 1).ToDouble(&size) )
303 {
304 wxString sizeStr;
305 if ( size < 1 )
306 sizeStr = _T("1");
c23d4004 307 else if ( size >= 1E6 )
7c55c50e
VZ
308 sizeStr = _T("1E6");
309
310 if ( !sizeStr.empty() )
311 {
312 // replace the old size with the adjusted one
313 str = wxString(s, 0, pos) + sizeStr;
314 }
315 }
316
29131e8a 317 description = pango_font_description_from_string(wxPANGO_CONV(str));
db16cab4 318
85ab460e
VZ
319 // ensure a valid facename is selected
320 if (!wxFontEnumerator::IsValidFacename(GetFaceName()))
321 SetFaceName(wxNORMAL_FONT->GetFaceName());
322
55034339 323 return true;
db16cab4
RR
324}
325
326wxString wxNativeFontInfo::ToString() const
327{
8361f92b 328 wxGtkString str(pango_font_description_to_string( description ));
db16cab4 329
8361f92b 330 return wxGTK_CONV_BACK(str);
db16cab4
RR
331}
332
333bool wxNativeFontInfo::FromUserString(const wxString& s)
334{
335 return FromString( s );
336}
337
338wxString wxNativeFontInfo::ToUserString() const
339{
340 return ToString();
341}
342
343// ----------------------------------------------------------------------------
344// wxNativeEncodingInfo
345// ----------------------------------------------------------------------------
346
82359764 347bool wxNativeEncodingInfo::FromString(const wxString& WXUNUSED(s))
db16cab4 348{
55034339 349 return false;
db16cab4
RR
350}
351
352wxString wxNativeEncodingInfo::ToString() const
353{
354 return wxEmptyString;
355}
356
82359764 357bool wxTestFontEncoding(const wxNativeEncodingInfo& WXUNUSED(info))
db16cab4 358{
55034339 359 return true;
db16cab4
RR
360}
361
362bool wxGetNativeFontEncoding(wxFontEncoding encoding,
363 wxNativeEncodingInfo *info)
364{
d0311dd3
VZ
365 // all encodings are available in GTK+ 2 because we translate text in any
366 // encoding to UTF-8 internally anyhow
82359764 367 info->facename.clear();
d0311dd3 368 info->encoding = encoding;
82359764 369
d0311dd3 370 return true;
db16cab4
RR
371}
372
2b5f62a0 373#else // GTK+ 1.x
db16cab4 374
79e4b627 375#ifdef __X__
4ea45e6b
VZ
376 #ifdef __VMS__
377 #pragma message disable nosimpint
378 #endif
379
380 #include <X11/Xlib.h>
381
382 #ifdef __VMS__
383 #pragma message enable nosimpint
384 #endif
79e4b627 385
79e4b627 386#elif defined(__WXGTK__)
4ea45e6b
VZ
387 // we have to declare struct tm to avoid problems with first forward
388 // declaring it in C code (glib.h included from gdk.h does it) and then
389 // defining it when time.h is included from the headers below - this is
390 // known not to work at least with Sun CC 6.01
391 #include <time.h>
392
393 #include <gdk/gdk.h>
79e4b627
VZ
394#endif
395
2e0e025e
RR
396
397// ----------------------------------------------------------------------------
398// private data
399// ----------------------------------------------------------------------------
400
401static wxHashTable *g_fontHash = (wxHashTable*) NULL;
7beba2fc
VZ
402
403// ----------------------------------------------------------------------------
404// private functions
405// ----------------------------------------------------------------------------
406
407// define the functions to create and destroy native fonts for this toolkit
408#ifdef __X__
3fe34ed0 409 wxNativeFont wxLoadFont(const wxString& fontSpec)
7beba2fc
VZ
410 {
411 return XLoadQueryFont((Display *)wxGetDisplay(), fontSpec);
412 }
413
409d5a58 414 inline void wxFreeFont(wxNativeFont font)
7beba2fc 415 {
a5fc62a1 416 XFreeFont((Display *)wxGetDisplay(), (XFontStruct *)font);
7beba2fc
VZ
417 }
418#elif defined(__WXGTK__)
3fe34ed0 419 wxNativeFont wxLoadFont(const wxString& fontSpec)
7beba2fc 420 {
8fa3a431
VZ
421 // VZ: we should use gdk_fontset_load() instead of gdk_font_load()
422 // here to be able to display Japanese fonts correctly (at least
423 // this is what people report) but unfortunately doing it results
424 // in tons of warnings when using GTK with "normal" European
425 // languages and so we can't always do it and I don't know enough
426 // to determine when should this be done... (FIXME)
427 return gdk_font_load( wxConvertWX2MB(fontSpec) );
7beba2fc
VZ
428 }
429
409d5a58 430 inline void wxFreeFont(wxNativeFont font)
7beba2fc
VZ
431 {
432 gdk_font_unref(font);
433 }
434#else
435 #error "Unknown GUI toolkit"
436#endif
437
438static bool wxTestFontSpec(const wxString& fontspec);
439
440static wxNativeFont wxLoadQueryFont(int pointSize,
441 int family,
442 int style,
443 int weight,
444 bool underlined,
445 const wxString& facename,
446 const wxString& xregistry,
30764ab5
VZ
447 const wxString& xencoding,
448 wxString* xFontName);
7beba2fc
VZ
449
450// ============================================================================
451// implementation
452// ============================================================================
453
454// ----------------------------------------------------------------------------
455// wxNativeEncodingInfo
456// ----------------------------------------------------------------------------
457
458// convert to/from the string representation: format is
1e1d0be1 459// encodingid;registry;encoding[;facename]
7beba2fc
VZ
460bool wxNativeEncodingInfo::FromString(const wxString& s)
461{
6c49baf2 462 // use ";", not "-" because it may be part of encoding name
1e1d0be1 463 wxStringTokenizer tokenizer(s, _T(";"));
1e1d0be1
VS
464
465 wxString encid = tokenizer.GetNextToken();
466 long enc;
467 if ( !encid.ToLong(&enc) )
55034339 468 return false;
1e1d0be1 469 encoding = (wxFontEncoding)enc;
7beba2fc
VZ
470
471 xregistry = tokenizer.GetNextToken();
472 if ( !xregistry )
55034339 473 return false;
7beba2fc
VZ
474
475 xencoding = tokenizer.GetNextToken();
476 if ( !xencoding )
55034339 477 return false;
7beba2fc
VZ
478
479 // ok even if empty
480 facename = tokenizer.GetNextToken();
481
55034339 482 return true;
7beba2fc
VZ
483}
484
485wxString wxNativeEncodingInfo::ToString() const
486{
487 wxString s;
1e1d0be1 488 s << (long)encoding << _T(';') << xregistry << _T(';') << xencoding;
55034339 489 if ( !facename.empty() )
7beba2fc 490 {
1e1d0be1 491 s << _T(';') << facename;
7beba2fc
VZ
492 }
493
494 return s;
495}
496
ab5fe833
VZ
497// ----------------------------------------------------------------------------
498// wxNativeFontInfo
499// ----------------------------------------------------------------------------
500
501void wxNativeFontInfo::Init()
502{
55034339 503 m_isDefault = true;
ab5fe833
VZ
504}
505
506bool wxNativeFontInfo::FromString(const wxString& s)
507{
508 wxStringTokenizer tokenizer(s, _T(";"));
509
510 // check the version
511 wxString token = tokenizer.GetNextToken();
512 if ( token != _T('0') )
55034339 513 return false;
ab5fe833
VZ
514
515 xFontName = tokenizer.GetNextToken();
516
517 // this should be the end
518 if ( tokenizer.HasMoreTokens() )
55034339 519 return false;
ab5fe833
VZ
520
521 return FromXFontName(xFontName);
522}
523
524wxString wxNativeFontInfo::ToString() const
525{
526 // 0 is the version
527 return wxString::Format(_T("%d;%s"), 0, GetXFontName().c_str());
528}
529
530bool wxNativeFontInfo::FromUserString(const wxString& s)
531{
532 return FromXFontName(s);
533}
534
535wxString wxNativeFontInfo::ToUserString() const
536{
537 return GetXFontName();
538}
539
409d5a58
VZ
540bool wxNativeFontInfo::HasElements() const
541{
542 // we suppose that the foundry is never empty, so if it is it means that we
543 // had never parsed the XLFD
544 return !fontElements[0].empty();
545}
546
53f6aab7
VZ
547wxString wxNativeFontInfo::GetXFontComponent(wxXLFDField field) const
548{
55034339 549 wxCHECK_MSG( field < wxXLFD_MAX, wxEmptyString, _T("invalid XLFD field") );
53f6aab7 550
409d5a58 551 if ( !HasElements() )
53f6aab7
VZ
552 {
553 // const_cast
554 if ( !((wxNativeFontInfo *)this)->FromXFontName(xFontName) )
55034339 555 return wxEmptyString;
53f6aab7
VZ
556 }
557
558 return fontElements[field];
559}
560
295272bd 561bool wxNativeFontInfo::FromXFontName(const wxString& fontname)
ab5fe833
VZ
562{
563 // TODO: we should be able to handle the font aliases here, but how?
409d5a58
VZ
564 wxStringTokenizer tokenizer(fontname, _T("-"));
565
566 // skip the leading, usually empty field (font name registry)
567 if ( !tokenizer.HasMoreTokens() )
55034339 568 return false;
409d5a58
VZ
569
570 (void)tokenizer.GetNextToken();
ab5fe833
VZ
571
572 for ( size_t n = 0; n < WXSIZEOF(fontElements); n++ )
573 {
574 if ( !tokenizer.HasMoreTokens() )
575 {
576 // not enough elements in the XLFD - or maybe an alias
55034339 577 return false;
ab5fe833
VZ
578 }
579
b4e4abb5
VZ
580 wxString field = tokenizer.GetNextToken();
581 if ( !field.empty() && field != _T('*') )
582 {
583 // we're really initialized now
55034339 584 m_isDefault = false;
b4e4abb5
VZ
585 }
586
587 fontElements[n] = field;
ab5fe833
VZ
588 }
589
590 // this should be all
011ba5ed 591 if ( tokenizer.HasMoreTokens() )
55034339 592 return false;
011ba5ed 593
55034339 594 return true;
ab5fe833
VZ
595}
596
597wxString wxNativeFontInfo::GetXFontName() const
598{
599 if ( xFontName.empty() )
600 {
601 for ( size_t n = 0; n < WXSIZEOF(fontElements); n++ )
602 {
603 // replace the non specified elements with '*' except for the
604 // additional style which is usually just omitted
605 wxString elt = fontElements[n];
409d5a58 606 if ( elt.empty() && n != wxXLFD_ADDSTYLE )
ab5fe833
VZ
607 {
608 elt = _T('*');
609 }
610
611 // const_cast
612 ((wxNativeFontInfo *)this)->xFontName << _T('-') << elt;
613 }
614 }
615
616 return xFontName;
617}
618
409d5a58
VZ
619void
620wxNativeFontInfo::SetXFontComponent(wxXLFDField field, const wxString& value)
621{
622 wxCHECK_RET( field < wxXLFD_MAX, _T("invalid XLFD field") );
623
624 // this class should be initialized with a valid font spec first and only
625 // then the fields may be modified!
626 wxASSERT_MSG( !IsDefault(), _T("can't modify an uninitialized XLFD") );
627
628 if ( !HasElements() )
629 {
630 // const_cast
631 if ( !((wxNativeFontInfo *)this)->FromXFontName(xFontName) )
632 {
633 wxFAIL_MSG( _T("can't set font element for invalid XLFD") );
634
635 return;
636 }
637 }
638
639 fontElements[field] = value;
640
641 // invalidate the XFLD, it doesn't correspond to the font elements any more
642 xFontName.clear();
643}
644
645void wxNativeFontInfo::SetXFontName(const wxString& xFontName_)
646{
647 // invalidate the font elements, GetXFontComponent() will reparse the XLFD
648 fontElements[0].clear();
649
650 xFontName = xFontName_;
651
55034339 652 m_isDefault = false;
409d5a58
VZ
653}
654
2b5f62a0
VZ
655int wxNativeFontInfo::GetPointSize() const
656{
657 const wxString s = GetXFontComponent(wxXLFD_POINTSIZE);
658
659 // return -1 to indicate that the size is unknown
660 long l;
661 return s.ToLong(&l) ? l : -1;
662}
663
664wxFontStyle wxNativeFontInfo::GetStyle() const
665{
666 const wxString s = GetXFontComponent(wxXLFD_SLANT);
667
668 if ( s.length() != 1 )
669 {
670 // it is really unknown but we don't have any way to return it from
671 // here
672 return wxFONTSTYLE_NORMAL;
673 }
674
675 switch ( s[0] )
676 {
677 default:
678 // again, unknown but consider normal by default
679
680 case _T('r'):
681 return wxFONTSTYLE_NORMAL;
682
683 case _T('i'):
684 return wxFONTSTYLE_ITALIC;
685
686 case _T('o'):
687 return wxFONTSTYLE_SLANT;
688 }
689}
690
691wxFontWeight wxNativeFontInfo::GetWeight() const
692{
693 const wxString s = GetXFontComponent(wxXLFD_WEIGHT).MakeLower();
694 if ( s.find(_T("bold")) != wxString::npos || s == _T("black") )
695 return wxFONTWEIGHT_BOLD;
696 else if ( s == _T("light") )
697 return wxFONTWEIGHT_LIGHT;
698
699 return wxFONTWEIGHT_NORMAL;
700}
701
702bool wxNativeFontInfo::GetUnderlined() const
703{
704 // X fonts are never underlined
55034339 705 return false;
2b5f62a0
VZ
706}
707
708wxString wxNativeFontInfo::GetFaceName() const
709{
77ffb593 710 // wxWidgets facename probably more accurately corresponds to X family
2b5f62a0
VZ
711 return GetXFontComponent(wxXLFD_FAMILY);
712}
713
714wxFontFamily wxNativeFontInfo::GetFamily() const
715{
77ffb593 716 // and wxWidgets family -- to X foundry, but we have to translate it to
2b5f62a0
VZ
717 // wxFontFamily somehow...
718 wxFAIL_MSG(_T("not implemented")); // GetXFontComponent(wxXLFD_FOUNDRY);
719
720 return wxFONTFAMILY_DEFAULT;
721}
722
723wxFontEncoding wxNativeFontInfo::GetEncoding() const
724{
725 // we already have the code for this but need to refactor it first
726 wxFAIL_MSG( _T("not implemented") );
727
728 return wxFONTENCODING_MAX;
729}
730
731void wxNativeFontInfo::SetPointSize(int pointsize)
732{
733 SetXFontComponent(wxXLFD_POINTSIZE, wxString::Format(_T("%d"), pointsize));
734}
735
736void wxNativeFontInfo::SetStyle(wxFontStyle style)
737{
738 wxString s;
739 switch ( style )
740 {
741 case wxFONTSTYLE_ITALIC:
742 s = _T('i');
743 break;
744
745 case wxFONTSTYLE_SLANT:
746 s = _T('o');
747 break;
748
749 case wxFONTSTYLE_NORMAL:
750 s = _T('r');
751
752 default:
753 wxFAIL_MSG( _T("unknown wxFontStyle in wxNativeFontInfo::SetStyle") );
754 return;
755 }
756
757 SetXFontComponent(wxXLFD_SLANT, s);
758}
759
760void wxNativeFontInfo::SetWeight(wxFontWeight weight)
761{
762 wxString s;
763 switch ( weight )
764 {
765 case wxFONTWEIGHT_BOLD:
766 s = _T("bold");
767 break;
768
769 case wxFONTWEIGHT_LIGHT:
770 s = _T("light");
771 break;
772
773 case wxFONTWEIGHT_NORMAL:
774 s = _T("medium");
775 break;
776
777 default:
778 wxFAIL_MSG( _T("unknown wxFontWeight in wxNativeFontInfo::SetWeight") );
779 return;
780 }
781
782 SetXFontComponent(wxXLFD_WEIGHT, s);
783}
784
785void wxNativeFontInfo::SetUnderlined(bool WXUNUSED(underlined))
786{
787 // can't do this under X
788}
789
85ab460e 790bool wxNativeFontInfo::SetFaceName(const wxString& facename)
2b5f62a0
VZ
791{
792 SetXFontComponent(wxXLFD_FAMILY, facename);
85ab460e 793 return true;
2b5f62a0
VZ
794}
795
55034339 796void wxNativeFontInfo::SetFamily(wxFontFamily WXUNUSED(family))
2b5f62a0
VZ
797{
798 // wxFontFamily -> X foundry, anyone?
799 wxFAIL_MSG( _T("not implemented") );
800
801 // SetXFontComponent(wxXLFD_FOUNDRY, ...);
802}
803
804void wxNativeFontInfo::SetEncoding(wxFontEncoding encoding)
805{
806 wxNativeEncodingInfo info;
807 if ( wxGetNativeFontEncoding(encoding, &info) )
808 {
809 SetXFontComponent(wxXLFD_ENCODING, info.xencoding);
810 SetXFontComponent(wxXLFD_REGISTRY, info.xregistry);
811 }
812}
813
7beba2fc
VZ
814// ----------------------------------------------------------------------------
815// common functions
816// ----------------------------------------------------------------------------
817
818bool wxGetNativeFontEncoding(wxFontEncoding encoding,
819 wxNativeEncodingInfo *info)
820{
55034339 821 wxCHECK_MSG( info, false, _T("bad pointer in wxGetNativeFontEncoding") );
7beba2fc
VZ
822
823 if ( encoding == wxFONTENCODING_DEFAULT )
824 {
825 encoding = wxFont::GetDefaultEncoding();
826 }
827
828 switch ( encoding )
829 {
830 case wxFONTENCODING_ISO8859_1:
831 case wxFONTENCODING_ISO8859_2:
832 case wxFONTENCODING_ISO8859_3:
833 case wxFONTENCODING_ISO8859_4:
834 case wxFONTENCODING_ISO8859_5:
835 case wxFONTENCODING_ISO8859_6:
836 case wxFONTENCODING_ISO8859_7:
837 case wxFONTENCODING_ISO8859_8:
838 case wxFONTENCODING_ISO8859_9:
839 case wxFONTENCODING_ISO8859_10:
840 case wxFONTENCODING_ISO8859_11:
80a24267 841 case wxFONTENCODING_ISO8859_12:
7beba2fc
VZ
842 case wxFONTENCODING_ISO8859_13:
843 case wxFONTENCODING_ISO8859_14:
844 case wxFONTENCODING_ISO8859_15:
845 {
846 int cp = encoding - wxFONTENCODING_ISO8859_1 + 1;
847 info->xregistry = wxT("iso8859");
848 info->xencoding.Printf(wxT("%d"), cp);
849 }
850 break;
851
bb84929e 852 case wxFONTENCODING_UTF8:
5707316c 853 info->xregistry = wxT("iso10646");
bb84929e
VZ
854 info->xencoding = wxT("*");
855 break;
856
2b5f62a0 857 case wxFONTENCODING_GB2312:
82680055 858 info->xregistry = wxT("GB2312"); // or the otherway round?
2b5f62a0
VZ
859 info->xencoding = wxT("*");
860 break;
861
7beba2fc 862 case wxFONTENCODING_KOI8:
15ad38c3 863 case wxFONTENCODING_KOI8_U:
7beba2fc
VZ
864 info->xregistry = wxT("koi8");
865
5707316c 866 // we don't make distinction between koi8-r, koi8-u and koi8-ru (so far)
7beba2fc
VZ
867 info->xencoding = wxT("*");
868 break;
869
870 case wxFONTENCODING_CP1250:
871 case wxFONTENCODING_CP1251:
872 case wxFONTENCODING_CP1252:
873 case wxFONTENCODING_CP1253:
874 case wxFONTENCODING_CP1254:
875 case wxFONTENCODING_CP1255:
876 case wxFONTENCODING_CP1256:
877 case wxFONTENCODING_CP1257:
878 {
879 int cp = encoding - wxFONTENCODING_CP1250 + 1250;
880 info->xregistry = wxT("microsoft");
881 info->xencoding.Printf(wxT("cp%d"), cp);
882 }
883 break;
884
d946915c
MB
885 case wxFONTENCODING_EUC_JP:
886 case wxFONTENCODING_SHIFT_JIS:
887 info->xregistry = "jis*";
888 info->xencoding = "*";
889 break;
890
7beba2fc
VZ
891 case wxFONTENCODING_SYSTEM:
892 info->xregistry =
81c67e27 893 info->xencoding = wxT("*");
7beba2fc
VZ
894 break;
895
896 default:
897 // don't know how to translate this encoding into X fontspec
55034339 898 return false;
7beba2fc
VZ
899 }
900
ab5fe833 901 info->encoding = encoding;
6b0eebc5 902
55034339 903 return true;
7beba2fc
VZ
904}
905
906bool wxTestFontEncoding(const wxNativeEncodingInfo& info)
907{
908 wxString fontspec;
909 fontspec.Printf(_T("-*-%s-*-*-*-*-*-*-*-*-*-*-%s-%s"),
910 !info.facename ? _T("*") : info.facename.c_str(),
911 info.xregistry.c_str(),
912 info.xencoding.c_str());
913
914 return wxTestFontSpec(fontspec);
915}
916
917// ----------------------------------------------------------------------------
918// X-specific functions
919// ----------------------------------------------------------------------------
920
921wxNativeFont wxLoadQueryNearestFont(int pointSize,
922 int family,
923 int style,
924 int weight,
925 bool underlined,
926 const wxString &facename,
30764ab5
VZ
927 wxFontEncoding encoding,
928 wxString* xFontName)
7beba2fc 929{
97d3f0ee
VZ
930 if ( encoding == wxFONTENCODING_DEFAULT )
931 {
932 encoding = wxFont::GetDefaultEncoding();
933 }
934
7beba2fc
VZ
935 // first determine the encoding - if the font doesn't exist at all in this
936 // encoding, it's useless to do all other approximations (i.e. size,
937 // family &c don't matter much)
938 wxNativeEncodingInfo info;
97d3f0ee 939 if ( encoding == wxFONTENCODING_SYSTEM )
81c67e27
RR
940 {
941 // This will always work so we don't test to save time
942 wxGetNativeFontEncoding(wxFONTENCODING_SYSTEM, &info);
943 }
944 else
7beba2fc 945 {
81c67e27
RR
946 if ( !wxGetNativeFontEncoding(encoding, &info) ||
947 !wxTestFontEncoding(info) )
7beba2fc 948 {
1e6feb95 949#if wxUSE_FONTMAP
142b3bc2 950 if ( !wxFontMapper::Get()->GetAltForEncoding(encoding, &info) )
1e6feb95 951#endif // wxUSE_FONTMAP
81c67e27
RR
952 {
953 // unspported encoding - replace it with the default
954 //
955 // NB: we can't just return 0 from here because wxGTK code doesn't
956 // check for it (i.e. it supposes that we'll always succeed),
957 // so it would provoke a crash
958 wxGetNativeFontEncoding(wxFONTENCODING_SYSTEM, &info);
959 }
97d3f0ee 960 }
7beba2fc 961 }
6c49baf2 962
81c67e27 963 // OK, we have the correct xregistry/xencoding in info structure
30764ab5
VZ
964 wxNativeFont font = 0;
965
966 // if we already have the X font name, try to use it
55034339 967 if( xFontName && !xFontName->empty() )
6c49baf2
VZ
968 {
969 //
970 // Make sure point size is correct for scale factor.
971 //
972 wxStringTokenizer tokenizer(*xFontName, _T("-"), wxTOKEN_RET_DELIMS);
973 wxString newFontName;
974
975 for(int i = 0; i < 8; i++)
976 newFontName += tokenizer.NextToken();
977
978 (void) tokenizer.NextToken();
979
401eb3de 980 newFontName += wxString::Format(wxT("%d-"), pointSize);
6c49baf2
VZ
981
982 while(tokenizer.HasMoreTokens())
983 newFontName += tokenizer.GetNextToken();
984
985 font = wxLoadFont(newFontName);
986
987 if(font)
988 *xFontName = newFontName;
989 }
30764ab5 990
7beba2fc
VZ
991 if ( !font )
992 {
993 // search up and down by stepsize 10
994 int max_size = pointSize + 20 * (1 + (pointSize/180));
995 int min_size = pointSize - 20 * (1 + (pointSize/180));
996
34791896 997 int i, round; // counters
7beba2fc 998
34791896
RR
999 // first round: search for equal, then for smaller and for larger size with the given weight and style
1000 int testweight = weight;
1001 int teststyle = style;
1002
1003 for ( round = 0; round < 3; round++ )
1004 {
1005 // second round: use normal weight
1006 if ( round == 1 )
b12401e0 1007 {
34791896
RR
1008 if ( testweight != wxNORMAL )
1009 {
1010 testweight = wxNORMAL;
1011 }
1012 else
1013 {
1014 ++round; // fall through to third round
1015 }
1016 }
1017
1018 // third round: ... and use normal style
1019 if ( round == 2 )
1020 {
1021 if ( teststyle != wxNORMAL )
1022 {
1023 teststyle = wxNORMAL;
1024 }
1025 else
1026 {
1027 break;
1028 }
1029 }
1030 // Search for equal or smaller size (approx.)
1031 for ( i = pointSize; !font && i >= 10 && i >= min_size; i -= 10 )
1032 {
1033 font = wxLoadQueryFont(i, family, teststyle, testweight, underlined,
30764ab5
VZ
1034 facename, info.xregistry, info.xencoding,
1035 xFontName);
b12401e0 1036 }
7beba2fc 1037
b12401e0
MB
1038 // Search for larger size (approx.)
1039 for ( i = pointSize + 10; !font && i <= max_size; i += 10 )
1040 {
34791896 1041 font = wxLoadQueryFont(i, family, teststyle, testweight, underlined,
30764ab5
VZ
1042 facename, info.xregistry, info.xencoding,
1043 xFontName);
34791896 1044 }
7beba2fc
VZ
1045 }
1046
1047 // Try default family
1048 if ( !font && family != wxDEFAULT )
1049 {
1050 font = wxLoadQueryFont(pointSize, wxDEFAULT, style, weight,
1051 underlined, facename,
30764ab5
VZ
1052 info.xregistry, info.xencoding,
1053 xFontName );
7beba2fc
VZ
1054 }
1055
f139dfe8
VZ
1056 // ignore size, family, style and weight but try to find font with the
1057 // given facename and encoding
7beba2fc
VZ
1058 if ( !font )
1059 {
1060 font = wxLoadQueryFont(120, wxDEFAULT, wxNORMAL, wxNORMAL,
1061 underlined, facename,
30764ab5
VZ
1062 info.xregistry, info.xencoding,
1063 xFontName);
7beba2fc 1064
f139dfe8
VZ
1065 // ignore family as well
1066 if ( !font )
1067 {
1068 font = wxLoadQueryFont(120, wxDEFAULT, wxNORMAL, wxNORMAL,
1069 underlined, wxEmptyString,
1070 info.xregistry, info.xencoding,
1071 xFontName);
1072
1073 // if it still failed, try to get the font of any size but
1074 // with the requested encoding: this can happen if the
1075 // encoding is only available in one size which happens to be
1076 // different from 120
1077 if ( !font )
1078 {
1079 font = wxLoadQueryFont(-1, wxDEFAULT, wxNORMAL, wxNORMAL,
55034339 1080 false, wxEmptyString,
f139dfe8
VZ
1081 info.xregistry, info.xencoding,
1082 xFontName);
1083
1084 // this should never happen as we had tested for it in the
1085 // very beginning, but if it does, do return something non
1086 // NULL or we'd crash in wxFont code
1087 if ( !font )
1088 {
1089 wxFAIL_MSG( _T("this encoding should be available!") );
1090
1091 font = wxLoadQueryFont(-1,
1092 wxDEFAULT, wxNORMAL, wxNORMAL,
55034339 1093 false, wxEmptyString,
f139dfe8
VZ
1094 _T("*"), _T("*"),
1095 xFontName);
1096 }
1097 }
1098 }
7beba2fc
VZ
1099 }
1100 }
1101
1102 return font;
1103}
1104
1105// ----------------------------------------------------------------------------
1106// private functions
1107// ----------------------------------------------------------------------------
1108
55034339 1109// returns true if there are any fonts matching this font spec
7beba2fc
VZ
1110static bool wxTestFontSpec(const wxString& fontspec)
1111{
97d3f0ee
VZ
1112 // some X servers will fail to load this font because there are too many
1113 // matches so we must test explicitly for this
1114 if ( fontspec == _T("-*-*-*-*-*-*-*-*-*-*-*-*-*-*") )
1115 {
55034339 1116 return true;
97d3f0ee
VZ
1117 }
1118
2e0e025e
RR
1119 wxNativeFont test = (wxNativeFont) g_fontHash->Get( fontspec );
1120 if (test)
1121 {
55034339 1122 return true;
2e0e025e
RR
1123 }
1124
1125 test = wxLoadFont(fontspec);
1126 g_fontHash->Put( fontspec, (wxObject*) test );
6c49baf2 1127
7beba2fc
VZ
1128 if ( test )
1129 {
1130 wxFreeFont(test);
1131
55034339 1132 return true;
7beba2fc
VZ
1133 }
1134 else
1135 {
55034339 1136 return false;
7beba2fc
VZ
1137 }
1138}
1139
1140static wxNativeFont wxLoadQueryFont(int pointSize,
1141 int family,
1142 int style,
1143 int weight,
1144 bool WXUNUSED(underlined),
1145 const wxString& facename,
1146 const wxString& xregistry,
30764ab5
VZ
1147 const wxString& xencoding,
1148 wxString* xFontName)
7beba2fc
VZ
1149{
1150 wxString xfamily;
1151 switch (family)
1152 {
1153 case wxDECORATIVE: xfamily = wxT("lucida"); break;
1154 case wxROMAN: xfamily = wxT("times"); break;
1155 case wxMODERN: xfamily = wxT("courier"); break;
1156 case wxSWISS: xfamily = wxT("helvetica"); break;
1157 case wxTELETYPE: xfamily = wxT("lucidatypewriter"); break;
1158 case wxSCRIPT: xfamily = wxT("utopia"); break;
1159 default: xfamily = wxT("*");
1160 }
16d865f7 1161#if wxUSE_NANOX
c2ff68d3
JS
1162 int xweight;
1163 switch (weight)
1164 {
1165 case wxBOLD:
1166 {
1167 xweight = MWLF_WEIGHT_BOLD;
1168 break;
1169 }
1170 case wxLIGHT:
1171 {
1172 xweight = MWLF_WEIGHT_LIGHT;
1173 break;
1174 }
1175 case wxNORMAL:
1176 {
1177 xweight = MWLF_WEIGHT_NORMAL;
1178 break;
1179 }
1180
1181 default:
1182 {
1183 xweight = MWLF_WEIGHT_DEFAULT;
1184 break;
1185 }
1186 }
16d865f7
JS
1187 GR_SCREEN_INFO screenInfo;
1188 GrGetScreenInfo(& screenInfo);
1189
1190 int yPixelsPerCM = screenInfo.ydpcm;
1191
0a68bc69 1192 // A point is 1/72 of an inch.
16d865f7 1193 // An inch is 2.541 cm.
0a68bc69 1194 // So pixelHeight = (pointSize / 72) (inches) * 2.541 (for cm) * yPixelsPerCM (for pixels)
c2ff68d3
JS
1195 // In fact pointSize is 10 * the normal point size so
1196 // divide by 10.
1197
15d5a947 1198 int pixelHeight = (int) ( (((float)pointSize) / 720.0) * 2.541 * (float) yPixelsPerCM) ;
c2ff68d3
JS
1199
1200 // An alternative: assume that the screen is 72 dpi.
0a68bc69
JS
1201 //int pixelHeight = (int) (((float)pointSize / 720.0) * 72.0) ;
1202 //int pixelHeight = (int) ((float)pointSize / 10.0) ;
2b5f62a0 1203
16d865f7
JS
1204 GR_LOGFONT logFont;
1205 logFont.lfHeight = pixelHeight;
1206 logFont.lfWidth = 0;
1207 logFont.lfEscapement = 0;
1208 logFont.lfOrientation = 0;
c2ff68d3 1209 logFont.lfWeight = xweight;
16d865f7
JS
1210 logFont.lfItalic = (style == wxNORMAL ? 0 : 1) ;
1211 logFont.lfUnderline = 0;
1212 logFont.lfStrikeOut = 0;
1213 logFont.lfCharSet = MWLF_CHARSET_DEFAULT; // TODO: select appropriate one
1214 logFont.lfOutPrecision = MWLF_TYPE_DEFAULT;
1215 logFont.lfClipPrecision = 0; // Not used
1216 logFont.lfRoman = (family == wxROMAN ? 1 : 0) ;
1217 logFont.lfSerif = (family == wxSWISS ? 0 : 1) ;
1218 logFont.lfSansSerif = !logFont.lfSerif ;
1219 logFont.lfModern = (family == wxMODERN ? 1 : 0) ;
1220 logFont.lfProportional = (family == wxTELETYPE ? 0 : 1) ;
1221 logFont.lfOblique = 0;
1222 logFont.lfSmallCaps = 0;
1223 logFont.lfPitch = 0; // 0 = default
1224 strcpy(logFont.lfFaceName, facename.c_str());
1225
1226 XFontStruct* fontInfo = (XFontStruct*) malloc(sizeof(XFontStruct));
1227 fontInfo->fid = GrCreateFont((GR_CHAR*) facename.c_str(), pixelHeight, & logFont);
1228 GrGetFontInfo(fontInfo->fid, & fontInfo->info);
1229 return (wxNativeFont) fontInfo;
2b5f62a0 1230
16d865f7 1231#else
7beba2fc 1232 wxString fontSpec;
55034339 1233 if (!facename.empty())
7beba2fc
VZ
1234 {
1235 fontSpec.Printf(wxT("-*-%s-*-*-normal-*-*-*-*-*-*-*-*-*"),
1236 facename.c_str());
1237
1238 if ( wxTestFontSpec(fontSpec) )
1239 {
1240 xfamily = facename;
1241 }
1242 //else: no such family, use default one instead
1243 }
1244
1245 wxString xstyle;
1246 switch (style)
1247 {
f9dbf34f
VZ
1248 case wxSLANT:
1249 fontSpec.Printf(wxT("-*-%s-*-o-*-*-*-*-*-*-*-*-*-*"),
1250 xfamily.c_str());
1251 if ( wxTestFontSpec(fontSpec) )
1252 {
1253 xstyle = wxT("o");
1254 break;
1255 }
1256 // fall through - try wxITALIC now
1257
1258 case wxITALIC:
1259 fontSpec.Printf(wxT("-*-%s-*-i-*-*-*-*-*-*-*-*-*-*"),
1260 xfamily.c_str());
1261 if ( wxTestFontSpec(fontSpec) )
1262 {
1263 xstyle = wxT("i");
1264 }
1265 else if ( style == wxITALIC ) // and not wxSLANT
1266 {
1267 // try wxSLANT
1268 fontSpec.Printf(wxT("-*-%s-*-o-*-*-*-*-*-*-*-*-*-*"),
1269 xfamily.c_str());
1270 if ( wxTestFontSpec(fontSpec) )
1271 {
1272 xstyle = wxT("o");
1273 }
1274 else
1275 {
1276 // no italic, no slant - leave default
1277 xstyle = wxT("*");
1278 }
1279 }
1280 break;
1281
1282 default:
1283 wxFAIL_MSG(_T("unknown font style"));
1284 // fall back to normal
1285
1286 case wxNORMAL:
1287 xstyle = wxT("r");
1288 break;
7beba2fc
VZ
1289 }
1290
1291 wxString xweight;
1292 switch (weight)
1293 {
1294 case wxBOLD:
1295 {
1296 fontSpec.Printf(wxT("-*-%s-bold-*-*-*-*-*-*-*-*-*-*-*"),
1297 xfamily.c_str());
1298 if ( wxTestFontSpec(fontSpec) )
1299 {
1300 xweight = wxT("bold");
1301 break;
1302 }
1303 fontSpec.Printf(wxT("-*-%s-heavy-*-*-*-*-*-*-*-*-*-*-*"),
1304 xfamily.c_str());
1305 if ( wxTestFontSpec(fontSpec) )
1306 {
1307 xweight = wxT("heavy");
1308 break;
1309 }
1310 fontSpec.Printf(wxT("-*-%s-extrabold-*-*-*-*-*-*-*-*-*-*-*"),
1311 xfamily.c_str());
1312 if ( wxTestFontSpec(fontSpec) )
1313 {
1314 xweight = wxT("extrabold");
1315 break;
1316 }
1317 fontSpec.Printf(wxT("-*-%s-demibold-*-*-*-*-*-*-*-*-*-*-*"),
1318 xfamily.c_str());
1319 if ( wxTestFontSpec(fontSpec) )
1320 {
1321 xweight = wxT("demibold");
1322 break;
1323 }
1324 fontSpec.Printf(wxT("-*-%s-black-*-*-*-*-*-*-*-*-*-*-*"),
1325 xfamily.c_str());
1326 if ( wxTestFontSpec(fontSpec) )
1327 {
1328 xweight = wxT("black");
1329 break;
1330 }
1331 fontSpec.Printf(wxT("-*-%s-ultrablack-*-*-*-*-*-*-*-*-*-*-*"),
1332 xfamily.c_str());
1333 if ( wxTestFontSpec(fontSpec) )
1334 {
1335 xweight = wxT("ultrablack");
1336 break;
1337 }
1338 }
1339 break;
1340 case wxLIGHT:
1341 {
1342 fontSpec.Printf(wxT("-*-%s-light-*-*-*-*-*-*-*-*-*-*-*"),
1343 xfamily.c_str());
1344 if ( wxTestFontSpec(fontSpec) )
1345 {
1346 xweight = wxT("light");
1347 break;
1348 }
1349 fontSpec.Printf(wxT("-*-%s-thin-*-*-*-*-*-*-*-*-*-*-*"),
1350 xfamily.c_str());
1351 if ( wxTestFontSpec(fontSpec) )
1352 {
1353 xweight = wxT("thin");
1354 break;
1355 }
1356 }
1357 break;
1358 case wxNORMAL:
1359 {
1360 fontSpec.Printf(wxT("-*-%s-medium-*-*-*-*-*-*-*-*-*-*-*"),
1361 xfamily.c_str());
1362 if ( wxTestFontSpec(fontSpec) )
1363 {
1364 xweight = wxT("medium");
1365 break;
1366 }
1367 fontSpec.Printf(wxT("-*-%s-normal-*-*-*-*-*-*-*-*-*-*-*"),
1368 xfamily.c_str());
1369 if ( wxTestFontSpec(fontSpec) )
1370 {
1371 xweight = wxT("normal");
1372 break;
1373 }
1374 fontSpec.Printf(wxT("-*-%s-regular-*-*-*-*-*-*-*-*-*-*-*"),
1375 xfamily.c_str());
1376 if ( wxTestFontSpec(fontSpec) )
1377 {
1378 xweight = wxT("regular");
1379 break;
1380 }
1381 xweight = wxT("*");
1382 }
1383 break;
1384 default: xweight = wxT("*"); break;
1385 }
1386
f139dfe8
VZ
1387 // if pointSize is -1, don't specify any
1388 wxString sizeSpec;
73b0423d 1389 if ( pointSize == -1 )
f139dfe8
VZ
1390 {
1391 sizeSpec = _T('*');
1392 }
1393 else
1394 {
1395 sizeSpec.Printf(_T("%d"), pointSize);
1396 }
1397
7beba2fc 1398 // construct the X font spec from our data
f139dfe8 1399 fontSpec.Printf(wxT("-*-%s-%s-%s-normal-*-*-%s-*-*-*-*-%s-%s"),
7beba2fc 1400 xfamily.c_str(), xweight.c_str(), xstyle.c_str(),
f139dfe8 1401 sizeSpec.c_str(), xregistry.c_str(), xencoding.c_str());
7beba2fc 1402
30764ab5
VZ
1403 if( xFontName )
1404 *xFontName = fontSpec;
1405
7beba2fc 1406 return wxLoadFont(fontSpec);
16d865f7
JS
1407#endif
1408 // wxUSE_NANOX
7beba2fc
VZ
1409}
1410
2e0e025e
RR
1411// ----------------------------------------------------------------------------
1412// wxFontModule
1413// ----------------------------------------------------------------------------
1414
1415class wxFontModule : public wxModule
1416{
1417public:
1418 bool OnInit();
1419 void OnExit();
1420
1421private:
1422 DECLARE_DYNAMIC_CLASS(wxFontModule)
1423};
1424
1425IMPLEMENT_DYNAMIC_CLASS(wxFontModule, wxModule)
1426
1427bool wxFontModule::OnInit()
1428{
1429 g_fontHash = new wxHashTable( wxKEY_STRING );
1430
55034339 1431 return true;
2e0e025e
RR
1432}
1433
1434void wxFontModule::OnExit()
1435{
1436 delete g_fontHash;
1437
1438 g_fontHash = (wxHashTable *)NULL;
1439}
db16cab4 1440
2b5f62a0 1441#endif // GTK 2.0/1.x