Added missing header and missing logic. :)
[wxWidgets.git] / src / common / fontcmn.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: common/fontcmn.cpp
3 // Purpose: implementation of wxFontBase methods
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 20.09.99
7 // RCS-ID: $Id$
8 // Copyright: (c) wxWindows team
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 #ifdef __GNUG__
21 #pragma implementation "fontbase.h"
22 #endif
23
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
26
27 #ifdef __BORLANDC__
28 #pragma hdrstop
29 #endif
30
31 #ifndef WX_PRECOMP
32 #include "wx/font.h"
33 #include "wx/intl.h"
34 #endif // WX_PRECOMP
35
36 #include "wx/gdicmn.h"
37 #include "wx/fontutil.h" // for wxNativeFontInfo
38 #include "wx/fontmap.h"
39
40 #include "wx/tokenzr.h"
41
42 // ============================================================================
43 // implementation
44 // ============================================================================
45
46 // ----------------------------------------------------------------------------
47 // wxFontBase
48 // ----------------------------------------------------------------------------
49
50 wxFontEncoding wxFontBase::ms_encodingDefault = wxFONTENCODING_SYSTEM;
51
52 /* static */
53 wxFont *wxFontBase::New(int size,
54 int family,
55 int style,
56 int weight,
57 bool underlined,
58 const wxString& face,
59 wxFontEncoding encoding)
60 {
61 return new wxFont(size, family, style, weight, underlined, face, encoding);
62 }
63
64 /* static */
65 wxFont *wxFontBase::New(const wxNativeFontInfo& info)
66 {
67 return new wxFont(info);
68 }
69
70 /* static */
71 wxFont *wxFontBase::New(const wxString& strNativeFontDesc)
72 {
73 wxNativeFontInfo fontInfo;
74 if ( !fontInfo.FromString(strNativeFontDesc) )
75 return new wxFont(*wxNORMAL_FONT);
76
77 return New(fontInfo);
78 }
79
80 wxNativeFontInfo *wxFontBase::GetNativeFontInfo() const
81 {
82 #ifdef wxNO_NATIVE_FONTINFO
83 wxNativeFontInfo *fontInfo = new wxNativeFontInfo();
84
85 fontInfo->SetPointSize(GetPointSize());
86 fontInfo->SetFamily(GetFamily());
87 fontInfo->SetStyle((wxFontStyle)GetStyle());
88 fontInfo->SetWeight((wxFontWeight)GetWeight());
89 fontInfo->SetUnderlined(GetUnderlined());
90 fontInfo->SetFaceName(GetFaceName());
91 fontInfo->SetEncoding(GetEncoding());
92
93 return fontInfo;
94 #else
95 return (wxNativeFontInfo *)NULL;
96 #endif
97 }
98
99 void wxFontBase::SetNativeFontInfo(const wxNativeFontInfo& info)
100 {
101 #ifdef wxNO_NATIVE_FONTINFO
102 SetPointSize(info.pointSize);
103 SetFamily(info.family);
104 SetStyle(info.style);
105 SetWeight(info.weight);
106 SetUnderlined(info.underlined);
107 SetFaceName(info.faceName);
108 SetEncoding(info.encoding);
109 #else
110 (void)info;
111 #endif
112 }
113
114 wxString wxFontBase::GetNativeFontInfoDesc() const
115 {
116 wxString fontDesc;
117 wxNativeFontInfo *fontInfo = GetNativeFontInfo();
118 if ( fontInfo )
119 {
120 fontDesc = fontInfo->ToString();
121 delete fontInfo;
122 }
123
124 return fontDesc;
125 }
126
127 wxString wxFontBase::GetNativeFontInfoUserDesc() const
128 {
129 wxString fontDesc;
130 wxNativeFontInfo *fontInfo = GetNativeFontInfo();
131 if ( fontInfo )
132 {
133 fontDesc = fontInfo->ToUserString();
134 delete fontInfo;
135 }
136
137 return fontDesc;
138 }
139
140 void wxFontBase::SetNativeFontInfo(const wxString& info)
141 {
142 wxNativeFontInfo fontInfo;
143 if ( !info.empty() && fontInfo.FromString(info) )
144 {
145 SetNativeFontInfo(fontInfo);
146 }
147 }
148
149 void wxFontBase::SetNativeFontInfoUserDesc(const wxString& info)
150 {
151 wxNativeFontInfo fontInfo;
152 if ( !info.empty() && fontInfo.FromUserString(info) )
153 {
154 SetNativeFontInfo(fontInfo);
155 }
156 }
157
158 wxFont& wxFont::operator=(const wxFont& font)
159 {
160 if ( this != &font )
161 Ref(font);
162
163 return (wxFont &)*this;
164 }
165
166 bool wxFontBase::operator==(const wxFont& font) const
167 {
168 // either it is the same font, i.e. they share the same common data or they
169 // have different ref datas but still describe the same font
170 return GetFontData() == font.GetFontData() ||
171 (
172 Ok() == font.Ok() &&
173 GetPointSize() == font.GetPointSize() &&
174 GetFamily() == font.GetFamily() &&
175 GetStyle() == font.GetStyle() &&
176 GetWeight() == font.GetWeight() &&
177 GetUnderlined() == font.GetUnderlined() &&
178 GetFaceName() == font.GetFaceName() &&
179 GetEncoding() == font.GetEncoding()
180 );
181 }
182
183 bool wxFontBase::operator!=(const wxFont& font) const
184 {
185 return !(*this == font);
186 }
187
188 wxString wxFontBase::GetFamilyString() const
189 {
190 wxCHECK_MSG( Ok(), wxT("wxDEFAULT"), wxT("invalid font") );
191
192 switch ( GetFamily() )
193 {
194 case wxDECORATIVE: return wxT("wxDECORATIVE");
195 case wxROMAN: return wxT("wxROMAN");
196 case wxSCRIPT: return wxT("wxSCRIPT");
197 case wxSWISS: return wxT("wxSWISS");
198 case wxMODERN: return wxT("wxMODERN");
199 case wxTELETYPE: return wxT("wxTELETYPE");
200 default: return wxT("wxDEFAULT");
201 }
202 }
203
204 wxString wxFontBase::GetStyleString() const
205 {
206 wxCHECK_MSG( Ok(), wxT("wxDEFAULT"), wxT("invalid font") );
207
208 switch ( GetStyle() )
209 {
210 case wxNORMAL: return wxT("wxNORMAL");
211 case wxSLANT: return wxT("wxSLANT");
212 case wxITALIC: return wxT("wxITALIC");
213 default: return wxT("wxDEFAULT");
214 }
215 }
216
217 wxString wxFontBase::GetWeightString() const
218 {
219 wxCHECK_MSG( Ok(), wxT("wxDEFAULT"), wxT("invalid font") );
220
221 switch ( GetWeight() )
222 {
223 case wxNORMAL: return wxT("wxNORMAL");
224 case wxBOLD: return wxT("wxBOLD");
225 case wxLIGHT: return wxT("wxLIGHT");
226 default: return wxT("wxDEFAULT");
227 }
228 }
229
230 // ----------------------------------------------------------------------------
231 // wxNativeFontInfo
232 // ----------------------------------------------------------------------------
233
234 #ifdef wxNO_NATIVE_FONTINFO
235
236 // These are the generic forms of FromString()/ToString.
237 //
238 // convert to/from the string representation: format is
239 // version;pointsize;family;style;weight;underlined;facename;encoding
240
241 bool wxNativeFontInfo::FromString(const wxString& s)
242 {
243 long l;
244
245 wxStringTokenizer tokenizer(s, _T(";"));
246
247 wxString token = tokenizer.GetNextToken();
248 //
249 // Ignore the version for now
250 //
251
252 token = tokenizer.GetNextToken();
253 if ( !token.ToLong(&l) )
254 return FALSE;
255 pointSize = (int)l;
256
257 token = tokenizer.GetNextToken();
258 if ( !token.ToLong(&l) )
259 return FALSE;
260 family = (int)l;
261
262 token = tokenizer.GetNextToken();
263 if ( !token.ToLong(&l) )
264 return FALSE;
265 style = (wxFontStyle)l;
266
267 token = tokenizer.GetNextToken();
268 if ( !token.ToLong(&l) )
269 return FALSE;
270 weight = (wxFontWeight)l;
271
272 token = tokenizer.GetNextToken();
273 if ( !token.ToLong(&l) )
274 return FALSE;
275 underlined = l != 0;
276
277 faceName = tokenizer.GetNextToken();
278 if( !faceName )
279 return FALSE;
280
281 token = tokenizer.GetNextToken();
282 if ( !token.ToLong(&l) )
283 return FALSE;
284 encoding = (wxFontEncoding)l;
285
286 return TRUE;
287 }
288
289 wxString wxNativeFontInfo::ToString() const
290 {
291 wxString s;
292
293 s.Printf(_T("%d;%d;%d;%d;%d;%d;%s;%d"),
294 0, // version
295 pointSize,
296 family,
297 (int)style,
298 (int)weight,
299 underlined,
300 faceName.GetData(),
301 (int)encoding);
302
303 return s;
304 }
305
306 void wxNativeFontInfo::Init()
307 {
308 pointSize = wxNORMAL_FONT->GetPointSize();
309 family = wxFONTFAMILY_DEFAULT;
310 style = wxFONTSTYLE_NORMAL;
311 weight = wxFONTWEIGHT_NORMAL;
312 underlined = FALSE;
313 faceName.clear();
314 encoding = wxFONTENCODING_DEFAULT;
315 }
316
317 int wxNativeFontInfo::GetPointSize() const
318 {
319 return pointSize;
320 }
321
322 wxFontStyle wxNativeFontInfo::GetStyle() const
323 {
324 return style;
325 }
326
327 wxFontWeight wxNativeFontInfo::GetWeight() const
328 {
329 return weight;
330 }
331
332 bool wxNativeFontInfo::GetUnderlined() const
333 {
334 return underlined;
335 }
336
337 wxString wxNativeFontInfo::GetFaceName() const
338 {
339 return faceName;
340 }
341
342 wxFontEncoding wxNativeFontInfo::GetEncoding() const
343 {
344 return encoding;
345 }
346
347 void wxNativeFontInfo::SetPointSize(int pointsize)
348 {
349 pointSize = pointsize;
350 }
351
352 void wxNativeFontInfo::SetStyle(wxFontStyle style_)
353 {
354 style = style_;
355 }
356
357 void wxNativeFontInfo::SetWeight(wxFontWeight weight_)
358 {
359 weight = weight_;
360 }
361
362 void wxNativeFontInfo::SetUnderlined(bool underlined_)
363 {
364 underlined = underlined_;
365 }
366
367 void wxNativeFontInfo::SetFaceName(wxString facename_)
368 {
369 facename = facename_;
370 }
371
372 void wxNativeFontInfo::SetEncoding(wxFontEncoding encoding_)
373 {
374 encoding = encoding_;
375 }
376
377 #endif // generic wxNativeFontInfo implementation
378
379 // conversion to/from user-readable string: this is used in the generic
380 // versions and under MSW as well because there is no standard font description
381 // format there anyhow (but there is a well-defined standard for X11 fonts used
382 // by wxGTK and wxMotif)
383
384 #if defined(wxNO_NATIVE_FONTINFO) || defined(__WXMSW__)
385
386 wxString wxNativeFontInfo::ToUserString() const
387 {
388 wxString desc;
389
390 // first put the adjectives, if any - this is English-centric, of course,
391 // but what else can we do?
392 if ( GetUnderlined() )
393 {
394 desc << _("underlined ");
395 }
396
397 switch ( GetWeight() )
398 {
399 default:
400 wxFAIL_MSG( _T("unknown font weight") );
401 // fall through
402
403 case wxFONTWEIGHT_NORMAL:
404 break;
405
406 case wxFONTWEIGHT_LIGHT:
407 desc << _("light ");
408 break;
409
410 case wxFONTWEIGHT_BOLD:
411 desc << _("bold ");
412 break;
413 }
414
415 switch ( GetStyle() )
416 {
417 default:
418 wxFAIL_MSG( _T("unknown font style") );
419 // fall through
420
421 case wxFONTSTYLE_NORMAL:
422 break;
423
424 // we don't distinguish between the two for now anyhow...
425 case wxFONTSTYLE_ITALIC:
426 case wxFONTSTYLE_SLANT:
427 desc << _("italic");
428 break;
429 }
430
431 wxString face = GetFaceName();
432 if ( !face.empty() )
433 {
434 desc << _T(' ') << face;
435 }
436
437 int size = GetPointSize();
438 if ( size != wxNORMAL_FONT->GetPointSize() )
439 {
440 desc << _T(' ') << size;
441 }
442
443 wxFontEncoding enc = GetEncoding();
444 if ( enc != wxFONTENCODING_DEFAULT && enc != wxFONTENCODING_SYSTEM )
445 {
446 desc << _T(' ') << wxTheFontMapper->GetEncodingName(enc);
447 }
448
449 return desc;
450 }
451
452 bool wxNativeFontInfo::FromUserString(const wxString& s)
453 {
454 // reset to the default state
455 Init();
456
457 // parse a more or less free form string
458 //
459 // TODO: we should handle at least the quoted facenames
460 wxStringTokenizer tokenizer(s, _T(";, "), wxTOKEN_STRTOK);
461
462 wxString face;
463 unsigned long size;
464 wxFontEncoding encoding;
465
466 while ( tokenizer.HasMoreTokens() )
467 {
468 wxString token = tokenizer.GetNextToken();
469
470 // normalize it
471 token.Trim(TRUE).Trim(FALSE).MakeLower();
472
473 // look for the known tokens
474 if ( token == _T("underlined") || token == _("underlined") )
475 {
476 SetUnderlined(TRUE);
477 }
478 else if ( token == _T("light") || token == _("light") )
479 {
480 SetWeight(wxFONTWEIGHT_LIGHT);
481 }
482 else if ( token == _T("bold") || token == _("bold") )
483 {
484 SetWeight(wxFONTWEIGHT_BOLD);
485 }
486 else if ( token == _T("italic") || token == _("italic") )
487 {
488 SetStyle(wxFONTSTYLE_ITALIC);
489 }
490 else if ( token.ToULong(&size) )
491 {
492 SetPointSize(size);
493 }
494 else if ( (encoding = wxTheFontMapper->CharsetToEncoding(token, FALSE))
495 != wxFONTENCODING_DEFAULT )
496 {
497 SetEncoding(encoding);
498 }
499 else // assume it is the face name
500 {
501 if ( !face.empty() )
502 {
503 face += _T(' ');
504 }
505
506 face += token;
507
508 // skip the code which resets face below
509 continue;
510 }
511
512 // if we had had the facename, we shouldn't continue appending tokens
513 // to it (i.e. "foo bold bar" shouldn't result in the facename "foo
514 // bar")
515 if ( !face.empty() )
516 {
517 SetFaceName(face);
518 face.clear();
519 }
520 }
521
522 // we might not have flushed it inside the loop
523 if ( !face.empty() )
524 {
525 SetFaceName(face);
526 }
527
528 return TRUE;
529 }
530
531 #endif // generic or wxMSW
532