]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/common/fontcmn.cpp
Applied #15375 to stop event-sending in generic wxSpinCtrl ctor (eco)
[wxWidgets.git] / src / common / fontcmn.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: src/common/fontcmn.cpp
3// Purpose: implementation of wxFontBase methods
4// Author: Vadim Zeitlin
5// Modified by:
6// Created: 20.09.99
7// Copyright: (c) wxWidgets team
8// Licence: wxWindows licence
9/////////////////////////////////////////////////////////////////////////////
10
11// ============================================================================
12// declarations
13// ============================================================================
14
15// ----------------------------------------------------------------------------
16// headers
17// ----------------------------------------------------------------------------
18
19// For compilers that support precompilation, includes "wx.h".
20#include "wx/wxprec.h"
21
22#ifdef __BORLANDC__
23 #pragma hdrstop
24#endif
25
26#include "wx/font.h"
27
28#ifndef WX_PRECOMP
29 #include "wx/dc.h"
30 #include "wx/intl.h"
31 #include "wx/math.h"
32 #include "wx/dcscreen.h"
33 #include "wx/log.h"
34 #include "wx/gdicmn.h"
35#endif // WX_PRECOMP
36
37#if defined(__WXMSW__)
38 #include "wx/msw/private.h" // includes windows.h for LOGFONT
39 #include "wx/msw/winundef.h"
40#endif
41
42#include "wx/fontutil.h" // for wxNativeFontInfo
43#include "wx/fontmap.h"
44#include "wx/fontenum.h"
45
46#include "wx/tokenzr.h"
47
48// debugger helper: this function can be called from a debugger to show what
49// the date really is
50extern const char *wxDumpFont(const wxFont *font)
51{
52 static char buf[256];
53
54 const wxFontWeight weight = font->GetWeight();
55
56 wxString s;
57 s.Printf(wxS("%s-%s-%s-%d-%d"),
58 font->GetFaceName(),
59 weight == wxFONTWEIGHT_NORMAL
60 ? wxT("normal")
61 : weight == wxFONTWEIGHT_BOLD
62 ? wxT("bold")
63 : wxT("light"),
64 font->GetStyle() == wxFONTSTYLE_NORMAL
65 ? wxT("regular")
66 : wxT("italic"),
67 font->GetPointSize(),
68 font->GetEncoding());
69
70 wxStrlcpy(buf, s.mb_str(), WXSIZEOF(buf));
71 return buf;
72}
73
74// ----------------------------------------------------------------------------
75// XTI
76// ----------------------------------------------------------------------------
77
78wxBEGIN_ENUM( wxFontFamily )
79wxENUM_MEMBER( wxFONTFAMILY_DEFAULT )
80wxENUM_MEMBER( wxFONTFAMILY_DECORATIVE )
81wxENUM_MEMBER( wxFONTFAMILY_ROMAN )
82wxENUM_MEMBER( wxFONTFAMILY_SCRIPT )
83wxENUM_MEMBER( wxFONTFAMILY_SWISS )
84wxENUM_MEMBER( wxFONTFAMILY_MODERN )
85wxENUM_MEMBER( wxFONTFAMILY_TELETYPE )
86wxEND_ENUM( wxFontFamily )
87
88wxBEGIN_ENUM( wxFontStyle )
89wxENUM_MEMBER( wxFONTSTYLE_NORMAL )
90wxENUM_MEMBER( wxFONTSTYLE_ITALIC )
91wxENUM_MEMBER( wxFONTSTYLE_SLANT )
92wxEND_ENUM( wxFontStyle )
93
94wxBEGIN_ENUM( wxFontWeight )
95wxENUM_MEMBER( wxFONTWEIGHT_NORMAL )
96wxENUM_MEMBER( wxFONTWEIGHT_LIGHT )
97wxENUM_MEMBER( wxFONTWEIGHT_BOLD )
98wxEND_ENUM( wxFontWeight )
99
100wxIMPLEMENT_DYNAMIC_CLASS_WITH_COPY_XTI(wxFont, wxGDIObject, "wx/font.h")
101
102//WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<wxFont>)
103
104wxBEGIN_PROPERTIES_TABLE(wxFont)
105wxPROPERTY( Size,int, SetPointSize, GetPointSize, 12, 0 /*flags*/, \
106 wxT("Helpstring"), wxT("group"))
107wxPROPERTY( Family, wxFontFamily , SetFamily, GetFamily, (wxFontFamily)wxDEFAULT, \
108 0 /*flags*/, wxT("Helpstring"), wxT("group")) // wxFontFamily
109wxPROPERTY( Style, wxFontStyle, SetStyle, GetStyle, (wxFontStyle)wxNORMAL, 0 /*flags*/, \
110 wxT("Helpstring"), wxT("group")) // wxFontStyle
111wxPROPERTY( Weight, wxFontWeight, SetWeight, GetWeight, (wxFontWeight)wxNORMAL, 0 /*flags*/, \
112 wxT("Helpstring"), wxT("group")) // wxFontWeight
113wxPROPERTY( Underlined, bool, SetUnderlined, GetUnderlined, false, 0 /*flags*/, \
114 wxT("Helpstring"), wxT("group"))
115wxPROPERTY( Strikethrough, bool, SetStrikethrough, GetStrikethrough, false, 0, \
116 wxT("Helpstring"), wxT("group"))
117wxPROPERTY( Face, wxString, SetFaceName, GetFaceName, wxEMPTY_PARAMETER_VALUE, \
118 0 /*flags*/, wxT("Helpstring"), wxT("group"))
119wxPROPERTY( Encoding, wxFontEncoding, SetEncoding, GetEncoding, \
120 wxFONTENCODING_DEFAULT, 0 /*flags*/, wxT("Helpstring"), wxT("group"))
121wxEND_PROPERTIES_TABLE()
122
123wxCONSTRUCTOR_6( wxFont, int, Size, wxFontFamily, Family, wxFontStyle, Style, wxFontWeight, Weight, \
124 bool, Underlined, wxString, Face )
125
126wxEMPTY_HANDLERS_TABLE(wxFont)
127
128// ============================================================================
129// implementation
130// ============================================================================
131
132// ----------------------------------------------------------------------------
133// wxFontBase
134// ----------------------------------------------------------------------------
135
136wxFontEncoding wxFontBase::ms_encodingDefault = wxFONTENCODING_SYSTEM;
137
138/* static */
139void wxFontBase::SetDefaultEncoding(wxFontEncoding encoding)
140{
141 // GetDefaultEncoding() should return something != wxFONTENCODING_DEFAULT
142 // and, besides, using this value here doesn't make any sense
143 wxCHECK_RET( encoding != wxFONTENCODING_DEFAULT,
144 wxT("can't set default encoding to wxFONTENCODING_DEFAULT") );
145
146 ms_encodingDefault = encoding;
147}
148
149wxFontBase::~wxFontBase()
150{
151 // this destructor is required for Darwin
152}
153
154/* static */
155wxFont *wxFontBase::New(int size,
156 wxFontFamily family,
157 wxFontStyle style,
158 wxFontWeight weight,
159 bool underlined,
160 const wxString& face,
161 wxFontEncoding encoding)
162{
163 return new wxFont(size, family, style, weight, underlined, face, encoding);
164}
165
166/* static */
167wxFont *wxFontBase::New(const wxSize& pixelSize,
168 wxFontFamily family,
169 wxFontStyle style,
170 wxFontWeight weight,
171 bool underlined,
172 const wxString& face,
173 wxFontEncoding encoding)
174{
175 return new wxFont(pixelSize, family, style, weight, underlined,
176 face, encoding);
177}
178
179/* static */
180wxFont *wxFontBase::New(int pointSize,
181 wxFontFamily family,
182 int flags,
183 const wxString& face,
184 wxFontEncoding encoding)
185{
186 return New(pointSize, family,
187 GetStyleFromFlags(flags),
188 GetWeightFromFlags(flags),
189 GetUnderlinedFromFlags(flags),
190 face, encoding);
191}
192
193/* static */
194wxFont *wxFontBase::New(const wxSize& pixelSize,
195 wxFontFamily family,
196 int flags,
197 const wxString& face,
198 wxFontEncoding encoding)
199{
200 return New(pixelSize, family,
201 GetStyleFromFlags(flags),
202 GetWeightFromFlags(flags),
203 GetUnderlinedFromFlags(flags),
204 face, encoding);
205}
206
207/* static */
208wxFont *wxFontBase::New(const wxNativeFontInfo& info)
209{
210 return new wxFont(info);
211}
212
213/* static */
214wxFont *wxFontBase::New(const wxString& strNativeFontDesc)
215{
216 wxNativeFontInfo fontInfo;
217 if ( !fontInfo.FromString(strNativeFontDesc) )
218 return new wxFont(*wxNORMAL_FONT);
219
220 return New(fontInfo);
221}
222
223bool wxFontBase::IsFixedWidth() const
224{
225 return GetFamily() == wxFONTFAMILY_TELETYPE;
226}
227
228wxSize wxFontBase::GetPixelSize() const
229{
230 wxScreenDC dc;
231 dc.SetFont(*(wxFont *)this);
232 return wxSize(dc.GetCharWidth(), dc.GetCharHeight());
233}
234
235bool wxFontBase::IsUsingSizeInPixels() const
236{
237 return false;
238}
239
240void wxFontBase::SetPixelSize( const wxSize& pixelSize )
241{
242 wxCHECK_RET( pixelSize.GetWidth() >= 0 && pixelSize.GetHeight() > 0,
243 "Negative values for the pixel size or zero pixel height are not allowed" );
244
245 wxScreenDC dc;
246
247 // NOTE: this algorithm for adjusting the font size is used by all
248 // implementations of wxFont except under wxMSW and wxGTK where
249 // native support to font creation using pixel-size is provided.
250
251 int largestGood = 0;
252 int smallestBad = 0;
253
254 bool initialGoodFound = false;
255 bool initialBadFound = false;
256
257 // NB: this assignment was separated from the variable definition
258 // in order to fix a gcc v3.3.3 compiler crash
259 int currentSize = GetPointSize();
260 while (currentSize > 0)
261 {
262 dc.SetFont(*static_cast<wxFont*>(this));
263
264 // if currentSize (in points) results in a font that is smaller
265 // than required by pixelSize it is considered a good size
266 // NOTE: the pixel size width may be zero
267 if (dc.GetCharHeight() <= pixelSize.GetHeight() &&
268 (pixelSize.GetWidth() == 0 ||
269 dc.GetCharWidth() <= pixelSize.GetWidth()))
270 {
271 largestGood = currentSize;
272 initialGoodFound = true;
273 }
274 else
275 {
276 smallestBad = currentSize;
277 initialBadFound = true;
278 }
279 if (!initialGoodFound)
280 {
281 currentSize /= 2;
282 }
283 else if (!initialBadFound)
284 {
285 currentSize *= 2;
286 }
287 else
288 {
289 int distance = smallestBad - largestGood;
290 if (distance == 1)
291 break;
292
293 currentSize = largestGood + distance / 2;
294 }
295
296 SetPointSize(currentSize);
297 }
298
299 if (currentSize != largestGood)
300 SetPointSize(largestGood);
301}
302
303void wxFontBase::DoSetNativeFontInfo(const wxNativeFontInfo& info)
304{
305#ifdef wxNO_NATIVE_FONTINFO
306 SetPointSize(info.pointSize);
307 SetFamily(info.family);
308 SetStyle(info.style);
309 SetWeight(info.weight);
310 SetUnderlined(info.underlined);
311 SetStrikethrough(info.strikethrough);
312 SetFaceName(info.faceName);
313 SetEncoding(info.encoding);
314#else
315 (void)info;
316#endif
317}
318
319wxString wxFontBase::GetNativeFontInfoDesc() const
320{
321 wxCHECK_MSG( IsOk(), wxEmptyString, wxT("invalid font") );
322
323 wxString fontDesc;
324 const wxNativeFontInfo *fontInfo = GetNativeFontInfo();
325 if ( fontInfo )
326 {
327 fontDesc = fontInfo->ToString();
328 wxASSERT_MSG(!fontDesc.empty(), wxT("This should be a non-empty string!"));
329 }
330 else
331 {
332 wxFAIL_MSG(wxT("Derived class should have created the wxNativeFontInfo!"));
333 }
334
335 return fontDesc;
336}
337
338wxString wxFontBase::GetNativeFontInfoUserDesc() const
339{
340 wxCHECK_MSG( IsOk(), wxEmptyString, wxT("invalid font") );
341
342 wxString fontDesc;
343 const wxNativeFontInfo *fontInfo = GetNativeFontInfo();
344 if ( fontInfo )
345 {
346 fontDesc = fontInfo->ToUserString();
347 wxASSERT_MSG(!fontDesc.empty(), wxT("This should be a non-empty string!"));
348 }
349 else
350 {
351 wxFAIL_MSG(wxT("Derived class should have created the wxNativeFontInfo!"));
352 }
353
354 return fontDesc;
355}
356
357bool wxFontBase::SetNativeFontInfo(const wxString& info)
358{
359 wxNativeFontInfo fontInfo;
360 if ( !info.empty() && fontInfo.FromString(info) )
361 {
362 SetNativeFontInfo(fontInfo);
363 return true;
364 }
365
366 return false;
367}
368
369bool wxFontBase::SetNativeFontInfoUserDesc(const wxString& info)
370{
371 wxNativeFontInfo fontInfo;
372 if ( !info.empty() && fontInfo.FromUserString(info) )
373 {
374 SetNativeFontInfo(fontInfo);
375 return true;
376 }
377
378 return false;
379}
380
381bool wxFontBase::operator==(const wxFont& font) const
382{
383 // either it is the same font, i.e. they share the same common data or they
384 // have different ref datas but still describe the same font
385 return IsSameAs(font) ||
386 (
387 IsOk() == font.IsOk() &&
388 GetPointSize() == font.GetPointSize() &&
389 // in wxGTK1 GetPixelSize() calls GetInternalFont() which uses
390 // operator==() resulting in infinite recursion so we can't use it
391 // in that port
392#if !defined(__WXGTK__) || defined(__WXGTK20__)
393 GetPixelSize() == font.GetPixelSize() &&
394#endif
395 GetFamily() == font.GetFamily() &&
396 GetStyle() == font.GetStyle() &&
397 GetWeight() == font.GetWeight() &&
398 GetUnderlined() == font.GetUnderlined() &&
399 GetStrikethrough() == font.GetStrikethrough() &&
400 GetFaceName().IsSameAs(font.GetFaceName(), false) &&
401 GetEncoding() == font.GetEncoding()
402 );
403}
404
405wxFontFamily wxFontBase::GetFamily() const
406{
407 wxCHECK_MSG( IsOk(), wxFONTFAMILY_UNKNOWN, wxS("invalid font") );
408
409 // Don't return wxFONTFAMILY_UNKNOWN from here because it prevents the code
410 // like wxFont(size, wxNORMAL_FONT->GetFamily(), ...) from working (see
411 // #12330). This is really just a hack but it allows to keep compatibility
412 // and doesn't really have any bad drawbacks so do this until someone comes
413 // up with a better idea.
414 const wxFontFamily family = DoGetFamily();
415
416 return family == wxFONTFAMILY_UNKNOWN ? wxFONTFAMILY_DEFAULT : family;
417}
418
419wxString wxFontBase::GetFamilyString() const
420{
421 wxCHECK_MSG( IsOk(), "wxFONTFAMILY_DEFAULT", "invalid font" );
422
423 switch ( GetFamily() )
424 {
425 case wxFONTFAMILY_DECORATIVE: return "wxFONTFAMILY_DECORATIVE";
426 case wxFONTFAMILY_ROMAN: return "wxFONTFAMILY_ROMAN";
427 case wxFONTFAMILY_SCRIPT: return "wxFONTFAMILY_SCRIPT";
428 case wxFONTFAMILY_SWISS: return "wxFONTFAMILY_SWISS";
429 case wxFONTFAMILY_MODERN: return "wxFONTFAMILY_MODERN";
430 case wxFONTFAMILY_TELETYPE: return "wxFONTFAMILY_TELETYPE";
431 case wxFONTFAMILY_UNKNOWN: return "wxFONTFAMILY_UNKNOWN";
432 default: return "wxFONTFAMILY_DEFAULT";
433 }
434}
435
436wxString wxFontBase::GetStyleString() const
437{
438 wxCHECK_MSG( IsOk(), "wxFONTSTYLE_DEFAULT", "invalid font" );
439
440 switch ( GetStyle() )
441 {
442 case wxFONTSTYLE_NORMAL: return "wxFONTSTYLE_NORMAL";
443 case wxFONTSTYLE_SLANT: return "wxFONTSTYLE_SLANT";
444 case wxFONTSTYLE_ITALIC: return "wxFONTSTYLE_ITALIC";
445 default: return "wxFONTSTYLE_DEFAULT";
446 }
447}
448
449wxString wxFontBase::GetWeightString() const
450{
451 wxCHECK_MSG( IsOk(), "wxFONTWEIGHT_DEFAULT", "invalid font" );
452
453 switch ( GetWeight() )
454 {
455 case wxFONTWEIGHT_NORMAL: return "wxFONTWEIGHT_NORMAL";
456 case wxFONTWEIGHT_BOLD: return "wxFONTWEIGHT_BOLD";
457 case wxFONTWEIGHT_LIGHT: return "wxFONTWEIGHT_LIGHT";
458 default: return "wxFONTWEIGHT_DEFAULT";
459 }
460}
461
462bool wxFontBase::SetFaceName(const wxString& facename)
463{
464#if wxUSE_FONTENUM
465 if (!wxFontEnumerator::IsValidFacename(facename))
466 {
467 UnRef(); // make IsOk() return false
468 return false;
469 }
470#else // !wxUSE_FONTENUM
471 wxUnusedVar(facename);
472#endif // wxUSE_FONTENUM/!wxUSE_FONTENUM
473
474 return true;
475}
476
477void wxFontBase::SetSymbolicSize(wxFontSymbolicSize size)
478{
479 SetSymbolicSizeRelativeTo(size, wxNORMAL_FONT->GetPointSize());
480}
481
482/* static */
483int wxFontBase::AdjustToSymbolicSize(wxFontSymbolicSize size, int base)
484{
485 // Using a fixed factor (1.2, from CSS2) is a bad idea as explained at
486 // http://www.w3.org/TR/CSS21/fonts.html#font-size-props so use the values
487 // from http://style.cleverchimp.com/font_size_intervals/altintervals.html
488 // instead.
489 static const float factors[] = { 0.60f, 0.75f, 0.89f, 1.f, 1.2f, 1.5f, 2.f };
490
491 wxCOMPILE_TIME_ASSERT
492 (
493 WXSIZEOF(factors) == wxFONTSIZE_XX_LARGE - wxFONTSIZE_XX_SMALL + 1,
494 WrongFontSizeFactorsSize
495 );
496
497 return wxRound(factors[size - wxFONTSIZE_XX_SMALL]*base);
498}
499
500wxFont& wxFont::MakeBold()
501{
502 SetWeight(wxFONTWEIGHT_BOLD);
503 return *this;
504}
505
506wxFont wxFont::Bold() const
507{
508 wxFont font(*this);
509 font.MakeBold();
510 return font;
511}
512
513wxFont& wxFont::MakeItalic()
514{
515 SetStyle(wxFONTSTYLE_ITALIC);
516 return *this;
517}
518
519wxFont wxFont::Italic() const
520{
521 wxFont font(*this);
522 font.MakeItalic();
523 return font;
524}
525
526wxFont& wxFont::MakeUnderlined()
527{
528 SetUnderlined(true);
529 return *this;
530}
531
532wxFont wxFont::Underlined() const
533{
534 wxFont font(*this);
535 font.MakeUnderlined();
536 return font;
537}
538
539wxFont wxFont::Strikethrough() const
540{
541 wxFont font(*this);
542 font.MakeStrikethrough();
543 return font;
544}
545
546wxFont& wxFont::MakeStrikethrough()
547{
548 SetStrikethrough(true);
549 return *this;
550}
551
552wxFont& wxFont::Scale(float x)
553{
554 SetPointSize(int(x*GetPointSize() + 0.5));
555 return *this;
556}
557
558wxFont wxFont::Scaled(float x) const
559{
560 wxFont font(*this);
561 font.Scale(x);
562 return font;
563}
564
565// ----------------------------------------------------------------------------
566// wxNativeFontInfo
567// ----------------------------------------------------------------------------
568
569// Up to now, there are no native implementations of this function:
570void wxNativeFontInfo::SetFaceName(const wxArrayString& facenames)
571{
572#if wxUSE_FONTENUM
573 for (size_t i=0; i < facenames.GetCount(); i++)
574 {
575 if (wxFontEnumerator::IsValidFacename(facenames[i]))
576 {
577 SetFaceName(facenames[i]);
578 return;
579 }
580 }
581
582 // set the first valid facename we can find on this system
583 wxString validfacename = wxFontEnumerator::GetFacenames().Item(0);
584 wxLogTrace(wxT("font"), wxT("Falling back to '%s'"), validfacename.c_str());
585 SetFaceName(validfacename);
586#else // !wxUSE_FONTENUM
587 SetFaceName(facenames[0]);
588#endif // wxUSE_FONTENUM/!wxUSE_FONTENUM
589}
590
591
592#ifdef wxNO_NATIVE_FONTINFO
593
594// These are the generic forms of FromString()/ToString.
595//
596// convert to/from the string representation: the general format is
597// "version;the rest..." with currently defined versions being:
598//
599// 0;pointsize;family;style;weight;underlined;facename;encoding
600// 1;pointsize;family;style;weight;underlined;strikethrough;facename;encoding
601
602bool wxNativeFontInfo::FromString(const wxString& s)
603{
604 long l;
605 unsigned long version;
606
607 wxStringTokenizer tokenizer(s, wxT(";"));
608
609 wxString token = tokenizer.GetNextToken();
610 if ( !token.ToULong(&version) || version > 1 )
611 return false;
612
613 token = tokenizer.GetNextToken();
614 if ( !token.ToLong(&l) )
615 return false;
616 pointSize = (int)l;
617
618 token = tokenizer.GetNextToken();
619 if ( !token.ToLong(&l) )
620 return false;
621 family = (wxFontFamily)l;
622
623 token = tokenizer.GetNextToken();
624 if ( !token.ToLong(&l) )
625 return false;
626 style = (wxFontStyle)l;
627
628 token = tokenizer.GetNextToken();
629 if ( !token.ToLong(&l) )
630 return false;
631 weight = (wxFontWeight)l;
632
633 token = tokenizer.GetNextToken();
634 if ( !token.ToLong(&l) )
635 return false;
636 underlined = l != 0;
637
638 if ( version == 1 )
639 {
640 token = tokenizer.GetNextToken();
641 if ( !token.ToLong(&l) )
642 return false;
643 strikethrough = l != 0;
644 }
645
646 faceName = tokenizer.GetNextToken();
647
648#ifndef __WXMAC__
649 if( !faceName )
650 return false;
651#endif
652
653 token = tokenizer.GetNextToken();
654 if ( !token.ToLong(&l) )
655 return false;
656 encoding = (wxFontEncoding)l;
657
658 return true;
659}
660
661wxString wxNativeFontInfo::ToString() const
662{
663 wxString s;
664
665 s.Printf(wxT("%d;%d;%d;%d;%d;%d;%d;%s;%d"),
666 1, // version
667 pointSize,
668 family,
669 (int)style,
670 (int)weight,
671 underlined,
672 strikethrough,
673 faceName.GetData(),
674 (int)encoding);
675
676 return s;
677}
678
679void wxNativeFontInfo::Init()
680{
681 pointSize = 0;
682 family = wxFONTFAMILY_DEFAULT;
683 style = wxFONTSTYLE_NORMAL;
684 weight = wxFONTWEIGHT_NORMAL;
685 underlined = false;
686 strikethrough = false;
687 faceName.clear();
688 encoding = wxFONTENCODING_DEFAULT;
689}
690
691int wxNativeFontInfo::GetPointSize() const
692{
693 return pointSize;
694}
695
696wxFontStyle wxNativeFontInfo::GetStyle() const
697{
698 return style;
699}
700
701wxFontWeight wxNativeFontInfo::GetWeight() const
702{
703 return weight;
704}
705
706bool wxNativeFontInfo::GetUnderlined() const
707{
708 return underlined;
709}
710
711bool wxNativeFontInfo::GetStrikethrough() const
712{
713 return strikethrough;
714}
715
716wxString wxNativeFontInfo::GetFaceName() const
717{
718 return faceName;
719}
720
721wxFontFamily wxNativeFontInfo::GetFamily() const
722{
723 return family;
724}
725
726wxFontEncoding wxNativeFontInfo::GetEncoding() const
727{
728 return encoding;
729}
730
731void wxNativeFontInfo::SetPointSize(int pointsize)
732{
733 pointSize = pointsize;
734}
735
736void wxNativeFontInfo::SetStyle(wxFontStyle style_)
737{
738 style = style_;
739}
740
741void wxNativeFontInfo::SetWeight(wxFontWeight weight_)
742{
743 weight = weight_;
744}
745
746void wxNativeFontInfo::SetUnderlined(bool underlined_)
747{
748 underlined = underlined_;
749}
750
751void wxNativeFontInfo::SetStrikethrough(bool strikethrough_)
752{
753 strikethrough = strikethrough_;
754}
755
756bool wxNativeFontInfo::SetFaceName(const wxString& facename_)
757{
758 faceName = facename_;
759 return true;
760}
761
762void wxNativeFontInfo::SetFamily(wxFontFamily family_)
763{
764 family = family_;
765}
766
767void wxNativeFontInfo::SetEncoding(wxFontEncoding encoding_)
768{
769 encoding = encoding_;
770}
771
772#endif // generic wxNativeFontInfo implementation
773
774// conversion to/from user-readable string: this is used in the generic
775// versions and under MSW as well because there is no standard font description
776// format there anyhow (but there is a well-defined standard for X11 fonts used
777// by wxGTK and wxMotif)
778
779#if defined(wxNO_NATIVE_FONTINFO) || defined(__WXMSW__) || defined (__WXPM__) || defined(__WXOSX__)
780
781wxString wxNativeFontInfo::ToUserString() const
782{
783 wxString desc;
784
785 // first put the adjectives, if any - this is English-centric, of course,
786 // but what else can we do?
787 if ( GetUnderlined() )
788 {
789 desc << _("underlined");
790 }
791
792 if ( GetStrikethrough() )
793 {
794 desc << _("strikethrough");
795 }
796
797 switch ( GetWeight() )
798 {
799 default:
800 wxFAIL_MSG( wxT("unknown font weight") );
801 // fall through
802
803 case wxFONTWEIGHT_NORMAL:
804 break;
805
806 case wxFONTWEIGHT_LIGHT:
807 desc << _(" light");
808 break;
809
810 case wxFONTWEIGHT_BOLD:
811 desc << _(" bold");
812 break;
813 }
814
815 switch ( GetStyle() )
816 {
817 default:
818 wxFAIL_MSG( wxT("unknown font style") );
819 // fall through
820
821 case wxFONTSTYLE_NORMAL:
822 break;
823
824 // we don't distinguish between the two for now anyhow...
825 case wxFONTSTYLE_ITALIC:
826 case wxFONTSTYLE_SLANT:
827 desc << _(" italic");
828 break;
829 }
830
831 wxString face = GetFaceName();
832 if ( !face.empty() )
833 {
834 if (face.Contains(' ') || face.Contains(';') || face.Contains(','))
835 {
836 face.Replace("'", "");
837 // eventually remove quote characters: most systems do not
838 // allow them in a facename anyway so this usually does nothing
839
840 // make it possible for FromUserString() function to understand
841 // that the different words which compose this facename are
842 // not different adjectives or other data but rather all parts
843 // of the facename
844 desc << wxT(" '") << face << wxT("'");
845 }
846 else
847 desc << wxT(' ') << face;
848 }
849 else // no face name specified
850 {
851 // use the family
852 wxString familyStr;
853 switch ( GetFamily() )
854 {
855 case wxFONTFAMILY_DECORATIVE:
856 familyStr = "decorative";
857 break;
858
859 case wxFONTFAMILY_ROMAN:
860 familyStr = "roman";
861 break;
862
863 case wxFONTFAMILY_SCRIPT:
864 familyStr = "script";
865 break;
866
867 case wxFONTFAMILY_SWISS:
868 familyStr = "swiss";
869 break;
870
871 case wxFONTFAMILY_MODERN:
872 familyStr = "modern";
873 break;
874
875 case wxFONTFAMILY_TELETYPE:
876 familyStr = "teletype";
877 break;
878
879 case wxFONTFAMILY_DEFAULT:
880 case wxFONTFAMILY_UNKNOWN:
881 break;
882
883 default:
884 wxFAIL_MSG( "unknown font family" );
885 }
886
887 if ( !familyStr.empty() )
888 desc << " '" << familyStr << " family'";
889 }
890
891 int size = GetPointSize();
892 if ( size != wxNORMAL_FONT->GetPointSize() )
893 {
894 desc << wxT(' ') << size;
895 }
896
897#if wxUSE_FONTMAP
898 wxFontEncoding enc = GetEncoding();
899 if ( enc != wxFONTENCODING_DEFAULT && enc != wxFONTENCODING_SYSTEM )
900 {
901 desc << wxT(' ') << wxFontMapper::GetEncodingName(enc);
902 }
903#endif // wxUSE_FONTMAP
904
905 return desc.Strip(wxString::both).MakeLower();
906}
907
908bool wxNativeFontInfo::FromUserString(const wxString& s)
909{
910 // reset to the default state
911 Init();
912
913 // ToUserString() will quote the facename if it contains spaces, commas
914 // or semicolons: we must be able to understand that quoted text is
915 // a single token:
916 wxString toparse(s);
917
918 // parse a more or less free form string
919 wxStringTokenizer tokenizer(toparse, wxT(";, "), wxTOKEN_STRTOK);
920
921 wxString face;
922 unsigned long size;
923 bool weightfound = false, pointsizefound = false;
924#if wxUSE_FONTMAP
925 bool encodingfound = false;
926#endif
927 bool insideQuotes = false;
928
929 while ( tokenizer.HasMoreTokens() )
930 {
931 wxString token = tokenizer.GetNextToken();
932
933 // normalize it
934 token.Trim(true).Trim(false).MakeLower();
935 if (insideQuotes)
936 {
937 if (token.StartsWith("'") ||
938 token.EndsWith("'"))
939 {
940 insideQuotes = false;
941
942 // add this last token to the facename:
943 face += " " + token;
944
945 // normalize facename:
946 face = face.Trim(true).Trim(false);
947 face.Replace("'", "");
948
949 continue;
950 }
951 }
952 else
953 {
954 if (token.StartsWith("'"))
955 insideQuotes = true;
956 }
957
958 // look for the known tokens
959 if ( insideQuotes )
960 {
961 // only the facename may be quoted:
962 face += " " + token;
963 continue;
964 }
965 if ( token == wxT("underlined") || token == _("underlined") )
966 {
967 SetUnderlined(true);
968 }
969 else if ( token == wxT("strikethrough") || token == _("strikethrough") )
970 {
971 SetStrikethrough(true);
972 }
973 else if ( token == wxT("light") || token == _("light") )
974 {
975 SetWeight(wxFONTWEIGHT_LIGHT);
976 weightfound = true;
977 }
978 else if ( token == wxT("bold") || token == _("bold") )
979 {
980 SetWeight(wxFONTWEIGHT_BOLD);
981 weightfound = true;
982 }
983 else if ( token == wxT("italic") || token == _("italic") )
984 {
985 SetStyle(wxFONTSTYLE_ITALIC);
986 }
987 else if ( token.ToULong(&size) )
988 {
989 SetPointSize(size);
990 pointsizefound = true;
991 }
992 else
993 {
994#if wxUSE_FONTMAP
995 // try to interpret this as an encoding
996 wxFontEncoding encoding = wxFontMapper::Get()->CharsetToEncoding(token, false);
997 if ( encoding != wxFONTENCODING_DEFAULT &&
998 encoding != wxFONTENCODING_SYSTEM ) // returned when the recognition failed
999 {
1000 SetEncoding(encoding);
1001 encodingfound = true;
1002 }
1003 else
1004 {
1005#endif // wxUSE_FONTMAP
1006
1007 // assume it is the face name
1008 if ( !face.empty() )
1009 {
1010 face += wxT(' ');
1011 }
1012
1013 face += token;
1014
1015 // skip the code which resets face below
1016 continue;
1017
1018#if wxUSE_FONTMAP
1019 }
1020#endif // wxUSE_FONTMAP
1021 }
1022
1023 // if we had had the facename, we shouldn't continue appending tokens
1024 // to it (i.e. "foo bold bar" shouldn't result in the facename "foo
1025 // bar")
1026 if ( !face.empty() )
1027 {
1028 wxString familyStr;
1029 if ( face.EndsWith(" family", &familyStr) )
1030 {
1031 // it's not a facename but rather a font family
1032 wxFontFamily family;
1033 if ( familyStr == "decorative" )
1034 family = wxFONTFAMILY_DECORATIVE;
1035 else if ( familyStr == "roman" )
1036 family = wxFONTFAMILY_ROMAN;
1037 else if ( familyStr == "script" )
1038 family = wxFONTFAMILY_SCRIPT;
1039 else if ( familyStr == "swiss" )
1040 family = wxFONTFAMILY_SWISS;
1041 else if ( familyStr == "modern" )
1042 family = wxFONTFAMILY_MODERN;
1043 else if ( familyStr == "teletype" )
1044 family = wxFONTFAMILY_TELETYPE;
1045 else
1046 return false;
1047
1048 SetFamily(family);
1049 }
1050 // NB: the check on the facename is implemented in wxFontBase::SetFaceName
1051 // and not in wxNativeFontInfo::SetFaceName thus we need to explicitly
1052 // call here wxFontEnumerator::IsValidFacename
1053 else if (
1054#if wxUSE_FONTENUM
1055 !wxFontEnumerator::IsValidFacename(face) ||
1056#endif // wxUSE_FONTENUM
1057 !SetFaceName(face) )
1058 {
1059 SetFaceName(wxNORMAL_FONT->GetFaceName());
1060 }
1061
1062 face.clear();
1063 }
1064 }
1065
1066 // we might not have flushed it inside the loop
1067 if ( !face.empty() )
1068 {
1069 // NB: the check on the facename is implemented in wxFontBase::SetFaceName
1070 // and not in wxNativeFontInfo::SetFaceName thus we need to explicitly
1071 // call here wxFontEnumerator::IsValidFacename
1072 if (
1073#if wxUSE_FONTENUM
1074 !wxFontEnumerator::IsValidFacename(face) ||
1075#endif // wxUSE_FONTENUM
1076 !SetFaceName(face) )
1077 {
1078 SetFaceName(wxNORMAL_FONT->GetFaceName());
1079 }
1080 }
1081
1082 // set point size to default value if size was not given
1083 if ( !pointsizefound )
1084 SetPointSize(wxNORMAL_FONT->GetPointSize());
1085
1086 // set font weight to default value if weight was not given
1087 if ( !weightfound )
1088 SetWeight(wxFONTWEIGHT_NORMAL);
1089
1090#if wxUSE_FONTMAP
1091 // set font encoding to default value if encoding was not given
1092 if ( !encodingfound )
1093 SetEncoding(wxFONTENCODING_SYSTEM);
1094#endif // wxUSE_FONTMAP
1095
1096 return true;
1097}
1098
1099#endif // generic or wxMSW or wxOS2
1100
1101
1102// wxFont <-> wxString utilities, used by wxConfig
1103wxString wxToString(const wxFontBase& font)
1104{
1105 return font.IsOk() ? font.GetNativeFontInfoDesc()
1106 : wxString();
1107}
1108
1109bool wxFromString(const wxString& str, wxFontBase *font)
1110{
1111 wxCHECK_MSG( font, false, wxT("NULL output parameter") );
1112
1113 if ( str.empty() )
1114 {
1115 *font = wxNullFont;
1116 return true;
1117 }
1118
1119 return font->SetNativeFontInfo(str);
1120}
1121
1122