]> git.saurik.com Git - wxWidgets.git/blame - src/common/fontcmn.cpp
Fix wxSnvprintf (and hence wxString::Format) for Unicode, when using
[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
cafbf6fb
VZ
52/* static */
53void 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
799ea011
GD
63wxFontBase::~wxFontBase()
64{
65 // this destructor is required for Darwin
66}
67
7beba2fc 68/* static */
0c5d3e1c
VZ
69wxFont *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
30764ab5
VZ
80/* static */
81wxFont *wxFontBase::New(const wxNativeFontInfo& info)
82{
83 return new wxFont(info);
84}
85
7826e2dd
VZ
86/* static */
87wxFont *wxFontBase::New(const wxString& strNativeFontDesc)
30764ab5 88{
30764ab5 89 wxNativeFontInfo fontInfo;
7826e2dd 90 if ( !fontInfo.FromString(strNativeFontDesc) )
09fcd889 91 return new wxFont(*wxNORMAL_FONT);
7826e2dd
VZ
92
93 return New(fontInfo);
94}
95
53f6aab7
VZ
96bool wxFontBase::IsFixedWidth() const
97{
98 return GetFamily() == wxFONTFAMILY_TELETYPE;
99}
100
7826e2dd
VZ
101wxNativeFontInfo *wxFontBase::GetNativeFontInfo() const
102{
ab5fe833
VZ
103#ifdef wxNO_NATIVE_FONTINFO
104 wxNativeFontInfo *fontInfo = new wxNativeFontInfo();
30764ab5 105
ab5fe833 106 fontInfo->SetPointSize(GetPointSize());
f7b301fa 107 fontInfo->SetFamily((wxFontFamily)GetFamily());
ab5fe833
VZ
108 fontInfo->SetStyle((wxFontStyle)GetStyle());
109 fontInfo->SetWeight((wxFontWeight)GetWeight());
110 fontInfo->SetUnderlined(GetUnderlined());
111 fontInfo->SetFaceName(GetFaceName());
112 fontInfo->SetEncoding(GetEncoding());
30764ab5
VZ
113
114 return fontInfo;
115#else
7826e2dd 116 return (wxNativeFontInfo *)NULL;
30764ab5
VZ
117#endif
118}
119
120void wxFontBase::SetNativeFontInfo(const wxNativeFontInfo& info)
121{
ab5fe833 122#ifdef wxNO_NATIVE_FONTINFO
30764ab5
VZ
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);
33ac7e6f 130#else
1e6feb95 131 (void)info;
30764ab5
VZ
132#endif
133}
134
7826e2dd
VZ
135wxString 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
ab5fe833
VZ
148wxString 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
31d1b66e
VZ
161void wxFontBase::SetNativeFontInfo(const wxString& info)
162{
163 wxNativeFontInfo fontInfo;
164 if ( !info.empty() && fontInfo.FromString(info) )
165 {
166 SetNativeFontInfo(fontInfo);
167 }
168}
169
ab5fe833
VZ
170void wxFontBase::SetNativeFontInfoUserDesc(const wxString& info)
171{
172 wxNativeFontInfo fontInfo;
173 if ( !info.empty() && fontInfo.FromUserString(info) )
174 {
175 SetNativeFontInfo(fontInfo);
176 }
177}
178
0c5d3e1c
VZ
179wxFont& wxFont::operator=(const wxFont& font)
180{
181 if ( this != &font )
182 Ref(font);
183
184 return (wxFont &)*this;
185}
186
0c5d3e1c
VZ
187bool wxFontBase::operator==(const wxFont& font) const
188{
8bf30fe9
VZ
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() &&
e6adf058 197 GetWeight() == font.GetWeight() &&
8bf30fe9
VZ
198 GetUnderlined() == font.GetUnderlined() &&
199 GetFaceName() == font.GetFaceName() &&
200 GetEncoding() == font.GetEncoding()
201 );
0c5d3e1c
VZ
202}
203
204bool wxFontBase::operator!=(const wxFont& font) const
205{
8bf30fe9 206 return !(*this == font);
0c5d3e1c
VZ
207}
208
209wxString wxFontBase::GetFamilyString() const
210{
223d09f6 211 wxCHECK_MSG( Ok(), wxT("wxDEFAULT"), wxT("invalid font") );
0c5d3e1c
VZ
212
213 switch ( GetFamily() )
214 {
223d09f6
KB
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");
0c5d3e1c
VZ
222 }
223}
224
225wxString wxFontBase::GetStyleString() const
226{
223d09f6 227 wxCHECK_MSG( Ok(), wxT("wxDEFAULT"), wxT("invalid font") );
0c5d3e1c
VZ
228
229 switch ( GetStyle() )
230 {
223d09f6
KB
231 case wxNORMAL: return wxT("wxNORMAL");
232 case wxSLANT: return wxT("wxSLANT");
233 case wxITALIC: return wxT("wxITALIC");
234 default: return wxT("wxDEFAULT");
0c5d3e1c
VZ
235 }
236}
237
238wxString wxFontBase::GetWeightString() const
239{
223d09f6 240 wxCHECK_MSG( Ok(), wxT("wxDEFAULT"), wxT("invalid font") );
0c5d3e1c
VZ
241
242 switch ( GetWeight() )
243 {
223d09f6
KB
244 case wxNORMAL: return wxT("wxNORMAL");
245 case wxBOLD: return wxT("wxBOLD");
246 case wxLIGHT: return wxT("wxLIGHT");
247 default: return wxT("wxDEFAULT");
0c5d3e1c
VZ
248 }
249}
250
30764ab5
VZ
251// ----------------------------------------------------------------------------
252// wxNativeFontInfo
253// ----------------------------------------------------------------------------
254
ab5fe833
VZ
255#ifdef wxNO_NATIVE_FONTINFO
256
30764ab5
VZ
257// These are the generic forms of FromString()/ToString.
258//
259// convert to/from the string representation: format is
09fcd889 260// version;pointsize;family;style;weight;underlined;facename;encoding
30764ab5
VZ
261
262bool wxNativeFontInfo::FromString(const wxString& s)
263{
264 long l;
265
266 wxStringTokenizer tokenizer(s, _T(";"));
267
268 wxString token = tokenizer.GetNextToken();
09fcd889
VZ
269 //
270 // Ignore the version for now
271 //
33ac7e6f 272
09fcd889 273 token = tokenizer.GetNextToken();
30764ab5
VZ
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;
f7b301fa 281 family = (wxFontFamily)l;
30764ab5
VZ
282
283 token = tokenizer.GetNextToken();
284 if ( !token.ToLong(&l) )
285 return FALSE;
ab5fe833 286 style = (wxFontStyle)l;
30764ab5
VZ
287
288 token = tokenizer.GetNextToken();
289 if ( !token.ToLong(&l) )
290 return FALSE;
ab5fe833 291 weight = (wxFontWeight)l;
30764ab5
VZ
292
293 token = tokenizer.GetNextToken();
294 if ( !token.ToLong(&l) )
295 return FALSE;
189e08b4 296 underlined = l != 0;
30764ab5
VZ
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
310wxString wxNativeFontInfo::ToString() const
311{
312 wxString s;
313
09fcd889
VZ
314 s.Printf(_T("%d;%d;%d;%d;%d;%d;%s;%d"),
315 0, // version
30764ab5
VZ
316 pointSize,
317 family,
ab5fe833
VZ
318 (int)style,
319 (int)weight,
30764ab5
VZ
320 underlined,
321 faceName.GetData(),
322 (int)encoding);
323
324 return s;
325}
326
ab5fe833
VZ
327void 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
338int wxNativeFontInfo::GetPointSize() const
339{
340 return pointSize;
341}
342
343wxFontStyle wxNativeFontInfo::GetStyle() const
344{
345 return style;
346}
347
348wxFontWeight wxNativeFontInfo::GetWeight() const
349{
350 return weight;
351}
352
353bool wxNativeFontInfo::GetUnderlined() const
354{
355 return underlined;
356}
357
358wxString wxNativeFontInfo::GetFaceName() const
359{
360 return faceName;
361}
362
7936354d
VZ
363wxFontFamily wxNativeFontInfo::GetFamily() const
364{
365 return family;
366}
367
ab5fe833
VZ
368wxFontEncoding wxNativeFontInfo::GetEncoding() const
369{
370 return encoding;
371}
372
373void wxNativeFontInfo::SetPointSize(int pointsize)
374{
375 pointSize = pointsize;
376}
377
378void wxNativeFontInfo::SetStyle(wxFontStyle style_)
379{
380 style = style_;
381}
382
383void wxNativeFontInfo::SetWeight(wxFontWeight weight_)
384{
385 weight = weight_;
386}
387
388void wxNativeFontInfo::SetUnderlined(bool underlined_)
389{
390 underlined = underlined_;
391}
392
393void wxNativeFontInfo::SetFaceName(wxString facename_)
394{
f7b301fa 395 faceName = facename_;
ab5fe833
VZ
396}
397
3f1d1373 398void wxNativeFontInfo::SetFamily(wxFontFamily family_)
7936354d
VZ
399{
400 family = family_;
401}
402
ab5fe833
VZ
403void wxNativeFontInfo::SetEncoding(wxFontEncoding encoding_)
404{
405 encoding = encoding_;
406}
407
7826e2dd 408#endif // generic wxNativeFontInfo implementation
30764ab5 409
ab5fe833
VZ
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
0eb529d9 415#if defined(wxNO_NATIVE_FONTINFO) || defined(__WXMSW__) || defined (__WXPM__)
ab5fe833
VZ
416
417wxString 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:
a9249b2e 458 desc << _("italic");
ab5fe833
VZ
459 break;
460 }
461
a9249b2e
VZ
462 wxString face = GetFaceName();
463 if ( !face.empty() )
ab5fe833 464 {
a9249b2e 465 desc << _T(' ') << face;
ab5fe833
VZ
466 }
467
a9249b2e
VZ
468 int size = GetPointSize();
469 if ( size != wxNORMAL_FONT->GetPointSize() )
ab5fe833 470 {
a9249b2e 471 desc << _T(' ') << size;
ab5fe833 472 }
a9249b2e 473
e7e52b6d 474#if wxUSE_FONTMAP
a9249b2e
VZ
475 wxFontEncoding enc = GetEncoding();
476 if ( enc != wxFONTENCODING_DEFAULT && enc != wxFONTENCODING_SYSTEM )
477 {
142b3bc2 478 desc << _T(' ') << wxFontMapper::Get()->GetEncodingName(enc);
a9249b2e 479 }
e7e52b6d 480#endif // wxUSE_FONTMAP
a9249b2e
VZ
481
482 return desc;
ab5fe833
VZ
483}
484
485bool 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;
e7e52b6d
VZ
497
498#if wxUSE_FONTMAP
ab5fe833 499 wxFontEncoding encoding;
e7e52b6d 500#endif // wxUSE_FONTMAP
ab5fe833
VZ
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 {
a9249b2e 528 SetPointSize(size);
ab5fe833 529 }
e7e52b6d 530#if wxUSE_FONTMAP
142b3bc2 531 else if ( (encoding = wxFontMapper::Get()->CharsetToEncoding(token, FALSE))
ab5fe833
VZ
532 != wxFONTENCODING_DEFAULT )
533 {
534 SetEncoding(encoding);
535 }
e7e52b6d 536#endif // wxUSE_FONTMAP
ab5fe833
VZ
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
0eb529d9 569#endif // generic or wxMSW or wxOS2
ab5fe833 570