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