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