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