use facename in wxFontRefData::Init() in Unicode build (part of patch 1671684)
[wxWidgets.git] / src / x11 / font.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/x11/font.cpp
3 // Purpose: wxFont class
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 17/09/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // for compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
14
15 // ============================================================================
16 // declarations
17 // ============================================================================
18
19 // ----------------------------------------------------------------------------
20 // headers
21 // ----------------------------------------------------------------------------
22
23 #ifdef __VMS
24 #pragma message disable nosimpint
25 #include "wx/vms_x_fix.h"
26 #endif
27
28 #ifdef __VMS
29 #pragma message enable nosimpint
30 #endif
31
32 #include "wx/font.h"
33
34 #ifndef WX_PRECOMP
35 #include "wx/string.h"
36 #include "wx/utils.h" // for wxGetDisplay()
37 #include "wx/settings.h"
38 #include "wx/gdicmn.h"
39 #endif
40
41 #include "wx/fontutil.h" // for wxNativeFontInfo
42 #include "wx/tokenzr.h"
43 #include "wx/fontenum.h"
44
45 #include "wx/x11/private.h"
46
47 IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
48
49 // ----------------------------------------------------------------------------
50 // constants
51 // ----------------------------------------------------------------------------
52
53 // the default size (in points) for the fonts
54 static const int wxDEFAULT_FONT_SIZE = 12;
55
56
57 #if wxUSE_UNICODE
58 #else
59 // ----------------------------------------------------------------------------
60 // wxXFont
61 // ----------------------------------------------------------------------------
62
63 // For every wxFont, there must be a font for each display and scale requested.
64 // So these objects are stored in wxFontRefData::m_fonts
65 class wxXFont : public wxObject
66 {
67 public:
68 wxXFont();
69 virtual ~wxXFont();
70
71 WXFontStructPtr m_fontStruct; // XFontStruct
72 WXDisplay* m_display; // XDisplay
73 int m_scale; // Scale * 100
74 };
75
76 wxXFont::wxXFont()
77 {
78 m_fontStruct = (WXFontStructPtr) 0;
79 m_display = (WXDisplay*) 0;
80 m_scale = 100;
81 }
82
83 wxXFont::~wxXFont()
84 {
85 // Freeing the font used to produce a segv, but
86 // appears to be OK now (bug fix in X11?)
87 XFontStruct* fontStruct = (XFontStruct*) m_fontStruct;
88 XFreeFont((Display*) m_display, fontStruct);
89 }
90 #endif
91
92 // ----------------------------------------------------------------------------
93 // wxFontRefData
94 // ----------------------------------------------------------------------------
95
96 class wxFontRefData: public wxObjectRefData
97 {
98 friend class wxFont;
99
100 public:
101 wxFontRefData(int size = wxDEFAULT,
102 int family = wxDEFAULT,
103 int style = wxDEFAULT,
104 int weight = wxDEFAULT,
105 bool underlined = false,
106 const wxString& faceName = wxEmptyString,
107 wxFontEncoding encoding = wxFONTENCODING_DEFAULT);
108
109 // copy cstr
110 wxFontRefData(const wxFontRefData& data);
111
112 // from XFLD
113 wxFontRefData(const wxString& fontname);
114
115 // dstr
116 virtual ~wxFontRefData();
117
118 // setters: all of them also take care to modify m_nativeFontInfo if we
119 // have it so as to not lose the information not carried by our fields
120 void SetPointSize(int pointSize);
121 void SetFamily(int family);
122 void SetStyle(int style);
123 void SetWeight(int weight);
124 void SetUnderlined(bool underlined);
125 bool SetFaceName(const wxString& facename);
126 void SetEncoding(wxFontEncoding encoding);
127
128 void SetNoAntiAliasing( bool no = true ) { m_noAA = no; }
129 bool GetNoAntiAliasing() const { return m_noAA; }
130
131 // and this one also modifies all the other font data fields
132 void SetNativeFontInfo(const wxNativeFontInfo& info);
133
134 protected:
135 // common part of all ctors
136 void Init(int size,
137 int family,
138 int style,
139 int weight,
140 bool underlined,
141 const wxString& faceName,
142 wxFontEncoding encoding);
143
144 // set all fields from (already initialized and valid) m_nativeFontInfo
145 void InitFromNative();
146
147 // font attributes
148 int m_pointSize;
149 int m_family;
150 int m_style;
151 int m_weight;
152 bool m_underlined;
153 wxString m_faceName;
154 wxFontEncoding m_encoding; // Unused in Unicode mode
155 bool m_noAA; // No anti-aliasing
156
157 wxNativeFontInfo m_nativeFontInfo;
158
159 void ClearX11Fonts();
160
161 #if wxUSE_UNICODE
162 #else
163 // A list of wxXFonts
164 wxList m_fonts;
165 #endif
166 };
167
168 #define M_FONTDATA ((wxFontRefData*)m_refData)
169
170 // ----------------------------------------------------------------------------
171 // wxFontRefData
172 // ----------------------------------------------------------------------------
173
174 void wxFontRefData::Init(int pointSize,
175 int family,
176 int style,
177 int weight,
178 bool underlined,
179 const wxString& faceName,
180 wxFontEncoding encoding)
181 {
182 m_family = family == wxFONTFAMILY_DEFAULT ? wxFONTFAMILY_SWISS : family;
183
184 m_faceName = faceName;
185
186 // we accept both wxDEFAULT and wxNORMAL here - should we?
187 m_style = style == wxDEFAULT ? wxFONTSTYLE_NORMAL : style;
188 m_weight = weight == wxDEFAULT ? wxFONTWEIGHT_NORMAL : weight;
189
190 // and here, do we really want to forbid creation of the font of the size
191 // 90 (the value of wxDEFAULT)??
192 m_pointSize = pointSize == wxDEFAULT || pointSize == -1
193 ? wxDEFAULT_FONT_SIZE
194 : pointSize;
195
196 m_underlined = underlined;
197 m_encoding = encoding;
198
199 #if wxUSE_UNICODE
200 if ( m_nativeFontInfo.description )
201 pango_font_description_free(m_nativeFontInfo.description);
202
203 // Create native font info
204 m_nativeFontInfo.description = pango_font_description_new();
205
206 // if a face name is specified, use it if it's available, otherwise use
207 // just the family
208 if ( faceName.empty() || !wxFontEnumerator::IsValidFacename(faceName) )
209 {
210 // TODO: scan system for valid fonts matching the given family instead
211 // of hardcoding them here
212 switch ( m_family )
213 {
214 case wxFONTFAMILY_TELETYPE:
215 m_faceName = wxT("monospace");
216 break;
217
218 case wxFONTFAMILY_ROMAN:
219 m_faceName = wxT("serif");
220 break;
221
222 default:
223 m_faceName = wxT("sans");
224 }
225 }
226 else // specified face name is available, use it
227 {
228 m_faceName = faceName;
229 }
230
231 m_nativeFontInfo.SetFaceName(m_faceName);
232 m_nativeFontInfo.SetPointSize(m_pointSize);
233 m_nativeFontInfo.SetWeight((wxFontWeight)m_weight);
234 m_nativeFontInfo.SetStyle((wxFontStyle)m_style);
235 #endif // wxUSE_UNICODE
236 }
237
238 void wxFontRefData::InitFromNative()
239 {
240 m_noAA = false;
241
242 #if wxUSE_UNICODE
243 // Get native info
244 PangoFontDescription *desc = m_nativeFontInfo.description;
245
246 // init fields
247 m_faceName = wxGTK_CONV_BACK( pango_font_description_get_family( desc ) );
248
249 m_pointSize = pango_font_description_get_size( desc ) / PANGO_SCALE;
250
251 switch (pango_font_description_get_style( desc ))
252 {
253 case PANGO_STYLE_NORMAL:
254 m_style = wxFONTSTYLE_NORMAL;
255 break;
256 case PANGO_STYLE_ITALIC:
257 m_style = wxFONTSTYLE_ITALIC;
258 break;
259 case PANGO_STYLE_OBLIQUE:
260 m_style = wxFONTSTYLE_SLANT;
261 break;
262 }
263
264 // Not defined in some Pango versions
265 #define wxPANGO_WEIGHT_SEMIBOLD 600
266
267 switch (pango_font_description_get_weight( desc ))
268 {
269 case PANGO_WEIGHT_ULTRALIGHT:
270 case PANGO_WEIGHT_LIGHT:
271 m_weight = wxFONTWEIGHT_LIGHT;
272 break;
273
274 default:
275 wxFAIL_MSG(_T("unknown Pango font weight"));
276 // fall through
277
278 case PANGO_WEIGHT_NORMAL:
279 m_weight = wxFONTWEIGHT_NORMAL;
280 break;
281
282 case wxPANGO_WEIGHT_SEMIBOLD:
283 case PANGO_WEIGHT_BOLD:
284 case PANGO_WEIGHT_ULTRABOLD:
285 case PANGO_WEIGHT_HEAVY:
286 m_weight = wxFONTWEIGHT_BOLD;
287 break;
288 }
289
290 if (m_faceName == wxT("monospace"))
291 {
292 m_family = wxFONTFAMILY_TELETYPE;
293 }
294 else if (m_faceName == wxT("sans"))
295 {
296 m_family = wxFONTFAMILY_SWISS;
297 }
298 else
299 {
300 m_family = wxFONTFAMILY_UNKNOWN;
301 }
302
303 // Pango description are never underlined (?)
304 m_underlined = false;
305
306 // Cannot we choose that
307 m_encoding = wxFONTENCODING_SYSTEM;
308 #else // X11
309 // get the font parameters from the XLFD
310 // -------------------------------------
311
312 m_faceName = m_nativeFontInfo.GetXFontComponent(wxXLFD_FAMILY);
313
314 m_weight = wxFONTWEIGHT_NORMAL;
315
316 wxString w = m_nativeFontInfo.GetXFontComponent(wxXLFD_WEIGHT).Upper();
317 if ( !w.empty() && w != _T('*') )
318 {
319 // the test below catches all of BOLD, EXTRABOLD, DEMIBOLD, ULTRABOLD
320 // and BLACK
321 if ( ((w[0u] == _T('B') && (!wxStrcmp(w.c_str() + 1, wxT("OLD")) ||
322 !wxStrcmp(w.c_str() + 1, wxT("LACK"))))) ||
323 wxStrstr(w.c_str() + 1, _T("BOLD")) )
324 {
325 m_weight = wxFONTWEIGHT_BOLD;
326 }
327 else if ( w == _T("LIGHT") || w == _T("THIN") )
328 {
329 m_weight = wxFONTWEIGHT_LIGHT;
330 }
331 }
332
333 switch ( wxToupper(*m_nativeFontInfo.
334 GetXFontComponent(wxXLFD_SLANT).c_str()) )
335 {
336 case _T('I'): // italique
337 m_style = wxFONTSTYLE_ITALIC;
338 break;
339
340 case _T('O'): // oblique
341 m_style = wxFONTSTYLE_SLANT;
342 break;
343
344 default:
345 m_style = wxFONTSTYLE_NORMAL;
346 }
347
348 long ptSize;
349 if ( m_nativeFontInfo.GetXFontComponent(wxXLFD_POINTSIZE).ToLong(&ptSize) )
350 {
351 // size in XLFD is in 10 point units
352 m_pointSize = (int)(ptSize / 10);
353 }
354 else
355 {
356 m_pointSize = wxDEFAULT_FONT_SIZE;
357 }
358
359 // examine the spacing: if the font is monospaced, assume wxTELETYPE
360 // family for compatibility with the old code which used it instead of
361 // IsFixedWidth()
362 if ( m_nativeFontInfo.GetXFontComponent(wxXLFD_SPACING).Upper() == _T('M') )
363 {
364 m_family = wxFONTFAMILY_TELETYPE;
365 }
366 else // not monospaceed
367 {
368 // don't even try guessing it, it doesn't work for too many fonts
369 // anyhow
370 m_family = wxFONTFAMILY_UNKNOWN;
371 }
372
373 // X fonts are never underlined...
374 m_underlined = false;
375
376 // deal with font encoding
377 wxString
378 registry = m_nativeFontInfo.GetXFontComponent(wxXLFD_REGISTRY).Upper(),
379 encoding = m_nativeFontInfo.GetXFontComponent(wxXLFD_ENCODING).Upper();
380
381 if ( registry == _T("ISO8859") )
382 {
383 int cp;
384 if ( wxSscanf(encoding, wxT("%d"), &cp) == 1 )
385 {
386 m_encoding = (wxFontEncoding)(wxFONTENCODING_ISO8859_1 + cp - 1);
387 }
388 }
389 else if ( registry == _T("MICROSOFT") )
390 {
391 int cp;
392 if ( wxSscanf(encoding, wxT("cp125%d"), &cp) == 1 )
393 {
394 m_encoding = (wxFontEncoding)(wxFONTENCODING_CP1250 + cp);
395 }
396 }
397 else if ( registry == _T("KOI8") )
398 {
399 m_encoding = wxFONTENCODING_KOI8;
400 }
401 else // unknown encoding
402 {
403 // may be give a warning here? or use wxFontMapper?
404 m_encoding = wxFONTENCODING_SYSTEM;
405 }
406 #endif // Pango/X11
407 }
408
409 wxFontRefData::wxFontRefData( const wxFontRefData& data )
410 : wxObjectRefData()
411 {
412 m_pointSize = data.m_pointSize;
413 m_family = data.m_family;
414 m_style = data.m_style;
415 m_weight = data.m_weight;
416
417 m_underlined = data.m_underlined;
418
419 m_faceName = data.m_faceName;
420 m_encoding = data.m_encoding;
421
422 m_noAA = data.m_noAA;
423
424 m_nativeFontInfo = data.m_nativeFontInfo;
425 }
426
427 wxFontRefData::wxFontRefData(int size, int family, int style,
428 int weight, bool underlined,
429 const wxString& faceName,
430 wxFontEncoding encoding)
431 {
432 Init(size, family, style, weight, underlined, faceName, encoding);
433 }
434
435 wxFontRefData::wxFontRefData(const wxString& fontname)
436 {
437 // VZ: FromString() should really work in both cases, doesn't it?
438 #if wxUSE_UNICODE
439 m_nativeFontInfo.FromString( fontname );
440 #else
441 m_nativeFontInfo.SetXFontName(fontname);
442 #endif
443
444 InitFromNative();
445 }
446
447 void wxFontRefData::ClearX11Fonts()
448 {
449 #if wxUSE_UNICODE
450 #else
451 wxList::compatibility_iterator node = m_fonts.GetFirst();
452 while (node)
453 {
454 wxXFont* f = (wxXFont*) node->GetData();
455 delete f;
456 node = node->GetNext();
457 }
458 m_fonts.Clear();
459 #endif
460 }
461
462 wxFontRefData::~wxFontRefData()
463 {
464 ClearX11Fonts();
465 }
466
467 // ----------------------------------------------------------------------------
468 // wxFontRefData SetXXX()
469 // ----------------------------------------------------------------------------
470
471 void wxFontRefData::SetPointSize(int pointSize)
472 {
473 m_pointSize = pointSize;
474
475 #if wxUSE_UNICODE
476 // Get native info
477 PangoFontDescription *desc = m_nativeFontInfo.description;
478
479 pango_font_description_set_size( desc, m_pointSize * PANGO_SCALE );
480 #endif
481 }
482
483 void wxFontRefData::SetFamily(int family)
484 {
485 m_family = family;
486
487 // TODO: what are we supposed to do with m_nativeFontInfo here?
488 }
489
490 void wxFontRefData::SetStyle(int style)
491 {
492 m_style = style;
493
494 #if wxUSE_UNICODE
495 // Get native info
496 PangoFontDescription *desc = m_nativeFontInfo.description;
497
498 switch ( style )
499 {
500 case wxFONTSTYLE_ITALIC:
501 pango_font_description_set_style( desc, PANGO_STYLE_ITALIC );
502 break;
503 case wxFONTSTYLE_SLANT:
504 pango_font_description_set_style( desc, PANGO_STYLE_OBLIQUE );
505 break;
506 default:
507 wxFAIL_MSG( _T("unknown font style") );
508 // fall through
509 case wxFONTSTYLE_NORMAL:
510 pango_font_description_set_style( desc, PANGO_STYLE_NORMAL );
511 break;
512 }
513 #endif
514 }
515
516 void wxFontRefData::SetWeight(int weight)
517 {
518 m_weight = weight;
519 }
520
521 void wxFontRefData::SetUnderlined(bool underlined)
522 {
523 m_underlined = underlined;
524
525 // the XLFD doesn't have "underlined" field anyhow
526 }
527
528 bool wxFontRefData::SetFaceName(const wxString& facename)
529 {
530 m_faceName = facename;
531 return true;
532 }
533
534 void wxFontRefData::SetEncoding(wxFontEncoding encoding)
535 {
536 m_encoding = encoding;
537 }
538
539 void wxFontRefData::SetNativeFontInfo(const wxNativeFontInfo& info)
540 {
541 // previously cached fonts shouldn't be used
542 ClearX11Fonts();
543
544 m_nativeFontInfo = info;
545
546 // set all the other font parameters from the native font info
547 InitFromNative();
548 }
549
550 // ----------------------------------------------------------------------------
551 // wxFont
552 // ----------------------------------------------------------------------------
553
554 wxFont::wxFont(const wxNativeFontInfo& info)
555 {
556 #if wxUSE_UNICODE
557 Create( info.GetPointSize(),
558 info.GetFamily(),
559 info.GetStyle(),
560 info.GetWeight(),
561 info.GetUnderlined(),
562 info.GetFaceName(),
563 info.GetEncoding() );
564 #else
565 (void) Create(info.GetXFontName());
566 #endif
567 }
568
569 bool wxFont::Create(int pointSize,
570 int family,
571 int style,
572 int weight,
573 bool underlined,
574 const wxString& faceName,
575 wxFontEncoding encoding)
576 {
577 UnRef();
578
579 m_refData = new wxFontRefData(pointSize, family, style, weight,
580 underlined, faceName, encoding);
581
582 return true;
583 }
584
585 #if !wxUSE_UNICODE
586
587 bool wxFont::Create(const wxString& fontname, wxFontEncoding enc)
588 {
589 if( !fontname )
590 {
591 *this = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT);
592 return true;
593 }
594
595 m_refData = new wxFontRefData();
596
597 M_FONTDATA->m_nativeFontInfo.SetXFontName(fontname); // X font name
598
599 wxString tmp;
600
601 wxStringTokenizer tn( fontname, wxT("-") );
602
603 tn.GetNextToken(); // skip initial empty token
604 tn.GetNextToken(); // foundry
605
606
607 M_FONTDATA->m_faceName = tn.GetNextToken(); // family
608
609 tmp = tn.GetNextToken().MakeUpper(); // weight
610 if (tmp == wxT("BOLD")) M_FONTDATA->m_weight = wxBOLD;
611 if (tmp == wxT("BLACK")) M_FONTDATA->m_weight = wxBOLD;
612 if (tmp == wxT("EXTRABOLD")) M_FONTDATA->m_weight = wxBOLD;
613 if (tmp == wxT("DEMIBOLD")) M_FONTDATA->m_weight = wxBOLD;
614 if (tmp == wxT("ULTRABOLD")) M_FONTDATA->m_weight = wxBOLD;
615
616 if (tmp == wxT("LIGHT")) M_FONTDATA->m_weight = wxLIGHT;
617 if (tmp == wxT("THIN")) M_FONTDATA->m_weight = wxLIGHT;
618
619 tmp = tn.GetNextToken().MakeUpper(); // slant
620 if (tmp == wxT("I")) M_FONTDATA->m_style = wxITALIC;
621 if (tmp == wxT("O")) M_FONTDATA->m_style = wxITALIC;
622
623 tn.GetNextToken(); // set width
624 tn.GetNextToken(); // add. style
625 tn.GetNextToken(); // pixel size
626
627 tmp = tn.GetNextToken(); // pointsize
628 if (tmp != wxT("*"))
629 {
630 long num = wxStrtol (tmp.c_str(), (wxChar **) NULL, 10);
631 M_FONTDATA->m_pointSize = (int)(num / 10);
632 }
633
634 tn.GetNextToken(); // x-res
635 tn.GetNextToken(); // y-res
636
637 tmp = tn.GetNextToken().MakeUpper(); // spacing
638
639 if (tmp == wxT("M"))
640 M_FONTDATA->m_family = wxMODERN;
641 else if (M_FONTDATA->m_faceName == wxT("TIMES"))
642 M_FONTDATA->m_family = wxROMAN;
643 else if (M_FONTDATA->m_faceName == wxT("HELVETICA"))
644 M_FONTDATA->m_family = wxSWISS;
645 else if (M_FONTDATA->m_faceName == wxT("LUCIDATYPEWRITER"))
646 M_FONTDATA->m_family = wxTELETYPE;
647 else if (M_FONTDATA->m_faceName == wxT("LUCIDA"))
648 M_FONTDATA->m_family = wxDECORATIVE;
649 else if (M_FONTDATA->m_faceName == wxT("UTOPIA"))
650 M_FONTDATA->m_family = wxSCRIPT;
651
652 tn.GetNextToken(); // avg width
653
654 // deal with font encoding
655 M_FONTDATA->m_encoding = enc;
656 if ( M_FONTDATA->m_encoding == wxFONTENCODING_SYSTEM )
657 {
658 wxString registry = tn.GetNextToken().MakeUpper(),
659 encoding = tn.GetNextToken().MakeUpper();
660
661 if ( registry == _T("ISO8859") )
662 {
663 int cp;
664 if ( wxSscanf(encoding, wxT("%d"), &cp) == 1 )
665 {
666 M_FONTDATA->m_encoding =
667 (wxFontEncoding)(wxFONTENCODING_ISO8859_1 + cp - 1);
668 }
669 }
670 else if ( registry == _T("MICROSOFT") )
671 {
672 int cp;
673 if ( wxSscanf(encoding, wxT("cp125%d"), &cp) == 1 )
674 {
675 M_FONTDATA->m_encoding =
676 (wxFontEncoding)(wxFONTENCODING_CP1250 + cp);
677 }
678 }
679 else if ( registry == _T("KOI8") )
680 {
681 M_FONTDATA->m_encoding = wxFONTENCODING_KOI8;
682 }
683 //else: unknown encoding - may be give a warning here?
684 else
685 return false;
686 }
687 return true;
688 }
689 #endif // !wxUSE_UNICODE
690
691 wxFont::~wxFont()
692 {
693 }
694
695 // ----------------------------------------------------------------------------
696 // change the font attributes
697 // ----------------------------------------------------------------------------
698
699 void wxFont::Unshare()
700 {
701 // Don't change shared data
702 if (!m_refData)
703 {
704 m_refData = new wxFontRefData();
705 }
706 else
707 {
708 wxFontRefData* ref = new wxFontRefData(*(wxFontRefData*)m_refData);
709 UnRef();
710 m_refData = ref;
711 }
712 }
713
714 // ----------------------------------------------------------------------------
715 // accessors
716 // ----------------------------------------------------------------------------
717
718 int wxFont::GetPointSize() const
719 {
720 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
721
722 return M_FONTDATA->m_pointSize;
723 }
724
725 wxString wxFont::GetFaceName() const
726 {
727 wxCHECK_MSG( Ok(), wxEmptyString, wxT("invalid font") );
728
729 return M_FONTDATA->m_faceName;
730 }
731
732 int wxFont::GetFamily() const
733 {
734 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
735
736 return M_FONTDATA->m_family;
737 }
738
739 int wxFont::GetStyle() const
740 {
741 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
742
743 return M_FONTDATA->m_style;
744 }
745
746 int wxFont::GetWeight() const
747 {
748 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
749
750 return M_FONTDATA->m_weight;
751 }
752
753 bool wxFont::GetUnderlined() const
754 {
755 wxCHECK_MSG( Ok(), false, wxT("invalid font") );
756
757 return M_FONTDATA->m_underlined;
758 }
759
760 wxFontEncoding wxFont::GetEncoding() const
761 {
762 wxCHECK_MSG( Ok(), wxFONTENCODING_DEFAULT, wxT("invalid font") );
763
764 return M_FONTDATA->m_encoding;
765 }
766
767 bool wxFont::GetNoAntiAliasing() const
768 {
769 wxCHECK_MSG( Ok(), wxFONTENCODING_DEFAULT, wxT("invalid font") );
770
771 return M_FONTDATA->m_noAA;
772 }
773
774 const wxNativeFontInfo *wxFont::GetNativeFontInfo() const
775 {
776 wxCHECK_MSG( Ok(), (wxNativeFontInfo *)NULL, wxT("invalid font") );
777
778 #if wxUSE_UNICODE
779 #else
780 if ( M_FONTDATA->m_nativeFontInfo.GetXFontName().empty() )
781 GetInternalFont();
782 #endif
783
784 return &(M_FONTDATA->m_nativeFontInfo);
785 }
786
787 bool wxFont::IsFixedWidth() const
788 {
789 wxCHECK_MSG( Ok(), false, wxT("invalid font") );
790
791 #if wxUSE_UNICODE
792 return wxFontBase::IsFixedWidth();
793 #else
794 // Robert, is this right? HasNativeFont doesn't exist.
795 if ( true )
796 // if ( M_FONTDATA->HasNativeFont() )
797 {
798 // the monospace fonts are supposed to have "M" in the spacing field
799 wxString spacing = M_FONTDATA->
800 m_nativeFontInfo.GetXFontComponent(wxXLFD_SPACING);
801
802 return spacing.Upper() == _T('M');
803 }
804 // Unreaceable code for now
805 // return wxFontBase::IsFixedWidth();
806 #endif
807
808 }
809
810 // ----------------------------------------------------------------------------
811 // change font attributes
812 // ----------------------------------------------------------------------------
813
814 void wxFont::SetPointSize(int pointSize)
815 {
816 Unshare();
817
818 M_FONTDATA->SetPointSize(pointSize);
819 }
820
821 void wxFont::SetFamily(int family)
822 {
823 Unshare();
824
825 M_FONTDATA->SetFamily(family);
826 }
827
828 void wxFont::SetStyle(int style)
829 {
830 Unshare();
831
832 M_FONTDATA->SetStyle(style);
833 }
834
835 void wxFont::SetWeight(int weight)
836 {
837 Unshare();
838
839 M_FONTDATA->SetWeight(weight);
840 }
841
842 bool wxFont::SetFaceName(const wxString& faceName)
843 {
844 Unshare();
845
846 return M_FONTDATA->SetFaceName(faceName) &&
847 wxFontBase::SetFaceName(faceName);
848 }
849
850 void wxFont::SetUnderlined(bool underlined)
851 {
852 Unshare();
853
854 M_FONTDATA->SetUnderlined(underlined);
855 }
856
857 void wxFont::SetEncoding(wxFontEncoding encoding)
858 {
859 Unshare();
860
861 M_FONTDATA->SetEncoding(encoding);
862 }
863
864 void wxFont::DoSetNativeFontInfo( const wxNativeFontInfo& info )
865 {
866 Unshare();
867
868 M_FONTDATA->SetNativeFontInfo( info );
869 }
870
871 void wxFont::SetNoAntiAliasing( bool no )
872 {
873 Unshare();
874
875 M_FONTDATA->SetNoAntiAliasing( no );
876 }
877
878 #if wxUSE_UNICODE
879 #else
880
881 // ----------------------------------------------------------------------------
882 // X11 implementation
883 // ----------------------------------------------------------------------------
884
885 // Find an existing, or create a new, XFontStruct
886 // based on this wxFont and the given scale. Append the
887 // font to list in the private data for future reference.
888 wxXFont* wxFont::GetInternalFont(double scale, WXDisplay* display) const
889 {
890 if ( !Ok() )
891 return (wxXFont *)NULL;
892
893 long intScale = long(scale * 100.0 + 0.5); // key for wxXFont
894 int pointSize = (M_FONTDATA->m_pointSize * 10 * intScale) / 100;
895
896 // search existing fonts first
897 wxList::compatibility_iterator node = M_FONTDATA->m_fonts.GetFirst();
898 while (node)
899 {
900 wxXFont* f = (wxXFont*) node->GetData();
901 if ((!display || (f->m_display == display)) && (f->m_scale == intScale))
902 return f;
903 node = node->GetNext();
904 }
905
906 wxString xFontName = M_FONTDATA->m_nativeFontInfo.GetXFontName();
907 if (xFontName == "-*-*-*-*-*--*-*-*-*-*-*-*-*")
908 // wxFont constructor not called with native font info parameter => take M_FONTDATA values
909 xFontName.Clear();
910
911 // not found, create a new one
912 XFontStruct *font = (XFontStruct *)
913 wxLoadQueryNearestFont(pointSize,
914 M_FONTDATA->m_family,
915 M_FONTDATA->m_style,
916 M_FONTDATA->m_weight,
917 M_FONTDATA->m_underlined,
918 wxT(""),
919 M_FONTDATA->m_encoding,
920 & xFontName);
921
922 if ( !font )
923 {
924 wxFAIL_MSG( wxT("Could not allocate even a default font -- something is wrong.") );
925
926 return (wxXFont*) NULL;
927 }
928
929 wxXFont* f = new wxXFont;
930 f->m_fontStruct = (WXFontStructPtr)font;
931 f->m_display = ( display ? display : wxGetDisplay() );
932 f->m_scale = intScale;
933 M_FONTDATA->m_fonts.Append(f);
934
935 return f;
936 }
937
938 WXFontStructPtr wxFont::GetFontStruct(double scale, WXDisplay* display) const
939 {
940 wxXFont* f = GetInternalFont(scale, display);
941
942 return (f ? f->m_fontStruct : (WXFontStructPtr) 0);
943 }
944
945 #endif