]> git.saurik.com Git - wxWidgets.git/blame - src/os2/font.cpp
Fixed blatant non-initialisation bug
[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
20// For compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
0e320a79 22
21802234
DW
23#ifndef WX_PRECOMP
24 #include <stdio.h>
25 #include "wx/setup.h"
26 #include "wx/list.h"
27 #include "wx/utils.h"
28 #include "wx/app.h"
29 #include "wx/font.h"
30#endif // WX_PRECOMP
31
32#include "wx/os2/private.h"
0e320a79 33
21802234
DW
34 IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
35
36 #if wxUSE_PORTABLE_FONTS_IN_MSW
37 IMPLEMENT_DYNAMIC_CLASS(wxFontNameDirectory, wxObject)
38 #endif
0e320a79 39
21802234
DW
40// ----------------------------------------------------------------------------
41// wxFontRefData - the internal description of the font
42// ----------------------------------------------------------------------------
43
44class WXDLLEXPORT wxFontRefData: public wxGDIRefData
0e320a79 45{
21802234
DW
46friend class WXDLLEXPORT wxFont;
47
48public:
49 wxFontRefData()
50 {
51 Init(12, wxDEFAULT, wxNORMAL, wxNORMAL, FALSE,
52 "", wxFONTENCODING_DEFAULT);
53 }
54
55 wxFontRefData(const wxFontRefData& data)
56 {
57 Init(data.m_pointSize, data.m_family, data.m_style, data.m_weight,
58 data.m_underlined, data.m_faceName, data.m_encoding);
59
60 m_fontId = data.m_fontId;
61 }
62
63 wxFontRefData(int size,
64 int family,
65 int style,
66 int weight,
67 bool underlined,
68 const wxString& faceName,
69 wxFontEncoding encoding)
70 {
71 Init(size, family, style, weight, underlined, faceName, encoding);
72 }
0e320a79 73
21802234
DW
74 virtual ~wxFontRefData();
75
76protected:
77 // common part of all ctors
78 void Init(int size,
79 int family,
80 int style,
81 int weight,
82 bool underlined,
83 const wxString& faceName,
84 wxFontEncoding encoding);
85
86 // If TRUE, the pointer to the actual font is temporary and SHOULD NOT BE
87 // DELETED by destructor
88 bool m_temporary;
89
90 int m_fontId;
91
92 // font characterstics
93 int m_pointSize;
94 int m_family;
95 int m_style;
96 int m_weight;
97 bool m_underlined;
98 wxString m_faceName;
99 wxFontEncoding m_encoding;
100
101 // Windows font handle
102 WXHFONT m_hFont;
103};
104
105// ============================================================================
106// implementation
107// ============================================================================
108
109// ----------------------------------------------------------------------------
110// wxFontRefData
111// ----------------------------------------------------------------------------
112
113void wxFontRefData::Init(int pointSize,
114 int family,
115 int style,
116 int weight,
117 bool underlined,
118 const wxString& faceName,
119 wxFontEncoding encoding)
0e320a79 120{
21802234
DW
121 m_style = style;
122 m_pointSize = pointSize;
123 m_family = family;
124 m_style = style;
125 m_weight = weight;
126 m_underlined = underlined;
127 m_faceName = faceName;
128 m_encoding = encoding;
129
130 m_fontId = 0;
131 m_temporary = FALSE;
132
133 m_hFont = 0;
0e320a79
DW
134}
135
136wxFontRefData::~wxFontRefData()
137{
21802234
DW
138// TODO:
139// if ( m_hFont )
140// {
141// if ( !::DeleteObject((HFONT) m_hFont) )
142// {
143// wxLogLastError("DeleteObject(font)");
144// }
145// }
0e320a79
DW
146}
147
21802234
DW
148// ----------------------------------------------------------------------------
149// wxFont
150// ----------------------------------------------------------------------------
0e320a79 151
21802234 152void wxFont::Init()
0e320a79 153{
0e320a79
DW
154 if ( wxTheFontList )
155 wxTheFontList->Append(this);
156}
157
21802234
DW
158/* Constructor for a font. Note that the real construction is done
159 * in wxDC::SetFont, when information is available about scaling etc.
160 */
161bool wxFont::Create(int pointSize,
162 int family,
163 int style,
164 int weight,
165 bool underlined,
166 const wxString& faceName,
167 wxFontEncoding encoding)
0e320a79
DW
168{
169 UnRef();
21802234
DW
170 m_refData = new wxFontRefData(pointSize, family, style, weight,
171 underlined, faceName, encoding);
0e320a79
DW
172
173 RealizeResource();
174
175 return TRUE;
176}
177
178wxFont::~wxFont()
179{
21802234 180 if ( wxTheFontList )
0e320a79
DW
181 wxTheFontList->DeleteObject(this);
182}
183
21802234
DW
184// ----------------------------------------------------------------------------
185// real implementation
186// ----------------------------------------------------------------------------
187
0e320a79
DW
188bool wxFont::RealizeResource()
189{
21802234
DW
190 if ( GetResourceHandle() )
191 {
192 // VZ: the old code returned FALSE in this case, but it doesn't seem
193 // to make sense because the font _was_ created
223d09f6 194 wxLogDebug(wxT("Calling wxFont::RealizeResource() twice"));
21802234
DW
195
196 return TRUE;
197 }
198
199 int ff_family = 0;
200 wxString ff_face;
201
202// OS/2 combines the family with styles to give a facename
203
204 switch ( M_FONTDATA->m_family )
205 {
206 case wxSCRIPT:
207// ff_family = FF_SCRIPT ;
223d09f6 208 ff_face = wxT("Script") ;
21802234
DW
209 break ;
210
211 case wxDECORATIVE:
212// ff_family = FF_DECORATIVE;
213 break;
214
215 case wxROMAN:
216// ff_family = FF_ROMAN;
223d09f6 217 ff_face = wxT("Times New Roman") ;
21802234
DW
218 break;
219
220 case wxTELETYPE:
221 case wxMODERN:
222// ff_family = FF_MODERN;
223d09f6 223 ff_face = wxT("Courier New") ;
21802234
DW
224 break;
225
226 case wxSWISS:
227// ff_family = FF_SWISS;
223d09f6 228 ff_face = wxT("Arial") ;
21802234
DW
229 break;
230
231 case wxDEFAULT:
232 default:
233// ff_family = FF_SWISS;
223d09f6 234 ff_face = wxT("Arial") ;
21802234
DW
235 }
236
237 BYTE ff_italic;
238 switch ( M_FONTDATA->m_style )
239 {
240 case wxITALIC:
241 case wxSLANT:
242 ff_italic = 1;
243 break;
244
245 default:
223d09f6 246 wxFAIL_MSG(wxT("unknown font slant"));
21802234
DW
247 // fall through
248
249 case wxNORMAL:
250 ff_italic = 0;
251 }
252
253 int ff_weight = 0;
254 switch ( M_FONTDATA->m_weight )
255 {
256 default:
223d09f6 257 wxFAIL_MSG(wxT("unknown font weight"));
21802234
DW
258 // fall through
259
260 case wxNORMAL:
261// ff_weight = FW_NORMAL;
262 break;
263
264 case wxLIGHT:
265// ff_weight = FW_LIGHT;
266 break;
267
268 case wxBOLD:
269// ff_weight = FW_BOLD;
270 break;
271 }
272
273 const wxChar* pzFace;
274 if ( M_FONTDATA->m_faceName.IsEmpty() )
275 pzFace = ff_face;
276 else
277 pzFace = M_FONTDATA->m_faceName ;
278
279#if 0
280 /* Always calculate fonts using the screen DC (is this the best strategy?)
281 * There may be confusion if a font is selected into a printer
282 * DC (say), because the height will be calculated very differently.
283 */
284 // What sort of display is it?
285 int technology = ::GetDeviceCaps(dc, TECHNOLOGY);
286
287 int nHeight;
288
289 if (technology != DT_RASDISPLAY && technology != DT_RASPRINTER)
290 {
291 // Have to get screen DC Caps, because a metafile will return 0.
292 HDC dc2 = ::GetDC(NULL);
293 nHeight = M_FONTDATA->m_pointSize*GetDeviceCaps(dc2, LOGPIXELSY)/72;
294 ::ReleaseDC(NULL, dc2);
295 }
296 else
297 {
298 nHeight = M_FONTDATA->m_pointSize*GetDeviceCaps(dc, LOGPIXELSY)/72;
299 }
300#endif // 0
301
302#if 0
303 // Have to get screen DC Caps, because a metafile will return 0.
304 HDC dc2 = ::GetDC(NULL);
305 ppInch = ::GetDeviceCaps(dc2, LOGPIXELSY);
306 ::ReleaseDC(NULL, dc2);
307#endif // 0
308
309 // New behaviour: apparently ppInch varies according to Large/Small Fonts
310 // setting in Windows. This messes up fonts. So, set ppInch to a constant
311 // 96 dpi.
312 static const int ppInch = 96;
313
314#if wxFONT_SIZE_COMPATIBILITY
315 // Incorrect, but compatible with old wxWindows behaviour
316 int nHeight = (M_FONTDATA->m_pointSize*ppInch/72);
317#else
318 // Correct for Windows compatibility
319 int nHeight = - (M_FONTDATA->m_pointSize*ppInch/72);
320#endif
321
322 BYTE ff_underline = M_FONTDATA->m_underlined;
323
324 wxFontEncoding encoding = M_FONTDATA->m_encoding;
325 if ( encoding == wxFONTENCODING_DEFAULT )
326 {
327 encoding = wxFont::GetDefaultEncoding();
328 }
329
330 DWORD charset;
331 switch ( encoding )
332 {
333 case wxFONTENCODING_ISO8859_1:
334 case wxFONTENCODING_ISO8859_15:
335 case wxFONTENCODING_CP1250:
336// charset = ANSI_CHARSET;
337 break;
338
339 case wxFONTENCODING_ISO8859_2:
340 case wxFONTENCODING_CP1252:
341// charset = EASTEUROPE_CHARSET;
342 break;
343
344 case wxFONTENCODING_ISO8859_4:
345 case wxFONTENCODING_ISO8859_10:
346// charset = BALTIC_CHARSET;
347 break;
348
349 case wxFONTENCODING_ISO8859_5:
350 case wxFONTENCODING_CP1251:
351// charset = RUSSIAN_CHARSET;
352 break;
353
354 case wxFONTENCODING_ISO8859_6:
355// charset = ARABIC_CHARSET;
356 break;
357
358 case wxFONTENCODING_ISO8859_7:
359// charset = GREEK_CHARSET;
360 break;
361
362 case wxFONTENCODING_ISO8859_8:
363// charset = HEBREW_CHARSET;
364 break;
365
366 case wxFONTENCODING_ISO8859_9:
367// charset = TURKISH_CHARSET;
368 break;
369
370 case wxFONTENCODING_ISO8859_11:
371// charset = THAI_CHARSET;
372 break;
373
374 case wxFONTENCODING_CP437:
375// charset = OEM_CHARSET;
376 break;
377
378 default:
223d09f6 379 wxFAIL_MSG(wxT("unsupported encoding"));
21802234
DW
380 // fall through
381
382 case wxFONTENCODING_SYSTEM:
383// charset = ANSI_CHARSET;
384 break;
385 }
386
387// TODO:
9dea36ef 388WXHFONT hFont = 0;
21802234
DW
389// HFONT hFont = ::CreateFont
390// (
391// nHeight, // height
392// 0, // width (choose best)
393// 0, // escapement
394// 0, // orientation
395// ff_weight, // weight
396// ff_italic, // italic?
397// ff_underline, // underlined?
398// 0, // strikeout?
399// charset, // charset
400// OUT_DEFAULT_PRECIS, // precision
401// CLIP_DEFAULT_PRECIS, // clip precision
402// PROOF_QUALITY, // quality of match
403// DEFAULT_PITCH | // fixed or variable
404// ff_family, // family id
405// pzFace // face name
406// );
407
408 M_FONTDATA->m_hFont = (WXHFONT)hFont;
409 if ( !hFont )
410 {
411 wxLogLastError("CreateFont");
412 }
413
414 return hFont != 0;
415}
416
417bool wxFont::FreeResource(bool force)
418{
419 if ( GetResourceHandle() )
420 {
421// TODO:
422// if ( !::DeleteObject((HFONT) M_FONTDATA->m_hFont) )
423// {
424// wxLogLastError("DeleteObject(font)");
425// }
426
427 M_FONTDATA->m_hFont = 0;
428
429 return TRUE;
430 }
0e320a79
DW
431 return FALSE;
432}
433
21802234
DW
434WXHANDLE wxFont::GetResourceHandle()
435{
436 if ( !M_FONTDATA )
437 return 0;
438 else
439 return (WXHANDLE)M_FONTDATA->m_hFont ;
440}
441
442bool wxFont::IsFree() const
443{
444 return (M_FONTDATA && (M_FONTDATA->m_hFont == 0));
445}
446
0e320a79
DW
447void wxFont::Unshare()
448{
21802234
DW
449 // Don't change shared data
450 if ( !m_refData )
0e320a79 451 {
21802234
DW
452 m_refData = new wxFontRefData();
453 }
0e320a79
DW
454 else
455 {
21802234
DW
456 wxFontRefData* ref = new wxFontRefData(*M_FONTDATA);
457 UnRef();
458 m_refData = ref;
459 }
0e320a79
DW
460}
461
21802234
DW
462// ----------------------------------------------------------------------------
463// change font attribute: we recreate font when doing it
464// ----------------------------------------------------------------------------
465
0e320a79
DW
466void wxFont::SetPointSize(int pointSize)
467{
468 Unshare();
469
470 M_FONTDATA->m_pointSize = pointSize;
471
472 RealizeResource();
473}
474
475void wxFont::SetFamily(int family)
476{
477 Unshare();
478
479 M_FONTDATA->m_family = family;
480
481 RealizeResource();
482}
483
484void wxFont::SetStyle(int style)
485{
486 Unshare();
487
488 M_FONTDATA->m_style = style;
489
490 RealizeResource();
491}
492
493void wxFont::SetWeight(int weight)
494{
495 Unshare();
496
497 M_FONTDATA->m_weight = weight;
498
499 RealizeResource();
500}
501
502void wxFont::SetFaceName(const wxString& faceName)
503{
504 Unshare();
505
506 M_FONTDATA->m_faceName = faceName;
507
508 RealizeResource();
509}
510
511void wxFont::SetUnderlined(bool underlined)
512{
513 Unshare();
514
515 M_FONTDATA->m_underlined = underlined;
516
517 RealizeResource();
518}
519
21802234 520void wxFont::SetEncoding(wxFontEncoding encoding)
0e320a79 521{
21802234
DW
522 Unshare();
523
524 M_FONTDATA->m_encoding = encoding;
525
526 RealizeResource();
0e320a79
DW
527}
528
21802234
DW
529// ----------------------------------------------------------------------------
530// accessors
531// ----------------------------------------------------------------------------
532
533int wxFont::GetPointSize() const
0e320a79 534{
21802234 535 return M_FONTDATA->m_pointSize;
0e320a79
DW
536}
537
21802234 538int wxFont::GetFamily() const
0e320a79 539{
21802234
DW
540 return M_FONTDATA->m_family;
541}
542
543int wxFont::GetFontId() const
544{
545 return M_FONTDATA->m_fontId;
546}
547
548int wxFont::GetStyle() const
549{
550 return M_FONTDATA->m_style;
551}
552
553int wxFont::GetWeight() const
554{
555 return M_FONTDATA->m_weight;
556}
557
558bool wxFont::GetUnderlined() const
559{
560 return M_FONTDATA->m_underlined;
561}
562
563wxString wxFont::GetFaceName() const
564{
565 wxString str;
566 if ( M_FONTDATA )
567 str = M_FONTDATA->m_faceName ;
568 return str;
569}
570
571wxFontEncoding wxFont::GetEncoding() const
572{
573 return M_FONTDATA->m_encoding;
0e320a79
DW
574}
575