]> git.saurik.com Git - wxWidgets.git/blame - src/os2/font.cpp
don't compare invalid iterators/node pointers
[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
21802234
DW
23#ifndef WX_PRECOMP
24 #include <stdio.h>
21802234
DW
25 #include "wx/list.h"
26 #include "wx/utils.h"
27 #include "wx/app.h"
28 #include "wx/font.h"
6eb280e9 29 #include "wx/log.h"
21802234
DW
30#endif // WX_PRECOMP
31
32#include "wx/os2/private.h"
0e320a79 33
cc95f4f9
DW
34#include "wx/fontutil.h"
35#include "wx/fontmap.h"
bd6685b3 36#include "wx/encinfo.h"
cc95f4f9
DW
37
38#include "wx/tokenzr.h"
21802234 39
6670f564
WS
40#include <malloc.h>
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,
0fba44b4 54 wxEmptyString, wxFONTENCODING_DEFAULT);
21802234
DW
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 //
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;
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
6670f564 350 m_bNativeFontInfoOk = true;
cc95f4f9
DW
351 m_vNativeFontInfo = rInfo;
352
a23692f0 353 if (hPS == NULLHANDLE)
cc95f4f9
DW
354 {
355 m_hPS = ::WinGetPS(HWND_DESKTOP);
6670f564 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
6670f564 372bool wxFontRefData::Alloc( wxFont* pFont )
cc95f4f9
DW
373{
374 wxString sFaceName;
828621c2 375 long flId = m_hFont;
e1146627 376 long lRc;
d697657f
DW
377 ERRORID vError;
378 wxString sError;
cc95f4f9
DW
379
380 if (!m_bNativeFontInfoOk)
381 {
382 wxFillLogFont( &m_vNativeFontInfo.fa
383 ,&m_vNativeFontInfo.fn
54ffa107 384 ,&m_hPS
828621c2 385 ,&m_bInternalPS
cc95f4f9
DW
386 ,&flId
387 ,sFaceName
388 ,pFont
389 );
6670f564 390 m_bNativeFontInfoOk = true;
cc95f4f9 391 }
07df68c8
DW
392 else
393 {
394 if (flId == 0L)
395 flId = 1L;
396 else
397 flId++;
398 if (flId > 254)
399 flId = 1L;
400 }
e1146627
DW
401 if((lRc = ::GpiCreateLogFont( m_hPS
402 ,NULL
403 ,flId
404 ,&m_vNativeFontInfo.fa
405 )) != GPI_ERROR)
406 {
828621c2
DW
407 m_hFont = (WXHFONT)flId;
408 m_nFontId = flId;
e1146627 409 }
cc95f4f9
DW
410 if (!m_hFont)
411 {
d697657f
DW
412 vError = ::WinGetLastError(vHabmain);
413 sError = wxPMErrorToStr(vError);
2173b18f 414 wxLogLastError(wxT("CreateFont"));
cc95f4f9
DW
415 }
416
e1146627 417 ::GpiSetCharSet(m_hPS, flId); // sets font for presentation space
cc95f4f9
DW
418 ::GpiQueryFontMetrics(m_hPS, sizeof(FONTMETRICS), &m_vNativeFontInfo.fm);
419
420 //
421 // Set refData members with the results
422 //
cc95f4f9
DW
423 memcpy(&m_vFattrs, &m_vNativeFontInfo.fa, sizeof(m_vFattrs));
424 memcpy(&m_vFname, &m_vNativeFontInfo.fn, sizeof(m_vFname));
2c1e8f2e
DW
425 //
426 // Going to leave the point size alone. Mostly we use outline fonts
427 // that can be set to any point size inside of Presentation Parameters,
428 // regardless of whether or not the actual font is registered in the system.
429 // The GpiCreateLogFont will do enough by selecting the right family,
430 // and face name.
431 //
07df68c8 432 if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Times New Roman") == 0)
cc95f4f9 433 m_nFamily = wxROMAN;
07df68c8
DW
434 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Times New Roman MT 30") == 0)
435 m_nFamily = wxROMAN;
436 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "@Times New Roman MT 30") == 0)
437 m_nFamily = wxROMAN;
438 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Tms Rmn") == 0)
439 m_nFamily = wxROMAN;
440 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "WarpSans") == 0)
441 m_nFamily = wxDECORATIVE;
a4353f07 442 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Helvetica") == 0)
e1146627 443 m_nFamily = wxSWISS;
07df68c8 444 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Helv") == 0)
e1146627 445 m_nFamily = wxSWISS;
07df68c8 446 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Script") == 0)
cc95f4f9 447 m_nFamily = wxSCRIPT;
07df68c8 448 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Courier New") == 0)
e1146627 449 m_nFamily = wxTELETYPE;
07df68c8 450 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Courier") == 0)
e1146627 451 m_nFamily = wxTELETYPE;
07df68c8
DW
452 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "System Monospaced") == 0)
453 m_nFamily = wxTELETYPE;
454 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "System VIO") == 0)
1b75810c 455 m_nFamily = wxMODERN;
07df68c8
DW
456 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "System Proportional") == 0)
457 m_nFamily = wxMODERN;
458 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Arial") == 0)
a23692f0 459 m_nFamily = wxSWISS;
1b75810c
DW
460 else if (strcmp(m_vNativeFontInfo.fm.szFamilyname, "Swiss") == 0)
461 m_nFamily = wxSWISS;
cc95f4f9
DW
462 else
463 m_nFamily = wxSWISS;
464
465 if (m_vNativeFontInfo.fa.fsSelection & FATTR_SEL_ITALIC)
466 m_nStyle = wxFONTSTYLE_ITALIC;
467 else
468 m_nStyle = wxFONTSTYLE_NORMAL;
469 switch(m_vNativeFontInfo.fn.usWeightClass)
470 {
471 case FWEIGHT_DONT_CARE:
472 m_nWeight = wxFONTWEIGHT_NORMAL;
473 break;
474
475 case FWEIGHT_NORMAL:
476 m_nWeight = wxFONTWEIGHT_NORMAL;
477 break;
478
479 case FWEIGHT_LIGHT:
480 m_nWeight = wxFONTWEIGHT_LIGHT;
481 break;
482
483 case FWEIGHT_BOLD:
484 m_nWeight = wxFONTWEIGHT_BOLD;
485 break;
486
487 case FWEIGHT_ULTRA_BOLD:
488 m_nWeight = wxFONTWEIGHT_MAX;
489 break;
490
491 default:
492 m_nWeight = wxFONTWEIGHT_NORMAL;
493 }
494 m_bUnderlined = ((m_vNativeFontInfo.fa.fsSelection & FATTR_SEL_UNDERSCORE) != 0);
0fba44b4 495 m_sFaceName = (wxChar*)m_vNativeFontInfo.fa.szFacename;
cc95f4f9 496 m_vEncoding = wxGetFontEncFromCharSet(m_vNativeFontInfo.fa.usCodePage);
828621c2
DW
497
498 //
499 // We don't actuall keep the font around if using a temporary PS
500 //
501 if (m_bInternalPS)
502 {
503 if(m_hFont)
504 ::GpiDeleteSetId( m_hPS
505 ,flId
506 );
507
508 ::WinReleasePS(m_hPS);
509 }
510 else
511 //
512 // Select the font into the Presentation space
513 //
514 ::GpiSetCharSet(m_hPS, flId); // sets font for presentation space
6670f564 515 return true;
cc95f4f9
DW
516} // end of wxFontRefData::Alloc
517
518void wxFontRefData::Free()
0e320a79 519{
e99762c0
DW
520 if (m_pFM)
521 delete [] m_pFM;
522 m_pFM = (PFONTMETRICS)NULL;
cc95f4f9
DW
523
524 if ( m_hFont )
525 {
cc95f4f9
DW
526 ::GpiDeleteSetId(m_hPS, 1L); /* delete the logical font */
527 m_nFontId = 0;
528 m_hFont = 0;
529 }
530 if (m_bInternalPS)
531 ::WinReleasePS(m_hPS);
532 m_hPS = NULLHANDLE;
533} // end of wxFontRefData::Free
0e320a79 534
21802234 535// ----------------------------------------------------------------------------
cc95f4f9 536// wxNativeFontInfo
21802234 537// ----------------------------------------------------------------------------
0e320a79 538
cc95f4f9
DW
539void wxNativeFontInfo::Init()
540{
541 memset(&fa, '\0', sizeof(FATTRS));
542} // end of wxNativeFontInfo::Init
543
544int wxNativeFontInfo::GetPointSize() const
545{
546 return fm.lEmHeight;
547} // end of wxNativeFontInfo::GetPointSize
548
549wxFontStyle wxNativeFontInfo::GetStyle() const
550{
551 return fa.fsSelection & FATTR_SEL_ITALIC ? wxFONTSTYLE_ITALIC : wxFONTSTYLE_NORMAL;
552} // end of wxNativeFontInfo::GetStyle
553
554wxFontWeight wxNativeFontInfo::GetWeight() const
555{
556 switch(fn.usWeightClass)
19193a2c 557 {
cc95f4f9
DW
558 case FWEIGHT_DONT_CARE:
559 return wxFONTWEIGHT_NORMAL;
560
561 case FWEIGHT_NORMAL:
562 return wxFONTWEIGHT_NORMAL;
19193a2c 563
cc95f4f9
DW
564 case FWEIGHT_LIGHT:
565 return wxFONTWEIGHT_LIGHT;
566
567 case FWEIGHT_BOLD:
568 return wxFONTWEIGHT_BOLD;
569
570 case FWEIGHT_ULTRA_BOLD:
571 return wxFONTWEIGHT_MAX;
19193a2c 572 }
cc95f4f9
DW
573 return wxFONTWEIGHT_NORMAL;
574} // end of wxNativeFontInfo::GetWeight
19193a2c 575
cc95f4f9
DW
576bool wxNativeFontInfo::GetUnderlined() const
577{
578 return ((fa.fsSelection & FATTR_SEL_UNDERSCORE) != 0);
579} // end of wxNativeFontInfo::GetUnderlined
580
581wxString wxNativeFontInfo::GetFaceName() const
582{
0fba44b4 583 return (wxChar*)fm.szFacename;
cc95f4f9
DW
584} // end of wxNativeFontInfo::GetFaceName
585
586wxFontFamily wxNativeFontInfo::GetFamily() const
587{
588 int nFamily;
589
590 //
591 // Extract family from facename
592 //
07df68c8
DW
593 if (strcmp(fm.szFamilyname, "Times New Roman") == 0)
594 nFamily = wxROMAN;
595 else if (strcmp(fm.szFamilyname, "Times New Roman MT 30") == 0)
596 nFamily = wxROMAN;
597 else if (strcmp(fm.szFamilyname, "@Times New Roman MT 30") == 0)
cc95f4f9 598 nFamily = wxROMAN;
07df68c8
DW
599 else if (strcmp(fm.szFamilyname, "Tms Rmn") == 0)
600 nFamily = wxROMAN;
601 else if (strcmp(fm.szFamilyname, "WarpSans") == 0)
602 nFamily = wxDECORATIVE;
a4353f07 603 else if (strcmp(fm.szFamilyname, "Helvetica") == 0)
07df68c8
DW
604 nFamily = wxSWISS;
605 else if (strcmp(fm.szFamilyname, "Helv") == 0)
cc95f4f9 606 nFamily = wxSWISS;
07df68c8 607 else if (strcmp(fm.szFamilyname, "Script") == 0)
cc95f4f9 608 nFamily = wxSCRIPT;
07df68c8
DW
609 else if (strcmp(fm.szFamilyname, "Courier New") == 0)
610 nFamily = wxTELETYPE;
611 else if (strcmp(fm.szFamilyname, "Courier") == 0)
612 nFamily = wxTELETYPE;
613 else if (strcmp(fm.szFamilyname, "System Monospaced") == 0)
614 nFamily = wxTELETYPE;
615 else if (strcmp(fm.szFamilyname, "System VIO") == 0)
1b75810c 616 nFamily = wxMODERN;
07df68c8
DW
617 else if (strcmp(fm.szFamilyname, "System Proportional") == 0)
618 nFamily = wxMODERN;
619 else if (strcmp(fm.szFamilyname, "Arial") == 0)
a23692f0 620 nFamily = wxSWISS;
1b75810c
DW
621 else if (strcmp(fm.szFamilyname, "Swiss") == 0)
622 nFamily = wxSWISS;
cc95f4f9
DW
623 else
624 nFamily = wxSWISS;
625 return (wxFontFamily)nFamily;
626} // end of wxNativeFontInfo::GetFamily
627
628wxFontEncoding wxNativeFontInfo::GetEncoding() const
629{
630 return wxGetFontEncFromCharSet(fa.usCodePage);
631} // end of wxNativeFontInfo::GetEncoding
632
633void wxNativeFontInfo::SetPointSize(
634 int nPointsize
635)
636{
637 fm.lEmHeight = (LONG)nPointsize;
638} // end of wxNativeFontInfo::SetPointSize
639
640void wxNativeFontInfo::SetStyle(
641 wxFontStyle eStyle
642)
643{
644 switch (eStyle)
645 {
646 default:
647 wxFAIL_MSG( _T("unknown font style") );
648 // fall through
649
650 case wxFONTSTYLE_NORMAL:
651 break;
652
653 case wxFONTSTYLE_ITALIC:
654 case wxFONTSTYLE_SLANT:
655 fa.fsSelection |= FATTR_SEL_ITALIC;
656 break;
657 }
658} // end of wxNativeFontInfo::SetStyle
659
660void wxNativeFontInfo::SetWeight(
661 wxFontWeight eWeight
662)
663{
664 switch (eWeight)
665 {
666 default:
667 wxFAIL_MSG( _T("unknown font weight") );
668 // fall through
669
670 case wxFONTWEIGHT_NORMAL:
671 fn.usWeightClass = FWEIGHT_NORMAL;
672 break;
673
674 case wxFONTWEIGHT_LIGHT:
675 fn.usWeightClass = FWEIGHT_LIGHT;
676 break;
677
678 case wxFONTWEIGHT_BOLD:
679 fn.usWeightClass = FWEIGHT_BOLD;
680 break;
681 }
682} // end of wxNativeFontInfo::SetWeight
683
684void wxNativeFontInfo::SetUnderlined(
685 bool bUnderlined
686)
687{
688 if(bUnderlined)
689 fa.fsSelection |= FATTR_SEL_UNDERSCORE;
690} // end of wxNativeFontInfo::SetUnderlined
691
692void wxNativeFontInfo::SetFaceName(
fbfb8bcc 693 const wxString& sFacename
cc95f4f9
DW
694)
695{
0fba44b4 696 wxStrncpy((wxChar*)fa.szFacename, sFacename, WXSIZEOF(fa.szFacename));
cc95f4f9
DW
697} // end of wxNativeFontInfo::SetFaceName
698
699void wxNativeFontInfo::SetFamily(
700 wxFontFamily eFamily
701)
702{
703 wxString sFacename;
704
705 switch (eFamily)
706 {
707 case wxSCRIPT:
1b75810c 708 sFacename = wxT("Tms Rmn");
cc95f4f9
DW
709 break;
710
711 case wxDECORATIVE:
07df68c8 712 sFacename = wxT("WarpSans");
cc95f4f9
DW
713 break;
714
715 case wxROMAN:
1b75810c 716 sFacename = wxT("Tms Rmn");
cc95f4f9
DW
717 break;
718
719 case wxTELETYPE:
1b75810c 720 sFacename = wxT("Courier") ;
07df68c8
DW
721 break;
722
cc95f4f9 723 case wxMODERN:
1b75810c 724 sFacename = wxT("System VIO") ;
cc95f4f9
DW
725 break;
726
727 case wxSWISS:
07df68c8 728 sFacename = wxT("Helv") ;
cc95f4f9
DW
729 break;
730
731 case wxDEFAULT:
732 default:
a23692f0 733 sFacename = wxT("System VIO") ;
cc95f4f9
DW
734 }
735
0fba44b4 736 if (!wxStrlen((wxChar*)fa.szFacename) )
cc95f4f9
DW
737 {
738 SetFaceName(sFacename);
739 }
740} // end of wxNativeFontInfo::SetFamily
741
6670f564 742void wxNativeFontInfo::SetEncoding( wxFontEncoding eEncoding )
cc95f4f9
DW
743{
744 wxNativeEncodingInfo vInfo;
745
746 if ( !wxGetNativeFontEncoding( eEncoding
747 ,&vInfo
748 ))
749 {
142b3bc2 750 if (wxFontMapper::Get()->GetAltForEncoding( eEncoding
cc95f4f9
DW
751 ,&vInfo
752 ))
753 {
754 if (!vInfo.facename.empty())
755 {
756 //
757 // If we have this encoding only in some particular facename, use
758 // the facename - it is better to show the correct characters in a
759 // wrong facename than unreadable text in a correct one
760 //
761 SetFaceName(vInfo.facename);
762 }
763 }
764 else
cc95f4f9
DW
765 {
766 // unsupported encoding, replace with the default
767 vInfo.charset = 850;
768 }
769 }
6670f564 770 fa.usCodePage = (USHORT)vInfo.charset;
cc95f4f9
DW
771} // end of wxNativeFontInfo::SetFaceName
772
6670f564 773bool wxNativeFontInfo::FromString( const wxString& rsStr )
cc95f4f9
DW
774{
775 long lVal;
776
777 wxStringTokenizer vTokenizer(rsStr, _T(";"));
778
779 //
780 // First the version
781 //
782 wxString sToken = vTokenizer.GetNextToken();
783
784 if (sToken != _T('0'))
785 return FALSE;
786
787 sToken = vTokenizer.GetNextToken();
788 if (!sToken.ToLong(&lVal))
789 return FALSE;
790 fm.lEmHeight = lVal;
791
792 sToken = vTokenizer.GetNextToken();
793 if (!sToken.ToLong(&lVal))
794 return FALSE;
795 fa.lAveCharWidth = lVal;
796
797 sToken = vTokenizer.GetNextToken();
798 if (!sToken.ToLong(&lVal))
799 return FALSE;
800 fa.fsSelection = (USHORT)lVal;
801
802 sToken = vTokenizer.GetNextToken();
803 if (!sToken.ToLong(&lVal))
804 return FALSE;
805 fa.fsType = (USHORT)lVal;
806
807 sToken = vTokenizer.GetNextToken();
808 if (!sToken.ToLong(&lVal))
809 return FALSE;
810 fa.fsFontUse = (USHORT)lVal;
811
812 sToken = vTokenizer.GetNextToken();
813 if (!sToken.ToLong(&lVal))
814 return FALSE;
815 fa.idRegistry = (USHORT)lVal;
816
817 sToken = vTokenizer.GetNextToken();
818 if (!sToken.ToLong(&lVal))
819 return FALSE;
820 fa.usCodePage = (USHORT)lVal;
821
822 sToken = vTokenizer.GetNextToken();
823 if (!sToken.ToLong(&lVal))
824 return FALSE;
825 fa.lMatch = lVal;
826
827 sToken = vTokenizer.GetNextToken();
828 if (!sToken.ToLong(&lVal))
829 return FALSE;
830 fn.usWeightClass = (USHORT)lVal;
831
832 sToken = vTokenizer.GetNextToken();
833 if(!sToken)
834 return FALSE;
0fba44b4 835 wxStrcpy((wxChar*)fa.szFacename, sToken.c_str());
6670f564 836 return true;
cc95f4f9
DW
837} // end of wxNativeFontInfo::FromString
838
839wxString wxNativeFontInfo::ToString() const
840{
841 wxString sStr;
842
843 sStr.Printf(_T("%d;%ld;%ld;%ld;%d;%d;%d;%d;%d;%ld;%d;%s"),
844 0, // version, in case we want to change the format later
845 fm.lEmHeight,
846 fa.lAveCharWidth,
847 fa.lMaxBaselineExt,
848 fa.fsSelection,
849 fa.fsType,
850 fa.fsFontUse,
851 fa.idRegistry,
852 fa.usCodePage,
853 fa.lMatch,
854 fn.usWeightClass,
855 fa.szFacename);
856 return sStr;
857} // end of wxNativeFontInfo::ToString
858
859// ----------------------------------------------------------------------------
860// wxFont
861// ----------------------------------------------------------------------------
19193a2c 862
6670f564
WS
863bool wxFont::Create( const wxNativeFontInfo& rInfo,
864 WXHFONT hFont )
cc95f4f9
DW
865{
866 UnRef();
867 m_refData = new wxFontRefData( rInfo
868 ,hFont
869 );
870 RealizeResource();
6670f564 871 return true;
cc95f4f9
DW
872} // end of wxFont::Create
873
874wxFont::wxFont(
875 const wxString& rsFontdesc
876)
877{
878 wxNativeFontInfo vInfo;
879
880 if (vInfo.FromString(rsFontdesc))
881 (void)Create(vInfo);
882} // end of wxFont::wxFont
0e320a79 883
e99762c0
DW
884// ----------------------------------------------------------------------------
885// Constructor for a font. Note that the real construction is done
886// in wxDC::SetFont, when information is available about scaling etc.
887// ----------------------------------------------------------------------------
6670f564
WS
888bool wxFont::Create( int nPointSize,
889 int nFamily,
890 int nStyle,
891 int nWeight,
892 bool bUnderlined,
893 const wxString& rsFaceName,
894 wxFontEncoding vEncoding )
0e320a79
DW
895{
896 UnRef();
cc95f4f9
DW
897
898 //
899 // wxDEFAULT is a valid value for the font size too so we must treat it
900 // specially here (otherwise the size would be 70 == wxDEFAULT value)
901 //
902 if (nPointSize == wxDEFAULT)
903 {
904 nPointSize = wxNORMAL_FONT->GetPointSize();
905 }
e99762c0
DW
906 m_refData = new wxFontRefData( nPointSize
907 ,nFamily
908 ,nStyle
909 ,nWeight
910 ,bUnderlined
911 ,rsFaceName
912 ,vEncoding
913 );
0e320a79 914 RealizeResource();
6670f564 915 return true;
e99762c0 916} // end of wxFont::Create
0e320a79
DW
917
918wxFont::~wxFont()
919{
e99762c0 920} // end of wxFont::~wxFont
0e320a79 921
21802234
DW
922// ----------------------------------------------------------------------------
923// real implementation
f6bcfd97
BP
924// Boris' Kovalenko comments:
925// Because OS/2 fonts are associated with PS we can not create the font
926// here, but we may check that font definition is true
21802234
DW
927// ----------------------------------------------------------------------------
928
0e320a79
DW
929bool wxFont::RealizeResource()
930{
21802234
DW
931 if ( GetResourceHandle() )
932 {
6670f564 933 return true;
21802234 934 }
cc95f4f9 935 return M_FONTDATA->Alloc(this);
e99762c0 936} // end of wxFont::RealizeResource
21802234 937
6670f564 938bool wxFont::FreeResource( bool WXUNUSED(bForce) )
21802234 939{
e99762c0 940 if (GetResourceHandle())
21802234 941 {
cc95f4f9 942 M_FONTDATA->Free();
6670f564 943 return true;
21802234 944 }
6670f564 945 return false;
e99762c0 946} // end of wxFont::FreeResource
0e320a79 947
5fd2b2c6
DW
948WXHANDLE wxFont::GetResourceHandle()
949{
950 return GetHFONT();
e99762c0 951} // end of wxFont::GetResourceHandle
21802234 952
cc95f4f9
DW
953WXHFONT wxFont::GetHFONT() const
954{
955 return M_FONTDATA ? M_FONTDATA->GetHFONT() : 0;
956} // end of wxFont::GetHFONT
957
21802234
DW
958bool wxFont::IsFree() const
959{
cc95f4f9 960 return M_FONTDATA && (M_FONTDATA->GetHFONT() == 0);
e99762c0 961} // end of wxFont::IsFree
21802234 962
0e320a79
DW
963void wxFont::Unshare()
964{
21802234
DW
965 // Don't change shared data
966 if ( !m_refData )
0e320a79 967 {
21802234
DW
968 m_refData = new wxFontRefData();
969 }
0e320a79
DW
970 else
971 {
21802234
DW
972 wxFontRefData* ref = new wxFontRefData(*M_FONTDATA);
973 UnRef();
974 m_refData = ref;
975 }
e99762c0 976} // end of wxFont::Unshare
0e320a79 977
21802234
DW
978// ----------------------------------------------------------------------------
979// change font attribute: we recreate font when doing it
980// ----------------------------------------------------------------------------
981
e99762c0
DW
982void wxFont::SetPointSize(
983 int nPointSize
984)
0e320a79
DW
985{
986 Unshare();
987
cc95f4f9 988 M_FONTDATA->SetPointSize(nPointSize);
0e320a79
DW
989
990 RealizeResource();
e99762c0 991} // end of wxFont::SetPointSize
0e320a79 992
e99762c0
DW
993void wxFont::SetFamily(
994 int nFamily
995)
0e320a79
DW
996{
997 Unshare();
998
cc95f4f9 999 M_FONTDATA->SetFamily(nFamily);
0e320a79
DW
1000
1001 RealizeResource();
e99762c0 1002} // end of wxFont::SetFamily
0e320a79 1003
e99762c0
DW
1004void wxFont::SetStyle(
1005 int nStyle
1006)
0e320a79
DW
1007{
1008 Unshare();
1009
cc95f4f9 1010 M_FONTDATA->SetStyle(nStyle);
0e320a79
DW
1011
1012 RealizeResource();
e99762c0 1013} // end of wxFont::SetStyle
0e320a79 1014
e99762c0
DW
1015void wxFont::SetWeight(
1016 int nWeight
1017)
0e320a79
DW
1018{
1019 Unshare();
1020
cc95f4f9 1021 M_FONTDATA->SetWeight(nWeight);
0e320a79
DW
1022
1023 RealizeResource();
e99762c0 1024} // end of wxFont::SetWeight
0e320a79 1025
e99762c0
DW
1026void wxFont::SetFaceName(
1027 const wxString& rsFaceName
1028)
0e320a79
DW
1029{
1030 Unshare();
1031
cc95f4f9 1032 M_FONTDATA->SetFaceName(rsFaceName);
0e320a79
DW
1033
1034 RealizeResource();
e99762c0 1035} // end of wxFont::SetFaceName
0e320a79 1036
e99762c0
DW
1037void wxFont::SetUnderlined(
1038 bool bUnderlined
1039)
0e320a79
DW
1040{
1041 Unshare();
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{
21802234
DW
1052 Unshare();
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{
1063 Unshare();
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{
cc95f4f9 1078 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
7e99520b 1079
cc95f4f9 1080 return M_FONTDATA->GetPointSize();
e99762c0 1081} // end of wxFont::GetPointSize
0e320a79 1082
21802234 1083int wxFont::GetFamily() const
0e320a79 1084{
cc95f4f9 1085 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
21802234 1086
cc95f4f9
DW
1087 return M_FONTDATA->GetFamily();
1088} // end of wxFont::GetFamily
21802234
DW
1089
1090int wxFont::GetStyle() const
1091{
cc95f4f9
DW
1092 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
1093
1094 return M_FONTDATA->GetStyle();
e99762c0 1095} // end of wxFont::GetStyle
21802234
DW
1096
1097int wxFont::GetWeight() const
1098{
cc95f4f9
DW
1099 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
1100
1101 return M_FONTDATA->GetWeight();
21802234
DW
1102}
1103
1104bool wxFont::GetUnderlined() const
1105{
cc95f4f9
DW
1106 wxCHECK_MSG( Ok(), FALSE, wxT("invalid font") );
1107
1108 return M_FONTDATA->GetUnderlined();
e99762c0 1109} // end of wxFont::GetUnderlined
21802234
DW
1110
1111wxString wxFont::GetFaceName() const
1112{
521bf4ff 1113 wxCHECK_MSG( Ok(), wxEmptyString, wxT("invalid font") );
e99762c0 1114
cc95f4f9 1115 return M_FONTDATA->GetFaceName();
e99762c0 1116} // end of wxFont::GetFaceName
21802234
DW
1117
1118wxFontEncoding wxFont::GetEncoding() const
1119{
cc95f4f9 1120 wxCHECK_MSG( Ok(), wxFONTENCODING_DEFAULT, wxT("invalid font") );
e99762c0 1121
cc95f4f9
DW
1122 return M_FONTDATA->GetEncoding();
1123} // end of wxFont::GetEncoding
0e320a79 1124
3bf5a59b 1125const wxNativeFontInfo* wxFont::GetNativeFontInfo() const
cc95f4f9 1126{
3bf5a59b
VZ
1127 return M_FONTDATA->HasNativeFontInfo() ? &(M_FONTDATA->GetNativeFontInfo())
1128 : NULL;
cc95f4f9
DW
1129} // end of wxFont::GetNativeFontInfo
1130
1131//
1132// Internal use only method to set the FONTMETRICS array
1133//
1134void wxFont::SetFM(
1135 PFONTMETRICS pFM
1136, int nNumFonts
1137)
1138{
1139 M_FONTDATA->SetFM(pFM);
1140 M_FONTDATA->SetNumFonts(nNumFonts);
1141} // end of wxFont::SetFM
e99762c0
DW
1142
1143
d0a6b279
DW
1144void wxFont::SetPS(
1145 HPS hPS
1146)
1147{
1148 Unshare();
1149
1150 M_FONTDATA->SetPS(hPS);
1151
1152 RealizeResource();
47df2b8c 1153} // end of wxFont::SetPS