]> git.saurik.com Git - wxWidgets.git/blame - src/unix/fontutil.cpp
added test for env var expansion
[wxWidgets.git] / src / unix / fontutil.cpp
CommitLineData
7beba2fc
VZ
1/////////////////////////////////////////////////////////////////////////////
2// Name: unix/fontutil.cpp
3// Purpose: Font helper functions for X11 (GDK/X)
4// Author: Vadim Zeitlin
5// Modified by:
6// Created: 05.11.99
7// RCS-ID: $Id$
8// Copyright: (c) Vadim Zeitlin
9// Licence: wxWindows license
10/////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
20#ifdef __GNUG__
21 #pragma implementation "fontutil.h"
22#endif
23
24// For compilers that support precompilation, includes "wx.h".
25#include "wx/wxprec.h"
26
27#ifdef __BORLANDC__
28 #pragma hdrstop
29#endif
30
31#ifndef WX_PRECOMP
32#endif // PCH
33
db16cab4
RR
34#include "wx/fontutil.h"
35#include "wx/fontmap.h"
36#include "wx/tokenzr.h"
37#include "wx/hash.h"
38#include "wx/module.h"
39
40#ifdef __WXGTK20__
41
42#include "wx/gtk/private.h"
43
44// ----------------------------------------------------------------------------
45// wxNativeFontInfo
46// ----------------------------------------------------------------------------
47
48void wxNativeFontInfo::Init()
49{
50 description = NULL;
51}
52
53int wxNativeFontInfo::GetPointSize() const
54{
55 return pango_font_description_get_size( description ) / PANGO_SCALE;
56}
57
58wxFontStyle wxNativeFontInfo::GetStyle() const
59{
60 wxFontStyle m_style = wxFONTSTYLE_NORMAL;
61
62 switch (pango_font_description_get_style( description ))
63 {
64 case PANGO_STYLE_NORMAL:
65 m_style = wxFONTSTYLE_NORMAL;
66 break;
67 case PANGO_STYLE_ITALIC:
68 m_style = wxFONTSTYLE_ITALIC;
69 break;
70 case PANGO_STYLE_OBLIQUE:
71 m_style = wxFONTSTYLE_SLANT;
72 break;
73 }
74
75 return m_style;
76}
77
78wxFontWeight wxNativeFontInfo::GetWeight() const
79{
80 wxFontWeight m_weight = wxFONTWEIGHT_NORMAL;
81
82 switch (pango_font_description_get_weight( description ))
83 {
84 case PANGO_WEIGHT_ULTRALIGHT:
85 m_weight = wxFONTWEIGHT_LIGHT;
86 break;
87 case PANGO_WEIGHT_LIGHT:
88 m_weight = wxFONTWEIGHT_LIGHT;
89 break;
90 case PANGO_WEIGHT_NORMAL:
91 m_weight = wxFONTWEIGHT_NORMAL;
92 break;
93 case PANGO_WEIGHT_BOLD:
94 m_weight = wxFONTWEIGHT_BOLD;
95 break;
96 case PANGO_WEIGHT_ULTRABOLD:
97 m_weight = wxFONTWEIGHT_BOLD;
98 break;
99 case PANGO_WEIGHT_HEAVY:
100 m_weight = wxFONTWEIGHT_BOLD;
101 break;
102 }
103
104 return m_weight;
105}
106
107bool wxNativeFontInfo::GetUnderlined() const
108{
109 return FALSE;
110}
111
112wxString wxNativeFontInfo::GetFaceName() const
113{
114 wxString tmp = wxGTK_CONV_BACK( pango_font_description_get_family( description ) );
115
116 return tmp;
117}
118
119wxFontFamily wxNativeFontInfo::GetFamily() const
120{
121 return wxFONTFAMILY_SWISS;
122}
123
124wxFontEncoding wxNativeFontInfo::GetEncoding() const
125{
126 return wxFONTENCODING_SYSTEM;
127}
128
129bool wxNativeFontInfo::FromString(const wxString& s)
130{
131 if (description)
132 pango_font_description_free( description );
133
134 description = pango_font_description_from_string( wxGTK_CONV( s ) );
135
136 return TRUE;
137}
138
139wxString wxNativeFontInfo::ToString() const
140{
141 wxString tmp = wxGTK_CONV_BACK( pango_font_description_to_string( description ) );
142
143 return tmp;
144}
145
146bool wxNativeFontInfo::FromUserString(const wxString& s)
147{
148 return FromString( s );
149}
150
151wxString wxNativeFontInfo::ToUserString() const
152{
153 return ToString();
154}
155
156// ----------------------------------------------------------------------------
157// wxNativeEncodingInfo
158// ----------------------------------------------------------------------------
159
160bool wxNativeEncodingInfo::FromString(const wxString& s)
161{
162 return FALSE;
163}
164
165wxString wxNativeEncodingInfo::ToString() const
166{
167 return wxEmptyString;
168}
169
170bool wxTestFontEncoding(const wxNativeEncodingInfo& info)
171{
172 return TRUE;
173}
174
175bool wxGetNativeFontEncoding(wxFontEncoding encoding,
176 wxNativeEncodingInfo *info)
177{
178 return FALSE;
179}
180
181#else
182 // __WXGTK20__
183
79e4b627 184#ifdef __X__
4ea45e6b
VZ
185 #ifdef __VMS__
186 #pragma message disable nosimpint
187 #endif
188
189 #include <X11/Xlib.h>
190
191 #ifdef __VMS__
192 #pragma message enable nosimpint
193 #endif
79e4b627
VZ
194
195 #include "wx/utils.h" // for wxGetDisplay()
196#elif defined(__WXGTK__)
4ea45e6b
VZ
197 // we have to declare struct tm to avoid problems with first forward
198 // declaring it in C code (glib.h included from gdk.h does it) and then
199 // defining it when time.h is included from the headers below - this is
200 // known not to work at least with Sun CC 6.01
201 #include <time.h>
202
203 #include <gdk/gdk.h>
79e4b627
VZ
204#endif
205
2e0e025e
RR
206
207// ----------------------------------------------------------------------------
208// private data
209// ----------------------------------------------------------------------------
210
211static wxHashTable *g_fontHash = (wxHashTable*) NULL;
7beba2fc
VZ
212
213// ----------------------------------------------------------------------------
214// private functions
215// ----------------------------------------------------------------------------
216
217// define the functions to create and destroy native fonts for this toolkit
218#ifdef __X__
3fe34ed0 219 wxNativeFont wxLoadFont(const wxString& fontSpec)
7beba2fc
VZ
220 {
221 return XLoadQueryFont((Display *)wxGetDisplay(), fontSpec);
222 }
223
409d5a58 224 inline void wxFreeFont(wxNativeFont font)
7beba2fc 225 {
a5fc62a1 226 XFreeFont((Display *)wxGetDisplay(), (XFontStruct *)font);
7beba2fc
VZ
227 }
228#elif defined(__WXGTK__)
3fe34ed0 229 wxNativeFont wxLoadFont(const wxString& fontSpec)
7beba2fc 230 {
97d3f0ee 231 return gdk_font_load( wxConvertWX2MB(fontSpec) );
7beba2fc
VZ
232 }
233
409d5a58 234 inline void wxFreeFont(wxNativeFont font)
7beba2fc
VZ
235 {
236 gdk_font_unref(font);
237 }
238#else
239 #error "Unknown GUI toolkit"
240#endif
241
242static bool wxTestFontSpec(const wxString& fontspec);
243
244static wxNativeFont wxLoadQueryFont(int pointSize,
245 int family,
246 int style,
247 int weight,
248 bool underlined,
249 const wxString& facename,
250 const wxString& xregistry,
30764ab5
VZ
251 const wxString& xencoding,
252 wxString* xFontName);
7beba2fc
VZ
253
254// ============================================================================
255// implementation
256// ============================================================================
257
258// ----------------------------------------------------------------------------
259// wxNativeEncodingInfo
260// ----------------------------------------------------------------------------
261
262// convert to/from the string representation: format is
1e1d0be1 263// encodingid;registry;encoding[;facename]
7beba2fc
VZ
264bool wxNativeEncodingInfo::FromString(const wxString& s)
265{
6c49baf2 266 // use ";", not "-" because it may be part of encoding name
1e1d0be1 267 wxStringTokenizer tokenizer(s, _T(";"));
1e1d0be1
VS
268
269 wxString encid = tokenizer.GetNextToken();
270 long enc;
271 if ( !encid.ToLong(&enc) )
272 return FALSE;
273 encoding = (wxFontEncoding)enc;
7beba2fc
VZ
274
275 xregistry = tokenizer.GetNextToken();
276 if ( !xregistry )
277 return FALSE;
278
279 xencoding = tokenizer.GetNextToken();
280 if ( !xencoding )
281 return FALSE;
282
283 // ok even if empty
284 facename = tokenizer.GetNextToken();
285
286 return TRUE;
287}
288
289wxString wxNativeEncodingInfo::ToString() const
290{
291 wxString s;
1e1d0be1 292 s << (long)encoding << _T(';') << xregistry << _T(';') << xencoding;
7beba2fc
VZ
293 if ( !!facename )
294 {
1e1d0be1 295 s << _T(';') << facename;
7beba2fc
VZ
296 }
297
298 return s;
299}
300
ab5fe833
VZ
301// ----------------------------------------------------------------------------
302// wxNativeFontInfo
303// ----------------------------------------------------------------------------
304
305void wxNativeFontInfo::Init()
306{
409d5a58 307 m_isDefault = TRUE;
ab5fe833
VZ
308}
309
310bool wxNativeFontInfo::FromString(const wxString& s)
311{
312 wxStringTokenizer tokenizer(s, _T(";"));
313
314 // check the version
315 wxString token = tokenizer.GetNextToken();
316 if ( token != _T('0') )
317 return FALSE;
318
319 xFontName = tokenizer.GetNextToken();
320
321 // this should be the end
322 if ( tokenizer.HasMoreTokens() )
323 return FALSE;
324
325 return FromXFontName(xFontName);
326}
327
328wxString wxNativeFontInfo::ToString() const
329{
330 // 0 is the version
331 return wxString::Format(_T("%d;%s"), 0, GetXFontName().c_str());
332}
333
334bool wxNativeFontInfo::FromUserString(const wxString& s)
335{
336 return FromXFontName(s);
337}
338
339wxString wxNativeFontInfo::ToUserString() const
340{
341 return GetXFontName();
342}
343
409d5a58
VZ
344bool wxNativeFontInfo::HasElements() const
345{
346 // we suppose that the foundry is never empty, so if it is it means that we
347 // had never parsed the XLFD
348 return !fontElements[0].empty();
349}
350
53f6aab7
VZ
351wxString wxNativeFontInfo::GetXFontComponent(wxXLFDField field) const
352{
353 wxCHECK_MSG( field < wxXLFD_MAX, _T(""), _T("invalid XLFD field") );
354
409d5a58 355 if ( !HasElements() )
53f6aab7
VZ
356 {
357 // const_cast
358 if ( !((wxNativeFontInfo *)this)->FromXFontName(xFontName) )
359 return _T("");
360 }
361
362 return fontElements[field];
363}
364
295272bd 365bool wxNativeFontInfo::FromXFontName(const wxString& fontname)
ab5fe833
VZ
366{
367 // TODO: we should be able to handle the font aliases here, but how?
409d5a58
VZ
368 wxStringTokenizer tokenizer(fontname, _T("-"));
369
370 // skip the leading, usually empty field (font name registry)
371 if ( !tokenizer.HasMoreTokens() )
372 return FALSE;
373
374 (void)tokenizer.GetNextToken();
ab5fe833
VZ
375
376 for ( size_t n = 0; n < WXSIZEOF(fontElements); n++ )
377 {
378 if ( !tokenizer.HasMoreTokens() )
379 {
380 // not enough elements in the XLFD - or maybe an alias
381 return FALSE;
382 }
383
384 fontElements[n] = tokenizer.GetNextToken();
385 }
386
387 // this should be all
011ba5ed
VZ
388 if ( tokenizer.HasMoreTokens() )
389 return FALSE;
390
391 // we're initialized now
392 m_isDefault = FALSE;
393
394 return TRUE;
ab5fe833
VZ
395}
396
397wxString wxNativeFontInfo::GetXFontName() const
398{
399 if ( xFontName.empty() )
400 {
401 for ( size_t n = 0; n < WXSIZEOF(fontElements); n++ )
402 {
403 // replace the non specified elements with '*' except for the
404 // additional style which is usually just omitted
405 wxString elt = fontElements[n];
409d5a58 406 if ( elt.empty() && n != wxXLFD_ADDSTYLE )
ab5fe833
VZ
407 {
408 elt = _T('*');
409 }
410
411 // const_cast
412 ((wxNativeFontInfo *)this)->xFontName << _T('-') << elt;
413 }
414 }
415
416 return xFontName;
417}
418
409d5a58
VZ
419void
420wxNativeFontInfo::SetXFontComponent(wxXLFDField field, const wxString& value)
421{
422 wxCHECK_RET( field < wxXLFD_MAX, _T("invalid XLFD field") );
423
424 // this class should be initialized with a valid font spec first and only
425 // then the fields may be modified!
426 wxASSERT_MSG( !IsDefault(), _T("can't modify an uninitialized XLFD") );
427
428 if ( !HasElements() )
429 {
430 // const_cast
431 if ( !((wxNativeFontInfo *)this)->FromXFontName(xFontName) )
432 {
433 wxFAIL_MSG( _T("can't set font element for invalid XLFD") );
434
435 return;
436 }
437 }
438
439 fontElements[field] = value;
440
441 // invalidate the XFLD, it doesn't correspond to the font elements any more
442 xFontName.clear();
443}
444
445void wxNativeFontInfo::SetXFontName(const wxString& xFontName_)
446{
447 // invalidate the font elements, GetXFontComponent() will reparse the XLFD
448 fontElements[0].clear();
449
450 xFontName = xFontName_;
451
452 m_isDefault = FALSE;
453}
454
7beba2fc
VZ
455// ----------------------------------------------------------------------------
456// common functions
457// ----------------------------------------------------------------------------
458
459bool wxGetNativeFontEncoding(wxFontEncoding encoding,
460 wxNativeEncodingInfo *info)
461{
462 wxCHECK_MSG( info, FALSE, _T("bad pointer in wxGetNativeFontEncoding") );
463
464 if ( encoding == wxFONTENCODING_DEFAULT )
465 {
466 encoding = wxFont::GetDefaultEncoding();
467 }
468
469 switch ( encoding )
470 {
471 case wxFONTENCODING_ISO8859_1:
472 case wxFONTENCODING_ISO8859_2:
473 case wxFONTENCODING_ISO8859_3:
474 case wxFONTENCODING_ISO8859_4:
475 case wxFONTENCODING_ISO8859_5:
476 case wxFONTENCODING_ISO8859_6:
477 case wxFONTENCODING_ISO8859_7:
478 case wxFONTENCODING_ISO8859_8:
479 case wxFONTENCODING_ISO8859_9:
480 case wxFONTENCODING_ISO8859_10:
481 case wxFONTENCODING_ISO8859_11:
80a24267 482 case wxFONTENCODING_ISO8859_12:
7beba2fc
VZ
483 case wxFONTENCODING_ISO8859_13:
484 case wxFONTENCODING_ISO8859_14:
485 case wxFONTENCODING_ISO8859_15:
486 {
487 int cp = encoding - wxFONTENCODING_ISO8859_1 + 1;
488 info->xregistry = wxT("iso8859");
489 info->xencoding.Printf(wxT("%d"), cp);
490 }
491 break;
492
bb84929e 493 case wxFONTENCODING_UTF8:
5707316c 494 info->xregistry = wxT("iso10646");
bb84929e
VZ
495 info->xencoding = wxT("*");
496 break;
497
7beba2fc
VZ
498 case wxFONTENCODING_KOI8:
499 info->xregistry = wxT("koi8");
500
5707316c 501 // we don't make distinction between koi8-r, koi8-u and koi8-ru (so far)
7beba2fc
VZ
502 info->xencoding = wxT("*");
503 break;
504
505 case wxFONTENCODING_CP1250:
506 case wxFONTENCODING_CP1251:
507 case wxFONTENCODING_CP1252:
508 case wxFONTENCODING_CP1253:
509 case wxFONTENCODING_CP1254:
510 case wxFONTENCODING_CP1255:
511 case wxFONTENCODING_CP1256:
512 case wxFONTENCODING_CP1257:
513 {
514 int cp = encoding - wxFONTENCODING_CP1250 + 1250;
515 info->xregistry = wxT("microsoft");
516 info->xencoding.Printf(wxT("cp%d"), cp);
517 }
518 break;
519
520 case wxFONTENCODING_SYSTEM:
521 info->xregistry =
81c67e27 522 info->xencoding = wxT("*");
7beba2fc
VZ
523 break;
524
525 default:
526 // don't know how to translate this encoding into X fontspec
527 return FALSE;
528 }
529
ab5fe833 530 info->encoding = encoding;
6b0eebc5 531
7beba2fc
VZ
532 return TRUE;
533}
534
535bool wxTestFontEncoding(const wxNativeEncodingInfo& info)
536{
537 wxString fontspec;
538 fontspec.Printf(_T("-*-%s-*-*-*-*-*-*-*-*-*-*-%s-%s"),
539 !info.facename ? _T("*") : info.facename.c_str(),
540 info.xregistry.c_str(),
541 info.xencoding.c_str());
542
543 return wxTestFontSpec(fontspec);
544}
545
546// ----------------------------------------------------------------------------
547// X-specific functions
548// ----------------------------------------------------------------------------
549
550wxNativeFont wxLoadQueryNearestFont(int pointSize,
551 int family,
552 int style,
553 int weight,
554 bool underlined,
555 const wxString &facename,
30764ab5
VZ
556 wxFontEncoding encoding,
557 wxString* xFontName)
7beba2fc 558{
97d3f0ee
VZ
559 if ( encoding == wxFONTENCODING_DEFAULT )
560 {
561 encoding = wxFont::GetDefaultEncoding();
562 }
563
7beba2fc
VZ
564 // first determine the encoding - if the font doesn't exist at all in this
565 // encoding, it's useless to do all other approximations (i.e. size,
566 // family &c don't matter much)
567 wxNativeEncodingInfo info;
97d3f0ee 568 if ( encoding == wxFONTENCODING_SYSTEM )
81c67e27
RR
569 {
570 // This will always work so we don't test to save time
571 wxGetNativeFontEncoding(wxFONTENCODING_SYSTEM, &info);
572 }
573 else
7beba2fc 574 {
81c67e27
RR
575 if ( !wxGetNativeFontEncoding(encoding, &info) ||
576 !wxTestFontEncoding(info) )
7beba2fc 577 {
1e6feb95 578#if wxUSE_FONTMAP
142b3bc2 579 if ( !wxFontMapper::Get()->GetAltForEncoding(encoding, &info) )
1e6feb95 580#endif // wxUSE_FONTMAP
81c67e27
RR
581 {
582 // unspported encoding - replace it with the default
583 //
584 // NB: we can't just return 0 from here because wxGTK code doesn't
585 // check for it (i.e. it supposes that we'll always succeed),
586 // so it would provoke a crash
587 wxGetNativeFontEncoding(wxFONTENCODING_SYSTEM, &info);
588 }
97d3f0ee 589 }
7beba2fc 590 }
6c49baf2 591
81c67e27 592 // OK, we have the correct xregistry/xencoding in info structure
30764ab5
VZ
593 wxNativeFont font = 0;
594
595 // if we already have the X font name, try to use it
596 if( xFontName && !xFontName->IsEmpty() )
6c49baf2
VZ
597 {
598 //
599 // Make sure point size is correct for scale factor.
600 //
601 wxStringTokenizer tokenizer(*xFontName, _T("-"), wxTOKEN_RET_DELIMS);
602 wxString newFontName;
603
604 for(int i = 0; i < 8; i++)
605 newFontName += tokenizer.NextToken();
606
607 (void) tokenizer.NextToken();
608
401eb3de 609 newFontName += wxString::Format(wxT("%d-"), pointSize);
6c49baf2
VZ
610
611 while(tokenizer.HasMoreTokens())
612 newFontName += tokenizer.GetNextToken();
613
614 font = wxLoadFont(newFontName);
615
616 if(font)
617 *xFontName = newFontName;
618 }
30764ab5 619
f139dfe8 620 // try to load exactly the font requested first
30764ab5 621 if( !font )
f139dfe8 622 {
30764ab5 623 font = wxLoadQueryFont( pointSize, family, style, weight,
f139dfe8 624 underlined, facename,
30764ab5
VZ
625 info.xregistry, info.xencoding,
626 xFontName );
f139dfe8 627 }
7beba2fc
VZ
628
629 if ( !font )
630 {
631 // search up and down by stepsize 10
632 int max_size = pointSize + 20 * (1 + (pointSize/180));
633 int min_size = pointSize - 20 * (1 + (pointSize/180));
634
635 int i;
636
637 // Search for smaller size (approx.)
638 for ( i = pointSize - 10; !font && i >= 10 && i >= min_size; i -= 10 )
639 {
640 font = wxLoadQueryFont(i, family, style, weight, underlined,
30764ab5
VZ
641 facename, info.xregistry, info.xencoding,
642 xFontName);
7beba2fc
VZ
643 }
644
645 // Search for larger size (approx.)
646 for ( i = pointSize + 10; !font && i <= max_size; i += 10 )
647 {
648 font = wxLoadQueryFont(i, family, style, weight, underlined,
30764ab5
VZ
649 facename, info.xregistry, info.xencoding,
650 xFontName);
7beba2fc
VZ
651 }
652
653 // Try default family
654 if ( !font && family != wxDEFAULT )
655 {
656 font = wxLoadQueryFont(pointSize, wxDEFAULT, style, weight,
657 underlined, facename,
30764ab5
VZ
658 info.xregistry, info.xencoding,
659 xFontName );
7beba2fc
VZ
660 }
661
f139dfe8
VZ
662 // ignore size, family, style and weight but try to find font with the
663 // given facename and encoding
7beba2fc
VZ
664 if ( !font )
665 {
666 font = wxLoadQueryFont(120, wxDEFAULT, wxNORMAL, wxNORMAL,
667 underlined, facename,
30764ab5
VZ
668 info.xregistry, info.xencoding,
669 xFontName);
7beba2fc 670
f139dfe8
VZ
671 // ignore family as well
672 if ( !font )
673 {
674 font = wxLoadQueryFont(120, wxDEFAULT, wxNORMAL, wxNORMAL,
675 underlined, wxEmptyString,
676 info.xregistry, info.xencoding,
677 xFontName);
678
679 // if it still failed, try to get the font of any size but
680 // with the requested encoding: this can happen if the
681 // encoding is only available in one size which happens to be
682 // different from 120
683 if ( !font )
684 {
685 font = wxLoadQueryFont(-1, wxDEFAULT, wxNORMAL, wxNORMAL,
686 FALSE, wxEmptyString,
687 info.xregistry, info.xencoding,
688 xFontName);
689
690 // this should never happen as we had tested for it in the
691 // very beginning, but if it does, do return something non
692 // NULL or we'd crash in wxFont code
693 if ( !font )
694 {
695 wxFAIL_MSG( _T("this encoding should be available!") );
696
697 font = wxLoadQueryFont(-1,
698 wxDEFAULT, wxNORMAL, wxNORMAL,
699 FALSE, wxEmptyString,
700 _T("*"), _T("*"),
701 xFontName);
702 }
703 }
704 }
7beba2fc
VZ
705 }
706 }
707
708 return font;
709}
710
711// ----------------------------------------------------------------------------
712// private functions
713// ----------------------------------------------------------------------------
714
715// returns TRUE if there are any fonts matching this font spec
716static bool wxTestFontSpec(const wxString& fontspec)
717{
97d3f0ee
VZ
718 // some X servers will fail to load this font because there are too many
719 // matches so we must test explicitly for this
720 if ( fontspec == _T("-*-*-*-*-*-*-*-*-*-*-*-*-*-*") )
721 {
722 return TRUE;
723 }
724
2e0e025e
RR
725 wxNativeFont test = (wxNativeFont) g_fontHash->Get( fontspec );
726 if (test)
727 {
2e0e025e
RR
728 return TRUE;
729 }
730
731 test = wxLoadFont(fontspec);
732 g_fontHash->Put( fontspec, (wxObject*) test );
6c49baf2 733
7beba2fc
VZ
734 if ( test )
735 {
736 wxFreeFont(test);
737
738 return TRUE;
739 }
740 else
741 {
742 return FALSE;
743 }
744}
745
746static wxNativeFont wxLoadQueryFont(int pointSize,
747 int family,
748 int style,
749 int weight,
750 bool WXUNUSED(underlined),
751 const wxString& facename,
752 const wxString& xregistry,
30764ab5
VZ
753 const wxString& xencoding,
754 wxString* xFontName)
7beba2fc
VZ
755{
756 wxString xfamily;
757 switch (family)
758 {
759 case wxDECORATIVE: xfamily = wxT("lucida"); break;
760 case wxROMAN: xfamily = wxT("times"); break;
761 case wxMODERN: xfamily = wxT("courier"); break;
762 case wxSWISS: xfamily = wxT("helvetica"); break;
763 case wxTELETYPE: xfamily = wxT("lucidatypewriter"); break;
764 case wxSCRIPT: xfamily = wxT("utopia"); break;
765 default: xfamily = wxT("*");
766 }
16d865f7 767#if wxUSE_NANOX
c2ff68d3
JS
768 int xweight;
769 switch (weight)
770 {
771 case wxBOLD:
772 {
773 xweight = MWLF_WEIGHT_BOLD;
774 break;
775 }
776 case wxLIGHT:
777 {
778 xweight = MWLF_WEIGHT_LIGHT;
779 break;
780 }
781 case wxNORMAL:
782 {
783 xweight = MWLF_WEIGHT_NORMAL;
784 break;
785 }
786
787 default:
788 {
789 xweight = MWLF_WEIGHT_DEFAULT;
790 break;
791 }
792 }
16d865f7
JS
793 GR_SCREEN_INFO screenInfo;
794 GrGetScreenInfo(& screenInfo);
795
796 int yPixelsPerCM = screenInfo.ydpcm;
797
0a68bc69 798 // A point is 1/72 of an inch.
16d865f7 799 // An inch is 2.541 cm.
0a68bc69 800 // So pixelHeight = (pointSize / 72) (inches) * 2.541 (for cm) * yPixelsPerCM (for pixels)
c2ff68d3
JS
801 // In fact pointSize is 10 * the normal point size so
802 // divide by 10.
803
15d5a947 804 int pixelHeight = (int) ( (((float)pointSize) / 720.0) * 2.541 * (float) yPixelsPerCM) ;
c2ff68d3
JS
805
806 // An alternative: assume that the screen is 72 dpi.
0a68bc69
JS
807 //int pixelHeight = (int) (((float)pointSize / 720.0) * 72.0) ;
808 //int pixelHeight = (int) ((float)pointSize / 10.0) ;
16d865f7
JS
809
810 GR_LOGFONT logFont;
811 logFont.lfHeight = pixelHeight;
812 logFont.lfWidth = 0;
813 logFont.lfEscapement = 0;
814 logFont.lfOrientation = 0;
c2ff68d3 815 logFont.lfWeight = xweight;
16d865f7
JS
816 logFont.lfItalic = (style == wxNORMAL ? 0 : 1) ;
817 logFont.lfUnderline = 0;
818 logFont.lfStrikeOut = 0;
819 logFont.lfCharSet = MWLF_CHARSET_DEFAULT; // TODO: select appropriate one
820 logFont.lfOutPrecision = MWLF_TYPE_DEFAULT;
821 logFont.lfClipPrecision = 0; // Not used
822 logFont.lfRoman = (family == wxROMAN ? 1 : 0) ;
823 logFont.lfSerif = (family == wxSWISS ? 0 : 1) ;
824 logFont.lfSansSerif = !logFont.lfSerif ;
825 logFont.lfModern = (family == wxMODERN ? 1 : 0) ;
826 logFont.lfProportional = (family == wxTELETYPE ? 0 : 1) ;
827 logFont.lfOblique = 0;
828 logFont.lfSmallCaps = 0;
829 logFont.lfPitch = 0; // 0 = default
830 strcpy(logFont.lfFaceName, facename.c_str());
831
832 XFontStruct* fontInfo = (XFontStruct*) malloc(sizeof(XFontStruct));
833 fontInfo->fid = GrCreateFont((GR_CHAR*) facename.c_str(), pixelHeight, & logFont);
834 GrGetFontInfo(fontInfo->fid, & fontInfo->info);
835 return (wxNativeFont) fontInfo;
836
837#else
7beba2fc
VZ
838 wxString fontSpec;
839 if (!facename.IsEmpty())
840 {
841 fontSpec.Printf(wxT("-*-%s-*-*-normal-*-*-*-*-*-*-*-*-*"),
842 facename.c_str());
843
844 if ( wxTestFontSpec(fontSpec) )
845 {
846 xfamily = facename;
847 }
848 //else: no such family, use default one instead
849 }
850
851 wxString xstyle;
852 switch (style)
853 {
f9dbf34f
VZ
854 case wxSLANT:
855 fontSpec.Printf(wxT("-*-%s-*-o-*-*-*-*-*-*-*-*-*-*"),
856 xfamily.c_str());
857 if ( wxTestFontSpec(fontSpec) )
858 {
859 xstyle = wxT("o");
860 break;
861 }
862 // fall through - try wxITALIC now
863
864 case wxITALIC:
865 fontSpec.Printf(wxT("-*-%s-*-i-*-*-*-*-*-*-*-*-*-*"),
866 xfamily.c_str());
867 if ( wxTestFontSpec(fontSpec) )
868 {
869 xstyle = wxT("i");
870 }
871 else if ( style == wxITALIC ) // and not wxSLANT
872 {
873 // try wxSLANT
874 fontSpec.Printf(wxT("-*-%s-*-o-*-*-*-*-*-*-*-*-*-*"),
875 xfamily.c_str());
876 if ( wxTestFontSpec(fontSpec) )
877 {
878 xstyle = wxT("o");
879 }
880 else
881 {
882 // no italic, no slant - leave default
883 xstyle = wxT("*");
884 }
885 }
886 break;
887
888 default:
889 wxFAIL_MSG(_T("unknown font style"));
890 // fall back to normal
891
892 case wxNORMAL:
893 xstyle = wxT("r");
894 break;
7beba2fc
VZ
895 }
896
897 wxString xweight;
898 switch (weight)
899 {
900 case wxBOLD:
901 {
902 fontSpec.Printf(wxT("-*-%s-bold-*-*-*-*-*-*-*-*-*-*-*"),
903 xfamily.c_str());
904 if ( wxTestFontSpec(fontSpec) )
905 {
906 xweight = wxT("bold");
907 break;
908 }
909 fontSpec.Printf(wxT("-*-%s-heavy-*-*-*-*-*-*-*-*-*-*-*"),
910 xfamily.c_str());
911 if ( wxTestFontSpec(fontSpec) )
912 {
913 xweight = wxT("heavy");
914 break;
915 }
916 fontSpec.Printf(wxT("-*-%s-extrabold-*-*-*-*-*-*-*-*-*-*-*"),
917 xfamily.c_str());
918 if ( wxTestFontSpec(fontSpec) )
919 {
920 xweight = wxT("extrabold");
921 break;
922 }
923 fontSpec.Printf(wxT("-*-%s-demibold-*-*-*-*-*-*-*-*-*-*-*"),
924 xfamily.c_str());
925 if ( wxTestFontSpec(fontSpec) )
926 {
927 xweight = wxT("demibold");
928 break;
929 }
930 fontSpec.Printf(wxT("-*-%s-black-*-*-*-*-*-*-*-*-*-*-*"),
931 xfamily.c_str());
932 if ( wxTestFontSpec(fontSpec) )
933 {
934 xweight = wxT("black");
935 break;
936 }
937 fontSpec.Printf(wxT("-*-%s-ultrablack-*-*-*-*-*-*-*-*-*-*-*"),
938 xfamily.c_str());
939 if ( wxTestFontSpec(fontSpec) )
940 {
941 xweight = wxT("ultrablack");
942 break;
943 }
944 }
945 break;
946 case wxLIGHT:
947 {
948 fontSpec.Printf(wxT("-*-%s-light-*-*-*-*-*-*-*-*-*-*-*"),
949 xfamily.c_str());
950 if ( wxTestFontSpec(fontSpec) )
951 {
952 xweight = wxT("light");
953 break;
954 }
955 fontSpec.Printf(wxT("-*-%s-thin-*-*-*-*-*-*-*-*-*-*-*"),
956 xfamily.c_str());
957 if ( wxTestFontSpec(fontSpec) )
958 {
959 xweight = wxT("thin");
960 break;
961 }
962 }
963 break;
964 case wxNORMAL:
965 {
966 fontSpec.Printf(wxT("-*-%s-medium-*-*-*-*-*-*-*-*-*-*-*"),
967 xfamily.c_str());
968 if ( wxTestFontSpec(fontSpec) )
969 {
970 xweight = wxT("medium");
971 break;
972 }
973 fontSpec.Printf(wxT("-*-%s-normal-*-*-*-*-*-*-*-*-*-*-*"),
974 xfamily.c_str());
975 if ( wxTestFontSpec(fontSpec) )
976 {
977 xweight = wxT("normal");
978 break;
979 }
980 fontSpec.Printf(wxT("-*-%s-regular-*-*-*-*-*-*-*-*-*-*-*"),
981 xfamily.c_str());
982 if ( wxTestFontSpec(fontSpec) )
983 {
984 xweight = wxT("regular");
985 break;
986 }
987 xweight = wxT("*");
988 }
989 break;
990 default: xweight = wxT("*"); break;
991 }
992
f139dfe8
VZ
993 // if pointSize is -1, don't specify any
994 wxString sizeSpec;
73b0423d 995 if ( pointSize == -1 )
f139dfe8
VZ
996 {
997 sizeSpec = _T('*');
998 }
999 else
1000 {
1001 sizeSpec.Printf(_T("%d"), pointSize);
1002 }
1003
7beba2fc 1004 // construct the X font spec from our data
f139dfe8 1005 fontSpec.Printf(wxT("-*-%s-%s-%s-normal-*-*-%s-*-*-*-*-%s-%s"),
7beba2fc 1006 xfamily.c_str(), xweight.c_str(), xstyle.c_str(),
f139dfe8 1007 sizeSpec.c_str(), xregistry.c_str(), xencoding.c_str());
7beba2fc 1008
30764ab5
VZ
1009 if( xFontName )
1010 *xFontName = fontSpec;
1011
7beba2fc 1012 return wxLoadFont(fontSpec);
16d865f7
JS
1013#endif
1014 // wxUSE_NANOX
7beba2fc
VZ
1015}
1016
2e0e025e
RR
1017// ----------------------------------------------------------------------------
1018// wxFontModule
1019// ----------------------------------------------------------------------------
1020
1021class wxFontModule : public wxModule
1022{
1023public:
1024 bool OnInit();
1025 void OnExit();
1026
1027private:
1028 DECLARE_DYNAMIC_CLASS(wxFontModule)
1029};
1030
1031IMPLEMENT_DYNAMIC_CLASS(wxFontModule, wxModule)
1032
1033bool wxFontModule::OnInit()
1034{
1035 g_fontHash = new wxHashTable( wxKEY_STRING );
1036
1037 return TRUE;
1038}
1039
1040void wxFontModule::OnExit()
1041{
1042 delete g_fontHash;
1043
1044 g_fontHash = (wxHashTable *)NULL;
1045}
db16cab4
RR
1046
1047#endif
1048 // not GTK 2.0