]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/os2/font.cpp
Fix the off-by-one a little differently, and correct a refresh problem
[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// ============================================================================
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 #include "wx/log.h"
32#endif // WX_PRECOMP
33
34#include "wx/os2/private.h"
35
36#include "wx/fontutil.h"
37#include "wx/fontmap.h"
38#include "wx/encinfo.h"
39
40#include "wx/tokenzr.h"
41
42IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
43
44// ----------------------------------------------------------------------------
45// wxFontRefData - the internal description of the font
46// ----------------------------------------------------------------------------
47
48class WXDLLEXPORT wxFontRefData: public wxGDIRefData
49{
50public:
51 wxFontRefData()
52 {
53 Init(-1, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, FALSE,
54 "", 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
245protected:
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
306void 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
335void 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
367wxFontRefData::~wxFontRefData()
368{
369 Free();
370}
371
372bool wxFontRefData::Alloc(
373 wxFont* pFont
374)
375{
376 wxString sFaceName;
377 long flId = m_hFont;
378 long lRc;
379 short nIndex = 0;
380 PFONTMETRICS pFM = NULL;
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("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 = 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
522void 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
543void wxNativeFontInfo::Init()
544{
545 memset(&fa, '\0', sizeof(FATTRS));
546} // end of wxNativeFontInfo::Init
547
548int wxNativeFontInfo::GetPointSize() const
549{
550 return fm.lEmHeight;
551} // end of wxNativeFontInfo::GetPointSize
552
553wxFontStyle wxNativeFontInfo::GetStyle() const
554{
555 return fa.fsSelection & FATTR_SEL_ITALIC ? wxFONTSTYLE_ITALIC : wxFONTSTYLE_NORMAL;
556} // end of wxNativeFontInfo::GetStyle
557
558wxFontWeight 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
580bool wxNativeFontInfo::GetUnderlined() const
581{
582 return ((fa.fsSelection & FATTR_SEL_UNDERSCORE) != 0);
583} // end of wxNativeFontInfo::GetUnderlined
584
585wxString wxNativeFontInfo::GetFaceName() const
586{
587 return fm.szFacename;
588} // end of wxNativeFontInfo::GetFaceName
589
590wxFontFamily 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
632wxFontEncoding wxNativeFontInfo::GetEncoding() const
633{
634 return wxGetFontEncFromCharSet(fa.usCodePage);
635} // end of wxNativeFontInfo::GetEncoding
636
637void wxNativeFontInfo::SetPointSize(
638 int nPointsize
639)
640{
641 fm.lEmHeight = (LONG)nPointsize;
642} // end of wxNativeFontInfo::SetPointSize
643
644void 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
664void 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
688void wxNativeFontInfo::SetUnderlined(
689 bool bUnderlined
690)
691{
692 if(bUnderlined)
693 fa.fsSelection |= FATTR_SEL_UNDERSCORE;
694} // end of wxNativeFontInfo::SetUnderlined
695
696void wxNativeFontInfo::SetFaceName(
697 wxString sFacename
698)
699{
700 wxStrncpy(fa.szFacename, sFacename, WXSIZEOF(fa.szFacename));
701} // end of wxNativeFontInfo::SetFaceName
702
703void wxNativeFontInfo::SetFamily(
704 wxFontFamily eFamily
705)
706{
707 wxString sFacename;
708
709 switch (eFamily)
710 {
711 case wxSCRIPT:
712 sFacename = wxT("Tms Rmn");
713 break;
714
715 case wxDECORATIVE:
716 sFacename = wxT("WarpSans");
717 break;
718
719 case wxROMAN:
720 sFacename = wxT("Tms Rmn");
721 break;
722
723 case wxTELETYPE:
724 sFacename = wxT("Courier") ;
725 break;
726
727 case wxMODERN:
728 sFacename = wxT("System VIO") ;
729 break;
730
731 case wxSWISS:
732 sFacename = wxT("Helv") ;
733 break;
734
735 case wxDEFAULT:
736 default:
737 sFacename = wxT("System VIO") ;
738 }
739
740 if (!wxStrlen(fa.szFacename) )
741 {
742 SetFaceName(sFacename);
743 }
744} // end of wxNativeFontInfo::SetFamily
745
746void wxNativeFontInfo::SetEncoding(
747 wxFontEncoding eEncoding
748)
749{
750 wxNativeEncodingInfo vInfo;
751
752 if ( !wxGetNativeFontEncoding( eEncoding
753 ,&vInfo
754 ))
755 {
756 if (wxFontMapper::Get()->GetAltForEncoding( eEncoding
757 ,&vInfo
758 ))
759 {
760 if (!vInfo.facename.empty())
761 {
762 //
763 // If we have this encoding only in some particular facename, use
764 // the facename - it is better to show the correct characters in a
765 // wrong facename than unreadable text in a correct one
766 //
767 SetFaceName(vInfo.facename);
768 }
769 }
770 else
771 {
772 // unsupported encoding, replace with the default
773 vInfo.charset = 850;
774 }
775 }
776 fa.usCodePage = vInfo.charset;
777} // end of wxNativeFontInfo::SetFaceName
778
779bool wxNativeFontInfo::FromString(
780 const wxString& rsStr
781)
782{
783 long lVal;
784
785 wxStringTokenizer vTokenizer(rsStr, _T(";"));
786
787 //
788 // First the version
789 //
790 wxString sToken = vTokenizer.GetNextToken();
791
792 if (sToken != _T('0'))
793 return FALSE;
794
795 sToken = vTokenizer.GetNextToken();
796 if (!sToken.ToLong(&lVal))
797 return FALSE;
798 fm.lEmHeight = lVal;
799
800 sToken = vTokenizer.GetNextToken();
801 if (!sToken.ToLong(&lVal))
802 return FALSE;
803 fa.lAveCharWidth = lVal;
804
805 sToken = vTokenizer.GetNextToken();
806 if (!sToken.ToLong(&lVal))
807 return FALSE;
808 fa.fsSelection = (USHORT)lVal;
809
810 sToken = vTokenizer.GetNextToken();
811 if (!sToken.ToLong(&lVal))
812 return FALSE;
813 fa.fsType = (USHORT)lVal;
814
815 sToken = vTokenizer.GetNextToken();
816 if (!sToken.ToLong(&lVal))
817 return FALSE;
818 fa.fsFontUse = (USHORT)lVal;
819
820 sToken = vTokenizer.GetNextToken();
821 if (!sToken.ToLong(&lVal))
822 return FALSE;
823 fa.idRegistry = (USHORT)lVal;
824
825 sToken = vTokenizer.GetNextToken();
826 if (!sToken.ToLong(&lVal))
827 return FALSE;
828 fa.usCodePage = (USHORT)lVal;
829
830 sToken = vTokenizer.GetNextToken();
831 if (!sToken.ToLong(&lVal))
832 return FALSE;
833 fa.lMatch = lVal;
834
835 sToken = vTokenizer.GetNextToken();
836 if (!sToken.ToLong(&lVal))
837 return FALSE;
838 fn.usWeightClass = (USHORT)lVal;
839
840 sToken = vTokenizer.GetNextToken();
841 if(!sToken)
842 return FALSE;
843 wxStrcpy(fa.szFacename, sToken.c_str());
844 return TRUE;
845} // end of wxNativeFontInfo::FromString
846
847wxString wxNativeFontInfo::ToString() const
848{
849 wxString sStr;
850
851 sStr.Printf(_T("%d;%ld;%ld;%ld;%d;%d;%d;%d;%d;%ld;%d;%s"),
852 0, // version, in case we want to change the format later
853 fm.lEmHeight,
854 fa.lAveCharWidth,
855 fa.lMaxBaselineExt,
856 fa.fsSelection,
857 fa.fsType,
858 fa.fsFontUse,
859 fa.idRegistry,
860 fa.usCodePage,
861 fa.lMatch,
862 fn.usWeightClass,
863 fa.szFacename);
864 return sStr;
865} // end of wxNativeFontInfo::ToString
866
867// ----------------------------------------------------------------------------
868// wxFont
869// ----------------------------------------------------------------------------
870
871void wxFont::Init()
872{
873} // end of wxFont::Init
874
875bool wxFont::Create(
876 const wxNativeFontInfo& rInfo
877, WXHFONT hFont
878)
879{
880 UnRef();
881 m_refData = new wxFontRefData( rInfo
882 ,hFont
883 );
884 RealizeResource();
885 return TRUE;
886} // end of wxFont::Create
887
888wxFont::wxFont(
889 const wxString& rsFontdesc
890)
891{
892 wxNativeFontInfo vInfo;
893
894 if (vInfo.FromString(rsFontdesc))
895 (void)Create(vInfo);
896} // end of wxFont::wxFont
897
898// ----------------------------------------------------------------------------
899// Constructor for a font. Note that the real construction is done
900// in wxDC::SetFont, when information is available about scaling etc.
901// ----------------------------------------------------------------------------
902bool wxFont::Create(
903 int nPointSize
904, int nFamily
905, int nStyle
906, int nWeight
907, bool bUnderlined
908, const wxString& rsFaceName
909, wxFontEncoding vEncoding
910)
911{
912 UnRef();
913
914 //
915 // wxDEFAULT is a valid value for the font size too so we must treat it
916 // specially here (otherwise the size would be 70 == wxDEFAULT value)
917 //
918 if (nPointSize == wxDEFAULT)
919 {
920 nPointSize = wxNORMAL_FONT->GetPointSize();
921 }
922 m_refData = new wxFontRefData( nPointSize
923 ,nFamily
924 ,nStyle
925 ,nWeight
926 ,bUnderlined
927 ,rsFaceName
928 ,vEncoding
929 );
930 RealizeResource();
931 return TRUE;
932} // end of wxFont::Create
933
934wxFont::~wxFont()
935{
936} // end of wxFont::~wxFont
937
938// ----------------------------------------------------------------------------
939// real implementation
940// Boris' Kovalenko comments:
941// Because OS/2 fonts are associated with PS we can not create the font
942// here, but we may check that font definition is true
943// ----------------------------------------------------------------------------
944
945bool wxFont::RealizeResource()
946{
947 if ( GetResourceHandle() )
948 {
949 return TRUE;
950 }
951 return M_FONTDATA->Alloc(this);
952} // end of wxFont::RealizeResource
953
954bool wxFont::FreeResource(
955 bool bForce
956)
957{
958 if (GetResourceHandle())
959 {
960 M_FONTDATA->Free();
961 return TRUE;
962 }
963 return FALSE;
964} // end of wxFont::FreeResource
965
966WXHANDLE wxFont::GetResourceHandle()
967{
968 return GetHFONT();
969} // end of wxFont::GetResourceHandle
970
971WXHFONT wxFont::GetHFONT() const
972{
973 return M_FONTDATA ? M_FONTDATA->GetHFONT() : 0;
974} // end of wxFont::GetHFONT
975
976bool wxFont::IsFree() const
977{
978 return M_FONTDATA && (M_FONTDATA->GetHFONT() == 0);
979} // end of wxFont::IsFree
980
981void wxFont::Unshare()
982{
983 // Don't change shared data
984 if ( !m_refData )
985 {
986 m_refData = new wxFontRefData();
987 }
988 else
989 {
990 wxFontRefData* ref = new wxFontRefData(*M_FONTDATA);
991 UnRef();
992 m_refData = ref;
993 }
994} // end of wxFont::Unshare
995
996// ----------------------------------------------------------------------------
997// change font attribute: we recreate font when doing it
998// ----------------------------------------------------------------------------
999
1000void wxFont::SetPointSize(
1001 int nPointSize
1002)
1003{
1004 Unshare();
1005
1006 M_FONTDATA->SetPointSize(nPointSize);
1007
1008 RealizeResource();
1009} // end of wxFont::SetPointSize
1010
1011void wxFont::SetFamily(
1012 int nFamily
1013)
1014{
1015 Unshare();
1016
1017 M_FONTDATA->SetFamily(nFamily);
1018
1019 RealizeResource();
1020} // end of wxFont::SetFamily
1021
1022void wxFont::SetStyle(
1023 int nStyle
1024)
1025{
1026 Unshare();
1027
1028 M_FONTDATA->SetStyle(nStyle);
1029
1030 RealizeResource();
1031} // end of wxFont::SetStyle
1032
1033void wxFont::SetWeight(
1034 int nWeight
1035)
1036{
1037 Unshare();
1038
1039 M_FONTDATA->SetWeight(nWeight);
1040
1041 RealizeResource();
1042} // end of wxFont::SetWeight
1043
1044void wxFont::SetFaceName(
1045 const wxString& rsFaceName
1046)
1047{
1048 Unshare();
1049
1050 M_FONTDATA->SetFaceName(rsFaceName);
1051
1052 RealizeResource();
1053} // end of wxFont::SetFaceName
1054
1055void wxFont::SetUnderlined(
1056 bool bUnderlined
1057)
1058{
1059 Unshare();
1060
1061 M_FONTDATA->SetUnderlined(bUnderlined);
1062
1063 RealizeResource();
1064} // end of wxFont::SetUnderlined
1065
1066void wxFont::SetEncoding(
1067 wxFontEncoding vEncoding
1068)
1069{
1070 Unshare();
1071
1072 M_FONTDATA->SetEncoding(vEncoding);
1073
1074 RealizeResource();
1075} // end of wxFont::SetEncoding
1076
1077void wxFont::DoSetNativeFontInfo(
1078 const wxNativeFontInfo& rInfo
1079)
1080{
1081 Unshare();
1082
1083 FreeResource();
1084
1085 *M_FONTDATA = wxFontRefData(rInfo);
1086
1087 RealizeResource();
1088}
1089
1090// ----------------------------------------------------------------------------
1091// accessors
1092// ----------------------------------------------------------------------------
1093
1094int wxFont::GetPointSize() const
1095{
1096 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
1097
1098 return M_FONTDATA->GetPointSize();
1099} // end of wxFont::GetPointSize
1100
1101int wxFont::GetFamily() const
1102{
1103 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
1104
1105 return M_FONTDATA->GetFamily();
1106} // end of wxFont::GetFamily
1107
1108int wxFont::GetStyle() const
1109{
1110 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
1111
1112 return M_FONTDATA->GetStyle();
1113} // end of wxFont::GetStyle
1114
1115int wxFont::GetWeight() const
1116{
1117 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
1118
1119 return M_FONTDATA->GetWeight();
1120}
1121
1122bool wxFont::GetUnderlined() const
1123{
1124 wxCHECK_MSG( Ok(), FALSE, wxT("invalid font") );
1125
1126 return M_FONTDATA->GetUnderlined();
1127} // end of wxFont::GetUnderlined
1128
1129wxString wxFont::GetFaceName() const
1130{
1131 wxCHECK_MSG( Ok(), wxT(""), wxT("invalid font") );
1132
1133 return M_FONTDATA->GetFaceName();
1134} // end of wxFont::GetFaceName
1135
1136wxFontEncoding wxFont::GetEncoding() const
1137{
1138 wxCHECK_MSG( Ok(), wxFONTENCODING_DEFAULT, wxT("invalid font") );
1139
1140 return M_FONTDATA->GetEncoding();
1141} // end of wxFont::GetEncoding
1142
1143const wxNativeFontInfo* wxFont::GetNativeFontInfo() const
1144{
1145 return M_FONTDATA->HasNativeFontInfo() ? &(M_FONTDATA->GetNativeFontInfo())
1146 : NULL;
1147} // end of wxFont::GetNativeFontInfo
1148
1149//
1150// Internal use only method to set the FONTMETRICS array
1151//
1152void wxFont::SetFM(
1153 PFONTMETRICS pFM
1154, int nNumFonts
1155)
1156{
1157 M_FONTDATA->SetFM(pFM);
1158 M_FONTDATA->SetNumFonts(nNumFonts);
1159} // end of wxFont::SetFM
1160
1161
1162void wxFont::SetPS(
1163 HPS hPS
1164)
1165{
1166 Unshare();
1167
1168 M_FONTDATA->SetPS(hPS);
1169
1170 RealizeResource();
1171} // end of wxFont::SetPS
1172