]> git.saurik.com Git - wxWidgets.git/blame - src/os2/font.cpp
guard against nullptr
[wxWidgets.git] / src / os2 / font.cpp
CommitLineData
0e320a79 1/////////////////////////////////////////////////////////////////////////////
521bf4ff 2// Name: src/os2/font.cpp
0e320a79 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 8// Copyright: (c) David Webster
65571936 9// Licence: wxWindows licence
0e320a79
DW
10/////////////////////////////////////////////////////////////////////////////
11
6670f564
WS
12// For compilers that support precompilation, includes "wx.h".
13#include "wx/wxprec.h"
14
21802234
DW
15// ============================================================================
16// declarations
17// ============================================================================
18
19// ----------------------------------------------------------------------------
20// headers
21// ----------------------------------------------------------------------------
22
48a1108e
WS
23#include "wx/font.h"
24
21802234
DW
25#ifndef WX_PRECOMP
26 #include <stdio.h>
21802234
DW
27 #include "wx/list.h"
28 #include "wx/utils.h"
29 #include "wx/app.h"
6eb280e9 30 #include "wx/log.h"
21802234
DW
31#endif // WX_PRECOMP
32
33#include "wx/os2/private.h"
0e320a79 34
cc95f4f9
DW
35#include "wx/fontutil.h"
36#include "wx/fontmap.h"
bd6685b3 37#include "wx/encinfo.h"
cc95f4f9
DW
38
39#include "wx/tokenzr.h"
21802234 40
6670f564
WS
41#include <malloc.h>
42
21802234
DW
43// ----------------------------------------------------------------------------
44// wxFontRefData - the internal description of the font
45// ----------------------------------------------------------------------------
46
47class WXDLLEXPORT wxFontRefData: public wxGDIRefData
0e320a79 48{
21802234
DW
49public:
50 wxFontRefData()
51 {
17b1d76b 52 Init(-1, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false,
0fba44b4 53 wxEmptyString, wxFONTENCODING_DEFAULT);
21802234
DW
54 }
55
e99762c0 56 wxFontRefData( int nSize
98ecc3aa
FM
57 ,wxFontFamily nFamily
58 ,wxFontStyle nStyle
59 ,wxFontWeight nWeight
e99762c0
DW
60 ,bool bUnderlined
61 ,const wxString& sFaceName
62 ,wxFontEncoding vEncoding
63 )
21802234 64 {
cc95f4f9
DW
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;
21802234 97 }
0e320a79 98
21802234
DW
99 virtual ~wxFontRefData();
100
cc95f4f9
DW
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 {
2c1e8f2e
DW
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;
cc95f4f9
DW
119 }
120
98ecc3aa 121 inline wxFontFamily GetFamily(void) const
cc95f4f9
DW
122 {
123 return m_nFamily;
124 }
125
98ecc3aa 126 inline wxFontStyle GetStyle(void) const
cc95f4f9
DW
127 {
128 return m_bNativeFontInfoOk ? m_vNativeFontInfo.GetStyle()
129 : m_nStyle;
130 }
131
98ecc3aa 132 inline wxFontWeight GetWeight(void) const
cc95f4f9
DW
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
98ecc3aa 176 inline void SetFamily(wxFontFamily nFamily)
cc95f4f9
DW
177 {
178 m_nFamily = nFamily;
179 }
180
98ecc3aa 181 inline void SetStyle(wxFontStyle nStyle)
cc95f4f9
DW
182 {
183 if (m_bNativeFontInfoOk)
98ecc3aa 184 m_vNativeFontInfo.SetStyle(nStyle);
cc95f4f9
DW
185 else
186 m_nStyle = nStyle;
187 }
188
98ecc3aa 189 inline void SetWeight(wxFontWeight nWeight)
cc95f4f9
DW
190 {
191 if (m_bNativeFontInfoOk)
98ecc3aa 192 m_vNativeFontInfo.SetWeight(nWeight);
cc95f4f9
DW
193 else
194 m_nWeight = nWeight;
195 }
196
85ab460e 197 inline bool SetFaceName(const wxString& sFaceName)
cc95f4f9
DW
198 {
199 if (m_bNativeFontInfoOk)
85ab460e 200 return m_vNativeFontInfo.SetFaceName(sFaceName);
cc95f4f9
DW
201 else
202 m_sFaceName = sFaceName;
85ab460e 203 return true;
cc95f4f9
DW
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 249 void Init( int nSize
46f83c8e
FM
250 ,wxFontFamily nFamily
251 ,wxFontStyle nStyle
252 ,wxFontWeight nWeight
e99762c0
DW
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 //
6670f564 263 // If true, the pointer to the actual font is temporary and SHOULD NOT BE
21802234 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;
0951e426
FM
273 wxFontFamily m_nFamily;
274 wxFontStyle m_nStyle;
275 wxFontWeight m_nWeight;
e99762c0
DW
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 297
68c95704 298#define M_FONTDATA ((wxFontRefData*)m_refData)
873fd4af 299
21802234
DW
300// ============================================================================
301// implementation
302// ============================================================================
303
304// ----------------------------------------------------------------------------
305// wxFontRefData
306// ----------------------------------------------------------------------------
307
e99762c0
DW
308void wxFontRefData::Init(
309 int nPointSize
98ecc3aa
FM
310, wxFontFamily nFamily
311, wxFontStyle nStyle
312, wxFontWeight nWeight
e99762c0
DW
313, bool bUnderlined
314, const wxString& rsFaceName
315, wxFontEncoding vEncoding
316)
0e320a79 317{
e99762c0
DW
318 m_nStyle = nStyle;
319 m_nPointSize = nPointSize;
320 m_nFamily = nFamily;
321 m_nStyle = nStyle;
322 m_nWeight = nWeight;
323 m_bUnderlined = bUnderlined;
324 m_sFaceName = rsFaceName;
325 m_vEncoding = vEncoding;
cc95f4f9
DW
326 m_hFont = 0;
327
8ecff181 328 m_bNativeFontInfoOk = false;
cc95f4f9 329
e99762c0 330 m_nFontId = 0;
8ecff181 331 m_bTemporary = false;
e99762c0
DW
332 m_pFM = (PFONTMETRICS)NULL;
333 m_hPS = NULLHANDLE;
334 m_nNumFonts = 0;
335} // end of wxFontRefData::Init
0e320a79 336
cc95f4f9
DW
337void wxFontRefData::Init(
338 const wxNativeFontInfo& rInfo
339, WXHFONT hFont //this is the FontId -- functions as the hFont for OS/2
340, WXHANDLE hPS // Presentation Space we are using
341)
342{
343 //
344 // hFont may be zero, or it be passed in case we really want to
345 // use the exact font created in the underlying system
346 // (for example where we can't guarantee conversion from HFONT
347 // to LOGFONT back to HFONT)
348 //
349 m_hFont = hFont;
350 m_nFontId = (int)hFont;
351
6670f564 352 m_bNativeFontInfoOk = true;
cc95f4f9
DW
353 m_vNativeFontInfo = rInfo;
354
a23692f0 355 if (hPS == NULLHANDLE)
cc95f4f9
DW
356 {
357 m_hPS = ::WinGetPS(HWND_DESKTOP);
6670f564 358 m_bInternalPS = true;
cc95f4f9
DW
359 }
360 else
361 m_hPS = (HPS)hPS;
a23692f0
DW
362
363 m_nFontId = 0;
8ecff181 364 m_bTemporary = false;
a23692f0
DW
365 m_pFM = (PFONTMETRICS)NULL;
366 m_nNumFonts = 0;
367} // end of wxFontRefData::Init
cc95f4f9 368
0e320a79 369wxFontRefData::~wxFontRefData()
cc95f4f9
DW
370{
371 Free();
372}
373
6670f564 374bool wxFontRefData::Alloc( wxFont* pFont )
cc95f4f9
DW
375{
376 wxString sFaceName;
828621c2 377 long flId = m_hFont;
e1146627 378 long lRc;
d697657f
DW
379 ERRORID vError;
380 wxString sError;
cc95f4f9
DW
381
382 if (!m_bNativeFontInfoOk)
383 {
384 wxFillLogFont( &m_vNativeFontInfo.fa
385 ,&m_vNativeFontInfo.fn
54ffa107 386 ,&m_hPS
828621c2 387 ,&m_bInternalPS
cc95f4f9
DW
388 ,&flId
389 ,sFaceName
390 ,pFont
391 );
6670f564 392 m_bNativeFontInfoOk = true;
cc95f4f9 393 }
07df68c8
DW
394 else
395 {
396 if (flId == 0L)
397 flId = 1L;
398 else
399 flId++;
400 if (flId > 254)
401 flId = 1L;
402 }
e1146627
DW
403 if((lRc = ::GpiCreateLogFont( m_hPS
404 ,NULL
405 ,flId
406 ,&m_vNativeFontInfo.fa
407 )) != GPI_ERROR)
408 {
828621c2
DW
409 m_hFont = (WXHFONT)flId;
410 m_nFontId = flId;
e1146627 411 }
cc95f4f9
DW
412 if (!m_hFont)
413 {
d697657f
DW
414 vError = ::WinGetLastError(vHabmain);
415 sError = wxPMErrorToStr(vError);
2173b18f 416 wxLogLastError(wxT("CreateFont"));
cc95f4f9
DW
417 }
418
e1146627 419 ::GpiSetCharSet(m_hPS, flId); // sets font for presentation space
cc95f4f9
DW
420 ::GpiQueryFontMetrics(m_hPS, sizeof(FONTMETRICS), &m_vNativeFontInfo.fm);
421
422 //
423 // Set refData members with the results
424 //
cc95f4f9
DW
425 memcpy(&m_vFattrs, &m_vNativeFontInfo.fa, sizeof(m_vFattrs));
426 memcpy(&m_vFname, &m_vNativeFontInfo.fn, sizeof(m_vFname));
2c1e8f2e
DW
427 //
428 // Going to leave the point size alone. Mostly we use outline fonts
429 // that can be set to any point size inside of Presentation Parameters,
430 // regardless of whether or not the actual font is registered in the system.
431 // The GpiCreateLogFont will do enough by selecting the right family,
432 // and face name.
433 //
07df68c8 434 if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Times New Roman") == 0)
0951e426 435 m_nFamily = wxFONTFAMILY_ROMAN;
07df68c8 436 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Times New Roman MT 30") == 0)
0951e426 437 m_nFamily = wxFONTFAMILY_ROMAN;
07df68c8 438 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "@Times New Roman MT 30") == 0)
0951e426 439 m_nFamily = wxFONTFAMILY_ROMAN;
07df68c8 440 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Tms Rmn") == 0)
0951e426 441 m_nFamily = wxFONTFAMILY_ROMAN;
07df68c8 442 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "WarpSans") == 0)
0951e426 443 m_nFamily = wxFONTFAMILY_DECORATIVE;
a4353f07 444 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Helvetica") == 0)
0951e426 445 m_nFamily = wxFONTFAMILY_SWISS;
07df68c8 446 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Helv") == 0)
0951e426 447 m_nFamily = wxFONTFAMILY_SWISS;
07df68c8 448 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Script") == 0)
0951e426 449 m_nFamily = wxFONTFAMILY_SCRIPT;
07df68c8 450 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Courier New") == 0)
0951e426 451 m_nFamily = wxFONTFAMILY_TELETYPE;
07df68c8 452 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Courier") == 0)
0951e426 453 m_nFamily = wxFONTFAMILY_TELETYPE;
07df68c8 454 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "System Monospaced") == 0)
0951e426 455 m_nFamily = wxFONTFAMILY_TELETYPE;
07df68c8 456 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "System VIO") == 0)
0951e426 457 m_nFamily = wxFONTFAMILY_MODERN;
07df68c8 458 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "System Proportional") == 0)
0951e426 459 m_nFamily = wxFONTFAMILY_MODERN;
07df68c8 460 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Arial") == 0)
0951e426 461 m_nFamily = wxFONTFAMILY_SWISS;
1b75810c 462 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Swiss") == 0)
0951e426 463 m_nFamily = wxFONTFAMILY_SWISS;
cc95f4f9 464 else
0951e426 465 m_nFamily = wxFONTFAMILY_SWISS;
cc95f4f9
DW
466
467 if (m_vNativeFontInfo.fa.fsSelection & FATTR_SEL_ITALIC)
468 m_nStyle = wxFONTSTYLE_ITALIC;
469 else
470 m_nStyle = wxFONTSTYLE_NORMAL;
471 switch(m_vNativeFontInfo.fn.usWeightClass)
472 {
473 case FWEIGHT_DONT_CARE:
474 m_nWeight = wxFONTWEIGHT_NORMAL;
475 break;
476
477 case FWEIGHT_NORMAL:
478 m_nWeight = wxFONTWEIGHT_NORMAL;
479 break;
480
481 case FWEIGHT_LIGHT:
482 m_nWeight = wxFONTWEIGHT_LIGHT;
483 break;
484
485 case FWEIGHT_BOLD:
486 m_nWeight = wxFONTWEIGHT_BOLD;
487 break;
488
489 case FWEIGHT_ULTRA_BOLD:
490 m_nWeight = wxFONTWEIGHT_MAX;
491 break;
492
493 default:
494 m_nWeight = wxFONTWEIGHT_NORMAL;
495 }
496 m_bUnderlined = ((m_vNativeFontInfo.fa.fsSelection & FATTR_SEL_UNDERSCORE) != 0);
0fba44b4 497 m_sFaceName = (wxChar*)m_vNativeFontInfo.fa.szFacename;
cc95f4f9 498 m_vEncoding = wxGetFontEncFromCharSet(m_vNativeFontInfo.fa.usCodePage);
828621c2
DW
499
500 //
501 // We don't actuall keep the font around if using a temporary PS
502 //
503 if (m_bInternalPS)
504 {
505 if(m_hFont)
506 ::GpiDeleteSetId( m_hPS
507 ,flId
508 );
509
510 ::WinReleasePS(m_hPS);
511 }
512 else
513 //
514 // Select the font into the Presentation space
515 //
516 ::GpiSetCharSet(m_hPS, flId); // sets font for presentation space
6670f564 517 return true;
cc95f4f9
DW
518} // end of wxFontRefData::Alloc
519
520void wxFontRefData::Free()
0e320a79 521{
e99762c0
DW
522 if (m_pFM)
523 delete [] m_pFM;
524 m_pFM = (PFONTMETRICS)NULL;
cc95f4f9
DW
525
526 if ( m_hFont )
527 {
cc95f4f9
DW
528 ::GpiDeleteSetId(m_hPS, 1L); /* delete the logical font */
529 m_nFontId = 0;
530 m_hFont = 0;
531 }
532 if (m_bInternalPS)
533 ::WinReleasePS(m_hPS);
534 m_hPS = NULLHANDLE;
535} // end of wxFontRefData::Free
0e320a79 536
21802234 537// ----------------------------------------------------------------------------
cc95f4f9 538// wxNativeFontInfo
21802234 539// ----------------------------------------------------------------------------
0e320a79 540
cc95f4f9
DW
541void wxNativeFontInfo::Init()
542{
543 memset(&fa, '\0', sizeof(FATTRS));
544} // end of wxNativeFontInfo::Init
545
546int wxNativeFontInfo::GetPointSize() const
547{
548 return fm.lEmHeight;
549} // end of wxNativeFontInfo::GetPointSize
550
551wxFontStyle wxNativeFontInfo::GetStyle() const
552{
553 return fa.fsSelection & FATTR_SEL_ITALIC ? wxFONTSTYLE_ITALIC : wxFONTSTYLE_NORMAL;
554} // end of wxNativeFontInfo::GetStyle
555
556wxFontWeight wxNativeFontInfo::GetWeight() const
557{
558 switch(fn.usWeightClass)
19193a2c 559 {
cc95f4f9
DW
560 case FWEIGHT_DONT_CARE:
561 return wxFONTWEIGHT_NORMAL;
562
563 case FWEIGHT_NORMAL:
564 return wxFONTWEIGHT_NORMAL;
19193a2c 565
cc95f4f9
DW
566 case FWEIGHT_LIGHT:
567 return wxFONTWEIGHT_LIGHT;
568
569 case FWEIGHT_BOLD:
570 return wxFONTWEIGHT_BOLD;
571
572 case FWEIGHT_ULTRA_BOLD:
573 return wxFONTWEIGHT_MAX;
19193a2c 574 }
cc95f4f9
DW
575 return wxFONTWEIGHT_NORMAL;
576} // end of wxNativeFontInfo::GetWeight
19193a2c 577
cc95f4f9
DW
578bool wxNativeFontInfo::GetUnderlined() const
579{
580 return ((fa.fsSelection & FATTR_SEL_UNDERSCORE) != 0);
581} // end of wxNativeFontInfo::GetUnderlined
582
583wxString wxNativeFontInfo::GetFaceName() const
584{
0fba44b4 585 return (wxChar*)fm.szFacename;
cc95f4f9
DW
586} // end of wxNativeFontInfo::GetFaceName
587
588wxFontFamily wxNativeFontInfo::GetFamily() const
589{
590 int nFamily;
591
592 //
593 // Extract family from facename
594 //
07df68c8 595 if (strcmp(fm.szFamilyname, "Times New Roman") == 0)
0951e426 596 nFamily = wxFONTFAMILY_ROMAN;
07df68c8 597 else if (strcmp(fm.szFamilyname, "Times New Roman MT 30") == 0)
0951e426 598 nFamily = wxFONTFAMILY_ROMAN;
07df68c8 599 else if (strcmp(fm.szFamilyname, "@Times New Roman MT 30") == 0)
0951e426 600 nFamily = wxFONTFAMILY_ROMAN;
07df68c8 601 else if (strcmp(fm.szFamilyname, "Tms Rmn") == 0)
0951e426 602 nFamily = wxFONTFAMILY_ROMAN;
07df68c8 603 else if (strcmp(fm.szFamilyname, "WarpSans") == 0)
0951e426 604 nFamily = wxFONTFAMILY_DECORATIVE;
a4353f07 605 else if (strcmp(fm.szFamilyname, "Helvetica") == 0)
0951e426 606 nFamily = wxFONTFAMILY_SWISS;
07df68c8 607 else if (strcmp(fm.szFamilyname, "Helv") == 0)
0951e426 608 nFamily = wxFONTFAMILY_SWISS;
07df68c8 609 else if (strcmp(fm.szFamilyname, "Script") == 0)
0951e426 610 nFamily = wxFONTFAMILY_SCRIPT;
07df68c8 611 else if (strcmp(fm.szFamilyname, "Courier New") == 0)
0951e426 612 nFamily = wxFONTFAMILY_TELETYPE;
07df68c8 613 else if (strcmp(fm.szFamilyname, "Courier") == 0)
0951e426 614 nFamily = wxFONTFAMILY_TELETYPE;
07df68c8 615 else if (strcmp(fm.szFamilyname, "System Monospaced") == 0)
0951e426 616 nFamily = wxFONTFAMILY_TELETYPE;
07df68c8 617 else if (strcmp(fm.szFamilyname, "System VIO") == 0)
0951e426 618 nFamily = wxFONTFAMILY_MODERN;
07df68c8 619 else if (strcmp(fm.szFamilyname, "System Proportional") == 0)
0951e426 620 nFamily = wxFONTFAMILY_MODERN;
07df68c8 621 else if (strcmp(fm.szFamilyname, "Arial") == 0)
0951e426 622 nFamily = wxFONTFAMILY_SWISS;
1b75810c 623 else if (strcmp(fm.szFamilyname, "Swiss") == 0)
0951e426 624 nFamily = wxFONTFAMILY_SWISS;
cc95f4f9 625 else
0951e426 626 nFamily = wxFONTFAMILY_SWISS;
cc95f4f9
DW
627 return (wxFontFamily)nFamily;
628} // end of wxNativeFontInfo::GetFamily
629
630wxFontEncoding wxNativeFontInfo::GetEncoding() const
631{
632 return wxGetFontEncFromCharSet(fa.usCodePage);
633} // end of wxNativeFontInfo::GetEncoding
634
635void wxNativeFontInfo::SetPointSize(
636 int nPointsize
637)
638{
639 fm.lEmHeight = (LONG)nPointsize;
640} // end of wxNativeFontInfo::SetPointSize
641
642void wxNativeFontInfo::SetStyle(
643 wxFontStyle eStyle
644)
645{
646 switch (eStyle)
647 {
648 default:
9a83f860 649 wxFAIL_MSG( wxT("unknown font style") );
cc95f4f9
DW
650 // fall through
651
652 case wxFONTSTYLE_NORMAL:
653 break;
654
655 case wxFONTSTYLE_ITALIC:
656 case wxFONTSTYLE_SLANT:
657 fa.fsSelection |= FATTR_SEL_ITALIC;
658 break;
659 }
660} // end of wxNativeFontInfo::SetStyle
661
662void wxNativeFontInfo::SetWeight(
663 wxFontWeight eWeight
664)
665{
666 switch (eWeight)
667 {
668 default:
9a83f860 669 wxFAIL_MSG( wxT("unknown font weight") );
cc95f4f9
DW
670 // fall through
671
672 case wxFONTWEIGHT_NORMAL:
673 fn.usWeightClass = FWEIGHT_NORMAL;
674 break;
675
676 case wxFONTWEIGHT_LIGHT:
677 fn.usWeightClass = FWEIGHT_LIGHT;
678 break;
679
680 case wxFONTWEIGHT_BOLD:
681 fn.usWeightClass = FWEIGHT_BOLD;
682 break;
683 }
684} // end of wxNativeFontInfo::SetWeight
685
686void wxNativeFontInfo::SetUnderlined(
687 bool bUnderlined
688)
689{
690 if(bUnderlined)
691 fa.fsSelection |= FATTR_SEL_UNDERSCORE;
692} // end of wxNativeFontInfo::SetUnderlined
693
85ab460e 694bool wxNativeFontInfo::SetFaceName(
fbfb8bcc 695 const wxString& sFacename
cc95f4f9
DW
696)
697{
e408bf52 698 wxStrlcpy((wxChar*)fa.szFacename, sFacename, WXSIZEOF(fa.szFacename));
85ab460e 699 return true;
cc95f4f9
DW
700} // end of wxNativeFontInfo::SetFaceName
701
702void wxNativeFontInfo::SetFamily(
703 wxFontFamily eFamily
704)
705{
706 wxString sFacename;
707
708 switch (eFamily)
709 {
0951e426 710 case wxFONTFAMILY_SCRIPT:
1b75810c 711 sFacename = wxT("Tms Rmn");
cc95f4f9
DW
712 break;
713
0951e426 714 case wxFONTFAMILY_DECORATIVE:
07df68c8 715 sFacename = wxT("WarpSans");
cc95f4f9
DW
716 break;
717
0951e426 718 case wxFONTFAMILY_ROMAN:
1b75810c 719 sFacename = wxT("Tms Rmn");
cc95f4f9
DW
720 break;
721
0951e426 722 case wxFONTFAMILY_TELETYPE:
1b75810c 723 sFacename = wxT("Courier") ;
07df68c8
DW
724 break;
725
0951e426 726 case wxFONTFAMILY_MODERN:
1b75810c 727 sFacename = wxT("System VIO") ;
cc95f4f9
DW
728 break;
729
0951e426 730 case wxFONTFAMILY_SWISS:
07df68c8 731 sFacename = wxT("Helv") ;
cc95f4f9
DW
732 break;
733
0951e426 734 case wxFONTFAMILY_DEFAULT:
cc95f4f9 735 default:
a23692f0 736 sFacename = wxT("System VIO") ;
cc95f4f9
DW
737 }
738
0fba44b4 739 if (!wxStrlen((wxChar*)fa.szFacename) )
cc95f4f9
DW
740 {
741 SetFaceName(sFacename);
742 }
743} // end of wxNativeFontInfo::SetFamily
744
6670f564 745void wxNativeFontInfo::SetEncoding( wxFontEncoding eEncoding )
cc95f4f9
DW
746{
747 wxNativeEncodingInfo vInfo;
748
749 if ( !wxGetNativeFontEncoding( eEncoding
750 ,&vInfo
751 ))
752 {
142b3bc2 753 if (wxFontMapper::Get()->GetAltForEncoding( eEncoding
cc95f4f9
DW
754 ,&vInfo
755 ))
756 {
757 if (!vInfo.facename.empty())
758 {
759 //
760 // If we have this encoding only in some particular facename, use
761 // the facename - it is better to show the correct characters in a
762 // wrong facename than unreadable text in a correct one
763 //
764 SetFaceName(vInfo.facename);
765 }
766 }
767 else
cc95f4f9
DW
768 {
769 // unsupported encoding, replace with the default
770 vInfo.charset = 850;
771 }
772 }
6670f564 773 fa.usCodePage = (USHORT)vInfo.charset;
cc95f4f9
DW
774} // end of wxNativeFontInfo::SetFaceName
775
6670f564 776bool wxNativeFontInfo::FromString( const wxString& rsStr )
cc95f4f9
DW
777{
778 long lVal;
779
9a83f860 780 wxStringTokenizer vTokenizer(rsStr, wxT(";"));
cc95f4f9
DW
781
782 //
783 // First the version
784 //
785 wxString sToken = vTokenizer.GetNextToken();
786
9a83f860 787 if (sToken != wxT('0'))
8ecff181 788 return false;
cc95f4f9
DW
789
790 sToken = vTokenizer.GetNextToken();
791 if (!sToken.ToLong(&lVal))
8ecff181 792 return false;
cc95f4f9
DW
793 fm.lEmHeight = lVal;
794
795 sToken = vTokenizer.GetNextToken();
796 if (!sToken.ToLong(&lVal))
8ecff181 797 return false;
cc95f4f9
DW
798 fa.lAveCharWidth = lVal;
799
800 sToken = vTokenizer.GetNextToken();
801 if (!sToken.ToLong(&lVal))
8ecff181 802 return false;
cc95f4f9
DW
803 fa.fsSelection = (USHORT)lVal;
804
805 sToken = vTokenizer.GetNextToken();
806 if (!sToken.ToLong(&lVal))
8ecff181 807 return false;
cc95f4f9
DW
808 fa.fsType = (USHORT)lVal;
809
810 sToken = vTokenizer.GetNextToken();
811 if (!sToken.ToLong(&lVal))
8ecff181 812 return false;
cc95f4f9
DW
813 fa.fsFontUse = (USHORT)lVal;
814
815 sToken = vTokenizer.GetNextToken();
816 if (!sToken.ToLong(&lVal))
8ecff181 817 return false;
cc95f4f9
DW
818 fa.idRegistry = (USHORT)lVal;
819
820 sToken = vTokenizer.GetNextToken();
821 if (!sToken.ToLong(&lVal))
8ecff181 822 return false;
cc95f4f9
DW
823 fa.usCodePage = (USHORT)lVal;
824
825 sToken = vTokenizer.GetNextToken();
826 if (!sToken.ToLong(&lVal))
8ecff181 827 return false;
cc95f4f9
DW
828 fa.lMatch = lVal;
829
830 sToken = vTokenizer.GetNextToken();
831 if (!sToken.ToLong(&lVal))
8ecff181 832 return false;
cc95f4f9
DW
833 fn.usWeightClass = (USHORT)lVal;
834
835 sToken = vTokenizer.GetNextToken();
836 if(!sToken)
8ecff181 837 return false;
0fba44b4 838 wxStrcpy((wxChar*)fa.szFacename, sToken.c_str());
6670f564 839 return true;
cc95f4f9
DW
840} // end of wxNativeFontInfo::FromString
841
842wxString wxNativeFontInfo::ToString() const
843{
844 wxString sStr;
845
9a83f860 846 sStr.Printf(wxT("%d;%ld;%ld;%ld;%d;%d;%d;%d;%d;%ld;%d;%s"),
cc95f4f9
DW
847 0, // version, in case we want to change the format later
848 fm.lEmHeight,
849 fa.lAveCharWidth,
850 fa.lMaxBaselineExt,
851 fa.fsSelection,
852 fa.fsType,
853 fa.fsFontUse,
854 fa.idRegistry,
855 fa.usCodePage,
856 fa.lMatch,
857 fn.usWeightClass,
fb2c90ca 858 (char *)fa.szFacename);
cc95f4f9
DW
859 return sStr;
860} // end of wxNativeFontInfo::ToString
861
862// ----------------------------------------------------------------------------
863// wxFont
864// ----------------------------------------------------------------------------
19193a2c 865
6670f564
WS
866bool wxFont::Create( const wxNativeFontInfo& rInfo,
867 WXHFONT hFont )
cc95f4f9
DW
868{
869 UnRef();
870 m_refData = new wxFontRefData( rInfo
871 ,hFont
872 );
873 RealizeResource();
6670f564 874 return true;
cc95f4f9
DW
875} // end of wxFont::Create
876
877wxFont::wxFont(
878 const wxString& rsFontdesc
879)
880{
881 wxNativeFontInfo vInfo;
882
883 if (vInfo.FromString(rsFontdesc))
884 (void)Create(vInfo);
885} // end of wxFont::wxFont
0e320a79 886
e99762c0
DW
887// ----------------------------------------------------------------------------
888// Constructor for a font. Note that the real construction is done
889// in wxDC::SetFont, when information is available about scaling etc.
890// ----------------------------------------------------------------------------
6670f564 891bool wxFont::Create( int nPointSize,
0c14b6c3
FM
892 wxFontFamily nFamily,
893 wxFontStyle nStyle,
894 wxFontWeight nWeight,
6670f564
WS
895 bool bUnderlined,
896 const wxString& rsFaceName,
897 wxFontEncoding vEncoding )
0e320a79
DW
898{
899 UnRef();
cc95f4f9
DW
900
901 //
902 // wxDEFAULT is a valid value for the font size too so we must treat it
903 // specially here (otherwise the size would be 70 == wxDEFAULT value)
904 //
905 if (nPointSize == wxDEFAULT)
906 {
907 nPointSize = wxNORMAL_FONT->GetPointSize();
908 }
e99762c0
DW
909 m_refData = new wxFontRefData( nPointSize
910 ,nFamily
911 ,nStyle
912 ,nWeight
913 ,bUnderlined
914 ,rsFaceName
915 ,vEncoding
916 );
0e320a79 917 RealizeResource();
6670f564 918 return true;
e99762c0 919} // end of wxFont::Create
0e320a79
DW
920
921wxFont::~wxFont()
922{
e99762c0 923} // end of wxFont::~wxFont
0e320a79 924
21802234
DW
925// ----------------------------------------------------------------------------
926// real implementation
f6bcfd97 927// Boris' Kovalenko comments:
4c51a665 928// Because OS/2 fonts are associated with PS we cannot create the font
f6bcfd97 929// here, but we may check that font definition is true
21802234
DW
930// ----------------------------------------------------------------------------
931
4b3f61d1
SN
932wxGDIRefData *wxFont::CreateGDIRefData() const
933{
934 return new wxFontRefData();
935}
936
937wxGDIRefData *wxFont::CloneGDIRefData(const wxGDIRefData *data) const
938{
5c33522f 939 return new wxFontRefData(*static_cast<const wxFontRefData *>(data));
4b3f61d1
SN
940}
941
0e320a79
DW
942bool wxFont::RealizeResource()
943{
21802234
DW
944 if ( GetResourceHandle() )
945 {
6670f564 946 return true;
21802234 947 }
cc95f4f9 948 return M_FONTDATA->Alloc(this);
e99762c0 949} // end of wxFont::RealizeResource
21802234 950
6670f564 951bool wxFont::FreeResource( bool WXUNUSED(bForce) )
21802234 952{
e99762c0 953 if (GetResourceHandle())
21802234 954 {
cc95f4f9 955 M_FONTDATA->Free();
6670f564 956 return true;
21802234 957 }
6670f564 958 return false;
e99762c0 959} // end of wxFont::FreeResource
0e320a79 960
17b1d76b 961WXHANDLE wxFont::GetResourceHandle() const
5fd2b2c6
DW
962{
963 return GetHFONT();
e99762c0 964} // end of wxFont::GetResourceHandle
21802234 965
cc95f4f9
DW
966WXHFONT wxFont::GetHFONT() const
967{
968 return M_FONTDATA ? M_FONTDATA->GetHFONT() : 0;
969} // end of wxFont::GetHFONT
970
21802234
DW
971bool wxFont::IsFree() const
972{
cc95f4f9 973 return M_FONTDATA && (M_FONTDATA->GetHFONT() == 0);
e99762c0 974} // end of wxFont::IsFree
21802234 975
21802234
DW
976// ----------------------------------------------------------------------------
977// change font attribute: we recreate font when doing it
978// ----------------------------------------------------------------------------
979
e99762c0
DW
980void wxFont::SetPointSize(
981 int nPointSize
982)
0e320a79 983{
4b3f61d1 984 AllocExclusive();
0e320a79 985
cc95f4f9 986 M_FONTDATA->SetPointSize(nPointSize);
0e320a79
DW
987
988 RealizeResource();
e99762c0 989} // end of wxFont::SetPointSize
0e320a79 990
e99762c0 991void wxFont::SetFamily(
98ecc3aa 992 wxFontFamily nFamily
e99762c0 993)
0e320a79 994{
4b3f61d1 995 AllocExclusive();
0e320a79 996
cc95f4f9 997 M_FONTDATA->SetFamily(nFamily);
0e320a79
DW
998
999 RealizeResource();
e99762c0 1000} // end of wxFont::SetFamily
0e320a79 1001
e99762c0 1002void wxFont::SetStyle(
98ecc3aa 1003 wxFontStyle nStyle
e99762c0 1004)
0e320a79 1005{
4b3f61d1 1006 AllocExclusive();
0e320a79 1007
cc95f4f9 1008 M_FONTDATA->SetStyle(nStyle);
0e320a79
DW
1009
1010 RealizeResource();
e99762c0 1011} // end of wxFont::SetStyle
0e320a79 1012
e99762c0 1013void wxFont::SetWeight(
98ecc3aa 1014 wxFontWeight nWeight
e99762c0 1015)
0e320a79 1016{
4b3f61d1 1017 AllocExclusive();
0e320a79 1018
cc95f4f9 1019 M_FONTDATA->SetWeight(nWeight);
0e320a79
DW
1020
1021 RealizeResource();
e99762c0 1022} // end of wxFont::SetWeight
0e320a79 1023
85ab460e 1024bool wxFont::SetFaceName(
e99762c0
DW
1025 const wxString& rsFaceName
1026)
0e320a79 1027{
4b3f61d1 1028 AllocExclusive();
0e320a79 1029
85ab460e 1030 bool refdataok = M_FONTDATA->SetFaceName(rsFaceName);
0e320a79
DW
1031
1032 RealizeResource();
85ab460e
VZ
1033
1034 return refdataok && wxFontBase::SetFaceName(rsFaceName);
e99762c0 1035} // end of wxFont::SetFaceName
0e320a79 1036
e99762c0
DW
1037void wxFont::SetUnderlined(
1038 bool bUnderlined
1039)
0e320a79 1040{
4b3f61d1 1041 AllocExclusive();
0e320a79 1042
cc95f4f9 1043 M_FONTDATA->SetUnderlined(bUnderlined);
0e320a79
DW
1044
1045 RealizeResource();
e99762c0 1046} // end of wxFont::SetUnderlined
0e320a79 1047
e99762c0
DW
1048void wxFont::SetEncoding(
1049 wxFontEncoding vEncoding
1050)
0e320a79 1051{
4b3f61d1 1052 AllocExclusive();
21802234 1053
cc95f4f9 1054 M_FONTDATA->SetEncoding(vEncoding);
21802234
DW
1055
1056 RealizeResource();
e99762c0
DW
1057} // end of wxFont::SetEncoding
1058
9045ad9d 1059void wxFont::DoSetNativeFontInfo(
cc95f4f9 1060 const wxNativeFontInfo& rInfo
e99762c0
DW
1061)
1062{
4b3f61d1 1063 AllocExclusive();
e99762c0 1064
cc95f4f9 1065 FreeResource();
e99762c0 1066
cc95f4f9 1067 *M_FONTDATA = wxFontRefData(rInfo);
e99762c0 1068
cc95f4f9
DW
1069 RealizeResource();
1070}
0e320a79 1071
21802234
DW
1072// ----------------------------------------------------------------------------
1073// accessors
1074// ----------------------------------------------------------------------------
1075
1076int wxFont::GetPointSize() const
0e320a79 1077{
a1b806b9 1078 wxCHECK_MSG( IsOk(), 0, wxT("invalid font") );
7e99520b 1079
cc95f4f9 1080 return M_FONTDATA->GetPointSize();
e99762c0 1081} // end of wxFont::GetPointSize
0e320a79 1082
59b7da02 1083wxFontFamily wxFont::DoGetFamily() const
0e320a79 1084{
cc95f4f9 1085 return M_FONTDATA->GetFamily();
59b7da02 1086} // end of wxFont::DoGetFamily
21802234 1087
0c14b6c3 1088wxFontStyle wxFont::GetStyle() const
21802234 1089{
a1b806b9 1090 wxCHECK_MSG( IsOk(), wxFONTSTYLE_MAX, wxT("invalid font") );
cc95f4f9
DW
1091
1092 return M_FONTDATA->GetStyle();
e99762c0 1093} // end of wxFont::GetStyle
21802234 1094
0c14b6c3 1095wxFontWeight wxFont::GetWeight() const
21802234 1096{
a1b806b9 1097 wxCHECK_MSG( IsOk(), wxFONTWEIGHT_MAX, wxT("invalid font") );
cc95f4f9
DW
1098
1099 return M_FONTDATA->GetWeight();
21802234
DW
1100}
1101
1102bool wxFont::GetUnderlined() const
1103{
a1b806b9 1104 wxCHECK_MSG( IsOk(), false, wxT("invalid font") );
cc95f4f9
DW
1105
1106 return M_FONTDATA->GetUnderlined();
e99762c0 1107} // end of wxFont::GetUnderlined
21802234
DW
1108
1109wxString wxFont::GetFaceName() const
1110{
a1b806b9 1111 wxCHECK_MSG( IsOk(), wxEmptyString, wxT("invalid font") );
e99762c0 1112
cc95f4f9 1113 return M_FONTDATA->GetFaceName();
e99762c0 1114} // end of wxFont::GetFaceName
21802234
DW
1115
1116wxFontEncoding wxFont::GetEncoding() const
1117{
a1b806b9 1118 wxCHECK_MSG( IsOk(), wxFONTENCODING_DEFAULT, wxT("invalid font") );
e99762c0 1119
cc95f4f9
DW
1120 return M_FONTDATA->GetEncoding();
1121} // end of wxFont::GetEncoding
0e320a79 1122
3bf5a59b 1123const wxNativeFontInfo* wxFont::GetNativeFontInfo() const
cc95f4f9 1124{
3bf5a59b
VZ
1125 return M_FONTDATA->HasNativeFontInfo() ? &(M_FONTDATA->GetNativeFontInfo())
1126 : NULL;
cc95f4f9
DW
1127} // end of wxFont::GetNativeFontInfo
1128
1129//
1130// Internal use only method to set the FONTMETRICS array
1131//
48a1108e 1132void wxFont::SetFM( PFONTMETRICS pFM, int nNumFonts )
cc95f4f9
DW
1133{
1134 M_FONTDATA->SetFM(pFM);
1135 M_FONTDATA->SetNumFonts(nNumFonts);
1136} // end of wxFont::SetFM
e99762c0
DW
1137
1138
48a1108e 1139void wxFont::SetPS( HPS hPS )
d0a6b279 1140{
4b3f61d1 1141 AllocExclusive();
d0a6b279
DW
1142
1143 M_FONTDATA->SetPS(hPS);
1144
1145 RealizeResource();
47df2b8c 1146} // end of wxFont::SetPS