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