]>
Commit | Line | Data |
---|---|---|
2bda0e17 | 1 | ///////////////////////////////////////////////////////////////////////////// |
a9249b2e | 2 | // Name: src/msw/font.cpp |
2bda0e17 KB |
3 | // Purpose: wxFont class |
4 | // Author: Julian Smart | |
5 | // Modified by: | |
6 | // Created: 01/02/97 | |
7 | // RCS-ID: $Id$ | |
77ffb593 | 8 | // Copyright: (c) wxWidgets team |
65571936 | 9 | // Licence: wxWindows licence |
2bda0e17 KB |
10 | ///////////////////////////////////////////////////////////////////////////// |
11 | ||
0c5d3e1c VZ |
12 | // ============================================================================ |
13 | // declarations | |
14 | // ============================================================================ | |
15 | ||
16 | // ---------------------------------------------------------------------------- | |
17 | // headers | |
18 | // ---------------------------------------------------------------------------- | |
19 | ||
2bda0e17 KB |
20 | // For compilers that support precompilation, includes "wx.h". |
21 | #include "wx/wxprec.h" | |
22 | ||
23 | #ifdef __BORLANDC__ | |
0c5d3e1c | 24 | #pragma hdrstop |
2bda0e17 KB |
25 | #endif |
26 | ||
48a1108e WS |
27 | #include "wx/font.h" |
28 | ||
2bda0e17 | 29 | #ifndef WX_PRECOMP |
0c5d3e1c VZ |
30 | #include "wx/list.h" |
31 | #include "wx/utils.h" | |
32 | #include "wx/app.h" | |
f94dfb38 | 33 | #include "wx/log.h" |
081d8d96 | 34 | #include "wx/msw/private.h" |
0c5d3e1c | 35 | #endif // WX_PRECOMP |
2bda0e17 | 36 | |
081d8d96 | 37 | #include "wx/encinfo.h" |
76e23cdb | 38 | #include "wx/fontutil.h" |
bff67a6a | 39 | #include "wx/fontmap.h" |
76e23cdb | 40 | |
66160760 VZ |
41 | #ifndef __WXWINCE__ |
42 | #include "wx/sysopt.h" | |
43 | #endif | |
44 | ||
14ba694c | 45 | #include "wx/scopeguard.h" |
1e6feb95 | 46 | #include "wx/tokenzr.h" |
2bda0e17 | 47 | |
3ca6a5f0 BP |
48 | // ---------------------------------------------------------------------------- |
49 | // constants | |
50 | // ---------------------------------------------------------------------------- | |
51 | ||
9cf8de4c VZ |
52 | // the mask used to extract the pitch from LOGFONT::lfPitchAndFamily field |
53 | static const int PITCH_MASK = FIXED_PITCH | VARIABLE_PITCH; | |
54 | ||
0c5d3e1c VZ |
55 | // ---------------------------------------------------------------------------- |
56 | // wxFontRefData - the internal description of the font | |
57 | // ---------------------------------------------------------------------------- | |
2bda0e17 | 58 | |
0c5d3e1c | 59 | class WXDLLEXPORT wxFontRefData: public wxGDIRefData |
2bda0e17 | 60 | { |
0c5d3e1c | 61 | public: |
a9249b2e | 62 | // constructors |
0c5d3e1c VZ |
63 | wxFontRefData() |
64 | { | |
c47addef | 65 | Init(-1, wxSize(0,0), false, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, |
c7a49742 | 66 | wxFONTWEIGHT_NORMAL, false, false, wxEmptyString, |
544229d1 | 67 | wxFONTENCODING_DEFAULT); |
0c5d3e1c VZ |
68 | } |
69 | ||
70 | wxFontRefData(int size, | |
544229d1 VZ |
71 | const wxSize& pixelSize, |
72 | bool sizeUsingPixels, | |
0c14b6c3 FM |
73 | wxFontFamily family, |
74 | wxFontStyle style, | |
75 | wxFontWeight weight, | |
0c5d3e1c | 76 | bool underlined, |
c7a49742 | 77 | bool strikethrough, |
0c5d3e1c VZ |
78 | const wxString& faceName, |
79 | wxFontEncoding encoding) | |
80 | { | |
544229d1 | 81 | Init(size, pixelSize, sizeUsingPixels, family, style, weight, |
c7a49742 | 82 | underlined, strikethrough, faceName, encoding); |
0c5d3e1c | 83 | } |
2bda0e17 | 84 | |
04ef50df | 85 | wxFontRefData(const wxNativeFontInfo& info, WXHFONT hFont = 0) |
09fcd889 | 86 | { |
04ef50df | 87 | Init(info, hFont); |
09fcd889 VZ |
88 | } |
89 | ||
04a18b0d | 90 | wxFontRefData(const wxFontRefData& data) : wxGDIRefData() |
a9249b2e | 91 | { |
df898907 | 92 | Init(data.m_nativeFontInfo); |
a9249b2e VZ |
93 | } |
94 | ||
0c5d3e1c VZ |
95 | virtual ~wxFontRefData(); |
96 | ||
a9249b2e | 97 | // operations |
df898907 | 98 | bool Alloc(); |
a9249b2e VZ |
99 | |
100 | void Free(); | |
101 | ||
102 | // all wxFont accessors | |
103 | int GetPointSize() const | |
104 | { | |
df898907 | 105 | return m_nativeFontInfo.GetPointSize(); |
a9249b2e VZ |
106 | } |
107 | ||
544229d1 VZ |
108 | wxSize GetPixelSize() const |
109 | { | |
df898907 | 110 | return m_nativeFontInfo.GetPixelSize(); |
544229d1 | 111 | } |
907173e5 | 112 | |
544229d1 VZ |
113 | bool IsUsingSizeInPixels() const |
114 | { | |
df898907 | 115 | return m_sizeUsingPixels; |
544229d1 VZ |
116 | } |
117 | ||
9817be8a | 118 | wxFontFamily GetFamily() const |
a9249b2e | 119 | { |
df898907 | 120 | return m_nativeFontInfo.GetFamily(); |
a9249b2e VZ |
121 | } |
122 | ||
9817be8a | 123 | wxFontStyle GetStyle() const |
a9249b2e | 124 | { |
df898907 | 125 | return m_nativeFontInfo.GetStyle(); |
a9249b2e VZ |
126 | } |
127 | ||
9817be8a | 128 | wxFontWeight GetWeight() const |
a9249b2e | 129 | { |
df898907 | 130 | return m_nativeFontInfo.GetWeight(); |
a9249b2e VZ |
131 | } |
132 | ||
133 | bool GetUnderlined() const | |
134 | { | |
df898907 | 135 | return m_nativeFontInfo.GetUnderlined(); |
a9249b2e VZ |
136 | } |
137 | ||
c7a49742 VZ |
138 | bool GetStrikethrough() const |
139 | { | |
140 | return m_nativeFontInfo.GetStrikethrough(); | |
141 | } | |
142 | ||
a9249b2e VZ |
143 | wxString GetFaceName() const |
144 | { | |
9bd26720 VZ |
145 | wxString facename = m_nativeFontInfo.GetFaceName(); |
146 | if ( facename.empty() ) | |
147 | { | |
148 | facename = GetMSWFaceName(); | |
149 | if ( !facename.empty() ) | |
150 | { | |
151 | // cache the face name, it shouldn't change unless the family | |
152 | // does and wxNativeFontInfo::SetFamily() resets the face name | |
153 | const_cast<wxFontRefData *>(this)->SetFaceName(facename); | |
154 | } | |
155 | } | |
156 | ||
157 | return facename; | |
a9249b2e VZ |
158 | } |
159 | ||
160 | wxFontEncoding GetEncoding() const | |
161 | { | |
df898907 | 162 | return m_nativeFontInfo.GetEncoding(); |
a9249b2e VZ |
163 | } |
164 | ||
df898907 | 165 | WXHFONT GetHFONT() const |
8e34db1d | 166 | { |
64932e41 | 167 | AllocIfNeeded(); |
8e34db1d VZ |
168 | |
169 | return (WXHFONT)m_hFont; | |
170 | } | |
171 | ||
172 | bool HasHFONT() const | |
173 | { | |
174 | return m_hFont != 0; | |
175 | } | |
a9249b2e | 176 | |
8e34db1d VZ |
177 | // ... and setters: notice that all of them invalidate the currently |
178 | // allocated HFONT, if any, so that the next call to GetHFONT() recreates a | |
179 | // new one | |
a9249b2e VZ |
180 | void SetPointSize(int pointSize) |
181 | { | |
8e34db1d VZ |
182 | Free(); |
183 | ||
df898907 FM |
184 | m_nativeFontInfo.SetPointSize(pointSize); |
185 | m_sizeUsingPixels = false; | |
544229d1 VZ |
186 | } |
187 | ||
188 | void SetPixelSize(const wxSize& pixelSize) | |
189 | { | |
5414d62e VZ |
190 | wxCHECK_RET( pixelSize.GetWidth() >= 0, "negative font width" ); |
191 | wxCHECK_RET( pixelSize.GetHeight() != 0, "zero font height" ); | |
192 | ||
8e34db1d VZ |
193 | Free(); |
194 | ||
df898907 FM |
195 | m_nativeFontInfo.SetPixelSize(pixelSize); |
196 | m_sizeUsingPixels = true; | |
a9249b2e VZ |
197 | } |
198 | ||
0c14b6c3 | 199 | void SetFamily(wxFontFamily family) |
a9249b2e | 200 | { |
8e34db1d VZ |
201 | Free(); |
202 | ||
df898907 | 203 | m_nativeFontInfo.SetFamily(family); |
a9249b2e VZ |
204 | } |
205 | ||
0c14b6c3 | 206 | void SetStyle(wxFontStyle style) |
a9249b2e | 207 | { |
8e34db1d VZ |
208 | Free(); |
209 | ||
df898907 | 210 | m_nativeFontInfo.SetStyle(style); |
a9249b2e VZ |
211 | } |
212 | ||
0c14b6c3 | 213 | void SetWeight(wxFontWeight weight) |
a9249b2e | 214 | { |
8e34db1d VZ |
215 | Free(); |
216 | ||
df898907 | 217 | m_nativeFontInfo.SetWeight(weight); |
a9249b2e VZ |
218 | } |
219 | ||
85ab460e | 220 | bool SetFaceName(const wxString& faceName) |
a9249b2e | 221 | { |
8e34db1d VZ |
222 | Free(); |
223 | ||
df898907 | 224 | return m_nativeFontInfo.SetFaceName(faceName); |
a9249b2e VZ |
225 | } |
226 | ||
227 | void SetUnderlined(bool underlined) | |
228 | { | |
8e34db1d VZ |
229 | Free(); |
230 | ||
df898907 | 231 | m_nativeFontInfo.SetUnderlined(underlined); |
a9249b2e VZ |
232 | } |
233 | ||
c7a49742 VZ |
234 | void SetStrikethrough(bool strikethrough) |
235 | { | |
236 | Free(); | |
237 | ||
238 | m_nativeFontInfo.SetStrikethrough(strikethrough); | |
239 | } | |
240 | ||
a9249b2e VZ |
241 | void SetEncoding(wxFontEncoding encoding) |
242 | { | |
8e34db1d VZ |
243 | Free(); |
244 | ||
df898907 | 245 | m_nativeFontInfo.SetEncoding(encoding); |
a9249b2e VZ |
246 | } |
247 | ||
a9249b2e | 248 | const wxNativeFontInfo& GetNativeFontInfo() const |
a77c05ea | 249 | { |
64932e41 VZ |
250 | // we need to create the font now to get the corresponding LOGFONT if |
251 | // it hadn't been done yet | |
252 | AllocIfNeeded(); | |
253 | ||
a77c05ea VZ |
254 | // ensure that we have a valid face name in our font information: |
255 | // GetFaceName() will try to retrieve it from our HFONT and save it if | |
256 | // it was successful | |
257 | (void)GetFaceName(); | |
258 | ||
259 | return m_nativeFontInfo; | |
260 | } | |
a9249b2e | 261 | |
8e34db1d | 262 | void SetNativeFontInfo(const wxNativeFontInfo& nativeFontInfo) |
9cc79dd6 VZ |
263 | { |
264 | Free(); | |
265 | ||
266 | m_nativeFontInfo = nativeFontInfo; | |
9cc79dd6 | 267 | } |
8e34db1d | 268 | |
0c5d3e1c VZ |
269 | protected: |
270 | // common part of all ctors | |
271 | void Init(int size, | |
544229d1 VZ |
272 | const wxSize& pixelSize, |
273 | bool sizeUsingPixels, | |
0c14b6c3 FM |
274 | wxFontFamily family, |
275 | wxFontStyle style, | |
276 | wxFontWeight weight, | |
0c5d3e1c | 277 | bool underlined, |
c7a49742 | 278 | bool strikethrough, |
0c5d3e1c VZ |
279 | const wxString& faceName, |
280 | wxFontEncoding encoding); | |
281 | ||
04ef50df | 282 | void Init(const wxNativeFontInfo& info, WXHFONT hFont = 0); |
09fcd889 | 283 | |
64932e41 VZ |
284 | void AllocIfNeeded() const |
285 | { | |
286 | if ( !m_hFont ) | |
287 | const_cast<wxFontRefData *>(this)->Alloc(); | |
288 | } | |
289 | ||
9bd26720 VZ |
290 | // retrieve the face name really being used by the font: this is used to |
291 | // get the face name selected by the system when we don't specify it (but | |
292 | // use just the family for example) | |
293 | wxString GetMSWFaceName() const | |
294 | { | |
295 | ScreenHDC hdc; | |
792339b9 | 296 | SelectInHDC selectFont(hdc, (HFONT)GetHFONT()); |
9bd26720 VZ |
297 | |
298 | UINT otmSize = GetOutlineTextMetrics(hdc, 0, NULL); | |
299 | if ( !otmSize ) | |
300 | { | |
301 | wxLogLastError("GetOutlineTextMetrics(NULL)"); | |
302 | return wxString(); | |
303 | } | |
304 | ||
305 | OUTLINETEXTMETRIC * const | |
306 | otm = static_cast<OUTLINETEXTMETRIC *>(malloc(otmSize)); | |
307 | wxON_BLOCK_EXIT1( free, otm ); | |
308 | ||
309 | otm->otmSize = otmSize; | |
310 | if ( !GetOutlineTextMetrics(hdc, otmSize, otm) ) | |
311 | { | |
312 | wxLogLastError("GetOutlineTextMetrics()"); | |
313 | return wxString(); | |
314 | } | |
315 | ||
d395f181 VZ |
316 | // in spite of its type, the otmpFamilyName field of OUTLINETEXTMETRIC |
317 | // gives an offset in _bytes_ of the face (not family!) name from the | |
318 | // struct start while the name itself is an array of TCHARs | |
319 | // | |
320 | // FWIW otmpFaceName contains the same thing as otmpFamilyName followed | |
321 | // by a possible " Italic" or " Bold" or something else suffix | |
9bd26720 | 322 | return reinterpret_cast<wxChar *>(otm) + |
d395f181 | 323 | wxPtrToUInt(otm->otmpFamilyName)/sizeof(wxChar); |
9bd26720 VZ |
324 | } |
325 | ||
0572fce8 | 326 | // are we using m_nativeFontInfo.lf.lfHeight for point size or pixel size? |
df898907 | 327 | bool m_sizeUsingPixels; |
0c5d3e1c | 328 | |
8e34db1d | 329 | // Windows font handle, created on demand in GetHFONT() |
df898907 | 330 | HFONT m_hFont; |
789034a0 | 331 | |
09fcd889 VZ |
332 | // Native font info |
333 | wxNativeFontInfo m_nativeFontInfo; | |
0c5d3e1c VZ |
334 | }; |
335 | ||
68c95704 | 336 | #define M_FONTDATA ((wxFontRefData*)m_refData) |
873fd4af | 337 | |
0c5d3e1c VZ |
338 | // ============================================================================ |
339 | // implementation | |
340 | // ============================================================================ | |
341 | ||
342 | // ---------------------------------------------------------------------------- | |
343 | // wxFontRefData | |
344 | // ---------------------------------------------------------------------------- | |
345 | ||
346 | void wxFontRefData::Init(int pointSize, | |
544229d1 VZ |
347 | const wxSize& pixelSize, |
348 | bool sizeUsingPixels, | |
0c14b6c3 FM |
349 | wxFontFamily family, |
350 | wxFontStyle style, | |
351 | wxFontWeight weight, | |
0c5d3e1c | 352 | bool underlined, |
c7a49742 | 353 | bool strikethrough, |
0c5d3e1c VZ |
354 | const wxString& faceName, |
355 | wxFontEncoding encoding) | |
b823f5a1 | 356 | { |
0572fce8 VZ |
357 | m_hFont = NULL; |
358 | ||
544229d1 | 359 | m_sizeUsingPixels = sizeUsingPixels; |
0572fce8 VZ |
360 | if ( m_sizeUsingPixels ) |
361 | SetPixelSize(pixelSize); | |
362 | else | |
363 | SetPointSize(pointSize); | |
df898907 | 364 | |
0572fce8 VZ |
365 | SetStyle(style); |
366 | SetWeight(weight); | |
367 | SetUnderlined(underlined); | |
c7a49742 | 368 | SetStrikethrough(strikethrough); |
0c5d3e1c | 369 | |
0572fce8 VZ |
370 | // set the family/facename |
371 | SetFamily(family); | |
372 | if ( !faceName.empty() ) | |
373 | SetFaceName(faceName); | |
789034a0 | 374 | |
0572fce8 VZ |
375 | // deal with encoding now (it may override the font family and facename |
376 | // so do it after setting them) | |
377 | SetEncoding(encoding); | |
09fcd889 VZ |
378 | } |
379 | ||
04ef50df | 380 | void wxFontRefData::Init(const wxNativeFontInfo& info, WXHFONT hFont) |
09fcd889 | 381 | { |
04ef50df JS |
382 | // hFont may be zero, or it be passed in case we really want to |
383 | // use the exact font created in the underlying system | |
384 | // (for example where we can't guarantee conversion from HFONT | |
385 | // to LOGFONT back to HFONT) | |
8e34db1d | 386 | m_hFont = (HFONT)hFont; |
09fcd889 | 387 | m_nativeFontInfo = info; |
d014871d | 388 | |
df898907 | 389 | // TODO: m_sizeUsingPixels? |
b823f5a1 JS |
390 | } |
391 | ||
0c5d3e1c | 392 | wxFontRefData::~wxFontRefData() |
a9249b2e VZ |
393 | { |
394 | Free(); | |
395 | } | |
396 | ||
df898907 | 397 | bool wxFontRefData::Alloc() |
a9249b2e | 398 | { |
8e34db1d VZ |
399 | m_hFont = ::CreateFontIndirect(&m_nativeFontInfo.lf); |
400 | if ( !m_hFont ) | |
a9249b2e VZ |
401 | { |
402 | wxLogLastError(wxT("CreateFont")); | |
cbe874bd | 403 | return false; |
a9249b2e VZ |
404 | } |
405 | ||
cbe874bd | 406 | return true; |
a9249b2e VZ |
407 | } |
408 | ||
409 | void wxFontRefData::Free() | |
2bda0e17 | 410 | { |
b9b3ccd9 | 411 | if ( m_hFont ) |
0c5d3e1c | 412 | { |
8e34db1d | 413 | if ( !::DeleteObject(m_hFont) ) |
0c5d3e1c | 414 | { |
f6bcfd97 | 415 | wxLogLastError(wxT("DeleteObject(font)")); |
0c5d3e1c | 416 | } |
a9249b2e VZ |
417 | |
418 | m_hFont = 0; | |
0c5d3e1c | 419 | } |
2bda0e17 KB |
420 | } |
421 | ||
09fcd889 VZ |
422 | // ---------------------------------------------------------------------------- |
423 | // wxNativeFontInfo | |
424 | // ---------------------------------------------------------------------------- | |
425 | ||
a9249b2e VZ |
426 | void wxNativeFontInfo::Init() |
427 | { | |
428 | wxZeroMemory(lf); | |
64c1effe | 429 | |
66160760 VZ |
430 | // we get better font quality if we use PROOF_QUALITY instead of |
431 | // DEFAULT_QUALITY but some fonts (e.g. "Terminal 6pt") are not available | |
432 | // then so we allow to set a global option to choose between quality and | |
433 | // wider font selection | |
99ae6124 WS |
434 | #ifdef __WXWINCE__ |
435 | lf.lfQuality = CLEARTYPE_QUALITY; | |
436 | #else | |
df898907 | 437 | lf.lfQuality = wxSystemOptions::GetOptionInt("msw.font.no-proof-quality") |
66160760 VZ |
438 | ? DEFAULT_QUALITY |
439 | : PROOF_QUALITY; | |
99ae6124 | 440 | #endif |
a9249b2e VZ |
441 | } |
442 | ||
443 | int wxNativeFontInfo::GetPointSize() const | |
444 | { | |
7936354d VZ |
445 | // FIXME: using the screen here results in incorrect font size calculation |
446 | // for printing! | |
a9249b2e VZ |
447 | const int ppInch = ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY); |
448 | ||
ee8fd6b1 VZ |
449 | // BC++ 2007 doesn't provide abs(long) overload, hence the cast |
450 | return (int) (((72.0*abs((int)lf.lfHeight)) / (double) ppInch) + 0.5); | |
a9249b2e VZ |
451 | } |
452 | ||
544229d1 VZ |
453 | wxSize wxNativeFontInfo::GetPixelSize() const |
454 | { | |
455 | wxSize ret; | |
cde96954 | 456 | ret.SetHeight(abs((int)lf.lfHeight)); |
544229d1 VZ |
457 | ret.SetWidth(lf.lfWidth); |
458 | return ret; | |
459 | } | |
460 | ||
a9249b2e VZ |
461 | wxFontStyle wxNativeFontInfo::GetStyle() const |
462 | { | |
463 | return lf.lfItalic ? wxFONTSTYLE_ITALIC : wxFONTSTYLE_NORMAL; | |
464 | } | |
465 | ||
466 | wxFontWeight wxNativeFontInfo::GetWeight() const | |
467 | { | |
468 | if ( lf.lfWeight <= 300 ) | |
469 | return wxFONTWEIGHT_LIGHT; | |
470 | ||
471 | if ( lf.lfWeight >= 600 ) | |
472 | return wxFONTWEIGHT_BOLD; | |
473 | ||
474 | return wxFONTWEIGHT_NORMAL; | |
475 | } | |
476 | ||
477 | bool wxNativeFontInfo::GetUnderlined() const | |
478 | { | |
479 | return lf.lfUnderline != 0; | |
480 | } | |
481 | ||
c7a49742 VZ |
482 | bool wxNativeFontInfo::GetStrikethrough() const |
483 | { | |
484 | return lf.lfStrikeOut != 0; | |
485 | } | |
486 | ||
a9249b2e VZ |
487 | wxString wxNativeFontInfo::GetFaceName() const |
488 | { | |
489 | return lf.lfFaceName; | |
490 | } | |
491 | ||
36e2bb4e RD |
492 | wxFontFamily wxNativeFontInfo::GetFamily() const |
493 | { | |
9cf8de4c | 494 | wxFontFamily family; |
36e2bb4e | 495 | |
9cf8de4c VZ |
496 | // extract family from pitch-and-family |
497 | switch ( lf.lfPitchAndFamily & ~PITCH_MASK ) | |
36e2bb4e | 498 | { |
df898907 FM |
499 | case 0: |
500 | family = wxFONTFAMILY_UNKNOWN; | |
501 | break; | |
502 | ||
36e2bb4e | 503 | case FF_ROMAN: |
9cf8de4c | 504 | family = wxFONTFAMILY_ROMAN; |
36e2bb4e RD |
505 | break; |
506 | ||
507 | case FF_SWISS: | |
9cf8de4c | 508 | family = wxFONTFAMILY_SWISS; |
36e2bb4e RD |
509 | break; |
510 | ||
511 | case FF_SCRIPT: | |
9cf8de4c | 512 | family = wxFONTFAMILY_SCRIPT; |
36e2bb4e RD |
513 | break; |
514 | ||
515 | case FF_MODERN: | |
9cf8de4c | 516 | family = wxFONTFAMILY_MODERN; |
36e2bb4e RD |
517 | break; |
518 | ||
519 | case FF_DECORATIVE: | |
9cf8de4c | 520 | family = wxFONTFAMILY_DECORATIVE; |
36e2bb4e | 521 | break; |
df898907 FM |
522 | |
523 | default: | |
524 | wxFAIL_MSG( "unknown LOGFONT::lfFamily value" ); | |
525 | family = wxFONTFAMILY_UNKNOWN; | |
526 | // just to avoid a warning | |
36e2bb4e | 527 | } |
9cf8de4c VZ |
528 | |
529 | return family; | |
36e2bb4e RD |
530 | } |
531 | ||
a9249b2e VZ |
532 | wxFontEncoding wxNativeFontInfo::GetEncoding() const |
533 | { | |
534 | return wxGetFontEncFromCharSet(lf.lfCharSet); | |
535 | } | |
536 | ||
537 | void wxNativeFontInfo::SetPointSize(int pointsize) | |
538 | { | |
7936354d VZ |
539 | // FIXME: using the screen here results in incorrect font size calculation |
540 | // for printing! | |
a9249b2e VZ |
541 | const int ppInch = ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY); |
542 | ||
543 | lf.lfHeight = -(int)((pointsize*((double)ppInch)/72.0) + 0.5); | |
544 | } | |
545 | ||
544229d1 VZ |
546 | void wxNativeFontInfo::SetPixelSize(const wxSize& pixelSize) |
547 | { | |
5414d62e VZ |
548 | // MSW accepts both positive and negative heights here but they mean |
549 | // different things: positive specifies the cell height while negative | |
550 | // specifies the character height. We used to just pass the value to MSW | |
551 | // unchanged but changed the behaviour for positive values in 2.9.1 to | |
552 | // match other ports and, more importantly, the expected behaviour. So now | |
553 | // passing the negative height doesn't make sense at all any more but we | |
554 | // still accept it for compatibility with the existing code which worked | |
555 | // around the wrong interpretation of the height argument in older wxMSW | |
556 | // versions by passing a negative value explicitly itself. | |
557 | lf.lfHeight = -abs(pixelSize.GetHeight()); | |
544229d1 VZ |
558 | lf.lfWidth = pixelSize.GetWidth(); |
559 | } | |
560 | ||
a9249b2e VZ |
561 | void wxNativeFontInfo::SetStyle(wxFontStyle style) |
562 | { | |
563 | switch ( style ) | |
564 | { | |
565 | default: | |
df898907 | 566 | wxFAIL_MSG( "unknown font style" ); |
a9249b2e VZ |
567 | // fall through |
568 | ||
569 | case wxFONTSTYLE_NORMAL: | |
a38d0585 | 570 | lf.lfItalic = FALSE; |
a9249b2e VZ |
571 | break; |
572 | ||
573 | case wxFONTSTYLE_ITALIC: | |
574 | case wxFONTSTYLE_SLANT: | |
575 | lf.lfItalic = TRUE; | |
576 | break; | |
577 | } | |
578 | } | |
579 | ||
580 | void wxNativeFontInfo::SetWeight(wxFontWeight weight) | |
581 | { | |
582 | switch ( weight ) | |
583 | { | |
584 | default: | |
df898907 | 585 | wxFAIL_MSG( "unknown font weight" ); |
a9249b2e VZ |
586 | // fall through |
587 | ||
588 | case wxFONTWEIGHT_NORMAL: | |
589 | lf.lfWeight = FW_NORMAL; | |
590 | break; | |
591 | ||
592 | case wxFONTWEIGHT_LIGHT: | |
593 | lf.lfWeight = FW_LIGHT; | |
594 | break; | |
595 | ||
596 | case wxFONTWEIGHT_BOLD: | |
597 | lf.lfWeight = FW_BOLD; | |
598 | break; | |
599 | } | |
600 | } | |
601 | ||
602 | void wxNativeFontInfo::SetUnderlined(bool underlined) | |
603 | { | |
604 | lf.lfUnderline = underlined; | |
605 | } | |
606 | ||
c7a49742 VZ |
607 | void wxNativeFontInfo::SetStrikethrough(bool strikethrough) |
608 | { | |
609 | lf.lfStrikeOut = strikethrough; | |
610 | } | |
611 | ||
85ab460e | 612 | bool wxNativeFontInfo::SetFaceName(const wxString& facename) |
a9249b2e | 613 | { |
64accea5 | 614 | wxStrlcpy(lf.lfFaceName, facename.c_str(), WXSIZEOF(lf.lfFaceName)); |
85ab460e | 615 | return true; |
a9249b2e VZ |
616 | } |
617 | ||
7936354d VZ |
618 | void wxNativeFontInfo::SetFamily(wxFontFamily family) |
619 | { | |
76d88590 | 620 | BYTE ff_family = FF_DONTCARE; |
7936354d VZ |
621 | |
622 | switch ( family ) | |
623 | { | |
df898907 | 624 | case wxFONTFAMILY_SCRIPT: |
7936354d | 625 | ff_family = FF_SCRIPT; |
7936354d VZ |
626 | break; |
627 | ||
df898907 | 628 | case wxFONTFAMILY_DECORATIVE: |
7936354d | 629 | ff_family = FF_DECORATIVE; |
7936354d VZ |
630 | break; |
631 | ||
df898907 | 632 | case wxFONTFAMILY_ROMAN: |
7936354d | 633 | ff_family = FF_ROMAN; |
7936354d VZ |
634 | break; |
635 | ||
df898907 FM |
636 | case wxFONTFAMILY_TELETYPE: |
637 | case wxFONTFAMILY_MODERN: | |
7936354d | 638 | ff_family = FF_MODERN; |
7936354d VZ |
639 | break; |
640 | ||
df898907 | 641 | case wxFONTFAMILY_SWISS: |
df898907 | 642 | case wxFONTFAMILY_DEFAULT: |
7936354d | 643 | ff_family = FF_SWISS; |
76d88590 | 644 | break; |
a4a0bff1 VZ |
645 | |
646 | case wxFONTFAMILY_UNKNOWN: | |
647 | wxFAIL_MSG( "invalid font family" ); | |
648 | return; | |
7936354d VZ |
649 | } |
650 | ||
76d88590 VZ |
651 | wxCHECK_RET( ff_family != FF_DONTCARE, "unknown wxFontFamily" ); |
652 | ||
5c519b6c | 653 | lf.lfPitchAndFamily = (BYTE)(DEFAULT_PITCH) | ff_family; |
7936354d | 654 | |
060c4f90 FM |
655 | // reset the facename so that CreateFontIndirect() will automatically choose a |
656 | // face name based only on the font family. | |
657 | lf.lfFaceName[0] = '\0'; | |
7936354d VZ |
658 | } |
659 | ||
a9249b2e VZ |
660 | void wxNativeFontInfo::SetEncoding(wxFontEncoding encoding) |
661 | { | |
662 | wxNativeEncodingInfo info; | |
663 | if ( !wxGetNativeFontEncoding(encoding, &info) ) | |
664 | { | |
bff67a6a | 665 | #if wxUSE_FONTMAP |
142b3bc2 | 666 | if ( wxFontMapper::Get()->GetAltForEncoding(encoding, &info) ) |
e7e52b6d VZ |
667 | { |
668 | if ( !info.facename.empty() ) | |
669 | { | |
670 | // if we have this encoding only in some particular facename, use | |
671 | // the facename - it is better to show the correct characters in a | |
672 | // wrong facename than unreadable text in a correct one | |
673 | SetFaceName(info.facename); | |
674 | } | |
675 | } | |
676 | else | |
bff67a6a VZ |
677 | #endif // wxUSE_FONTMAP |
678 | { | |
679 | // unsupported encoding, replace with the default | |
9cf8de4c | 680 | info.charset = DEFAULT_CHARSET; |
bff67a6a | 681 | } |
a9249b2e VZ |
682 | } |
683 | ||
373a5fb3 | 684 | lf.lfCharSet = (BYTE)info.charset; |
a9249b2e VZ |
685 | } |
686 | ||
09fcd889 VZ |
687 | bool wxNativeFontInfo::FromString(const wxString& s) |
688 | { | |
689 | long l; | |
690 | ||
d508a9d9 | 691 | wxStringTokenizer tokenizer(s, wxS(";"), wxTOKEN_RET_EMPTY_ALL); |
09fcd889 | 692 | |
a9249b2e | 693 | // first the version |
09fcd889 | 694 | wxString token = tokenizer.GetNextToken(); |
df898907 | 695 | if ( token != wxS('0') ) |
cbe874bd | 696 | return false; |
09fcd889 VZ |
697 | |
698 | token = tokenizer.GetNextToken(); | |
699 | if ( !token.ToLong(&l) ) | |
cbe874bd | 700 | return false; |
09fcd889 VZ |
701 | lf.lfHeight = l; |
702 | ||
703 | token = tokenizer.GetNextToken(); | |
704 | if ( !token.ToLong(&l) ) | |
cbe874bd | 705 | return false; |
09fcd889 VZ |
706 | lf.lfWidth = l; |
707 | ||
708 | token = tokenizer.GetNextToken(); | |
709 | if ( !token.ToLong(&l) ) | |
cbe874bd | 710 | return false; |
09fcd889 VZ |
711 | lf.lfEscapement = l; |
712 | ||
713 | token = tokenizer.GetNextToken(); | |
714 | if ( !token.ToLong(&l) ) | |
cbe874bd | 715 | return false; |
09fcd889 VZ |
716 | lf.lfOrientation = l; |
717 | ||
718 | token = tokenizer.GetNextToken(); | |
719 | if ( !token.ToLong(&l) ) | |
cbe874bd | 720 | return false; |
09fcd889 VZ |
721 | lf.lfWeight = l; |
722 | ||
723 | token = tokenizer.GetNextToken(); | |
724 | if ( !token.ToLong(&l) ) | |
cbe874bd | 725 | return false; |
33ac7e6f | 726 | lf.lfItalic = (BYTE)l; |
09fcd889 VZ |
727 | |
728 | token = tokenizer.GetNextToken(); | |
729 | if ( !token.ToLong(&l) ) | |
cbe874bd | 730 | return false; |
33ac7e6f | 731 | lf.lfUnderline = (BYTE)l; |
09fcd889 VZ |
732 | |
733 | token = tokenizer.GetNextToken(); | |
734 | if ( !token.ToLong(&l) ) | |
cbe874bd | 735 | return false; |
33ac7e6f | 736 | lf.lfStrikeOut = (BYTE)l; |
09fcd889 VZ |
737 | |
738 | token = tokenizer.GetNextToken(); | |
739 | if ( !token.ToLong(&l) ) | |
cbe874bd | 740 | return false; |
33ac7e6f | 741 | lf.lfCharSet = (BYTE)l; |
09fcd889 VZ |
742 | |
743 | token = tokenizer.GetNextToken(); | |
744 | if ( !token.ToLong(&l) ) | |
cbe874bd | 745 | return false; |
33ac7e6f | 746 | lf.lfOutPrecision = (BYTE)l; |
09fcd889 VZ |
747 | |
748 | token = tokenizer.GetNextToken(); | |
749 | if ( !token.ToLong(&l) ) | |
cbe874bd | 750 | return false; |
33ac7e6f | 751 | lf.lfClipPrecision = (BYTE)l; |
09fcd889 VZ |
752 | |
753 | token = tokenizer.GetNextToken(); | |
754 | if ( !token.ToLong(&l) ) | |
cbe874bd | 755 | return false; |
33ac7e6f | 756 | lf.lfQuality = (BYTE)l; |
09fcd889 VZ |
757 | |
758 | token = tokenizer.GetNextToken(); | |
759 | if ( !token.ToLong(&l) ) | |
cbe874bd | 760 | return false; |
33ac7e6f | 761 | lf.lfPitchAndFamily = (BYTE)l; |
09fcd889 | 762 | |
d508a9d9 | 763 | if ( !tokenizer.HasMoreTokens() ) |
cbe874bd | 764 | return false; |
d508a9d9 VZ |
765 | |
766 | // the face name may be empty | |
3515776e | 767 | SetFaceName(tokenizer.GetNextToken()); |
09fcd889 | 768 | |
cbe874bd | 769 | return true; |
09fcd889 VZ |
770 | } |
771 | ||
772 | wxString wxNativeFontInfo::ToString() const | |
773 | { | |
774 | wxString s; | |
775 | ||
df898907 | 776 | s.Printf(wxS("%d;%ld;%ld;%ld;%ld;%ld;%d;%d;%d;%d;%d;%d;%d;%d;%s"), |
09fcd889 VZ |
777 | 0, // version, in case we want to change the format later |
778 | lf.lfHeight, | |
779 | lf.lfWidth, | |
780 | lf.lfEscapement, | |
781 | lf.lfOrientation, | |
782 | lf.lfWeight, | |
783 | lf.lfItalic, | |
784 | lf.lfUnderline, | |
785 | lf.lfStrikeOut, | |
786 | lf.lfCharSet, | |
787 | lf.lfOutPrecision, | |
788 | lf.lfClipPrecision, | |
789 | lf.lfQuality, | |
790 | lf.lfPitchAndFamily, | |
d508a9d9 | 791 | lf.lfFaceName); |
09fcd889 VZ |
792 | |
793 | return s; | |
794 | } | |
795 | ||
0c5d3e1c VZ |
796 | // ---------------------------------------------------------------------------- |
797 | // wxFont | |
798 | // ---------------------------------------------------------------------------- | |
799 | ||
d014871d FM |
800 | wxFont::wxFont(const wxString& fontdesc) |
801 | { | |
802 | wxNativeFontInfo info; | |
803 | if ( info.FromString(fontdesc) ) | |
804 | (void)Create(info); | |
805 | } | |
806 | ||
b960795e | 807 | wxFont::wxFont(const wxFontInfo& info) |
0634700a | 808 | { |
b960795e VZ |
809 | m_refData = new wxFontRefData(info.GetPointSize(), |
810 | info.GetPixelSize(), | |
811 | info.IsUsingSizeInPixels(), | |
812 | info.GetFamily(), | |
813 | info.GetStyle(), | |
814 | info.GetWeight(), | |
815 | info.IsUnderlined(), | |
816 | info.IsStrikethrough(), | |
817 | info.GetFaceName(), | |
818 | info.GetEncoding()); | |
0634700a VZ |
819 | } |
820 | ||
04ef50df | 821 | bool wxFont::Create(const wxNativeFontInfo& info, WXHFONT hFont) |
76e23cdb | 822 | { |
09fcd889 VZ |
823 | UnRef(); |
824 | ||
04ef50df | 825 | m_refData = new wxFontRefData(info, hFont); |
09fcd889 | 826 | |
adbd3cbc | 827 | return RealizeResource(); |
76e23cdb VZ |
828 | } |
829 | ||
df455719 VZ |
830 | bool wxFont::DoCreate(int pointSize, |
831 | const wxSize& pixelSize, | |
832 | bool sizeUsingPixels, | |
0c14b6c3 FM |
833 | wxFontFamily family, |
834 | wxFontStyle style, | |
835 | wxFontWeight weight, | |
df455719 VZ |
836 | bool underlined, |
837 | const wxString& faceName, | |
838 | wxFontEncoding encoding) | |
2bda0e17 | 839 | { |
0c5d3e1c | 840 | UnRef(); |
3ca6a5f0 BP |
841 | |
842 | // wxDEFAULT is a valid value for the font size too so we must treat it | |
843 | // specially here (otherwise the size would be 70 == wxDEFAULT value) | |
d180df5c | 844 | if ( pointSize == wxDEFAULT || pointSize == -1 ) |
a9249b2e VZ |
845 | { |
846 | pointSize = wxNORMAL_FONT->GetPointSize(); | |
847 | } | |
3ca6a5f0 | 848 | |
544229d1 VZ |
849 | m_refData = new wxFontRefData(pointSize, pixelSize, sizeUsingPixels, |
850 | family, style, weight, | |
c7a49742 | 851 | underlined, false, faceName, encoding); |
2bda0e17 | 852 | |
adbd3cbc | 853 | return RealizeResource(); |
2bda0e17 KB |
854 | } |
855 | ||
856 | wxFont::~wxFont() | |
857 | { | |
2bda0e17 KB |
858 | } |
859 | ||
0c5d3e1c VZ |
860 | // ---------------------------------------------------------------------------- |
861 | // real implementation | |
862 | // ---------------------------------------------------------------------------- | |
863 | ||
8f884a0d | 864 | wxGDIRefData *wxFont::CreateGDIRefData() const |
f030b28c VZ |
865 | { |
866 | return new wxFontRefData(); | |
867 | } | |
868 | ||
8f884a0d | 869 | wxGDIRefData *wxFont::CloneGDIRefData(const wxGDIRefData *data) const |
f030b28c | 870 | { |
5c33522f | 871 | return new wxFontRefData(*static_cast<const wxFontRefData *>(data)); |
f030b28c VZ |
872 | } |
873 | ||
0c5d3e1c | 874 | bool wxFont::RealizeResource() |
2bda0e17 | 875 | { |
d014871d | 876 | // NOTE: the GetHFONT() call automatically triggers a reallocation of |
0572fce8 | 877 | // the HFONT if necessary (will do nothing if we already have the resource); |
d014871d FM |
878 | // it returns NULL only if there is a failure in wxFontRefData::Alloc()... |
879 | return GetHFONT() != NULL; | |
2bda0e17 KB |
880 | } |
881 | ||
33ac7e6f | 882 | bool wxFont::FreeResource(bool WXUNUSED(force)) |
2bda0e17 | 883 | { |
d014871d | 884 | if ( !M_FONTDATA ) |
adbd3cbc | 885 | return false; |
0c5d3e1c | 886 | |
adbd3cbc | 887 | M_FONTDATA->Free(); |
a9249b2e | 888 | |
adbd3cbc | 889 | return true; |
2bda0e17 KB |
890 | } |
891 | ||
2b5f62a0 | 892 | WXHANDLE wxFont::GetResourceHandle() const |
f6bcfd97 | 893 | { |
2b5f62a0 | 894 | return (WXHANDLE)GetHFONT(); |
f6bcfd97 BP |
895 | } |
896 | ||
897 | WXHFONT wxFont::GetHFONT() const | |
2bda0e17 | 898 | { |
d014871d FM |
899 | // NOTE: wxFontRefData::GetHFONT() will automatically call |
900 | // wxFontRefData::Alloc() if necessary | |
df898907 | 901 | return M_FONTDATA ? M_FONTDATA->GetHFONT() : 0; |
2bda0e17 KB |
902 | } |
903 | ||
e90babdf | 904 | bool wxFont::IsFree() const |
2bda0e17 | 905 | { |
8e34db1d | 906 | return M_FONTDATA && !M_FONTDATA->HasHFONT(); |
adbd3cbc VZ |
907 | } |
908 | ||
0c5d3e1c VZ |
909 | // ---------------------------------------------------------------------------- |
910 | // change font attribute: we recreate font when doing it | |
911 | // ---------------------------------------------------------------------------- | |
912 | ||
debe6624 | 913 | void wxFont::SetPointSize(int pointSize) |
2bda0e17 | 914 | { |
f030b28c | 915 | AllocExclusive(); |
b823f5a1 | 916 | |
8e34db1d | 917 | M_FONTDATA->Free(); |
a9249b2e | 918 | M_FONTDATA->SetPointSize(pointSize); |
2bda0e17 KB |
919 | } |
920 | ||
544229d1 VZ |
921 | void wxFont::SetPixelSize(const wxSize& pixelSize) |
922 | { | |
f030b28c | 923 | AllocExclusive(); |
544229d1 VZ |
924 | |
925 | M_FONTDATA->SetPixelSize(pixelSize); | |
544229d1 VZ |
926 | } |
927 | ||
0c14b6c3 | 928 | void wxFont::SetFamily(wxFontFamily family) |
2bda0e17 | 929 | { |
f030b28c | 930 | AllocExclusive(); |
b823f5a1 | 931 | |
a9249b2e | 932 | M_FONTDATA->SetFamily(family); |
2bda0e17 KB |
933 | } |
934 | ||
0c14b6c3 | 935 | void wxFont::SetStyle(wxFontStyle style) |
2bda0e17 | 936 | { |
f030b28c | 937 | AllocExclusive(); |
b823f5a1 | 938 | |
a9249b2e | 939 | M_FONTDATA->SetStyle(style); |
2bda0e17 KB |
940 | } |
941 | ||
0c14b6c3 | 942 | void wxFont::SetWeight(wxFontWeight weight) |
2bda0e17 | 943 | { |
f030b28c | 944 | AllocExclusive(); |
b823f5a1 | 945 | |
a9249b2e | 946 | M_FONTDATA->SetWeight(weight); |
2bda0e17 KB |
947 | } |
948 | ||
85ab460e | 949 | bool wxFont::SetFaceName(const wxString& faceName) |
2bda0e17 | 950 | { |
f030b28c | 951 | AllocExclusive(); |
b823f5a1 | 952 | |
8e34db1d VZ |
953 | if ( !M_FONTDATA->SetFaceName(faceName) ) |
954 | return false; | |
85ab460e VZ |
955 | |
956 | // NB: using win32's GetObject() API on M_FONTDATA->GetHFONT() | |
957 | // to retrieve a LOGFONT and then compare lf.lfFaceName | |
958 | // with given facename is not reliable at all: | |
959 | // Windows copies the facename given to ::CreateFontIndirect() | |
960 | // without any validity check. | |
961 | // Thus we use wxFontBase::SetFaceName to check if facename | |
962 | // is valid... | |
8e34db1d | 963 | return wxFontBase::SetFaceName(faceName); |
2bda0e17 KB |
964 | } |
965 | ||
debe6624 | 966 | void wxFont::SetUnderlined(bool underlined) |
2bda0e17 | 967 | { |
f030b28c | 968 | AllocExclusive(); |
b823f5a1 | 969 | |
a9249b2e | 970 | M_FONTDATA->SetUnderlined(underlined); |
2bda0e17 KB |
971 | } |
972 | ||
c7a49742 VZ |
973 | void wxFont::SetStrikethrough(bool strikethrough) |
974 | { | |
975 | AllocExclusive(); | |
976 | ||
977 | M_FONTDATA->SetStrikethrough(strikethrough); | |
978 | } | |
979 | ||
0c5d3e1c | 980 | void wxFont::SetEncoding(wxFontEncoding encoding) |
2bda0e17 | 981 | { |
f030b28c | 982 | AllocExclusive(); |
0c5d3e1c | 983 | |
a9249b2e | 984 | M_FONTDATA->SetEncoding(encoding); |
09fcd889 VZ |
985 | } |
986 | ||
9045ad9d | 987 | void wxFont::DoSetNativeFontInfo(const wxNativeFontInfo& info) |
09fcd889 | 988 | { |
f030b28c | 989 | AllocExclusive(); |
09fcd889 | 990 | |
8e34db1d | 991 | M_FONTDATA->SetNativeFontInfo(info); |
0c5d3e1c VZ |
992 | } |
993 | ||
994 | // ---------------------------------------------------------------------------- | |
995 | // accessors | |
996 | // ---------------------------------------------------------------------------- | |
997 | ||
998 | int wxFont::GetPointSize() const | |
999 | { | |
d014871d | 1000 | wxCHECK_MSG( IsOk(), 0, wxT("invalid font") ); |
789034a0 | 1001 | |
a9249b2e | 1002 | return M_FONTDATA->GetPointSize(); |
0c5d3e1c VZ |
1003 | } |
1004 | ||
544229d1 VZ |
1005 | wxSize wxFont::GetPixelSize() const |
1006 | { | |
d014871d | 1007 | wxCHECK_MSG( IsOk(), wxDefaultSize, wxT("invalid font") ); |
68585e17 | 1008 | |
544229d1 VZ |
1009 | return M_FONTDATA->GetPixelSize(); |
1010 | } | |
1011 | ||
1012 | bool wxFont::IsUsingSizeInPixels() const | |
1013 | { | |
d014871d | 1014 | wxCHECK_MSG( IsOk(), 0, wxT("invalid font") ); |
544229d1 VZ |
1015 | |
1016 | return M_FONTDATA->IsUsingSizeInPixels(); | |
1017 | } | |
1018 | ||
59b7da02 | 1019 | wxFontFamily wxFont::DoGetFamily() const |
0c5d3e1c | 1020 | { |
a9249b2e | 1021 | return M_FONTDATA->GetFamily(); |
2bda0e17 KB |
1022 | } |
1023 | ||
0c14b6c3 | 1024 | wxFontStyle wxFont::GetStyle() const |
2bda0e17 | 1025 | { |
d014871d | 1026 | wxCHECK_MSG( IsOk(), wxFONTSTYLE_MAX, wxT("invalid font") ); |
789034a0 | 1027 | |
a9249b2e | 1028 | return M_FONTDATA->GetStyle(); |
2bda0e17 KB |
1029 | } |
1030 | ||
0c14b6c3 | 1031 | wxFontWeight wxFont::GetWeight() const |
2bda0e17 | 1032 | { |
d014871d | 1033 | wxCHECK_MSG( IsOk(), wxFONTWEIGHT_MAX, wxT("invalid font") ); |
789034a0 | 1034 | |
a9249b2e | 1035 | return M_FONTDATA->GetWeight(); |
2bda0e17 KB |
1036 | } |
1037 | ||
0c5d3e1c VZ |
1038 | bool wxFont::GetUnderlined() const |
1039 | { | |
d014871d | 1040 | wxCHECK_MSG( IsOk(), false, wxT("invalid font") ); |
789034a0 | 1041 | |
a9249b2e | 1042 | return M_FONTDATA->GetUnderlined(); |
0c5d3e1c VZ |
1043 | } |
1044 | ||
c7a49742 VZ |
1045 | bool wxFont::GetStrikethrough() const |
1046 | { | |
1047 | wxCHECK_MSG( IsOk(), false, wxT("invalid font") ); | |
1048 | ||
1049 | return M_FONTDATA->GetStrikethrough(); | |
1050 | } | |
1051 | ||
0c5d3e1c VZ |
1052 | wxString wxFont::GetFaceName() const |
1053 | { | |
d014871d | 1054 | wxCHECK_MSG( IsOk(), wxEmptyString, wxT("invalid font") ); |
789034a0 | 1055 | |
a9249b2e | 1056 | return M_FONTDATA->GetFaceName(); |
0c5d3e1c VZ |
1057 | } |
1058 | ||
1059 | wxFontEncoding wxFont::GetEncoding() const | |
1060 | { | |
d014871d | 1061 | wxCHECK_MSG( IsOk(), wxFONTENCODING_DEFAULT, wxT("invalid font") ); |
789034a0 | 1062 | |
a9249b2e | 1063 | return M_FONTDATA->GetEncoding(); |
0c5d3e1c | 1064 | } |
a1d58ddc | 1065 | |
3bf5a59b | 1066 | const wxNativeFontInfo *wxFont::GetNativeFontInfo() const |
1e6feb95 | 1067 | { |
7c6e85dc | 1068 | return IsOk() ? &(M_FONTDATA->GetNativeFontInfo()) : NULL; |
09fcd889 VZ |
1069 | } |
1070 | ||
9cf8de4c VZ |
1071 | bool wxFont::IsFixedWidth() const |
1072 | { | |
d014871d FM |
1073 | wxCHECK_MSG( IsOk(), false, wxT("invalid font") ); |
1074 | ||
cd49ac33 VZ |
1075 | // LOGFONT doesn't contain the correct pitch information so we need to call |
1076 | // GetTextMetrics() to get it | |
1077 | ScreenHDC hdc; | |
1078 | SelectInHDC selectFont(hdc, M_FONTDATA->GetHFONT()); | |
9cf8de4c | 1079 | |
cd49ac33 VZ |
1080 | TEXTMETRIC tm; |
1081 | if ( !::GetTextMetrics(hdc, &tm) ) | |
1082 | { | |
1083 | wxLogLastError(wxT("GetTextMetrics")); | |
1084 | return false; | |
1085 | } | |
1086 | ||
1087 | // Quoting MSDN description of TMPF_FIXED_PITCH: "Note very carefully that | |
1088 | // those meanings are the opposite of what the constant name implies." | |
1089 | return !(tm.tmPitchAndFamily & TMPF_FIXED_PITCH); | |
9cf8de4c | 1090 | } |