]> git.saurik.com Git - wxWidgets.git/blame - src/common/fontcmn.cpp
added some missing mac headers
[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$
77ffb593 8// Copyright: (c) wxWidgets team
65571936 9// Licence: wxWindows licence
0c5d3e1c
VZ
10/////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
14f355c2 20#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
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"
1c193821
JS
37
38#if defined(__WXMSW__)
39 #include "wx/msw/private.h" // includes windows.h for LOGFONT
40 #include "wx/msw/winundef.h"
41#endif
42
76e23cdb 43#include "wx/fontutil.h" // for wxNativeFontInfo
ab5fe833 44#include "wx/fontmap.h"
76e23cdb 45
30764ab5
VZ
46#include "wx/tokenzr.h"
47
0c5d3e1c
VZ
48// ============================================================================
49// implementation
50// ============================================================================
51
544229d1
VZ
52// ----------------------------------------------------------------------------
53// helper functions
54// ----------------------------------------------------------------------------
55
56static void AdjustFontSize(wxFont font, wxDC& dc, const wxSize& pixelSize)
57{
58 int currentSize = font.GetPointSize();
59 int largestGood;
60 int smallestBad;
61
62 bool initialGoodFound = false;
63 bool initialBadFound = false;
64
65 while (currentSize > 0)
66 {
67 dc.SetFont(font);
68
69 // if currentSize (in points) results in a font that is smaller
70 // than required by pixelSize it is considered a good size
71 if (dc.GetCharHeight() <= pixelSize.GetHeight() &&
72 (!pixelSize.GetWidth() ||
73 dc.GetCharWidth() <= pixelSize.GetWidth()))
74 {
75 largestGood = currentSize;
76 initialGoodFound = true;
77 }
78 else
79 {
80 smallestBad = currentSize;
81 initialBadFound = true;
82 }
83 if (!initialGoodFound)
84 {
85 currentSize /= 2;
86 }
87 else if (!initialBadFound)
88 {
89 currentSize *= 2;
90 }
91 else
92 {
93 int distance = smallestBad - largestGood;
94 if (distance == 1)
95 break;
96
97 currentSize = largestGood + distance / 2;
98 }
99
100 font.SetPointSize(currentSize);
101 }
102
103 if (currentSize != largestGood)
104 font.SetPointSize(largestGood);
105}
106
0c5d3e1c
VZ
107// ----------------------------------------------------------------------------
108// wxFontBase
109// ----------------------------------------------------------------------------
110
111wxFontEncoding wxFontBase::ms_encodingDefault = wxFONTENCODING_SYSTEM;
112
cafbf6fb
VZ
113/* static */
114void wxFontBase::SetDefaultEncoding(wxFontEncoding encoding)
115{
116 // GetDefaultEncoding() should return something != wxFONTENCODING_DEFAULT
117 // and, besides, using this value here doesn't make any sense
118 wxCHECK_RET( encoding != wxFONTENCODING_DEFAULT,
119 _T("can't set default encoding to wxFONTENCODING_DEFAULT") );
120
121 ms_encodingDefault = encoding;
122}
123
799ea011
GD
124wxFontBase::~wxFontBase()
125{
126 // this destructor is required for Darwin
127}
128
7beba2fc 129/* static */
0c5d3e1c
VZ
130wxFont *wxFontBase::New(int size,
131 int family,
132 int style,
133 int weight,
134 bool underlined,
135 const wxString& face,
136 wxFontEncoding encoding)
137{
138 return new wxFont(size, family, style, weight, underlined, face, encoding);
139}
140
544229d1 141static inline int flags2Style(int flags)
01cb1c26 142{
544229d1 143 return flags & wxFONTFLAG_ITALIC
01cb1c26
VZ
144 ? wxFONTSTYLE_ITALIC
145 : flags & wxFONTFLAG_SLANT
146 ? wxFONTSTYLE_SLANT
544229d1
VZ
147 : wxFONTSTYLE_NORMAL;
148}
149
150static inline int flags2Weight(int flags)
151{
152 return flags & wxFONTFLAG_LIGHT
01cb1c26
VZ
153 ? wxFONTWEIGHT_LIGHT
154 : flags & wxFONTFLAG_BOLD
155 ? wxFONTWEIGHT_BOLD
544229d1
VZ
156 : wxFONTWEIGHT_NORMAL;
157}
158
159static inline bool flags2Underlined(int flags)
160{
161 return (flags & wxFONTFLAG_UNDERLINED) != 0;
162}
163
164/* static */
165wxFont *wxFontBase::New(int pointSize,
166 wxFontFamily family,
167 int flags,
168 const wxString& face,
169 wxFontEncoding encoding)
170{
171 return New(pointSize, family, flags2Style(flags), flags2Weight(flags),
172 flags2Underlined(flags), face, encoding);
173}
174
175/* static */
176wxFont *wxFontBase::New(const wxSize& pixelSize,
177 int family,
178 int style,
179 int weight,
180 bool underlined,
181 const wxString& face,
182 wxFontEncoding encoding)
183{
184#if defined(__WXMSW__)
185 return new wxFont(pixelSize, family, style, weight, underlined,
186 face, encoding);
187#else
188 wxFont * ret = New(10, family, style, weight, underlined, face, encoding);
189 wxScreenDC dc;
190 ret->AdjustFontSize(*(wxFont *)this, dc, pixelSize);
191 return ret;
192#endif
193}
194
195/* static */
196wxFont *wxFontBase::New(const wxSize& pixelSize,
197 wxFontFamily family,
198 int flags,
199 const wxString& face,
200 wxFontEncoding encoding)
201{
202 return New(pixelSize, family, flags2Style(flags), flags2Weight(flags),
203 flags2Underlined(flags), face, encoding);
204}
205
206wxSize wxFontBase::GetPixelSize() const
207{
208 wxScreenDC dc;
209 dc.SetFont(*(wxFont *)this);
210 return wxSize(dc.GetCharWidth(), dc.GetCharHeight());
211}
212
213bool wxFontBase::IsUsingSizeInPixels() const
214{
215 return false;
216}
217
218void wxFontBase::SetPixelSize( const wxSize& pixelSize )
219{
220 wxScreenDC dc;
221 AdjustFontSize(*(wxFont *)this, dc, pixelSize);
01cb1c26
VZ
222}
223
30764ab5
VZ
224/* static */
225wxFont *wxFontBase::New(const wxNativeFontInfo& info)
226{
227 return new wxFont(info);
228}
229
7826e2dd
VZ
230/* static */
231wxFont *wxFontBase::New(const wxString& strNativeFontDesc)
30764ab5 232{
30764ab5 233 wxNativeFontInfo fontInfo;
7826e2dd 234 if ( !fontInfo.FromString(strNativeFontDesc) )
09fcd889 235 return new wxFont(*wxNORMAL_FONT);
7826e2dd
VZ
236
237 return New(fontInfo);
238}
239
53f6aab7
VZ
240bool wxFontBase::IsFixedWidth() const
241{
242 return GetFamily() == wxFONTFAMILY_TELETYPE;
243}
244
9045ad9d 245void wxFontBase::DoSetNativeFontInfo(const wxNativeFontInfo& info)
30764ab5 246{
ab5fe833 247#ifdef wxNO_NATIVE_FONTINFO
30764ab5
VZ
248 SetPointSize(info.pointSize);
249 SetFamily(info.family);
250 SetStyle(info.style);
251 SetWeight(info.weight);
252 SetUnderlined(info.underlined);
253 SetFaceName(info.faceName);
254 SetEncoding(info.encoding);
33ac7e6f 255#else
1e6feb95 256 (void)info;
30764ab5
VZ
257#endif
258}
259
7826e2dd
VZ
260wxString wxFontBase::GetNativeFontInfoDesc() const
261{
262 wxString fontDesc;
3bf5a59b 263 const wxNativeFontInfo *fontInfo = GetNativeFontInfo();
7826e2dd
VZ
264 if ( fontInfo )
265 {
266 fontDesc = fontInfo->ToString();
7826e2dd
VZ
267 }
268
269 return fontDesc;
270}
271
ab5fe833
VZ
272wxString wxFontBase::GetNativeFontInfoUserDesc() const
273{
274 wxString fontDesc;
3bf5a59b 275 const wxNativeFontInfo *fontInfo = GetNativeFontInfo();
ab5fe833
VZ
276 if ( fontInfo )
277 {
278 fontDesc = fontInfo->ToUserString();
ab5fe833
VZ
279 }
280
281 return fontDesc;
282}
283
31d1b66e
VZ
284void wxFontBase::SetNativeFontInfo(const wxString& info)
285{
286 wxNativeFontInfo fontInfo;
287 if ( !info.empty() && fontInfo.FromString(info) )
288 {
289 SetNativeFontInfo(fontInfo);
290 }
291}
292
ab5fe833
VZ
293void wxFontBase::SetNativeFontInfoUserDesc(const wxString& info)
294{
295 wxNativeFontInfo fontInfo;
296 if ( !info.empty() && fontInfo.FromUserString(info) )
297 {
298 SetNativeFontInfo(fontInfo);
299 }
300}
301
0c5d3e1c
VZ
302wxFont& wxFont::operator=(const wxFont& font)
303{
304 if ( this != &font )
305 Ref(font);
306
307 return (wxFont &)*this;
308}
309
0c5d3e1c
VZ
310bool wxFontBase::operator==(const wxFont& font) const
311{
8bf30fe9
VZ
312 // either it is the same font, i.e. they share the same common data or they
313 // have different ref datas but still describe the same font
314 return GetFontData() == font.GetFontData() ||
315 (
316 Ok() == font.Ok() &&
317 GetPointSize() == font.GetPointSize() &&
318 GetFamily() == font.GetFamily() &&
319 GetStyle() == font.GetStyle() &&
e6adf058 320 GetWeight() == font.GetWeight() &&
8bf30fe9
VZ
321 GetUnderlined() == font.GetUnderlined() &&
322 GetFaceName() == font.GetFaceName() &&
323 GetEncoding() == font.GetEncoding()
324 );
0c5d3e1c
VZ
325}
326
327bool wxFontBase::operator!=(const wxFont& font) const
328{
8bf30fe9 329 return !(*this == font);
0c5d3e1c
VZ
330}
331
332wxString wxFontBase::GetFamilyString() const
333{
223d09f6 334 wxCHECK_MSG( Ok(), wxT("wxDEFAULT"), wxT("invalid font") );
0c5d3e1c
VZ
335
336 switch ( GetFamily() )
337 {
223d09f6
KB
338 case wxDECORATIVE: return wxT("wxDECORATIVE");
339 case wxROMAN: return wxT("wxROMAN");
340 case wxSCRIPT: return wxT("wxSCRIPT");
341 case wxSWISS: return wxT("wxSWISS");
342 case wxMODERN: return wxT("wxMODERN");
343 case wxTELETYPE: return wxT("wxTELETYPE");
344 default: return wxT("wxDEFAULT");
0c5d3e1c
VZ
345 }
346}
347
348wxString wxFontBase::GetStyleString() const
349{
223d09f6 350 wxCHECK_MSG( Ok(), wxT("wxDEFAULT"), wxT("invalid font") );
0c5d3e1c
VZ
351
352 switch ( GetStyle() )
353 {
223d09f6
KB
354 case wxNORMAL: return wxT("wxNORMAL");
355 case wxSLANT: return wxT("wxSLANT");
356 case wxITALIC: return wxT("wxITALIC");
357 default: return wxT("wxDEFAULT");
0c5d3e1c
VZ
358 }
359}
360
361wxString wxFontBase::GetWeightString() const
362{
223d09f6 363 wxCHECK_MSG( Ok(), wxT("wxDEFAULT"), wxT("invalid font") );
0c5d3e1c
VZ
364
365 switch ( GetWeight() )
366 {
223d09f6
KB
367 case wxNORMAL: return wxT("wxNORMAL");
368 case wxBOLD: return wxT("wxBOLD");
369 case wxLIGHT: return wxT("wxLIGHT");
370 default: return wxT("wxDEFAULT");
0c5d3e1c
VZ
371 }
372}
373
30764ab5
VZ
374// ----------------------------------------------------------------------------
375// wxNativeFontInfo
376// ----------------------------------------------------------------------------
377
ab5fe833
VZ
378#ifdef wxNO_NATIVE_FONTINFO
379
30764ab5
VZ
380// These are the generic forms of FromString()/ToString.
381//
382// convert to/from the string representation: format is
09fcd889 383// version;pointsize;family;style;weight;underlined;facename;encoding
30764ab5
VZ
384
385bool wxNativeFontInfo::FromString(const wxString& s)
386{
387 long l;
388
389 wxStringTokenizer tokenizer(s, _T(";"));
390
391 wxString token = tokenizer.GetNextToken();
09fcd889
VZ
392 //
393 // Ignore the version for now
394 //
33ac7e6f 395
09fcd889 396 token = tokenizer.GetNextToken();
30764ab5 397 if ( !token.ToLong(&l) )
a62848fd 398 return false;
30764ab5
VZ
399 pointSize = (int)l;
400
401 token = tokenizer.GetNextToken();
402 if ( !token.ToLong(&l) )
a62848fd 403 return false;
f7b301fa 404 family = (wxFontFamily)l;
30764ab5
VZ
405
406 token = tokenizer.GetNextToken();
407 if ( !token.ToLong(&l) )
a62848fd 408 return false;
ab5fe833 409 style = (wxFontStyle)l;
30764ab5
VZ
410
411 token = tokenizer.GetNextToken();
412 if ( !token.ToLong(&l) )
a62848fd 413 return false;
ab5fe833 414 weight = (wxFontWeight)l;
30764ab5
VZ
415
416 token = tokenizer.GetNextToken();
417 if ( !token.ToLong(&l) )
a62848fd 418 return false;
189e08b4 419 underlined = l != 0;
30764ab5
VZ
420
421 faceName = tokenizer.GetNextToken();
0a9f0ef7
JS
422
423#ifndef __WXMAC__
30764ab5 424 if( !faceName )
a62848fd 425 return false;
0a9f0ef7 426#endif
30764ab5
VZ
427
428 token = tokenizer.GetNextToken();
429 if ( !token.ToLong(&l) )
a62848fd 430 return false;
30764ab5
VZ
431 encoding = (wxFontEncoding)l;
432
a62848fd 433 return true;
30764ab5
VZ
434}
435
436wxString wxNativeFontInfo::ToString() const
437{
438 wxString s;
439
09fcd889
VZ
440 s.Printf(_T("%d;%d;%d;%d;%d;%d;%s;%d"),
441 0, // version
30764ab5
VZ
442 pointSize,
443 family,
ab5fe833
VZ
444 (int)style,
445 (int)weight,
30764ab5
VZ
446 underlined,
447 faceName.GetData(),
448 (int)encoding);
449
450 return s;
451}
452
ab5fe833
VZ
453void wxNativeFontInfo::Init()
454{
3bf5a59b 455 pointSize = 0;
ab5fe833
VZ
456 family = wxFONTFAMILY_DEFAULT;
457 style = wxFONTSTYLE_NORMAL;
458 weight = wxFONTWEIGHT_NORMAL;
a62848fd 459 underlined = false;
ab5fe833
VZ
460 faceName.clear();
461 encoding = wxFONTENCODING_DEFAULT;
462}
463
464int wxNativeFontInfo::GetPointSize() const
465{
466 return pointSize;
467}
468
469wxFontStyle wxNativeFontInfo::GetStyle() const
470{
471 return style;
472}
473
474wxFontWeight wxNativeFontInfo::GetWeight() const
475{
476 return weight;
477}
478
479bool wxNativeFontInfo::GetUnderlined() const
480{
481 return underlined;
482}
483
484wxString wxNativeFontInfo::GetFaceName() const
485{
486 return faceName;
487}
488
7936354d
VZ
489wxFontFamily wxNativeFontInfo::GetFamily() const
490{
491 return family;
492}
493
ab5fe833
VZ
494wxFontEncoding wxNativeFontInfo::GetEncoding() const
495{
496 return encoding;
497}
498
499void wxNativeFontInfo::SetPointSize(int pointsize)
500{
501 pointSize = pointsize;
502}
503
504void wxNativeFontInfo::SetStyle(wxFontStyle style_)
505{
506 style = style_;
507}
508
509void wxNativeFontInfo::SetWeight(wxFontWeight weight_)
510{
511 weight = weight_;
512}
513
514void wxNativeFontInfo::SetUnderlined(bool underlined_)
515{
516 underlined = underlined_;
517}
518
519void wxNativeFontInfo::SetFaceName(wxString facename_)
520{
f7b301fa 521 faceName = facename_;
ab5fe833
VZ
522}
523
3f1d1373 524void wxNativeFontInfo::SetFamily(wxFontFamily family_)
7936354d
VZ
525{
526 family = family_;
527}
528
ab5fe833
VZ
529void wxNativeFontInfo::SetEncoding(wxFontEncoding encoding_)
530{
531 encoding = encoding_;
532}
533
7826e2dd 534#endif // generic wxNativeFontInfo implementation
30764ab5 535
ab5fe833
VZ
536// conversion to/from user-readable string: this is used in the generic
537// versions and under MSW as well because there is no standard font description
538// format there anyhow (but there is a well-defined standard for X11 fonts used
539// by wxGTK and wxMotif)
540
0eb529d9 541#if defined(wxNO_NATIVE_FONTINFO) || defined(__WXMSW__) || defined (__WXPM__)
ab5fe833
VZ
542
543wxString wxNativeFontInfo::ToUserString() const
544{
545 wxString desc;
546
547 // first put the adjectives, if any - this is English-centric, of course,
548 // but what else can we do?
549 if ( GetUnderlined() )
550 {
551 desc << _("underlined ");
552 }
553
554 switch ( GetWeight() )
555 {
556 default:
557 wxFAIL_MSG( _T("unknown font weight") );
558 // fall through
559
560 case wxFONTWEIGHT_NORMAL:
561 break;
562
563 case wxFONTWEIGHT_LIGHT:
564 desc << _("light ");
565 break;
566
567 case wxFONTWEIGHT_BOLD:
568 desc << _("bold ");
569 break;
570 }
571
572 switch ( GetStyle() )
573 {
574 default:
575 wxFAIL_MSG( _T("unknown font style") );
576 // fall through
577
578 case wxFONTSTYLE_NORMAL:
579 break;
580
581 // we don't distinguish between the two for now anyhow...
582 case wxFONTSTYLE_ITALIC:
583 case wxFONTSTYLE_SLANT:
a9249b2e 584 desc << _("italic");
ab5fe833
VZ
585 break;
586 }
587
a9249b2e
VZ
588 wxString face = GetFaceName();
589 if ( !face.empty() )
ab5fe833 590 {
a9249b2e 591 desc << _T(' ') << face;
ab5fe833
VZ
592 }
593
a9249b2e
VZ
594 int size = GetPointSize();
595 if ( size != wxNORMAL_FONT->GetPointSize() )
ab5fe833 596 {
a9249b2e 597 desc << _T(' ') << size;
ab5fe833 598 }
a9249b2e 599
e7e52b6d 600#if wxUSE_FONTMAP
a9249b2e
VZ
601 wxFontEncoding enc = GetEncoding();
602 if ( enc != wxFONTENCODING_DEFAULT && enc != wxFONTENCODING_SYSTEM )
603 {
142b3bc2 604 desc << _T(' ') << wxFontMapper::Get()->GetEncodingName(enc);
a9249b2e 605 }
e7e52b6d 606#endif // wxUSE_FONTMAP
a9249b2e
VZ
607
608 return desc;
ab5fe833
VZ
609}
610
611bool wxNativeFontInfo::FromUserString(const wxString& s)
612{
613 // reset to the default state
614 Init();
615
616 // parse a more or less free form string
617 //
618 // TODO: we should handle at least the quoted facenames
619 wxStringTokenizer tokenizer(s, _T(";, "), wxTOKEN_STRTOK);
620
621 wxString face;
622 unsigned long size;
e7e52b6d
VZ
623
624#if wxUSE_FONTMAP
ab5fe833 625 wxFontEncoding encoding;
e7e52b6d 626#endif // wxUSE_FONTMAP
ab5fe833
VZ
627
628 while ( tokenizer.HasMoreTokens() )
629 {
630 wxString token = tokenizer.GetNextToken();
631
632 // normalize it
a62848fd 633 token.Trim(true).Trim(false).MakeLower();
ab5fe833
VZ
634
635 // look for the known tokens
636 if ( token == _T("underlined") || token == _("underlined") )
637 {
a62848fd 638 SetUnderlined(true);
ab5fe833
VZ
639 }
640 else if ( token == _T("light") || token == _("light") )
641 {
642 SetWeight(wxFONTWEIGHT_LIGHT);
643 }
644 else if ( token == _T("bold") || token == _("bold") )
645 {
646 SetWeight(wxFONTWEIGHT_BOLD);
647 }
648 else if ( token == _T("italic") || token == _("italic") )
649 {
650 SetStyle(wxFONTSTYLE_ITALIC);
651 }
652 else if ( token.ToULong(&size) )
653 {
a9249b2e 654 SetPointSize(size);
ab5fe833 655 }
e7e52b6d 656#if wxUSE_FONTMAP
a62848fd 657 else if ( (encoding = wxFontMapper::Get()->CharsetToEncoding(token, false))
ab5fe833
VZ
658 != wxFONTENCODING_DEFAULT )
659 {
660 SetEncoding(encoding);
661 }
e7e52b6d 662#endif // wxUSE_FONTMAP
ab5fe833
VZ
663 else // assume it is the face name
664 {
665 if ( !face.empty() )
666 {
667 face += _T(' ');
668 }
669
670 face += token;
671
672 // skip the code which resets face below
673 continue;
674 }
675
676 // if we had had the facename, we shouldn't continue appending tokens
677 // to it (i.e. "foo bold bar" shouldn't result in the facename "foo
678 // bar")
679 if ( !face.empty() )
680 {
681 SetFaceName(face);
682 face.clear();
683 }
684 }
685
686 // we might not have flushed it inside the loop
687 if ( !face.empty() )
688 {
689 SetFaceName(face);
690 }
691
a62848fd 692 return true;
ab5fe833
VZ
693}
694
0eb529d9 695#endif // generic or wxMSW or wxOS2
ab5fe833 696