]> git.saurik.com Git - wxWidgets.git/blob - src/gtk/font.cpp
added operator[](unsigned int) const -- testing it now on Linux/axp,
[wxWidgets.git] / src / gtk / font.cpp
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/utils.h"
24 #include "wx/log.h"
25 #include "wx/gdicmn.h"
26 #include "wx/tokenzr.h"
27
28 #include <strings.h>
29
30 #include "gdk/gdk.h"
31
32 // ----------------------------------------------------------------------------
33 // wxFontRefData
34 // ----------------------------------------------------------------------------
35
36 class wxFontRefData : public wxObjectRefData
37 {
38 public:
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,
45 wxFontEncoding encoding = wxFONTENCODING_DEFAULT);
46 wxFontRefData( const wxFontRefData& data );
47 virtual ~wxFontRefData();
48
49 protected:
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
59 private:
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;
68
69 friend wxFont;
70 };
71
72 // ============================================================================
73 // implementation
74 // ============================================================================
75
76 // ----------------------------------------------------------------------------
77 // wxFontRefData
78 // ----------------------------------------------------------------------------
79
80 void wxFontRefData::Init(int pointSize,
81 int family,
82 int style,
83 int weight,
84 bool underlined,
85 const wxString& faceName,
86 wxFontEncoding encoding)
87 {
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;
112 }
113
114 wxFontRefData::wxFontRefData( const wxFontRefData& data )
115 : m_scaled_xfonts(wxKEY_INTEGER)
116 {
117 Init(data.m_pointSize, data.m_family, data.m_style, data.m_weight,
118 data.m_underlined, data.m_faceName, data.m_encoding);
119 }
120
121 wxFontRefData::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);
127 }
128
129 wxFontRefData::~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 }
139 }
140
141 // ----------------------------------------------------------------------------
142 // wxFont
143 // ----------------------------------------------------------------------------
144
145 IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
146
147 void wxFont::Init()
148 {
149 if (wxTheFontList)
150 wxTheFontList->Append( this );
151 }
152
153 wxFont::wxFont( GdkFont *WXUNUSED(font), char *xFontName )
154 {
155 if (!xFontName)
156 return;
157
158 Init();
159
160 m_refData = new wxFontRefData();
161
162 wxString tmp;
163
164 wxString fontname( xFontName );
165 wxStringTokenizer tn( fontname, wxT("-") );
166
167 tn.GetNextToken(); // foundry
168
169 M_FONTDATA->m_faceName = tn.GetNextToken(); // family
170
171 tmp = tn.GetNextToken().MakeUpper(); // weight
172 if (tmp == wxT("BOLD")) M_FONTDATA->m_weight = wxBOLD;
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
181 tmp = tn.GetNextToken().MakeUpper(); // slant
182 if (tmp == wxT("I")) M_FONTDATA->m_style = wxITALIC;
183 if (tmp == wxT("O")) M_FONTDATA->m_style = wxITALIC;
184
185 tn.GetNextToken(); // set width
186 tn.GetNextToken(); // add. style
187 tn.GetNextToken(); // pixel size
188
189 tmp = tn.GetNextToken(); // pointsize
190 long num = wxStrtol (tmp.c_str(), (wxChar **) NULL, 10);
191 M_FONTDATA->m_pointSize = num / 10;
192
193 tn.GetNextToken(); // x-res
194 tn.GetNextToken(); // y-res
195
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;
220 if ( wxSscanf(encoding, wxT("%d"), &cp) == 1 )
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;
229 if ( wxSscanf(encoding, wxT("cp125%d"), &cp) == 1 )
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?
240 }
241
242 bool wxFont::Create( int pointSize,
243 int family,
244 int style,
245 int weight,
246 bool underlined,
247 const wxString& face,
248 wxFontEncoding encoding )
249 {
250 m_refData = new wxFontRefData(pointSize, family, style, weight,
251 underlined, face, encoding);
252
253 return TRUE;
254 }
255
256 void wxFont::Unshare()
257 {
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 }
268 }
269
270 wxFont::~wxFont()
271 {
272 if (wxTheFontList)
273 wxTheFontList->DeleteObject( this );
274 }
275
276 // ----------------------------------------------------------------------------
277 // accessors
278 // ----------------------------------------------------------------------------
279
280 int wxFont::GetPointSize() const
281 {
282 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
283
284 return M_FONTDATA->m_pointSize;
285 }
286
287 wxString wxFont::GetFaceName() const
288 {
289 wxCHECK_MSG( Ok(), wxT(""), wxT("invalid font") );
290
291 return M_FONTDATA->m_faceName;
292 }
293
294 int wxFont::GetFamily() const
295 {
296 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
297
298 return M_FONTDATA->m_family;
299 }
300
301 int wxFont::GetStyle() const
302 {
303 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
304
305 return M_FONTDATA->m_style;
306 }
307
308 int wxFont::GetWeight() const
309 {
310 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
311
312 return M_FONTDATA->m_weight;
313 }
314
315 bool wxFont::GetUnderlined() const
316 {
317 wxCHECK_MSG( Ok(), FALSE, wxT("invalid font") );
318
319 return M_FONTDATA->m_underlined;
320 }
321
322
323 wxFontEncoding wxFont::GetEncoding() const
324 {
325 wxCHECK_MSG( Ok(), wxFONTENCODING_DEFAULT, wxT("invalid font") );
326
327 return M_FONTDATA->m_encoding;
328 }
329
330 // ----------------------------------------------------------------------------
331 // change font attributes
332 // ----------------------------------------------------------------------------
333
334 void wxFont::SetPointSize(int pointSize)
335 {
336 Unshare();
337
338 M_FONTDATA->m_pointSize = pointSize;
339 }
340
341 void wxFont::SetFamily(int family)
342 {
343 Unshare();
344
345 M_FONTDATA->m_family = family;
346 }
347
348 void wxFont::SetStyle(int style)
349 {
350 Unshare();
351
352 M_FONTDATA->m_style = style;
353 }
354
355 void wxFont::SetWeight(int weight)
356 {
357 Unshare();
358
359 M_FONTDATA->m_weight = weight;
360 }
361
362 void wxFont::SetFaceName(const wxString& faceName)
363 {
364 Unshare();
365
366 M_FONTDATA->m_faceName = faceName;
367 }
368
369 void wxFont::SetUnderlined(bool underlined)
370 {
371 Unshare();
372
373 M_FONTDATA->m_underlined = underlined;
374 }
375
376 void wxFont::SetEncoding(wxFontEncoding encoding)
377 {
378 Unshare();
379
380 M_FONTDATA->m_encoding = encoding;
381 }
382
383 // ----------------------------------------------------------------------------
384 // get internal representation of font
385 // ----------------------------------------------------------------------------
386
387 GdkFont *wxFont::GetInternalFont( float scale ) const
388 {
389 if (!Ok())
390 {
391 wxFAIL_MSG( wxT("invalid font") );
392
393 return (GdkFont*) NULL;
394 }
395
396 long int_scale = long(scale * 100.0 + 0.5); /* key for fontlist */
397 int point_scale = (int)((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 {
407 #if 0
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
418 #endif // 0
419 {
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 );
427 }
428
429 M_FONTDATA->m_scaled_xfonts.Append( int_scale, (wxObject*)font );
430 }
431
432 if (!font)
433 {
434 wxLogError(wxT("could not load any font"));
435 }
436
437 return font;
438 }
439