]> git.saurik.com Git - wxWidgets.git/blame - src/os2/font.cpp
Fix the off-by-one a little differently, and correct a refresh problem
[wxWidgets.git] / src / os2 / font.cpp
CommitLineData
0e320a79
DW
1/////////////////////////////////////////////////////////////////////////////
2// Name: font.cpp
3// Purpose: wxFont class
21802234 4// Author: David Webster
0e320a79 5// Modified by:
21802234 6// Created: 10/06/99
0e320a79 7// RCS-ID: $Id$
21802234
DW
8// Copyright: (c) David Webster
9// Licence: wxWindows licence
0e320a79
DW
10/////////////////////////////////////////////////////////////////////////////
11
21802234
DW
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
7e99520b 20 #include <malloc.h>
21802234
DW
21// For compilers that support precompilation, includes "wx.h".
22#include "wx/wxprec.h"
0e320a79 23
21802234
DW
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"
6eb280e9 31 #include "wx/log.h"
21802234
DW
32#endif // WX_PRECOMP
33
34#include "wx/os2/private.h"
0e320a79 35
cc95f4f9
DW
36#include "wx/fontutil.h"
37#include "wx/fontmap.h"
bd6685b3 38#include "wx/encinfo.h"
cc95f4f9
DW
39
40#include "wx/tokenzr.h"
21802234 41
cc95f4f9 42IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
0e320a79 43
21802234
DW
44// ----------------------------------------------------------------------------
45// wxFontRefData - the internal description of the font
46// ----------------------------------------------------------------------------
47
48class WXDLLEXPORT wxFontRefData: public wxGDIRefData
0e320a79 49{
21802234
DW
50public:
51 wxFontRefData()
52 {
cc95f4f9 53 Init(-1, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, FALSE,
21802234
DW
54 "", wxFONTENCODING_DEFAULT);
55 }
56
e99762c0
DW
57 wxFontRefData( int nSize
58 ,int nFamily
59 ,int nStyle
60 ,int nWeight
61 ,bool bUnderlined
62 ,const wxString& sFaceName
63 ,wxFontEncoding vEncoding
64 )
21802234 65 {
cc95f4f9
DW
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;
21802234 98 }
0e320a79 99
21802234
DW
100 virtual ~wxFontRefData();
101
cc95f4f9
DW
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 {
2c1e8f2e
DW
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;
cc95f4f9
DW
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
21802234 245protected:
cc95f4f9
DW
246 //
247 // Common part of all ctors
248 //
e99762c0
DW
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
cc95f4f9
DW
258 void Init( const wxNativeFontInfo& rInfo
259 ,WXHFONT hFont = 0
260 ,WXHANDLE hPS = 0
261 );
e99762c0 262 //
21802234
DW
263 // If TRUE, the pointer to the actual font is temporary and SHOULD NOT BE
264 // DELETED by destructor
e99762c0
DW
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;
cc95f4f9
DW
279 WXHFONT m_hFont;
280
281 //
282 // Native font info
283 //
284 wxNativeFontInfo m_vNativeFontInfo;
285 bool m_bNativeFontInfoOk;
e99762c0
DW
286
287 //
288 // Some PM specific stuff
289 //
cc95f4f9
DW
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?
e99762c0 296}; // end of CLASS wxFontRefData
21802234
DW
297
298// ============================================================================
299// implementation
300// ============================================================================
301
302// ----------------------------------------------------------------------------
303// wxFontRefData
304// ----------------------------------------------------------------------------
305
e99762c0
DW
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)
0e320a79 315{
e99762c0
DW
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;
cc95f4f9
DW
324 m_hFont = 0;
325
326 m_bNativeFontInfoOk = FALSE;
327
e99762c0
DW
328 m_nFontId = 0;
329 m_bTemporary = FALSE;
e99762c0
DW
330 m_pFM = (PFONTMETRICS)NULL;
331 m_hPS = NULLHANDLE;
332 m_nNumFonts = 0;
333} // end of wxFontRefData::Init
0e320a79 334
cc95f4f9
DW
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
a23692f0 353 if (hPS == NULLHANDLE)
cc95f4f9
DW
354 {
355 m_hPS = ::WinGetPS(HWND_DESKTOP);
07df68c8 356 m_bInternalPS = TRUE;
cc95f4f9
DW
357 }
358 else
359 m_hPS = (HPS)hPS;
a23692f0
DW
360
361 m_nFontId = 0;
362 m_bTemporary = FALSE;
363 m_pFM = (PFONTMETRICS)NULL;
364 m_nNumFonts = 0;
365} // end of wxFontRefData::Init
cc95f4f9 366
0e320a79 367wxFontRefData::~wxFontRefData()
cc95f4f9
DW
368{
369 Free();
370}
371
372bool wxFontRefData::Alloc(
373 wxFont* pFont
374)
375{
376 wxString sFaceName;
828621c2 377 long flId = m_hFont;
e1146627
DW
378 long lRc;
379 short nIndex = 0;
380 PFONTMETRICS pFM = NULL;
d697657f
DW
381 ERRORID vError;
382 wxString sError;
cc95f4f9
DW
383
384 if (!m_bNativeFontInfoOk)
385 {
386 wxFillLogFont( &m_vNativeFontInfo.fa
387 ,&m_vNativeFontInfo.fn
54ffa107 388 ,&m_hPS
828621c2 389 ,&m_bInternalPS
cc95f4f9
DW
390 ,&flId
391 ,sFaceName
392 ,pFont
393 );
394 m_bNativeFontInfoOk = TRUE;
395 }
07df68c8
DW
396 else
397 {
398 if (flId == 0L)
399 flId = 1L;
400 else
401 flId++;
402 if (flId > 254)
403 flId = 1L;
404 }
e1146627
DW
405 if((lRc = ::GpiCreateLogFont( m_hPS
406 ,NULL
407 ,flId
408 ,&m_vNativeFontInfo.fa
409 )) != GPI_ERROR)
410 {
828621c2
DW
411 m_hFont = (WXHFONT)flId;
412 m_nFontId = flId;
e1146627 413 }
cc95f4f9
DW
414 if (!m_hFont)
415 {
d697657f
DW
416 vError = ::WinGetLastError(vHabmain);
417 sError = wxPMErrorToStr(vError);
cc95f4f9
DW
418 wxLogLastError("CreateFont");
419 }
420
e1146627 421 ::GpiSetCharSet(m_hPS, flId); // sets font for presentation space
cc95f4f9
DW
422 ::GpiQueryFontMetrics(m_hPS, sizeof(FONTMETRICS), &m_vNativeFontInfo.fm);
423
424 //
425 // Set refData members with the results
426 //
cc95f4f9
DW
427 memcpy(&m_vFattrs, &m_vNativeFontInfo.fa, sizeof(m_vFattrs));
428 memcpy(&m_vFname, &m_vNativeFontInfo.fn, sizeof(m_vFname));
2c1e8f2e
DW
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 //
07df68c8 436 if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Times New Roman") == 0)
cc95f4f9 437 m_nFamily = wxROMAN;
07df68c8
DW
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;
a4353f07 446 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Helvetica") == 0)
e1146627 447 m_nFamily = wxSWISS;
07df68c8 448 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Helv") == 0)
e1146627 449 m_nFamily = wxSWISS;
07df68c8 450 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Script") == 0)
cc95f4f9 451 m_nFamily = wxSCRIPT;
07df68c8 452 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Courier New") == 0)
e1146627 453 m_nFamily = wxTELETYPE;
07df68c8 454 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Courier") == 0)
e1146627 455 m_nFamily = wxTELETYPE;
07df68c8
DW
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)
1b75810c 459 m_nFamily = wxMODERN;
07df68c8
DW
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)
a23692f0 463 m_nFamily = wxSWISS;
1b75810c
DW
464 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Swiss") == 0)
465 m_nFamily = wxSWISS;
cc95f4f9
DW
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);
828621c2
DW
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
cc95f4f9
DW
519 return TRUE;
520} // end of wxFontRefData::Alloc
521
522void wxFontRefData::Free()
0e320a79 523{
e99762c0
DW
524 if (m_pFM)
525 delete [] m_pFM;
526 m_pFM = (PFONTMETRICS)NULL;
cc95f4f9
DW
527
528 if ( m_hFont )
529 {
cc95f4f9
DW
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
0e320a79 538
21802234 539// ----------------------------------------------------------------------------
cc95f4f9 540// wxNativeFontInfo
21802234 541// ----------------------------------------------------------------------------
0e320a79 542
cc95f4f9
DW
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)
19193a2c 561 {
cc95f4f9
DW
562 case FWEIGHT_DONT_CARE:
563 return wxFONTWEIGHT_NORMAL;
564
565 case FWEIGHT_NORMAL:
566 return wxFONTWEIGHT_NORMAL;
19193a2c 567
cc95f4f9
DW
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;
19193a2c 576 }
cc95f4f9
DW
577 return wxFONTWEIGHT_NORMAL;
578} // end of wxNativeFontInfo::GetWeight
19193a2c 579
cc95f4f9
DW
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 //
07df68c8
DW
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)
cc95f4f9 602 nFamily = wxROMAN;
07df68c8
DW
603 else if (strcmp(fm.szFamilyname, "Tms Rmn") == 0)
604 nFamily = wxROMAN;
605 else if (strcmp(fm.szFamilyname, "WarpSans") == 0)
606 nFamily = wxDECORATIVE;
a4353f07 607 else if (strcmp(fm.szFamilyname, "Helvetica") == 0)
07df68c8
DW
608 nFamily = wxSWISS;
609 else if (strcmp(fm.szFamilyname, "Helv") == 0)
cc95f4f9 610 nFamily = wxSWISS;
07df68c8 611 else if (strcmp(fm.szFamilyname, "Script") == 0)
cc95f4f9 612 nFamily = wxSCRIPT;
07df68c8
DW
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)
1b75810c 620 nFamily = wxMODERN;
07df68c8
DW
621 else if (strcmp(fm.szFamilyname, "System Proportional") == 0)
622 nFamily = wxMODERN;
623 else if (strcmp(fm.szFamilyname, "Arial") == 0)
a23692f0 624 nFamily = wxSWISS;
1b75810c
DW
625 else if (strcmp(fm.szFamilyname, "Swiss") == 0)
626 nFamily = wxSWISS;
cc95f4f9
DW
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:
1b75810c 712 sFacename = wxT("Tms Rmn");
cc95f4f9
DW
713 break;
714
715 case wxDECORATIVE:
07df68c8 716 sFacename = wxT("WarpSans");
cc95f4f9
DW
717 break;
718
719 case wxROMAN:
1b75810c 720 sFacename = wxT("Tms Rmn");
cc95f4f9
DW
721 break;
722
723 case wxTELETYPE:
1b75810c 724 sFacename = wxT("Courier") ;
07df68c8
DW
725 break;
726
cc95f4f9 727 case wxMODERN:
1b75810c 728 sFacename = wxT("System VIO") ;
cc95f4f9
DW
729 break;
730
731 case wxSWISS:
07df68c8 732 sFacename = wxT("Helv") ;
cc95f4f9
DW
733 break;
734
735 case wxDEFAULT:
736 default:
a23692f0 737 sFacename = wxT("System VIO") ;
cc95f4f9
DW
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 {
142b3bc2 756 if (wxFontMapper::Get()->GetAltForEncoding( eEncoding
cc95f4f9
DW
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
cc95f4f9
DW
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// ----------------------------------------------------------------------------
19193a2c 870
21802234 871void wxFont::Init()
0e320a79 872{
cc95f4f9
DW
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
0e320a79 897
e99762c0
DW
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)
0e320a79
DW
911{
912 UnRef();
cc95f4f9
DW
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 }
e99762c0
DW
922 m_refData = new wxFontRefData( nPointSize
923 ,nFamily
924 ,nStyle
925 ,nWeight
926 ,bUnderlined
927 ,rsFaceName
928 ,vEncoding
929 );
0e320a79 930 RealizeResource();
0e320a79 931 return TRUE;
e99762c0 932} // end of wxFont::Create
0e320a79
DW
933
934wxFont::~wxFont()
935{
e99762c0 936} // end of wxFont::~wxFont
0e320a79 937
21802234
DW
938// ----------------------------------------------------------------------------
939// real implementation
f6bcfd97
BP
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
21802234
DW
943// ----------------------------------------------------------------------------
944
0e320a79
DW
945bool wxFont::RealizeResource()
946{
21802234
DW
947 if ( GetResourceHandle() )
948 {
cc95f4f9 949 return TRUE;
21802234 950 }
cc95f4f9 951 return M_FONTDATA->Alloc(this);
e99762c0 952} // end of wxFont::RealizeResource
21802234 953
e99762c0
DW
954bool wxFont::FreeResource(
955 bool bForce
956)
21802234 957{
e99762c0 958 if (GetResourceHandle())
21802234 959 {
cc95f4f9 960 M_FONTDATA->Free();
21802234
DW
961 return TRUE;
962 }
0e320a79 963 return FALSE;
e99762c0 964} // end of wxFont::FreeResource
0e320a79 965
5fd2b2c6
DW
966WXHANDLE wxFont::GetResourceHandle()
967{
968 return GetHFONT();
e99762c0 969} // end of wxFont::GetResourceHandle
21802234 970
cc95f4f9
DW
971WXHFONT wxFont::GetHFONT() const
972{
973 return M_FONTDATA ? M_FONTDATA->GetHFONT() : 0;
974} // end of wxFont::GetHFONT
975
21802234
DW
976bool wxFont::IsFree() const
977{
cc95f4f9 978 return M_FONTDATA && (M_FONTDATA->GetHFONT() == 0);
e99762c0 979} // end of wxFont::IsFree
21802234 980
0e320a79
DW
981void wxFont::Unshare()
982{
21802234
DW
983 // Don't change shared data
984 if ( !m_refData )
0e320a79 985 {
21802234
DW
986 m_refData = new wxFontRefData();
987 }
0e320a79
DW
988 else
989 {
21802234
DW
990 wxFontRefData* ref = new wxFontRefData(*M_FONTDATA);
991 UnRef();
992 m_refData = ref;
993 }
e99762c0 994} // end of wxFont::Unshare
0e320a79 995
21802234
DW
996// ----------------------------------------------------------------------------
997// change font attribute: we recreate font when doing it
998// ----------------------------------------------------------------------------
999
e99762c0
DW
1000void wxFont::SetPointSize(
1001 int nPointSize
1002)
0e320a79
DW
1003{
1004 Unshare();
1005
cc95f4f9 1006 M_FONTDATA->SetPointSize(nPointSize);
0e320a79
DW
1007
1008 RealizeResource();
e99762c0 1009} // end of wxFont::SetPointSize
0e320a79 1010
e99762c0
DW
1011void wxFont::SetFamily(
1012 int nFamily
1013)
0e320a79
DW
1014{
1015 Unshare();
1016
cc95f4f9 1017 M_FONTDATA->SetFamily(nFamily);
0e320a79
DW
1018
1019 RealizeResource();
e99762c0 1020} // end of wxFont::SetFamily
0e320a79 1021
e99762c0
DW
1022void wxFont::SetStyle(
1023 int nStyle
1024)
0e320a79
DW
1025{
1026 Unshare();
1027
cc95f4f9 1028 M_FONTDATA->SetStyle(nStyle);
0e320a79
DW
1029
1030 RealizeResource();
e99762c0 1031} // end of wxFont::SetStyle
0e320a79 1032
e99762c0
DW
1033void wxFont::SetWeight(
1034 int nWeight
1035)
0e320a79
DW
1036{
1037 Unshare();
1038
cc95f4f9 1039 M_FONTDATA->SetWeight(nWeight);
0e320a79
DW
1040
1041 RealizeResource();
e99762c0 1042} // end of wxFont::SetWeight
0e320a79 1043
e99762c0
DW
1044void wxFont::SetFaceName(
1045 const wxString& rsFaceName
1046)
0e320a79
DW
1047{
1048 Unshare();
1049
cc95f4f9 1050 M_FONTDATA->SetFaceName(rsFaceName);
0e320a79
DW
1051
1052 RealizeResource();
e99762c0 1053} // end of wxFont::SetFaceName
0e320a79 1054
e99762c0
DW
1055void wxFont::SetUnderlined(
1056 bool bUnderlined
1057)
0e320a79
DW
1058{
1059 Unshare();
1060
cc95f4f9 1061 M_FONTDATA->SetUnderlined(bUnderlined);
0e320a79
DW
1062
1063 RealizeResource();
e99762c0 1064} // end of wxFont::SetUnderlined
0e320a79 1065
e99762c0
DW
1066void wxFont::SetEncoding(
1067 wxFontEncoding vEncoding
1068)
0e320a79 1069{
21802234
DW
1070 Unshare();
1071
cc95f4f9 1072 M_FONTDATA->SetEncoding(vEncoding);
21802234
DW
1073
1074 RealizeResource();
e99762c0
DW
1075} // end of wxFont::SetEncoding
1076
9045ad9d 1077void wxFont::DoSetNativeFontInfo(
cc95f4f9 1078 const wxNativeFontInfo& rInfo
e99762c0
DW
1079)
1080{
1081 Unshare();
1082
cc95f4f9 1083 FreeResource();
e99762c0 1084
cc95f4f9 1085 *M_FONTDATA = wxFontRefData(rInfo);
e99762c0 1086
cc95f4f9
DW
1087 RealizeResource();
1088}
0e320a79 1089
21802234
DW
1090// ----------------------------------------------------------------------------
1091// accessors
1092// ----------------------------------------------------------------------------
1093
1094int wxFont::GetPointSize() const
0e320a79 1095{
cc95f4f9 1096 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
7e99520b 1097
cc95f4f9 1098 return M_FONTDATA->GetPointSize();
e99762c0 1099} // end of wxFont::GetPointSize
0e320a79 1100
21802234 1101int wxFont::GetFamily() const
0e320a79 1102{
cc95f4f9 1103 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
21802234 1104
cc95f4f9
DW
1105 return M_FONTDATA->GetFamily();
1106} // end of wxFont::GetFamily
21802234
DW
1107
1108int wxFont::GetStyle() const
1109{
cc95f4f9
DW
1110 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
1111
1112 return M_FONTDATA->GetStyle();
e99762c0 1113} // end of wxFont::GetStyle
21802234
DW
1114
1115int wxFont::GetWeight() const
1116{
cc95f4f9
DW
1117 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
1118
1119 return M_FONTDATA->GetWeight();
21802234
DW
1120}
1121
1122bool wxFont::GetUnderlined() const
1123{
cc95f4f9
DW
1124 wxCHECK_MSG( Ok(), FALSE, wxT("invalid font") );
1125
1126 return M_FONTDATA->GetUnderlined();
e99762c0 1127} // end of wxFont::GetUnderlined
21802234
DW
1128
1129wxString wxFont::GetFaceName() const
1130{
cc95f4f9 1131 wxCHECK_MSG( Ok(), wxT(""), wxT("invalid font") );
e99762c0 1132
cc95f4f9 1133 return M_FONTDATA->GetFaceName();
e99762c0 1134} // end of wxFont::GetFaceName
21802234
DW
1135
1136wxFontEncoding wxFont::GetEncoding() const
1137{
cc95f4f9 1138 wxCHECK_MSG( Ok(), wxFONTENCODING_DEFAULT, wxT("invalid font") );
e99762c0 1139
cc95f4f9
DW
1140 return M_FONTDATA->GetEncoding();
1141} // end of wxFont::GetEncoding
0e320a79 1142
3bf5a59b 1143const wxNativeFontInfo* wxFont::GetNativeFontInfo() const
cc95f4f9 1144{
3bf5a59b
VZ
1145 return M_FONTDATA->HasNativeFontInfo() ? &(M_FONTDATA->GetNativeFontInfo())
1146 : NULL;
cc95f4f9
DW
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
e99762c0
DW
1160
1161
d0a6b279
DW
1162void wxFont::SetPS(
1163 HPS hPS
1164)
1165{
1166 Unshare();
1167
1168 M_FONTDATA->SetPS(hPS);
1169
1170 RealizeResource();
47df2b8c 1171} // end of wxFont::SetPS
d0a6b279 1172