]> git.saurik.com Git - wxWidgets.git/blob - src/os2/font.cpp
Improved selection mode handling in wxGrid::SelectBlock
[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 IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
35
36 #if wxUSE_PORTABLE_FONTS_IN_MSW
37 IMPLEMENT_DYNAMIC_CLASS(wxFontNameDirectory, wxObject)
38 #endif
39
40 // ----------------------------------------------------------------------------
41 // wxFontRefData - the internal description of the font
42 // ----------------------------------------------------------------------------
43
44 class WXDLLEXPORT wxFontRefData: public wxGDIRefData
45 {
46 friend class WXDLLEXPORT wxFont;
47
48 public:
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 }
73
74 virtual ~wxFontRefData();
75
76 protected:
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
113 void wxFontRefData::Init(int pointSize,
114 int family,
115 int style,
116 int weight,
117 bool underlined,
118 const wxString& faceName,
119 wxFontEncoding encoding)
120 {
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;
134 }
135
136 wxFontRefData::~wxFontRefData()
137 {
138 // TODO:
139 // if ( m_hFont )
140 // {
141 // if ( !::DeleteObject((HFONT) m_hFont) )
142 // {
143 // wxLogLastError("DeleteObject(font)");
144 // }
145 // }
146 }
147
148 // ----------------------------------------------------------------------------
149 // wxFont
150 // ----------------------------------------------------------------------------
151
152 void wxFont::Init()
153 {
154 if ( wxTheFontList )
155 wxTheFontList->Append(this);
156 }
157
158 /* Constructor for a font. Note that the real construction is done
159 * in wxDC::SetFont, when information is available about scaling etc.
160 */
161 bool wxFont::Create(int pointSize,
162 int family,
163 int style,
164 int weight,
165 bool underlined,
166 const wxString& faceName,
167 wxFontEncoding encoding)
168 {
169 UnRef();
170 m_refData = new wxFontRefData(pointSize, family, style, weight,
171 underlined, faceName, encoding);
172
173 RealizeResource();
174
175 return TRUE;
176 }
177
178 wxFont::~wxFont()
179 {
180 if ( wxTheFontList )
181 wxTheFontList->DeleteObject(this);
182 }
183
184 // ----------------------------------------------------------------------------
185 // real implementation
186 // ----------------------------------------------------------------------------
187
188 bool wxFont::RealizeResource()
189 {
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
194 wxLogDebug(wxT("Calling wxFont::RealizeResource() twice"));
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 ;
208 ff_face = wxT("Script") ;
209 break ;
210
211 case wxDECORATIVE:
212 // ff_family = FF_DECORATIVE;
213 break;
214
215 case wxROMAN:
216 // ff_family = FF_ROMAN;
217 ff_face = wxT("Times New Roman") ;
218 break;
219
220 case wxTELETYPE:
221 case wxMODERN:
222 // ff_family = FF_MODERN;
223 ff_face = wxT("Courier New") ;
224 break;
225
226 case wxSWISS:
227 // ff_family = FF_SWISS;
228 ff_face = wxT("Arial") ;
229 break;
230
231 case wxDEFAULT:
232 default:
233 // ff_family = FF_SWISS;
234 ff_face = wxT("Arial") ;
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:
246 wxFAIL_MSG(wxT("unknown font slant"));
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:
257 wxFAIL_MSG(wxT("unknown font weight"));
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:
379 wxFAIL_MSG(wxT("unsupported encoding"));
380 // fall through
381
382 case wxFONTENCODING_SYSTEM:
383 // charset = ANSI_CHARSET;
384 break;
385 }
386
387 // TODO:
388 WXHFONT hFont = 0;
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
417 bool 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 }
431 return FALSE;
432 }
433
434 WXHANDLE wxFont::GetResourceHandle()
435 {
436 if ( !M_FONTDATA )
437 return 0;
438 else
439 return (WXHANDLE)M_FONTDATA->m_hFont ;
440 }
441
442 bool wxFont::IsFree() const
443 {
444 return (M_FONTDATA && (M_FONTDATA->m_hFont == 0));
445 }
446
447 void wxFont::Unshare()
448 {
449 // Don't change shared data
450 if ( !m_refData )
451 {
452 m_refData = new wxFontRefData();
453 }
454 else
455 {
456 wxFontRefData* ref = new wxFontRefData(*M_FONTDATA);
457 UnRef();
458 m_refData = ref;
459 }
460 }
461
462 // ----------------------------------------------------------------------------
463 // change font attribute: we recreate font when doing it
464 // ----------------------------------------------------------------------------
465
466 void wxFont::SetPointSize(int pointSize)
467 {
468 Unshare();
469
470 M_FONTDATA->m_pointSize = pointSize;
471
472 RealizeResource();
473 }
474
475 void wxFont::SetFamily(int family)
476 {
477 Unshare();
478
479 M_FONTDATA->m_family = family;
480
481 RealizeResource();
482 }
483
484 void wxFont::SetStyle(int style)
485 {
486 Unshare();
487
488 M_FONTDATA->m_style = style;
489
490 RealizeResource();
491 }
492
493 void wxFont::SetWeight(int weight)
494 {
495 Unshare();
496
497 M_FONTDATA->m_weight = weight;
498
499 RealizeResource();
500 }
501
502 void wxFont::SetFaceName(const wxString& faceName)
503 {
504 Unshare();
505
506 M_FONTDATA->m_faceName = faceName;
507
508 RealizeResource();
509 }
510
511 void wxFont::SetUnderlined(bool underlined)
512 {
513 Unshare();
514
515 M_FONTDATA->m_underlined = underlined;
516
517 RealizeResource();
518 }
519
520 void wxFont::SetEncoding(wxFontEncoding encoding)
521 {
522 Unshare();
523
524 M_FONTDATA->m_encoding = encoding;
525
526 RealizeResource();
527 }
528
529 // ----------------------------------------------------------------------------
530 // accessors
531 // ----------------------------------------------------------------------------
532
533 int wxFont::GetPointSize() const
534 {
535 return M_FONTDATA->m_pointSize;
536 }
537
538 int wxFont::GetFamily() const
539 {
540 return M_FONTDATA->m_family;
541 }
542
543 int wxFont::GetFontId() const
544 {
545 return M_FONTDATA->m_fontId;
546 }
547
548 int wxFont::GetStyle() const
549 {
550 return M_FONTDATA->m_style;
551 }
552
553 int wxFont::GetWeight() const
554 {
555 return M_FONTDATA->m_weight;
556 }
557
558 bool wxFont::GetUnderlined() const
559 {
560 return M_FONTDATA->m_underlined;
561 }
562
563 wxString wxFont::GetFaceName() const
564 {
565 wxString str;
566 if ( M_FONTDATA )
567 str = M_FONTDATA->m_faceName ;
568 return str;
569 }
570
571 wxFontEncoding wxFont::GetEncoding() const
572 {
573 return M_FONTDATA->m_encoding;
574 }
575