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