]> git.saurik.com Git - wxWidgets.git/blame - src/common/fontcmn.cpp
Fixes for GNUPro 00r1
[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
7beba2fc 52/* static */
0c5d3e1c
VZ
53wxFont *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
30764ab5
VZ
64/* static */
65wxFont *wxFontBase::New(const wxNativeFontInfo& info)
66{
67 return new wxFont(info);
68}
69
7826e2dd
VZ
70/* static */
71wxFont *wxFontBase::New(const wxString& strNativeFontDesc)
30764ab5 72{
30764ab5 73 wxNativeFontInfo fontInfo;
7826e2dd 74 if ( !fontInfo.FromString(strNativeFontDesc) )
09fcd889 75 return new wxFont(*wxNORMAL_FONT);
7826e2dd
VZ
76
77 return New(fontInfo);
78}
79
80wxNativeFontInfo *wxFontBase::GetNativeFontInfo() const
81{
ab5fe833
VZ
82#ifdef wxNO_NATIVE_FONTINFO
83 wxNativeFontInfo *fontInfo = new wxNativeFontInfo();
30764ab5 84
ab5fe833 85 fontInfo->SetPointSize(GetPointSize());
f7b301fa 86 fontInfo->SetFamily((wxFontFamily)GetFamily());
ab5fe833
VZ
87 fontInfo->SetStyle((wxFontStyle)GetStyle());
88 fontInfo->SetWeight((wxFontWeight)GetWeight());
89 fontInfo->SetUnderlined(GetUnderlined());
90 fontInfo->SetFaceName(GetFaceName());
91 fontInfo->SetEncoding(GetEncoding());
30764ab5
VZ
92
93 return fontInfo;
94#else
7826e2dd 95 return (wxNativeFontInfo *)NULL;
30764ab5
VZ
96#endif
97}
98
99void wxFontBase::SetNativeFontInfo(const wxNativeFontInfo& info)
100{
ab5fe833 101#ifdef wxNO_NATIVE_FONTINFO
30764ab5
VZ
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);
33ac7e6f 109#else
1e6feb95 110 (void)info;
30764ab5
VZ
111#endif
112}
113
7826e2dd
VZ
114wxString 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
ab5fe833
VZ
127wxString 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
31d1b66e
VZ
140void wxFontBase::SetNativeFontInfo(const wxString& info)
141{
142 wxNativeFontInfo fontInfo;
143 if ( !info.empty() && fontInfo.FromString(info) )
144 {
145 SetNativeFontInfo(fontInfo);
146 }
147}
148
ab5fe833
VZ
149void wxFontBase::SetNativeFontInfoUserDesc(const wxString& info)
150{
151 wxNativeFontInfo fontInfo;
152 if ( !info.empty() && fontInfo.FromUserString(info) )
153 {
154 SetNativeFontInfo(fontInfo);
155 }
156}
157
0c5d3e1c
VZ
158wxFont& wxFont::operator=(const wxFont& font)
159{
160 if ( this != &font )
161 Ref(font);
162
163 return (wxFont &)*this;
164}
165
0c5d3e1c
VZ
166bool wxFontBase::operator==(const wxFont& font) const
167{
8bf30fe9
VZ
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() &&
e6adf058 176 GetWeight() == font.GetWeight() &&
8bf30fe9
VZ
177 GetUnderlined() == font.GetUnderlined() &&
178 GetFaceName() == font.GetFaceName() &&
179 GetEncoding() == font.GetEncoding()
180 );
0c5d3e1c
VZ
181}
182
183bool wxFontBase::operator!=(const wxFont& font) const
184{
8bf30fe9 185 return !(*this == font);
0c5d3e1c
VZ
186}
187
188wxString wxFontBase::GetFamilyString() const
189{
223d09f6 190 wxCHECK_MSG( Ok(), wxT("wxDEFAULT"), wxT("invalid font") );
0c5d3e1c
VZ
191
192 switch ( GetFamily() )
193 {
223d09f6
KB
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");
0c5d3e1c
VZ
201 }
202}
203
204wxString wxFontBase::GetStyleString() const
205{
223d09f6 206 wxCHECK_MSG( Ok(), wxT("wxDEFAULT"), wxT("invalid font") );
0c5d3e1c
VZ
207
208 switch ( GetStyle() )
209 {
223d09f6
KB
210 case wxNORMAL: return wxT("wxNORMAL");
211 case wxSLANT: return wxT("wxSLANT");
212 case wxITALIC: return wxT("wxITALIC");
213 default: return wxT("wxDEFAULT");
0c5d3e1c
VZ
214 }
215}
216
217wxString wxFontBase::GetWeightString() const
218{
223d09f6 219 wxCHECK_MSG( Ok(), wxT("wxDEFAULT"), wxT("invalid font") );
0c5d3e1c
VZ
220
221 switch ( GetWeight() )
222 {
223d09f6
KB
223 case wxNORMAL: return wxT("wxNORMAL");
224 case wxBOLD: return wxT("wxBOLD");
225 case wxLIGHT: return wxT("wxLIGHT");
226 default: return wxT("wxDEFAULT");
0c5d3e1c
VZ
227 }
228}
229
30764ab5
VZ
230// ----------------------------------------------------------------------------
231// wxNativeFontInfo
232// ----------------------------------------------------------------------------
233
ab5fe833
VZ
234#ifdef wxNO_NATIVE_FONTINFO
235
30764ab5
VZ
236// These are the generic forms of FromString()/ToString.
237//
238// convert to/from the string representation: format is
09fcd889 239// version;pointsize;family;style;weight;underlined;facename;encoding
30764ab5
VZ
240
241bool wxNativeFontInfo::FromString(const wxString& s)
242{
243 long l;
244
245 wxStringTokenizer tokenizer(s, _T(";"));
246
247 wxString token = tokenizer.GetNextToken();
09fcd889
VZ
248 //
249 // Ignore the version for now
250 //
33ac7e6f 251
09fcd889 252 token = tokenizer.GetNextToken();
30764ab5
VZ
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;
f7b301fa 260 family = (wxFontFamily)l;
30764ab5
VZ
261
262 token = tokenizer.GetNextToken();
263 if ( !token.ToLong(&l) )
264 return FALSE;
ab5fe833 265 style = (wxFontStyle)l;
30764ab5
VZ
266
267 token = tokenizer.GetNextToken();
268 if ( !token.ToLong(&l) )
269 return FALSE;
ab5fe833 270 weight = (wxFontWeight)l;
30764ab5
VZ
271
272 token = tokenizer.GetNextToken();
273 if ( !token.ToLong(&l) )
274 return FALSE;
189e08b4 275 underlined = l != 0;
30764ab5
VZ
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
289wxString wxNativeFontInfo::ToString() const
290{
291 wxString s;
292
09fcd889
VZ
293 s.Printf(_T("%d;%d;%d;%d;%d;%d;%s;%d"),
294 0, // version
30764ab5
VZ
295 pointSize,
296 family,
ab5fe833
VZ
297 (int)style,
298 (int)weight,
30764ab5
VZ
299 underlined,
300 faceName.GetData(),
301 (int)encoding);
302
303 return s;
304}
305
ab5fe833
VZ
306void 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
317int wxNativeFontInfo::GetPointSize() const
318{
319 return pointSize;
320}
321
322wxFontStyle wxNativeFontInfo::GetStyle() const
323{
324 return style;
325}
326
327wxFontWeight wxNativeFontInfo::GetWeight() const
328{
329 return weight;
330}
331
332bool wxNativeFontInfo::GetUnderlined() const
333{
334 return underlined;
335}
336
337wxString wxNativeFontInfo::GetFaceName() const
338{
339 return faceName;
340}
341
7936354d
VZ
342wxFontFamily wxNativeFontInfo::GetFamily() const
343{
344 return family;
345}
346
ab5fe833
VZ
347wxFontEncoding wxNativeFontInfo::GetEncoding() const
348{
349 return encoding;
350}
351
352void wxNativeFontInfo::SetPointSize(int pointsize)
353{
354 pointSize = pointsize;
355}
356
357void wxNativeFontInfo::SetStyle(wxFontStyle style_)
358{
359 style = style_;
360}
361
362void wxNativeFontInfo::SetWeight(wxFontWeight weight_)
363{
364 weight = weight_;
365}
366
367void wxNativeFontInfo::SetUnderlined(bool underlined_)
368{
369 underlined = underlined_;
370}
371
372void wxNativeFontInfo::SetFaceName(wxString facename_)
373{
f7b301fa 374 faceName = facename_;
ab5fe833
VZ
375}
376
3f1d1373 377void wxNativeFontInfo::SetFamily(wxFontFamily family_)
7936354d
VZ
378{
379 family = family_;
380}
381
ab5fe833
VZ
382void wxNativeFontInfo::SetEncoding(wxFontEncoding encoding_)
383{
384 encoding = encoding_;
385}
386
7826e2dd 387#endif // generic wxNativeFontInfo implementation
30764ab5 388
ab5fe833
VZ
389// conversion to/from user-readable string: this is used in the generic
390// versions and under MSW as well because there is no standard font description
391// format there anyhow (but there is a well-defined standard for X11 fonts used
392// by wxGTK and wxMotif)
393
394#if defined(wxNO_NATIVE_FONTINFO) || defined(__WXMSW__)
395
396wxString wxNativeFontInfo::ToUserString() const
397{
398 wxString desc;
399
400 // first put the adjectives, if any - this is English-centric, of course,
401 // but what else can we do?
402 if ( GetUnderlined() )
403 {
404 desc << _("underlined ");
405 }
406
407 switch ( GetWeight() )
408 {
409 default:
410 wxFAIL_MSG( _T("unknown font weight") );
411 // fall through
412
413 case wxFONTWEIGHT_NORMAL:
414 break;
415
416 case wxFONTWEIGHT_LIGHT:
417 desc << _("light ");
418 break;
419
420 case wxFONTWEIGHT_BOLD:
421 desc << _("bold ");
422 break;
423 }
424
425 switch ( GetStyle() )
426 {
427 default:
428 wxFAIL_MSG( _T("unknown font style") );
429 // fall through
430
431 case wxFONTSTYLE_NORMAL:
432 break;
433
434 // we don't distinguish between the two for now anyhow...
435 case wxFONTSTYLE_ITALIC:
436 case wxFONTSTYLE_SLANT:
a9249b2e 437 desc << _("italic");
ab5fe833
VZ
438 break;
439 }
440
a9249b2e
VZ
441 wxString face = GetFaceName();
442 if ( !face.empty() )
ab5fe833 443 {
a9249b2e 444 desc << _T(' ') << face;
ab5fe833
VZ
445 }
446
a9249b2e
VZ
447 int size = GetPointSize();
448 if ( size != wxNORMAL_FONT->GetPointSize() )
ab5fe833 449 {
a9249b2e 450 desc << _T(' ') << size;
ab5fe833 451 }
a9249b2e 452
e7e52b6d 453#if wxUSE_FONTMAP
a9249b2e
VZ
454 wxFontEncoding enc = GetEncoding();
455 if ( enc != wxFONTENCODING_DEFAULT && enc != wxFONTENCODING_SYSTEM )
456 {
457 desc << _T(' ') << wxTheFontMapper->GetEncodingName(enc);
458 }
e7e52b6d 459#endif // wxUSE_FONTMAP
a9249b2e
VZ
460
461 return desc;
ab5fe833
VZ
462}
463
464bool wxNativeFontInfo::FromUserString(const wxString& s)
465{
466 // reset to the default state
467 Init();
468
469 // parse a more or less free form string
470 //
471 // TODO: we should handle at least the quoted facenames
472 wxStringTokenizer tokenizer(s, _T(";, "), wxTOKEN_STRTOK);
473
474 wxString face;
475 unsigned long size;
e7e52b6d
VZ
476
477#if wxUSE_FONTMAP
ab5fe833 478 wxFontEncoding encoding;
e7e52b6d 479#endif // wxUSE_FONTMAP
ab5fe833
VZ
480
481 while ( tokenizer.HasMoreTokens() )
482 {
483 wxString token = tokenizer.GetNextToken();
484
485 // normalize it
486 token.Trim(TRUE).Trim(FALSE).MakeLower();
487
488 // look for the known tokens
489 if ( token == _T("underlined") || token == _("underlined") )
490 {
491 SetUnderlined(TRUE);
492 }
493 else if ( token == _T("light") || token == _("light") )
494 {
495 SetWeight(wxFONTWEIGHT_LIGHT);
496 }
497 else if ( token == _T("bold") || token == _("bold") )
498 {
499 SetWeight(wxFONTWEIGHT_BOLD);
500 }
501 else if ( token == _T("italic") || token == _("italic") )
502 {
503 SetStyle(wxFONTSTYLE_ITALIC);
504 }
505 else if ( token.ToULong(&size) )
506 {
a9249b2e 507 SetPointSize(size);
ab5fe833 508 }
e7e52b6d 509#if wxUSE_FONTMAP
ab5fe833
VZ
510 else if ( (encoding = wxTheFontMapper->CharsetToEncoding(token, FALSE))
511 != wxFONTENCODING_DEFAULT )
512 {
513 SetEncoding(encoding);
514 }
e7e52b6d 515#endif // wxUSE_FONTMAP
ab5fe833
VZ
516 else // assume it is the face name
517 {
518 if ( !face.empty() )
519 {
520 face += _T(' ');
521 }
522
523 face += token;
524
525 // skip the code which resets face below
526 continue;
527 }
528
529 // if we had had the facename, we shouldn't continue appending tokens
530 // to it (i.e. "foo bold bar" shouldn't result in the facename "foo
531 // bar")
532 if ( !face.empty() )
533 {
534 SetFaceName(face);
535 face.clear();
536 }
537 }
538
539 // we might not have flushed it inside the loop
540 if ( !face.empty() )
541 {
542 SetFaceName(face);
543 }
544
545 return TRUE;
546}
547
548#endif // generic or wxMSW
549