]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/font.cpp
Fixed [ 1556843 ] wxGTK FindFocus returns NULL when a wxListBox is focused
[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"
9eddec69 26 #include "wx/settings.h"
ce5d92e1 27 #include "wx/cmndata.h"
dd05139a 28 #include "wx/gdicmn.h"
e4db172a
WS
29#endif
30
7beba2fc 31#include "wx/fontutil.h"
8636aed8 32#include "wx/tokenzr.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);
85ab460e 91 bool SetFaceName(const wxString& facename);
409d5a58
VZ
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
85ab460e 324bool wxFontRefData::SetFaceName(const wxString& facename)
409d5a58
VZ
325{
326 m_faceName = facename;
7beba2fc 327
85ab460e 328 return 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 return M_FONTDATA->HasNativeFont() ? M_FONTDATA->m_nativeFontInfo.GetPointSize()
422 : M_FONTDATA->m_pointSize;
ff7b1510 423}
c801d85f 424
8bbe427f 425wxString wxFont::GetFaceName() const
c801d85f 426{
e4db172a 427 wxCHECK_MSG( Ok(), wxEmptyString, wxT("invalid font") );
8bbe427f 428
02d9204c
MR
429 return M_FONTDATA->HasNativeFont() ? M_FONTDATA->m_nativeFontInfo.GetFaceName()
430 : M_FONTDATA->m_faceName;
ff7b1510 431}
c801d85f 432
8bbe427f 433int wxFont::GetFamily() const
c801d85f 434{
223d09f6 435 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
8bbe427f 436
b67d14be
MR
437 int ret = M_FONTDATA->m_family;
438 if (M_FONTDATA->HasNativeFont())
439 // wxNativeFontInfo::GetFamily is expensive, must not call more than once
440 ret = M_FONTDATA->m_nativeFontInfo.GetFamily();
441
442 if (ret == wxFONTFAMILY_DEFAULT)
443 ret = M_FONTDATA->m_family;
444
445 return ret;
ff7b1510 446}
c801d85f 447
8bbe427f 448int wxFont::GetStyle() const
c801d85f 449{
223d09f6 450 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
d84eb083 451
02d9204c
MR
452 return M_FONTDATA->HasNativeFont() ? M_FONTDATA->m_nativeFontInfo.GetStyle()
453 : M_FONTDATA->m_style;
ff7b1510 454}
c801d85f 455
8bbe427f 456int wxFont::GetWeight() const
c801d85f 457{
223d09f6 458 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
8bbe427f 459
02d9204c
MR
460 return M_FONTDATA->HasNativeFont() ? M_FONTDATA->m_nativeFontInfo.GetWeight()
461 : M_FONTDATA->m_weight;
8bbe427f
VZ
462}
463
8bbe427f
VZ
464bool wxFont::GetUnderlined() const
465{
de6185e2 466 wxCHECK_MSG( Ok(), false, wxT("invalid font") );
8bbe427f
VZ
467
468 return M_FONTDATA->m_underlined;
ff7b1510 469}
c801d85f 470
0c5d3e1c 471wxFontEncoding wxFont::GetEncoding() const
358fc25c 472{
5f11fef5 473 wxCHECK_MSG( Ok(), wxFONTENCODING_SYSTEM, wxT("invalid font") );
0c5d3e1c
VZ
474
475 return M_FONTDATA->m_encoding;
358fc25c
RR
476}
477
5ac2e80c 478bool wxFont::GetNoAntiAliasing() const
2b5f62a0 479{
5f11fef5 480 wxCHECK_MSG( Ok(), false, wxT("invalid font") );
2b5f62a0
VZ
481
482 return M_FONTDATA->m_noAA;
483}
484
3bf5a59b 485const wxNativeFontInfo *wxFont::GetNativeFontInfo() const
30764ab5 486{
7826e2dd 487 wxCHECK_MSG( Ok(), (wxNativeFontInfo *)NULL, wxT("invalid font") );
30764ab5 488
3bf5a59b 489 return &(M_FONTDATA->m_nativeFontInfo);
30764ab5
VZ
490}
491
53f6aab7
VZ
492bool wxFont::IsFixedWidth() const
493{
de6185e2 494 wxCHECK_MSG( Ok(), false, wxT("invalid font") );
53f6aab7 495
53f6aab7
VZ
496 return wxFontBase::IsFixedWidth();
497}
30764ab5 498
0c5d3e1c
VZ
499// ----------------------------------------------------------------------------
500// change font attributes
501// ----------------------------------------------------------------------------
502
358fc25c
RR
503void wxFont::SetPointSize(int pointSize)
504{
505 Unshare();
011ba5ed 506
409d5a58 507 M_FONTDATA->SetPointSize(pointSize);
358fc25c
RR
508}
509
510void wxFont::SetFamily(int family)
511{
512 Unshare();
513
409d5a58 514 M_FONTDATA->SetFamily(family);
358fc25c
RR
515}
516
517void wxFont::SetStyle(int style)
518{
519 Unshare();
520
409d5a58 521 M_FONTDATA->SetStyle(style);
358fc25c
RR
522}
523
524void wxFont::SetWeight(int weight)
525{
526 Unshare();
527
409d5a58 528 M_FONTDATA->SetWeight(weight);
358fc25c
RR
529}
530
85ab460e 531bool wxFont::SetFaceName(const wxString& faceName)
358fc25c
RR
532{
533 Unshare();
534
85ab460e
VZ
535 return M_FONTDATA->SetFaceName(faceName) &&
536 wxFontBase::SetFaceName(faceName);
358fc25c
RR
537}
538
539void wxFont::SetUnderlined(bool underlined)
540{
541 Unshare();
542
409d5a58 543 M_FONTDATA->SetUnderlined(underlined);
358fc25c
RR
544}
545
0c5d3e1c
VZ
546void wxFont::SetEncoding(wxFontEncoding encoding)
547{
548 Unshare();
c801d85f 549
409d5a58 550 M_FONTDATA->SetEncoding(encoding);
30764ab5
VZ
551}
552
9045ad9d 553void wxFont::DoSetNativeFontInfo( const wxNativeFontInfo& info )
2b5f62a0
VZ
554{
555 Unshare();
556
557 M_FONTDATA->SetNativeFontInfo( info );
558}
559
560void wxFont::SetNoAntiAliasing( bool no )
30764ab5
VZ
561{
562 Unshare();
563
2b5f62a0 564 M_FONTDATA->SetNoAntiAliasing( no );
0c5d3e1c 565}