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