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