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