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