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