]> git.saurik.com Git - wxWidgets.git/blob - src/os2/font.cpp
Avoid do-nothing virtuals in WinCE.
[wxWidgets.git] / src / os2 / font.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/os2/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 #include "wx/font.h"
24
25 #ifndef WX_PRECOMP
26 #include <stdio.h>
27 #include "wx/list.h"
28 #include "wx/utils.h"
29 #include "wx/app.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
43 IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
44
45 // ----------------------------------------------------------------------------
46 // wxFontRefData - the internal description of the font
47 // ----------------------------------------------------------------------------
48
49 class WXDLLEXPORT wxFontRefData: public wxGDIRefData
50 {
51 public:
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 bool SetFaceName(const wxString& sFaceName)
200 {
201 if (m_bNativeFontInfoOk)
202 return m_vNativeFontInfo.SetFaceName(sFaceName);
203 else
204 m_sFaceName = sFaceName;
205 return true;
206 }
207
208 inline void SetUnderlined(bool bUnderlined)
209 {
210 if (m_bNativeFontInfoOk)
211 m_vNativeFontInfo.SetUnderlined(bUnderlined);
212 else
213 m_bUnderlined = bUnderlined;
214 }
215
216 inline void SetEncoding(wxFontEncoding vEncoding)
217 {
218 if (m_bNativeFontInfoOk)
219 m_vNativeFontInfo.SetEncoding(vEncoding);
220 else
221 m_vEncoding = vEncoding;
222 }
223
224 inline void SetPS(HPS hPS)
225 {
226 m_hPS = hPS;
227 }
228
229 inline void SetFM(PFONTMETRICS pFM)
230 {
231 m_pFM = pFM;
232 }
233
234 inline void SetNumFonts(int nNumFonts)
235 {
236 m_nNumFonts = nNumFonts;
237 }
238
239 //
240 // Native font info tests
241 //
242 bool HasNativeFontInfo() const { return m_bNativeFontInfoOk; }
243
244 const wxNativeFontInfo& GetNativeFontInfo() const
245 { return m_vNativeFontInfo; }
246
247 protected:
248 //
249 // Common part of all ctors
250 //
251 void Init( int nSize
252 ,int nFamily
253 ,int nStyle
254 ,int nWeight
255 ,bool bUnderlined
256 ,const wxString& rsFaceName
257 ,wxFontEncoding vEncoding
258 );
259
260 void Init( const wxNativeFontInfo& rInfo
261 ,WXHFONT hFont = 0
262 ,WXHANDLE hPS = 0
263 );
264 //
265 // If true, the pointer to the actual font is temporary and SHOULD NOT BE
266 // DELETED by destructor
267 //
268 bool m_bTemporary;
269 int m_nFontId;
270
271 //
272 // Font characterstics
273 //
274 int m_nPointSize;
275 int m_nFamily;
276 int m_nStyle;
277 int m_nWeight;
278 bool m_bUnderlined;
279 wxString m_sFaceName;
280 wxFontEncoding m_vEncoding;
281 WXHFONT m_hFont;
282
283 //
284 // Native font info
285 //
286 wxNativeFontInfo m_vNativeFontInfo;
287 bool m_bNativeFontInfoOk;
288
289 //
290 // Some PM specific stuff
291 //
292 PFONTMETRICS m_pFM; // array of FONTMETRICS structs
293 int m_nNumFonts; // number of fonts in array
294 HPS m_hPS; // PS handle this font belongs to
295 FATTRS m_vFattrs; // Current fattrs struct
296 FACENAMEDESC m_vFname; // Current facename struct
297 bool m_bInternalPS; // Internally generated PS?
298 }; // end of CLASS wxFontRefData
299
300 #define M_FONTDATA ((wxFontRefData*)m_refData)
301
302 // ============================================================================
303 // implementation
304 // ============================================================================
305
306 // ----------------------------------------------------------------------------
307 // wxFontRefData
308 // ----------------------------------------------------------------------------
309
310 void wxFontRefData::Init(
311 int nPointSize
312 , int nFamily
313 , int nStyle
314 , int nWeight
315 , bool bUnderlined
316 , const wxString& rsFaceName
317 , wxFontEncoding vEncoding
318 )
319 {
320 m_nStyle = nStyle;
321 m_nPointSize = nPointSize;
322 m_nFamily = nFamily;
323 m_nStyle = nStyle;
324 m_nWeight = nWeight;
325 m_bUnderlined = bUnderlined;
326 m_sFaceName = rsFaceName;
327 m_vEncoding = vEncoding;
328 m_hFont = 0;
329
330 m_bNativeFontInfoOk = false;
331
332 m_nFontId = 0;
333 m_bTemporary = false;
334 m_pFM = (PFONTMETRICS)NULL;
335 m_hPS = NULLHANDLE;
336 m_nNumFonts = 0;
337 } // end of wxFontRefData::Init
338
339 void wxFontRefData::Init(
340 const wxNativeFontInfo& rInfo
341 , WXHFONT hFont //this is the FontId -- functions as the hFont for OS/2
342 , WXHANDLE hPS // Presentation Space we are using
343 )
344 {
345 //
346 // hFont may be zero, or it be passed in case we really want to
347 // use the exact font created in the underlying system
348 // (for example where we can't guarantee conversion from HFONT
349 // to LOGFONT back to HFONT)
350 //
351 m_hFont = hFont;
352 m_nFontId = (int)hFont;
353
354 m_bNativeFontInfoOk = true;
355 m_vNativeFontInfo = rInfo;
356
357 if (hPS == NULLHANDLE)
358 {
359 m_hPS = ::WinGetPS(HWND_DESKTOP);
360 m_bInternalPS = true;
361 }
362 else
363 m_hPS = (HPS)hPS;
364
365 m_nFontId = 0;
366 m_bTemporary = false;
367 m_pFM = (PFONTMETRICS)NULL;
368 m_nNumFonts = 0;
369 } // end of wxFontRefData::Init
370
371 wxFontRefData::~wxFontRefData()
372 {
373 Free();
374 }
375
376 bool wxFontRefData::Alloc( wxFont* pFont )
377 {
378 wxString sFaceName;
379 long flId = m_hFont;
380 long lRc;
381 ERRORID vError;
382 wxString sError;
383
384 if (!m_bNativeFontInfoOk)
385 {
386 wxFillLogFont( &m_vNativeFontInfo.fa
387 ,&m_vNativeFontInfo.fn
388 ,&m_hPS
389 ,&m_bInternalPS
390 ,&flId
391 ,sFaceName
392 ,pFont
393 );
394 m_bNativeFontInfoOk = true;
395 }
396 else
397 {
398 if (flId == 0L)
399 flId = 1L;
400 else
401 flId++;
402 if (flId > 254)
403 flId = 1L;
404 }
405 if((lRc = ::GpiCreateLogFont( m_hPS
406 ,NULL
407 ,flId
408 ,&m_vNativeFontInfo.fa
409 )) != GPI_ERROR)
410 {
411 m_hFont = (WXHFONT)flId;
412 m_nFontId = flId;
413 }
414 if (!m_hFont)
415 {
416 vError = ::WinGetLastError(vHabmain);
417 sError = wxPMErrorToStr(vError);
418 wxLogLastError(wxT("CreateFont"));
419 }
420
421 ::GpiSetCharSet(m_hPS, flId); // sets font for presentation space
422 ::GpiQueryFontMetrics(m_hPS, sizeof(FONTMETRICS), &m_vNativeFontInfo.fm);
423
424 //
425 // Set refData members with the results
426 //
427 memcpy(&m_vFattrs, &m_vNativeFontInfo.fa, sizeof(m_vFattrs));
428 memcpy(&m_vFname, &m_vNativeFontInfo.fn, sizeof(m_vFname));
429 //
430 // Going to leave the point size alone. Mostly we use outline fonts
431 // that can be set to any point size inside of Presentation Parameters,
432 // regardless of whether or not the actual font is registered in the system.
433 // The GpiCreateLogFont will do enough by selecting the right family,
434 // and face name.
435 //
436 if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Times New Roman") == 0)
437 m_nFamily = wxROMAN;
438 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Times New Roman MT 30") == 0)
439 m_nFamily = wxROMAN;
440 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "@Times New Roman MT 30") == 0)
441 m_nFamily = wxROMAN;
442 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Tms Rmn") == 0)
443 m_nFamily = wxROMAN;
444 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "WarpSans") == 0)
445 m_nFamily = wxDECORATIVE;
446 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Helvetica") == 0)
447 m_nFamily = wxSWISS;
448 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Helv") == 0)
449 m_nFamily = wxSWISS;
450 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Script") == 0)
451 m_nFamily = wxSCRIPT;
452 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Courier New") == 0)
453 m_nFamily = wxTELETYPE;
454 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Courier") == 0)
455 m_nFamily = wxTELETYPE;
456 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "System Monospaced") == 0)
457 m_nFamily = wxTELETYPE;
458 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "System VIO") == 0)
459 m_nFamily = wxMODERN;
460 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "System Proportional") == 0)
461 m_nFamily = wxMODERN;
462 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Arial") == 0)
463 m_nFamily = wxSWISS;
464 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Swiss") == 0)
465 m_nFamily = wxSWISS;
466 else
467 m_nFamily = wxSWISS;
468
469 if (m_vNativeFontInfo.fa.fsSelection & FATTR_SEL_ITALIC)
470 m_nStyle = wxFONTSTYLE_ITALIC;
471 else
472 m_nStyle = wxFONTSTYLE_NORMAL;
473 switch(m_vNativeFontInfo.fn.usWeightClass)
474 {
475 case FWEIGHT_DONT_CARE:
476 m_nWeight = wxFONTWEIGHT_NORMAL;
477 break;
478
479 case FWEIGHT_NORMAL:
480 m_nWeight = wxFONTWEIGHT_NORMAL;
481 break;
482
483 case FWEIGHT_LIGHT:
484 m_nWeight = wxFONTWEIGHT_LIGHT;
485 break;
486
487 case FWEIGHT_BOLD:
488 m_nWeight = wxFONTWEIGHT_BOLD;
489 break;
490
491 case FWEIGHT_ULTRA_BOLD:
492 m_nWeight = wxFONTWEIGHT_MAX;
493 break;
494
495 default:
496 m_nWeight = wxFONTWEIGHT_NORMAL;
497 }
498 m_bUnderlined = ((m_vNativeFontInfo.fa.fsSelection & FATTR_SEL_UNDERSCORE) != 0);
499 m_sFaceName = (wxChar*)m_vNativeFontInfo.fa.szFacename;
500 m_vEncoding = wxGetFontEncFromCharSet(m_vNativeFontInfo.fa.usCodePage);
501
502 //
503 // We don't actuall keep the font around if using a temporary PS
504 //
505 if (m_bInternalPS)
506 {
507 if(m_hFont)
508 ::GpiDeleteSetId( m_hPS
509 ,flId
510 );
511
512 ::WinReleasePS(m_hPS);
513 }
514 else
515 //
516 // Select the font into the Presentation space
517 //
518 ::GpiSetCharSet(m_hPS, flId); // sets font for presentation space
519 return true;
520 } // end of wxFontRefData::Alloc
521
522 void wxFontRefData::Free()
523 {
524 if (m_pFM)
525 delete [] m_pFM;
526 m_pFM = (PFONTMETRICS)NULL;
527
528 if ( m_hFont )
529 {
530 ::GpiDeleteSetId(m_hPS, 1L); /* delete the logical font */
531 m_nFontId = 0;
532 m_hFont = 0;
533 }
534 if (m_bInternalPS)
535 ::WinReleasePS(m_hPS);
536 m_hPS = NULLHANDLE;
537 } // end of wxFontRefData::Free
538
539 // ----------------------------------------------------------------------------
540 // wxNativeFontInfo
541 // ----------------------------------------------------------------------------
542
543 void wxNativeFontInfo::Init()
544 {
545 memset(&fa, '\0', sizeof(FATTRS));
546 } // end of wxNativeFontInfo::Init
547
548 int wxNativeFontInfo::GetPointSize() const
549 {
550 return fm.lEmHeight;
551 } // end of wxNativeFontInfo::GetPointSize
552
553 wxFontStyle wxNativeFontInfo::GetStyle() const
554 {
555 return fa.fsSelection & FATTR_SEL_ITALIC ? wxFONTSTYLE_ITALIC : wxFONTSTYLE_NORMAL;
556 } // end of wxNativeFontInfo::GetStyle
557
558 wxFontWeight wxNativeFontInfo::GetWeight() const
559 {
560 switch(fn.usWeightClass)
561 {
562 case FWEIGHT_DONT_CARE:
563 return wxFONTWEIGHT_NORMAL;
564
565 case FWEIGHT_NORMAL:
566 return wxFONTWEIGHT_NORMAL;
567
568 case FWEIGHT_LIGHT:
569 return wxFONTWEIGHT_LIGHT;
570
571 case FWEIGHT_BOLD:
572 return wxFONTWEIGHT_BOLD;
573
574 case FWEIGHT_ULTRA_BOLD:
575 return wxFONTWEIGHT_MAX;
576 }
577 return wxFONTWEIGHT_NORMAL;
578 } // end of wxNativeFontInfo::GetWeight
579
580 bool wxNativeFontInfo::GetUnderlined() const
581 {
582 return ((fa.fsSelection & FATTR_SEL_UNDERSCORE) != 0);
583 } // end of wxNativeFontInfo::GetUnderlined
584
585 wxString wxNativeFontInfo::GetFaceName() const
586 {
587 return (wxChar*)fm.szFacename;
588 } // end of wxNativeFontInfo::GetFaceName
589
590 wxFontFamily wxNativeFontInfo::GetFamily() const
591 {
592 int nFamily;
593
594 //
595 // Extract family from facename
596 //
597 if (strcmp(fm.szFamilyname, "Times New Roman") == 0)
598 nFamily = wxROMAN;
599 else if (strcmp(fm.szFamilyname, "Times New Roman MT 30") == 0)
600 nFamily = wxROMAN;
601 else if (strcmp(fm.szFamilyname, "@Times New Roman MT 30") == 0)
602 nFamily = wxROMAN;
603 else if (strcmp(fm.szFamilyname, "Tms Rmn") == 0)
604 nFamily = wxROMAN;
605 else if (strcmp(fm.szFamilyname, "WarpSans") == 0)
606 nFamily = wxDECORATIVE;
607 else if (strcmp(fm.szFamilyname, "Helvetica") == 0)
608 nFamily = wxSWISS;
609 else if (strcmp(fm.szFamilyname, "Helv") == 0)
610 nFamily = wxSWISS;
611 else if (strcmp(fm.szFamilyname, "Script") == 0)
612 nFamily = wxSCRIPT;
613 else if (strcmp(fm.szFamilyname, "Courier New") == 0)
614 nFamily = wxTELETYPE;
615 else if (strcmp(fm.szFamilyname, "Courier") == 0)
616 nFamily = wxTELETYPE;
617 else if (strcmp(fm.szFamilyname, "System Monospaced") == 0)
618 nFamily = wxTELETYPE;
619 else if (strcmp(fm.szFamilyname, "System VIO") == 0)
620 nFamily = wxMODERN;
621 else if (strcmp(fm.szFamilyname, "System Proportional") == 0)
622 nFamily = wxMODERN;
623 else if (strcmp(fm.szFamilyname, "Arial") == 0)
624 nFamily = wxSWISS;
625 else if (strcmp(fm.szFamilyname, "Swiss") == 0)
626 nFamily = wxSWISS;
627 else
628 nFamily = wxSWISS;
629 return (wxFontFamily)nFamily;
630 } // end of wxNativeFontInfo::GetFamily
631
632 wxFontEncoding wxNativeFontInfo::GetEncoding() const
633 {
634 return wxGetFontEncFromCharSet(fa.usCodePage);
635 } // end of wxNativeFontInfo::GetEncoding
636
637 void wxNativeFontInfo::SetPointSize(
638 int nPointsize
639 )
640 {
641 fm.lEmHeight = (LONG)nPointsize;
642 } // end of wxNativeFontInfo::SetPointSize
643
644 void wxNativeFontInfo::SetStyle(
645 wxFontStyle eStyle
646 )
647 {
648 switch (eStyle)
649 {
650 default:
651 wxFAIL_MSG( _T("unknown font style") );
652 // fall through
653
654 case wxFONTSTYLE_NORMAL:
655 break;
656
657 case wxFONTSTYLE_ITALIC:
658 case wxFONTSTYLE_SLANT:
659 fa.fsSelection |= FATTR_SEL_ITALIC;
660 break;
661 }
662 } // end of wxNativeFontInfo::SetStyle
663
664 void wxNativeFontInfo::SetWeight(
665 wxFontWeight eWeight
666 )
667 {
668 switch (eWeight)
669 {
670 default:
671 wxFAIL_MSG( _T("unknown font weight") );
672 // fall through
673
674 case wxFONTWEIGHT_NORMAL:
675 fn.usWeightClass = FWEIGHT_NORMAL;
676 break;
677
678 case wxFONTWEIGHT_LIGHT:
679 fn.usWeightClass = FWEIGHT_LIGHT;
680 break;
681
682 case wxFONTWEIGHT_BOLD:
683 fn.usWeightClass = FWEIGHT_BOLD;
684 break;
685 }
686 } // end of wxNativeFontInfo::SetWeight
687
688 void wxNativeFontInfo::SetUnderlined(
689 bool bUnderlined
690 )
691 {
692 if(bUnderlined)
693 fa.fsSelection |= FATTR_SEL_UNDERSCORE;
694 } // end of wxNativeFontInfo::SetUnderlined
695
696 bool wxNativeFontInfo::SetFaceName(
697 const wxString& sFacename
698 )
699 {
700 wxStrncpy((wxChar*)fa.szFacename, sFacename, WXSIZEOF(fa.szFacename));
701 return true;
702 } // end of wxNativeFontInfo::SetFaceName
703
704 void wxNativeFontInfo::SetFamily(
705 wxFontFamily eFamily
706 )
707 {
708 wxString sFacename;
709
710 switch (eFamily)
711 {
712 case wxSCRIPT:
713 sFacename = wxT("Tms Rmn");
714 break;
715
716 case wxDECORATIVE:
717 sFacename = wxT("WarpSans");
718 break;
719
720 case wxROMAN:
721 sFacename = wxT("Tms Rmn");
722 break;
723
724 case wxTELETYPE:
725 sFacename = wxT("Courier") ;
726 break;
727
728 case wxMODERN:
729 sFacename = wxT("System VIO") ;
730 break;
731
732 case wxSWISS:
733 sFacename = wxT("Helv") ;
734 break;
735
736 case wxDEFAULT:
737 default:
738 sFacename = wxT("System VIO") ;
739 }
740
741 if (!wxStrlen((wxChar*)fa.szFacename) )
742 {
743 SetFaceName(sFacename);
744 }
745 } // end of wxNativeFontInfo::SetFamily
746
747 void wxNativeFontInfo::SetEncoding( wxFontEncoding eEncoding )
748 {
749 wxNativeEncodingInfo vInfo;
750
751 if ( !wxGetNativeFontEncoding( eEncoding
752 ,&vInfo
753 ))
754 {
755 if (wxFontMapper::Get()->GetAltForEncoding( eEncoding
756 ,&vInfo
757 ))
758 {
759 if (!vInfo.facename.empty())
760 {
761 //
762 // If we have this encoding only in some particular facename, use
763 // the facename - it is better to show the correct characters in a
764 // wrong facename than unreadable text in a correct one
765 //
766 SetFaceName(vInfo.facename);
767 }
768 }
769 else
770 {
771 // unsupported encoding, replace with the default
772 vInfo.charset = 850;
773 }
774 }
775 fa.usCodePage = (USHORT)vInfo.charset;
776 } // end of wxNativeFontInfo::SetFaceName
777
778 bool wxNativeFontInfo::FromString( const wxString& rsStr )
779 {
780 long lVal;
781
782 wxStringTokenizer vTokenizer(rsStr, _T(";"));
783
784 //
785 // First the version
786 //
787 wxString sToken = vTokenizer.GetNextToken();
788
789 if (sToken != _T('0'))
790 return false;
791
792 sToken = vTokenizer.GetNextToken();
793 if (!sToken.ToLong(&lVal))
794 return false;
795 fm.lEmHeight = lVal;
796
797 sToken = vTokenizer.GetNextToken();
798 if (!sToken.ToLong(&lVal))
799 return false;
800 fa.lAveCharWidth = lVal;
801
802 sToken = vTokenizer.GetNextToken();
803 if (!sToken.ToLong(&lVal))
804 return false;
805 fa.fsSelection = (USHORT)lVal;
806
807 sToken = vTokenizer.GetNextToken();
808 if (!sToken.ToLong(&lVal))
809 return false;
810 fa.fsType = (USHORT)lVal;
811
812 sToken = vTokenizer.GetNextToken();
813 if (!sToken.ToLong(&lVal))
814 return false;
815 fa.fsFontUse = (USHORT)lVal;
816
817 sToken = vTokenizer.GetNextToken();
818 if (!sToken.ToLong(&lVal))
819 return false;
820 fa.idRegistry = (USHORT)lVal;
821
822 sToken = vTokenizer.GetNextToken();
823 if (!sToken.ToLong(&lVal))
824 return false;
825 fa.usCodePage = (USHORT)lVal;
826
827 sToken = vTokenizer.GetNextToken();
828 if (!sToken.ToLong(&lVal))
829 return false;
830 fa.lMatch = lVal;
831
832 sToken = vTokenizer.GetNextToken();
833 if (!sToken.ToLong(&lVal))
834 return false;
835 fn.usWeightClass = (USHORT)lVal;
836
837 sToken = vTokenizer.GetNextToken();
838 if(!sToken)
839 return false;
840 wxStrcpy((wxChar*)fa.szFacename, sToken.c_str());
841 return true;
842 } // end of wxNativeFontInfo::FromString
843
844 wxString wxNativeFontInfo::ToString() const
845 {
846 wxString sStr;
847
848 sStr.Printf(_T("%d;%ld;%ld;%ld;%d;%d;%d;%d;%d;%ld;%d;%s"),
849 0, // version, in case we want to change the format later
850 fm.lEmHeight,
851 fa.lAveCharWidth,
852 fa.lMaxBaselineExt,
853 fa.fsSelection,
854 fa.fsType,
855 fa.fsFontUse,
856 fa.idRegistry,
857 fa.usCodePage,
858 fa.lMatch,
859 fn.usWeightClass,
860 fa.szFacename);
861 return sStr;
862 } // end of wxNativeFontInfo::ToString
863
864 // ----------------------------------------------------------------------------
865 // wxFont
866 // ----------------------------------------------------------------------------
867
868 bool 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
879 wxFont::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 // ----------------------------------------------------------------------------
893 bool 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
923 wxFont::~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
934 bool wxFont::RealizeResource()
935 {
936 if ( GetResourceHandle() )
937 {
938 return true;
939 }
940 return M_FONTDATA->Alloc(this);
941 } // end of wxFont::RealizeResource
942
943 bool 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
953 WXHANDLE wxFont::GetResourceHandle() const
954 {
955 return GetHFONT();
956 } // end of wxFont::GetResourceHandle
957
958 WXHFONT wxFont::GetHFONT() const
959 {
960 return M_FONTDATA ? M_FONTDATA->GetHFONT() : 0;
961 } // end of wxFont::GetHFONT
962
963 bool wxFont::IsFree() const
964 {
965 return M_FONTDATA && (M_FONTDATA->GetHFONT() == 0);
966 } // end of wxFont::IsFree
967
968 void 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
987 void wxFont::SetPointSize(
988 int nPointSize
989 )
990 {
991 Unshare();
992
993 M_FONTDATA->SetPointSize(nPointSize);
994
995 RealizeResource();
996 } // end of wxFont::SetPointSize
997
998 void wxFont::SetFamily(
999 int nFamily
1000 )
1001 {
1002 Unshare();
1003
1004 M_FONTDATA->SetFamily(nFamily);
1005
1006 RealizeResource();
1007 } // end of wxFont::SetFamily
1008
1009 void wxFont::SetStyle(
1010 int nStyle
1011 )
1012 {
1013 Unshare();
1014
1015 M_FONTDATA->SetStyle(nStyle);
1016
1017 RealizeResource();
1018 } // end of wxFont::SetStyle
1019
1020 void wxFont::SetWeight(
1021 int nWeight
1022 )
1023 {
1024 Unshare();
1025
1026 M_FONTDATA->SetWeight(nWeight);
1027
1028 RealizeResource();
1029 } // end of wxFont::SetWeight
1030
1031 bool wxFont::SetFaceName(
1032 const wxString& rsFaceName
1033 )
1034 {
1035 Unshare();
1036
1037 bool refdataok = M_FONTDATA->SetFaceName(rsFaceName);
1038
1039 RealizeResource();
1040
1041 return refdataok && wxFontBase::SetFaceName(rsFaceName);
1042 } // end of wxFont::SetFaceName
1043
1044 void wxFont::SetUnderlined(
1045 bool bUnderlined
1046 )
1047 {
1048 Unshare();
1049
1050 M_FONTDATA->SetUnderlined(bUnderlined);
1051
1052 RealizeResource();
1053 } // end of wxFont::SetUnderlined
1054
1055 void wxFont::SetEncoding(
1056 wxFontEncoding vEncoding
1057 )
1058 {
1059 Unshare();
1060
1061 M_FONTDATA->SetEncoding(vEncoding);
1062
1063 RealizeResource();
1064 } // end of wxFont::SetEncoding
1065
1066 void wxFont::DoSetNativeFontInfo(
1067 const wxNativeFontInfo& rInfo
1068 )
1069 {
1070 Unshare();
1071
1072 FreeResource();
1073
1074 *M_FONTDATA = wxFontRefData(rInfo);
1075
1076 RealizeResource();
1077 }
1078
1079 // ----------------------------------------------------------------------------
1080 // accessors
1081 // ----------------------------------------------------------------------------
1082
1083 int wxFont::GetPointSize() const
1084 {
1085 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
1086
1087 return M_FONTDATA->GetPointSize();
1088 } // end of wxFont::GetPointSize
1089
1090 int wxFont::GetFamily() const
1091 {
1092 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
1093
1094 return M_FONTDATA->GetFamily();
1095 } // end of wxFont::GetFamily
1096
1097 int wxFont::GetStyle() const
1098 {
1099 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
1100
1101 return M_FONTDATA->GetStyle();
1102 } // end of wxFont::GetStyle
1103
1104 int wxFont::GetWeight() const
1105 {
1106 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
1107
1108 return M_FONTDATA->GetWeight();
1109 }
1110
1111 bool wxFont::GetUnderlined() const
1112 {
1113 wxCHECK_MSG( Ok(), false, wxT("invalid font") );
1114
1115 return M_FONTDATA->GetUnderlined();
1116 } // end of wxFont::GetUnderlined
1117
1118 wxString wxFont::GetFaceName() const
1119 {
1120 wxCHECK_MSG( Ok(), wxEmptyString, wxT("invalid font") );
1121
1122 return M_FONTDATA->GetFaceName();
1123 } // end of wxFont::GetFaceName
1124
1125 wxFontEncoding wxFont::GetEncoding() const
1126 {
1127 wxCHECK_MSG( Ok(), wxFONTENCODING_DEFAULT, wxT("invalid font") );
1128
1129 return M_FONTDATA->GetEncoding();
1130 } // end of wxFont::GetEncoding
1131
1132 const wxNativeFontInfo* wxFont::GetNativeFontInfo() const
1133 {
1134 return M_FONTDATA->HasNativeFontInfo() ? &(M_FONTDATA->GetNativeFontInfo())
1135 : NULL;
1136 } // end of wxFont::GetNativeFontInfo
1137
1138 //
1139 // Internal use only method to set the FONTMETRICS array
1140 //
1141 void wxFont::SetFM( PFONTMETRICS pFM, int nNumFonts )
1142 {
1143 M_FONTDATA->SetFM(pFM);
1144 M_FONTDATA->SetNumFonts(nNumFonts);
1145 } // end of wxFont::SetFM
1146
1147
1148 void wxFont::SetPS( HPS hPS )
1149 {
1150 Unshare();
1151
1152 M_FONTDATA->SetPS(hPS);
1153
1154 RealizeResource();
1155 } // end of wxFont::SetPS