]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/msw/font.cpp
applied patch 419155 (OLE x-compilation with mingw)
[wxWidgets.git] / src / msw / font.cpp
... / ...
CommitLineData
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 "wx/setup.h"
33 #include "wx/list.h"
34 #include "wx/utils.h"
35 #include "wx/app.h"
36 #include "wx/font.h"
37 #include "wx/log.h"
38#endif // WX_PRECOMP
39
40#include "wx/fontutil.h"
41#include "wx/tokenzr.h"
42
43#include "wx/msw/private.h"
44
45IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
46
47// ----------------------------------------------------------------------------
48// constants
49// ----------------------------------------------------------------------------
50
51// the default font size in points
52static const int wxDEFAULT_FONT_SIZE = 12;
53
54// ----------------------------------------------------------------------------
55// wxFontRefData - the internal description of the font
56// ----------------------------------------------------------------------------
57
58class WXDLLEXPORT wxFontRefData: public wxGDIRefData
59{
60friend class WXDLLEXPORT wxFont;
61
62public:
63 wxFontRefData()
64 {
65 Init(wxDEFAULT_FONT_SIZE, wxDEFAULT, wxNORMAL, wxNORMAL, FALSE,
66 "", wxFONTENCODING_DEFAULT);
67 }
68
69 wxFontRefData(const wxFontRefData& data)
70 {
71 Init(data.m_pointSize, data.m_family, data.m_style, data.m_weight,
72 data.m_underlined, data.m_faceName, data.m_encoding);
73
74 m_fontId = data.m_fontId;
75 }
76
77 wxFontRefData(int size,
78 int family,
79 int style,
80 int weight,
81 bool underlined,
82 const wxString& faceName,
83 wxFontEncoding encoding)
84 {
85 Init(size, family, style, weight, underlined, faceName, encoding);
86 }
87
88 wxFontRefData(const wxNativeFontInfo& info)
89 {
90 Init(info);
91 }
92
93 virtual ~wxFontRefData();
94
95protected:
96 // common part of all ctors
97 void Init(int size,
98 int family,
99 int style,
100 int weight,
101 bool underlined,
102 const wxString& faceName,
103 wxFontEncoding encoding);
104
105 void Init(const wxNativeFontInfo& info);
106
107 // If TRUE, the pointer to the actual font is temporary and SHOULD NOT BE
108 // DELETED by destructor
109 bool m_temporary;
110
111 int m_fontId;
112
113 // font characterstics
114 int m_pointSize;
115 int m_family;
116 int m_style;
117 int m_weight;
118 bool m_underlined;
119 wxString m_faceName;
120 wxFontEncoding m_encoding;
121
122 // Windows font handle
123 WXHFONT m_hFont;
124
125 // Native font info
126 wxNativeFontInfo m_nativeFontInfo;
127 bool m_nativeFontInfoOk;
128};
129
130// ============================================================================
131// implementation
132// ============================================================================
133
134// ----------------------------------------------------------------------------
135// wxFontRefData
136// ----------------------------------------------------------------------------
137
138void wxFontRefData::Init(int pointSize,
139 int family,
140 int style,
141 int weight,
142 bool underlined,
143 const wxString& faceName,
144 wxFontEncoding encoding)
145{
146 m_style = style;
147 m_pointSize = pointSize;
148 m_family = family;
149 m_style = style;
150 m_weight = weight;
151 m_underlined = underlined;
152 m_faceName = faceName;
153 m_encoding = encoding;
154
155 m_fontId = 0;
156 m_temporary = FALSE;
157
158 m_hFont = 0;
159
160 m_nativeFontInfoOk = FALSE;
161}
162
163void wxFontRefData::Init(const wxNativeFontInfo& info)
164{
165 // extract family from pitch-and-family
166 int lfFamily = info.lf.lfPitchAndFamily;
167 if ( lfFamily & FIXED_PITCH )
168 lfFamily -= FIXED_PITCH;
169 if ( lfFamily & VARIABLE_PITCH )
170 lfFamily -= VARIABLE_PITCH;
171
172 switch ( lfFamily )
173 {
174 case FF_ROMAN:
175 m_family = wxROMAN;
176 break;
177
178 case FF_SWISS:
179 m_family = wxSWISS;
180 break;
181
182 case FF_SCRIPT:
183 m_family = wxSCRIPT;
184 break;
185
186 case FF_MODERN:
187 m_family = wxMODERN;
188 break;
189
190 case FF_DECORATIVE:
191 m_family = wxDECORATIVE;
192 break;
193
194 default:
195 m_family = wxSWISS;
196 }
197
198 // weight and style
199 switch ( info.lf.lfWeight )
200 {
201 case FW_LIGHT:
202 m_weight = wxLIGHT;
203 break;
204
205 default:
206 case FW_NORMAL:
207 m_weight = wxNORMAL;
208 break;
209
210 case FW_BOLD:
211 m_weight = wxBOLD;
212 break;
213 }
214
215 m_style = info.lf.lfItalic ? wxITALIC : wxNORMAL;
216
217 m_underlined = info.lf.lfUnderline != 0;
218
219 m_faceName = info.lf.lfFaceName;
220
221 int height = abs(info.lf.lfHeight);
222
223 // remember that 1pt = 1/72inch
224 const int ppInch = ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY);
225 m_pointSize = (int) (((72.0*((double)height))/(double) ppInch) + 0.5);
226
227 m_encoding = wxGetFontEncFromCharSet(info.lf.lfCharSet);
228
229 m_fontId = 0;
230 m_temporary = FALSE;
231
232 m_hFont = 0;
233
234 m_nativeFontInfoOk = TRUE;
235 m_nativeFontInfo = info;
236}
237
238wxFontRefData::~wxFontRefData()
239{
240 if ( m_hFont )
241 {
242 if ( !::DeleteObject((HFONT) m_hFont) )
243 {
244 wxLogLastError(wxT("DeleteObject(font)"));
245 }
246 }
247}
248
249
250// ----------------------------------------------------------------------------
251// wxNativeFontInfo
252// ----------------------------------------------------------------------------
253
254bool wxNativeFontInfo::FromString(const wxString& s)
255{
256 long l;
257
258 wxStringTokenizer tokenizer(s, _T(";"));
259
260 wxString token = tokenizer.GetNextToken();
261 //
262 // Ignore the version for now
263 //
264
265 token = tokenizer.GetNextToken();
266 if ( !token.ToLong(&l) )
267 return FALSE;
268 lf.lfHeight = l;
269
270 token = tokenizer.GetNextToken();
271 if ( !token.ToLong(&l) )
272 return FALSE;
273 lf.lfWidth = l;
274
275 token = tokenizer.GetNextToken();
276 if ( !token.ToLong(&l) )
277 return FALSE;
278 lf.lfEscapement = l;
279
280 token = tokenizer.GetNextToken();
281 if ( !token.ToLong(&l) )
282 return FALSE;
283 lf.lfOrientation = l;
284
285 token = tokenizer.GetNextToken();
286 if ( !token.ToLong(&l) )
287 return FALSE;
288 lf.lfWeight = l;
289
290 token = tokenizer.GetNextToken();
291 if ( !token.ToLong(&l) )
292 return FALSE;
293 lf.lfItalic = l;
294
295 token = tokenizer.GetNextToken();
296 if ( !token.ToLong(&l) )
297 return FALSE;
298 lf.lfUnderline = l;
299
300 token = tokenizer.GetNextToken();
301 if ( !token.ToLong(&l) )
302 return FALSE;
303 lf.lfStrikeOut = l;
304
305 token = tokenizer.GetNextToken();
306 if ( !token.ToLong(&l) )
307 return FALSE;
308 lf.lfCharSet = l;
309
310 token = tokenizer.GetNextToken();
311 if ( !token.ToLong(&l) )
312 return FALSE;
313 lf.lfOutPrecision = l;
314
315 token = tokenizer.GetNextToken();
316 if ( !token.ToLong(&l) )
317 return FALSE;
318 lf.lfClipPrecision = l;
319
320 token = tokenizer.GetNextToken();
321 if ( !token.ToLong(&l) )
322 return FALSE;
323 lf.lfQuality = l;
324
325 token = tokenizer.GetNextToken();
326 if ( !token.ToLong(&l) )
327 return FALSE;
328 lf.lfPitchAndFamily = l;
329
330 token = tokenizer.GetNextToken();
331 if(!token)
332 return FALSE;
333 wxStrcpy(lf.lfFaceName, token.c_str());
334
335 return TRUE;
336}
337
338wxString wxNativeFontInfo::ToString() const
339{
340 wxString s;
341
342 s.Printf(_T("%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%s"),
343 0, // version, in case we want to change the format later
344 lf.lfHeight,
345 lf.lfWidth,
346 lf.lfEscapement,
347 lf.lfOrientation,
348 lf.lfWeight,
349 lf.lfItalic,
350 lf.lfUnderline,
351 lf.lfStrikeOut,
352 lf.lfCharSet,
353 lf.lfOutPrecision,
354 lf.lfClipPrecision,
355 lf.lfQuality,
356 lf.lfPitchAndFamily,
357 lf.lfFaceName);
358
359 return s;
360}
361
362// ----------------------------------------------------------------------------
363// wxFont
364// ----------------------------------------------------------------------------
365
366void wxFont::Init()
367{
368 if ( wxTheFontList )
369 wxTheFontList->Append(this);
370}
371
372bool wxFont::Create(const wxNativeFontInfo& info)
373{
374 UnRef();
375
376 m_refData = new wxFontRefData(info);
377
378 RealizeResource();
379
380 return TRUE;
381}
382
383wxFont::wxFont(const wxString& fontdesc)
384{
385 wxNativeFontInfo info;
386 if ( info.FromString(fontdesc) )
387 (void)Create(info);
388}
389
390/* Constructor for a font. Note that the real construction is done
391 * in wxDC::SetFont, when information is available about scaling etc.
392 */
393bool wxFont::Create(int pointSize,
394 int family,
395 int style,
396 int weight,
397 bool underlined,
398 const wxString& faceName,
399 wxFontEncoding encoding)
400{
401 UnRef();
402
403 // wxDEFAULT is a valid value for the font size too so we must treat it
404 // specially here (otherwise the size would be 70 == wxDEFAULT value)
405 if ( pointSize == wxDEFAULT )
406 pointSize = wxDEFAULT_FONT_SIZE;
407
408 m_refData = new wxFontRefData(pointSize, family, style, weight,
409 underlined, faceName, encoding);
410
411 RealizeResource();
412
413 return TRUE;
414}
415
416wxFont::~wxFont()
417{
418 if ( wxTheFontList )
419 wxTheFontList->DeleteObject(this);
420}
421
422// ----------------------------------------------------------------------------
423// real implementation
424// ----------------------------------------------------------------------------
425
426bool wxFont::RealizeResource()
427{
428 if ( GetResourceHandle() )
429 {
430 // VZ: the old code returned FALSE in this case, but it doesn't seem
431 // to make sense because the font _was_ created
432 return TRUE;
433 }
434
435 if(!M_FONTDATA->m_nativeFontInfoOk)
436 {
437 wxFillLogFont(&M_FONTDATA->m_nativeFontInfo.lf, this);
438 M_FONTDATA->m_nativeFontInfoOk = TRUE;
439 }
440
441 M_FONTDATA->m_hFont = (WXHFONT)::CreateFontIndirect(&M_FONTDATA->m_nativeFontInfo.lf);
442 M_FONTDATA->m_faceName = M_FONTDATA->m_nativeFontInfo.lf.lfFaceName;
443 if ( !M_FONTDATA->m_hFont )
444 {
445 wxLogLastError(wxT("CreateFont"));
446
447 return FALSE;
448 }
449
450 return TRUE;
451}
452
453bool wxFont::FreeResource(bool force)
454{
455 if ( GetResourceHandle() )
456 {
457 if ( !::DeleteObject((HFONT) M_FONTDATA->m_hFont) )
458 {
459 wxLogLastError(wxT("DeleteObject(font)"));
460 }
461
462 M_FONTDATA->m_hFont = 0;
463
464 return TRUE;
465 }
466 return FALSE;
467}
468
469WXHANDLE wxFont::GetResourceHandle()
470{
471 return GetHFONT();
472}
473
474WXHFONT wxFont::GetHFONT() const
475{
476 if ( !M_FONTDATA )
477 return 0;
478 else
479 return (WXHANDLE)M_FONTDATA->m_hFont;
480}
481
482bool wxFont::IsFree() const
483{
484 return (M_FONTDATA && (M_FONTDATA->m_hFont == 0));
485}
486
487void wxFont::Unshare()
488{
489 // Don't change shared data
490 if ( !m_refData )
491 {
492 m_refData = new wxFontRefData();
493 }
494 else
495 {
496 wxFontRefData* ref = new wxFontRefData(*M_FONTDATA);
497 UnRef();
498 m_refData = ref;
499 }
500}
501
502// ----------------------------------------------------------------------------
503// change font attribute: we recreate font when doing it
504// ----------------------------------------------------------------------------
505
506void wxFont::SetPointSize(int pointSize)
507{
508 Unshare();
509
510 M_FONTDATA->m_pointSize = pointSize;
511 M_FONTDATA->m_nativeFontInfoOk = FALSE;
512
513 RealizeResource();
514}
515
516void wxFont::SetFamily(int family)
517{
518 Unshare();
519
520 M_FONTDATA->m_family = family;
521 M_FONTDATA->m_nativeFontInfoOk = FALSE;
522
523 RealizeResource();
524}
525
526void wxFont::SetStyle(int style)
527{
528 Unshare();
529
530 M_FONTDATA->m_style = style;
531 M_FONTDATA->m_nativeFontInfoOk = FALSE;
532
533 RealizeResource();
534}
535
536void wxFont::SetWeight(int weight)
537{
538 Unshare();
539
540 M_FONTDATA->m_weight = weight;
541 M_FONTDATA->m_nativeFontInfoOk = FALSE;
542
543 RealizeResource();
544}
545
546void wxFont::SetFaceName(const wxString& faceName)
547{
548 Unshare();
549
550 M_FONTDATA->m_faceName = faceName;
551 M_FONTDATA->m_nativeFontInfoOk = FALSE;
552
553 RealizeResource();
554}
555
556void wxFont::SetUnderlined(bool underlined)
557{
558 Unshare();
559
560 M_FONTDATA->m_underlined = underlined;
561 M_FONTDATA->m_nativeFontInfoOk = FALSE;
562
563 RealizeResource();
564}
565
566void wxFont::SetEncoding(wxFontEncoding encoding)
567{
568 Unshare();
569
570 M_FONTDATA->m_encoding = encoding;
571 M_FONTDATA->m_nativeFontInfoOk = FALSE;
572
573 RealizeResource();
574}
575
576void wxFont::SetNativeFontInfo(const wxNativeFontInfo& info)
577{
578 Unshare();
579
580 FreeResource();
581
582 M_FONTDATA->Init(info);
583
584 RealizeResource();
585}
586
587// ----------------------------------------------------------------------------
588// accessors
589// ----------------------------------------------------------------------------
590
591int wxFont::GetPointSize() const
592{
593 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
594
595 return M_FONTDATA->m_pointSize;
596}
597
598int wxFont::GetFamily() const
599{
600 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
601
602 return M_FONTDATA->m_family;
603}
604
605int wxFont::GetFontId() const
606{
607 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
608
609 return M_FONTDATA->m_fontId;
610}
611
612int wxFont::GetStyle() const
613{
614 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
615
616 return M_FONTDATA->m_style;
617}
618
619int wxFont::GetWeight() const
620{
621 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
622
623 return M_FONTDATA->m_weight;
624}
625
626bool wxFont::GetUnderlined() const
627{
628 wxCHECK_MSG( Ok(), FALSE, wxT("invalid font") );
629
630 return M_FONTDATA->m_underlined;
631}
632
633wxString wxFont::GetFaceName() const
634{
635 wxCHECK_MSG( Ok(), wxT(""), wxT("invalid font") );
636
637 return M_FONTDATA->m_faceName;
638}
639
640wxFontEncoding wxFont::GetEncoding() const
641{
642 wxCHECK_MSG( Ok(), wxFONTENCODING_DEFAULT, wxT("invalid font") );
643
644 return M_FONTDATA->m_encoding;
645}
646
647wxNativeFontInfo *wxFont::GetNativeFontInfo() const
648{
649 if( M_FONTDATA->m_nativeFontInfoOk )
650 return new wxNativeFontInfo(M_FONTDATA->m_nativeFontInfo);
651
652 return 0;
653}
654