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