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