1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxFont class
4 // Author: David Webster
8 // Copyright: (c) David Webster
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
21 // For compilers that support precompilation, includes "wx.h".
22 #include "wx/wxprec.h"
33 #include "wx/os2/private.h"
35 IMPLEMENT_DYNAMIC_CLASS(wxFont
, wxGDIObject
)
37 #if wxUSE_PORTABLE_FONTS_IN_MSW
38 IMPLEMENT_DYNAMIC_CLASS(wxFontNameDirectory
, wxObject
)
41 // ----------------------------------------------------------------------------
42 // wxFontRefData - the internal description of the font
43 // ----------------------------------------------------------------------------
45 class WXDLLEXPORT wxFontRefData
: public wxGDIRefData
47 friend class WXDLLEXPORT wxFont
;
52 Init(12, wxDEFAULT
, wxNORMAL
, wxNORMAL
, FALSE
,
53 "", wxFONTENCODING_DEFAULT
);
56 wxFontRefData(const wxFontRefData
& data
)
58 Init(data
.m_nPointSize
, data
.m_nFamily
, data
.m_nStyle
, data
.m_nWeight
,
59 data
.m_bUnderlined
, data
.m_sFaceName
, data
.m_vEncoding
);
61 m_nFontId
= data
.m_nFontId
;
64 wxFontRefData( int nSize
69 ,const wxString
& sFaceName
70 ,wxFontEncoding vEncoding
73 Init(nSize
, nFamily
, nStyle
, nWeight
, bUnderlined
, sFaceName
, vEncoding
);
76 virtual ~wxFontRefData();
79 // common part of all ctors
85 ,const wxString
& rsFaceName
86 ,wxFontEncoding vEncoding
90 // If TRUE, the pointer to the actual font is temporary and SHOULD NOT BE
91 // DELETED by destructor
97 // Font characterstics
104 wxString m_sFaceName
;
105 wxFontEncoding m_vEncoding
;
108 // Some PM specific stuff
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
118 // ============================================================================
120 // ============================================================================
122 // ----------------------------------------------------------------------------
124 // ----------------------------------------------------------------------------
126 void wxFontRefData::Init(
132 , const wxString
& rsFaceName
133 , wxFontEncoding vEncoding
137 m_nPointSize
= nPointSize
;
141 m_bUnderlined
= bUnderlined
;
142 m_sFaceName
= rsFaceName
;
143 m_vEncoding
= vEncoding
;
145 m_bTemporary
= FALSE
;
148 m_pFM
= (PFONTMETRICS
)NULL
;
151 } // end of wxFontRefData::Init
153 wxFontRefData::~wxFontRefData()
157 m_pFM
= (PFONTMETRICS
)NULL
;
160 // ----------------------------------------------------------------------------
162 // ----------------------------------------------------------------------------
164 wxFont::wxFont(const wxNativeFontInfo
& rInfo
)
168 (void)Create( rInfo
.pointSize
182 wxTheFontList
->Append(this);
185 // ----------------------------------------------------------------------------
186 // Constructor for a font. Note that the real construction is done
187 // in wxDC::SetFont, when information is available about scaling etc.
188 // ----------------------------------------------------------------------------
195 , const wxString
& rsFaceName
196 , wxFontEncoding vEncoding
200 m_refData
= new wxFontRefData( nPointSize
210 } // end of wxFont::Create
215 wxTheFontList
->DeleteObject(this);
216 } // end of wxFont::~wxFont
218 // ----------------------------------------------------------------------------
219 // real implementation
220 // Boris' Kovalenko comments:
221 // Because OS/2 fonts are associated with PS we can not create the font
222 // here, but we may check that font definition is true
223 // ----------------------------------------------------------------------------
225 bool wxFont::RealizeResource()
229 PFONTMETRICS pFM
= NULL
;
232 if ( GetResourceHandle() )
234 // VZ: the old code returned FALSE in this case, but it doesn't seem
235 // to make sense because the font _was_ created
236 wxLogDebug(wxT("Calling wxFont::RealizeResource() twice"));
242 bool bInternalPS
= FALSE
; // if we have to create one
248 if (!M_FONTDATA
->m_hPS
)
250 M_FONTDATA
->m_hPS
= ::WinGetPS(HWND_DESKTOP
);
254 if (M_FONTDATA
->m_pFM
)
256 delete [] M_FONTDATA
->m_pFM
;
257 M_FONTDATA
->m_pFM
= NULL
;
260 // Determine the number of fonts.
262 lNumFonts
= ::GpiQueryFonts( M_FONTDATA
->m_hPS
266 ,(LONG
) sizeof(FONTMETRICS
)
271 // Allocate space for the font metrics.
273 pFM
= new FONTMETRICS
[lNumFonts
+ 1];
276 // Retrieve the font metrics.
279 lTemp
= ::GpiQueryFonts( M_FONTDATA
->m_hPS
283 ,(LONG
) sizeof(FONTMETRICS
)
292 for (int i
= 0; i
< lNumFonts
; i
++)
294 sVals
<< "Face: " <<M_FONTDATA
->m_pFM
[i
].szFacename
295 << "Family: " <<M_FONTDATA
->m_pFM
[i
].szFamilyname
296 << " PointSize: " << M_FONTDATA
->m_pFM
[i
].lEmHeight
297 << " Height: " << M_FONTDATA
->m_pFM
[i
].lXHeight
301 M_FONTDATA
->m_vFattrs
.usRecordLength
= sizeof(FATTRS
);
302 M_FONTDATA
->m_vFattrs
.fsFontUse
= FATTR_FONTUSE_OUTLINE
| // only outline fonts allowed
303 FATTR_FONTUSE_TRANSFORMABLE
; // may be transformed
304 M_FONTDATA
->m_vFattrs
.fsType
= 0;
305 M_FONTDATA
->m_vFattrs
.lMaxBaselineExt
= M_FONTDATA
->m_vFattrs
.lAveCharWidth
= 0;
306 M_FONTDATA
->m_vFattrs
.idRegistry
= 0;
307 M_FONTDATA
->m_vFattrs
.lMatch
= 0;
309 M_FONTDATA
->m_vFname
.usSize
= sizeof(FACENAMEDESC
);
310 M_FONTDATA
->m_vFname
.usWidthClass
= FWIDTH_NORMAL
;
311 M_FONTDATA
->m_vFname
.usReserved
= 0;
312 M_FONTDATA
->m_vFname
.flOptions
= 0;
314 OS2SelectMatchingFontByName();
316 long lNumLids
= ::GpiQueryNumberSetIds(M_FONTDATA
->m_hPS
);
320 // First we should generate unique id
328 if(!::GpiQuerySetIds( M_FONTDATA
->m_hPS
336 ::WinReleasePS(M_FONTDATA
->m_hPS
);
340 for(unsigned long LCNum
= 0; LCNum
< lNumLids
; LCNum
++)
341 if(alIds
[LCNum
] == flId
)
343 if(flId
> 254) // wow, no id available!
346 ::WinReleasePS(M_FONTDATA
->m_hPS
);
352 // Release and delete the current font
354 ::GpiSetCharSet(M_FONTDATA
->m_hPS
, LCID_DEFAULT
);/* release the font before deleting */
355 ::GpiDeleteSetId(M_FONTDATA
->m_hPS
, 1L); /* delete the logical font */
358 // Now build a facestring
361 strcpy(zFacename
, M_FONTDATA
->m_vFattrs
.szFacename
);
363 if(::GpiQueryFaceString( M_FONTDATA
->m_hPS
365 ,&M_FONTDATA
->m_vFname
367 ,M_FONTDATA
->m_vFattrs
.szFacename
370 vError
= ::WinGetLastError(vHabmain
);
373 M_FONTDATA
->m_sFaceName
= zFacename
;
375 if(::GpiCreateLogFont( M_FONTDATA
->m_hPS
378 ,&M_FONTDATA
->m_vFattrs
380 M_FONTDATA
->m_hFont
= (WXHFONT
)1;
385 if(M_FONTDATA
->m_hFont
)
386 ::GpiDeleteSetId( M_FONTDATA
->m_hPS
390 ::WinReleasePS(M_FONTDATA
->m_hPS
);
393 ::GpiSetCharSet(M_FONTDATA
->m_hPS
, flId
); // sets font for presentation space
394 if (!M_FONTDATA
->m_hFont
)
396 wxLogLastError("CreateFont");
398 M_FONTDATA
->m_nFontId
= flId
;
399 return(M_FONTDATA
->m_hFont
!= 0);
400 } // end of wxFont::RealizeResource
402 bool wxFont::FreeResource(
406 if (GetResourceHandle())
408 M_FONTDATA
->m_hFont
= 0;
409 ::GpiDeleteSetId( M_FONTDATA
->m_hPS
410 ,M_FONTDATA
->m_nFontId
415 } // end of wxFont::FreeResource
417 WXHANDLE
wxFont::GetHFONT() const
422 return (WXHANDLE
)M_FONTDATA
->m_hFont
;
423 } // end of wxFont::GetHFONT
425 WXHANDLE
wxFont::GetResourceHandle()
428 } // end of wxFont::GetResourceHandle
430 bool wxFont::IsFree() const
432 return (M_FONTDATA
&& (M_FONTDATA
->m_hFont
== 0));
433 } // end of wxFont::IsFree
435 void wxFont::Unshare()
437 // Don't change shared data
440 m_refData
= new wxFontRefData();
444 wxFontRefData
* ref
= new wxFontRefData(*M_FONTDATA
);
448 } // end of wxFont::Unshare
450 // ----------------------------------------------------------------------------
451 // change font attribute: we recreate font when doing it
452 // ----------------------------------------------------------------------------
454 void wxFont::SetPointSize(
460 M_FONTDATA
->m_nPointSize
= nPointSize
;
463 } // end of wxFont::SetPointSize
465 void wxFont::SetFamily(
471 M_FONTDATA
->m_nFamily
= nFamily
;
474 } // end of wxFont::SetFamily
476 void wxFont::SetStyle(
482 M_FONTDATA
->m_nStyle
= nStyle
;
485 } // end of wxFont::SetStyle
487 void wxFont::SetWeight(
493 M_FONTDATA
->m_nWeight
= nWeight
;
496 } // end of wxFont::SetWeight
498 void wxFont::SetFaceName(
499 const wxString
& rsFaceName
504 M_FONTDATA
->m_sFaceName
= rsFaceName
;
507 } // end of wxFont::SetFaceName
509 void wxFont::SetUnderlined(
515 M_FONTDATA
->m_bUnderlined
= bUnderlined
;
518 } // end of wxFont::SetUnderlined
520 void wxFont::SetEncoding(
521 wxFontEncoding vEncoding
526 M_FONTDATA
->m_vEncoding
= vEncoding
;
529 } // end of wxFont::SetEncoding
537 M_FONTDATA
->m_hPS
= hPS
;
540 } // end of wxFont::SetPS
548 // Don't realize the font with this one
550 M_FONTDATA
->m_pFM
= pFM
;
551 M_FONTDATA
->m_nNumFonts
= nNumFonts
;
552 } // end of wxFont::SetFM
554 // ----------------------------------------------------------------------------
556 // ----------------------------------------------------------------------------
558 int wxFont::GetPointSize() const
564 return pTmp
->m_nPointSize
;
567 } // end of wxFont::GetPointSize
569 int wxFont::GetFamily() const
571 return M_FONTDATA
->m_nFamily
;
572 } // end of wxFont::GetFamily
574 int wxFont::GetFontId() const
576 return M_FONTDATA
->m_nFontId
;
577 } // end of wxFont::GetFontId
579 int wxFont::GetStyle() const
581 return M_FONTDATA
->m_nStyle
;
582 } // end of wxFont::GetStyle
584 int wxFont::GetWeight() const
586 return M_FONTDATA
->m_nWeight
;
589 bool wxFont::GetUnderlined() const
591 return M_FONTDATA
->m_bUnderlined
;
592 } // end of wxFont::GetUnderlined
594 wxString
wxFont::GetFaceName() const
599 sStr
= M_FONTDATA
->m_sFaceName
;
601 } // end of wxFont::GetFaceName
603 wxFontEncoding
wxFont::GetEncoding() const
605 return M_FONTDATA
->m_vEncoding
;
606 } // end of wxFont::GetEncoding
608 HPS
wxFont::GetPS() const
610 return M_FONTDATA
->m_hPS
;
611 } // end of wxFont::GetPS
613 void wxFont::OS2SelectMatchingFontByName()
626 char zFontFaceName
[FACESIZE
];
628 USHORT usWeightClass
;
632 for(i
= 0;i
< 16; i
++)
633 anMinDiff
[i
] = nMinDiff0
;
638 sFaceName
= wxT("Script");
643 sFaceName
= wxT("Times New Roman");
648 sFaceName
= wxT("Courier") ;
652 sFaceName
= wxT("WarpSans") ;
657 sFaceName
= wxT("Helv") ;
663 wxFAIL_MSG(_T("unknown font weight"));
665 usWeightClass
= FWEIGHT_DONT_CARE
;
669 usWeightClass
= FWEIGHT_NORMAL
;
673 usWeightClass
= FWEIGHT_LIGHT
;
677 usWeightClass
= FWEIGHT_BOLD
;
680 case wxFONTWEIGHT_MAX
:
681 usWeightClass
= FWEIGHT_ULTRA_BOLD
;
684 M_FONTDATA
->m_vFname
.usWeightClass
= usWeightClass
;
690 fsSelection
= FM_SEL_ITALIC
;
691 M_FONTDATA
->m_vFname
.flOptions
= FTYPE_ITALIC
;
695 wxFAIL_MSG(wxT("unknown font slant"));
703 wxStrncpy(zFontFaceName
, sFaceName
.c_str(), WXSIZEOF(zFontFaceName
));
704 M_FONTDATA
->m_nPointSize
= GetPointSize();
706 for(i
= 0, nIs
= 0; i
< M_FONTDATA
->m_nNumFonts
; i
++)
709 int nPointSize
= M_FONTDATA
->m_nPointSize
;
712 anDiff
[0] = wxGpiStrcmp(M_FONTDATA
->m_pFM
[i
].szFamilyname
, zFontFaceName
);
713 anDiff
[1] = abs(M_FONTDATA
->m_pFM
[i
].lEmHeight
- M_FONTDATA
->m_nPointSize
);
714 anDiff
[2] = abs(M_FONTDATA
->m_pFM
[i
].usWeightClass
- usWeightClass
);
715 anDiff
[3] = abs((M_FONTDATA
->m_pFM
[i
].fsSelection
& 0x2f) - fsSelection
);
718 nEmHeight
= (int)M_FONTDATA
->m_pFM
[i
].lEmHeight
;
719 nXHeight
=(int)M_FONTDATA
->m_pFM
[i
].lXHeight
;
720 if( (nIs
& 0x01) == 0)
724 anMinDiff
[1] = anDiff
[1];
725 anMinDiff
[2] = anDiff
[2];
726 anMinDiff
[3] = anDiff
[3];
728 else if(anDiff
[3] < anMinDiff
[3])
731 anMinDiff
[3] = anDiff
[3];
733 else if(anDiff
[2] < anMinDiff
[2])
736 anMinDiff
[2] = anDiff
[2];
738 else if(anDiff
[1] < anMinDiff
[1])
741 anMinDiff
[1] = anDiff
[1];
745 else if(anDiff
[0] < anMinDiff
[0])
749 anMinDiff
[3] = anDiff
[3];
750 anMinDiff
[2] = anDiff
[2];
751 anMinDiff
[1] = anDiff
[1];
752 anMinDiff
[0] = anDiff
[0];
754 else if(anDiff
[0] == anMinDiff
[0])
756 if(anDiff
[3] < anMinDiff
[3])
759 anMinDiff
[3] = anDiff
[3];
762 else if(anDiff
[2] < anMinDiff
[2])
765 anMinDiff
[2] = anDiff
[2];
768 else if(anDiff
[1] < anMinDiff
[1])
771 anMinDiff
[1] = anDiff
[1];
777 M_FONTDATA
->m_vFattrs
.usRecordLength
= sizeof(FATTRS
); // sets size of structure
778 M_FONTDATA
->m_vFattrs
.fsSelection
= M_FONTDATA
->m_pFM
[nIndex
].fsSelection
; // uses default selection
779 M_FONTDATA
->m_vFattrs
.lMatch
= M_FONTDATA
->m_pFM
[nIndex
].lMatch
; // force match
780 M_FONTDATA
->m_vFattrs
.idRegistry
= M_FONTDATA
->m_pFM
[nIndex
].idRegistry
; // uses default registry
781 M_FONTDATA
->m_vFattrs
.usCodePage
= M_FONTDATA
->m_pFM
[nIndex
].usCodePage
; // code-page
782 if(M_FONTDATA
->m_pFM
[nIndex
].lMatch
)
784 M_FONTDATA
->m_vFattrs
.lMaxBaselineExt
= M_FONTDATA
->m_pFM
[nIndex
].lMaxBaselineExt
; // requested font height
785 M_FONTDATA
->m_vFattrs
.lAveCharWidth
= M_FONTDATA
->m_pFM
[nIndex
].lAveCharWidth
; // requested font width
789 M_FONTDATA
->m_vFattrs
.lMaxBaselineExt
= 0;
790 M_FONTDATA
->m_vFattrs
.lAveCharWidth
= 0;
792 M_FONTDATA
->m_vFattrs
.fsType
= 0;// pfm->fsType; /* uses default type */
793 M_FONTDATA
->m_vFattrs
.fsFontUse
= 0;
795 wxStrcpy(M_FONTDATA
->m_vFattrs
.szFacename
, M_FONTDATA
->m_pFM
[nIndex
].szFacename
);
797 strcpy(zFontFaceName
, M_FONTDATA
->m_pFM
[nIndex
].szFacename
);
798 strcpy(zFontFaceName
, M_FONTDATA
->m_vFattrs
.szFacename
);
800 if(usWeightClass
>= FWEIGHT_BOLD
)
801 M_FONTDATA
->m_vFattrs
.fsSelection
|= FATTR_SEL_BOLD
;
803 M_FONTDATA
->m_vFattrs
.fsSelection
|= FATTR_SEL_UNDERSCORE
;
804 if(fsSelection
& FM_SEL_ITALIC
)
805 M_FONTDATA
->m_vFattrs
.fsSelection
|= FATTR_SEL_ITALIC
;