]> git.saurik.com Git - wxWidgets.git/blob - src/gtk/font.cpp
5ca1b2b600049bccc51795395affeebb107bf003
[wxWidgets.git] / src / gtk / font.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/gtk/font.cpp
3 // Purpose: wxFont for wxGTK
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/gdicmn.h"
28 #endif
29
30 #include "wx/fontutil.h"
31 #include "wx/tokenzr.h"
32
33 #include "wx/gtk/private.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 // wxFontRefData
44 // ----------------------------------------------------------------------------
45
46 class wxFontRefData : public wxGDIRefData
47 {
48 public:
49 // from broken down font parameters, also default ctor
50 wxFontRefData(int size = -1,
51 wxFontFamily family = wxFONTFAMILY_DEFAULT,
52 wxFontStyle style = wxFONTSTYLE_NORMAL,
53 wxFontWeight weight = wxFONTWEIGHT_NORMAL,
54 bool underlined = false,
55 const wxString& faceName = wxEmptyString,
56 wxFontEncoding encoding = wxFONTENCODING_DEFAULT);
57
58 wxFontRefData(const wxString& nativeFontInfoString);
59
60 // copy ctor
61 wxFontRefData( const wxFontRefData& data );
62
63 virtual ~wxFontRefData();
64
65 // setters: all of them also take care to modify m_nativeFontInfo if we
66 // have it so as to not lose the information not carried by our fields
67 void SetPointSize(int pointSize);
68 void SetFamily(wxFontFamily family);
69 void SetStyle(wxFontStyle style);
70 void SetWeight(wxFontWeight weight);
71 void SetUnderlined(bool underlined);
72 bool SetFaceName(const wxString& facename);
73 void SetEncoding(wxFontEncoding encoding);
74
75 // and this one also modifies all the other font data fields
76 void SetNativeFontInfo(const wxNativeFontInfo& info);
77
78 protected:
79 // common part of all ctors
80 void Init(int pointSize,
81 wxFontFamily family,
82 wxFontStyle style,
83 wxFontWeight weight,
84 bool underlined,
85 const wxString& faceName,
86 wxFontEncoding encoding);
87
88 // set all fields from (already initialized and valid) m_nativeFontInfo
89 void InitFromNative();
90
91 private:
92 bool m_underlined;
93
94 // The native font info: basically a PangoFontDescription
95 wxNativeFontInfo m_nativeFontInfo;
96
97 friend class wxFont;
98 };
99
100 #define M_FONTDATA ((wxFontRefData*)m_refData)
101
102 // ----------------------------------------------------------------------------
103 // wxFontRefData
104 // ----------------------------------------------------------------------------
105
106 void wxFontRefData::Init(int pointSize,
107 wxFontFamily family,
108 wxFontStyle style,
109 wxFontWeight weight,
110 bool underlined,
111 const wxString& faceName,
112 wxFontEncoding WXUNUSED(encoding))
113 {
114 if (family == wxFONTFAMILY_DEFAULT)
115 family = wxFONTFAMILY_SWISS;
116
117 m_underlined = underlined;
118
119 // Create native font info
120 m_nativeFontInfo.description = pango_font_description_new();
121
122 // And set its values
123 if (!faceName.empty())
124 {
125 pango_font_description_set_family( m_nativeFontInfo.description,
126 wxGTK_CONV_SYS(faceName) );
127 }
128 else
129 {
130 SetFamily(family);
131 }
132
133 SetStyle( style == wxDEFAULT ? wxFONTSTYLE_NORMAL : style );
134 SetPointSize( (pointSize == wxDEFAULT || pointSize == -1)
135 ? wxDEFAULT_FONT_SIZE
136 : pointSize );
137 SetWeight( weight == wxDEFAULT ? wxFONTWEIGHT_NORMAL : weight );
138 }
139
140 void wxFontRefData::InitFromNative()
141 {
142 // Get native info
143 PangoFontDescription *desc = m_nativeFontInfo.description;
144
145 // Pango sometimes needs to have a size
146 int pango_size = pango_font_description_get_size( desc );
147 if (pango_size == 0)
148 m_nativeFontInfo.SetPointSize(wxDEFAULT_FONT_SIZE);
149
150 // Pango description are never underlined
151 m_underlined = false;
152 }
153
154 wxFontRefData::wxFontRefData( const wxFontRefData& data )
155 : wxGDIRefData()
156 {
157 m_underlined = data.m_underlined;
158
159 // Forces a copy of the internal data. wxNativeFontInfo should probably
160 // have a copy ctor and assignment operator to fix this properly but that
161 // would break binary compatibility...
162 m_nativeFontInfo.FromString(data.m_nativeFontInfo.ToString());
163 }
164
165 wxFontRefData::wxFontRefData(int size, wxFontFamily family, wxFontStyle style,
166 wxFontWeight weight, bool underlined,
167 const wxString& faceName,
168 wxFontEncoding encoding)
169 {
170 Init(size, family, style, weight, underlined, faceName, encoding);
171 }
172
173 wxFontRefData::wxFontRefData(const wxString& nativeFontInfoString)
174 {
175 m_nativeFontInfo.FromString( nativeFontInfoString );
176
177 InitFromNative();
178 }
179
180 wxFontRefData::~wxFontRefData()
181 {
182 }
183
184 // ----------------------------------------------------------------------------
185 // wxFontRefData SetXXX()
186 // ----------------------------------------------------------------------------
187
188 void wxFontRefData::SetPointSize(int pointSize)
189 {
190 m_nativeFontInfo.SetPointSize(pointSize);
191 }
192
193 /*
194 NOTE: disabled because pango_font_description_set_absolute_size() and
195 wxDC::GetCharHeight() do not mix well: setting with the former a pixel
196 size of "30" makes the latter return 36...
197 Besides, we need to return GetPointSize() a point size value even if
198 SetPixelSize() was used and this would require further changes
199 (and use of pango_font_description_get_size_is_absolute in some places).
200
201 bool wxFontRefData::SetPixelSize(const wxSize& pixelSize)
202 {
203 wxCHECK_MSG( pixelSize.GetWidth() >= 0 && pixelSize.GetHeight() > 0, false,
204 "Negative values for the pixel size or zero pixel height are not allowed" );
205
206 if (wx_pango_version_check(1,8,0) != NULL ||
207 pixelSize.GetWidth() != 0)
208 {
209 // NOTE: pango_font_description_set_absolute_size() only sets the font height;
210 // if the user set the pixel width of the font explicitly or the pango
211 // library is too old, we cannot proceed
212 return false;
213 }
214
215 pango_font_description_set_absolute_size( m_nativeFontInfo.description,
216 pixelSize.GetHeight() * PANGO_SCALE );
217
218 return true;
219 }
220 */
221
222 void wxFontRefData::SetFamily(wxFontFamily family)
223 {
224 m_nativeFontInfo.SetFamily(family);
225 }
226
227 void wxFontRefData::SetStyle(wxFontStyle style)
228 {
229 m_nativeFontInfo.SetStyle(style);
230 }
231
232 void wxFontRefData::SetWeight(wxFontWeight weight)
233 {
234 m_nativeFontInfo.SetWeight(weight);
235 }
236
237 void wxFontRefData::SetUnderlined(bool underlined)
238 {
239 m_underlined = underlined;
240
241 // the Pango font descriptor does not have an underlined attribute
242 // (and wxNativeFontInfo::SetUnderlined asserts); rather it's
243 // wxWindowDCImpl::DoDrawText that handles underlined fonts, so we
244 // here we just need to save the underlined attribute
245 }
246
247 bool wxFontRefData::SetFaceName(const wxString& facename)
248 {
249 return m_nativeFontInfo.SetFaceName(facename);
250 }
251
252 void wxFontRefData::SetEncoding(wxFontEncoding WXUNUSED(encoding))
253 {
254 // with GTK+ 2 Pango always uses UTF8 internally, we cannot change it
255 }
256
257 void wxFontRefData::SetNativeFontInfo(const wxNativeFontInfo& info)
258 {
259 m_nativeFontInfo = info;
260
261 // set all the other font parameters from the native font info
262 InitFromNative();
263 }
264
265 // ----------------------------------------------------------------------------
266 // wxFont creation
267 // ----------------------------------------------------------------------------
268
269 wxFont::wxFont(const wxNativeFontInfo& info)
270 {
271 Create( info.GetPointSize(),
272 info.GetFamily(),
273 info.GetStyle(),
274 info.GetWeight(),
275 info.GetUnderlined(),
276 info.GetFaceName(),
277 info.GetEncoding() );
278 }
279
280 wxFont::wxFont(int pointSize,
281 wxFontFamily family,
282 int flags,
283 const wxString& face,
284 wxFontEncoding encoding)
285 {
286 m_refData = new wxFontRefData(pointSize, family,
287 GetStyleFromFlags(flags),
288 GetWeightFromFlags(flags),
289 GetUnderlinedFromFlags(flags),
290 face, encoding);
291 }
292
293 bool wxFont::Create( int pointSize,
294 wxFontFamily family,
295 wxFontStyle style,
296 wxFontWeight weight,
297 bool underlined,
298 const wxString& face,
299 wxFontEncoding encoding )
300 {
301 UnRef();
302
303 m_refData = new wxFontRefData(pointSize, family, style, weight,
304 underlined, face, encoding);
305
306 return true;
307 }
308
309 bool wxFont::Create(const wxString& fontname)
310 {
311 // VZ: does this really happen?
312 if ( fontname.empty() )
313 {
314 *this = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
315
316 return true;
317 }
318
319 m_refData = new wxFontRefData(fontname);
320
321 return true;
322 }
323
324 wxFont::~wxFont()
325 {
326 }
327
328 // ----------------------------------------------------------------------------
329 // accessors
330 // ----------------------------------------------------------------------------
331
332 int wxFont::GetPointSize() const
333 {
334 wxCHECK_MSG( IsOk(), 0, wxT("invalid font") );
335
336 return M_FONTDATA->m_nativeFontInfo.GetPointSize();
337 }
338
339 wxString wxFont::GetFaceName() const
340 {
341 wxCHECK_MSG( IsOk(), wxEmptyString, wxT("invalid font") );
342
343 return M_FONTDATA->m_nativeFontInfo.GetFaceName();
344 }
345
346 wxFontFamily wxFont::DoGetFamily() const
347 {
348 return M_FONTDATA->m_nativeFontInfo.GetFamily();
349 }
350
351 wxFontStyle wxFont::GetStyle() const
352 {
353 wxCHECK_MSG( IsOk(), wxFONTSTYLE_MAX, wxT("invalid font") );
354
355 return M_FONTDATA->m_nativeFontInfo.GetStyle();
356 }
357
358 wxFontWeight wxFont::GetWeight() const
359 {
360 wxCHECK_MSG( IsOk(), wxFONTWEIGHT_MAX, wxT("invalid font") );
361
362 return M_FONTDATA->m_nativeFontInfo.GetWeight();
363 }
364
365 bool wxFont::GetUnderlined() const
366 {
367 wxCHECK_MSG( IsOk(), false, wxT("invalid font") );
368
369 return M_FONTDATA->m_underlined;
370 }
371
372 wxFontEncoding wxFont::GetEncoding() const
373 {
374 wxCHECK_MSG( IsOk(), wxFONTENCODING_SYSTEM, wxT("invalid font") );
375
376 return wxFONTENCODING_UTF8;
377 // Pango always uses UTF8... see also SetEncoding()
378 }
379
380 const wxNativeFontInfo *wxFont::GetNativeFontInfo() const
381 {
382 wxCHECK_MSG( IsOk(), NULL, wxT("invalid font") );
383
384 return &(M_FONTDATA->m_nativeFontInfo);
385 }
386
387 bool wxFont::IsFixedWidth() const
388 {
389 wxCHECK_MSG( IsOk(), false, wxT("invalid font") );
390
391 return wxFontBase::IsFixedWidth();
392 }
393
394 // ----------------------------------------------------------------------------
395 // change font attributes
396 // ----------------------------------------------------------------------------
397
398 void wxFont::SetPointSize(int pointSize)
399 {
400 AllocExclusive();
401
402 M_FONTDATA->SetPointSize(pointSize);
403 }
404
405 void wxFont::SetFamily(wxFontFamily family)
406 {
407 AllocExclusive();
408
409 M_FONTDATA->SetFamily(family);
410 }
411
412 void wxFont::SetStyle(wxFontStyle style)
413 {
414 AllocExclusive();
415
416 M_FONTDATA->SetStyle(style);
417 }
418
419 void wxFont::SetWeight(wxFontWeight weight)
420 {
421 AllocExclusive();
422
423 M_FONTDATA->SetWeight(weight);
424 }
425
426 bool wxFont::SetFaceName(const wxString& faceName)
427 {
428 AllocExclusive();
429
430 return M_FONTDATA->SetFaceName(faceName) &&
431 wxFontBase::SetFaceName(faceName);
432 }
433
434 void wxFont::SetUnderlined(bool underlined)
435 {
436 AllocExclusive();
437
438 M_FONTDATA->SetUnderlined(underlined);
439 }
440
441 void wxFont::SetEncoding(wxFontEncoding encoding)
442 {
443 AllocExclusive();
444
445 M_FONTDATA->SetEncoding(encoding);
446 }
447
448 void wxFont::DoSetNativeFontInfo( const wxNativeFontInfo& info )
449 {
450 AllocExclusive();
451
452 M_FONTDATA->SetNativeFontInfo( info );
453 }
454
455 wxGDIRefData* wxFont::CreateGDIRefData() const
456 {
457 return new wxFontRefData;
458 }
459
460 wxGDIRefData* wxFont::CloneGDIRefData(const wxGDIRefData* data) const
461 {
462 return new wxFontRefData(*static_cast<const wxFontRefData*>(data));
463 }