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