Font updates for OS/2
[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 #include <malloc.h>
21 // For compilers that support precompilation, includes "wx.h".
22 #include "wx/wxprec.h"
23
24 #ifndef WX_PRECOMP
25 #include <stdio.h>
26 #include "wx/setup.h"
27 #include "wx/list.h"
28 #include "wx/utils.h"
29 #include "wx/app.h"
30 #include "wx/font.h"
31 #endif // WX_PRECOMP
32
33 #include "wx/os2/private.h"
34
35 IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
36
37 #if wxUSE_PORTABLE_FONTS_IN_MSW
38 IMPLEMENT_DYNAMIC_CLASS(wxFontNameDirectory, wxObject)
39 #endif
40
41 // ----------------------------------------------------------------------------
42 // wxFontRefData - the internal description of the font
43 // ----------------------------------------------------------------------------
44
45 class WXDLLEXPORT wxFontRefData: public wxGDIRefData
46 {
47 friend class WXDLLEXPORT wxFont;
48
49 public:
50 wxFontRefData()
51 {
52 Init(12, wxDEFAULT, wxNORMAL, wxNORMAL, FALSE,
53 "", wxFONTENCODING_DEFAULT);
54 }
55
56 wxFontRefData(const wxFontRefData& data)
57 {
58 Init(data.m_nPointSize, data.m_nFamily, data.m_nStyle, data.m_nWeight,
59 data.m_bUnderlined, data.m_sFaceName, data.m_vEncoding);
60
61 m_nFontId = data.m_nFontId;
62 }
63
64 wxFontRefData( int nSize
65 ,int nFamily
66 ,int nStyle
67 ,int nWeight
68 ,bool bUnderlined
69 ,const wxString& sFaceName
70 ,wxFontEncoding vEncoding
71 )
72 {
73 Init(nSize, nFamily, nStyle, nWeight, bUnderlined, sFaceName, vEncoding);
74 }
75
76 virtual ~wxFontRefData();
77
78 protected:
79 // common part of all ctors
80 void Init( int nSize
81 ,int nFamily
82 ,int nStyle
83 ,int nWeight
84 ,bool bUnderlined
85 ,const wxString& rsFaceName
86 ,wxFontEncoding vEncoding
87 );
88
89 //
90 // If TRUE, the pointer to the actual font is temporary and SHOULD NOT BE
91 // DELETED by destructor
92 //
93 bool m_bTemporary;
94 int m_nFontId;
95
96 //
97 // Font characterstics
98 //
99 int m_nPointSize;
100 int m_nFamily;
101 int m_nStyle;
102 int m_nWeight;
103 bool m_bUnderlined;
104 wxString m_sFaceName;
105 wxFontEncoding m_vEncoding;
106
107 //
108 // Some PM specific stuff
109 //
110 WXHFONT m_hFont;
111 PFONTMETRICS m_pFM; // array of FONTMETRICS structs
112 int m_nNumFonts; // number of fonts in array
113 HPS m_hPS; // PS handle this font belongs to
114 FATTRS m_vFattrs; // Current fattrs struct
115 FACENAMEDESC m_vFname; // Current facename struct
116 }; // end of CLASS wxFontRefData
117
118 // ============================================================================
119 // implementation
120 // ============================================================================
121
122 // ----------------------------------------------------------------------------
123 // wxFontRefData
124 // ----------------------------------------------------------------------------
125
126 void wxFontRefData::Init(
127 int nPointSize
128 , int nFamily
129 , int nStyle
130 , int nWeight
131 , bool bUnderlined
132 , const wxString& rsFaceName
133 , wxFontEncoding vEncoding
134 )
135 {
136 m_nStyle = nStyle;
137 m_nPointSize = nPointSize;
138 m_nFamily = nFamily;
139 m_nStyle = nStyle;
140 m_nWeight = nWeight;
141 m_bUnderlined = bUnderlined;
142 m_sFaceName = rsFaceName;
143 m_vEncoding = vEncoding;
144 m_nFontId = 0;
145 m_bTemporary = FALSE;
146
147 m_hFont = 0;
148 m_pFM = (PFONTMETRICS)NULL;
149 m_hPS = NULLHANDLE;
150 m_nNumFonts = 0;
151 } // end of wxFontRefData::Init
152
153 wxFontRefData::~wxFontRefData()
154 {
155 if (m_pFM)
156 delete [] m_pFM;
157 m_pFM = (PFONTMETRICS)NULL;
158 }
159
160 // ----------------------------------------------------------------------------
161 // wxFont
162 // ----------------------------------------------------------------------------
163
164 void wxFont::Init()
165 {
166 if ( wxTheFontList )
167 wxTheFontList->Append(this);
168 }
169
170 // ----------------------------------------------------------------------------
171 // Constructor for a font. Note that the real construction is done
172 // in wxDC::SetFont, when information is available about scaling etc.
173 // ----------------------------------------------------------------------------
174 bool wxFont::Create(
175 int nPointSize
176 , int nFamily
177 , int nStyle
178 , int nWeight
179 , bool bUnderlined
180 , const wxString& rsFaceName
181 , wxFontEncoding vEncoding
182 )
183 {
184 UnRef();
185 m_refData = new wxFontRefData( nPointSize
186 ,nFamily
187 ,nStyle
188 ,nWeight
189 ,bUnderlined
190 ,rsFaceName
191 ,vEncoding
192 );
193 RealizeResource();
194 return TRUE;
195 } // end of wxFont::Create
196
197 wxFont::~wxFont()
198 {
199 if (wxTheFontList)
200 wxTheFontList->DeleteObject(this);
201 } // end of wxFont::~wxFont
202
203 // ----------------------------------------------------------------------------
204 // real implementation
205 // Boris' Kovalenko comments:
206 // Because OS/2 fonts are associated with PS we can not create the font
207 // here, but we may check that font definition is true
208 // ----------------------------------------------------------------------------
209
210 bool wxFont::RealizeResource()
211 {
212 LONG lNumFonts = 0L;
213 LONG lTemp = 0L;
214 PFONTMETRICS pFM = NULL;
215 ERRORID vError;
216
217 if ( GetResourceHandle() )
218 {
219 // VZ: the old code returned FALSE in this case, but it doesn't seem
220 // to make sense because the font _was_ created
221 wxLogDebug(wxT("Calling wxFont::RealizeResource() twice"));
222
223 return TRUE;
224 }
225
226 LONG flId;
227 bool bInternalPS = FALSE; // if we have to create one
228
229 //
230 // Now cheking
231 //
232 flId = 1L;
233 if (!M_FONTDATA->m_hPS)
234 {
235 M_FONTDATA->m_hPS = ::WinGetPS(HWND_DESKTOP);
236 bInternalPS = TRUE;
237 }
238
239 if (M_FONTDATA->m_pFM)
240 {
241 delete [] M_FONTDATA->m_pFM;
242 M_FONTDATA->m_pFM = NULL;
243 }
244 //
245 // Determine the number of fonts.
246 //
247 lNumFonts = ::GpiQueryFonts( M_FONTDATA->m_hPS
248 ,QF_PUBLIC
249 ,NULL
250 ,&lTemp
251 ,(LONG) sizeof(FONTMETRICS)
252 ,NULL
253 );
254
255 //
256 // Allocate space for the font metrics.
257 //
258 pFM = new FONTMETRICS[lNumFonts + 1];
259
260 //
261 // Retrieve the font metrics.
262 //
263 lTemp = lNumFonts;
264 lTemp = ::GpiQueryFonts( M_FONTDATA->m_hPS
265 ,QF_PUBLIC
266 ,NULL
267 ,&lTemp
268 ,(LONG) sizeof(FONTMETRICS)
269 ,pFM
270 );
271 SetFM( pFM
272 ,(int)lNumFonts
273 );
274
275 wxString sVals;
276
277 for (int i = 0; i < lNumFonts; i++)
278 {
279 sVals << "Face: " <<M_FONTDATA->m_pFM[i].szFacename
280 << "Family: " <<M_FONTDATA->m_pFM[i].szFamilyname
281 << " PointSize: " << M_FONTDATA->m_pFM[i].lEmHeight
282 << " Height: " << M_FONTDATA->m_pFM[i].lXHeight
283 ;
284 sVals = "";
285 }
286 M_FONTDATA->m_vFattrs.usRecordLength = sizeof(FATTRS);
287 M_FONTDATA->m_vFattrs.fsFontUse = FATTR_FONTUSE_OUTLINE | // only outline fonts allowed
288 FATTR_FONTUSE_TRANSFORMABLE; // may be transformed
289 M_FONTDATA->m_vFattrs.fsType = 0;
290 M_FONTDATA->m_vFattrs.lMaxBaselineExt = M_FONTDATA->m_vFattrs.lAveCharWidth = 0;
291 M_FONTDATA->m_vFattrs.idRegistry = 0;
292 M_FONTDATA->m_vFattrs.lMatch = 0;
293
294 M_FONTDATA->m_vFname.usSize = sizeof(FACENAMEDESC);
295 M_FONTDATA->m_vFname.usWidthClass = FWIDTH_NORMAL;
296 M_FONTDATA->m_vFname.usReserved = 0;
297 M_FONTDATA->m_vFname.flOptions = 0;
298
299 OS2SelectMatchingFontByName();
300
301 long lNumLids = ::GpiQueryNumberSetIds(M_FONTDATA->m_hPS);
302 long lGpiError;
303
304 //
305 // First we should generate unique id
306 //
307 if(lNumLids )
308 {
309 long alTypes[255];
310 STR8 azNames[255];
311 long alIds[255];
312
313 if(!::GpiQuerySetIds( M_FONTDATA->m_hPS
314 ,lNumLids
315 ,alTypes
316 ,azNames
317 ,alIds
318 ))
319 {
320 if (bInternalPS)
321 ::WinReleasePS(M_FONTDATA->m_hPS);
322 return 0;
323 }
324
325 for(unsigned long LCNum = 0; LCNum < lNumLids; LCNum++)
326 if(alIds[LCNum] == flId)
327 ++flId;
328 if(flId > 254) // wow, no id available!
329 {
330 if (bInternalPS)
331 ::WinReleasePS(M_FONTDATA->m_hPS);
332 return 0;
333 }
334 }
335
336 //
337 // Release and delete the current font
338 //
339 ::GpiSetCharSet(M_FONTDATA->m_hPS, LCID_DEFAULT);/* release the font before deleting */
340 ::GpiDeleteSetId(M_FONTDATA->m_hPS, 1L); /* delete the logical font */
341
342 //
343 // Now build a facestring
344 //
345 char zFacename[128];
346 strcpy(zFacename, M_FONTDATA->m_vFattrs.szFacename);
347
348 if(::GpiQueryFaceString( M_FONTDATA->m_hPS
349 ,zFacename
350 ,&M_FONTDATA->m_vFname
351 ,FACESIZE
352 ,M_FONTDATA->m_vFattrs.szFacename
353 ) == GPI_ERROR)
354 {
355 vError = ::WinGetLastError(vHabmain);
356 }
357
358 strcpy(zFacename, M_FONTDATA->m_vFattrs.szFacename);
359
360 if(::GpiCreateLogFont( M_FONTDATA->m_hPS
361 ,NULL
362 ,flId
363 ,&M_FONTDATA->m_vFattrs
364 ) != GPI_ERROR)
365 M_FONTDATA->m_hFont = (WXHFONT)1;
366
367
368 if (bInternalPS)
369 {
370 if(M_FONTDATA->m_hFont)
371 ::GpiDeleteSetId( M_FONTDATA->m_hPS
372 ,flId
373 );
374
375 ::WinReleasePS(M_FONTDATA->m_hPS);
376 }
377 else
378 ::GpiSetCharSet(M_FONTDATA->m_hPS, flId); // sets font for presentation space
379 if (!M_FONTDATA->m_hFont)
380 {
381 wxLogLastError("CreateFont");
382 }
383 M_FONTDATA->m_nFontId = flId;
384 return(M_FONTDATA->m_hFont != 0);
385 } // end of wxFont::RealizeResource
386
387 bool wxFont::FreeResource(
388 bool bForce
389 )
390 {
391 if (GetResourceHandle())
392 {
393 M_FONTDATA->m_hFont = 0;
394 ::GpiDeleteSetId( M_FONTDATA->m_hPS
395 ,M_FONTDATA->m_nFontId
396 );
397 return TRUE;
398 }
399 return FALSE;
400 } // end of wxFont::FreeResource
401
402 WXHANDLE wxFont::GetResourceHandle()
403 {
404 if (!M_FONTDATA)
405 return 0;
406 else
407 return (WXHANDLE)M_FONTDATA->m_hFont;
408 } // end of wxFont::GetResourceHandle
409
410 bool wxFont::IsFree() const
411 {
412 return (M_FONTDATA && (M_FONTDATA->m_hFont == 0));
413 } // end of wxFont::IsFree
414
415 void wxFont::Unshare()
416 {
417 // Don't change shared data
418 if ( !m_refData )
419 {
420 m_refData = new wxFontRefData();
421 }
422 else
423 {
424 wxFontRefData* ref = new wxFontRefData(*M_FONTDATA);
425 UnRef();
426 m_refData = ref;
427 }
428 } // end of wxFont::Unshare
429
430 // ----------------------------------------------------------------------------
431 // change font attribute: we recreate font when doing it
432 // ----------------------------------------------------------------------------
433
434 void wxFont::SetPointSize(
435 int nPointSize
436 )
437 {
438 Unshare();
439
440 M_FONTDATA->m_nPointSize = nPointSize;
441
442 RealizeResource();
443 } // end of wxFont::SetPointSize
444
445 void wxFont::SetFamily(
446 int nFamily
447 )
448 {
449 Unshare();
450
451 M_FONTDATA->m_nFamily = nFamily;
452
453 RealizeResource();
454 } // end of wxFont::SetFamily
455
456 void wxFont::SetStyle(
457 int nStyle
458 )
459 {
460 Unshare();
461
462 M_FONTDATA->m_nStyle = nStyle;
463
464 RealizeResource();
465 } // end of wxFont::SetStyle
466
467 void wxFont::SetWeight(
468 int nWeight
469 )
470 {
471 Unshare();
472
473 M_FONTDATA->m_nWeight = nWeight;
474
475 RealizeResource();
476 } // end of wxFont::SetWeight
477
478 void wxFont::SetFaceName(
479 const wxString& rsFaceName
480 )
481 {
482 Unshare();
483
484 M_FONTDATA->m_sFaceName = rsFaceName;
485
486 RealizeResource();
487 } // end of wxFont::SetFaceName
488
489 void wxFont::SetUnderlined(
490 bool bUnderlined
491 )
492 {
493 Unshare();
494
495 M_FONTDATA->m_bUnderlined = bUnderlined;
496
497 RealizeResource();
498 } // end of wxFont::SetUnderlined
499
500 void wxFont::SetEncoding(
501 wxFontEncoding vEncoding
502 )
503 {
504 Unshare();
505
506 M_FONTDATA->m_vEncoding = vEncoding;
507
508 RealizeResource();
509 } // end of wxFont::SetEncoding
510
511 void wxFont::SetPS(
512 HPS hPS
513 )
514 {
515 Unshare();
516
517 M_FONTDATA->m_hPS = hPS;
518
519 RealizeResource();
520 } // end of wxFont::SetPS
521
522 void wxFont::SetFM(
523 PFONTMETRICS pFM
524 , int nNumFonts
525 )
526 {
527 //
528 // Don't realize the font with this one
529 //
530 M_FONTDATA->m_pFM = pFM;
531 M_FONTDATA->m_nNumFonts = nNumFonts;
532 } // end of wxFont::SetFM
533
534 // ----------------------------------------------------------------------------
535 // accessors
536 // ----------------------------------------------------------------------------
537
538 int wxFont::GetPointSize() const
539 {
540 wxFontRefData* pTmp;
541
542 pTmp = M_FONTDATA;
543 if(pTmp)
544 return pTmp->m_nPointSize;
545 else
546 return 10;
547 } // end of wxFont::GetPointSize
548
549 int wxFont::GetFamily() const
550 {
551 return M_FONTDATA->m_nFamily;
552 } // end of wxFont::GetFamily
553
554 int wxFont::GetFontId() const
555 {
556 return M_FONTDATA->m_nFontId;
557 } // end of wxFont::GetFontId
558
559 int wxFont::GetStyle() const
560 {
561 return M_FONTDATA->m_nStyle;
562 } // end of wxFont::GetStyle
563
564 int wxFont::GetWeight() const
565 {
566 return M_FONTDATA->m_nWeight;
567 }
568
569 bool wxFont::GetUnderlined() const
570 {
571 return M_FONTDATA->m_bUnderlined;
572 } // end of wxFont::GetUnderlined
573
574 wxString wxFont::GetFaceName() const
575 {
576 wxString sStr;
577
578 if ( M_FONTDATA )
579 sStr = M_FONTDATA->m_sFaceName ;
580 return sStr;
581 } // end of wxFont::GetFaceName
582
583 wxFontEncoding wxFont::GetEncoding() const
584 {
585 return M_FONTDATA->m_vEncoding;
586 } // end of wxFont::GetEncoding
587
588 HPS wxFont::GetPS() const
589 {
590 return M_FONTDATA->m_hPS;
591 } // end of wxFont::GetPS
592
593 void wxFont::OS2SelectMatchingFontByName()
594 {
595 int i;
596 int nDiff0;
597 int nDiff;
598 int nIs;
599 int nIndex;
600 int nMinDiff;
601 int nMinDiff0;
602 int nApirc;
603 int anDiff[16];
604 int anMinDiff[16];
605 STR8 zFn;
606 char zFontFaceName[FACESIZE];
607 wxString sFaceName;
608 USHORT usWeightClass;
609 int fsSelection = 0;
610
611 nMinDiff0 = 0xf000;
612 for(i = 0;i < 16; i++)
613 anMinDiff[i] = nMinDiff0;
614
615 switch (GetFamily())
616 {
617 case wxSCRIPT:
618 sFaceName = wxT("Script");
619 break;
620
621 case wxDECORATIVE:
622 case wxROMAN:
623 sFaceName = wxT("Times New Roman");
624 break;
625
626 case wxTELETYPE:
627 case wxMODERN:
628 sFaceName = wxT("Courier") ;
629 break;
630
631 case wxSWISS:
632 sFaceName = wxT("WarpSans") ;
633 break;
634
635 case wxDEFAULT:
636 default:
637 sFaceName = wxT("Helv") ;
638 }
639
640 switch (GetWeight())
641 {
642 default:
643 wxFAIL_MSG(_T("unknown font weight"));
644 // fall through
645 usWeightClass = FWEIGHT_DONT_CARE;
646 break;
647
648 case wxNORMAL:
649 usWeightClass = FWEIGHT_NORMAL;
650 break;
651
652 case wxLIGHT:
653 usWeightClass = FWEIGHT_LIGHT;
654 break;
655
656 case wxBOLD:
657 usWeightClass = FWEIGHT_BOLD;
658 break;
659
660 case wxFONTWEIGHT_MAX:
661 usWeightClass = FWEIGHT_ULTRA_BOLD;
662 break;
663 }
664 M_FONTDATA->m_vFname.usWeightClass = usWeightClass;
665
666 switch (GetStyle())
667 {
668 case wxITALIC:
669 case wxSLANT:
670 fsSelection = FM_SEL_ITALIC;
671 M_FONTDATA->m_vFname.flOptions = FTYPE_ITALIC;
672 break;
673
674 default:
675 wxFAIL_MSG(wxT("unknown font slant"));
676 // fall through
677
678 case wxNORMAL:
679 fsSelection = 0;
680 break;
681 }
682
683 wxStrncpy(zFontFaceName, sFaceName.c_str(), WXSIZEOF(zFontFaceName));
684 M_FONTDATA->m_nPointSize = GetPointSize();
685 nIndex = 0;
686 for(i = 0, nIs = 0; i < M_FONTDATA->m_nNumFonts; i++)
687 {
688 // Debug code
689 int nPointSize = M_FONTDATA->m_nPointSize;
690 int nEmHeight = 0;
691 int nXHeight = 0;
692 anDiff[0] = wxGpiStrcmp(M_FONTDATA->m_pFM[i].szFamilyname, zFontFaceName);
693 anDiff[1] = abs(M_FONTDATA->m_pFM[i].lEmHeight - M_FONTDATA->m_nPointSize);
694 anDiff[2] = abs(M_FONTDATA->m_pFM[i].usWeightClass - usWeightClass);
695 anDiff[3] = abs((M_FONTDATA->m_pFM[i].fsSelection & 0x2f) - fsSelection);
696 if(anDiff[0] == 0)
697 {
698 nEmHeight = (int)M_FONTDATA->m_pFM[i].lEmHeight;
699 nXHeight =(int)M_FONTDATA->m_pFM[i].lXHeight;
700 if( (nIs & 0x01) == 0)
701 {
702 nIs = 1;
703 nIndex = i;
704 anMinDiff[1] = anDiff[1];
705 anMinDiff[2] = anDiff[2];
706 anMinDiff[3] = anDiff[3];
707 }
708 else if(anDiff[3] < anMinDiff[3])
709 {
710 nIndex = i;
711 anMinDiff[3] = anDiff[3];
712 }
713 else if(anDiff[2] < anMinDiff[2])
714 {
715 nIndex = i;
716 anMinDiff[2] = anDiff[2];
717 }
718 else if(anDiff[1] < anMinDiff[1])
719 {
720 nIndex = i;
721 anMinDiff[1] = anDiff[1];
722 }
723 anMinDiff[0] = 0;
724 }
725 else if(anDiff[0] < anMinDiff[0])
726 {
727 nIs = 2;
728 nIndex = i;
729 anMinDiff[3] = anDiff[3];
730 anMinDiff[2] = anDiff[2];
731 anMinDiff[1] = anDiff[1];
732 anMinDiff[0] = anDiff[0];
733 }
734 else if(anDiff[0] == anMinDiff[0])
735 {
736 if(anDiff[3] < anMinDiff[3])
737 {
738 nIndex = i;
739 anMinDiff[3] = anDiff[3];
740 nIs = 2;
741 }
742 else if(anDiff[2] < anMinDiff[2])
743 {
744 nIndex = i;
745 anMinDiff[2] = anDiff[2];
746 nIs = 2;
747 }
748 else if(anDiff[1] < anMinDiff[1])
749 {
750 nIndex = i;
751 anMinDiff[1] = anDiff[1];
752 nIs = 2;
753 }
754 }
755 }
756
757 M_FONTDATA->m_vFattrs.usRecordLength = sizeof(FATTRS); // sets size of structure
758 M_FONTDATA->m_vFattrs.fsSelection = M_FONTDATA->m_pFM[nIndex].fsSelection; // uses default selection
759 M_FONTDATA->m_vFattrs.lMatch = M_FONTDATA->m_pFM[nIndex].lMatch; // force match
760 M_FONTDATA->m_vFattrs.idRegistry = M_FONTDATA->m_pFM[nIndex].idRegistry; // uses default registry
761 M_FONTDATA->m_vFattrs.usCodePage = M_FONTDATA->m_pFM[nIndex].usCodePage; // code-page
762 if(M_FONTDATA->m_pFM[nIndex].lMatch)
763 {
764 M_FONTDATA->m_vFattrs.lMaxBaselineExt = M_FONTDATA->m_pFM[nIndex].lMaxBaselineExt; // requested font height
765 M_FONTDATA->m_vFattrs.lAveCharWidth = M_FONTDATA->m_pFM[nIndex].lAveCharWidth ; // requested font width
766 }
767 else
768 {
769 M_FONTDATA->m_vFattrs.lMaxBaselineExt = 0;
770 M_FONTDATA->m_vFattrs.lAveCharWidth = 0;
771 }
772 M_FONTDATA->m_vFattrs.fsType = 0;// pfm->fsType; /* uses default type */
773 M_FONTDATA->m_vFattrs.fsFontUse = 0;
774
775 wxStrcpy(M_FONTDATA->m_vFattrs.szFacename, M_FONTDATA->m_pFM[nIndex].szFacename);
776 // Debug
777 strcpy(zFontFaceName, M_FONTDATA->m_pFM[nIndex].szFacename);
778 strcpy(zFontFaceName, M_FONTDATA->m_vFattrs.szFacename);
779
780 if(usWeightClass >= FWEIGHT_BOLD)
781 M_FONTDATA->m_vFattrs.fsSelection |= FATTR_SEL_BOLD;
782 if(GetUnderlined())
783 M_FONTDATA->m_vFattrs.fsSelection |= FATTR_SEL_UNDERSCORE;
784 if(fsSelection & FM_SEL_ITALIC)
785 M_FONTDATA->m_vFattrs.fsSelection |= FATTR_SEL_ITALIC;
786 }
787
788
789