Include order is wxprec.h=>defs.h=>platform.h=>setup.h so remove explicit setup.h...
[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 void wxFont::Init()
864 {
865 } // end of wxFont::Init
866
867 bool wxFont::Create( const wxNativeFontInfo& rInfo,
868 WXHFONT hFont )
869 {
870 UnRef();
871 m_refData = new wxFontRefData( rInfo
872 ,hFont
873 );
874 RealizeResource();
875 return true;
876 } // end of wxFont::Create
877
878 wxFont::wxFont(
879 const wxString& rsFontdesc
880 )
881 {
882 wxNativeFontInfo vInfo;
883
884 if (vInfo.FromString(rsFontdesc))
885 (void)Create(vInfo);
886 } // end of wxFont::wxFont
887
888 // ----------------------------------------------------------------------------
889 // Constructor for a font. Note that the real construction is done
890 // in wxDC::SetFont, when information is available about scaling etc.
891 // ----------------------------------------------------------------------------
892 bool wxFont::Create( int nPointSize,
893 int nFamily,
894 int nStyle,
895 int nWeight,
896 bool bUnderlined,
897 const wxString& rsFaceName,
898 wxFontEncoding vEncoding )
899 {
900 UnRef();
901
902 //
903 // wxDEFAULT is a valid value for the font size too so we must treat it
904 // specially here (otherwise the size would be 70 == wxDEFAULT value)
905 //
906 if (nPointSize == wxDEFAULT)
907 {
908 nPointSize = wxNORMAL_FONT->GetPointSize();
909 }
910 m_refData = new wxFontRefData( nPointSize
911 ,nFamily
912 ,nStyle
913 ,nWeight
914 ,bUnderlined
915 ,rsFaceName
916 ,vEncoding
917 );
918 RealizeResource();
919 return true;
920 } // end of wxFont::Create
921
922 wxFont::~wxFont()
923 {
924 } // end of wxFont::~wxFont
925
926 // ----------------------------------------------------------------------------
927 // real implementation
928 // Boris' Kovalenko comments:
929 // Because OS/2 fonts are associated with PS we can not create the font
930 // here, but we may check that font definition is true
931 // ----------------------------------------------------------------------------
932
933 bool wxFont::RealizeResource()
934 {
935 if ( GetResourceHandle() )
936 {
937 return true;
938 }
939 return M_FONTDATA->Alloc(this);
940 } // end of wxFont::RealizeResource
941
942 bool wxFont::FreeResource( bool WXUNUSED(bForce) )
943 {
944 if (GetResourceHandle())
945 {
946 M_FONTDATA->Free();
947 return true;
948 }
949 return false;
950 } // end of wxFont::FreeResource
951
952 WXHANDLE wxFont::GetResourceHandle()
953 {
954 return GetHFONT();
955 } // end of wxFont::GetResourceHandle
956
957 WXHFONT wxFont::GetHFONT() const
958 {
959 return M_FONTDATA ? M_FONTDATA->GetHFONT() : 0;
960 } // end of wxFont::GetHFONT
961
962 bool wxFont::IsFree() const
963 {
964 return M_FONTDATA && (M_FONTDATA->GetHFONT() == 0);
965 } // end of wxFont::IsFree
966
967 void wxFont::Unshare()
968 {
969 // Don't change shared data
970 if ( !m_refData )
971 {
972 m_refData = new wxFontRefData();
973 }
974 else
975 {
976 wxFontRefData* ref = new wxFontRefData(*M_FONTDATA);
977 UnRef();
978 m_refData = ref;
979 }
980 } // end of wxFont::Unshare
981
982 // ----------------------------------------------------------------------------
983 // change font attribute: we recreate font when doing it
984 // ----------------------------------------------------------------------------
985
986 void wxFont::SetPointSize(
987 int nPointSize
988 )
989 {
990 Unshare();
991
992 M_FONTDATA->SetPointSize(nPointSize);
993
994 RealizeResource();
995 } // end of wxFont::SetPointSize
996
997 void wxFont::SetFamily(
998 int nFamily
999 )
1000 {
1001 Unshare();
1002
1003 M_FONTDATA->SetFamily(nFamily);
1004
1005 RealizeResource();
1006 } // end of wxFont::SetFamily
1007
1008 void wxFont::SetStyle(
1009 int nStyle
1010 )
1011 {
1012 Unshare();
1013
1014 M_FONTDATA->SetStyle(nStyle);
1015
1016 RealizeResource();
1017 } // end of wxFont::SetStyle
1018
1019 void wxFont::SetWeight(
1020 int nWeight
1021 )
1022 {
1023 Unshare();
1024
1025 M_FONTDATA->SetWeight(nWeight);
1026
1027 RealizeResource();
1028 } // end of wxFont::SetWeight
1029
1030 void wxFont::SetFaceName(
1031 const wxString& rsFaceName
1032 )
1033 {
1034 Unshare();
1035
1036 M_FONTDATA->SetFaceName(rsFaceName);
1037
1038 RealizeResource();
1039 } // end of wxFont::SetFaceName
1040
1041 void wxFont::SetUnderlined(
1042 bool bUnderlined
1043 )
1044 {
1045 Unshare();
1046
1047 M_FONTDATA->SetUnderlined(bUnderlined);
1048
1049 RealizeResource();
1050 } // end of wxFont::SetUnderlined
1051
1052 void wxFont::SetEncoding(
1053 wxFontEncoding vEncoding
1054 )
1055 {
1056 Unshare();
1057
1058 M_FONTDATA->SetEncoding(vEncoding);
1059
1060 RealizeResource();
1061 } // end of wxFont::SetEncoding
1062
1063 void wxFont::DoSetNativeFontInfo(
1064 const wxNativeFontInfo& rInfo
1065 )
1066 {
1067 Unshare();
1068
1069 FreeResource();
1070
1071 *M_FONTDATA = wxFontRefData(rInfo);
1072
1073 RealizeResource();
1074 }
1075
1076 // ----------------------------------------------------------------------------
1077 // accessors
1078 // ----------------------------------------------------------------------------
1079
1080 int wxFont::GetPointSize() const
1081 {
1082 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
1083
1084 return M_FONTDATA->GetPointSize();
1085 } // end of wxFont::GetPointSize
1086
1087 int wxFont::GetFamily() const
1088 {
1089 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
1090
1091 return M_FONTDATA->GetFamily();
1092 } // end of wxFont::GetFamily
1093
1094 int wxFont::GetStyle() const
1095 {
1096 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
1097
1098 return M_FONTDATA->GetStyle();
1099 } // end of wxFont::GetStyle
1100
1101 int wxFont::GetWeight() const
1102 {
1103 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
1104
1105 return M_FONTDATA->GetWeight();
1106 }
1107
1108 bool wxFont::GetUnderlined() const
1109 {
1110 wxCHECK_MSG( Ok(), FALSE, wxT("invalid font") );
1111
1112 return M_FONTDATA->GetUnderlined();
1113 } // end of wxFont::GetUnderlined
1114
1115 wxString wxFont::GetFaceName() const
1116 {
1117 wxCHECK_MSG( Ok(), wxEmptyString, wxT("invalid font") );
1118
1119 return M_FONTDATA->GetFaceName();
1120 } // end of wxFont::GetFaceName
1121
1122 wxFontEncoding wxFont::GetEncoding() const
1123 {
1124 wxCHECK_MSG( Ok(), wxFONTENCODING_DEFAULT, wxT("invalid font") );
1125
1126 return M_FONTDATA->GetEncoding();
1127 } // end of wxFont::GetEncoding
1128
1129 const wxNativeFontInfo* wxFont::GetNativeFontInfo() const
1130 {
1131 return M_FONTDATA->HasNativeFontInfo() ? &(M_FONTDATA->GetNativeFontInfo())
1132 : NULL;
1133 } // end of wxFont::GetNativeFontInfo
1134
1135 //
1136 // Internal use only method to set the FONTMETRICS array
1137 //
1138 void wxFont::SetFM(
1139 PFONTMETRICS pFM
1140 , int nNumFonts
1141 )
1142 {
1143 M_FONTDATA->SetFM(pFM);
1144 M_FONTDATA->SetNumFonts(nNumFonts);
1145 } // end of wxFont::SetFM
1146
1147
1148 void wxFont::SetPS(
1149 HPS hPS
1150 )
1151 {
1152 Unshare();
1153
1154 M_FONTDATA->SetPS(hPS);
1155
1156 RealizeResource();
1157 } // end of wxFont::SetPS