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