]> git.saurik.com Git - wxWidgets.git/blob - src/gtk/font.cpp
use the encoding of the font which is used to draw the text when convering it to...
[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;
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,
167 wxGTK_CONV_SYS(m_faceName) );
168 }
169 else
170 {
171 switch (m_family)
172 {
173 case wxFONTFAMILY_MODERN:
174 case wxFONTFAMILY_TELETYPE:
175 pango_font_description_set_family( m_nativeFontInfo.description, "monospace" );
176 break;
177 case wxFONTFAMILY_ROMAN:
178 pango_font_description_set_family( m_nativeFontInfo.description, "serif" );
179 break;
180 case wxFONTFAMILY_SWISS:
181 // SWISS = sans serif
182 default:
183 pango_font_description_set_family( m_nativeFontInfo.description, "sans" );
184 break;
185 }
186 }
187
188 SetStyle( m_style );
189 SetPointSize( m_pointSize );
190 SetWeight( m_weight );
191 }
192
193 void wxFontRefData::InitFromNative()
194 {
195 m_noAA = FALSE;
196
197 // Get native info
198 PangoFontDescription *desc = m_nativeFontInfo.description;
199
200 // init fields
201 m_faceName = wxGTK_CONV_BACK( pango_font_description_get_family( desc ) );
202
203 // Pango sometimes needs to have a size
204 int pango_size = pango_font_description_get_size( desc );
205 if (pango_size == 0)
206 m_nativeFontInfo.SetPointSize(12);
207
208 m_pointSize = m_nativeFontInfo.GetPointSize();
209 m_style = m_nativeFontInfo.GetStyle();
210 m_weight = m_nativeFontInfo.GetWeight();
211
212 if (m_faceName == wxT("monospace"))
213 {
214 m_family = wxFONTFAMILY_TELETYPE;
215 }
216 else if (m_faceName == wxT("sans"))
217 {
218 m_family = wxFONTFAMILY_SWISS;
219 }
220 else if (m_faceName == wxT("serif"))
221 {
222 m_family = wxFONTFAMILY_ROMAN;
223 }
224 else
225 {
226 m_family = wxFONTFAMILY_UNKNOWN;
227 }
228
229 // Pango description are never underlined (?)
230 m_underlined = FALSE;
231
232 // always with GTK+ 2
233 m_encoding = wxFONTENCODING_UTF8;
234 }
235
236 wxFontRefData::wxFontRefData( const wxFontRefData& data )
237 : wxObjectRefData()
238 {
239 m_pointSize = data.m_pointSize;
240 m_family = data.m_family;
241 m_style = data.m_style;
242 m_weight = data.m_weight;
243
244 m_underlined = data.m_underlined;
245
246 m_faceName = data.m_faceName;
247 m_encoding = data.m_encoding;
248
249 m_noAA = data.m_noAA;
250
251 // Forces a copy of the internal data. wxNativeFontInfo should probably
252 // have a copy ctor and assignment operator to fix this properly but that
253 // would break binary compatibility...
254 m_nativeFontInfo.FromString(data.m_nativeFontInfo.ToString());
255 }
256
257 wxFontRefData::wxFontRefData(int size, int family, int style,
258 int weight, bool underlined,
259 const wxString& faceName,
260 wxFontEncoding encoding)
261 {
262 Init(size, family, style, weight, underlined, faceName, encoding);
263 }
264
265 wxFontRefData::wxFontRefData(const wxString& fontname)
266 {
267 m_nativeFontInfo.FromString( fontname );
268
269 InitFromNative();
270 }
271
272 void wxFontRefData::ClearGdkFonts()
273 {
274 }
275
276 wxFontRefData::~wxFontRefData()
277 {
278 ClearGdkFonts();
279 }
280
281 // ----------------------------------------------------------------------------
282 // wxFontRefData SetXXX()
283 // ----------------------------------------------------------------------------
284
285 void wxFontRefData::SetPointSize(int pointSize)
286 {
287 m_pointSize = pointSize;
288
289 m_nativeFontInfo.SetPointSize(pointSize);
290 }
291
292 void wxFontRefData::SetFamily(int family)
293 {
294 m_family = family;
295
296 // TODO: what are we supposed to do with m_nativeFontInfo here?
297 }
298
299 void wxFontRefData::SetStyle(int style)
300 {
301 m_style = style;
302
303 m_nativeFontInfo.SetStyle((wxFontStyle)style);
304 }
305
306 void wxFontRefData::SetWeight(int weight)
307 {
308 m_weight = weight;
309
310 m_nativeFontInfo.SetWeight((wxFontWeight)weight);
311 }
312
313 void wxFontRefData::SetUnderlined(bool underlined)
314 {
315 m_underlined = underlined;
316
317 // the XLFD doesn't have "underlined" field anyhow
318 }
319
320 void wxFontRefData::SetFaceName(const wxString& facename)
321 {
322 m_faceName = facename;
323
324 m_nativeFontInfo.SetFaceName(facename);
325 }
326
327 void wxFontRefData::SetEncoding(wxFontEncoding encoding)
328 {
329 m_encoding = encoding;
330 }
331
332 void wxFontRefData::SetNativeFontInfo(const wxNativeFontInfo& info)
333 {
334 // previously cached fonts shouldn't be used
335 ClearGdkFonts();
336
337 m_nativeFontInfo = info;
338
339 // set all the other font parameters from the native font info
340 InitFromNative();
341 }
342
343 // ----------------------------------------------------------------------------
344 // wxFont creation
345 // ----------------------------------------------------------------------------
346
347 IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
348
349 wxFont::wxFont(const wxNativeFontInfo& info)
350 {
351 Create( info.GetPointSize(),
352 info.GetFamily(),
353 info.GetStyle(),
354 info.GetWeight(),
355 info.GetUnderlined(),
356 info.GetFaceName(),
357 info.GetEncoding() );
358 }
359
360 bool wxFont::Create( int pointSize,
361 int family,
362 int style,
363 int weight,
364 bool underlined,
365 const wxString& face,
366 wxFontEncoding encoding)
367 {
368 UnRef();
369
370 m_refData = new wxFontRefData(pointSize, family, style, weight,
371 underlined, face, encoding);
372
373 return TRUE;
374 }
375
376 bool wxFont::Create(const wxString& fontname)
377 {
378 // VZ: does this really happen?
379 if ( fontname.empty() )
380 {
381 *this = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
382
383 return TRUE;
384 }
385
386 m_refData = new wxFontRefData(fontname);
387
388 return TRUE;
389 }
390
391 void wxFont::Unshare()
392 {
393 if (!m_refData)
394 {
395 m_refData = new wxFontRefData();
396 }
397 else
398 {
399 wxFontRefData* ref = new wxFontRefData(*(wxFontRefData*)m_refData);
400 UnRef();
401 m_refData = ref;
402 }
403 }
404
405 wxFont::~wxFont()
406 {
407 }
408
409 // ----------------------------------------------------------------------------
410 // accessors
411 // ----------------------------------------------------------------------------
412
413 int wxFont::GetPointSize() const
414 {
415 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
416
417 #if wxUSE_PANGO
418 return M_FONTDATA->HasNativeFont() ? M_FONTDATA->m_nativeFontInfo.GetPointSize()
419 : M_FONTDATA->m_pointSize;
420 #else
421 return M_FONTDATA->m_pointSize;
422 #endif
423 }
424
425 wxString wxFont::GetFaceName() const
426 {
427 wxCHECK_MSG( Ok(), wxT(""), wxT("invalid font") );
428
429 #if wxUSE_PANGO
430 return M_FONTDATA->HasNativeFont() ? M_FONTDATA->m_nativeFontInfo.GetFaceName()
431 : M_FONTDATA->m_faceName;
432 #else
433 return M_FONTDATA->m_faceName;
434 #endif
435 }
436
437 int wxFont::GetFamily() const
438 {
439 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
440
441 #if wxUSE_PANGO
442 int ret = M_FONTDATA->m_family;
443 if (M_FONTDATA->HasNativeFont())
444 // wxNativeFontInfo::GetFamily is expensive, must not call more than once
445 ret = M_FONTDATA->m_nativeFontInfo.GetFamily();
446
447 if (ret == wxFONTFAMILY_DEFAULT)
448 ret = M_FONTDATA->m_family;
449
450 return ret;
451 #else
452 return M_FONTDATA->m_family;
453 #endif
454 }
455
456 int wxFont::GetStyle() const
457 {
458 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
459
460 #if wxUSE_PANGO
461 return M_FONTDATA->HasNativeFont() ? M_FONTDATA->m_nativeFontInfo.GetStyle()
462 : M_FONTDATA->m_style;
463 #else
464 return M_FONTDATA->m_style;
465 #endif
466 }
467
468 int wxFont::GetWeight() const
469 {
470 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
471
472 #if wxUSE_PANGO
473 return M_FONTDATA->HasNativeFont() ? M_FONTDATA->m_nativeFontInfo.GetWeight()
474 : M_FONTDATA->m_weight;
475 #else
476 return M_FONTDATA->m_weight;
477 #endif
478 }
479
480 bool wxFont::GetUnderlined() const
481 {
482 wxCHECK_MSG( Ok(), FALSE, wxT("invalid font") );
483
484 return M_FONTDATA->m_underlined;
485 }
486
487 wxFontEncoding wxFont::GetEncoding() const
488 {
489 wxCHECK_MSG( Ok(), wxFONTENCODING_SYSTEM, wxT("invalid font") );
490
491 return M_FONTDATA->m_encoding;
492 }
493
494 bool wxFont::GetNoAntiAliasing() const
495 {
496 wxCHECK_MSG( Ok(), false, wxT("invalid font") );
497
498 return M_FONTDATA->m_noAA;
499 }
500
501 const wxNativeFontInfo *wxFont::GetNativeFontInfo() const
502 {
503 wxCHECK_MSG( Ok(), (wxNativeFontInfo *)NULL, wxT("invalid font") );
504
505 return &(M_FONTDATA->m_nativeFontInfo);
506 }
507
508 bool wxFont::IsFixedWidth() const
509 {
510 wxCHECK_MSG( Ok(), FALSE, wxT("invalid font") );
511
512 return wxFontBase::IsFixedWidth();
513 }
514
515 // ----------------------------------------------------------------------------
516 // change font attributes
517 // ----------------------------------------------------------------------------
518
519 void wxFont::SetPointSize(int pointSize)
520 {
521 Unshare();
522
523 M_FONTDATA->SetPointSize(pointSize);
524 }
525
526 void wxFont::SetFamily(int family)
527 {
528 Unshare();
529
530 M_FONTDATA->SetFamily(family);
531 }
532
533 void wxFont::SetStyle(int style)
534 {
535 Unshare();
536
537 M_FONTDATA->SetStyle(style);
538 }
539
540 void wxFont::SetWeight(int weight)
541 {
542 Unshare();
543
544 M_FONTDATA->SetWeight(weight);
545 }
546
547 void wxFont::SetFaceName(const wxString& faceName)
548 {
549 Unshare();
550
551 M_FONTDATA->SetFaceName(faceName);
552 }
553
554 void wxFont::SetUnderlined(bool underlined)
555 {
556 Unshare();
557
558 M_FONTDATA->SetUnderlined(underlined);
559 }
560
561 void wxFont::SetEncoding(wxFontEncoding encoding)
562 {
563 Unshare();
564
565 M_FONTDATA->SetEncoding(encoding);
566 }
567
568 void wxFont::DoSetNativeFontInfo( const wxNativeFontInfo& info )
569 {
570 Unshare();
571
572 M_FONTDATA->SetNativeFontInfo( info );
573 }
574
575 void wxFont::SetNoAntiAliasing( bool no )
576 {
577 Unshare();
578
579 M_FONTDATA->SetNoAntiAliasing( no );
580 }