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