]> git.saurik.com Git - wxWidgets.git/blame - src/os2/font.cpp
Added chapter on collection and container classes to contents
[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 33
21802234
DW
34 IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
35
36 #if wxUSE_PORTABLE_FONTS_IN_MSW
37 IMPLEMENT_DYNAMIC_CLASS(wxFontNameDirectory, wxObject)
38 #endif
0e320a79 39
21802234
DW
40// ----------------------------------------------------------------------------
41// wxFontRefData - the internal description of the font
42// ----------------------------------------------------------------------------
43
44class WXDLLEXPORT wxFontRefData: public wxGDIRefData
0e320a79 45{
21802234
DW
46friend class WXDLLEXPORT wxFont;
47
48public:
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 }
0e320a79 73
21802234
DW
74 virtual ~wxFontRefData();
75
76protected:
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
113void wxFontRefData::Init(int pointSize,
114 int family,
115 int style,
116 int weight,
117 bool underlined,
118 const wxString& faceName,
119 wxFontEncoding encoding)
0e320a79 120{
21802234
DW
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;
0e320a79
DW
134}
135
136wxFontRefData::~wxFontRefData()
137{
21802234
DW
138// TODO:
139// if ( m_hFont )
140// {
141// if ( !::DeleteObject((HFONT) m_hFont) )
142// {
143// wxLogLastError("DeleteObject(font)");
144// }
145// }
0e320a79
DW
146}
147
21802234
DW
148// ----------------------------------------------------------------------------
149// wxFont
150// ----------------------------------------------------------------------------
0e320a79 151
21802234 152void wxFont::Init()
0e320a79 153{
0e320a79
DW
154 if ( wxTheFontList )
155 wxTheFontList->Append(this);
156}
157
21802234
DW
158/* Constructor for a font. Note that the real construction is done
159 * in wxDC::SetFont, when information is available about scaling etc.
160 */
161bool wxFont::Create(int pointSize,
162 int family,
163 int style,
164 int weight,
165 bool underlined,
166 const wxString& faceName,
167 wxFontEncoding encoding)
0e320a79
DW
168{
169 UnRef();
21802234
DW
170 m_refData = new wxFontRefData(pointSize, family, style, weight,
171 underlined, faceName, encoding);
0e320a79
DW
172
173 RealizeResource();
174
175 return TRUE;
176}
177
178wxFont::~wxFont()
179{
21802234 180 if ( wxTheFontList )
0e320a79
DW
181 wxTheFontList->DeleteObject(this);
182}
183
21802234
DW
184// ----------------------------------------------------------------------------
185// real implementation
f6bcfd97
BP
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
21802234
DW
189// ----------------------------------------------------------------------------
190
0e320a79
DW
191bool wxFont::RealizeResource()
192{
21802234
DW
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
223d09f6 197 wxLogDebug(wxT("Calling wxFont::RealizeResource() twice"));
21802234
DW
198
199 return TRUE;
200 }
201
f6bcfd97
BP
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
21802234
DW
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:
21802234 227 case wxDECORATIVE:
21802234 228 case wxROMAN:
223d09f6 229 ff_face = wxT("Times New Roman") ;
21802234
DW
230 break;
231
232 case wxTELETYPE:
233 case wxMODERN:
f6bcfd97 234 ff_face = wxT("Courier") ;
21802234
DW
235 break;
236
237 case wxSWISS:
21802234
DW
238 case wxDEFAULT:
239 default:
f6bcfd97 240 ff_face = wxT("Helvetica") ;
21802234
DW
241 }
242
21802234
DW
243 switch ( M_FONTDATA->m_style )
244 {
245 case wxITALIC:
246 case wxSLANT:
f6bcfd97 247 fAttrs.fsSelection = FATTR_SEL_ITALIC;
21802234
DW
248 break;
249
250 default:
223d09f6 251 wxFAIL_MSG(wxT("unknown font slant"));
21802234
DW
252 // fall through
253
254 case wxNORMAL:
f6bcfd97 255 fAttrs.fsSelection = 0;
21802234
DW
256 }
257
21802234
DW
258 switch ( M_FONTDATA->m_weight )
259 {
260 default:
223d09f6 261 wxFAIL_MSG(wxT("unknown font weight"));
21802234
DW
262 // fall through
263
264 case wxNORMAL:
f6bcfd97 265 fName.usWeightClass = FWEIGHT_NORMAL;
21802234
DW
266 break;
267
268 case wxLIGHT:
f6bcfd97 269 fName.usWeightClass = FWEIGHT_LIGHT;
21802234
DW
270 break;
271
272 case wxBOLD:
f6bcfd97 273 fName.usWeightClass = FWEIGHT_BOLD;
21802234
DW
274 break;
275 }
f6bcfd97
BP
276
277 if( M_FONTDATA->m_underlined )
278 fAttrs.fsSelection |= FATTR_SEL_UNDERSCORE;
21802234
DW
279
280 wxFontEncoding encoding = M_FONTDATA->m_encoding;
281 if ( encoding == wxFONTENCODING_DEFAULT )
282 {
283 encoding = wxFont::GetDefaultEncoding();
284 }
285
21802234
DW
286 switch ( encoding )
287 {
288 case wxFONTENCODING_ISO8859_1:
289 case wxFONTENCODING_ISO8859_15:
290 case wxFONTENCODING_CP1250:
f6bcfd97 291 fAttrs.usCodePage = 1250;
21802234
DW
292 break;
293
294 case wxFONTENCODING_ISO8859_2:
295 case wxFONTENCODING_CP1252:
f6bcfd97 296 fAttrs.usCodePage = 1252;
21802234
DW
297 break;
298
299 case wxFONTENCODING_ISO8859_4:
300 case wxFONTENCODING_ISO8859_10:
f6bcfd97 301 fAttrs.usCodePage = 850; // what is baltic?
21802234
DW
302 break;
303
304 case wxFONTENCODING_ISO8859_5:
305 case wxFONTENCODING_CP1251:
f6bcfd97 306 fAttrs.usCodePage = 1251;
21802234
DW
307 break;
308
309 case wxFONTENCODING_ISO8859_6:
f6bcfd97 310 fAttrs.usCodePage = 850; // what is arabic?
21802234
DW
311 break;
312
313 case wxFONTENCODING_ISO8859_7:
f6bcfd97 314 fAttrs.usCodePage = 850; // what is greek
21802234
DW
315 break;
316
317 case wxFONTENCODING_ISO8859_8:
f6bcfd97 318 fAttrs.usCodePage = 850; // what is hebrew?
21802234
DW
319 break;
320
321 case wxFONTENCODING_ISO8859_9:
f6bcfd97 322 fAttrs.usCodePage = 857;
21802234
DW
323 break;
324
325 case wxFONTENCODING_ISO8859_11:
f6bcfd97 326 fAttrs.usCodePage = 850; // what is thai
21802234
DW
327 break;
328
329 case wxFONTENCODING_CP437:
f6bcfd97 330 fAttrs.usCodePage = 437;
21802234
DW
331 break;
332
333 default:
223d09f6 334 wxFAIL_MSG(wxT("unsupported encoding"));
21802234
DW
335 // fall through
336
337 case wxFONTENCODING_SYSTEM:
f6bcfd97 338 fAttrs.usCodePage = 850; // what is ANSI?
21802234
DW
339 break;
340 }
341
f6bcfd97
BP
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
21802234
DW
390 if ( !hFont )
391 {
392 wxLogLastError("CreateFont");
393 }
394
395 return hFont != 0;
396}
397
398bool 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 }
0e320a79
DW
412 return FALSE;
413}
414
21802234
DW
415WXHANDLE wxFont::GetResourceHandle()
416{
417 if ( !M_FONTDATA )
418 return 0;
419 else
420 return (WXHANDLE)M_FONTDATA->m_hFont ;
421}
422
423bool wxFont::IsFree() const
424{
425 return (M_FONTDATA && (M_FONTDATA->m_hFont == 0));
426}
427
0e320a79
DW
428void wxFont::Unshare()
429{
21802234
DW
430 // Don't change shared data
431 if ( !m_refData )
0e320a79 432 {
21802234
DW
433 m_refData = new wxFontRefData();
434 }
0e320a79
DW
435 else
436 {
21802234
DW
437 wxFontRefData* ref = new wxFontRefData(*M_FONTDATA);
438 UnRef();
439 m_refData = ref;
440 }
0e320a79
DW
441}
442
21802234
DW
443// ----------------------------------------------------------------------------
444// change font attribute: we recreate font when doing it
445// ----------------------------------------------------------------------------
446
0e320a79
DW
447void wxFont::SetPointSize(int pointSize)
448{
449 Unshare();
450
451 M_FONTDATA->m_pointSize = pointSize;
452
453 RealizeResource();
454}
455
456void wxFont::SetFamily(int family)
457{
458 Unshare();
459
460 M_FONTDATA->m_family = family;
461
462 RealizeResource();
463}
464
465void wxFont::SetStyle(int style)
466{
467 Unshare();
468
469 M_FONTDATA->m_style = style;
470
471 RealizeResource();
472}
473
474void wxFont::SetWeight(int weight)
475{
476 Unshare();
477
478 M_FONTDATA->m_weight = weight;
479
480 RealizeResource();
481}
482
483void wxFont::SetFaceName(const wxString& faceName)
484{
485 Unshare();
486
487 M_FONTDATA->m_faceName = faceName;
488
489 RealizeResource();
490}
491
492void wxFont::SetUnderlined(bool underlined)
493{
494 Unshare();
495
496 M_FONTDATA->m_underlined = underlined;
497
498 RealizeResource();
499}
500
21802234 501void wxFont::SetEncoding(wxFontEncoding encoding)
0e320a79 502{
21802234
DW
503 Unshare();
504
505 M_FONTDATA->m_encoding = encoding;
506
507 RealizeResource();
0e320a79
DW
508}
509
21802234
DW
510// ----------------------------------------------------------------------------
511// accessors
512// ----------------------------------------------------------------------------
513
514int wxFont::GetPointSize() const
0e320a79 515{
21802234 516 return M_FONTDATA->m_pointSize;
0e320a79
DW
517}
518
21802234 519int wxFont::GetFamily() const
0e320a79 520{
21802234
DW
521 return M_FONTDATA->m_family;
522}
523
524int wxFont::GetFontId() const
525{
526 return M_FONTDATA->m_fontId;
527}
528
529int wxFont::GetStyle() const
530{
531 return M_FONTDATA->m_style;
532}
533
534int wxFont::GetWeight() const
535{
536 return M_FONTDATA->m_weight;
537}
538
539bool wxFont::GetUnderlined() const
540{
541 return M_FONTDATA->m_underlined;
542}
543
544wxString wxFont::GetFaceName() const
545{
546 wxString str;
547 if ( M_FONTDATA )
548 str = M_FONTDATA->m_faceName ;
549 return str;
550}
551
552wxFontEncoding wxFont::GetEncoding() const
553{
554 return M_FONTDATA->m_encoding;
0e320a79
DW
555}
556