]>
Commit | Line | Data |
---|---|---|
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 | |
9 | // Licence: wxWindows licence | |
10 | ///////////////////////////////////////////////////////////////////////////// | |
11 | ||
12 | #ifdef __GNUG__ | |
13 | #pragma implementation "font.h" | |
14 | #endif | |
15 | ||
16 | // For compilers that support precompilation, includes "wx.h". | |
17 | #include "wx/wxprec.h" | |
18 | ||
19 | #ifdef __BORLANDC__ | |
20 | #pragma hdrstop | |
21 | #endif | |
22 | ||
23 | #ifndef WX_PRECOMP | |
24 | #include <stdio.h> | |
25 | #include "wx/setup.h" | |
26 | #include "wx/list.h" | |
27 | #include "wx/utils.h" | |
28 | #include "wx/app.h" | |
29 | #include "wx/font.h" | |
30 | #endif | |
31 | ||
32 | #include "wx/msw/private.h" | |
a3b46648 | 33 | #include <assert.h> |
2bda0e17 KB |
34 | |
35 | #if !USE_SHARED_LIBRARIES | |
36 | IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject) | |
37 | ||
47d67540 | 38 | #if wxUSE_PORTABLE_FONTS_IN_MSW |
2bda0e17 KB |
39 | IMPLEMENT_DYNAMIC_CLASS(wxFontNameDirectory, wxObject) |
40 | #endif | |
41 | ||
42 | #endif | |
43 | ||
44 | wxFontRefData::wxFontRefData(void) | |
45 | { | |
46 | m_style = 0; | |
47 | m_temporary = FALSE; | |
48 | m_pointSize = 0; | |
49 | m_family = 0; | |
50 | m_fontId = 0; | |
51 | m_style = 0; | |
52 | m_weight = 0; | |
53 | m_underlined = 0; | |
54 | m_faceName = ""; | |
55 | m_hFont = 0; | |
56 | } | |
57 | ||
b823f5a1 JS |
58 | wxFontRefData::wxFontRefData(const wxFontRefData& data) |
59 | { | |
60 | m_style = data.m_style; | |
61 | m_temporary = FALSE; | |
62 | m_pointSize = data.m_pointSize; | |
63 | m_family = data.m_family; | |
64 | m_fontId = data.m_fontId; | |
65 | m_style = data.m_style; | |
66 | m_weight = data.m_weight; | |
67 | m_underlined = data.m_underlined; | |
68 | m_faceName = data.m_faceName; | |
69 | m_hFont = 0; | |
70 | } | |
71 | ||
2bda0e17 KB |
72 | wxFontRefData::~wxFontRefData(void) |
73 | { | |
74 | if ( m_hFont ) | |
75 | ::DeleteObject((HFONT) m_hFont); | |
76 | } | |
77 | ||
78 | wxFont::wxFont(void) | |
79 | { | |
80 | if ( wxTheFontList ) | |
81 | wxTheFontList->Append(this); | |
82 | } | |
83 | ||
84 | /* Constructor for a font. Note that the real construction is done | |
85 | * in wxDC::SetFont, when information is available about scaling etc. | |
86 | */ | |
b823f5a1 | 87 | wxFont::wxFont(int pointSize, int family, int style, int weight, bool underlined, const wxString& faceName) |
2bda0e17 | 88 | { |
b823f5a1 | 89 | Create(pointSize, family, style, weight, underlined, faceName); |
2bda0e17 KB |
90 | |
91 | if ( wxTheFontList ) | |
92 | wxTheFontList->Append(this); | |
93 | } | |
94 | ||
b823f5a1 | 95 | bool wxFont::Create(int pointSize, int family, int style, int weight, bool underlined, const wxString& faceName) |
2bda0e17 KB |
96 | { |
97 | UnRef(); | |
98 | m_refData = new wxFontRefData; | |
99 | ||
b823f5a1 JS |
100 | M_FONTDATA->m_family = family; |
101 | M_FONTDATA->m_style = style; | |
102 | M_FONTDATA->m_weight = weight; | |
103 | M_FONTDATA->m_pointSize = pointSize; | |
104 | M_FONTDATA->m_underlined = underlined; | |
105 | M_FONTDATA->m_faceName = faceName; | |
2bda0e17 KB |
106 | |
107 | RealizeResource(); | |
108 | ||
109 | return TRUE; | |
110 | } | |
111 | ||
112 | wxFont::~wxFont() | |
113 | { | |
114 | if (wxTheFontList) | |
115 | wxTheFontList->DeleteObject(this); | |
116 | } | |
117 | ||
118 | bool wxFont::RealizeResource(void) | |
119 | { | |
120 | if (M_FONTDATA && !M_FONTDATA->m_hFont) | |
121 | { | |
122 | BYTE ff_italic; | |
123 | int ff_weight = 0; | |
124 | int ff_family = 0; | |
48a84964 | 125 | wxString ff_face(_T("")); |
2bda0e17 KB |
126 | |
127 | switch (M_FONTDATA->m_family) | |
128 | { | |
129 | case wxSCRIPT: ff_family = FF_SCRIPT ; | |
48a84964 | 130 | ff_face = _T("Script") ; |
2bda0e17 KB |
131 | break ; |
132 | case wxDECORATIVE: ff_family = FF_DECORATIVE; | |
133 | break; | |
134 | case wxROMAN: ff_family = FF_ROMAN; | |
48a84964 | 135 | ff_face = _T("Times New Roman") ; |
2bda0e17 KB |
136 | break; |
137 | case wxTELETYPE: | |
138 | case wxMODERN: ff_family = FF_MODERN; | |
48a84964 | 139 | ff_face = _T("Courier New") ; |
2bda0e17 KB |
140 | break; |
141 | case wxSWISS: ff_family = FF_SWISS; | |
48a84964 | 142 | ff_face = _T("Arial") ; |
2bda0e17 KB |
143 | break; |
144 | case wxDEFAULT: | |
145 | default: ff_family = FF_SWISS; | |
48a84964 | 146 | ff_face = _T("Arial") ; |
2bda0e17 KB |
147 | } |
148 | ||
149 | if (M_FONTDATA->m_style == wxITALIC || M_FONTDATA->m_style == wxSLANT) | |
150 | ff_italic = 1; | |
151 | else | |
152 | ff_italic = 0; | |
153 | ||
154 | if (M_FONTDATA->m_weight == wxNORMAL) | |
155 | ff_weight = FW_NORMAL; | |
156 | else if (M_FONTDATA->m_weight == wxLIGHT) | |
157 | ff_weight = FW_LIGHT; | |
158 | else if (M_FONTDATA->m_weight == wxBOLD) | |
159 | ff_weight = FW_BOLD; | |
160 | ||
837e5743 | 161 | const wxChar* pzFace = (const wxChar*) ff_face; |
34da0970 | 162 | if (!M_FONTDATA->m_faceName.IsNull()) |
837e5743 | 163 | pzFace = (const wxChar*) M_FONTDATA->m_faceName ; |
2bda0e17 KB |
164 | |
165 | /* Always calculate fonts using the screen DC (is this the best strategy?) | |
166 | * There may be confusion if a font is selected into a printer | |
167 | * DC (say), because the height will be calculated very differently. | |
168 | // What sort of display is it? | |
169 | int technology = ::GetDeviceCaps(dc, TECHNOLOGY); | |
170 | ||
171 | int nHeight; | |
172 | ||
173 | if (technology != DT_RASDISPLAY && technology != DT_RASPRINTER) | |
174 | { | |
175 | // Have to get screen DC Caps, because a metafile will return 0. | |
176 | HDC dc2 = ::GetDC(NULL); | |
177 | nHeight = M_FONTDATA->m_pointSize*GetDeviceCaps(dc2, LOGPIXELSY)/72; | |
178 | ::ReleaseDC(NULL, dc2); | |
179 | } | |
180 | else | |
181 | { | |
182 | nHeight = M_FONTDATA->m_pointSize*GetDeviceCaps(dc, LOGPIXELSY)/72; | |
183 | } | |
184 | */ | |
185 | // Have to get screen DC Caps, because a metafile will return 0. | |
186 | HDC dc2 = ::GetDC(NULL); | |
187 | int ppInch = ::GetDeviceCaps(dc2, LOGPIXELSY); | |
188 | ::ReleaseDC(NULL, dc2); | |
189 | ||
190 | // New behaviour: apparently ppInch varies according to | |
191 | // Large/Small Fonts setting in Windows. This messes | |
192 | // up fonts. So, set ppInch to a constant 96 dpi. | |
193 | ppInch = 96; | |
194 | ||
1f112209 | 195 | #if wxFONT_SIZE_COMPATIBILITY |
2bda0e17 KB |
196 | // Incorrect, but compatible with old wxWindows behaviour |
197 | int nHeight = (M_FONTDATA->m_pointSize*ppInch/72); | |
198 | #else | |
199 | // Correct for Windows compatibility | |
200 | int nHeight = - (M_FONTDATA->m_pointSize*ppInch/72); | |
201 | #endif | |
202 | ||
203 | bool ff_underline = M_FONTDATA->m_underlined; | |
204 | ||
205 | M_FONTDATA->m_hFont = (WXHFONT) CreateFont(nHeight, 0, 0, 0,ff_weight,ff_italic,(BYTE)ff_underline, | |
206 | 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, | |
34da0970 | 207 | PROOF_QUALITY, DEFAULT_PITCH | ff_family, pzFace); |
b2aef89b | 208 | #ifdef WXDEBUG_CREATE |
48a84964 | 209 | if (m_hFont==NULL) wxError(_T("Cannot create font"),_T("Internal Error")) ; |
2bda0e17 KB |
210 | #endif |
211 | return (M_FONTDATA->m_hFont != (WXHFONT) NULL); | |
212 | } | |
213 | return FALSE; | |
214 | } | |
215 | ||
216 | bool wxFont::FreeResource(bool force) | |
217 | { | |
218 | if (M_FONTDATA && M_FONTDATA->m_hFont) | |
219 | { | |
220 | ::DeleteObject((HFONT) M_FONTDATA->m_hFont); | |
221 | M_FONTDATA->m_hFont = 0; | |
222 | return TRUE; | |
223 | } | |
224 | return FALSE; | |
225 | } | |
226 | ||
b823f5a1 | 227 | WXHANDLE wxFont::GetResourceHandle() |
2bda0e17 KB |
228 | { |
229 | if ( !M_FONTDATA ) | |
230 | return 0; | |
231 | else | |
232 | return (WXHANDLE)M_FONTDATA->m_hFont ; | |
233 | } | |
234 | ||
e90babdf | 235 | bool wxFont::IsFree() const |
2bda0e17 KB |
236 | { |
237 | return (M_FONTDATA && (M_FONTDATA->m_hFont == 0)); | |
238 | } | |
239 | ||
b823f5a1 JS |
240 | void wxFont::Unshare() |
241 | { | |
242 | // Don't change shared data | |
243 | if (!m_refData) | |
244 | { | |
245 | m_refData = new wxFontRefData(); | |
246 | } | |
247 | else | |
248 | { | |
249 | wxFontRefData* ref = new wxFontRefData(*(wxFontRefData*)m_refData); | |
250 | UnRef(); | |
251 | m_refData = ref; | |
252 | } | |
253 | } | |
254 | ||
debe6624 | 255 | void wxFont::SetPointSize(int pointSize) |
2bda0e17 | 256 | { |
b823f5a1 JS |
257 | Unshare(); |
258 | ||
2bda0e17 | 259 | M_FONTDATA->m_pointSize = pointSize; |
b823f5a1 JS |
260 | |
261 | RealizeResource(); | |
2bda0e17 KB |
262 | } |
263 | ||
debe6624 | 264 | void wxFont::SetFamily(int family) |
2bda0e17 | 265 | { |
b823f5a1 JS |
266 | Unshare(); |
267 | ||
2bda0e17 | 268 | M_FONTDATA->m_family = family; |
b823f5a1 JS |
269 | |
270 | RealizeResource(); | |
2bda0e17 KB |
271 | } |
272 | ||
debe6624 | 273 | void wxFont::SetStyle(int style) |
2bda0e17 | 274 | { |
b823f5a1 JS |
275 | Unshare(); |
276 | ||
2bda0e17 | 277 | M_FONTDATA->m_style = style; |
b823f5a1 JS |
278 | |
279 | RealizeResource(); | |
2bda0e17 KB |
280 | } |
281 | ||
debe6624 | 282 | void wxFont::SetWeight(int weight) |
2bda0e17 | 283 | { |
b823f5a1 JS |
284 | Unshare(); |
285 | ||
2bda0e17 | 286 | M_FONTDATA->m_weight = weight; |
b823f5a1 JS |
287 | |
288 | RealizeResource(); | |
2bda0e17 KB |
289 | } |
290 | ||
291 | void wxFont::SetFaceName(const wxString& faceName) | |
292 | { | |
b823f5a1 JS |
293 | Unshare(); |
294 | ||
2bda0e17 | 295 | M_FONTDATA->m_faceName = faceName; |
b823f5a1 JS |
296 | |
297 | RealizeResource(); | |
2bda0e17 KB |
298 | } |
299 | ||
debe6624 | 300 | void wxFont::SetUnderlined(bool underlined) |
2bda0e17 | 301 | { |
b823f5a1 JS |
302 | Unshare(); |
303 | ||
2bda0e17 | 304 | M_FONTDATA->m_underlined = underlined; |
b823f5a1 JS |
305 | |
306 | RealizeResource(); | |
2bda0e17 KB |
307 | } |
308 | ||
309 | wxString wxFont::GetFamilyString(void) const | |
310 | { | |
48a84964 | 311 | wxString fam(_T("")); |
2bda0e17 KB |
312 | switch (GetFamily()) |
313 | { | |
314 | case wxDECORATIVE: | |
48a84964 | 315 | fam = _T("wxDECORATIVE"); |
2bda0e17 KB |
316 | break; |
317 | case wxROMAN: | |
48a84964 | 318 | fam = _T("wxROMAN"); |
2bda0e17 KB |
319 | break; |
320 | case wxSCRIPT: | |
48a84964 | 321 | fam = _T("wxSCRIPT"); |
2bda0e17 KB |
322 | break; |
323 | case wxSWISS: | |
48a84964 | 324 | fam = _T("wxSWISS"); |
2bda0e17 KB |
325 | break; |
326 | case wxMODERN: | |
48a84964 | 327 | fam = _T("wxMODERN"); |
2bda0e17 KB |
328 | break; |
329 | case wxTELETYPE: | |
48a84964 | 330 | fam = _T("wxTELETYPE"); |
2bda0e17 KB |
331 | break; |
332 | default: | |
48a84964 | 333 | fam = _T("wxDEFAULT"); |
2bda0e17 KB |
334 | break; |
335 | } | |
336 | return fam; | |
337 | } | |
338 | ||
2bda0e17 KB |
339 | wxString wxFont::GetFaceName(void) const |
340 | { | |
48a84964 | 341 | wxString str(_T("")); |
2bda0e17 KB |
342 | if (M_FONTDATA) |
343 | str = M_FONTDATA->m_faceName ; | |
344 | return str; | |
345 | } | |
346 | ||
347 | wxString wxFont::GetStyleString(void) const | |
348 | { | |
48a84964 | 349 | wxString styl(_T("")); |
2bda0e17 KB |
350 | switch (GetStyle()) |
351 | { | |
352 | case wxITALIC: | |
48a84964 | 353 | styl = _T("wxITALIC"); |
2bda0e17 KB |
354 | break; |
355 | case wxSLANT: | |
48a84964 | 356 | styl = _T("wxSLANT"); |
2bda0e17 KB |
357 | break; |
358 | default: | |
48a84964 | 359 | styl = _T("wxNORMAL"); |
2bda0e17 KB |
360 | break; |
361 | } | |
362 | return styl; | |
363 | } | |
364 | ||
365 | wxString wxFont::GetWeightString(void) const | |
366 | { | |
48a84964 | 367 | wxString w(_T("")); |
2bda0e17 KB |
368 | switch (GetWeight()) |
369 | { | |
370 | case wxBOLD: | |
48a84964 | 371 | w = _T("wxBOLD"); |
2bda0e17 KB |
372 | break; |
373 | case wxLIGHT: | |
48a84964 | 374 | w = _T("wxLIGHT"); |
2bda0e17 KB |
375 | break; |
376 | default: | |
48a84964 | 377 | w = _T("wxNORMAL"); |
2bda0e17 KB |
378 | break; |
379 | } | |
380 | return w; | |
381 | } | |
382 |