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