]> git.saurik.com Git - wxWidgets.git/blob - src/msw/font.cpp
Revised Motif todo list
[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 #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("");
126
127 switch (M_FONTDATA->m_family)
128 {
129 case wxSCRIPT: ff_family = FF_SCRIPT ;
130 ff_face = "Script" ;
131 break ;
132 case wxDECORATIVE: ff_family = FF_DECORATIVE;
133 break;
134 case wxROMAN: ff_family = FF_ROMAN;
135 ff_face = "Times New Roman" ;
136 break;
137 case wxTELETYPE:
138 case wxMODERN: ff_family = FF_MODERN;
139 ff_face = "Courier New" ;
140 break;
141 case wxSWISS: ff_family = FF_SWISS;
142 ff_face = "Arial";
143 break;
144 case wxDEFAULT:
145 default: ff_family = FF_SWISS;
146 ff_face = "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 char* pzFace = (const char*) ff_face;
162 if (!M_FONTDATA->m_faceName.IsNull())
163 pzFace = (const char*) 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 FONT_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("Cannot create font","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()
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("");
312 switch (GetFamily())
313 {
314 case wxDECORATIVE:
315 fam = "wxDECORATIVE";
316 break;
317 case wxROMAN:
318 fam = "wxROMAN";
319 break;
320 case wxSCRIPT:
321 fam = "wxSCRIPT";
322 break;
323 case wxSWISS:
324 fam = "wxSWISS";
325 break;
326 case wxMODERN:
327 fam = "wxMODERN";
328 break;
329 case wxTELETYPE:
330 fam = "wxTELETYPE";
331 break;
332 default:
333 fam = "wxDEFAULT";
334 break;
335 }
336 return fam;
337 }
338
339 wxString wxFont::GetFaceName(void) const
340 {
341 wxString str("");
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("");
350 switch (GetStyle())
351 {
352 case wxITALIC:
353 styl = "wxITALIC";
354 break;
355 case wxSLANT:
356 styl = "wxSLANT";
357 break;
358 default:
359 styl = "wxNORMAL";
360 break;
361 }
362 return styl;
363 }
364
365 wxString wxFont::GetWeightString(void) const
366 {
367 wxString w("");
368 switch (GetWeight())
369 {
370 case wxBOLD:
371 w = "wxBOLD";
372 break;
373 case wxLIGHT:
374 w = "wxLIGHT";
375 break;
376 default:
377 w = "wxNORMAL";
378 break;
379 }
380 return w;
381 }
382