]> git.saurik.com Git - wxWidgets.git/blame - src/unix/fontutil.cpp
wxchar.h doesn't have to be C file anymore, it's C++
[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
47239bd6 51 #define wxPANGO_CONV_BACK wxGTK_CONV_BACK_SYS
2b5f62a0 52#else
29131e8a
VZ
53 #include "wx/x11/private.h"
54 #include "wx/gtk/private/string.h"
55
56 #define wxPANGO_CONV(s) (wxConvUTF8.cWX2MB((s)))
47239bd6 57 #define wxPANGO_CONV_BACK(s) (wxConvUTF8.cMB2WX((s)))
2b5f62a0 58#endif
db16cab4
RR
59
60// ----------------------------------------------------------------------------
61// wxNativeFontInfo
62// ----------------------------------------------------------------------------
63
64void wxNativeFontInfo::Init()
65{
66 description = NULL;
67}
68
23afe648
VZ
69void
70wxNativeFontInfo::Init(const wxNativeFontInfo& info)
fdf7514a
VS
71{
72 if (info.description)
73 description = pango_font_description_copy(info.description);
74 else
82680055 75 description = NULL;
fdf7514a
VS
76}
77
82680055 78void wxNativeFontInfo::Free()
fdf7514a
VS
79{
80 if (description)
81 pango_font_description_free(description);
82}
83
db16cab4
RR
84int wxNativeFontInfo::GetPointSize() const
85{
86 return pango_font_description_get_size( description ) / PANGO_SCALE;
87}
88
89wxFontStyle wxNativeFontInfo::GetStyle() const
90{
91 wxFontStyle m_style = wxFONTSTYLE_NORMAL;
92
93 switch (pango_font_description_get_style( description ))
94 {
95 case PANGO_STYLE_NORMAL:
96 m_style = wxFONTSTYLE_NORMAL;
97 break;
98 case PANGO_STYLE_ITALIC:
99 m_style = wxFONTSTYLE_ITALIC;
100 break;
101 case PANGO_STYLE_OBLIQUE:
102 m_style = wxFONTSTYLE_SLANT;
103 break;
104 }
2b5f62a0 105
db16cab4
RR
106 return m_style;
107}
108
109wxFontWeight wxNativeFontInfo::GetWeight() const
110{
0f6858b6
RR
111#if 0
112 // We seem to currently initialize only by string.
113 // In that case PANGO_FONT_MASK_WEIGHT is always set.
114 if (!(pango_font_description_get_set_fields(description) & PANGO_FONT_MASK_WEIGHT))
115 return wxFONTWEIGHT_NORMAL;
116#endif
db16cab4 117
0f6858b6
RR
118 PangoWeight pango_weight = pango_font_description_get_weight( description );
119
120 // Until the API can be changed the following ranges of weight values are used:
121 // wxFONTWEIGHT_LIGHT: 100 .. 349 - range of 250
122 // wxFONTWEIGHT_NORMAL: 350 .. 599 - range of 250
123 // wxFONTWEIGHT_BOLD: 600 .. 900 - range of 301 (600 is "semibold" already)
124
125 if (pango_weight >= 600)
126 return wxFONTWEIGHT_BOLD;
127
128 if (pango_weight < 350)
129 return wxFONTWEIGHT_LIGHT;
2b5f62a0 130
0f6858b6 131 return wxFONTWEIGHT_NORMAL;
db16cab4
RR
132}
133
134bool wxNativeFontInfo::GetUnderlined() const
135{
55034339 136 return false;
db16cab4
RR
137}
138
139wxString wxNativeFontInfo::GetFaceName() const
140{
47239bd6 141 return wxPANGO_CONV_BACK(pango_font_description_get_family(description));
db16cab4
RR
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
47239bd6 330 return wxPANGO_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
2b5f62a0 343#else // GTK+ 1.x
db16cab4 344
79e4b627 345#ifdef __X__
4ea45e6b
VZ
346 #ifdef __VMS__
347 #pragma message disable nosimpint
348 #endif
349
350 #include <X11/Xlib.h>
351
352 #ifdef __VMS__
353 #pragma message enable nosimpint
354 #endif
79e4b627 355
79e4b627 356#elif defined(__WXGTK__)
4ea45e6b
VZ
357 // we have to declare struct tm to avoid problems with first forward
358 // declaring it in C code (glib.h included from gdk.h does it) and then
359 // defining it when time.h is included from the headers below - this is
360 // known not to work at least with Sun CC 6.01
361 #include <time.h>
362
363 #include <gdk/gdk.h>
79e4b627
VZ
364#endif
365
2e0e025e
RR
366
367// ----------------------------------------------------------------------------
368// private data
369// ----------------------------------------------------------------------------
370
371static wxHashTable *g_fontHash = (wxHashTable*) NULL;
7beba2fc
VZ
372
373// ----------------------------------------------------------------------------
374// private functions
375// ----------------------------------------------------------------------------
376
377// define the functions to create and destroy native fonts for this toolkit
378#ifdef __X__
3fe34ed0 379 wxNativeFont wxLoadFont(const wxString& fontSpec)
7beba2fc
VZ
380 {
381 return XLoadQueryFont((Display *)wxGetDisplay(), fontSpec);
382 }
383
409d5a58 384 inline void wxFreeFont(wxNativeFont font)
7beba2fc 385 {
a5fc62a1 386 XFreeFont((Display *)wxGetDisplay(), (XFontStruct *)font);
7beba2fc
VZ
387 }
388#elif defined(__WXGTK__)
3fe34ed0 389 wxNativeFont wxLoadFont(const wxString& fontSpec)
7beba2fc 390 {
8fa3a431
VZ
391 // VZ: we should use gdk_fontset_load() instead of gdk_font_load()
392 // here to be able to display Japanese fonts correctly (at least
393 // this is what people report) but unfortunately doing it results
394 // in tons of warnings when using GTK with "normal" European
395 // languages and so we can't always do it and I don't know enough
396 // to determine when should this be done... (FIXME)
397 return gdk_font_load( wxConvertWX2MB(fontSpec) );
7beba2fc
VZ
398 }
399
409d5a58 400 inline void wxFreeFont(wxNativeFont font)
7beba2fc
VZ
401 {
402 gdk_font_unref(font);
403 }
404#else
405 #error "Unknown GUI toolkit"
406#endif
407
408static bool wxTestFontSpec(const wxString& fontspec);
409
410static wxNativeFont wxLoadQueryFont(int pointSize,
411 int family,
412 int style,
413 int weight,
414 bool underlined,
415 const wxString& facename,
416 const wxString& xregistry,
30764ab5
VZ
417 const wxString& xencoding,
418 wxString* xFontName);
7beba2fc
VZ
419
420// ============================================================================
421// implementation
422// ============================================================================
423
424// ----------------------------------------------------------------------------
425// wxNativeEncodingInfo
426// ----------------------------------------------------------------------------
427
428// convert to/from the string representation: format is
1e1d0be1 429// encodingid;registry;encoding[;facename]
7beba2fc
VZ
430bool wxNativeEncodingInfo::FromString(const wxString& s)
431{
6c49baf2 432 // use ";", not "-" because it may be part of encoding name
1e1d0be1 433 wxStringTokenizer tokenizer(s, _T(";"));
1e1d0be1
VS
434
435 wxString encid = tokenizer.GetNextToken();
436 long enc;
437 if ( !encid.ToLong(&enc) )
55034339 438 return false;
1e1d0be1 439 encoding = (wxFontEncoding)enc;
7beba2fc
VZ
440
441 xregistry = tokenizer.GetNextToken();
442 if ( !xregistry )
55034339 443 return false;
7beba2fc
VZ
444
445 xencoding = tokenizer.GetNextToken();
446 if ( !xencoding )
55034339 447 return false;
7beba2fc
VZ
448
449 // ok even if empty
450 facename = tokenizer.GetNextToken();
451
55034339 452 return true;
7beba2fc
VZ
453}
454
455wxString wxNativeEncodingInfo::ToString() const
456{
457 wxString s;
1e1d0be1 458 s << (long)encoding << _T(';') << xregistry << _T(';') << xencoding;
55034339 459 if ( !facename.empty() )
7beba2fc 460 {
1e1d0be1 461 s << _T(';') << facename;
7beba2fc
VZ
462 }
463
464 return s;
465}
466
ab5fe833
VZ
467// ----------------------------------------------------------------------------
468// wxNativeFontInfo
469// ----------------------------------------------------------------------------
470
471void wxNativeFontInfo::Init()
472{
55034339 473 m_isDefault = true;
ab5fe833
VZ
474}
475
476bool wxNativeFontInfo::FromString(const wxString& s)
477{
478 wxStringTokenizer tokenizer(s, _T(";"));
479
480 // check the version
481 wxString token = tokenizer.GetNextToken();
482 if ( token != _T('0') )
55034339 483 return false;
ab5fe833
VZ
484
485 xFontName = tokenizer.GetNextToken();
486
487 // this should be the end
488 if ( tokenizer.HasMoreTokens() )
55034339 489 return false;
ab5fe833
VZ
490
491 return FromXFontName(xFontName);
492}
493
494wxString wxNativeFontInfo::ToString() const
495{
496 // 0 is the version
497 return wxString::Format(_T("%d;%s"), 0, GetXFontName().c_str());
498}
499
500bool wxNativeFontInfo::FromUserString(const wxString& s)
501{
502 return FromXFontName(s);
503}
504
505wxString wxNativeFontInfo::ToUserString() const
506{
507 return GetXFontName();
508}
509
409d5a58
VZ
510bool wxNativeFontInfo::HasElements() const
511{
512 // we suppose that the foundry is never empty, so if it is it means that we
513 // had never parsed the XLFD
514 return !fontElements[0].empty();
515}
516
53f6aab7
VZ
517wxString wxNativeFontInfo::GetXFontComponent(wxXLFDField field) const
518{
55034339 519 wxCHECK_MSG( field < wxXLFD_MAX, wxEmptyString, _T("invalid XLFD field") );
53f6aab7 520
409d5a58 521 if ( !HasElements() )
53f6aab7
VZ
522 {
523 // const_cast
524 if ( !((wxNativeFontInfo *)this)->FromXFontName(xFontName) )
55034339 525 return wxEmptyString;
53f6aab7
VZ
526 }
527
528 return fontElements[field];
529}
530
295272bd 531bool wxNativeFontInfo::FromXFontName(const wxString& fontname)
ab5fe833
VZ
532{
533 // TODO: we should be able to handle the font aliases here, but how?
409d5a58
VZ
534 wxStringTokenizer tokenizer(fontname, _T("-"));
535
536 // skip the leading, usually empty field (font name registry)
537 if ( !tokenizer.HasMoreTokens() )
55034339 538 return false;
409d5a58
VZ
539
540 (void)tokenizer.GetNextToken();
ab5fe833
VZ
541
542 for ( size_t n = 0; n < WXSIZEOF(fontElements); n++ )
543 {
544 if ( !tokenizer.HasMoreTokens() )
545 {
546 // not enough elements in the XLFD - or maybe an alias
55034339 547 return false;
ab5fe833
VZ
548 }
549
b4e4abb5
VZ
550 wxString field = tokenizer.GetNextToken();
551 if ( !field.empty() && field != _T('*') )
552 {
553 // we're really initialized now
55034339 554 m_isDefault = false;
b4e4abb5
VZ
555 }
556
557 fontElements[n] = field;
ab5fe833
VZ
558 }
559
560 // this should be all
011ba5ed 561 if ( tokenizer.HasMoreTokens() )
55034339 562 return false;
011ba5ed 563
55034339 564 return true;
ab5fe833
VZ
565}
566
567wxString wxNativeFontInfo::GetXFontName() const
568{
569 if ( xFontName.empty() )
570 {
571 for ( size_t n = 0; n < WXSIZEOF(fontElements); n++ )
572 {
573 // replace the non specified elements with '*' except for the
574 // additional style which is usually just omitted
575 wxString elt = fontElements[n];
409d5a58 576 if ( elt.empty() && n != wxXLFD_ADDSTYLE )
ab5fe833
VZ
577 {
578 elt = _T('*');
579 }
580
581 // const_cast
582 ((wxNativeFontInfo *)this)->xFontName << _T('-') << elt;
583 }
584 }
585
586 return xFontName;
587}
588
409d5a58
VZ
589void
590wxNativeFontInfo::SetXFontComponent(wxXLFDField field, const wxString& value)
591{
592 wxCHECK_RET( field < wxXLFD_MAX, _T("invalid XLFD field") );
593
594 // this class should be initialized with a valid font spec first and only
595 // then the fields may be modified!
596 wxASSERT_MSG( !IsDefault(), _T("can't modify an uninitialized XLFD") );
597
598 if ( !HasElements() )
599 {
600 // const_cast
601 if ( !((wxNativeFontInfo *)this)->FromXFontName(xFontName) )
602 {
603 wxFAIL_MSG( _T("can't set font element for invalid XLFD") );
604
605 return;
606 }
607 }
608
609 fontElements[field] = value;
610
611 // invalidate the XFLD, it doesn't correspond to the font elements any more
612 xFontName.clear();
613}
614
615void wxNativeFontInfo::SetXFontName(const wxString& xFontName_)
616{
617 // invalidate the font elements, GetXFontComponent() will reparse the XLFD
618 fontElements[0].clear();
619
620 xFontName = xFontName_;
621
55034339 622 m_isDefault = false;
409d5a58
VZ
623}
624
2b5f62a0
VZ
625int wxNativeFontInfo::GetPointSize() const
626{
627 const wxString s = GetXFontComponent(wxXLFD_POINTSIZE);
628
629 // return -1 to indicate that the size is unknown
630 long l;
631 return s.ToLong(&l) ? l : -1;
632}
633
634wxFontStyle wxNativeFontInfo::GetStyle() const
635{
636 const wxString s = GetXFontComponent(wxXLFD_SLANT);
637
638 if ( s.length() != 1 )
639 {
640 // it is really unknown but we don't have any way to return it from
641 // here
642 return wxFONTSTYLE_NORMAL;
643 }
644
102798af 645 switch ( s[0].GetValue() )
2b5f62a0
VZ
646 {
647 default:
648 // again, unknown but consider normal by default
649
650 case _T('r'):
651 return wxFONTSTYLE_NORMAL;
652
653 case _T('i'):
654 return wxFONTSTYLE_ITALIC;
655
656 case _T('o'):
657 return wxFONTSTYLE_SLANT;
658 }
659}
660
661wxFontWeight wxNativeFontInfo::GetWeight() const
662{
663 const wxString s = GetXFontComponent(wxXLFD_WEIGHT).MakeLower();
664 if ( s.find(_T("bold")) != wxString::npos || s == _T("black") )
665 return wxFONTWEIGHT_BOLD;
666 else if ( s == _T("light") )
667 return wxFONTWEIGHT_LIGHT;
668
669 return wxFONTWEIGHT_NORMAL;
670}
671
672bool wxNativeFontInfo::GetUnderlined() const
673{
674 // X fonts are never underlined
55034339 675 return false;
2b5f62a0
VZ
676}
677
678wxString wxNativeFontInfo::GetFaceName() const
679{
77ffb593 680 // wxWidgets facename probably more accurately corresponds to X family
2b5f62a0
VZ
681 return GetXFontComponent(wxXLFD_FAMILY);
682}
683
684wxFontFamily wxNativeFontInfo::GetFamily() const
685{
77ffb593 686 // and wxWidgets family -- to X foundry, but we have to translate it to
2b5f62a0
VZ
687 // wxFontFamily somehow...
688 wxFAIL_MSG(_T("not implemented")); // GetXFontComponent(wxXLFD_FOUNDRY);
689
690 return wxFONTFAMILY_DEFAULT;
691}
692
693wxFontEncoding wxNativeFontInfo::GetEncoding() const
694{
695 // we already have the code for this but need to refactor it first
696 wxFAIL_MSG( _T("not implemented") );
697
698 return wxFONTENCODING_MAX;
699}
700
701void wxNativeFontInfo::SetPointSize(int pointsize)
702{
703 SetXFontComponent(wxXLFD_POINTSIZE, wxString::Format(_T("%d"), pointsize));
704}
705
706void wxNativeFontInfo::SetStyle(wxFontStyle style)
707{
708 wxString s;
709 switch ( style )
710 {
711 case wxFONTSTYLE_ITALIC:
712 s = _T('i');
713 break;
714
715 case wxFONTSTYLE_SLANT:
716 s = _T('o');
717 break;
718
719 case wxFONTSTYLE_NORMAL:
720 s = _T('r');
721
722 default:
723 wxFAIL_MSG( _T("unknown wxFontStyle in wxNativeFontInfo::SetStyle") );
724 return;
725 }
726
727 SetXFontComponent(wxXLFD_SLANT, s);
728}
729
730void wxNativeFontInfo::SetWeight(wxFontWeight weight)
731{
732 wxString s;
733 switch ( weight )
734 {
735 case wxFONTWEIGHT_BOLD:
736 s = _T("bold");
737 break;
738
739 case wxFONTWEIGHT_LIGHT:
740 s = _T("light");
741 break;
742
743 case wxFONTWEIGHT_NORMAL:
744 s = _T("medium");
745 break;
746
747 default:
748 wxFAIL_MSG( _T("unknown wxFontWeight in wxNativeFontInfo::SetWeight") );
749 return;
750 }
751
752 SetXFontComponent(wxXLFD_WEIGHT, s);
753}
754
755void wxNativeFontInfo::SetUnderlined(bool WXUNUSED(underlined))
756{
757 // can't do this under X
758}
759
85ab460e 760bool wxNativeFontInfo::SetFaceName(const wxString& facename)
2b5f62a0
VZ
761{
762 SetXFontComponent(wxXLFD_FAMILY, facename);
85ab460e 763 return true;
2b5f62a0
VZ
764}
765
55034339 766void wxNativeFontInfo::SetFamily(wxFontFamily WXUNUSED(family))
2b5f62a0
VZ
767{
768 // wxFontFamily -> X foundry, anyone?
769 wxFAIL_MSG( _T("not implemented") );
770
771 // SetXFontComponent(wxXLFD_FOUNDRY, ...);
772}
773
774void wxNativeFontInfo::SetEncoding(wxFontEncoding encoding)
775{
776 wxNativeEncodingInfo info;
777 if ( wxGetNativeFontEncoding(encoding, &info) )
778 {
779 SetXFontComponent(wxXLFD_ENCODING, info.xencoding);
780 SetXFontComponent(wxXLFD_REGISTRY, info.xregistry);
781 }
782}
783
7beba2fc
VZ
784// ----------------------------------------------------------------------------
785// common functions
786// ----------------------------------------------------------------------------
787
788bool wxGetNativeFontEncoding(wxFontEncoding encoding,
789 wxNativeEncodingInfo *info)
790{
55034339 791 wxCHECK_MSG( info, false, _T("bad pointer in wxGetNativeFontEncoding") );
7beba2fc
VZ
792
793 if ( encoding == wxFONTENCODING_DEFAULT )
794 {
795 encoding = wxFont::GetDefaultEncoding();
796 }
797
798 switch ( encoding )
799 {
800 case wxFONTENCODING_ISO8859_1:
801 case wxFONTENCODING_ISO8859_2:
802 case wxFONTENCODING_ISO8859_3:
803 case wxFONTENCODING_ISO8859_4:
804 case wxFONTENCODING_ISO8859_5:
805 case wxFONTENCODING_ISO8859_6:
806 case wxFONTENCODING_ISO8859_7:
807 case wxFONTENCODING_ISO8859_8:
808 case wxFONTENCODING_ISO8859_9:
809 case wxFONTENCODING_ISO8859_10:
810 case wxFONTENCODING_ISO8859_11:
80a24267 811 case wxFONTENCODING_ISO8859_12:
7beba2fc
VZ
812 case wxFONTENCODING_ISO8859_13:
813 case wxFONTENCODING_ISO8859_14:
814 case wxFONTENCODING_ISO8859_15:
815 {
816 int cp = encoding - wxFONTENCODING_ISO8859_1 + 1;
817 info->xregistry = wxT("iso8859");
818 info->xencoding.Printf(wxT("%d"), cp);
819 }
820 break;
821
bb84929e 822 case wxFONTENCODING_UTF8:
5707316c 823 info->xregistry = wxT("iso10646");
bb84929e
VZ
824 info->xencoding = wxT("*");
825 break;
826
2b5f62a0 827 case wxFONTENCODING_GB2312:
82680055 828 info->xregistry = wxT("GB2312"); // or the otherway round?
2b5f62a0
VZ
829 info->xencoding = wxT("*");
830 break;
831
7beba2fc 832 case wxFONTENCODING_KOI8:
15ad38c3 833 case wxFONTENCODING_KOI8_U:
7beba2fc
VZ
834 info->xregistry = wxT("koi8");
835
5707316c 836 // we don't make distinction between koi8-r, koi8-u and koi8-ru (so far)
7beba2fc
VZ
837 info->xencoding = wxT("*");
838 break;
839
840 case wxFONTENCODING_CP1250:
841 case wxFONTENCODING_CP1251:
842 case wxFONTENCODING_CP1252:
843 case wxFONTENCODING_CP1253:
844 case wxFONTENCODING_CP1254:
845 case wxFONTENCODING_CP1255:
846 case wxFONTENCODING_CP1256:
847 case wxFONTENCODING_CP1257:
848 {
849 int cp = encoding - wxFONTENCODING_CP1250 + 1250;
850 info->xregistry = wxT("microsoft");
851 info->xencoding.Printf(wxT("cp%d"), cp);
852 }
853 break;
854
d946915c
MB
855 case wxFONTENCODING_EUC_JP:
856 case wxFONTENCODING_SHIFT_JIS:
857 info->xregistry = "jis*";
858 info->xencoding = "*";
859 break;
860
7beba2fc
VZ
861 case wxFONTENCODING_SYSTEM:
862 info->xregistry =
81c67e27 863 info->xencoding = wxT("*");
7beba2fc
VZ
864 break;
865
866 default:
867 // don't know how to translate this encoding into X fontspec
55034339 868 return false;
7beba2fc
VZ
869 }
870
ab5fe833 871 info->encoding = encoding;
6b0eebc5 872
55034339 873 return true;
7beba2fc
VZ
874}
875
876bool wxTestFontEncoding(const wxNativeEncodingInfo& info)
877{
878 wxString fontspec;
879 fontspec.Printf(_T("-*-%s-*-*-*-*-*-*-*-*-*-*-%s-%s"),
880 !info.facename ? _T("*") : info.facename.c_str(),
881 info.xregistry.c_str(),
882 info.xencoding.c_str());
883
884 return wxTestFontSpec(fontspec);
885}
886
887// ----------------------------------------------------------------------------
888// X-specific functions
889// ----------------------------------------------------------------------------
890
891wxNativeFont wxLoadQueryNearestFont(int pointSize,
892 int family,
893 int style,
894 int weight,
895 bool underlined,
896 const wxString &facename,
30764ab5
VZ
897 wxFontEncoding encoding,
898 wxString* xFontName)
7beba2fc 899{
97d3f0ee
VZ
900 if ( encoding == wxFONTENCODING_DEFAULT )
901 {
902 encoding = wxFont::GetDefaultEncoding();
903 }
904
7beba2fc
VZ
905 // first determine the encoding - if the font doesn't exist at all in this
906 // encoding, it's useless to do all other approximations (i.e. size,
907 // family &c don't matter much)
908 wxNativeEncodingInfo info;
97d3f0ee 909 if ( encoding == wxFONTENCODING_SYSTEM )
81c67e27
RR
910 {
911 // This will always work so we don't test to save time
912 wxGetNativeFontEncoding(wxFONTENCODING_SYSTEM, &info);
913 }
914 else
7beba2fc 915 {
81c67e27
RR
916 if ( !wxGetNativeFontEncoding(encoding, &info) ||
917 !wxTestFontEncoding(info) )
7beba2fc 918 {
1e6feb95 919#if wxUSE_FONTMAP
142b3bc2 920 if ( !wxFontMapper::Get()->GetAltForEncoding(encoding, &info) )
1e6feb95 921#endif // wxUSE_FONTMAP
81c67e27
RR
922 {
923 // unspported encoding - replace it with the default
924 //
925 // NB: we can't just return 0 from here because wxGTK code doesn't
926 // check for it (i.e. it supposes that we'll always succeed),
927 // so it would provoke a crash
928 wxGetNativeFontEncoding(wxFONTENCODING_SYSTEM, &info);
929 }
97d3f0ee 930 }
7beba2fc 931 }
6c49baf2 932
81c67e27 933 // OK, we have the correct xregistry/xencoding in info structure
30764ab5
VZ
934 wxNativeFont font = 0;
935
936 // if we already have the X font name, try to use it
55034339 937 if( xFontName && !xFontName->empty() )
6c49baf2
VZ
938 {
939 //
940 // Make sure point size is correct for scale factor.
941 //
942 wxStringTokenizer tokenizer(*xFontName, _T("-"), wxTOKEN_RET_DELIMS);
943 wxString newFontName;
944
945 for(int i = 0; i < 8; i++)
946 newFontName += tokenizer.NextToken();
947
948 (void) tokenizer.NextToken();
949
401eb3de 950 newFontName += wxString::Format(wxT("%d-"), pointSize);
6c49baf2
VZ
951
952 while(tokenizer.HasMoreTokens())
953 newFontName += tokenizer.GetNextToken();
954
955 font = wxLoadFont(newFontName);
956
957 if(font)
958 *xFontName = newFontName;
959 }
30764ab5 960
7beba2fc
VZ
961 if ( !font )
962 {
963 // search up and down by stepsize 10
964 int max_size = pointSize + 20 * (1 + (pointSize/180));
965 int min_size = pointSize - 20 * (1 + (pointSize/180));
966
34791896 967 int i, round; // counters
7beba2fc 968
34791896
RR
969 // first round: search for equal, then for smaller and for larger size with the given weight and style
970 int testweight = weight;
971 int teststyle = style;
972
973 for ( round = 0; round < 3; round++ )
974 {
975 // second round: use normal weight
976 if ( round == 1 )
b12401e0 977 {
34791896
RR
978 if ( testweight != wxNORMAL )
979 {
980 testweight = wxNORMAL;
981 }
982 else
983 {
984 ++round; // fall through to third round
985 }
986 }
987
988 // third round: ... and use normal style
989 if ( round == 2 )
990 {
991 if ( teststyle != wxNORMAL )
992 {
993 teststyle = wxNORMAL;
994 }
995 else
996 {
997 break;
998 }
999 }
1000 // Search for equal or smaller size (approx.)
1001 for ( i = pointSize; !font && i >= 10 && i >= min_size; i -= 10 )
1002 {
1003 font = wxLoadQueryFont(i, family, teststyle, testweight, underlined,
30764ab5
VZ
1004 facename, info.xregistry, info.xencoding,
1005 xFontName);
b12401e0 1006 }
7beba2fc 1007
b12401e0
MB
1008 // Search for larger size (approx.)
1009 for ( i = pointSize + 10; !font && i <= max_size; i += 10 )
1010 {
34791896 1011 font = wxLoadQueryFont(i, family, teststyle, testweight, underlined,
30764ab5
VZ
1012 facename, info.xregistry, info.xencoding,
1013 xFontName);
34791896 1014 }
7beba2fc
VZ
1015 }
1016
1017 // Try default family
1018 if ( !font && family != wxDEFAULT )
1019 {
1020 font = wxLoadQueryFont(pointSize, wxDEFAULT, style, weight,
1021 underlined, facename,
30764ab5
VZ
1022 info.xregistry, info.xencoding,
1023 xFontName );
7beba2fc
VZ
1024 }
1025
f139dfe8
VZ
1026 // ignore size, family, style and weight but try to find font with the
1027 // given facename and encoding
7beba2fc
VZ
1028 if ( !font )
1029 {
1030 font = wxLoadQueryFont(120, wxDEFAULT, wxNORMAL, wxNORMAL,
1031 underlined, facename,
30764ab5
VZ
1032 info.xregistry, info.xencoding,
1033 xFontName);
7beba2fc 1034
f139dfe8
VZ
1035 // ignore family as well
1036 if ( !font )
1037 {
1038 font = wxLoadQueryFont(120, wxDEFAULT, wxNORMAL, wxNORMAL,
1039 underlined, wxEmptyString,
1040 info.xregistry, info.xencoding,
1041 xFontName);
1042
1043 // if it still failed, try to get the font of any size but
1044 // with the requested encoding: this can happen if the
1045 // encoding is only available in one size which happens to be
1046 // different from 120
1047 if ( !font )
1048 {
1049 font = wxLoadQueryFont(-1, wxDEFAULT, wxNORMAL, wxNORMAL,
55034339 1050 false, wxEmptyString,
f139dfe8
VZ
1051 info.xregistry, info.xencoding,
1052 xFontName);
1053
1054 // this should never happen as we had tested for it in the
1055 // very beginning, but if it does, do return something non
1056 // NULL or we'd crash in wxFont code
1057 if ( !font )
1058 {
1059 wxFAIL_MSG( _T("this encoding should be available!") );
1060
1061 font = wxLoadQueryFont(-1,
1062 wxDEFAULT, wxNORMAL, wxNORMAL,
55034339 1063 false, wxEmptyString,
f139dfe8
VZ
1064 _T("*"), _T("*"),
1065 xFontName);
1066 }
1067 }
1068 }
7beba2fc
VZ
1069 }
1070 }
1071
1072 return font;
1073}
1074
1075// ----------------------------------------------------------------------------
1076// private functions
1077// ----------------------------------------------------------------------------
1078
55034339 1079// returns true if there are any fonts matching this font spec
7beba2fc
VZ
1080static bool wxTestFontSpec(const wxString& fontspec)
1081{
97d3f0ee
VZ
1082 // some X servers will fail to load this font because there are too many
1083 // matches so we must test explicitly for this
1084 if ( fontspec == _T("-*-*-*-*-*-*-*-*-*-*-*-*-*-*") )
1085 {
55034339 1086 return true;
97d3f0ee
VZ
1087 }
1088
2e0e025e
RR
1089 wxNativeFont test = (wxNativeFont) g_fontHash->Get( fontspec );
1090 if (test)
1091 {
55034339 1092 return true;
2e0e025e
RR
1093 }
1094
1095 test = wxLoadFont(fontspec);
1096 g_fontHash->Put( fontspec, (wxObject*) test );
6c49baf2 1097
7beba2fc
VZ
1098 if ( test )
1099 {
1100 wxFreeFont(test);
1101
55034339 1102 return true;
7beba2fc
VZ
1103 }
1104 else
1105 {
55034339 1106 return false;
7beba2fc
VZ
1107 }
1108}
1109
1110static wxNativeFont wxLoadQueryFont(int pointSize,
1111 int family,
1112 int style,
1113 int weight,
1114 bool WXUNUSED(underlined),
1115 const wxString& facename,
1116 const wxString& xregistry,
30764ab5
VZ
1117 const wxString& xencoding,
1118 wxString* xFontName)
7beba2fc
VZ
1119{
1120 wxString xfamily;
1121 switch (family)
1122 {
1123 case wxDECORATIVE: xfamily = wxT("lucida"); break;
1124 case wxROMAN: xfamily = wxT("times"); break;
1125 case wxMODERN: xfamily = wxT("courier"); break;
1126 case wxSWISS: xfamily = wxT("helvetica"); break;
1127 case wxTELETYPE: xfamily = wxT("lucidatypewriter"); break;
1128 case wxSCRIPT: xfamily = wxT("utopia"); break;
1129 default: xfamily = wxT("*");
1130 }
16d865f7 1131#if wxUSE_NANOX
c2ff68d3
JS
1132 int xweight;
1133 switch (weight)
1134 {
1135 case wxBOLD:
1136 {
1137 xweight = MWLF_WEIGHT_BOLD;
1138 break;
1139 }
1140 case wxLIGHT:
1141 {
1142 xweight = MWLF_WEIGHT_LIGHT;
1143 break;
1144 }
1145 case wxNORMAL:
1146 {
1147 xweight = MWLF_WEIGHT_NORMAL;
1148 break;
1149 }
1150
1151 default:
1152 {
1153 xweight = MWLF_WEIGHT_DEFAULT;
1154 break;
1155 }
1156 }
16d865f7
JS
1157 GR_SCREEN_INFO screenInfo;
1158 GrGetScreenInfo(& screenInfo);
1159
1160 int yPixelsPerCM = screenInfo.ydpcm;
1161
0a68bc69 1162 // A point is 1/72 of an inch.
16d865f7 1163 // An inch is 2.541 cm.
0a68bc69 1164 // So pixelHeight = (pointSize / 72) (inches) * 2.541 (for cm) * yPixelsPerCM (for pixels)
c2ff68d3
JS
1165 // In fact pointSize is 10 * the normal point size so
1166 // divide by 10.
1167
15d5a947 1168 int pixelHeight = (int) ( (((float)pointSize) / 720.0) * 2.541 * (float) yPixelsPerCM) ;
c2ff68d3
JS
1169
1170 // An alternative: assume that the screen is 72 dpi.
0a68bc69
JS
1171 //int pixelHeight = (int) (((float)pointSize / 720.0) * 72.0) ;
1172 //int pixelHeight = (int) ((float)pointSize / 10.0) ;
2b5f62a0 1173
16d865f7
JS
1174 GR_LOGFONT logFont;
1175 logFont.lfHeight = pixelHeight;
1176 logFont.lfWidth = 0;
1177 logFont.lfEscapement = 0;
1178 logFont.lfOrientation = 0;
c2ff68d3 1179 logFont.lfWeight = xweight;
16d865f7
JS
1180 logFont.lfItalic = (style == wxNORMAL ? 0 : 1) ;
1181 logFont.lfUnderline = 0;
1182 logFont.lfStrikeOut = 0;
1183 logFont.lfCharSet = MWLF_CHARSET_DEFAULT; // TODO: select appropriate one
1184 logFont.lfOutPrecision = MWLF_TYPE_DEFAULT;
1185 logFont.lfClipPrecision = 0; // Not used
1186 logFont.lfRoman = (family == wxROMAN ? 1 : 0) ;
1187 logFont.lfSerif = (family == wxSWISS ? 0 : 1) ;
1188 logFont.lfSansSerif = !logFont.lfSerif ;
1189 logFont.lfModern = (family == wxMODERN ? 1 : 0) ;
1190 logFont.lfProportional = (family == wxTELETYPE ? 0 : 1) ;
1191 logFont.lfOblique = 0;
1192 logFont.lfSmallCaps = 0;
1193 logFont.lfPitch = 0; // 0 = default
1194 strcpy(logFont.lfFaceName, facename.c_str());
1195
1196 XFontStruct* fontInfo = (XFontStruct*) malloc(sizeof(XFontStruct));
1197 fontInfo->fid = GrCreateFont((GR_CHAR*) facename.c_str(), pixelHeight, & logFont);
1198 GrGetFontInfo(fontInfo->fid, & fontInfo->info);
1199 return (wxNativeFont) fontInfo;
2b5f62a0 1200
16d865f7 1201#else
7beba2fc 1202 wxString fontSpec;
55034339 1203 if (!facename.empty())
7beba2fc
VZ
1204 {
1205 fontSpec.Printf(wxT("-*-%s-*-*-normal-*-*-*-*-*-*-*-*-*"),
1206 facename.c_str());
1207
1208 if ( wxTestFontSpec(fontSpec) )
1209 {
1210 xfamily = facename;
1211 }
1212 //else: no such family, use default one instead
1213 }
1214
1215 wxString xstyle;
1216 switch (style)
1217 {
f9dbf34f
VZ
1218 case wxSLANT:
1219 fontSpec.Printf(wxT("-*-%s-*-o-*-*-*-*-*-*-*-*-*-*"),
1220 xfamily.c_str());
1221 if ( wxTestFontSpec(fontSpec) )
1222 {
1223 xstyle = wxT("o");
1224 break;
1225 }
1226 // fall through - try wxITALIC now
1227
1228 case wxITALIC:
1229 fontSpec.Printf(wxT("-*-%s-*-i-*-*-*-*-*-*-*-*-*-*"),
1230 xfamily.c_str());
1231 if ( wxTestFontSpec(fontSpec) )
1232 {
1233 xstyle = wxT("i");
1234 }
1235 else if ( style == wxITALIC ) // and not wxSLANT
1236 {
1237 // try wxSLANT
1238 fontSpec.Printf(wxT("-*-%s-*-o-*-*-*-*-*-*-*-*-*-*"),
1239 xfamily.c_str());
1240 if ( wxTestFontSpec(fontSpec) )
1241 {
1242 xstyle = wxT("o");
1243 }
1244 else
1245 {
1246 // no italic, no slant - leave default
1247 xstyle = wxT("*");
1248 }
1249 }
1250 break;
1251
1252 default:
1253 wxFAIL_MSG(_T("unknown font style"));
1254 // fall back to normal
1255
1256 case wxNORMAL:
1257 xstyle = wxT("r");
1258 break;
7beba2fc
VZ
1259 }
1260
1261 wxString xweight;
1262 switch (weight)
1263 {
1264 case wxBOLD:
1265 {
1266 fontSpec.Printf(wxT("-*-%s-bold-*-*-*-*-*-*-*-*-*-*-*"),
1267 xfamily.c_str());
1268 if ( wxTestFontSpec(fontSpec) )
1269 {
1270 xweight = wxT("bold");
1271 break;
1272 }
1273 fontSpec.Printf(wxT("-*-%s-heavy-*-*-*-*-*-*-*-*-*-*-*"),
1274 xfamily.c_str());
1275 if ( wxTestFontSpec(fontSpec) )
1276 {
1277 xweight = wxT("heavy");
1278 break;
1279 }
1280 fontSpec.Printf(wxT("-*-%s-extrabold-*-*-*-*-*-*-*-*-*-*-*"),
1281 xfamily.c_str());
1282 if ( wxTestFontSpec(fontSpec) )
1283 {
1284 xweight = wxT("extrabold");
1285 break;
1286 }
1287 fontSpec.Printf(wxT("-*-%s-demibold-*-*-*-*-*-*-*-*-*-*-*"),
1288 xfamily.c_str());
1289 if ( wxTestFontSpec(fontSpec) )
1290 {
1291 xweight = wxT("demibold");
1292 break;
1293 }
1294 fontSpec.Printf(wxT("-*-%s-black-*-*-*-*-*-*-*-*-*-*-*"),
1295 xfamily.c_str());
1296 if ( wxTestFontSpec(fontSpec) )
1297 {
1298 xweight = wxT("black");
1299 break;
1300 }
1301 fontSpec.Printf(wxT("-*-%s-ultrablack-*-*-*-*-*-*-*-*-*-*-*"),
1302 xfamily.c_str());
1303 if ( wxTestFontSpec(fontSpec) )
1304 {
1305 xweight = wxT("ultrablack");
1306 break;
1307 }
1308 }
1309 break;
1310 case wxLIGHT:
1311 {
1312 fontSpec.Printf(wxT("-*-%s-light-*-*-*-*-*-*-*-*-*-*-*"),
1313 xfamily.c_str());
1314 if ( wxTestFontSpec(fontSpec) )
1315 {
1316 xweight = wxT("light");
1317 break;
1318 }
1319 fontSpec.Printf(wxT("-*-%s-thin-*-*-*-*-*-*-*-*-*-*-*"),
1320 xfamily.c_str());
1321 if ( wxTestFontSpec(fontSpec) )
1322 {
1323 xweight = wxT("thin");
1324 break;
1325 }
1326 }
1327 break;
1328 case wxNORMAL:
1329 {
1330 fontSpec.Printf(wxT("-*-%s-medium-*-*-*-*-*-*-*-*-*-*-*"),
1331 xfamily.c_str());
1332 if ( wxTestFontSpec(fontSpec) )
1333 {
1334 xweight = wxT("medium");
1335 break;
1336 }
1337 fontSpec.Printf(wxT("-*-%s-normal-*-*-*-*-*-*-*-*-*-*-*"),
1338 xfamily.c_str());
1339 if ( wxTestFontSpec(fontSpec) )
1340 {
1341 xweight = wxT("normal");
1342 break;
1343 }
1344 fontSpec.Printf(wxT("-*-%s-regular-*-*-*-*-*-*-*-*-*-*-*"),
1345 xfamily.c_str());
1346 if ( wxTestFontSpec(fontSpec) )
1347 {
1348 xweight = wxT("regular");
1349 break;
1350 }
1351 xweight = wxT("*");
1352 }
1353 break;
1354 default: xweight = wxT("*"); break;
1355 }
1356
f139dfe8
VZ
1357 // if pointSize is -1, don't specify any
1358 wxString sizeSpec;
73b0423d 1359 if ( pointSize == -1 )
f139dfe8
VZ
1360 {
1361 sizeSpec = _T('*');
1362 }
1363 else
1364 {
1365 sizeSpec.Printf(_T("%d"), pointSize);
1366 }
1367
7beba2fc 1368 // construct the X font spec from our data
f139dfe8 1369 fontSpec.Printf(wxT("-*-%s-%s-%s-normal-*-*-%s-*-*-*-*-%s-%s"),
7beba2fc 1370 xfamily.c_str(), xweight.c_str(), xstyle.c_str(),
f139dfe8 1371 sizeSpec.c_str(), xregistry.c_str(), xencoding.c_str());
7beba2fc 1372
30764ab5
VZ
1373 if( xFontName )
1374 *xFontName = fontSpec;
1375
7beba2fc 1376 return wxLoadFont(fontSpec);
16d865f7
JS
1377#endif
1378 // wxUSE_NANOX
7beba2fc
VZ
1379}
1380
2e0e025e
RR
1381// ----------------------------------------------------------------------------
1382// wxFontModule
1383// ----------------------------------------------------------------------------
1384
1385class wxFontModule : public wxModule
1386{
1387public:
1388 bool OnInit();
1389 void OnExit();
1390
1391private:
1392 DECLARE_DYNAMIC_CLASS(wxFontModule)
1393};
1394
1395IMPLEMENT_DYNAMIC_CLASS(wxFontModule, wxModule)
1396
1397bool wxFontModule::OnInit()
1398{
1399 g_fontHash = new wxHashTable( wxKEY_STRING );
1400
55034339 1401 return true;
2e0e025e
RR
1402}
1403
1404void wxFontModule::OnExit()
1405{
1406 delete g_fontHash;
1407
1408 g_fontHash = (wxHashTable *)NULL;
1409}
db16cab4 1410
2b5f62a0 1411#endif // GTK 2.0/1.x