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