]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/gtk/font.cpp
Added conversion of menu labels (&->~)
[wxWidgets.git] / src / gtk / font.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: font.cpp
3// Purpose:
4// Author: Robert Roebling
5// Id: $Id$
6// Copyright: (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
7// Licence: wxWindows licence
8/////////////////////////////////////////////////////////////////////////////
9
10// ============================================================================
11// declarations
12// ============================================================================
13
14// ----------------------------------------------------------------------------
15// headers
16// ----------------------------------------------------------------------------
17
18#ifdef __GNUG__
19 #pragma implementation "font.h"
20#endif
21
22#include "wx/font.h"
23#include "wx/fontutil.h"
24#include "wx/cmndata.h"
25#include "wx/utils.h"
26#include "wx/log.h"
27#include "wx/gdicmn.h"
28#include "wx/tokenzr.h"
29#include "wx/settings.h"
30
31#include <strings.h>
32
33#include <gdk/gdk.h>
34#include <gtk/gtk.h>
35
36// ----------------------------------------------------------------------------
37// wxFontRefData
38// ----------------------------------------------------------------------------
39
40class wxFontRefData : public wxObjectRefData
41{
42public:
43 wxFontRefData(int size = wxDEFAULT,
44 int family = wxDEFAULT,
45 int style = wxDEFAULT,
46 int weight = wxDEFAULT,
47 bool underlined = FALSE,
48 const wxString& faceName = wxEmptyString,
49 wxFontEncoding encoding = wxFONTENCODING_DEFAULT);
50 wxFontRefData( const wxFontRefData& data );
51 virtual ~wxFontRefData();
52
53protected:
54 // common part of all ctors
55 void Init(int pointSize,
56 int family,
57 int style,
58 int weight,
59 bool underlined,
60 const wxString& faceName,
61 wxFontEncoding encoding);
62
63private:
64 wxList m_scaled_xfonts;
65 int m_pointSize;
66 int m_family,
67 m_style,
68 m_weight;
69 bool m_underlined;
70 wxString m_faceName;
71 wxFontEncoding m_encoding;
72
73 friend wxFont;
74};
75
76// ============================================================================
77// implementation
78// ============================================================================
79
80// ----------------------------------------------------------------------------
81// wxFontRefData
82// ----------------------------------------------------------------------------
83
84void wxFontRefData::Init(int pointSize,
85 int family,
86 int style,
87 int weight,
88 bool underlined,
89 const wxString& faceName,
90 wxFontEncoding encoding)
91{
92 if (family == wxDEFAULT)
93 m_family = wxSWISS;
94 else
95 m_family = family;
96
97 m_faceName = faceName;
98
99 if (style == wxDEFAULT)
100 m_style = wxNORMAL;
101 else
102 m_style = style;
103
104 if (weight == wxDEFAULT)
105 m_weight = wxNORMAL;
106 else
107 m_weight = weight;
108
109 if (pointSize == wxDEFAULT)
110 m_pointSize = 12;
111 else
112 m_pointSize = pointSize;
113
114 m_underlined = underlined;
115 m_encoding = encoding;
116}
117
118wxFontRefData::wxFontRefData( const wxFontRefData& data )
119 : m_scaled_xfonts(wxKEY_INTEGER)
120{
121 Init(data.m_pointSize, data.m_family, data.m_style, data.m_weight,
122 data.m_underlined, data.m_faceName, data.m_encoding);
123}
124
125wxFontRefData::wxFontRefData(int size, int family, int style,
126 int weight, bool underlined, const wxString& faceName, wxFontEncoding encoding )
127 : m_scaled_xfonts(wxKEY_INTEGER)
128{
129 Init(size, family, style, weight,
130 underlined, faceName, encoding);
131}
132
133wxFontRefData::~wxFontRefData()
134{
135 wxNode *node = m_scaled_xfonts.First();
136 while (node)
137 {
138 GdkFont *font = (GdkFont*)node->Data();
139 wxNode *next = node->Next();
140 gdk_font_unref( font );
141 node = next;
142 }
143}
144
145// ----------------------------------------------------------------------------
146// wxFont
147// ----------------------------------------------------------------------------
148
149IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
150
151void wxFont::Init()
152{
153 if (wxTheFontList)
154 wxTheFontList->Append( this );
155}
156
157wxFont::wxFont( const wxString& fontname, const wxFontData& fontdata )
158{
159 Init();
160
161 wxCHECK_RET( !!fontname, _T("invalid font spec") );
162
163 m_refData = new wxFontRefData();
164
165 wxString tmp;
166
167 wxStringTokenizer tn( fontname, wxT("-") );
168
169 tn.GetNextToken(); // skip initial empty token
170 tn.GetNextToken(); // foundry
171
172 M_FONTDATA->m_faceName = tn.GetNextToken(); // family
173
174 tmp = tn.GetNextToken().MakeUpper(); // weight
175 if (tmp == wxT("BOLD")) M_FONTDATA->m_weight = wxBOLD;
176 if (tmp == wxT("BLACK")) M_FONTDATA->m_weight = wxBOLD;
177 if (tmp == wxT("EXTRABOLD")) M_FONTDATA->m_weight = wxBOLD;
178 if (tmp == wxT("DEMIBOLD")) M_FONTDATA->m_weight = wxBOLD;
179 if (tmp == wxT("ULTRABOLD")) M_FONTDATA->m_weight = wxBOLD;
180
181 if (tmp == wxT("LIGHT")) M_FONTDATA->m_weight = wxLIGHT;
182 if (tmp == wxT("THIN")) M_FONTDATA->m_weight = wxLIGHT;
183
184 tmp = tn.GetNextToken().MakeUpper(); // slant
185 if (tmp == wxT("I")) M_FONTDATA->m_style = wxITALIC;
186 if (tmp == wxT("O")) M_FONTDATA->m_style = wxITALIC;
187
188 tn.GetNextToken(); // set width
189 tn.GetNextToken(); // add. style
190 tn.GetNextToken(); // pixel size
191
192 tmp = tn.GetNextToken(); // pointsize
193 long num = wxStrtol (tmp.c_str(), (wxChar **) NULL, 10);
194 M_FONTDATA->m_pointSize = (int)(num / 10);
195
196 tn.GetNextToken(); // x-res
197 tn.GetNextToken(); // y-res
198
199 tmp = tn.GetNextToken().MakeUpper(); // spacing
200
201 if (tmp == wxT("M"))
202 M_FONTDATA->m_family = wxMODERN;
203 else if (M_FONTDATA->m_faceName == wxT("TIMES"))
204 M_FONTDATA->m_family = wxROMAN;
205 else if (M_FONTDATA->m_faceName == wxT("HELVETICA"))
206 M_FONTDATA->m_family = wxSWISS;
207 else if (M_FONTDATA->m_faceName == wxT("LUCIDATYPEWRITER"))
208 M_FONTDATA->m_family = wxTELETYPE;
209 else if (M_FONTDATA->m_faceName == wxT("LUCIDA"))
210 M_FONTDATA->m_family = wxDECORATIVE;
211 else if (M_FONTDATA->m_faceName == wxT("UTOPIA"))
212 M_FONTDATA->m_family = wxSCRIPT;
213
214 tn.GetNextToken(); // avg width
215
216 // deal with font encoding
217 M_FONTDATA->m_encoding = fontdata.GetEncoding();
218 if ( M_FONTDATA->m_encoding == wxFONTENCODING_SYSTEM )
219 {
220 wxString registry = tn.GetNextToken().MakeUpper(),
221 encoding = tn.GetNextToken().MakeUpper();
222
223 if ( registry == _T("ISO8859") )
224 {
225 int cp;
226 if ( wxSscanf(encoding, wxT("%d"), &cp) == 1 )
227 {
228 M_FONTDATA->m_encoding =
229 (wxFontEncoding)(wxFONTENCODING_ISO8859_1 + cp - 1);
230 }
231 }
232 else if ( registry == _T("MICROSOFT") )
233 {
234 int cp;
235 if ( wxSscanf(encoding, wxT("cp125%d"), &cp) == 1 )
236 {
237 M_FONTDATA->m_encoding =
238 (wxFontEncoding)(wxFONTENCODING_CP1250 + cp);
239 }
240 }
241 else if ( registry == _T("KOI8") )
242 {
243 M_FONTDATA->m_encoding = wxFONTENCODING_KOI8;
244 }
245 //else: unknown encoding - may be give a warning here?
246 }
247}
248
249bool wxFont::Create( int pointSize,
250 int family,
251 int style,
252 int weight,
253 bool underlined,
254 const wxString& face,
255 wxFontEncoding encoding )
256{
257 m_refData = new wxFontRefData(pointSize, family, style, weight,
258 underlined, face, encoding);
259
260 return TRUE;
261}
262
263void wxFont::Unshare()
264{
265 if (!m_refData)
266 {
267 m_refData = new wxFontRefData();
268 }
269 else
270 {
271 wxFontRefData* ref = new wxFontRefData(*(wxFontRefData*)m_refData);
272 UnRef();
273 m_refData = ref;
274 }
275}
276
277wxFont::~wxFont()
278{
279 if (wxTheFontList)
280 wxTheFontList->DeleteObject( this );
281}
282
283// ----------------------------------------------------------------------------
284// accessors
285// ----------------------------------------------------------------------------
286
287int wxFont::GetPointSize() const
288{
289 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
290
291 return M_FONTDATA->m_pointSize;
292}
293
294wxString wxFont::GetFaceName() const
295{
296 wxCHECK_MSG( Ok(), wxT(""), wxT("invalid font") );
297
298 return M_FONTDATA->m_faceName;
299}
300
301int wxFont::GetFamily() const
302{
303 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
304
305 return M_FONTDATA->m_family;
306}
307
308int wxFont::GetStyle() const
309{
310 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
311
312 return M_FONTDATA->m_style;
313}
314
315int wxFont::GetWeight() const
316{
317 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
318
319 return M_FONTDATA->m_weight;
320}
321
322bool wxFont::GetUnderlined() const
323{
324 wxCHECK_MSG( Ok(), FALSE, wxT("invalid font") );
325
326 return M_FONTDATA->m_underlined;
327}
328
329
330wxFontEncoding wxFont::GetEncoding() const
331{
332 wxCHECK_MSG( Ok(), wxFONTENCODING_DEFAULT, wxT("invalid font") );
333
334 return M_FONTDATA->m_encoding;
335}
336
337// ----------------------------------------------------------------------------
338// change font attributes
339// ----------------------------------------------------------------------------
340
341void wxFont::SetPointSize(int pointSize)
342{
343 Unshare();
344
345 M_FONTDATA->m_pointSize = pointSize;
346}
347
348void wxFont::SetFamily(int family)
349{
350 Unshare();
351
352 M_FONTDATA->m_family = family;
353}
354
355void wxFont::SetStyle(int style)
356{
357 Unshare();
358
359 M_FONTDATA->m_style = style;
360}
361
362void wxFont::SetWeight(int weight)
363{
364 Unshare();
365
366 M_FONTDATA->m_weight = weight;
367}
368
369void wxFont::SetFaceName(const wxString& faceName)
370{
371 Unshare();
372
373 M_FONTDATA->m_faceName = faceName;
374}
375
376void wxFont::SetUnderlined(bool underlined)
377{
378 Unshare();
379
380 M_FONTDATA->m_underlined = underlined;
381}
382
383void wxFont::SetEncoding(wxFontEncoding encoding)
384{
385 Unshare();
386
387 M_FONTDATA->m_encoding = encoding;
388}
389
390// ----------------------------------------------------------------------------
391// get internal representation of font
392// ----------------------------------------------------------------------------
393
394static GdkFont *g_systemDefaultGuiFont = (GdkFont*) NULL;
395
396static GdkFont *GtkGetDefaultGuiFont()
397{
398 if (!g_systemDefaultGuiFont)
399 {
400 GtkWidget *widget = gtk_button_new();
401 GtkStyle *def = gtk_rc_get_style( widget );
402 if (def)
403 {
404 g_systemDefaultGuiFont = gdk_font_ref( def->font );
405 }
406 else
407 {
408 def = gtk_widget_get_default_style();
409 if (def)
410 g_systemDefaultGuiFont = gdk_font_ref( def->font );
411 }
412 gtk_widget_destroy( widget );
413 }
414 return g_systemDefaultGuiFont;
415}
416
417GdkFont *wxFont::GetInternalFont( float scale ) const
418{
419 if (!Ok())
420 {
421 wxFAIL_MSG( wxT("invalid font") );
422
423 return (GdkFont*) NULL;
424 }
425
426 long int_scale = long(scale * 100.0 + 0.5); /* key for fontlist */
427 int point_scale = (int)((M_FONTDATA->m_pointSize * 10 * int_scale) / 100);
428 GdkFont *font = (GdkFont *) NULL;
429
430 wxNode *node = M_FONTDATA->m_scaled_xfonts.Find(int_scale);
431 if (node)
432 {
433 font = (GdkFont*)node->Data();
434 }
435 else
436 {
437 if (*this == wxSystemSettings::GetSystemFont( wxSYS_DEFAULT_GUI_FONT))
438 {
439 font = GtkGetDefaultGuiFont();
440 }
441 if (!font)
442 {
443 font = wxLoadQueryNearestFont( point_scale,
444 M_FONTDATA->m_family,
445 M_FONTDATA->m_style,
446 M_FONTDATA->m_weight,
447 M_FONTDATA->m_underlined,
448 M_FONTDATA->m_faceName,
449 M_FONTDATA->m_encoding );
450 }
451
452 M_FONTDATA->m_scaled_xfonts.Append( int_scale, (wxObject*)font );
453 }
454
455 // it's quite useless to make it a wxCHECK because we're going to crash
456 // anyhow...
457 wxASSERT_MSG( font, wxT("could not load any font?") );
458
459 return font;
460}
461