1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: msw/fontutil.cpp
3 // Purpose: font-related helper functions for wxMSW
4 // Author: Modified by David Webster for OS/2
8 // Copyright: (c) 1999 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
23 #define DEBUG_PRINTF(NAME) \
26 printf( #NAME " %i\n",raz); fflush(stdout); \
32 #include "wx/string.h"
37 #include "wx/os2/private.h"
39 #include "wx/fontutil.h"
40 #include "wx/fontmap.h"
41 #include "wx/encinfo.h"
43 #include "wx/tokenzr.h"
45 // ============================================================================
47 // ============================================================================
49 // ----------------------------------------------------------------------------
50 // wxNativeEncodingInfo
51 // ----------------------------------------------------------------------------
53 // convert to/from the string representation: format is
54 // encodingid;facename[;charset]
56 bool wxNativeEncodingInfo::FromString( const wxString
& rsStr
)
58 wxStringTokenizer
vTokenizer(rsStr
, _T(";"));
59 wxString sEncid
= vTokenizer
.GetNextToken();
62 if (!sEncid
.ToLong(&lEnc
))
64 encoding
= (wxFontEncoding
)lEnc
;
65 facename
= vTokenizer
.GetNextToken();
69 wxString sTmp
= vTokenizer
.GetNextToken();
77 if ( wxSscanf(sTmp
, _T("%u"), &charset
) != 1 )
79 // should be a number!
84 } // end of wxNativeEncodingInfo::FromString
86 wxString
wxNativeEncodingInfo::ToString() const
90 sStr
<< (long)encoding
<< _T(';') << facename
;
94 sStr
<< _T(';') << charset
;
97 } // end of wxNativeEncodingInfo::ToString
99 // ----------------------------------------------------------------------------
101 // ----------------------------------------------------------------------------
103 bool wxGetNativeFontEncoding( wxFontEncoding vEncoding
,
104 wxNativeEncodingInfo
* pInfo
)
106 wxCHECK_MSG(pInfo
, FALSE
, _T("bad pointer in wxGetNativeFontEncoding") );
107 if (vEncoding
== wxFONTENCODING_DEFAULT
)
109 vEncoding
= wxFont::GetDefaultEncoding();
113 case wxFONTENCODING_ISO8859_1
:
114 case wxFONTENCODING_ISO8859_15
:
115 case wxFONTENCODING_CP1250
:
116 pInfo
->charset
= 1250;
119 case wxFONTENCODING_ISO8859_2
:
120 case wxFONTENCODING_CP1252
:
121 pInfo
->charset
= 1252;
124 case wxFONTENCODING_ISO8859_4
:
125 case wxFONTENCODING_ISO8859_10
:
126 pInfo
->charset
= 921; // what is baltic?
129 case wxFONTENCODING_ISO8859_5
:
130 case wxFONTENCODING_CP1251
:
131 pInfo
->charset
= 1251;
134 case wxFONTENCODING_ISO8859_6
:
135 pInfo
->charset
= 864;
138 case wxFONTENCODING_ISO8859_7
:
139 pInfo
->charset
= 869;
142 case wxFONTENCODING_ISO8859_8
:
143 pInfo
->charset
= 862;
146 case wxFONTENCODING_ISO8859_9
:
147 pInfo
->charset
= 857;
150 case wxFONTENCODING_ISO8859_11
:
151 pInfo
->charset
= 874; // what is thai
154 case wxFONTENCODING_CP437
:
155 pInfo
->charset
= 437;
159 wxFAIL_MSG(wxT("unsupported encoding"));
162 case wxFONTENCODING_SYSTEM
:
163 pInfo
->charset
= 850;
167 } // end of wxGetNativeFontEncoding
169 wxFontEncoding
wxGetFontEncFromCharSet(
173 wxFontEncoding eFontEncoding
;
179 eFontEncoding
= wxFONTENCODING_CP1250
;
183 eFontEncoding
= wxFONTENCODING_CP1252
;
187 eFontEncoding
= wxFONTENCODING_ISO8859_4
;
191 eFontEncoding
= wxFONTENCODING_CP1251
;
195 eFontEncoding
= wxFONTENCODING_ISO8859_6
;
199 eFontEncoding
= wxFONTENCODING_ISO8859_7
;
203 eFontEncoding
= wxFONTENCODING_ISO8859_8
;
207 eFontEncoding
= wxFONTENCODING_ISO8859_9
;
211 eFontEncoding
= wxFONTENCODING_ISO8859_11
;
215 eFontEncoding
= wxFONTENCODING_CP437
;
218 return eFontEncoding
;
219 } // end of wxGetNativeFontEncoding
221 bool wxTestFontEncoding( const wxNativeEncodingInfo
& rInfo
)
226 hPS
= ::WinGetPS(HWND_DESKTOP
);
228 memset(&vLogFont
, '\0', sizeof(FATTRS
)); // all default values
229 vLogFont
.usRecordLength
= sizeof(FATTRS
);
230 vLogFont
.usCodePage
= (USHORT
)rInfo
.charset
;
231 vLogFont
.lMaxBaselineExt
= 0L; // Outline fonts should use 0
232 vLogFont
.lAveCharWidth
= 0L; // Outline fonts should use 0
233 vLogFont
.fsFontUse
= FATTR_FONTUSE_OUTLINE
| // only outline fonts allowed
234 FATTR_FONTUSE_TRANSFORMABLE
; // may be transformed
236 wxStrncpy((wxChar
*)vLogFont
.szFacename
, rInfo
.facename
.c_str(), WXSIZEOF(vLogFont
.szFacename
));
238 if (!::GpiCreateLogFont( hPS
249 } // end of wxTestFontEncoding
251 // ----------------------------------------------------------------------------
252 // wxFont <-> LOGFONT conversion
253 // ----------------------------------------------------------------------------
255 void wxConvertVectorFontSize(
262 LONG lXFontResolution
;
263 LONG lYFontResolution
;
266 hPS
= WinGetScreenPS(HWND_DESKTOP
); // Screen presentation space
269 // Query device context for the screen and then query
270 // the resolution of the device for the device context.
273 hDC
= GpiQueryDevice(hPS
);
274 DevQueryCaps( hDC
, CAPS_HORIZONTAL_FONT_RES
, (LONG
)1, &lXFontResolution
);
275 DevQueryCaps( hDC
, CAPS_VERTICAL_FONT_RES
, (LONG
)1, &lYFontResolution
);
278 // Calculate the size of the character box, based on the
279 // point size selected and the resolution of the device.
280 // The size parameters are of type FIXED, NOT int.
281 // NOTE: 1 point == 1/72 of an inch.
284 vSizef
.cx
= (FIXED
)(((fxPointSize
) / 72 ) * lXFontResolution
);
285 vSizef
.cy
= (FIXED
)(((fxPointSize
) / 72 ) * lYFontResolution
);
287 pFattrs
->lMaxBaselineExt
= MAKELONG( HIUSHORT( vSizef
.cy
), 0 );
288 pFattrs
->lAveCharWidth
= MAKELONG( HIUSHORT( vSizef
.cx
), 0 );
291 } // end of wxConvertVectorPointSize
293 void wxFillLogFont( LOGFONT
* pFattrs
, // OS2 GPI FATTRS
294 PFACENAMEDESC pFaceName
,
301 LONG lNumFonts
= 0L; // For system font count
302 ERRORID vError
; // For logging API errors
304 bool bInternalPS
= false; // if we have to create one
305 PFONTMETRICS pFM
= NULL
;
308 // Initial house cleaning to free data buffers and ensure we have a
309 // functional PS to work with
313 *phPS
= ::WinGetPS(HWND_DESKTOP
);
318 // Determine the number of fonts.
320 if((lNumFonts
= ::GpiQueryFonts( *phPS
321 ,QF_PUBLIC
| QF_PRIVATE
324 ,(LONG
) sizeof(FONTMETRICS
)
331 vError
= ::WinGetLastError(wxGetInstance());
332 sError
= wxPMErrorToStr(vError
);
337 // Allocate space for the font metrics.
339 pFM
= new FONTMETRICS
[lNumFonts
+ 1];
342 // Retrieve the font metrics.
345 lTemp
= ::GpiQueryFonts( *phPS
349 ,(LONG
) sizeof(FONTMETRICS
)
357 // Initialize FATTR and FACENAMEDESC
359 pFattrs
->usRecordLength
= sizeof(FATTRS
);
360 pFattrs
->fsFontUse
= FATTR_FONTUSE_OUTLINE
; // only outline fonts allowed
362 pFattrs
->lMaxBaselineExt
= pFattrs
->lAveCharWidth
= 0;
363 pFattrs
->idRegistry
= 0;
366 pFaceName
->usSize
= sizeof(FACENAMEDESC
);
367 pFaceName
->usWeightClass
= FWEIGHT_DONT_CARE
;
368 pFaceName
->usWidthClass
= FWIDTH_DONT_CARE
;
369 pFaceName
->usReserved
= 0;
370 pFaceName
->flOptions
= 0;
373 // This does the actual selection of fonts
375 wxOS2SelectMatchingFontByName( pFattrs
382 // We should now have the correct FATTRS set with the selected
383 // font, so now we need to generate an ID
385 long lNumLids
= ::GpiQueryNumberSetIds(*phPS
);
393 memset(alIds
, 0, sizeof(long) * 255);
394 if(!::GpiQuerySetIds( *phPS
402 ::WinReleasePS(*phPS
);
407 for(unsigned long LCNum
= 0; LCNum
< (unsigned long)lNumLids
; LCNum
++)
408 if(alIds
[LCNum
] == *pflId
)
410 if(*pflId
> 254) // wow, no id available!
413 ::WinReleasePS(*phPS
);
420 // Release and delete the current font
422 ::GpiSetCharSet(*phPS
, LCID_DEFAULT
);/* release the font before deleting */
423 ::GpiDeleteSetId(*phPS
, 1L); /* delete the logical font */
426 // Now build a facestring
430 strcpy(zFacename
, pFattrs
->szFacename
);
432 if(::GpiQueryFaceString( *phPS
439 vError
= ::WinGetLastError(vHabmain
);
441 sFaceName
= (wxChar
*)zFacename
;
442 *pbInternalPS
= bInternalPS
;
445 // That's it, we now have everything we need to actually create the font
447 } // end of wxFillLogFont
449 void wxOS2SelectMatchingFontByName(
451 , PFACENAMEDESC pFaceName
454 , const wxFont
* pFont
464 wxChar zFontFaceName
[FACESIZE
];
466 USHORT usWeightClass
;
470 for(i
= 0;i
< 16; i
++)
471 anMinDiff
[i
] = nMinDiff0
;
473 switch (pFont
->GetFamily())
476 sFaceName
= wxT("Tms Rmn");
480 sFaceName
= wxT("WarpSans");
484 sFaceName
= wxT("Tms Rmn");
488 sFaceName
= wxT("Courier") ;
492 sFaceName
= wxT("System VIO") ;
496 sFaceName
= wxT("Helv") ;
501 sFaceName
= wxT("System VIO") ;
504 switch (pFont
->GetWeight())
507 wxFAIL_MSG(_T("unknown font weight"));
509 usWeightClass
= FWEIGHT_DONT_CARE
;
513 usWeightClass
= FWEIGHT_NORMAL
;
517 usWeightClass
= FWEIGHT_LIGHT
;
521 usWeightClass
= FWEIGHT_BOLD
;
524 case wxFONTWEIGHT_MAX
:
525 usWeightClass
= FWEIGHT_ULTRA_BOLD
;
528 pFaceName
->usWeightClass
= usWeightClass
;
530 switch (pFont
->GetStyle())
534 fsSelection
= FM_SEL_ITALIC
;
535 pFaceName
->flOptions
= FTYPE_ITALIC
;
539 wxFAIL_MSG(wxT("unknown font slant"));
547 wxStrncpy(zFontFaceName
, sFaceName
.c_str(), WXSIZEOF(zFontFaceName
));
548 nPointSize
= pFont
->GetPointSize();
551 // Matching logic to find the right FM struct
554 for(i
= 0, nIs
= 0; i
< nNumFonts
; i
++)
559 anDiff
[0] = wxGpiStrcmp((wxChar
*)pFM
[i
].szFacename
, zFontFaceName
);
560 anDiff
[1] = abs(pFM
[i
].lEmHeight
- nPointSize
);
561 anDiff
[2] = abs(pFM
[i
].usWeightClass
- usWeightClass
);
562 anDiff
[3] = abs((pFM
[i
].fsSelection
& 0x2f) - fsSelection
);
565 nEmHeight
= (int)pFM
[i
].lEmHeight
;
566 nXHeight
=(int)pFM
[i
].lXHeight
;
567 if( (nIs
& 0x01) == 0)
571 anMinDiff
[1] = anDiff
[1];
572 anMinDiff
[2] = anDiff
[2];
573 anMinDiff
[3] = anDiff
[3];
575 else if(anDiff
[3] < anMinDiff
[3])
578 anMinDiff
[3] = anDiff
[3];
580 else if(anDiff
[2] < anMinDiff
[2])
583 anMinDiff
[2] = anDiff
[2];
585 else if(anDiff
[1] < anMinDiff
[1])
588 anMinDiff
[1] = anDiff
[1];
592 else if(anDiff
[0] < anMinDiff
[0])
596 anMinDiff
[3] = anDiff
[3];
597 anMinDiff
[2] = anDiff
[2];
598 anMinDiff
[1] = anDiff
[1];
599 anMinDiff
[0] = anDiff
[0];
601 else if(anDiff
[0] == anMinDiff
[0])
603 if(anDiff
[3] < anMinDiff
[3])
606 anMinDiff
[3] = anDiff
[3];
609 else if(anDiff
[2] < anMinDiff
[2])
612 anMinDiff
[2] = anDiff
[2];
615 else if(anDiff
[1] < anMinDiff
[1])
618 anMinDiff
[1] = anDiff
[1];
625 // Fill in the FATTRS with the best match from FONTMETRICS
627 pFattrs
->usRecordLength
= sizeof(FATTRS
); // Sets size of structure
628 pFattrs
->lMatch
= pFM
[nIndex
].lMatch
; // Force match
629 pFattrs
->idRegistry
= 0;
630 pFattrs
->usCodePage
= 0;
631 pFattrs
->fsFontUse
= 0;
633 pFattrs
->lMaxBaselineExt
= 0;
634 pFattrs
->lAveCharWidth
= 0;
635 wxStrcpy((wxChar
*)pFattrs
->szFacename
, (wxChar
*)pFM
[nIndex
].szFacename
);
636 if (pFont
->GetWeight() == wxNORMAL
)
637 pFattrs
->fsSelection
= 0;
639 pFattrs
->fsSelection
= FATTR_SEL_BOLD
;
641 if (pFont
->GetStyle() == wxITALIC
|| pFont
->GetStyle() == wxSLANT
)
642 pFattrs
->fsSelection
|= FATTR_SEL_ITALIC
;
644 if (pFont
->GetUnderlined())
645 pFattrs
->fsSelection
|= FATTR_SEL_UNDERSCORE
;
646 } // end of wxOS2SelectMatchingFontByName
648 wxFont
wxCreateFontFromLogFont(
649 const LOGFONT
* pLogFont
650 , const PFONTMETRICS pFM
651 , PFACENAMEDESC pFaceName
654 wxNativeFontInfo vInfo
;
656 vInfo
.fa
= *pLogFont
;
658 vInfo
.fn
= *pFaceName
;
659 return wxFont(vInfo
);
660 } // end of wxCreateFontFromLogFont
699 d1
= wxToupper(s0
[i
]) - wxToupper(s1
[i
]);