]> git.saurik.com Git - wxWidgets.git/blame - src/os2/font.cpp
Rotated text patch from Hans-Joachim Baader (with some corrections)
[wxWidgets.git] / src / os2 / font.cpp
CommitLineData
0e320a79
DW
1/////////////////////////////////////////////////////////////////////////////
2// Name: font.cpp
3// Purpose: wxFont class
21802234 4// Author: David Webster
0e320a79 5// Modified by:
21802234 6// Created: 10/06/99
0e320a79 7// RCS-ID: $Id$
21802234
DW
8// Copyright: (c) David Webster
9// Licence: wxWindows licence
0e320a79
DW
10/////////////////////////////////////////////////////////////////////////////
11
21802234
DW
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
20// For compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
0e320a79 22
21802234
DW
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 // WX_PRECOMP
31
32#include "wx/os2/private.h"
0e320a79
DW
33
34#if !USE_SHARED_LIBRARIES
21802234
DW
35 IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
36
37 #if wxUSE_PORTABLE_FONTS_IN_MSW
38 IMPLEMENT_DYNAMIC_CLASS(wxFontNameDirectory, wxObject)
39 #endif
0e320a79
DW
40#endif
41
21802234
DW
42// ----------------------------------------------------------------------------
43// wxFontRefData - the internal description of the font
44// ----------------------------------------------------------------------------
45
46class WXDLLEXPORT wxFontRefData: public wxGDIRefData
0e320a79 47{
21802234
DW
48friend class WXDLLEXPORT wxFont;
49
50public:
51 wxFontRefData()
52 {
53 Init(12, wxDEFAULT, wxNORMAL, wxNORMAL, FALSE,
54 "", wxFONTENCODING_DEFAULT);
55 }
56
57 wxFontRefData(const wxFontRefData& data)
58 {
59 Init(data.m_pointSize, data.m_family, data.m_style, data.m_weight,
60 data.m_underlined, data.m_faceName, data.m_encoding);
61
62 m_fontId = data.m_fontId;
63 }
64
65 wxFontRefData(int size,
66 int family,
67 int style,
68 int weight,
69 bool underlined,
70 const wxString& faceName,
71 wxFontEncoding encoding)
72 {
73 Init(size, family, style, weight, underlined, faceName, encoding);
74 }
0e320a79 75
21802234
DW
76 virtual ~wxFontRefData();
77
78protected:
79 // common part of all ctors
80 void Init(int size,
81 int family,
82 int style,
83 int weight,
84 bool underlined,
85 const wxString& faceName,
86 wxFontEncoding encoding);
87
88 // If TRUE, the pointer to the actual font is temporary and SHOULD NOT BE
89 // DELETED by destructor
90 bool m_temporary;
91
92 int m_fontId;
93
94 // font characterstics
95 int m_pointSize;
96 int m_family;
97 int m_style;
98 int m_weight;
99 bool m_underlined;
100 wxString m_faceName;
101 wxFontEncoding m_encoding;
102
103 // Windows font handle
104 WXHFONT m_hFont;
105};
106
107// ============================================================================
108// implementation
109// ============================================================================
110
111// ----------------------------------------------------------------------------
112// wxFontRefData
113// ----------------------------------------------------------------------------
114
115void wxFontRefData::Init(int pointSize,
116 int family,
117 int style,
118 int weight,
119 bool underlined,
120 const wxString& faceName,
121 wxFontEncoding encoding)
0e320a79 122{
21802234
DW
123 m_style = style;
124 m_pointSize = pointSize;
125 m_family = family;
126 m_style = style;
127 m_weight = weight;
128 m_underlined = underlined;
129 m_faceName = faceName;
130 m_encoding = encoding;
131
132 m_fontId = 0;
133 m_temporary = FALSE;
134
135 m_hFont = 0;
0e320a79
DW
136}
137
138wxFontRefData::~wxFontRefData()
139{
21802234
DW
140// TODO:
141// if ( m_hFont )
142// {
143// if ( !::DeleteObject((HFONT) m_hFont) )
144// {
145// wxLogLastError("DeleteObject(font)");
146// }
147// }
0e320a79
DW
148}
149
21802234
DW
150// ----------------------------------------------------------------------------
151// wxFont
152// ----------------------------------------------------------------------------
0e320a79 153
21802234 154void wxFont::Init()
0e320a79 155{
0e320a79
DW
156 if ( wxTheFontList )
157 wxTheFontList->Append(this);
158}
159
21802234
DW
160/* Constructor for a font. Note that the real construction is done
161 * in wxDC::SetFont, when information is available about scaling etc.
162 */
163bool wxFont::Create(int pointSize,
164 int family,
165 int style,
166 int weight,
167 bool underlined,
168 const wxString& faceName,
169 wxFontEncoding encoding)
0e320a79
DW
170{
171 UnRef();
21802234
DW
172 m_refData = new wxFontRefData(pointSize, family, style, weight,
173 underlined, faceName, encoding);
0e320a79
DW
174
175 RealizeResource();
176
177 return TRUE;
178}
179
180wxFont::~wxFont()
181{
21802234 182 if ( wxTheFontList )
0e320a79
DW
183 wxTheFontList->DeleteObject(this);
184}
185
21802234
DW
186// ----------------------------------------------------------------------------
187// real implementation
188// ----------------------------------------------------------------------------
189
0e320a79
DW
190bool wxFont::RealizeResource()
191{
21802234
DW
192 if ( GetResourceHandle() )
193 {
194 // VZ: the old code returned FALSE in this case, but it doesn't seem
195 // to make sense because the font _was_ created
223d09f6 196 wxLogDebug(wxT("Calling wxFont::RealizeResource() twice"));
21802234
DW
197
198 return TRUE;
199 }
200
201 int ff_family = 0;
202 wxString ff_face;
203
204// OS/2 combines the family with styles to give a facename
205
206 switch ( M_FONTDATA->m_family )
207 {
208 case wxSCRIPT:
209// ff_family = FF_SCRIPT ;
223d09f6 210 ff_face = wxT("Script") ;
21802234
DW
211 break ;
212
213 case wxDECORATIVE:
214// ff_family = FF_DECORATIVE;
215 break;
216
217 case wxROMAN:
218// ff_family = FF_ROMAN;
223d09f6 219 ff_face = wxT("Times New Roman") ;
21802234
DW
220 break;
221
222 case wxTELETYPE:
223 case wxMODERN:
224// ff_family = FF_MODERN;
223d09f6 225 ff_face = wxT("Courier New") ;
21802234
DW
226 break;
227
228 case wxSWISS:
229// ff_family = FF_SWISS;
223d09f6 230 ff_face = wxT("Arial") ;
21802234
DW
231 break;
232
233 case wxDEFAULT:
234 default:
235// ff_family = FF_SWISS;
223d09f6 236 ff_face = wxT("Arial") ;
21802234
DW
237 }
238
239 BYTE ff_italic;
240 switch ( M_FONTDATA->m_style )
241 {
242 case wxITALIC:
243 case wxSLANT:
244 ff_italic = 1;
245 break;
246
247 default:
223d09f6 248 wxFAIL_MSG(wxT("unknown font slant"));
21802234
DW
249 // fall through
250
251 case wxNORMAL:
252 ff_italic = 0;
253 }
254
255 int ff_weight = 0;
256 switch ( M_FONTDATA->m_weight )
257 {
258 default:
223d09f6 259 wxFAIL_MSG(wxT("unknown font weight"));
21802234
DW
260 // fall through
261
262 case wxNORMAL:
263// ff_weight = FW_NORMAL;
264 break;
265
266 case wxLIGHT:
267// ff_weight = FW_LIGHT;
268 break;
269
270 case wxBOLD:
271// ff_weight = FW_BOLD;
272 break;
273 }
274
275 const wxChar* pzFace;
276 if ( M_FONTDATA->m_faceName.IsEmpty() )
277 pzFace = ff_face;
278 else
279 pzFace = M_FONTDATA->m_faceName ;
280
281#if 0
282 /* Always calculate fonts using the screen DC (is this the best strategy?)
283 * There may be confusion if a font is selected into a printer
284 * DC (say), because the height will be calculated very differently.
285 */
286 // What sort of display is it?
287 int technology = ::GetDeviceCaps(dc, TECHNOLOGY);
288
289 int nHeight;
290
291 if (technology != DT_RASDISPLAY && technology != DT_RASPRINTER)
292 {
293 // Have to get screen DC Caps, because a metafile will return 0.
294 HDC dc2 = ::GetDC(NULL);
295 nHeight = M_FONTDATA->m_pointSize*GetDeviceCaps(dc2, LOGPIXELSY)/72;
296 ::ReleaseDC(NULL, dc2);
297 }
298 else
299 {
300 nHeight = M_FONTDATA->m_pointSize*GetDeviceCaps(dc, LOGPIXELSY)/72;
301 }
302#endif // 0
303
304#if 0
305 // Have to get screen DC Caps, because a metafile will return 0.
306 HDC dc2 = ::GetDC(NULL);
307 ppInch = ::GetDeviceCaps(dc2, LOGPIXELSY);
308 ::ReleaseDC(NULL, dc2);
309#endif // 0
310
311 // New behaviour: apparently ppInch varies according to Large/Small Fonts
312 // setting in Windows. This messes up fonts. So, set ppInch to a constant
313 // 96 dpi.
314 static const int ppInch = 96;
315
316#if wxFONT_SIZE_COMPATIBILITY
317 // Incorrect, but compatible with old wxWindows behaviour
318 int nHeight = (M_FONTDATA->m_pointSize*ppInch/72);
319#else
320 // Correct for Windows compatibility
321 int nHeight = - (M_FONTDATA->m_pointSize*ppInch/72);
322#endif
323
324 BYTE ff_underline = M_FONTDATA->m_underlined;
325
326 wxFontEncoding encoding = M_FONTDATA->m_encoding;
327 if ( encoding == wxFONTENCODING_DEFAULT )
328 {
329 encoding = wxFont::GetDefaultEncoding();
330 }
331
332 DWORD charset;
333 switch ( encoding )
334 {
335 case wxFONTENCODING_ISO8859_1:
336 case wxFONTENCODING_ISO8859_15:
337 case wxFONTENCODING_CP1250:
338// charset = ANSI_CHARSET;
339 break;
340
341 case wxFONTENCODING_ISO8859_2:
342 case wxFONTENCODING_CP1252:
343// charset = EASTEUROPE_CHARSET;
344 break;
345
346 case wxFONTENCODING_ISO8859_4:
347 case wxFONTENCODING_ISO8859_10:
348// charset = BALTIC_CHARSET;
349 break;
350
351 case wxFONTENCODING_ISO8859_5:
352 case wxFONTENCODING_CP1251:
353// charset = RUSSIAN_CHARSET;
354 break;
355
356 case wxFONTENCODING_ISO8859_6:
357// charset = ARABIC_CHARSET;
358 break;
359
360 case wxFONTENCODING_ISO8859_7:
361// charset = GREEK_CHARSET;
362 break;
363
364 case wxFONTENCODING_ISO8859_8:
365// charset = HEBREW_CHARSET;
366 break;
367
368 case wxFONTENCODING_ISO8859_9:
369// charset = TURKISH_CHARSET;
370 break;
371
372 case wxFONTENCODING_ISO8859_11:
373// charset = THAI_CHARSET;
374 break;
375
376 case wxFONTENCODING_CP437:
377// charset = OEM_CHARSET;
378 break;
379
380 default:
223d09f6 381 wxFAIL_MSG(wxT("unsupported encoding"));
21802234
DW
382 // fall through
383
384 case wxFONTENCODING_SYSTEM:
385// charset = ANSI_CHARSET;
386 break;
387 }
388
389// TODO:
390WXHFONT hFont;
391// HFONT hFont = ::CreateFont
392// (
393// nHeight, // height
394// 0, // width (choose best)
395// 0, // escapement
396// 0, // orientation
397// ff_weight, // weight
398// ff_italic, // italic?
399// ff_underline, // underlined?
400// 0, // strikeout?
401// charset, // charset
402// OUT_DEFAULT_PRECIS, // precision
403// CLIP_DEFAULT_PRECIS, // clip precision
404// PROOF_QUALITY, // quality of match
405// DEFAULT_PITCH | // fixed or variable
406// ff_family, // family id
407// pzFace // face name
408// );
409
410 M_FONTDATA->m_hFont = (WXHFONT)hFont;
411 if ( !hFont )
412 {
413 wxLogLastError("CreateFont");
414 }
415
416 return hFont != 0;
417}
418
419bool wxFont::FreeResource(bool force)
420{
421 if ( GetResourceHandle() )
422 {
423// TODO:
424// if ( !::DeleteObject((HFONT) M_FONTDATA->m_hFont) )
425// {
426// wxLogLastError("DeleteObject(font)");
427// }
428
429 M_FONTDATA->m_hFont = 0;
430
431 return TRUE;
432 }
0e320a79
DW
433 return FALSE;
434}
435
21802234
DW
436WXHANDLE wxFont::GetResourceHandle()
437{
438 if ( !M_FONTDATA )
439 return 0;
440 else
441 return (WXHANDLE)M_FONTDATA->m_hFont ;
442}
443
444bool wxFont::IsFree() const
445{
446 return (M_FONTDATA && (M_FONTDATA->m_hFont == 0));
447}
448
0e320a79
DW
449void wxFont::Unshare()
450{
21802234
DW
451 // Don't change shared data
452 if ( !m_refData )
0e320a79 453 {
21802234
DW
454 m_refData = new wxFontRefData();
455 }
0e320a79
DW
456 else
457 {
21802234
DW
458 wxFontRefData* ref = new wxFontRefData(*M_FONTDATA);
459 UnRef();
460 m_refData = ref;
461 }
0e320a79
DW
462}
463
21802234
DW
464// ----------------------------------------------------------------------------
465// change font attribute: we recreate font when doing it
466// ----------------------------------------------------------------------------
467
0e320a79
DW
468void wxFont::SetPointSize(int pointSize)
469{
470 Unshare();
471
472 M_FONTDATA->m_pointSize = pointSize;
473
474 RealizeResource();
475}
476
477void wxFont::SetFamily(int family)
478{
479 Unshare();
480
481 M_FONTDATA->m_family = family;
482
483 RealizeResource();
484}
485
486void wxFont::SetStyle(int style)
487{
488 Unshare();
489
490 M_FONTDATA->m_style = style;
491
492 RealizeResource();
493}
494
495void wxFont::SetWeight(int weight)
496{
497 Unshare();
498
499 M_FONTDATA->m_weight = weight;
500
501 RealizeResource();
502}
503
504void wxFont::SetFaceName(const wxString& faceName)
505{
506 Unshare();
507
508 M_FONTDATA->m_faceName = faceName;
509
510 RealizeResource();
511}
512
513void wxFont::SetUnderlined(bool underlined)
514{
515 Unshare();
516
517 M_FONTDATA->m_underlined = underlined;
518
519 RealizeResource();
520}
521
21802234 522void wxFont::SetEncoding(wxFontEncoding encoding)
0e320a79 523{
21802234
DW
524 Unshare();
525
526 M_FONTDATA->m_encoding = encoding;
527
528 RealizeResource();
0e320a79
DW
529}
530
21802234
DW
531// ----------------------------------------------------------------------------
532// accessors
533// ----------------------------------------------------------------------------
534
535int wxFont::GetPointSize() const
0e320a79 536{
21802234 537 return M_FONTDATA->m_pointSize;
0e320a79
DW
538}
539
21802234 540int wxFont::GetFamily() const
0e320a79 541{
21802234
DW
542 return M_FONTDATA->m_family;
543}
544
545int wxFont::GetFontId() const
546{
547 return M_FONTDATA->m_fontId;
548}
549
550int wxFont::GetStyle() const
551{
552 return M_FONTDATA->m_style;
553}
554
555int wxFont::GetWeight() const
556{
557 return M_FONTDATA->m_weight;
558}
559
560bool wxFont::GetUnderlined() const
561{
562 return M_FONTDATA->m_underlined;
563}
564
565wxString wxFont::GetFaceName() const
566{
567 wxString str;
568 if ( M_FONTDATA )
569 str = M_FONTDATA->m_faceName ;
570 return str;
571}
572
573wxFontEncoding wxFont::GetEncoding() const
574{
575 return M_FONTDATA->m_encoding;
0e320a79
DW
576}
577