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