]> git.saurik.com Git - wxWidgets.git/blame - src/msw/font.cpp
end label edit patch from Ricky Gonzales <gonzales@pyramid3.net>
[wxWidgets.git] / src / msw / font.cpp
CommitLineData
2bda0e17
KB
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
b9b3ccd9 9// Licence: wxWindows licence
2bda0e17
KB
10/////////////////////////////////////////////////////////////////////////////
11
0c5d3e1c
VZ
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
2bda0e17 20#ifdef __GNUG__
0c5d3e1c 21 #pragma implementation "font.h"
2bda0e17
KB
22#endif
23
24// For compilers that support precompilation, includes "wx.h".
25#include "wx/wxprec.h"
26
27#ifdef __BORLANDC__
0c5d3e1c 28 #pragma hdrstop
2bda0e17
KB
29#endif
30
31#ifndef WX_PRECOMP
0c5d3e1c
VZ
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
2bda0e17
KB
39
40#include "wx/msw/private.h"
2bda0e17
KB
41
42#if !USE_SHARED_LIBRARIES
0c5d3e1c 43 IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
2bda0e17 44
0c5d3e1c
VZ
45 #if wxUSE_PORTABLE_FONTS_IN_MSW
46 IMPLEMENT_DYNAMIC_CLASS(wxFontNameDirectory, wxObject)
47 #endif
2bda0e17
KB
48#endif
49
0c5d3e1c
VZ
50// ----------------------------------------------------------------------------
51// wxFontRefData - the internal description of the font
52// ----------------------------------------------------------------------------
2bda0e17 53
0c5d3e1c 54class WXDLLEXPORT wxFontRefData: public wxGDIRefData
2bda0e17 55{
0c5d3e1c
VZ
56friend class WXDLLEXPORT wxFont;
57
58public:
59 wxFontRefData()
60 {
74b31181
VZ
61 Init(12, wxDEFAULT, wxNORMAL, wxNORMAL, FALSE,
62 "", wxFONTENCODING_DEFAULT);
0c5d3e1c
VZ
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 }
2bda0e17 83
0c5d3e1c
VZ
84 virtual ~wxFontRefData();
85
86protected:
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
123void wxFontRefData::Init(int pointSize,
124 int family,
125 int style,
126 int weight,
127 bool underlined,
128 const wxString& faceName,
129 wxFontEncoding encoding)
b823f5a1 130{
b9b3ccd9
VZ
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;
0c5d3e1c
VZ
138 m_encoding = encoding;
139
b9b3ccd9
VZ
140 m_fontId = 0;
141 m_temporary = FALSE;
0c5d3e1c 142
b9b3ccd9 143 m_hFont = 0;
b823f5a1
JS
144}
145
0c5d3e1c 146wxFontRefData::~wxFontRefData()
2bda0e17 147{
b9b3ccd9 148 if ( m_hFont )
0c5d3e1c 149 {
b9b3ccd9 150 if ( !::DeleteObject((HFONT) m_hFont) )
0c5d3e1c
VZ
151 {
152 wxLogLastError("DeleteObject(font)");
153 }
154 }
2bda0e17
KB
155}
156
0c5d3e1c
VZ
157// ----------------------------------------------------------------------------
158// wxFont
159// ----------------------------------------------------------------------------
160
161void wxFont::Init()
2bda0e17
KB
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 */
0c5d3e1c
VZ
170bool wxFont::Create(int pointSize,
171 int family,
172 int style,
173 int weight,
174 bool underlined,
175 const wxString& faceName,
176 wxFontEncoding encoding)
2bda0e17 177{
0c5d3e1c
VZ
178 UnRef();
179 m_refData = new wxFontRefData(pointSize, family, style, weight,
180 underlined, faceName, encoding);
2bda0e17 181
0c5d3e1c 182 RealizeResource();
2bda0e17 183
0c5d3e1c 184 return TRUE;
2bda0e17
KB
185}
186
187wxFont::~wxFont()
188{
0c5d3e1c
VZ
189 if ( wxTheFontList )
190 wxTheFontList->DeleteObject(this);
2bda0e17
KB
191}
192
0c5d3e1c
VZ
193// ----------------------------------------------------------------------------
194// real implementation
195// ----------------------------------------------------------------------------
196
197bool wxFont::RealizeResource()
2bda0e17 198{
0c5d3e1c
VZ
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
223d09f6 203 wxLogDebug(wxT("Calling wxFont::RealizeResource() twice"));
0c5d3e1c
VZ
204
205 return TRUE;
206 }
207
2bda0e17 208 int ff_family = 0;
0c5d3e1c 209 wxString ff_face;
2bda0e17 210
b9b3ccd9 211 switch ( M_FONTDATA->m_family )
2bda0e17 212 {
b9b3ccd9
VZ
213 case wxSCRIPT:
214 ff_family = FF_SCRIPT ;
223d09f6 215 ff_face = wxT("Script") ;
b9b3ccd9
VZ
216 break ;
217
218 case wxDECORATIVE:
219 ff_family = FF_DECORATIVE;
220 break;
221
222 case wxROMAN:
223 ff_family = FF_ROMAN;
223d09f6 224 ff_face = wxT("Times New Roman") ;
b9b3ccd9
VZ
225 break;
226
0c5d3e1c 227 case wxTELETYPE:
b9b3ccd9
VZ
228 case wxMODERN:
229 ff_family = FF_MODERN;
223d09f6 230 ff_face = wxT("Courier New") ;
b9b3ccd9
VZ
231 break;
232
233 case wxSWISS:
234 ff_family = FF_SWISS;
223d09f6 235 ff_face = wxT("Arial") ;
b9b3ccd9
VZ
236 break;
237
0c5d3e1c 238 case wxDEFAULT:
b9b3ccd9
VZ
239 default:
240 ff_family = FF_SWISS;
223d09f6 241 ff_face = wxT("Arial") ;
2bda0e17
KB
242 }
243
b9b3ccd9
VZ
244 BYTE ff_italic;
245 switch ( M_FONTDATA->m_style )
246 {
247 case wxITALIC:
248 case wxSLANT:
249 ff_italic = 1;
250 break;
2bda0e17 251
b9b3ccd9 252 default:
223d09f6 253 wxFAIL_MSG(wxT("unknown font slant"));
b9b3ccd9
VZ
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:
223d09f6 264 wxFAIL_MSG(wxT("unknown font weight"));
b9b3ccd9
VZ
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 }
2bda0e17 279
b9b3ccd9
VZ
280 const wxChar* pzFace;
281 if ( M_FONTDATA->m_faceName.IsEmpty() )
282 pzFace = ff_face;
283 else
284 pzFace = M_FONTDATA->m_faceName ;
2bda0e17 285
b9b3ccd9 286#if 0
0c5d3e1c
VZ
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.
b9b3ccd9 290 */
2bda0e17
KB
291 // What sort of display is it?
292 int technology = ::GetDeviceCaps(dc, TECHNOLOGY);
293
294 int nHeight;
0c5d3e1c 295
2bda0e17
KB
296 if (technology != DT_RASDISPLAY && technology != DT_RASPRINTER)
297 {
b9b3ccd9
VZ
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);
2bda0e17
KB
302 }
303 else
304 {
b9b3ccd9 305 nHeight = M_FONTDATA->m_pointSize*GetDeviceCaps(dc, LOGPIXELSY)/72;
2bda0e17 306 }
b9b3ccd9
VZ
307#endif // 0
308
309#if 0
2bda0e17
KB
310 // Have to get screen DC Caps, because a metafile will return 0.
311 HDC dc2 = ::GetDC(NULL);
b9b3ccd9 312 ppInch = ::GetDeviceCaps(dc2, LOGPIXELSY);
2bda0e17 313 ::ReleaseDC(NULL, dc2);
b9b3ccd9 314#endif // 0
2bda0e17 315
b9b3ccd9
VZ
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;
0c5d3e1c 320
1f112209 321#if wxFONT_SIZE_COMPATIBILITY
2bda0e17
KB
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
b9b3ccd9 329 BYTE ff_underline = M_FONTDATA->m_underlined;
2bda0e17 330
a1d58ddc 331 DWORD charset = wxCharsetFromEncoding(GetEncoding());
b9b3ccd9
VZ
332 HFONT hFont = ::CreateFont
333 (
334 nHeight, // height
335 0, // width (choose best)
336 0, // escapement
337 0, // orientation
338 ff_weight, // weight
339 ff_italic, // italic?
340 ff_underline, // underlined?
341 0, // strikeout?
342 charset, // charset
343 OUT_DEFAULT_PRECIS, // precision
344 CLIP_DEFAULT_PRECIS, // clip precision
345 PROOF_QUALITY, // quality of match
346 DEFAULT_PITCH | // fixed or variable
347 ff_family, // family id
348 pzFace // face name
349 );
350
351 M_FONTDATA->m_hFont = (WXHFONT)hFont;
352 if ( !hFont )
353 {
354 wxLogLastError("CreateFont");
355 }
356
357 return hFont != 0;
2bda0e17
KB
358}
359
360bool wxFont::FreeResource(bool force)
361{
0c5d3e1c
VZ
362 if ( GetResourceHandle() )
363 {
364 if ( !::DeleteObject((HFONT) M_FONTDATA->m_hFont) )
365 {
366 wxLogLastError("DeleteObject(font)");
367 }
368
369 M_FONTDATA->m_hFont = 0;
370
371 return TRUE;
372 }
373 return FALSE;
2bda0e17
KB
374}
375
b823f5a1 376WXHANDLE wxFont::GetResourceHandle()
2bda0e17 377{
0c5d3e1c
VZ
378 if ( !M_FONTDATA )
379 return 0;
380 else
381 return (WXHANDLE)M_FONTDATA->m_hFont ;
2bda0e17
KB
382}
383
e90babdf 384bool wxFont::IsFree() const
2bda0e17 385{
0c5d3e1c 386 return (M_FONTDATA && (M_FONTDATA->m_hFont == 0));
2bda0e17
KB
387}
388
b823f5a1
JS
389void wxFont::Unshare()
390{
b9b3ccd9
VZ
391 // Don't change shared data
392 if ( !m_refData )
b823f5a1 393 {
b9b3ccd9
VZ
394 m_refData = new wxFontRefData();
395 }
b823f5a1
JS
396 else
397 {
b9b3ccd9
VZ
398 wxFontRefData* ref = new wxFontRefData(*M_FONTDATA);
399 UnRef();
400 m_refData = ref;
401 }
b823f5a1
JS
402}
403
0c5d3e1c
VZ
404// ----------------------------------------------------------------------------
405// change font attribute: we recreate font when doing it
406// ----------------------------------------------------------------------------
407
debe6624 408void wxFont::SetPointSize(int pointSize)
2bda0e17 409{
b823f5a1
JS
410 Unshare();
411
2bda0e17 412 M_FONTDATA->m_pointSize = pointSize;
b823f5a1
JS
413
414 RealizeResource();
2bda0e17
KB
415}
416
debe6624 417void wxFont::SetFamily(int family)
2bda0e17 418{
b823f5a1
JS
419 Unshare();
420
2bda0e17 421 M_FONTDATA->m_family = family;
b823f5a1
JS
422
423 RealizeResource();
2bda0e17
KB
424}
425
debe6624 426void wxFont::SetStyle(int style)
2bda0e17 427{
b823f5a1
JS
428 Unshare();
429
2bda0e17 430 M_FONTDATA->m_style = style;
b823f5a1
JS
431
432 RealizeResource();
2bda0e17
KB
433}
434
debe6624 435void wxFont::SetWeight(int weight)
2bda0e17 436{
b823f5a1
JS
437 Unshare();
438
2bda0e17 439 M_FONTDATA->m_weight = weight;
b823f5a1
JS
440
441 RealizeResource();
2bda0e17
KB
442}
443
444void wxFont::SetFaceName(const wxString& faceName)
445{
b823f5a1
JS
446 Unshare();
447
2bda0e17 448 M_FONTDATA->m_faceName = faceName;
b823f5a1
JS
449
450 RealizeResource();
2bda0e17
KB
451}
452
debe6624 453void wxFont::SetUnderlined(bool underlined)
2bda0e17 454{
b823f5a1
JS
455 Unshare();
456
2bda0e17 457 M_FONTDATA->m_underlined = underlined;
b823f5a1
JS
458
459 RealizeResource();
2bda0e17
KB
460}
461
0c5d3e1c 462void wxFont::SetEncoding(wxFontEncoding encoding)
2bda0e17 463{
0c5d3e1c
VZ
464 Unshare();
465
466 M_FONTDATA->m_encoding = encoding;
467
468 RealizeResource();
469}
470
471// ----------------------------------------------------------------------------
472// accessors
473// ----------------------------------------------------------------------------
474
475int wxFont::GetPointSize() const
476{
477 return M_FONTDATA->m_pointSize;
478}
479
480int wxFont::GetFamily() const
481{
482 return M_FONTDATA->m_family;
2bda0e17
KB
483}
484
0c5d3e1c 485int wxFont::GetFontId() const
2bda0e17 486{
0c5d3e1c 487 return M_FONTDATA->m_fontId;
2bda0e17
KB
488}
489
0c5d3e1c 490int wxFont::GetStyle() const
2bda0e17 491{
0c5d3e1c 492 return M_FONTDATA->m_style;
2bda0e17
KB
493}
494
0c5d3e1c 495int wxFont::GetWeight() const
2bda0e17 496{
0c5d3e1c 497 return M_FONTDATA->m_weight;
2bda0e17
KB
498}
499
0c5d3e1c
VZ
500bool wxFont::GetUnderlined() const
501{
502 return M_FONTDATA->m_underlined;
503}
504
505wxString wxFont::GetFaceName() const
506{
507 wxString str;
508 if ( M_FONTDATA )
509 str = M_FONTDATA->m_faceName ;
510 return str;
511}
512
513wxFontEncoding wxFont::GetEncoding() const
514{
515 return M_FONTDATA->m_encoding;
516}
a1d58ddc
VZ
517
518// ----------------------------------------------------------------------------
519// public functions
520// ----------------------------------------------------------------------------
521
522int wxCharsetFromEncoding(wxFontEncoding encoding, bool *exact)
523{
524 if ( encoding == wxFONTENCODING_DEFAULT )
525 {
526 encoding = wxFont::GetDefaultEncoding();
527 }
528
529 if ( exact )
530 *exact = TRUE;
531
532 int charset;
533 switch ( encoding )
534 {
535 case wxFONTENCODING_ISO8859_1:
536 case wxFONTENCODING_ISO8859_15:
537 case wxFONTENCODING_CP1250:
538 charset = ANSI_CHARSET;
539 break;
540
541#if !defined(__WIN16__)
542 case wxFONTENCODING_ISO8859_2:
543 case wxFONTENCODING_CP1252:
544 charset = EASTEUROPE_CHARSET;
545 break;
546
547 case wxFONTENCODING_ISO8859_4:
548 case wxFONTENCODING_ISO8859_10:
549 charset = BALTIC_CHARSET;
550 break;
551
552 case wxFONTENCODING_ISO8859_5:
553 case wxFONTENCODING_CP1251:
554 charset = RUSSIAN_CHARSET;
555 break;
556
557 case wxFONTENCODING_ISO8859_6:
558 charset = ARABIC_CHARSET;
559 break;
560
561 case wxFONTENCODING_ISO8859_7:
562 charset = GREEK_CHARSET;
563 break;
564
565 case wxFONTENCODING_ISO8859_8:
566 charset = HEBREW_CHARSET;
567 break;
568
569 case wxFONTENCODING_ISO8859_9:
570 charset = TURKISH_CHARSET;
571 break;
572
573 case wxFONTENCODING_ISO8859_11:
574 charset = THAI_CHARSET;
575 break;
576#endif // BC++ 16-bit
577
578 case wxFONTENCODING_CP437:
579 charset = OEM_CHARSET;
580 break;
581
582 default:
583 if ( exact )
584 *exact = FALSE;
585 // fall through
586
587 case wxFONTENCODING_SYSTEM:
588 charset = ANSI_CHARSET;
589 }
590
591 return charset;
592}
593