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