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