]> git.saurik.com Git - wxWidgets.git/blob - src/gtk/font.cpp
c27134680f81880480b1c48b9fe5b957f0f7c0a8
[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, T("-") );
166
167 tn.GetNextToken(); // foundry
168
169 M_FONTDATA->m_faceName = tn.GetNextToken(); // courier
170
171 tmp = tn.GetNextToken().MakeUpper();
172 if (tmp == T("BOLD")) M_FONTDATA->m_weight = wxBOLD;
173
174 tmp = tn.GetNextToken().MakeUpper();
175 if (tmp == T("I")) M_FONTDATA->m_style = wxITALIC;
176 if (tmp == T("O")) M_FONTDATA->m_style = wxITALIC;
177
178 tn.GetNextToken(); // set width
179 tn.GetNextToken(); // ?
180 tn.GetNextToken(); // pixel size
181
182 tmp = tn.GetNextToken(); // pointsize
183 int num = wxStrtol (tmp.c_str(), (wxChar **) NULL, 10);
184 M_FONTDATA->m_pointSize = num / 10;
185
186 tn.GetNextToken(); // x-res
187 tn.GetNextToken(); // y-res
188
189 tmp = tn.GetNextToken().MakeUpper();
190 if (tmp == T("M")) M_FONTDATA->m_family = wxMODERN;
191 else if (M_FONTDATA->m_faceName == T("TIMES")) M_FONTDATA->m_family = wxROMAN;
192 else if (M_FONTDATA->m_faceName == T("HELVETICA")) M_FONTDATA->m_family = wxSWISS;
193 else if (M_FONTDATA->m_faceName == T("LUCIDATYPEWRITER")) M_FONTDATA->m_family = wxTELETYPE;
194 else if (M_FONTDATA->m_faceName == T("LUCIDA")) M_FONTDATA->m_family = wxDECORATIVE;
195 else if (M_FONTDATA->m_faceName == T("UTOPIA")) M_FONTDATA->m_family = wxSCRIPT;
196 }
197
198 bool wxFont::Create( int pointSize,
199 int family,
200 int style,
201 int weight,
202 bool underlined,
203 const wxString& face,
204 wxFontEncoding encoding )
205 {
206 m_refData = new wxFontRefData(pointSize, family, style, weight,
207 underlined, face, encoding);
208
209 return TRUE;
210 }
211
212 void wxFont::Unshare()
213 {
214 if (!m_refData)
215 {
216 m_refData = new wxFontRefData();
217 }
218 else
219 {
220 wxFontRefData* ref = new wxFontRefData(*(wxFontRefData*)m_refData);
221 UnRef();
222 m_refData = ref;
223 }
224 }
225
226 wxFont::~wxFont()
227 {
228 if (wxTheFontList)
229 wxTheFontList->DeleteObject( this );
230 }
231
232 // ----------------------------------------------------------------------------
233 // accessors
234 // ----------------------------------------------------------------------------
235
236 int wxFont::GetPointSize() const
237 {
238 wxCHECK_MSG( Ok(), 0, T("invalid font") );
239
240 return M_FONTDATA->m_pointSize;
241 }
242
243 wxString wxFont::GetFaceName() const
244 {
245 wxCHECK_MSG( Ok(), T(""), T("invalid font") );
246
247 return M_FONTDATA->m_faceName;
248 }
249
250 int wxFont::GetFamily() const
251 {
252 wxCHECK_MSG( Ok(), 0, T("invalid font") );
253
254 return M_FONTDATA->m_family;
255 }
256
257 int wxFont::GetStyle() const
258 {
259 wxCHECK_MSG( Ok(), 0, T("invalid font") );
260
261 return M_FONTDATA->m_style;
262 }
263
264 int wxFont::GetWeight() const
265 {
266 wxCHECK_MSG( Ok(), 0, T("invalid font") );
267
268 return M_FONTDATA->m_weight;
269 }
270
271 bool wxFont::GetUnderlined() const
272 {
273 wxCHECK_MSG( Ok(), FALSE, T("invalid font") );
274
275 return M_FONTDATA->m_underlined;
276 }
277
278
279 wxFontEncoding wxFont::GetEncoding() const
280 {
281 wxCHECK_MSG( Ok(), wxFONTENCODING_DEFAULT, T("invalid font") );
282
283 return M_FONTDATA->m_encoding;
284 }
285
286 // ----------------------------------------------------------------------------
287 // change font attributes
288 // ----------------------------------------------------------------------------
289
290 void wxFont::SetPointSize(int pointSize)
291 {
292 Unshare();
293
294 M_FONTDATA->m_pointSize = pointSize;
295 }
296
297 void wxFont::SetFamily(int family)
298 {
299 Unshare();
300
301 M_FONTDATA->m_family = family;
302 }
303
304 void wxFont::SetStyle(int style)
305 {
306 Unshare();
307
308 M_FONTDATA->m_style = style;
309 }
310
311 void wxFont::SetWeight(int weight)
312 {
313 Unshare();
314
315 M_FONTDATA->m_weight = weight;
316 }
317
318 void wxFont::SetFaceName(const wxString& faceName)
319 {
320 Unshare();
321
322 M_FONTDATA->m_faceName = faceName;
323 }
324
325 void wxFont::SetUnderlined(bool underlined)
326 {
327 Unshare();
328
329 M_FONTDATA->m_underlined = underlined;
330 }
331
332 void wxFont::SetEncoding(wxFontEncoding encoding)
333 {
334 Unshare();
335
336 M_FONTDATA->m_encoding = encoding;
337 }
338
339 // ----------------------------------------------------------------------------
340 // get internal representation of font
341 // ----------------------------------------------------------------------------
342
343 GdkFont *wxFont::GetInternalFont( float scale ) const
344 {
345 if (!Ok())
346 {
347 wxFAIL_MSG( T("invalid font") );
348
349 return (GdkFont*) NULL;
350 }
351
352 long int_scale = long(scale * 100.0 + 0.5); /* key for fontlist */
353 int point_scale = (M_FONTDATA->m_pointSize * 10 * int_scale) / 100;
354 GdkFont *font = (GdkFont *) NULL;
355
356 wxNode *node = M_FONTDATA->m_scaled_xfonts.Find(int_scale);
357 if (node)
358 {
359 font = (GdkFont*)node->Data();
360 }
361 else
362 {
363 #if 0
364 if ((int_scale == 100) &&
365 (M_FONTDATA->m_family == wxSWISS) &&
366 (M_FONTDATA->m_style == wxNORMAL) &&
367 (M_FONTDATA->m_pointSize == 12) &&
368 (M_FONTDATA->m_weight == wxNORMAL) &&
369 (M_FONTDATA->m_underlined == FALSE))
370 {
371 font = gdk_font_load( "-adobe-helvetica-medium-r-normal--*-120-*-*-*-*-*-*" );
372 }
373 else
374 #endif // 0
375 {
376 font = wxLoadQueryNearestFont( point_scale,
377 M_FONTDATA->m_family,
378 M_FONTDATA->m_style,
379 M_FONTDATA->m_weight,
380 M_FONTDATA->m_underlined,
381 M_FONTDATA->m_faceName,
382 M_FONTDATA->m_encoding );
383 }
384
385 M_FONTDATA->m_scaled_xfonts.Append( int_scale, (wxObject*)font );
386 }
387
388 if (!font)
389 {
390 wxLogError(T("could not load any font"));
391 }
392
393 return font;
394 }
395