]> git.saurik.com Git - wxWidgets.git/blob - src/gtk/font.cpp
Preserve original menu label for later retrieval
[wxWidgets.git] / src / gtk / font.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/gtk/font.cpp
3 // Purpose:
4 // Author: Robert Roebling
5 // Id: $Id$
6 // Copyright: (c) 1998 Robert Roebling and Julian Smart
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
9
10 // ============================================================================
11 // declarations
12 // ============================================================================
13
14 // ----------------------------------------------------------------------------
15 // headers
16 // ----------------------------------------------------------------------------
17
18 // For compilers that support precompilation, includes "wx.h".
19 #include "wx/wxprec.h"
20
21 #include "wx/font.h"
22
23 #ifndef WX_PRECOMP
24 #include "wx/log.h"
25 #include "wx/utils.h"
26 #include "wx/settings.h"
27 #include "wx/cmndata.h"
28 #include "wx/gdicmn.h"
29 #endif
30
31 #include "wx/fontutil.h"
32 #include "wx/tokenzr.h"
33
34 #include "wx/gtk/private.h"
35
36 // ----------------------------------------------------------------------------
37 // constants
38 // ----------------------------------------------------------------------------
39
40 // the default size (in points) for the fonts
41 static const int wxDEFAULT_FONT_SIZE = 12;
42
43 // ----------------------------------------------------------------------------
44 // wxScaledFontList: maps the font sizes to the GDK fonts for the given font
45 // ----------------------------------------------------------------------------
46
47 WX_DECLARE_HASH_MAP(int, GdkFont *, wxIntegerHash, wxIntegerEqual,
48 wxScaledFontList);
49
50 // ----------------------------------------------------------------------------
51 // wxFontRefData
52 // ----------------------------------------------------------------------------
53
54 class wxFontRefData : public wxObjectRefData
55 {
56 public:
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,
62 bool underlined = false,
63 const wxString& faceName = wxEmptyString,
64 wxFontEncoding encoding = wxFONTENCODING_DEFAULT);
65
66 // from XFLD
67 wxFontRefData(const wxString& fontname);
68
69 // copy ctor
70 wxFontRefData( const wxFontRefData& data );
71
72 virtual ~wxFontRefData();
73
74 // do we have the native font info?
75 bool HasNativeFont() const
76 {
77 // we always have a Pango font description
78 return true;
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);
88 bool SetFaceName(const wxString& facename);
89 void SetEncoding(wxFontEncoding encoding);
90
91 void SetNoAntiAliasing( bool no = true ) { m_noAA = no; }
92 bool GetNoAntiAliasing() const { return m_noAA; }
93
94 // and this one also modifies all the other font data fields
95 void SetNativeFontInfo(const wxNativeFontInfo& info);
96
97 protected:
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,
105 wxFontEncoding encoding);
106
107 // set all fields from (already initialized and valid) m_nativeFontInfo
108 void InitFromNative();
109
110 private:
111 // clear m_scaled_xfonts if any
112 void ClearGdkFonts();
113
114 int m_pointSize;
115 int m_family,
116 m_style,
117 m_weight;
118 bool m_underlined;
119 wxString m_faceName;
120 wxFontEncoding m_encoding;
121 bool m_noAA; // No anti-aliasing
122
123 // The native font info, basicly an XFLD under GTK 1.2 and
124 // the pango font description under GTK 2.0.
125 wxNativeFontInfo m_nativeFontInfo;
126
127 friend class wxFont;
128 };
129
130 #define M_FONTDATA ((wxFontRefData*)m_refData)
131
132 // ----------------------------------------------------------------------------
133 // wxFontRefData
134 // ----------------------------------------------------------------------------
135
136 void wxFontRefData::Init(int pointSize,
137 int family,
138 int style,
139 int weight,
140 bool underlined,
141 const wxString& faceName,
142 wxFontEncoding encoding)
143 {
144 m_family = family == wxFONTFAMILY_DEFAULT ? wxFONTFAMILY_SWISS : family;
145
146 m_faceName = faceName;
147
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;
151
152 // and here, do we really want to forbid creation of the font of the size
153 // 90 (the value of wxDEFAULT)??
154 m_pointSize = pointSize == wxDEFAULT || pointSize == -1
155 ? wxDEFAULT_FONT_SIZE
156 : pointSize;
157
158 m_underlined = underlined;
159 m_encoding = encoding;
160 if ( m_encoding == wxFONTENCODING_DEFAULT )
161 m_encoding = wxFont::GetDefaultEncoding();
162
163 m_noAA = false;
164
165 // Create native font info
166 m_nativeFontInfo.description = pango_font_description_new();
167
168 // And set its values
169 if (!m_faceName.empty())
170 {
171 pango_font_description_set_family( m_nativeFontInfo.description,
172 wxGTK_CONV_SYS(m_faceName) );
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 }
191 }
192
193 SetStyle( m_style );
194 SetPointSize( m_pointSize );
195 SetWeight( m_weight );
196 }
197
198 void wxFontRefData::InitFromNative()
199 {
200 m_noAA = false;
201
202 // Get native info
203 PangoFontDescription *desc = m_nativeFontInfo.description;
204
205 // init fields
206 m_faceName = wxGTK_CONV_BACK_SYS(pango_font_description_get_family(desc));
207
208 // Pango sometimes needs to have a size
209 int pango_size = pango_font_description_get_size( desc );
210 if (pango_size == 0)
211 m_nativeFontInfo.SetPointSize(12);
212
213 m_pointSize = m_nativeFontInfo.GetPointSize();
214 m_style = m_nativeFontInfo.GetStyle();
215 m_weight = m_nativeFontInfo.GetWeight();
216
217 if (m_faceName == wxT("monospace"))
218 {
219 m_family = wxFONTFAMILY_TELETYPE;
220 }
221 else if (m_faceName == wxT("sans"))
222 {
223 m_family = wxFONTFAMILY_SWISS;
224 }
225 else if (m_faceName == wxT("serif"))
226 {
227 m_family = wxFONTFAMILY_ROMAN;
228 }
229 else
230 {
231 m_family = wxFONTFAMILY_UNKNOWN;
232 }
233
234 // Pango description are never underlined (?)
235 m_underlined = false;
236
237 // always with GTK+ 2
238 m_encoding = wxFONTENCODING_UTF8;
239 }
240
241 wxFontRefData::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
254 m_noAA = data.m_noAA;
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());
260 }
261
262 wxFontRefData::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
270 wxFontRefData::wxFontRefData(const wxString& fontname)
271 {
272 m_nativeFontInfo.FromString( fontname );
273
274 InitFromNative();
275 }
276
277 void wxFontRefData::ClearGdkFonts()
278 {
279 }
280
281 wxFontRefData::~wxFontRefData()
282 {
283 ClearGdkFonts();
284 }
285
286 // ----------------------------------------------------------------------------
287 // wxFontRefData SetXXX()
288 // ----------------------------------------------------------------------------
289
290 void wxFontRefData::SetPointSize(int pointSize)
291 {
292 m_pointSize = pointSize;
293
294 m_nativeFontInfo.SetPointSize(pointSize);
295 }
296
297 void wxFontRefData::SetFamily(int family)
298 {
299 m_family = family;
300
301 // TODO: what are we supposed to do with m_nativeFontInfo here?
302 }
303
304 void wxFontRefData::SetStyle(int style)
305 {
306 m_style = style;
307
308 m_nativeFontInfo.SetStyle((wxFontStyle)style);
309 }
310
311 void wxFontRefData::SetWeight(int weight)
312 {
313 m_weight = weight;
314
315 m_nativeFontInfo.SetWeight((wxFontWeight)weight);
316 }
317
318 void wxFontRefData::SetUnderlined(bool underlined)
319 {
320 m_underlined = underlined;
321
322 // the XLFD doesn't have "underlined" field anyhow
323 }
324
325 bool wxFontRefData::SetFaceName(const wxString& facename)
326 {
327 m_faceName = facename;
328
329 return m_nativeFontInfo.SetFaceName(facename);
330 }
331
332 void wxFontRefData::SetEncoding(wxFontEncoding encoding)
333 {
334 m_encoding = encoding;
335 }
336
337 void 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
348 // ----------------------------------------------------------------------------
349 // wxFont creation
350 // ----------------------------------------------------------------------------
351
352 IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
353
354 wxFont::wxFont(const wxNativeFontInfo& info)
355 {
356 Create( info.GetPointSize(),
357 info.GetFamily(),
358 info.GetStyle(),
359 info.GetWeight(),
360 info.GetUnderlined(),
361 info.GetFaceName(),
362 info.GetEncoding() );
363 }
364
365 bool wxFont::Create( int pointSize,
366 int family,
367 int style,
368 int weight,
369 bool underlined,
370 const wxString& face,
371 wxFontEncoding encoding)
372 {
373 UnRef();
374
375 m_refData = new wxFontRefData(pointSize, family, style, weight,
376 underlined, face, encoding);
377
378 return true;
379 }
380
381 bool wxFont::Create(const wxString& fontname)
382 {
383 // VZ: does this really happen?
384 if ( fontname.empty() )
385 {
386 *this = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
387
388 return true;
389 }
390
391 m_refData = new wxFontRefData(fontname);
392
393 return true;
394 }
395
396 wxFont::~wxFont()
397 {
398 }
399
400 // ----------------------------------------------------------------------------
401 // accessors
402 // ----------------------------------------------------------------------------
403
404 int wxFont::GetPointSize() const
405 {
406 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
407
408 return M_FONTDATA->HasNativeFont() ? M_FONTDATA->m_nativeFontInfo.GetPointSize()
409 : M_FONTDATA->m_pointSize;
410 }
411
412 wxString wxFont::GetFaceName() const
413 {
414 wxCHECK_MSG( Ok(), wxEmptyString, wxT("invalid font") );
415
416 return M_FONTDATA->HasNativeFont() ? M_FONTDATA->m_nativeFontInfo.GetFaceName()
417 : M_FONTDATA->m_faceName;
418 }
419
420 int wxFont::GetFamily() const
421 {
422 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
423
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;
433 }
434
435 int wxFont::GetStyle() const
436 {
437 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
438
439 return M_FONTDATA->HasNativeFont() ? M_FONTDATA->m_nativeFontInfo.GetStyle()
440 : M_FONTDATA->m_style;
441 }
442
443 int wxFont::GetWeight() const
444 {
445 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
446
447 return M_FONTDATA->HasNativeFont() ? M_FONTDATA->m_nativeFontInfo.GetWeight()
448 : M_FONTDATA->m_weight;
449 }
450
451 bool wxFont::GetUnderlined() const
452 {
453 wxCHECK_MSG( Ok(), false, wxT("invalid font") );
454
455 return M_FONTDATA->m_underlined;
456 }
457
458 wxFontEncoding wxFont::GetEncoding() const
459 {
460 wxCHECK_MSG( Ok(), wxFONTENCODING_SYSTEM, wxT("invalid font") );
461
462 return M_FONTDATA->m_encoding;
463 }
464
465 bool wxFont::GetNoAntiAliasing() const
466 {
467 wxCHECK_MSG( Ok(), false, wxT("invalid font") );
468
469 return M_FONTDATA->m_noAA;
470 }
471
472 const wxNativeFontInfo *wxFont::GetNativeFontInfo() const
473 {
474 wxCHECK_MSG( Ok(), (wxNativeFontInfo *)NULL, wxT("invalid font") );
475
476 return &(M_FONTDATA->m_nativeFontInfo);
477 }
478
479 bool wxFont::IsFixedWidth() const
480 {
481 wxCHECK_MSG( Ok(), false, wxT("invalid font") );
482
483 return wxFontBase::IsFixedWidth();
484 }
485
486 // ----------------------------------------------------------------------------
487 // change font attributes
488 // ----------------------------------------------------------------------------
489
490 void wxFont::SetPointSize(int pointSize)
491 {
492 AllocExclusive();
493
494 M_FONTDATA->SetPointSize(pointSize);
495 }
496
497 void wxFont::SetFamily(int family)
498 {
499 AllocExclusive();
500
501 M_FONTDATA->SetFamily(family);
502 }
503
504 void wxFont::SetStyle(int style)
505 {
506 AllocExclusive();
507
508 M_FONTDATA->SetStyle(style);
509 }
510
511 void wxFont::SetWeight(int weight)
512 {
513 AllocExclusive();
514
515 M_FONTDATA->SetWeight(weight);
516 }
517
518 bool wxFont::SetFaceName(const wxString& faceName)
519 {
520 AllocExclusive();
521
522 return M_FONTDATA->SetFaceName(faceName) &&
523 wxFontBase::SetFaceName(faceName);
524 }
525
526 void wxFont::SetUnderlined(bool underlined)
527 {
528 AllocExclusive();
529
530 M_FONTDATA->SetUnderlined(underlined);
531 }
532
533 void wxFont::SetEncoding(wxFontEncoding encoding)
534 {
535 AllocExclusive();
536
537 M_FONTDATA->SetEncoding(encoding);
538 }
539
540 void wxFont::DoSetNativeFontInfo( const wxNativeFontInfo& info )
541 {
542 AllocExclusive();
543
544 M_FONTDATA->SetNativeFontInfo( info );
545 }
546
547 void wxFont::SetNoAntiAliasing( bool no )
548 {
549 AllocExclusive();
550
551 M_FONTDATA->SetNoAntiAliasing( no );
552 }
553
554 wxObjectRefData* wxFont::CreateRefData() const
555 {
556 return new wxFontRefData;
557 }
558
559 wxObjectRefData* wxFont::CloneRefData(const wxObjectRefData* data) const
560 {
561 return new wxFontRefData(*wx_static_cast(const wxFontRefData*, data));
562 }