]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/font.cpp
Combobox may not be fully created at this point
[wxWidgets.git] / src / gtk / font.cpp
CommitLineData
c801d85f 1/////////////////////////////////////////////////////////////////////////////
e4db172a 2// Name: src/gtk/font.cpp
c801d85f
KB
3// Purpose:
4// Author: Robert Roebling
a81258be 5// Id: $Id$
6c9a19aa 6// Copyright: (c) 1998 Robert Roebling and Julian Smart
65571936 7// Licence: wxWindows licence
c801d85f
KB
8/////////////////////////////////////////////////////////////////////////////
9
0c5d3e1c
VZ
10// ============================================================================
11// declarations
12// ============================================================================
13
14// ----------------------------------------------------------------------------
15// headers
16// ----------------------------------------------------------------------------
17
14f355c2
VS
18// For compilers that support precompilation, includes "wx.h".
19#include "wx/wxprec.h"
20
c801d85f 21#include "wx/font.h"
e4db172a
WS
22
23#ifndef WX_PRECOMP
24 #include "wx/log.h"
de6185e2 25 #include "wx/utils.h"
e4db172a
WS
26#endif
27
7beba2fc
VZ
28#include "wx/fontutil.h"
29#include "wx/cmndata.h"
4cb122de 30#include "wx/gdicmn.h"
8636aed8 31#include "wx/tokenzr.h"
c7985368 32#include "wx/settings.h"
0c5d3e1c 33
c801d85f
KB
34#include <strings.h>
35
9e691f46 36#include "wx/gtk/private.h"
d06b34a7 37#include <gdk/gdkprivate.h>
83624f79 38
409d5a58
VZ
39// ----------------------------------------------------------------------------
40// constants
41// ----------------------------------------------------------------------------
42
43// the default size (in points) for the fonts
44static const int wxDEFAULT_FONT_SIZE = 12;
45
46// ----------------------------------------------------------------------------
011ba5ed 47// wxScaledFontList: maps the font sizes to the GDK fonts for the given font
409d5a58
VZ
48// ----------------------------------------------------------------------------
49
011ba5ed
VZ
50WX_DECLARE_HASH_MAP(int, GdkFont *, wxIntegerHash, wxIntegerEqual,
51 wxScaledFontList);
409d5a58 52
0c5d3e1c
VZ
53// ----------------------------------------------------------------------------
54// wxFontRefData
55// ----------------------------------------------------------------------------
56
57class wxFontRefData : public wxObjectRefData
c801d85f 58{
8bbe427f 59public:
409d5a58
VZ
60 // from broken down font parameters, also default ctor
61 wxFontRefData(int size = -1,
62 int family = wxFONTFAMILY_DEFAULT,
63 int style = wxFONTSTYLE_NORMAL,
64 int weight = wxFONTWEIGHT_NORMAL,
de6185e2 65 bool underlined = false,
0c5d3e1c 66 const wxString& faceName = wxEmptyString,
7826e2dd 67 wxFontEncoding encoding = wxFONTENCODING_DEFAULT);
409d5a58
VZ
68
69 // from XFLD
70 wxFontRefData(const wxString& fontname);
71
72 // copy ctor
358fc25c 73 wxFontRefData( const wxFontRefData& data );
409d5a58 74
0c5d3e1c
VZ
75 virtual ~wxFontRefData();
76
409d5a58
VZ
77 // do we have the native font info?
78 bool HasNativeFont() const
79 {
011ba5ed 80 // we always have a Pango font description
de6185e2 81 return true;
409d5a58
VZ
82 }
83
84 // setters: all of them also take care to modify m_nativeFontInfo if we
85 // have it so as to not lose the information not carried by our fields
86 void SetPointSize(int pointSize);
87 void SetFamily(int family);
88 void SetStyle(int style);
89 void SetWeight(int weight);
90 void SetUnderlined(bool underlined);
91 void SetFaceName(const wxString& facename);
92 void SetEncoding(wxFontEncoding encoding);
93
de6185e2 94 void SetNoAntiAliasing( bool no = true ) { m_noAA = no; }
5ac2e80c 95 bool GetNoAntiAliasing() const { return m_noAA; }
cd9a673c 96
011ba5ed
VZ
97 // and this one also modifies all the other font data fields
98 void SetNativeFontInfo(const wxNativeFontInfo& info);
99
0c5d3e1c
VZ
100protected:
101 // common part of all ctors
102 void Init(int pointSize,
103 int family,
104 int style,
105 int weight,
106 bool underlined,
107 const wxString& faceName,
7826e2dd 108 wxFontEncoding encoding);
0c5d3e1c 109
011ba5ed
VZ
110 // set all fields from (already initialized and valid) m_nativeFontInfo
111 void InitFromNative();
112
0c5d3e1c 113private:
2b5f62a0 114 // clear m_scaled_xfonts if any
011ba5ed
VZ
115 void ClearGdkFonts();
116
f35c2659
RR
117 int m_pointSize;
118 int m_family,
119 m_style,
120 m_weight;
121 bool m_underlined;
122 wxString m_faceName;
5f11fef5 123 wxFontEncoding m_encoding;
2b5f62a0 124 bool m_noAA; // No anti-aliasing
7826e2dd 125
db16cab4
RR
126 // The native font info, basicly an XFLD under GTK 1.2 and
127 // the pango font description under GTK 2.0.
30764ab5 128 wxNativeFontInfo m_nativeFontInfo;
8bbe427f 129
f6bcfd97 130 friend class wxFont;
c801d85f
KB
131};
132
0c5d3e1c 133// ----------------------------------------------------------------------------
cd9a673c 134// wxFontRefData
0c5d3e1c
VZ
135// ----------------------------------------------------------------------------
136
137void wxFontRefData::Init(int pointSize,
138 int family,
139 int style,
140 int weight,
141 bool underlined,
142 const wxString& faceName,
7826e2dd 143 wxFontEncoding encoding)
8bbe427f 144{
409d5a58 145 m_family = family == wxFONTFAMILY_DEFAULT ? wxFONTFAMILY_SWISS : family;
0c5d3e1c
VZ
146
147 m_faceName = faceName;
148
409d5a58
VZ
149 // we accept both wxDEFAULT and wxNORMAL here - should we?
150 m_style = style == wxDEFAULT ? wxFONTSTYLE_NORMAL : style;
151 m_weight = weight == wxDEFAULT ? wxFONTWEIGHT_NORMAL : weight;
0c5d3e1c 152
409d5a58
VZ
153 // and here, do we really want to forbid creation of the font of the size
154 // 90 (the value of wxDEFAULT)??
011ba5ed
VZ
155 m_pointSize = pointSize == wxDEFAULT || pointSize == -1
156 ? wxDEFAULT_FONT_SIZE
157 : pointSize;
0c5d3e1c
VZ
158
159 m_underlined = underlined;
160 m_encoding = encoding;
cd9a673c 161
de6185e2 162 m_noAA = false;
011ba5ed 163
46eed000
RR
164 // Create native font info
165 m_nativeFontInfo.description = pango_font_description_new();
166
011ba5ed 167 // And set its values
2b5f62a0
VZ
168 if (!m_faceName.empty())
169 {
5f11fef5
VZ
170 pango_font_description_set_family( m_nativeFontInfo.description,
171 wxGTK_CONV_SYS(m_faceName) );
2b5f62a0
VZ
172 }
173 else
174 {
175 switch (m_family)
176 {
177 case wxFONTFAMILY_MODERN:
178 case wxFONTFAMILY_TELETYPE:
179 pango_font_description_set_family( m_nativeFontInfo.description, "monospace" );
180 break;
181 case wxFONTFAMILY_ROMAN:
182 pango_font_description_set_family( m_nativeFontInfo.description, "serif" );
183 break;
184 case wxFONTFAMILY_SWISS:
185 // SWISS = sans serif
186 default:
187 pango_font_description_set_family( m_nativeFontInfo.description, "sans" );
188 break;
189 }
46eed000 190 }
cd9a673c 191
46eed000
RR
192 SetStyle( m_style );
193 SetPointSize( m_pointSize );
194 SetWeight( m_weight );
358fc25c
RR
195}
196
011ba5ed 197void wxFontRefData::InitFromNative()
409d5a58 198{
de6185e2 199 m_noAA = false;
2b5f62a0 200
db16cab4
RR
201 // Get native info
202 PangoFontDescription *desc = m_nativeFontInfo.description;
011ba5ed 203
db16cab4
RR
204 // init fields
205 m_faceName = wxGTK_CONV_BACK( pango_font_description_get_family( desc ) );
011ba5ed 206
b6b579bd
RR
207 // Pango sometimes needs to have a size
208 int pango_size = pango_font_description_get_size( desc );
209 if (pango_size == 0)
d332c514 210 m_nativeFontInfo.SetPointSize(12);
0f6858b6 211
d332c514
MR
212 m_pointSize = m_nativeFontInfo.GetPointSize();
213 m_style = m_nativeFontInfo.GetStyle();
214 m_weight = m_nativeFontInfo.GetWeight();
011ba5ed 215
a732ef91 216 if (m_faceName == wxT("monospace"))
db16cab4
RR
217 {
218 m_family = wxFONTFAMILY_TELETYPE;
219 }
220 else if (m_faceName == wxT("sans"))
221 {
222 m_family = wxFONTFAMILY_SWISS;
223 }
2b5f62a0
VZ
224 else if (m_faceName == wxT("serif"))
225 {
226 m_family = wxFONTFAMILY_ROMAN;
227 }
db16cab4
RR
228 else
229 {
230 m_family = wxFONTFAMILY_UNKNOWN;
231 }
232
233 // Pango description are never underlined (?)
de6185e2 234 m_underlined = false;
db16cab4 235
5f11fef5
VZ
236 // always with GTK+ 2
237 m_encoding = wxFONTENCODING_UTF8;
409d5a58
VZ
238}
239
011ba5ed
VZ
240wxFontRefData::wxFontRefData( const wxFontRefData& data )
241 : wxObjectRefData()
242{
243 m_pointSize = data.m_pointSize;
244 m_family = data.m_family;
245 m_style = data.m_style;
246 m_weight = data.m_weight;
247
248 m_underlined = data.m_underlined;
249
250 m_faceName = data.m_faceName;
251 m_encoding = data.m_encoding;
252
2b5f62a0 253 m_noAA = data.m_noAA;
cd9a673c
RD
254
255 // Forces a copy of the internal data. wxNativeFontInfo should probably
256 // have a copy ctor and assignment operator to fix this properly but that
257 // would break binary compatibility...
258 m_nativeFontInfo.FromString(data.m_nativeFontInfo.ToString());
011ba5ed
VZ
259}
260
261wxFontRefData::wxFontRefData(int size, int family, int style,
262 int weight, bool underlined,
263 const wxString& faceName,
264 wxFontEncoding encoding)
265{
266 Init(size, family, style, weight, underlined, faceName, encoding);
267}
268
269wxFontRefData::wxFontRefData(const wxString& fontname)
8bbe427f 270{
011ba5ed 271 m_nativeFontInfo.FromString( fontname );
011ba5ed
VZ
272
273 InitFromNative();
274}
275
011ba5ed
VZ
276void wxFontRefData::ClearGdkFonts()
277{
2b5f62a0 278}
011ba5ed
VZ
279
280wxFontRefData::~wxFontRefData()
281{
282 ClearGdkFonts();
0c5d3e1c 283}
c801d85f 284
0c5d3e1c 285// ----------------------------------------------------------------------------
409d5a58 286// wxFontRefData SetXXX()
0c5d3e1c 287// ----------------------------------------------------------------------------
c801d85f 288
409d5a58 289void wxFontRefData::SetPointSize(int pointSize)
c801d85f 290{
409d5a58 291 m_pointSize = pointSize;
c801d85f 292
8a15e8ba 293 m_nativeFontInfo.SetPointSize(pointSize);
7826e2dd
VZ
294}
295
409d5a58 296void wxFontRefData::SetFamily(int family)
7826e2dd 297{
409d5a58 298 m_family = family;
30764ab5 299
409d5a58 300 // TODO: what are we supposed to do with m_nativeFontInfo here?
30764ab5
VZ
301}
302
409d5a58 303void wxFontRefData::SetStyle(int style)
c801d85f 304{
409d5a58
VZ
305 m_style = style;
306
7533ba25 307 m_nativeFontInfo.SetStyle((wxFontStyle)style);
409d5a58 308}
7beba2fc 309
409d5a58
VZ
310void wxFontRefData::SetWeight(int weight)
311{
312 m_weight = weight;
8bbe427f 313
7533ba25 314 m_nativeFontInfo.SetWeight((wxFontWeight)weight);
409d5a58 315}
30764ab5 316
409d5a58
VZ
317void wxFontRefData::SetUnderlined(bool underlined)
318{
319 m_underlined = underlined;
8636aed8 320
409d5a58
VZ
321 // the XLFD doesn't have "underlined" field anyhow
322}
30760ce7 323
409d5a58
VZ
324void wxFontRefData::SetFaceName(const wxString& facename)
325{
326 m_faceName = facename;
7beba2fc 327
8a15e8ba 328 m_nativeFontInfo.SetFaceName(facename);
409d5a58 329}
284b4c88 330
409d5a58
VZ
331void wxFontRefData::SetEncoding(wxFontEncoding encoding)
332{
333 m_encoding = encoding;
409d5a58 334}
284b4c88 335
011ba5ed
VZ
336void wxFontRefData::SetNativeFontInfo(const wxNativeFontInfo& info)
337{
338 // previously cached fonts shouldn't be used
339 ClearGdkFonts();
340
341 m_nativeFontInfo = info;
342
343 // set all the other font parameters from the native font info
344 InitFromNative();
345}
346
409d5a58
VZ
347// ----------------------------------------------------------------------------
348// wxFont creation
349// ----------------------------------------------------------------------------
36f210c8 350
409d5a58 351IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
36f210c8 352
409d5a58
VZ
353wxFont::wxFont(const wxNativeFontInfo& info)
354{
011ba5ed 355 Create( info.GetPointSize(),
db16cab4
RR
356 info.GetFamily(),
357 info.GetStyle(),
358 info.GetWeight(),
359 info.GetUnderlined(),
360 info.GetFaceName(),
361 info.GetEncoding() );
409d5a58
VZ
362}
363
364bool wxFont::Create( int pointSize,
365 int family,
366 int style,
367 int weight,
368 bool underlined,
369 const wxString& face,
370 wxFontEncoding encoding)
371{
2b5f62a0
VZ
372 UnRef();
373
409d5a58
VZ
374 m_refData = new wxFontRefData(pointSize, family, style, weight,
375 underlined, face, encoding);
376
de6185e2 377 return true;
409d5a58
VZ
378}
379
380bool wxFont::Create(const wxString& fontname)
381{
382 // VZ: does this really happen?
383 if ( fontname.empty() )
36f210c8 384 {
409d5a58 385 *this = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
7beba2fc 386
de6185e2 387 return true;
36f210c8 388 }
409d5a58
VZ
389
390 m_refData = new wxFontRefData(fontname);
391
de6185e2 392 return true;
ff7b1510 393}
c801d85f 394
0c5d3e1c 395void wxFont::Unshare()
8bbe427f 396{
0c5d3e1c
VZ
397 if (!m_refData)
398 {
399 m_refData = new wxFontRefData();
400 }
401 else
402 {
403 wxFontRefData* ref = new wxFontRefData(*(wxFontRefData*)m_refData);
404 UnRef();
405 m_refData = ref;
406 }
ff7b1510 407}
c801d85f 408
8bbe427f 409wxFont::~wxFont()
c801d85f 410{
ff7b1510 411}
c801d85f 412
0c5d3e1c
VZ
413// ----------------------------------------------------------------------------
414// accessors
415// ----------------------------------------------------------------------------
c801d85f 416
8bbe427f 417int wxFont::GetPointSize() const
c801d85f 418{
223d09f6 419 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
8bbe427f 420
02d9204c
MR
421#if wxUSE_PANGO
422 return M_FONTDATA->HasNativeFont() ? M_FONTDATA->m_nativeFontInfo.GetPointSize()
423 : M_FONTDATA->m_pointSize;
424#else
8bbe427f 425 return M_FONTDATA->m_pointSize;
02d9204c 426#endif
ff7b1510 427}
c801d85f 428
8bbe427f 429wxString wxFont::GetFaceName() const
c801d85f 430{
e4db172a 431 wxCHECK_MSG( Ok(), wxEmptyString, wxT("invalid font") );
8bbe427f 432
02d9204c
MR
433#if wxUSE_PANGO
434 return M_FONTDATA->HasNativeFont() ? M_FONTDATA->m_nativeFontInfo.GetFaceName()
435 : M_FONTDATA->m_faceName;
436#else
36b3b54a 437 return M_FONTDATA->m_faceName;
02d9204c 438#endif
ff7b1510 439}
c801d85f 440
8bbe427f 441int wxFont::GetFamily() const
c801d85f 442{
223d09f6 443 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
8bbe427f 444
02d9204c 445#if wxUSE_PANGO
b67d14be
MR
446 int ret = M_FONTDATA->m_family;
447 if (M_FONTDATA->HasNativeFont())
448 // wxNativeFontInfo::GetFamily is expensive, must not call more than once
449 ret = M_FONTDATA->m_nativeFontInfo.GetFamily();
450
451 if (ret == wxFONTFAMILY_DEFAULT)
452 ret = M_FONTDATA->m_family;
453
454 return ret;
02d9204c 455#else
8bbe427f 456 return M_FONTDATA->m_family;
02d9204c 457#endif
ff7b1510 458}
c801d85f 459
8bbe427f 460int wxFont::GetStyle() const
c801d85f 461{
223d09f6 462 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
d84eb083 463
02d9204c
MR
464#if wxUSE_PANGO
465 return M_FONTDATA->HasNativeFont() ? M_FONTDATA->m_nativeFontInfo.GetStyle()
466 : M_FONTDATA->m_style;
467#else
8bbe427f 468 return M_FONTDATA->m_style;
02d9204c 469#endif
ff7b1510 470}
c801d85f 471
8bbe427f 472int wxFont::GetWeight() const
c801d85f 473{
223d09f6 474 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
8bbe427f 475
02d9204c
MR
476#if wxUSE_PANGO
477 return M_FONTDATA->HasNativeFont() ? M_FONTDATA->m_nativeFontInfo.GetWeight()
478 : M_FONTDATA->m_weight;
479#else
8bbe427f 480 return M_FONTDATA->m_weight;
02d9204c 481#endif
8bbe427f
VZ
482}
483
8bbe427f
VZ
484bool wxFont::GetUnderlined() const
485{
de6185e2 486 wxCHECK_MSG( Ok(), false, wxT("invalid font") );
8bbe427f
VZ
487
488 return M_FONTDATA->m_underlined;
ff7b1510 489}
c801d85f 490
0c5d3e1c 491wxFontEncoding wxFont::GetEncoding() const
358fc25c 492{
5f11fef5 493 wxCHECK_MSG( Ok(), wxFONTENCODING_SYSTEM, wxT("invalid font") );
0c5d3e1c
VZ
494
495 return M_FONTDATA->m_encoding;
358fc25c
RR
496}
497
5ac2e80c 498bool wxFont::GetNoAntiAliasing() const
2b5f62a0 499{
5f11fef5 500 wxCHECK_MSG( Ok(), false, wxT("invalid font") );
2b5f62a0
VZ
501
502 return M_FONTDATA->m_noAA;
503}
504
3bf5a59b 505const wxNativeFontInfo *wxFont::GetNativeFontInfo() const
30764ab5 506{
7826e2dd 507 wxCHECK_MSG( Ok(), (wxNativeFontInfo *)NULL, wxT("invalid font") );
30764ab5 508
3bf5a59b 509 return &(M_FONTDATA->m_nativeFontInfo);
30764ab5
VZ
510}
511
53f6aab7
VZ
512bool wxFont::IsFixedWidth() const
513{
de6185e2 514 wxCHECK_MSG( Ok(), false, wxT("invalid font") );
53f6aab7 515
53f6aab7
VZ
516 return wxFontBase::IsFixedWidth();
517}
30764ab5 518
0c5d3e1c
VZ
519// ----------------------------------------------------------------------------
520// change font attributes
521// ----------------------------------------------------------------------------
522
358fc25c
RR
523void wxFont::SetPointSize(int pointSize)
524{
525 Unshare();
011ba5ed 526
409d5a58 527 M_FONTDATA->SetPointSize(pointSize);
358fc25c
RR
528}
529
530void wxFont::SetFamily(int family)
531{
532 Unshare();
533
409d5a58 534 M_FONTDATA->SetFamily(family);
358fc25c
RR
535}
536
537void wxFont::SetStyle(int style)
538{
539 Unshare();
540
409d5a58 541 M_FONTDATA->SetStyle(style);
358fc25c
RR
542}
543
544void wxFont::SetWeight(int weight)
545{
546 Unshare();
547
409d5a58 548 M_FONTDATA->SetWeight(weight);
358fc25c
RR
549}
550
551void wxFont::SetFaceName(const wxString& faceName)
552{
553 Unshare();
554
409d5a58 555 M_FONTDATA->SetFaceName(faceName);
358fc25c
RR
556}
557
558void wxFont::SetUnderlined(bool underlined)
559{
560 Unshare();
561
409d5a58 562 M_FONTDATA->SetUnderlined(underlined);
358fc25c
RR
563}
564
0c5d3e1c
VZ
565void wxFont::SetEncoding(wxFontEncoding encoding)
566{
567 Unshare();
c801d85f 568
409d5a58 569 M_FONTDATA->SetEncoding(encoding);
30764ab5
VZ
570}
571
9045ad9d 572void wxFont::DoSetNativeFontInfo( const wxNativeFontInfo& info )
2b5f62a0
VZ
573{
574 Unshare();
575
576 M_FONTDATA->SetNativeFontInfo( info );
577}
578
579void wxFont::SetNoAntiAliasing( bool no )
30764ab5
VZ
580{
581 Unshare();
582
2b5f62a0 583 M_FONTDATA->SetNoAntiAliasing( no );
0c5d3e1c 584}