]> git.saurik.com Git - wxWidgets.git/blob - src/gtk/font.cpp
Fix double deletion bug in wxGTK wxDVC dnd code.
[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 bool wxFont::Create( int pointSize,
281 wxFontFamily family,
282 wxFontStyle style,
283 wxFontWeight weight,
284 bool underlined,
285 const wxString& face,
286 wxFontEncoding encoding )
287 {
288 UnRef();
289
290 m_refData = new wxFontRefData(pointSize, family, style, weight,
291 underlined, face, encoding);
292
293 return true;
294 }
295
296 bool wxFont::Create(const wxString& fontname)
297 {
298 // VZ: does this really happen?
299 if ( fontname.empty() )
300 {
301 *this = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
302
303 return true;
304 }
305
306 m_refData = new wxFontRefData(fontname);
307
308 return true;
309 }
310
311 wxFont::~wxFont()
312 {
313 }
314
315 // ----------------------------------------------------------------------------
316 // accessors
317 // ----------------------------------------------------------------------------
318
319 int wxFont::GetPointSize() const
320 {
321 wxCHECK_MSG( IsOk(), 0, wxT("invalid font") );
322
323 return M_FONTDATA->m_nativeFontInfo.GetPointSize();
324 }
325
326 wxString wxFont::GetFaceName() const
327 {
328 wxCHECK_MSG( IsOk(), wxEmptyString, wxT("invalid font") );
329
330 return M_FONTDATA->m_nativeFontInfo.GetFaceName();
331 }
332
333 wxFontFamily wxFont::DoGetFamily() const
334 {
335 return M_FONTDATA->m_nativeFontInfo.GetFamily();
336 }
337
338 wxFontStyle wxFont::GetStyle() const
339 {
340 wxCHECK_MSG( IsOk(), wxFONTSTYLE_MAX, wxT("invalid font") );
341
342 return M_FONTDATA->m_nativeFontInfo.GetStyle();
343 }
344
345 wxFontWeight wxFont::GetWeight() const
346 {
347 wxCHECK_MSG( IsOk(), wxFONTWEIGHT_MAX, wxT("invalid font") );
348
349 return M_FONTDATA->m_nativeFontInfo.GetWeight();
350 }
351
352 bool wxFont::GetUnderlined() const
353 {
354 wxCHECK_MSG( IsOk(), false, wxT("invalid font") );
355
356 return M_FONTDATA->m_underlined;
357 }
358
359 wxFontEncoding wxFont::GetEncoding() const
360 {
361 wxCHECK_MSG( IsOk(), wxFONTENCODING_SYSTEM, wxT("invalid font") );
362
363 return wxFONTENCODING_UTF8;
364 // Pango always uses UTF8... see also SetEncoding()
365 }
366
367 const wxNativeFontInfo *wxFont::GetNativeFontInfo() const
368 {
369 wxCHECK_MSG( IsOk(), NULL, wxT("invalid font") );
370
371 return &(M_FONTDATA->m_nativeFontInfo);
372 }
373
374 bool wxFont::IsFixedWidth() const
375 {
376 wxCHECK_MSG( IsOk(), false, wxT("invalid font") );
377
378 return wxFontBase::IsFixedWidth();
379 }
380
381 // ----------------------------------------------------------------------------
382 // change font attributes
383 // ----------------------------------------------------------------------------
384
385 void wxFont::SetPointSize(int pointSize)
386 {
387 AllocExclusive();
388
389 M_FONTDATA->SetPointSize(pointSize);
390 }
391
392 void wxFont::SetFamily(wxFontFamily family)
393 {
394 AllocExclusive();
395
396 M_FONTDATA->SetFamily(family);
397 }
398
399 void wxFont::SetStyle(wxFontStyle style)
400 {
401 AllocExclusive();
402
403 M_FONTDATA->SetStyle(style);
404 }
405
406 void wxFont::SetWeight(wxFontWeight weight)
407 {
408 AllocExclusive();
409
410 M_FONTDATA->SetWeight(weight);
411 }
412
413 bool wxFont::SetFaceName(const wxString& faceName)
414 {
415 AllocExclusive();
416
417 return M_FONTDATA->SetFaceName(faceName) &&
418 wxFontBase::SetFaceName(faceName);
419 }
420
421 void wxFont::SetUnderlined(bool underlined)
422 {
423 AllocExclusive();
424
425 M_FONTDATA->SetUnderlined(underlined);
426 }
427
428 void wxFont::SetEncoding(wxFontEncoding encoding)
429 {
430 AllocExclusive();
431
432 M_FONTDATA->SetEncoding(encoding);
433 }
434
435 void wxFont::DoSetNativeFontInfo( const wxNativeFontInfo& info )
436 {
437 AllocExclusive();
438
439 M_FONTDATA->SetNativeFontInfo( info );
440 }
441
442 wxGDIRefData* wxFont::CreateGDIRefData() const
443 {
444 return new wxFontRefData;
445 }
446
447 wxGDIRefData* wxFont::CloneGDIRefData(const wxGDIRefData* data) const
448 {
449 return new wxFontRefData(*static_cast<const wxFontRefData*>(data));
450 }