]>
Commit | Line | Data |
---|---|---|
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" | |
33 | #include <assert.h> | |
34 | ||
35 | #if !USE_SHARED_LIBRARIES | |
36 | IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject) | |
37 | ||
38 | #if wxUSE_PORTABLE_FONTS_IN_MSW | |
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 | ||
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 | ||
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 | */ | |
87 | wxFont::wxFont(int pointSize, int family, int style, int weight, bool underlined, const wxString& faceName) | |
88 | { | |
89 | Create(pointSize, family, style, weight, underlined, faceName); | |
90 | ||
91 | if ( wxTheFontList ) | |
92 | wxTheFontList->Append(this); | |
93 | } | |
94 | ||
95 | bool wxFont::Create(int pointSize, int family, int style, int weight, bool underlined, const wxString& faceName) | |
96 | { | |
97 | UnRef(); | |
98 | m_refData = new wxFontRefData; | |
99 | ||
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; | |
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; | |
125 | wxString ff_face(_T("")); | |
126 | ||
127 | switch (M_FONTDATA->m_family) | |
128 | { | |
129 | case wxSCRIPT: ff_family = FF_SCRIPT ; | |
130 | ff_face = _T("Script") ; | |
131 | break ; | |
132 | case wxDECORATIVE: ff_family = FF_DECORATIVE; | |
133 | break; | |
134 | case wxROMAN: ff_family = FF_ROMAN; | |
135 | ff_face = _T("Times New Roman") ; | |
136 | break; | |
137 | case wxTELETYPE: | |
138 | case wxMODERN: ff_family = FF_MODERN; | |
139 | ff_face = _T("Courier New") ; | |
140 | break; | |
141 | case wxSWISS: ff_family = FF_SWISS; | |
142 | ff_face = _T("Arial") ; | |
143 | break; | |
144 | case wxDEFAULT: | |
145 | default: ff_family = FF_SWISS; | |
146 | ff_face = _T("Arial") ; | |
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 | ||
161 | const wxChar* pzFace = (const wxChar*) ff_face; | |
162 | if (!M_FONTDATA->m_faceName.IsNull()) | |
163 | pzFace = (const wxChar*) M_FONTDATA->m_faceName ; | |
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 | ||
195 | #if wxFONT_SIZE_COMPATIBILITY | |
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, | |
207 | PROOF_QUALITY, DEFAULT_PITCH | ff_family, pzFace); | |
208 | #ifdef WXDEBUG_CREATE | |
209 | if (m_hFont==NULL) wxError(_T("Cannot create font"),_T("Internal Error")) ; | |
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 | ||
227 | WXHANDLE wxFont::GetResourceHandle() | |
228 | { | |
229 | if ( !M_FONTDATA ) | |
230 | return 0; | |
231 | else | |
232 | return (WXHANDLE)M_FONTDATA->m_hFont ; | |
233 | } | |
234 | ||
235 | bool wxFont::IsFree() const | |
236 | { | |
237 | return (M_FONTDATA && (M_FONTDATA->m_hFont == 0)); | |
238 | } | |
239 | ||
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 | ||
255 | void wxFont::SetPointSize(int pointSize) | |
256 | { | |
257 | Unshare(); | |
258 | ||
259 | M_FONTDATA->m_pointSize = pointSize; | |
260 | ||
261 | RealizeResource(); | |
262 | } | |
263 | ||
264 | void wxFont::SetFamily(int family) | |
265 | { | |
266 | Unshare(); | |
267 | ||
268 | M_FONTDATA->m_family = family; | |
269 | ||
270 | RealizeResource(); | |
271 | } | |
272 | ||
273 | void wxFont::SetStyle(int style) | |
274 | { | |
275 | Unshare(); | |
276 | ||
277 | M_FONTDATA->m_style = style; | |
278 | ||
279 | RealizeResource(); | |
280 | } | |
281 | ||
282 | void wxFont::SetWeight(int weight) | |
283 | { | |
284 | Unshare(); | |
285 | ||
286 | M_FONTDATA->m_weight = weight; | |
287 | ||
288 | RealizeResource(); | |
289 | } | |
290 | ||
291 | void wxFont::SetFaceName(const wxString& faceName) | |
292 | { | |
293 | Unshare(); | |
294 | ||
295 | M_FONTDATA->m_faceName = faceName; | |
296 | ||
297 | RealizeResource(); | |
298 | } | |
299 | ||
300 | void wxFont::SetUnderlined(bool underlined) | |
301 | { | |
302 | Unshare(); | |
303 | ||
304 | M_FONTDATA->m_underlined = underlined; | |
305 | ||
306 | RealizeResource(); | |
307 | } | |
308 | ||
309 | wxString wxFont::GetFamilyString(void) const | |
310 | { | |
311 | wxString fam(_T("")); | |
312 | switch (GetFamily()) | |
313 | { | |
314 | case wxDECORATIVE: | |
315 | fam = _T("wxDECORATIVE"); | |
316 | break; | |
317 | case wxROMAN: | |
318 | fam = _T("wxROMAN"); | |
319 | break; | |
320 | case wxSCRIPT: | |
321 | fam = _T("wxSCRIPT"); | |
322 | break; | |
323 | case wxSWISS: | |
324 | fam = _T("wxSWISS"); | |
325 | break; | |
326 | case wxMODERN: | |
327 | fam = _T("wxMODERN"); | |
328 | break; | |
329 | case wxTELETYPE: | |
330 | fam = _T("wxTELETYPE"); | |
331 | break; | |
332 | default: | |
333 | fam = _T("wxDEFAULT"); | |
334 | break; | |
335 | } | |
336 | return fam; | |
337 | } | |
338 | ||
339 | wxString wxFont::GetFaceName(void) const | |
340 | { | |
341 | wxString str(_T("")); | |
342 | if (M_FONTDATA) | |
343 | str = M_FONTDATA->m_faceName ; | |
344 | return str; | |
345 | } | |
346 | ||
347 | wxString wxFont::GetStyleString(void) const | |
348 | { | |
349 | wxString styl(_T("")); | |
350 | switch (GetStyle()) | |
351 | { | |
352 | case wxITALIC: | |
353 | styl = _T("wxITALIC"); | |
354 | break; | |
355 | case wxSLANT: | |
356 | styl = _T("wxSLANT"); | |
357 | break; | |
358 | default: | |
359 | styl = _T("wxNORMAL"); | |
360 | break; | |
361 | } | |
362 | return styl; | |
363 | } | |
364 | ||
365 | wxString wxFont::GetWeightString(void) const | |
366 | { | |
367 | wxString w(_T("")); | |
368 | switch (GetWeight()) | |
369 | { | |
370 | case wxBOLD: | |
371 | w = _T("wxBOLD"); | |
372 | break; | |
373 | case wxLIGHT: | |
374 | w = _T("wxLIGHT"); | |
375 | break; | |
376 | default: | |
377 | w = _T("wxNORMAL"); | |
378 | break; | |
379 | } | |
380 | return w; | |
381 | } | |
382 |