]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/os2/font.cpp
Allow wx parents a chance to handle events fired by non-wx children. (i.e. wxActiveX...
[wxWidgets.git] / src / os2 / font.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: font.cpp
3// Purpose: wxFont class
4// Author: David Webster
5// Modified by:
6// Created: 10/06/99
7// RCS-ID: $Id$
8// Copyright: (c) David Webster
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12// For compilers that support precompilation, includes "wx.h".
13#include "wx/wxprec.h"
14
15// ============================================================================
16// declarations
17// ============================================================================
18
19// ----------------------------------------------------------------------------
20// headers
21// ----------------------------------------------------------------------------
22
23#ifndef WX_PRECOMP
24 #include <stdio.h>
25 #include "wx/setup.h"
26 #include "wx/list.h"
27 #include "wx/utils.h"
28 #include "wx/app.h"
29 #include "wx/font.h"
30 #include "wx/log.h"
31#endif // WX_PRECOMP
32
33#include "wx/os2/private.h"
34
35#include "wx/fontutil.h"
36#include "wx/fontmap.h"
37#include "wx/encinfo.h"
38
39#include "wx/tokenzr.h"
40
41#include <malloc.h>
42
43IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
44
45// ----------------------------------------------------------------------------
46// wxFontRefData - the internal description of the font
47// ----------------------------------------------------------------------------
48
49class WXDLLEXPORT wxFontRefData: public wxGDIRefData
50{
51public:
52 wxFontRefData()
53 {
54 Init(-1, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, FALSE,
55 wxEmptyString, wxFONTENCODING_DEFAULT);
56 }
57
58 wxFontRefData( int nSize
59 ,int nFamily
60 ,int nStyle
61 ,int nWeight
62 ,bool bUnderlined
63 ,const wxString& sFaceName
64 ,wxFontEncoding vEncoding
65 )
66 {
67 Init( nSize
68 ,nFamily
69 ,nStyle
70 ,nWeight
71 ,bUnderlined
72 ,sFaceName
73 ,vEncoding
74 );
75 }
76
77 wxFontRefData( const wxNativeFontInfo& rInfo
78 ,WXHFONT hFont = 0
79 ,WXHANDLE hPS = 0
80 )
81 {
82 Init( rInfo
83 ,hFont
84 ,hPS
85 );
86 }
87
88 wxFontRefData(const wxFontRefData& rData)
89 {
90 Init( rData.m_nPointSize
91 ,rData.m_nFamily
92 ,rData.m_nStyle
93 ,rData.m_nWeight
94 ,rData.m_bUnderlined
95 ,rData.m_sFaceName
96 ,rData.m_vEncoding
97 );
98 m_nFontId = rData.m_nFontId;
99 }
100
101 virtual ~wxFontRefData();
102
103 //
104 // Operations
105 //
106 bool Alloc(wxFont* pFont);
107 void Free(void);
108
109 //
110 // All wxFont accessors
111 //
112 inline int GetPointSize(void) const
113 {
114 //
115 // We don't use the actual native font point size since it is
116 // the chosen physical font, which is usually only and approximation
117 // of the desired outline font. The actual displayable point size
118 // is the one stored in the refData
119 //
120 return m_nPointSize;
121 }
122
123 inline int GetFamily(void) const
124 {
125 return m_nFamily;
126 }
127
128 inline int GetStyle(void) const
129 {
130 return m_bNativeFontInfoOk ? m_vNativeFontInfo.GetStyle()
131 : m_nStyle;
132 }
133
134 inline int GetWeight(void) const
135 {
136 return m_bNativeFontInfoOk ? m_vNativeFontInfo.GetWeight()
137 : m_nWeight;
138 }
139
140 inline bool GetUnderlined(void) const
141 {
142 return m_bNativeFontInfoOk ? m_vNativeFontInfo.GetUnderlined()
143 : m_bUnderlined;
144 }
145
146 inline wxString GetFaceName(void) const
147 {
148 wxString sFaceName;
149
150 if (m_bNativeFontInfoOk)
151 sFaceName = m_vNativeFontInfo.GetFaceName();
152 else
153 sFaceName = m_sFaceName;
154
155 return sFaceName;
156 }
157
158 inline wxFontEncoding GetEncoding(void) const
159 {
160 return m_bNativeFontInfoOk ? m_vNativeFontInfo.GetEncoding()
161 : m_vEncoding;
162 }
163
164 inline WXHFONT GetHFONT(void) const { return m_hFont; }
165 inline HPS GetPS(void) const { return m_hPS; }
166 inline PFONTMETRICS GetFM(void) const { return m_pFM; }
167 inline int GetNumFonts(void) const { return m_nNumFonts; }
168
169 // ... and setters
170 inline void SetPointSize(int nPointSize)
171 {
172 if (m_bNativeFontInfoOk)
173 m_vNativeFontInfo.SetPointSize(nPointSize);
174 else
175 m_nPointSize = nPointSize;
176 }
177
178 inline void SetFamily(int nFamily)
179 {
180 m_nFamily = nFamily;
181 }
182
183 inline void SetStyle(int nStyle)
184 {
185 if (m_bNativeFontInfoOk)
186 m_vNativeFontInfo.SetStyle((wxFontStyle)nStyle);
187 else
188 m_nStyle = nStyle;
189 }
190
191 inline void SetWeight(int nWeight)
192 {
193 if (m_bNativeFontInfoOk)
194 m_vNativeFontInfo.SetWeight((wxFontWeight)nWeight);
195 else
196 m_nWeight = nWeight;
197 }
198
199 inline void SetFaceName(const wxString& sFaceName)
200 {
201 if (m_bNativeFontInfoOk)
202 m_vNativeFontInfo.SetFaceName(sFaceName);
203 else
204 m_sFaceName = sFaceName;
205 }
206
207 inline void SetUnderlined(bool bUnderlined)
208 {
209 if (m_bNativeFontInfoOk)
210 m_vNativeFontInfo.SetUnderlined(bUnderlined);
211 else
212 m_bUnderlined = bUnderlined;
213 }
214
215 inline void SetEncoding(wxFontEncoding vEncoding)
216 {
217 if (m_bNativeFontInfoOk)
218 m_vNativeFontInfo.SetEncoding(vEncoding);
219 else
220 m_vEncoding = vEncoding;
221 }
222
223 inline void SetPS(HPS hPS)
224 {
225 m_hPS = hPS;
226 }
227
228 inline void SetFM(PFONTMETRICS pFM)
229 {
230 m_pFM = pFM;
231 }
232
233 inline void SetNumFonts(int nNumFonts)
234 {
235 m_nNumFonts = nNumFonts;
236 }
237
238 //
239 // Native font info tests
240 //
241 bool HasNativeFontInfo() const { return m_bNativeFontInfoOk; }
242
243 const wxNativeFontInfo& GetNativeFontInfo() const
244 { return m_vNativeFontInfo; }
245
246protected:
247 //
248 // Common part of all ctors
249 //
250 void Init( int nSize
251 ,int nFamily
252 ,int nStyle
253 ,int nWeight
254 ,bool bUnderlined
255 ,const wxString& rsFaceName
256 ,wxFontEncoding vEncoding
257 );
258
259 void Init( const wxNativeFontInfo& rInfo
260 ,WXHFONT hFont = 0
261 ,WXHANDLE hPS = 0
262 );
263 //
264 // If true, the pointer to the actual font is temporary and SHOULD NOT BE
265 // DELETED by destructor
266 //
267 bool m_bTemporary;
268 int m_nFontId;
269
270 //
271 // Font characterstics
272 //
273 int m_nPointSize;
274 int m_nFamily;
275 int m_nStyle;
276 int m_nWeight;
277 bool m_bUnderlined;
278 wxString m_sFaceName;
279 wxFontEncoding m_vEncoding;
280 WXHFONT m_hFont;
281
282 //
283 // Native font info
284 //
285 wxNativeFontInfo m_vNativeFontInfo;
286 bool m_bNativeFontInfoOk;
287
288 //
289 // Some PM specific stuff
290 //
291 PFONTMETRICS m_pFM; // array of FONTMETRICS structs
292 int m_nNumFonts; // number of fonts in array
293 HPS m_hPS; // PS handle this font belongs to
294 FATTRS m_vFattrs; // Current fattrs struct
295 FACENAMEDESC m_vFname; // Current facename struct
296 bool m_bInternalPS; // Internally generated PS?
297}; // end of CLASS wxFontRefData
298
299// ============================================================================
300// implementation
301// ============================================================================
302
303// ----------------------------------------------------------------------------
304// wxFontRefData
305// ----------------------------------------------------------------------------
306
307void wxFontRefData::Init(
308 int nPointSize
309, int nFamily
310, int nStyle
311, int nWeight
312, bool bUnderlined
313, const wxString& rsFaceName
314, wxFontEncoding vEncoding
315)
316{
317 m_nStyle = nStyle;
318 m_nPointSize = nPointSize;
319 m_nFamily = nFamily;
320 m_nStyle = nStyle;
321 m_nWeight = nWeight;
322 m_bUnderlined = bUnderlined;
323 m_sFaceName = rsFaceName;
324 m_vEncoding = vEncoding;
325 m_hFont = 0;
326
327 m_bNativeFontInfoOk = FALSE;
328
329 m_nFontId = 0;
330 m_bTemporary = FALSE;
331 m_pFM = (PFONTMETRICS)NULL;
332 m_hPS = NULLHANDLE;
333 m_nNumFonts = 0;
334} // end of wxFontRefData::Init
335
336void wxFontRefData::Init(
337 const wxNativeFontInfo& rInfo
338, WXHFONT hFont //this is the FontId -- functions as the hFont for OS/2
339, WXHANDLE hPS // Presentation Space we are using
340)
341{
342 //
343 // hFont may be zero, or it be passed in case we really want to
344 // use the exact font created in the underlying system
345 // (for example where we can't guarantee conversion from HFONT
346 // to LOGFONT back to HFONT)
347 //
348 m_hFont = hFont;
349 m_nFontId = (int)hFont;
350
351 m_bNativeFontInfoOk = true;
352 m_vNativeFontInfo = rInfo;
353
354 if (hPS == NULLHANDLE)
355 {
356 m_hPS = ::WinGetPS(HWND_DESKTOP);
357 m_bInternalPS = true;
358 }
359 else
360 m_hPS = (HPS)hPS;
361
362 m_nFontId = 0;
363 m_bTemporary = FALSE;
364 m_pFM = (PFONTMETRICS)NULL;
365 m_nNumFonts = 0;
366} // end of wxFontRefData::Init
367
368wxFontRefData::~wxFontRefData()
369{
370 Free();
371}
372
373bool wxFontRefData::Alloc( wxFont* pFont )
374{
375 wxString sFaceName;
376 long flId = m_hFont;
377 long lRc;
378 ERRORID vError;
379 wxString sError;
380
381 if (!m_bNativeFontInfoOk)
382 {
383 wxFillLogFont( &m_vNativeFontInfo.fa
384 ,&m_vNativeFontInfo.fn
385 ,&m_hPS
386 ,&m_bInternalPS
387 ,&flId
388 ,sFaceName
389 ,pFont
390 );
391 m_bNativeFontInfoOk = true;
392 }
393 else
394 {
395 if (flId == 0L)
396 flId = 1L;
397 else
398 flId++;
399 if (flId > 254)
400 flId = 1L;
401 }
402 if((lRc = ::GpiCreateLogFont( m_hPS
403 ,NULL
404 ,flId
405 ,&m_vNativeFontInfo.fa
406 )) != GPI_ERROR)
407 {
408 m_hFont = (WXHFONT)flId;
409 m_nFontId = flId;
410 }
411 if (!m_hFont)
412 {
413 vError = ::WinGetLastError(vHabmain);
414 sError = wxPMErrorToStr(vError);
415 wxLogLastError(wxT("CreateFont"));
416 }
417
418 ::GpiSetCharSet(m_hPS, flId); // sets font for presentation space
419 ::GpiQueryFontMetrics(m_hPS, sizeof(FONTMETRICS), &m_vNativeFontInfo.fm);
420
421 //
422 // Set refData members with the results
423 //
424 memcpy(&m_vFattrs, &m_vNativeFontInfo.fa, sizeof(m_vFattrs));
425 memcpy(&m_vFname, &m_vNativeFontInfo.fn, sizeof(m_vFname));
426 //
427 // Going to leave the point size alone. Mostly we use outline fonts
428 // that can be set to any point size inside of Presentation Parameters,
429 // regardless of whether or not the actual font is registered in the system.
430 // The GpiCreateLogFont will do enough by selecting the right family,
431 // and face name.
432 //
433 if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Times New Roman") == 0)
434 m_nFamily = wxROMAN;
435 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Times New Roman MT 30") == 0)
436 m_nFamily = wxROMAN;
437 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "@Times New Roman MT 30") == 0)
438 m_nFamily = wxROMAN;
439 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Tms Rmn") == 0)
440 m_nFamily = wxROMAN;
441 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "WarpSans") == 0)
442 m_nFamily = wxDECORATIVE;
443 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Helvetica") == 0)
444 m_nFamily = wxSWISS;
445 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Helv") == 0)
446 m_nFamily = wxSWISS;
447 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Script") == 0)
448 m_nFamily = wxSCRIPT;
449 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Courier New") == 0)
450 m_nFamily = wxTELETYPE;
451 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Courier") == 0)
452 m_nFamily = wxTELETYPE;
453 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "System Monospaced") == 0)
454 m_nFamily = wxTELETYPE;
455 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "System VIO") == 0)
456 m_nFamily = wxMODERN;
457 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "System Proportional") == 0)
458 m_nFamily = wxMODERN;
459 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Arial") == 0)
460 m_nFamily = wxSWISS;
461 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Swiss") == 0)
462 m_nFamily = wxSWISS;
463 else
464 m_nFamily = wxSWISS;
465
466 if (m_vNativeFontInfo.fa.fsSelection & FATTR_SEL_ITALIC)
467 m_nStyle = wxFONTSTYLE_ITALIC;
468 else
469 m_nStyle = wxFONTSTYLE_NORMAL;
470 switch(m_vNativeFontInfo.fn.usWeightClass)
471 {
472 case FWEIGHT_DONT_CARE:
473 m_nWeight = wxFONTWEIGHT_NORMAL;
474 break;
475
476 case FWEIGHT_NORMAL:
477 m_nWeight = wxFONTWEIGHT_NORMAL;
478 break;
479
480 case FWEIGHT_LIGHT:
481 m_nWeight = wxFONTWEIGHT_LIGHT;
482 break;
483
484 case FWEIGHT_BOLD:
485 m_nWeight = wxFONTWEIGHT_BOLD;
486 break;
487
488 case FWEIGHT_ULTRA_BOLD:
489 m_nWeight = wxFONTWEIGHT_MAX;
490 break;
491
492 default:
493 m_nWeight = wxFONTWEIGHT_NORMAL;
494 }
495 m_bUnderlined = ((m_vNativeFontInfo.fa.fsSelection & FATTR_SEL_UNDERSCORE) != 0);
496 m_sFaceName = (wxChar*)m_vNativeFontInfo.fa.szFacename;
497 m_vEncoding = wxGetFontEncFromCharSet(m_vNativeFontInfo.fa.usCodePage);
498
499 //
500 // We don't actuall keep the font around if using a temporary PS
501 //
502 if (m_bInternalPS)
503 {
504 if(m_hFont)
505 ::GpiDeleteSetId( m_hPS
506 ,flId
507 );
508
509 ::WinReleasePS(m_hPS);
510 }
511 else
512 //
513 // Select the font into the Presentation space
514 //
515 ::GpiSetCharSet(m_hPS, flId); // sets font for presentation space
516 return true;
517} // end of wxFontRefData::Alloc
518
519void wxFontRefData::Free()
520{
521 if (m_pFM)
522 delete [] m_pFM;
523 m_pFM = (PFONTMETRICS)NULL;
524
525 if ( m_hFont )
526 {
527 ::GpiDeleteSetId(m_hPS, 1L); /* delete the logical font */
528 m_nFontId = 0;
529 m_hFont = 0;
530 }
531 if (m_bInternalPS)
532 ::WinReleasePS(m_hPS);
533 m_hPS = NULLHANDLE;
534} // end of wxFontRefData::Free
535
536// ----------------------------------------------------------------------------
537// wxNativeFontInfo
538// ----------------------------------------------------------------------------
539
540void wxNativeFontInfo::Init()
541{
542 memset(&fa, '\0', sizeof(FATTRS));
543} // end of wxNativeFontInfo::Init
544
545int wxNativeFontInfo::GetPointSize() const
546{
547 return fm.lEmHeight;
548} // end of wxNativeFontInfo::GetPointSize
549
550wxFontStyle wxNativeFontInfo::GetStyle() const
551{
552 return fa.fsSelection & FATTR_SEL_ITALIC ? wxFONTSTYLE_ITALIC : wxFONTSTYLE_NORMAL;
553} // end of wxNativeFontInfo::GetStyle
554
555wxFontWeight wxNativeFontInfo::GetWeight() const
556{
557 switch(fn.usWeightClass)
558 {
559 case FWEIGHT_DONT_CARE:
560 return wxFONTWEIGHT_NORMAL;
561
562 case FWEIGHT_NORMAL:
563 return wxFONTWEIGHT_NORMAL;
564
565 case FWEIGHT_LIGHT:
566 return wxFONTWEIGHT_LIGHT;
567
568 case FWEIGHT_BOLD:
569 return wxFONTWEIGHT_BOLD;
570
571 case FWEIGHT_ULTRA_BOLD:
572 return wxFONTWEIGHT_MAX;
573 }
574 return wxFONTWEIGHT_NORMAL;
575} // end of wxNativeFontInfo::GetWeight
576
577bool wxNativeFontInfo::GetUnderlined() const
578{
579 return ((fa.fsSelection & FATTR_SEL_UNDERSCORE) != 0);
580} // end of wxNativeFontInfo::GetUnderlined
581
582wxString wxNativeFontInfo::GetFaceName() const
583{
584 return (wxChar*)fm.szFacename;
585} // end of wxNativeFontInfo::GetFaceName
586
587wxFontFamily wxNativeFontInfo::GetFamily() const
588{
589 int nFamily;
590
591 //
592 // Extract family from facename
593 //
594 if (strcmp(fm.szFamilyname, "Times New Roman") == 0)
595 nFamily = wxROMAN;
596 else if (strcmp(fm.szFamilyname, "Times New Roman MT 30") == 0)
597 nFamily = wxROMAN;
598 else if (strcmp(fm.szFamilyname, "@Times New Roman MT 30") == 0)
599 nFamily = wxROMAN;
600 else if (strcmp(fm.szFamilyname, "Tms Rmn") == 0)
601 nFamily = wxROMAN;
602 else if (strcmp(fm.szFamilyname, "WarpSans") == 0)
603 nFamily = wxDECORATIVE;
604 else if (strcmp(fm.szFamilyname, "Helvetica") == 0)
605 nFamily = wxSWISS;
606 else if (strcmp(fm.szFamilyname, "Helv") == 0)
607 nFamily = wxSWISS;
608 else if (strcmp(fm.szFamilyname, "Script") == 0)
609 nFamily = wxSCRIPT;
610 else if (strcmp(fm.szFamilyname, "Courier New") == 0)
611 nFamily = wxTELETYPE;
612 else if (strcmp(fm.szFamilyname, "Courier") == 0)
613 nFamily = wxTELETYPE;
614 else if (strcmp(fm.szFamilyname, "System Monospaced") == 0)
615 nFamily = wxTELETYPE;
616 else if (strcmp(fm.szFamilyname, "System VIO") == 0)
617 nFamily = wxMODERN;
618 else if (strcmp(fm.szFamilyname, "System Proportional") == 0)
619 nFamily = wxMODERN;
620 else if (strcmp(fm.szFamilyname, "Arial") == 0)
621 nFamily = wxSWISS;
622 else if (strcmp(fm.szFamilyname, "Swiss") == 0)
623 nFamily = wxSWISS;
624 else
625 nFamily = wxSWISS;
626 return (wxFontFamily)nFamily;
627} // end of wxNativeFontInfo::GetFamily
628
629wxFontEncoding wxNativeFontInfo::GetEncoding() const
630{
631 return wxGetFontEncFromCharSet(fa.usCodePage);
632} // end of wxNativeFontInfo::GetEncoding
633
634void wxNativeFontInfo::SetPointSize(
635 int nPointsize
636)
637{
638 fm.lEmHeight = (LONG)nPointsize;
639} // end of wxNativeFontInfo::SetPointSize
640
641void wxNativeFontInfo::SetStyle(
642 wxFontStyle eStyle
643)
644{
645 switch (eStyle)
646 {
647 default:
648 wxFAIL_MSG( _T("unknown font style") );
649 // fall through
650
651 case wxFONTSTYLE_NORMAL:
652 break;
653
654 case wxFONTSTYLE_ITALIC:
655 case wxFONTSTYLE_SLANT:
656 fa.fsSelection |= FATTR_SEL_ITALIC;
657 break;
658 }
659} // end of wxNativeFontInfo::SetStyle
660
661void wxNativeFontInfo::SetWeight(
662 wxFontWeight eWeight
663)
664{
665 switch (eWeight)
666 {
667 default:
668 wxFAIL_MSG( _T("unknown font weight") );
669 // fall through
670
671 case wxFONTWEIGHT_NORMAL:
672 fn.usWeightClass = FWEIGHT_NORMAL;
673 break;
674
675 case wxFONTWEIGHT_LIGHT:
676 fn.usWeightClass = FWEIGHT_LIGHT;
677 break;
678
679 case wxFONTWEIGHT_BOLD:
680 fn.usWeightClass = FWEIGHT_BOLD;
681 break;
682 }
683} // end of wxNativeFontInfo::SetWeight
684
685void wxNativeFontInfo::SetUnderlined(
686 bool bUnderlined
687)
688{
689 if(bUnderlined)
690 fa.fsSelection |= FATTR_SEL_UNDERSCORE;
691} // end of wxNativeFontInfo::SetUnderlined
692
693void wxNativeFontInfo::SetFaceName(
694 const wxString& sFacename
695)
696{
697 wxStrncpy((wxChar*)fa.szFacename, sFacename, WXSIZEOF(fa.szFacename));
698} // end of wxNativeFontInfo::SetFaceName
699
700void wxNativeFontInfo::SetFamily(
701 wxFontFamily eFamily
702)
703{
704 wxString sFacename;
705
706 switch (eFamily)
707 {
708 case wxSCRIPT:
709 sFacename = wxT("Tms Rmn");
710 break;
711
712 case wxDECORATIVE:
713 sFacename = wxT("WarpSans");
714 break;
715
716 case wxROMAN:
717 sFacename = wxT("Tms Rmn");
718 break;
719
720 case wxTELETYPE:
721 sFacename = wxT("Courier") ;
722 break;
723
724 case wxMODERN:
725 sFacename = wxT("System VIO") ;
726 break;
727
728 case wxSWISS:
729 sFacename = wxT("Helv") ;
730 break;
731
732 case wxDEFAULT:
733 default:
734 sFacename = wxT("System VIO") ;
735 }
736
737 if (!wxStrlen((wxChar*)fa.szFacename) )
738 {
739 SetFaceName(sFacename);
740 }
741} // end of wxNativeFontInfo::SetFamily
742
743void wxNativeFontInfo::SetEncoding( wxFontEncoding eEncoding )
744{
745 wxNativeEncodingInfo vInfo;
746
747 if ( !wxGetNativeFontEncoding( eEncoding
748 ,&vInfo
749 ))
750 {
751 if (wxFontMapper::Get()->GetAltForEncoding( eEncoding
752 ,&vInfo
753 ))
754 {
755 if (!vInfo.facename.empty())
756 {
757 //
758 // If we have this encoding only in some particular facename, use
759 // the facename - it is better to show the correct characters in a
760 // wrong facename than unreadable text in a correct one
761 //
762 SetFaceName(vInfo.facename);
763 }
764 }
765 else
766 {
767 // unsupported encoding, replace with the default
768 vInfo.charset = 850;
769 }
770 }
771 fa.usCodePage = (USHORT)vInfo.charset;
772} // end of wxNativeFontInfo::SetFaceName
773
774bool wxNativeFontInfo::FromString( const wxString& rsStr )
775{
776 long lVal;
777
778 wxStringTokenizer vTokenizer(rsStr, _T(";"));
779
780 //
781 // First the version
782 //
783 wxString sToken = vTokenizer.GetNextToken();
784
785 if (sToken != _T('0'))
786 return FALSE;
787
788 sToken = vTokenizer.GetNextToken();
789 if (!sToken.ToLong(&lVal))
790 return FALSE;
791 fm.lEmHeight = lVal;
792
793 sToken = vTokenizer.GetNextToken();
794 if (!sToken.ToLong(&lVal))
795 return FALSE;
796 fa.lAveCharWidth = lVal;
797
798 sToken = vTokenizer.GetNextToken();
799 if (!sToken.ToLong(&lVal))
800 return FALSE;
801 fa.fsSelection = (USHORT)lVal;
802
803 sToken = vTokenizer.GetNextToken();
804 if (!sToken.ToLong(&lVal))
805 return FALSE;
806 fa.fsType = (USHORT)lVal;
807
808 sToken = vTokenizer.GetNextToken();
809 if (!sToken.ToLong(&lVal))
810 return FALSE;
811 fa.fsFontUse = (USHORT)lVal;
812
813 sToken = vTokenizer.GetNextToken();
814 if (!sToken.ToLong(&lVal))
815 return FALSE;
816 fa.idRegistry = (USHORT)lVal;
817
818 sToken = vTokenizer.GetNextToken();
819 if (!sToken.ToLong(&lVal))
820 return FALSE;
821 fa.usCodePage = (USHORT)lVal;
822
823 sToken = vTokenizer.GetNextToken();
824 if (!sToken.ToLong(&lVal))
825 return FALSE;
826 fa.lMatch = lVal;
827
828 sToken = vTokenizer.GetNextToken();
829 if (!sToken.ToLong(&lVal))
830 return FALSE;
831 fn.usWeightClass = (USHORT)lVal;
832
833 sToken = vTokenizer.GetNextToken();
834 if(!sToken)
835 return FALSE;
836 wxStrcpy((wxChar*)fa.szFacename, sToken.c_str());
837 return true;
838} // end of wxNativeFontInfo::FromString
839
840wxString wxNativeFontInfo::ToString() const
841{
842 wxString sStr;
843
844 sStr.Printf(_T("%d;%ld;%ld;%ld;%d;%d;%d;%d;%d;%ld;%d;%s"),
845 0, // version, in case we want to change the format later
846 fm.lEmHeight,
847 fa.lAveCharWidth,
848 fa.lMaxBaselineExt,
849 fa.fsSelection,
850 fa.fsType,
851 fa.fsFontUse,
852 fa.idRegistry,
853 fa.usCodePage,
854 fa.lMatch,
855 fn.usWeightClass,
856 fa.szFacename);
857 return sStr;
858} // end of wxNativeFontInfo::ToString
859
860// ----------------------------------------------------------------------------
861// wxFont
862// ----------------------------------------------------------------------------
863
864void wxFont::Init()
865{
866} // end of wxFont::Init
867
868bool wxFont::Create( const wxNativeFontInfo& rInfo,
869 WXHFONT hFont )
870{
871 UnRef();
872 m_refData = new wxFontRefData( rInfo
873 ,hFont
874 );
875 RealizeResource();
876 return true;
877} // end of wxFont::Create
878
879wxFont::wxFont(
880 const wxString& rsFontdesc
881)
882{
883 wxNativeFontInfo vInfo;
884
885 if (vInfo.FromString(rsFontdesc))
886 (void)Create(vInfo);
887} // end of wxFont::wxFont
888
889// ----------------------------------------------------------------------------
890// Constructor for a font. Note that the real construction is done
891// in wxDC::SetFont, when information is available about scaling etc.
892// ----------------------------------------------------------------------------
893bool wxFont::Create( int nPointSize,
894 int nFamily,
895 int nStyle,
896 int nWeight,
897 bool bUnderlined,
898 const wxString& rsFaceName,
899 wxFontEncoding vEncoding )
900{
901 UnRef();
902
903 //
904 // wxDEFAULT is a valid value for the font size too so we must treat it
905 // specially here (otherwise the size would be 70 == wxDEFAULT value)
906 //
907 if (nPointSize == wxDEFAULT)
908 {
909 nPointSize = wxNORMAL_FONT->GetPointSize();
910 }
911 m_refData = new wxFontRefData( nPointSize
912 ,nFamily
913 ,nStyle
914 ,nWeight
915 ,bUnderlined
916 ,rsFaceName
917 ,vEncoding
918 );
919 RealizeResource();
920 return true;
921} // end of wxFont::Create
922
923wxFont::~wxFont()
924{
925} // end of wxFont::~wxFont
926
927// ----------------------------------------------------------------------------
928// real implementation
929// Boris' Kovalenko comments:
930// Because OS/2 fonts are associated with PS we can not create the font
931// here, but we may check that font definition is true
932// ----------------------------------------------------------------------------
933
934bool wxFont::RealizeResource()
935{
936 if ( GetResourceHandle() )
937 {
938 return true;
939 }
940 return M_FONTDATA->Alloc(this);
941} // end of wxFont::RealizeResource
942
943bool wxFont::FreeResource( bool WXUNUSED(bForce) )
944{
945 if (GetResourceHandle())
946 {
947 M_FONTDATA->Free();
948 return true;
949 }
950 return false;
951} // end of wxFont::FreeResource
952
953WXHANDLE wxFont::GetResourceHandle()
954{
955 return GetHFONT();
956} // end of wxFont::GetResourceHandle
957
958WXHFONT wxFont::GetHFONT() const
959{
960 return M_FONTDATA ? M_FONTDATA->GetHFONT() : 0;
961} // end of wxFont::GetHFONT
962
963bool wxFont::IsFree() const
964{
965 return M_FONTDATA && (M_FONTDATA->GetHFONT() == 0);
966} // end of wxFont::IsFree
967
968void wxFont::Unshare()
969{
970 // Don't change shared data
971 if ( !m_refData )
972 {
973 m_refData = new wxFontRefData();
974 }
975 else
976 {
977 wxFontRefData* ref = new wxFontRefData(*M_FONTDATA);
978 UnRef();
979 m_refData = ref;
980 }
981} // end of wxFont::Unshare
982
983// ----------------------------------------------------------------------------
984// change font attribute: we recreate font when doing it
985// ----------------------------------------------------------------------------
986
987void wxFont::SetPointSize(
988 int nPointSize
989)
990{
991 Unshare();
992
993 M_FONTDATA->SetPointSize(nPointSize);
994
995 RealizeResource();
996} // end of wxFont::SetPointSize
997
998void wxFont::SetFamily(
999 int nFamily
1000)
1001{
1002 Unshare();
1003
1004 M_FONTDATA->SetFamily(nFamily);
1005
1006 RealizeResource();
1007} // end of wxFont::SetFamily
1008
1009void wxFont::SetStyle(
1010 int nStyle
1011)
1012{
1013 Unshare();
1014
1015 M_FONTDATA->SetStyle(nStyle);
1016
1017 RealizeResource();
1018} // end of wxFont::SetStyle
1019
1020void wxFont::SetWeight(
1021 int nWeight
1022)
1023{
1024 Unshare();
1025
1026 M_FONTDATA->SetWeight(nWeight);
1027
1028 RealizeResource();
1029} // end of wxFont::SetWeight
1030
1031void wxFont::SetFaceName(
1032 const wxString& rsFaceName
1033)
1034{
1035 Unshare();
1036
1037 M_FONTDATA->SetFaceName(rsFaceName);
1038
1039 RealizeResource();
1040} // end of wxFont::SetFaceName
1041
1042void wxFont::SetUnderlined(
1043 bool bUnderlined
1044)
1045{
1046 Unshare();
1047
1048 M_FONTDATA->SetUnderlined(bUnderlined);
1049
1050 RealizeResource();
1051} // end of wxFont::SetUnderlined
1052
1053void wxFont::SetEncoding(
1054 wxFontEncoding vEncoding
1055)
1056{
1057 Unshare();
1058
1059 M_FONTDATA->SetEncoding(vEncoding);
1060
1061 RealizeResource();
1062} // end of wxFont::SetEncoding
1063
1064void wxFont::DoSetNativeFontInfo(
1065 const wxNativeFontInfo& rInfo
1066)
1067{
1068 Unshare();
1069
1070 FreeResource();
1071
1072 *M_FONTDATA = wxFontRefData(rInfo);
1073
1074 RealizeResource();
1075}
1076
1077// ----------------------------------------------------------------------------
1078// accessors
1079// ----------------------------------------------------------------------------
1080
1081int wxFont::GetPointSize() const
1082{
1083 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
1084
1085 return M_FONTDATA->GetPointSize();
1086} // end of wxFont::GetPointSize
1087
1088int wxFont::GetFamily() const
1089{
1090 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
1091
1092 return M_FONTDATA->GetFamily();
1093} // end of wxFont::GetFamily
1094
1095int wxFont::GetStyle() const
1096{
1097 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
1098
1099 return M_FONTDATA->GetStyle();
1100} // end of wxFont::GetStyle
1101
1102int wxFont::GetWeight() const
1103{
1104 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
1105
1106 return M_FONTDATA->GetWeight();
1107}
1108
1109bool wxFont::GetUnderlined() const
1110{
1111 wxCHECK_MSG( Ok(), FALSE, wxT("invalid font") );
1112
1113 return M_FONTDATA->GetUnderlined();
1114} // end of wxFont::GetUnderlined
1115
1116wxString wxFont::GetFaceName() const
1117{
1118 wxCHECK_MSG( Ok(), wxT(""), wxT("invalid font") );
1119
1120 return M_FONTDATA->GetFaceName();
1121} // end of wxFont::GetFaceName
1122
1123wxFontEncoding wxFont::GetEncoding() const
1124{
1125 wxCHECK_MSG( Ok(), wxFONTENCODING_DEFAULT, wxT("invalid font") );
1126
1127 return M_FONTDATA->GetEncoding();
1128} // end of wxFont::GetEncoding
1129
1130const wxNativeFontInfo* wxFont::GetNativeFontInfo() const
1131{
1132 return M_FONTDATA->HasNativeFontInfo() ? &(M_FONTDATA->GetNativeFontInfo())
1133 : NULL;
1134} // end of wxFont::GetNativeFontInfo
1135
1136//
1137// Internal use only method to set the FONTMETRICS array
1138//
1139void wxFont::SetFM(
1140 PFONTMETRICS pFM
1141, int nNumFonts
1142)
1143{
1144 M_FONTDATA->SetFM(pFM);
1145 M_FONTDATA->SetNumFonts(nNumFonts);
1146} // end of wxFont::SetFM
1147
1148
1149void wxFont::SetPS(
1150 HPS hPS
1151)
1152{
1153 Unshare();
1154
1155 M_FONTDATA->SetPS(hPS);
1156
1157 RealizeResource();
1158} // end of wxFont::SetPS