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 ///////////////////////////////////////////////////////////////////////////////
11 #define DEBUG_PRINTF(NAME) { static int raz=0; \
12 printf( #NAME " %i\n",raz); fflush(stdout); \
16 // ============================================================================
18 // ============================================================================
20 // ----------------------------------------------------------------------------
22 // ----------------------------------------------------------------------------
25 #pragma implementation "fontutil.h"
28 // For compilers that support precompilation, includes "wx.h".
29 #include "wx/wxprec.h"
33 #include "wx/string.h"
38 #include "wx/os2/private.h"
40 #include "wx/fontutil.h"
41 #include "wx/fontmap.h"
42 #include "wx/encinfo.h"
44 #include "wx/tokenzr.h"
46 // ============================================================================
48 // ============================================================================
50 // ----------------------------------------------------------------------------
51 // wxNativeEncodingInfo
52 // ----------------------------------------------------------------------------
54 // convert to/from the string representation: format is
55 // encodingid;facename[;charset]
57 bool wxNativeEncodingInfo::FromString(
61 wxStringTokenizer
vTokenizer(rsStr
, _T(";"));
62 wxString sEncid
= vTokenizer
.GetNextToken();
65 if (!sEncid
.ToLong(&lEnc
))
67 encoding
= (wxFontEncoding
)lEnc
;
68 facename
= vTokenizer
.GetNextToken();
72 wxString sTmp
= vTokenizer
.GetNextToken();
80 if ( wxSscanf(sTmp
, _T("%u"), &charset
) != 1 )
82 // should be a number!
87 } // end of wxNativeEncodingInfo::FromString
89 wxString
wxNativeEncodingInfo::ToString() const
93 sStr
<< (long)encoding
<< _T(';') << facename
;
97 sStr
<< _T(';') << charset
;
100 } // end of wxNativeEncodingInfo::ToString
102 // ----------------------------------------------------------------------------
104 // ----------------------------------------------------------------------------
106 bool wxGetNativeFontEncoding(
107 wxFontEncoding vEncoding
108 , wxNativeEncodingInfo
* pInfo
111 wxCHECK_MSG(pInfo
, FALSE
, _T("bad pointer in wxGetNativeFontEncoding") );
112 if (vEncoding
== wxFONTENCODING_DEFAULT
)
114 vEncoding
= wxFont::GetDefaultEncoding();
118 case wxFONTENCODING_ISO8859_1
:
119 case wxFONTENCODING_ISO8859_15
:
120 case wxFONTENCODING_CP1250
:
121 pInfo
->charset
= 1250;
124 case wxFONTENCODING_ISO8859_2
:
125 case wxFONTENCODING_CP1252
:
126 pInfo
->charset
= 1252;
129 case wxFONTENCODING_ISO8859_4
:
130 case wxFONTENCODING_ISO8859_10
:
131 pInfo
->charset
= 921; // what is baltic?
134 case wxFONTENCODING_ISO8859_5
:
135 case wxFONTENCODING_CP1251
:
136 pInfo
->charset
= 1251;
139 case wxFONTENCODING_ISO8859_6
:
140 pInfo
->charset
= 864;
143 case wxFONTENCODING_ISO8859_7
:
144 pInfo
->charset
= 869;
147 case wxFONTENCODING_ISO8859_8
:
148 pInfo
->charset
= 862;
151 case wxFONTENCODING_ISO8859_9
:
152 pInfo
->charset
= 857;
155 case wxFONTENCODING_ISO8859_11
:
156 pInfo
->charset
= 874; // what is thai
159 case wxFONTENCODING_CP437
:
160 pInfo
->charset
= 437;
164 wxFAIL_MSG(wxT("unsupported encoding"));
167 case wxFONTENCODING_SYSTEM
:
168 pInfo
->charset
= 850;
172 } // end of wxGetNativeFontEncoding
174 wxFontEncoding
wxGetFontEncFromCharSet(
178 wxFontEncoding eFontEncoding
;
184 eFontEncoding
= wxFONTENCODING_CP1250
;
188 eFontEncoding
= wxFONTENCODING_CP1252
;
192 eFontEncoding
= wxFONTENCODING_ISO8859_4
;
196 eFontEncoding
= wxFONTENCODING_CP1251
;
200 eFontEncoding
= wxFONTENCODING_ISO8859_6
;
204 eFontEncoding
= wxFONTENCODING_ISO8859_7
;
208 eFontEncoding
= wxFONTENCODING_ISO8859_8
;
212 eFontEncoding
= wxFONTENCODING_ISO8859_9
;
216 eFontEncoding
= wxFONTENCODING_ISO8859_11
;
220 eFontEncoding
= wxFONTENCODING_CP437
;
223 return eFontEncoding
;
224 } // end of wxGetNativeFontEncoding
226 bool wxTestFontEncoding(
227 const wxNativeEncodingInfo
& rInfo
233 hPS
= ::WinGetPS(HWND_DESKTOP
);
235 memset(&vLogFont
, '\0', sizeof(FATTRS
)); // all default values
236 vLogFont
.usRecordLength
= sizeof(FATTRS
);
237 vLogFont
.usCodePage
= rInfo
.charset
;
238 vLogFont
.lMaxBaselineExt
= 0L; // Outline fonts should use 0
239 vLogFont
.lAveCharWidth
= 0L; // Outline fonts should use 0
240 vLogFont
.fsFontUse
= FATTR_FONTUSE_OUTLINE
| // only outline fonts allowed
241 FATTR_FONTUSE_TRANSFORMABLE
; // may be transformed
243 wxStrncpy((wxChar
*)vLogFont
.szFacename
, rInfo
.facename
.c_str(), WXSIZEOF(vLogFont
.szFacename
));
245 if (!::GpiCreateLogFont( hPS
256 } // end of wxTestFontEncoding
258 // ----------------------------------------------------------------------------
259 // wxFont <-> LOGFONT conversion
260 // ----------------------------------------------------------------------------
262 void wxConvertVectorFontSize(
269 LONG lXFontResolution
;
270 LONG lYFontResolution
;
273 hPS
= WinGetScreenPS(HWND_DESKTOP
); // Screen presentation space
276 // Query device context for the screen and then query
277 // the resolution of the device for the device context.
280 hDC
= GpiQueryDevice(hPS
);
281 DevQueryCaps( hDC
, CAPS_HORIZONTAL_FONT_RES
, (LONG
)1, &lXFontResolution
);
282 DevQueryCaps( hDC
, CAPS_VERTICAL_FONT_RES
, (LONG
)1, &lYFontResolution
);
285 // Calculate the size of the character box, based on the
286 // point size selected and the resolution of the device.
287 // The size parameters are of type FIXED, NOT int.
288 // NOTE: 1 point == 1/72 of an inch.
291 vSizef
.cx
= (FIXED
)(((fxPointSize
) / 72 ) * lXFontResolution
);
292 vSizef
.cy
= (FIXED
)(((fxPointSize
) / 72 ) * lYFontResolution
);
294 pFattrs
->lMaxBaselineExt
= MAKELONG( HIUSHORT( vSizef
.cy
), 0 );
295 pFattrs
->lAveCharWidth
= MAKELONG( HIUSHORT( vSizef
.cx
), 0 );
298 } // end of wxConvertVectorPointSize
301 LOGFONT
* pFattrs
// OS2 GPI FATTRS
302 , PFACENAMEDESC pFaceName
306 , wxString
& sFaceName
310 LONG lNumFonts
= 0L; // For system font count
311 ERRORID vError
; // For logging API errors
313 bool bInternalPS
= FALSE
; // if we have to create one
314 PFONTMETRICS pFM
= NULL
;
317 // Initial house cleaning to free data buffers and ensure we have a
318 // functional PS to work with
322 *phPS
= ::WinGetPS(HWND_DESKTOP
);
327 // Determine the number of fonts.
329 if((lNumFonts
= ::GpiQueryFonts( *phPS
330 ,QF_PUBLIC
| QF_PRIVATE
333 ,(LONG
) sizeof(FONTMETRICS
)
340 vError
= ::WinGetLastError(wxGetInstance());
341 sError
= wxPMErrorToStr(vError
);
346 // Allocate space for the font metrics.
348 pFM
= new FONTMETRICS
[lNumFonts
+ 1];
351 // Retrieve the font metrics.
354 lTemp
= ::GpiQueryFonts( *phPS
358 ,(LONG
) sizeof(FONTMETRICS
)
366 // Initialize FATTR and FACENAMEDESC
368 pFattrs
->usRecordLength
= sizeof(FATTRS
);
369 pFattrs
->fsFontUse
= FATTR_FONTUSE_OUTLINE
; // only outline fonts allowed
371 pFattrs
->lMaxBaselineExt
= pFattrs
->lAveCharWidth
= 0;
372 pFattrs
->idRegistry
= 0;
375 pFaceName
->usSize
= sizeof(FACENAMEDESC
);
376 pFaceName
->usWeightClass
= FWEIGHT_DONT_CARE
;
377 pFaceName
->usWidthClass
= FWIDTH_DONT_CARE
;
378 pFaceName
->usReserved
= 0;
379 pFaceName
->flOptions
= 0;
382 // This does the actual selection of fonts
384 wxOS2SelectMatchingFontByName( pFattrs
391 // We should now have the correct FATTRS set with the selected
392 // font, so now we need to generate an ID
394 long lNumLids
= ::GpiQueryNumberSetIds(*phPS
);
402 memset(alIds
, 0, sizeof(long) * 255);
403 if(!::GpiQuerySetIds( *phPS
411 ::WinReleasePS(*phPS
);
416 for(unsigned long LCNum
= 0; LCNum
< (unsigned long)lNumLids
; LCNum
++)
417 if(alIds
[LCNum
] == *pflId
)
419 if(*pflId
> 254) // wow, no id available!
422 ::WinReleasePS(*phPS
);
429 // Release and delete the current font
431 ::GpiSetCharSet(*phPS
, LCID_DEFAULT
);/* release the font before deleting */
432 ::GpiDeleteSetId(*phPS
, 1L); /* delete the logical font */
435 // Now build a facestring
439 strcpy(zFacename
, pFattrs
->szFacename
);
441 if(::GpiQueryFaceString( *phPS
448 vError
= ::WinGetLastError(vHabmain
);
450 sFaceName
= (wxChar
*)zFacename
;
451 *pbInternalPS
= bInternalPS
;
454 // That's it, we now have everything we need to actually create the font
456 } // end of wxFillLogFont
458 void wxOS2SelectMatchingFontByName(
460 , PFACENAMEDESC pFaceName
463 , const wxFont
* pFont
473 wxChar zFontFaceName
[FACESIZE
];
475 USHORT usWeightClass
;
479 for(i
= 0;i
< 16; i
++)
480 anMinDiff
[i
] = nMinDiff0
;
482 switch (pFont
->GetFamily())
485 sFaceName
= wxT("Tms Rmn");
489 sFaceName
= wxT("WarpSans");
493 sFaceName
= wxT("Tms Rmn");
497 sFaceName
= wxT("Courier") ;
501 sFaceName
= wxT("System VIO") ;
505 sFaceName
= wxT("Helv") ;
510 sFaceName
= wxT("System VIO") ;
513 switch (pFont
->GetWeight())
516 wxFAIL_MSG(_T("unknown font weight"));
518 usWeightClass
= FWEIGHT_DONT_CARE
;
522 usWeightClass
= FWEIGHT_NORMAL
;
526 usWeightClass
= FWEIGHT_LIGHT
;
530 usWeightClass
= FWEIGHT_BOLD
;
533 case wxFONTWEIGHT_MAX
:
534 usWeightClass
= FWEIGHT_ULTRA_BOLD
;
537 pFaceName
->usWeightClass
= usWeightClass
;
539 switch (pFont
->GetStyle())
543 fsSelection
= FM_SEL_ITALIC
;
544 pFaceName
->flOptions
= FTYPE_ITALIC
;
548 wxFAIL_MSG(wxT("unknown font slant"));
556 wxStrncpy(zFontFaceName
, sFaceName
.c_str(), WXSIZEOF(zFontFaceName
));
557 nPointSize
= pFont
->GetPointSize();
560 // Matching logic to find the right FM struct
563 for(i
= 0, nIs
= 0; i
< nNumFonts
; i
++)
568 anDiff
[0] = wxGpiStrcmp((wxChar
*)pFM
[i
].szFacename
, zFontFaceName
);
569 anDiff
[1] = abs(pFM
[i
].lEmHeight
- nPointSize
);
570 anDiff
[2] = abs(pFM
[i
].usWeightClass
- usWeightClass
);
571 anDiff
[3] = abs((pFM
[i
].fsSelection
& 0x2f) - fsSelection
);
574 nEmHeight
= (int)pFM
[i
].lEmHeight
;
575 nXHeight
=(int)pFM
[i
].lXHeight
;
576 if( (nIs
& 0x01) == 0)
580 anMinDiff
[1] = anDiff
[1];
581 anMinDiff
[2] = anDiff
[2];
582 anMinDiff
[3] = anDiff
[3];
584 else if(anDiff
[3] < anMinDiff
[3])
587 anMinDiff
[3] = anDiff
[3];
589 else if(anDiff
[2] < anMinDiff
[2])
592 anMinDiff
[2] = anDiff
[2];
594 else if(anDiff
[1] < anMinDiff
[1])
597 anMinDiff
[1] = anDiff
[1];
601 else if(anDiff
[0] < anMinDiff
[0])
605 anMinDiff
[3] = anDiff
[3];
606 anMinDiff
[2] = anDiff
[2];
607 anMinDiff
[1] = anDiff
[1];
608 anMinDiff
[0] = anDiff
[0];
610 else if(anDiff
[0] == anMinDiff
[0])
612 if(anDiff
[3] < anMinDiff
[3])
615 anMinDiff
[3] = anDiff
[3];
618 else if(anDiff
[2] < anMinDiff
[2])
621 anMinDiff
[2] = anDiff
[2];
624 else if(anDiff
[1] < anMinDiff
[1])
627 anMinDiff
[1] = anDiff
[1];
634 // Fill in the FATTRS with the best match from FONTMETRICS
636 pFattrs
->usRecordLength
= sizeof(FATTRS
); // Sets size of structure
637 pFattrs
->lMatch
= pFM
[nIndex
].lMatch
; // Force match
638 pFattrs
->idRegistry
= 0;
639 pFattrs
->usCodePage
= 0;
640 pFattrs
->fsFontUse
= 0;
642 pFattrs
->lMaxBaselineExt
= 0;
643 pFattrs
->lAveCharWidth
= 0;
644 wxStrcpy((wxChar
*)pFattrs
->szFacename
, (wxChar
*)pFM
[nIndex
].szFacename
);
645 if (pFont
->GetWeight() == wxNORMAL
)
646 pFattrs
->fsSelection
= 0;
648 pFattrs
->fsSelection
= FATTR_SEL_BOLD
;
650 if (pFont
->GetStyle() == wxITALIC
|| pFont
->GetStyle() == wxSLANT
)
651 pFattrs
->fsSelection
|= FATTR_SEL_ITALIC
;
653 if (pFont
->GetUnderlined())
654 pFattrs
->fsSelection
|= FATTR_SEL_UNDERSCORE
;
655 } // end of wxOS2SelectMatchingFontByName
657 wxFont
wxCreateFontFromLogFont(
658 const LOGFONT
* pLogFont
659 , const PFONTMETRICS pFM
660 , PFACENAMEDESC pFaceName
663 wxNativeFontInfo vInfo
;
665 vInfo
.fa
= *pLogFont
;
667 vInfo
.fn
= *pFaceName
;
668 return wxFont(vInfo
);
669 } // end of wxCreateFontFromLogFont
708 d1
= wxToupper(s0
[i
]) - wxToupper(s1
[i
]);