]> git.saurik.com Git - wxWidgets.git/blame - src/os2/font.cpp
fixed incorrect GetTextExtent for wxTELETYPE font
[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 10/////////////////////////////////////////////////////////////////////////////
7e99520b
DW
11#define DEBUG_PRINTF(NAME) { static int raz=0; \
12 printf( #NAME " %i\n",raz); fflush(stdout); \
13 raz++; \
14 }
15
16 #include <malloc.h>
17 #include <stdio.h>
18
19 int HeapCheck(void)
20 {
21 int rc;
22
23 if (_HEAPOK != (rc = _heapchk()))
24 {
25 switch(rc)
26 {
27 case _HEAPEMPTY:
28 puts("The heap has not been initialized.");
29 break;
30 case _HEAPBADNODE:
31 puts("A memory node is corrupted or the heap is damaged.");
32 break;
33 case _HEAPBADBEGIN:
34 puts("The heap specified is not valid.");
35 break;
36 }
37 fflush(stdout);
38 }
39 return 0;
40 }
0e320a79 41
21802234
DW
42// ============================================================================
43// declarations
44// ============================================================================
45
46// ----------------------------------------------------------------------------
47// headers
48// ----------------------------------------------------------------------------
49
7e99520b 50 #include <malloc.h>
21802234
DW
51// For compilers that support precompilation, includes "wx.h".
52#include "wx/wxprec.h"
0e320a79 53
21802234
DW
54#ifndef WX_PRECOMP
55 #include <stdio.h>
56 #include "wx/setup.h"
57 #include "wx/list.h"
58 #include "wx/utils.h"
59 #include "wx/app.h"
60 #include "wx/font.h"
61#endif // WX_PRECOMP
62
63#include "wx/os2/private.h"
0e320a79 64
21802234
DW
65 IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
66
67 #if wxUSE_PORTABLE_FONTS_IN_MSW
68 IMPLEMENT_DYNAMIC_CLASS(wxFontNameDirectory, wxObject)
69 #endif
0e320a79 70
21802234
DW
71// ----------------------------------------------------------------------------
72// wxFontRefData - the internal description of the font
73// ----------------------------------------------------------------------------
74
75class WXDLLEXPORT wxFontRefData: public wxGDIRefData
0e320a79 76{
21802234
DW
77friend class WXDLLEXPORT wxFont;
78
79public:
80 wxFontRefData()
81 {
82 Init(12, wxDEFAULT, wxNORMAL, wxNORMAL, FALSE,
83 "", wxFONTENCODING_DEFAULT);
84 }
85
86 wxFontRefData(const wxFontRefData& data)
87 {
88 Init(data.m_pointSize, data.m_family, data.m_style, data.m_weight,
89 data.m_underlined, data.m_faceName, data.m_encoding);
90
91 m_fontId = data.m_fontId;
92 }
93
94 wxFontRefData(int size,
95 int family,
96 int style,
97 int weight,
98 bool underlined,
99 const wxString& faceName,
100 wxFontEncoding encoding)
101 {
102 Init(size, family, style, weight, underlined, faceName, encoding);
103 }
0e320a79 104
21802234
DW
105 virtual ~wxFontRefData();
106
107protected:
108 // common part of all ctors
109 void Init(int size,
110 int family,
111 int style,
112 int weight,
113 bool underlined,
114 const wxString& faceName,
115 wxFontEncoding encoding);
116
117 // If TRUE, the pointer to the actual font is temporary and SHOULD NOT BE
118 // DELETED by destructor
119 bool m_temporary;
120
121 int m_fontId;
122
123 // font characterstics
124 int m_pointSize;
125 int m_family;
126 int m_style;
127 int m_weight;
128 bool m_underlined;
129 wxString m_faceName;
130 wxFontEncoding m_encoding;
131
132 // Windows font handle
133 WXHFONT m_hFont;
134};
135
136// ============================================================================
137// implementation
138// ============================================================================
139
140// ----------------------------------------------------------------------------
141// wxFontRefData
142// ----------------------------------------------------------------------------
143
144void wxFontRefData::Init(int pointSize,
145 int family,
146 int style,
147 int weight,
148 bool underlined,
149 const wxString& faceName,
150 wxFontEncoding encoding)
0e320a79 151{
21802234
DW
152 m_style = style;
153 m_pointSize = pointSize;
154 m_family = family;
155 m_style = style;
156 m_weight = weight;
157 m_underlined = underlined;
158 m_faceName = faceName;
159 m_encoding = encoding;
160
161 m_fontId = 0;
162 m_temporary = FALSE;
163
164 m_hFont = 0;
0e320a79
DW
165}
166
167wxFontRefData::~wxFontRefData()
168{
7e99520b 169DEBUG_PRINTF(wxFontRefData::~wxFontRefData!!!)
21802234
DW
170// TODO:
171// if ( m_hFont )
172// {
173// if ( !::DeleteObject((HFONT) m_hFont) )
174// {
175// wxLogLastError("DeleteObject(font)");
176// }
177// }
0e320a79
DW
178}
179
21802234
DW
180// ----------------------------------------------------------------------------
181// wxFont
182// ----------------------------------------------------------------------------
0e320a79 183
21802234 184void wxFont::Init()
0e320a79 185{
7e99520b
DW
186
187DEBUG_PRINTF(wxFontRefData::~wxFontRefData!!!)
188
0e320a79
DW
189 if ( wxTheFontList )
190 wxTheFontList->Append(this);
191}
192
21802234
DW
193/* Constructor for a font. Note that the real construction is done
194 * in wxDC::SetFont, when information is available about scaling etc.
195 */
196bool wxFont::Create(int pointSize,
197 int family,
198 int style,
199 int weight,
200 bool underlined,
201 const wxString& faceName,
202 wxFontEncoding encoding)
0e320a79
DW
203{
204 UnRef();
7e99520b 205DEBUG_PRINTF(wxFontRefData::~wxFontRefData!!!)
21802234
DW
206 m_refData = new wxFontRefData(pointSize, family, style, weight,
207 underlined, faceName, encoding);
0e320a79
DW
208
209 RealizeResource();
210
211 return TRUE;
212}
213
214wxFont::~wxFont()
215{
7e99520b
DW
216 int l;
217 l = sizeof(*this);
218HeapCheck();
219 _heap_check();
220
21802234 221 if ( wxTheFontList )
0e320a79 222 wxTheFontList->DeleteObject(this);
7e99520b
DW
223HeapCheck();
224 _heap_check();
225
0e320a79
DW
226}
227
21802234
DW
228// ----------------------------------------------------------------------------
229// real implementation
f6bcfd97
BP
230// Boris' Kovalenko comments:
231// Because OS/2 fonts are associated with PS we can not create the font
232// here, but we may check that font definition is true
21802234
DW
233// ----------------------------------------------------------------------------
234
0e320a79
DW
235bool wxFont::RealizeResource()
236{
7e99520b 237DEBUG_PRINTF(wxFont::RealizeResource)
21802234
DW
238 if ( GetResourceHandle() )
239 {
240 // VZ: the old code returned FALSE in this case, but it doesn't seem
241 // to make sense because the font _was_ created
223d09f6 242 wxLogDebug(wxT("Calling wxFont::RealizeResource() twice"));
21802234
DW
243
244 return TRUE;
245 }
246
f6bcfd97
BP
247 HPS hps;
248 FATTRS fAttrs;
249 FACENAMEDESC fName;
250 LONG fLid;
251
252 fAttrs.usRecordLength = sizeof(FATTRS);
253 fAttrs.fsFontUse = FATTR_FONTUSE_OUTLINE | // only outline fonts allowed
254 FATTR_FONTUSE_TRANSFORMABLE; // may be transformed
255 fAttrs.fsType = 0;
256 fAttrs.lMaxBaselineExt = fAttrs.lAveCharWidth = 0;
257 fAttrs.idRegistry = 0;
258 fAttrs.lMatch = 0;
259
260 fName.usSize = sizeof(FACENAMEDESC);
261 fName.usWidthClass = FWIDTH_NORMAL;
262 fName.usReserved = 0;
263 fName.flOptions = 0;
264
21802234
DW
265 wxString ff_face;
266
267// OS/2 combines the family with styles to give a facename
268
269 switch ( M_FONTDATA->m_family )
270 {
271 case wxSCRIPT:
21802234 272 case wxDECORATIVE:
21802234 273 case wxROMAN:
223d09f6 274 ff_face = wxT("Times New Roman") ;
21802234
DW
275 break;
276
277 case wxTELETYPE:
278 case wxMODERN:
f6bcfd97 279 ff_face = wxT("Courier") ;
21802234
DW
280 break;
281
282 case wxSWISS:
21802234
DW
283 case wxDEFAULT:
284 default:
f6bcfd97 285 ff_face = wxT("Helvetica") ;
21802234
DW
286 }
287
21802234
DW
288 switch ( M_FONTDATA->m_style )
289 {
290 case wxITALIC:
291 case wxSLANT:
f6bcfd97 292 fAttrs.fsSelection = FATTR_SEL_ITALIC;
21802234
DW
293 break;
294
295 default:
223d09f6 296 wxFAIL_MSG(wxT("unknown font slant"));
21802234
DW
297 // fall through
298
299 case wxNORMAL:
f6bcfd97 300 fAttrs.fsSelection = 0;
21802234
DW
301 }
302
21802234
DW
303 switch ( M_FONTDATA->m_weight )
304 {
305 default:
223d09f6 306 wxFAIL_MSG(wxT("unknown font weight"));
21802234
DW
307 // fall through
308
309 case wxNORMAL:
f6bcfd97 310 fName.usWeightClass = FWEIGHT_NORMAL;
21802234
DW
311 break;
312
313 case wxLIGHT:
f6bcfd97 314 fName.usWeightClass = FWEIGHT_LIGHT;
21802234
DW
315 break;
316
317 case wxBOLD:
f6bcfd97 318 fName.usWeightClass = FWEIGHT_BOLD;
21802234
DW
319 break;
320 }
7e99520b 321
f6bcfd97
BP
322 if( M_FONTDATA->m_underlined )
323 fAttrs.fsSelection |= FATTR_SEL_UNDERSCORE;
21802234
DW
324
325 wxFontEncoding encoding = M_FONTDATA->m_encoding;
326 if ( encoding == wxFONTENCODING_DEFAULT )
327 {
328 encoding = wxFont::GetDefaultEncoding();
329 }
330
21802234
DW
331 switch ( encoding )
332 {
333 case wxFONTENCODING_ISO8859_1:
334 case wxFONTENCODING_ISO8859_15:
335 case wxFONTENCODING_CP1250:
f6bcfd97 336 fAttrs.usCodePage = 1250;
21802234
DW
337 break;
338
339 case wxFONTENCODING_ISO8859_2:
340 case wxFONTENCODING_CP1252:
f6bcfd97 341 fAttrs.usCodePage = 1252;
21802234
DW
342 break;
343
344 case wxFONTENCODING_ISO8859_4:
345 case wxFONTENCODING_ISO8859_10:
f6bcfd97 346 fAttrs.usCodePage = 850; // what is baltic?
21802234
DW
347 break;
348
349 case wxFONTENCODING_ISO8859_5:
350 case wxFONTENCODING_CP1251:
f6bcfd97 351 fAttrs.usCodePage = 1251;
21802234
DW
352 break;
353
354 case wxFONTENCODING_ISO8859_6:
f6bcfd97 355 fAttrs.usCodePage = 850; // what is arabic?
21802234
DW
356 break;
357
358 case wxFONTENCODING_ISO8859_7:
f6bcfd97 359 fAttrs.usCodePage = 850; // what is greek
21802234
DW
360 break;
361
362 case wxFONTENCODING_ISO8859_8:
f6bcfd97 363 fAttrs.usCodePage = 850; // what is hebrew?
21802234
DW
364 break;
365
366 case wxFONTENCODING_ISO8859_9:
f6bcfd97 367 fAttrs.usCodePage = 857;
21802234
DW
368 break;
369
370 case wxFONTENCODING_ISO8859_11:
f6bcfd97 371 fAttrs.usCodePage = 850; // what is thai
21802234
DW
372 break;
373
374 case wxFONTENCODING_CP437:
f6bcfd97 375 fAttrs.usCodePage = 437;
21802234
DW
376 break;
377
378 default:
223d09f6 379 wxFAIL_MSG(wxT("unsupported encoding"));
21802234
DW
380 // fall through
381
382 case wxFONTENCODING_SYSTEM:
f6bcfd97 383 fAttrs.usCodePage = 850; // what is ANSI?
21802234
DW
384 break;
385 }
386
7e99520b 387// Now cheking
f6bcfd97
BP
388 fLid = 1;
389 hps = ::WinGetPS( HWND_DESKTOP );
390
391 long numLids = ::GpiQueryNumberSetIds( hps );
392 long gpiError;
7e99520b 393
f6bcfd97
BP
394 // First we should generate unique id
395 if( numLids )
396 {
397 long Types[255];
398 STR8 Names[255];
399 long lIds[255];
400
401 if( !GpiQuerySetIds(hps, numLids, Types, Names, lIds) )
402 {
403 ::WinReleasePS( hps );
404 return 0;
405 }
7e99520b 406
f6bcfd97
BP
407 for(unsigned long LCNum = 0; LCNum < numLids; LCNum++)
408 if(lIds[LCNum] == fLid)
409 ++fLid;
410 if(fLid > 254) // wow, no id available!
411 {
412 ::WinReleasePS( hps );
413 return 0;
414 }
415 }
416
417 // now building facestring
418 if(::GpiQueryFaceString(hps, ff_face.c_str(), &fName, FACESIZE, fAttrs.szFacename) == GPI_ERROR)
419 {
420 ::WinReleasePS( hps );
421 return 0;
422 }
423
424 // now creating font
425 WXHFONT hFont = (WXHFONT)0;
426
427 if(::GpiCreateLogFont(hps, NULL, fLid, &fAttrs) != GPI_ERROR)
428 M_FONTDATA->m_hFont = hFont = (WXHFONT)1;
429
430 if( hFont )
431 ::GpiDeleteSetId(hps, fLid);
432
433 ::WinReleasePS( hps );
434
21802234
DW
435 if ( !hFont )
436 {
437 wxLogLastError("CreateFont");
438 }
439
440 return hFont != 0;
441}
442
443bool wxFont::FreeResource(bool force)
444{
445 if ( GetResourceHandle() )
446 {
447// TODO:
448// if ( !::DeleteObject((HFONT) M_FONTDATA->m_hFont) )
449// {
450// wxLogLastError("DeleteObject(font)");
451// }
452
453 M_FONTDATA->m_hFont = 0;
454
455 return TRUE;
456 }
0e320a79
DW
457 return FALSE;
458}
459
21802234
DW
460WXHANDLE wxFont::GetResourceHandle()
461{
462 if ( !M_FONTDATA )
463 return 0;
464 else
465 return (WXHANDLE)M_FONTDATA->m_hFont ;
466}
467
468bool wxFont::IsFree() const
469{
470 return (M_FONTDATA && (M_FONTDATA->m_hFont == 0));
471}
472
0e320a79
DW
473void wxFont::Unshare()
474{
21802234
DW
475 // Don't change shared data
476 if ( !m_refData )
0e320a79 477 {
21802234
DW
478 m_refData = new wxFontRefData();
479 }
0e320a79
DW
480 else
481 {
21802234
DW
482 wxFontRefData* ref = new wxFontRefData(*M_FONTDATA);
483 UnRef();
484 m_refData = ref;
485 }
0e320a79
DW
486}
487
21802234
DW
488// ----------------------------------------------------------------------------
489// change font attribute: we recreate font when doing it
490// ----------------------------------------------------------------------------
491
0e320a79
DW
492void wxFont::SetPointSize(int pointSize)
493{
494 Unshare();
495
496 M_FONTDATA->m_pointSize = pointSize;
497
498 RealizeResource();
499}
500
501void wxFont::SetFamily(int family)
502{
503 Unshare();
504
505 M_FONTDATA->m_family = family;
506
507 RealizeResource();
508}
509
510void wxFont::SetStyle(int style)
511{
512 Unshare();
513
514 M_FONTDATA->m_style = style;
515
516 RealizeResource();
517}
518
519void wxFont::SetWeight(int weight)
520{
521 Unshare();
522
523 M_FONTDATA->m_weight = weight;
524
525 RealizeResource();
526}
527
528void wxFont::SetFaceName(const wxString& faceName)
529{
530 Unshare();
531
532 M_FONTDATA->m_faceName = faceName;
533
534 RealizeResource();
535}
536
537void wxFont::SetUnderlined(bool underlined)
538{
539 Unshare();
540
541 M_FONTDATA->m_underlined = underlined;
542
543 RealizeResource();
544}
545
21802234 546void wxFont::SetEncoding(wxFontEncoding encoding)
0e320a79 547{
21802234
DW
548 Unshare();
549
550 M_FONTDATA->m_encoding = encoding;
551
552 RealizeResource();
0e320a79
DW
553}
554
21802234
DW
555// ----------------------------------------------------------------------------
556// accessors
557// ----------------------------------------------------------------------------
558
559int wxFont::GetPointSize() const
0e320a79 560{
7e99520b
DW
561DEBUG_PRINTF(wxFont::GetPointSize)
562 wxFontRefData* pTmp;
563
564 pTmp = M_FONTDATA;
565 if(pTmp)
566 return pTmp->m_pointSize;
567 else
568 return 10;
0e320a79
DW
569}
570
21802234 571int wxFont::GetFamily() const
0e320a79 572{
21802234
DW
573 return M_FONTDATA->m_family;
574}
575
576int wxFont::GetFontId() const
577{
578 return M_FONTDATA->m_fontId;
579}
580
581int wxFont::GetStyle() const
582{
583 return M_FONTDATA->m_style;
584}
585
586int wxFont::GetWeight() const
587{
588 return M_FONTDATA->m_weight;
589}
590
591bool wxFont::GetUnderlined() const
592{
593 return M_FONTDATA->m_underlined;
594}
595
596wxString wxFont::GetFaceName() const
597{
598 wxString str;
599 if ( M_FONTDATA )
600 str = M_FONTDATA->m_faceName ;
601 return str;
602}
603
604wxFontEncoding wxFont::GetEncoding() const
605{
606 return M_FONTDATA->m_encoding;
0e320a79
DW
607}
608