1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/msw/fontutil.cpp
3 // Purpose: font-related helper functions for wxMSW
4 // Author: Modified by David Webster for OS/2
7 // Copyright: (c) 1999 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
11 // ============================================================================
13 // ============================================================================
15 // ----------------------------------------------------------------------------
17 // ----------------------------------------------------------------------------
19 // For compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
22 #define DEBUG_PRINTF(NAME) \
25 printf( #NAME " %i\n",raz); fflush(stdout); \
31 #include "wx/string.h"
36 #include "wx/os2/private.h"
38 #include "wx/fontutil.h"
39 #include "wx/fontmap.h"
40 #include "wx/encinfo.h"
42 #include "wx/tokenzr.h"
44 // ============================================================================
46 // ============================================================================
48 // ----------------------------------------------------------------------------
49 // wxNativeEncodingInfo
50 // ----------------------------------------------------------------------------
52 // convert to/from the string representation: format is
53 // encodingid;facename[;charset]
55 bool wxNativeEncodingInfo::FromString( const wxString
& rsStr
)
57 wxStringTokenizer
vTokenizer(rsStr
, wxT(";"));
58 wxString sEncid
= vTokenizer
.GetNextToken();
61 if (!sEncid
.ToLong(&lEnc
))
63 encoding
= (wxFontEncoding
)lEnc
;
64 facename
= vTokenizer
.GetNextToken();
68 wxString sTmp
= vTokenizer
.GetNextToken();
76 if ( wxSscanf(sTmp
, wxT("%u"), &charset
) != 1 )
78 // should be a number!
83 } // end of wxNativeEncodingInfo::FromString
85 wxString
wxNativeEncodingInfo::ToString() const
89 sStr
<< (long)encoding
<< wxT(';') << facename
;
93 sStr
<< wxT(';') << charset
;
96 } // end of wxNativeEncodingInfo::ToString
98 // ----------------------------------------------------------------------------
100 // ----------------------------------------------------------------------------
102 bool wxGetNativeFontEncoding( wxFontEncoding vEncoding
,
103 wxNativeEncodingInfo
* pInfo
)
105 wxCHECK_MSG(pInfo
, FALSE
, wxT("bad pointer in wxGetNativeFontEncoding") );
106 if (vEncoding
== wxFONTENCODING_DEFAULT
)
108 vEncoding
= wxFont::GetDefaultEncoding();
112 case wxFONTENCODING_ISO8859_1
:
113 case wxFONTENCODING_ISO8859_15
:
114 case wxFONTENCODING_CP1250
:
115 pInfo
->charset
= 1250;
118 case wxFONTENCODING_ISO8859_2
:
119 case wxFONTENCODING_CP1252
:
120 pInfo
->charset
= 1252;
123 case wxFONTENCODING_ISO8859_4
:
124 case wxFONTENCODING_ISO8859_10
:
125 pInfo
->charset
= 921; // what is baltic?
128 case wxFONTENCODING_ISO8859_5
:
129 case wxFONTENCODING_CP1251
:
130 pInfo
->charset
= 1251;
133 case wxFONTENCODING_ISO8859_6
:
134 pInfo
->charset
= 864;
137 case wxFONTENCODING_ISO8859_7
:
138 pInfo
->charset
= 869;
141 case wxFONTENCODING_ISO8859_8
:
142 pInfo
->charset
= 862;
145 case wxFONTENCODING_ISO8859_9
:
146 pInfo
->charset
= 857;
149 case wxFONTENCODING_ISO8859_11
:
150 pInfo
->charset
= 874; // what is thai
153 case wxFONTENCODING_CP437
:
154 pInfo
->charset
= 437;
158 wxFAIL_MSG(wxT("unsupported encoding"));
161 case wxFONTENCODING_SYSTEM
:
162 pInfo
->charset
= 850;
166 } // end of wxGetNativeFontEncoding
168 wxFontEncoding
wxGetFontEncFromCharSet(
172 wxFontEncoding eFontEncoding
;
178 eFontEncoding
= wxFONTENCODING_CP1250
;
182 eFontEncoding
= wxFONTENCODING_CP1252
;
186 eFontEncoding
= wxFONTENCODING_ISO8859_4
;
190 eFontEncoding
= wxFONTENCODING_CP1251
;
194 eFontEncoding
= wxFONTENCODING_ISO8859_6
;
198 eFontEncoding
= wxFONTENCODING_ISO8859_7
;
202 eFontEncoding
= wxFONTENCODING_ISO8859_8
;
206 eFontEncoding
= wxFONTENCODING_ISO8859_9
;
210 eFontEncoding
= wxFONTENCODING_ISO8859_11
;
214 eFontEncoding
= wxFONTENCODING_CP437
;
217 return eFontEncoding
;
218 } // end of wxGetNativeFontEncoding
220 bool wxTestFontEncoding( const wxNativeEncodingInfo
& rInfo
)
225 hPS
= ::WinGetPS(HWND_DESKTOP
);
227 memset(&vLogFont
, '\0', sizeof(FATTRS
)); // all default values
228 vLogFont
.usRecordLength
= sizeof(FATTRS
);
229 vLogFont
.usCodePage
= (USHORT
)rInfo
.charset
;
230 vLogFont
.lMaxBaselineExt
= 0L; // Outline fonts should use 0
231 vLogFont
.lAveCharWidth
= 0L; // Outline fonts should use 0
232 vLogFont
.fsFontUse
= FATTR_FONTUSE_OUTLINE
| // only outline fonts allowed
233 FATTR_FONTUSE_TRANSFORMABLE
; // may be transformed
235 wxStrlcpy((wxChar
*)vLogFont
.szFacename
, rInfo
.facename
.c_str(), WXSIZEOF(vLogFont
.szFacename
));
237 if (!::GpiCreateLogFont( hPS
248 } // end of wxTestFontEncoding
250 // ----------------------------------------------------------------------------
251 // wxFont <-> LOGFONT conversion
252 // ----------------------------------------------------------------------------
254 void wxConvertVectorFontSize(
261 LONG lXFontResolution
;
262 LONG lYFontResolution
;
265 hPS
= WinGetScreenPS(HWND_DESKTOP
); // Screen presentation space
268 // Query device context for the screen and then query
269 // the resolution of the device for the device context.
272 hDC
= GpiQueryDevice(hPS
);
273 DevQueryCaps( hDC
, CAPS_HORIZONTAL_FONT_RES
, (LONG
)1, &lXFontResolution
);
274 DevQueryCaps( hDC
, CAPS_VERTICAL_FONT_RES
, (LONG
)1, &lYFontResolution
);
277 // Calculate the size of the character box, based on the
278 // point size selected and the resolution of the device.
279 // The size parameters are of type FIXED, NOT int.
280 // NOTE: 1 point == 1/72 of an inch.
283 // multiply first to avoid getting vSizef.cx,cy = 0 since fxPointSize
284 // is normally < 72 and FontResolution is typically ca. 100
285 vSizef
.cx
= (FIXED
)( (fxPointSize
* lXFontResolution
) / 72 );
286 vSizef
.cy
= (FIXED
)( (fxPointSize
* lYFontResolution
) / 72 );
290 pFattrs
->lMaxBaselineExt
= MAKELONG( HIUSHORT( vSizef
.cy
), 0 );
291 pFattrs
->lAveCharWidth
= MAKELONG( HIUSHORT( vSizef
.cx
), 0 );
295 } // end of wxConvertVectorPointSize
297 void wxFillLogFont( LOGFONT
* pFattrs
, // OS2 GPI FATTRS
298 PFACENAMEDESC pFaceName
,
305 LONG lNumFonts
= 0L; // For system font count
306 ERRORID vError
; // For logging API errors
308 bool bInternalPS
= false; // if we have to create one
309 PFONTMETRICS pFM
= NULL
;
312 // Initial house cleaning to free data buffers and ensure we have a
313 // functional PS to work with
317 *phPS
= ::WinGetPS(HWND_DESKTOP
);
322 // Determine the number of fonts.
324 if((lNumFonts
= ::GpiQueryFonts( *phPS
325 ,QF_PUBLIC
| QF_PRIVATE
328 ,(LONG
) sizeof(FONTMETRICS
)
335 vError
= ::WinGetLastError(wxGetInstance());
336 sError
= wxPMErrorToStr(vError
);
341 // Allocate space for the font metrics.
343 pFM
= new FONTMETRICS
[lNumFonts
+ 1];
346 // Retrieve the font metrics.
349 lTemp
= ::GpiQueryFonts( *phPS
353 ,(LONG
) sizeof(FONTMETRICS
)
361 // Initialize FATTR and FACENAMEDESC
363 pFattrs
->usRecordLength
= sizeof(FATTRS
);
364 pFattrs
->fsFontUse
= FATTR_FONTUSE_OUTLINE
; // only outline fonts allowed
366 pFattrs
->lMaxBaselineExt
= pFattrs
->lAveCharWidth
= 0;
367 pFattrs
->idRegistry
= 0;
370 pFaceName
->usSize
= sizeof(FACENAMEDESC
);
371 pFaceName
->usWeightClass
= FWEIGHT_DONT_CARE
;
372 pFaceName
->usWidthClass
= FWIDTH_DONT_CARE
;
373 pFaceName
->usReserved
= 0;
374 pFaceName
->flOptions
= 0;
377 // This does the actual selection of fonts
379 wxOS2SelectMatchingFontByName( pFattrs
386 // We should now have the correct FATTRS set with the selected
387 // font, so now we need to generate an ID
389 long lNumLids
= ::GpiQueryNumberSetIds(*phPS
);
397 memset(alIds
, 0, sizeof(long) * 255);
398 if(!::GpiQuerySetIds( *phPS
406 ::WinReleasePS(*phPS
);
411 for(unsigned long LCNum
= 0; LCNum
< (unsigned long)lNumLids
; LCNum
++)
412 if(alIds
[LCNum
] == *pflId
)
414 if(*pflId
> 254) // wow, no id available!
417 ::WinReleasePS(*phPS
);
424 // Release and delete the current font
426 ::GpiSetCharSet(*phPS
, LCID_DEFAULT
);/* release the font before deleting */
427 ::GpiDeleteSetId(*phPS
, 1L); /* delete the logical font */
430 // Now build a facestring
434 strcpy(zFacename
, pFattrs
->szFacename
);
436 if(::GpiQueryFaceString( *phPS
443 vError
= ::WinGetLastError(vHabmain
);
445 sFaceName
= (wxChar
*)zFacename
;
446 *pbInternalPS
= bInternalPS
;
449 // That's it, we now have everything we need to actually create the font
451 } // end of wxFillLogFont
453 void wxOS2SelectMatchingFontByName(
455 , PFACENAMEDESC pFaceName
458 , const wxFont
* pFont
468 wxChar zFontFaceName
[FACESIZE
];
470 USHORT usWeightClass
;
474 for(i
= 0;i
< 16; i
++)
475 anMinDiff
[i
] = nMinDiff0
;
477 switch (pFont
->GetFamily())
480 sFaceName
= wxT("Tms Rmn");
484 sFaceName
= wxT("WarpSans");
488 sFaceName
= wxT("Tms Rmn");
492 sFaceName
= wxT("Courier") ;
496 sFaceName
= wxT("System VIO") ;
500 sFaceName
= wxT("Helv") ;
505 sFaceName
= wxT("System VIO") ;
508 switch (pFont
->GetWeight())
511 wxFAIL_MSG(wxT("unknown font weight"));
513 usWeightClass
= FWEIGHT_DONT_CARE
;
517 usWeightClass
= FWEIGHT_NORMAL
;
521 usWeightClass
= FWEIGHT_LIGHT
;
525 usWeightClass
= FWEIGHT_BOLD
;
528 case wxFONTWEIGHT_MAX
:
529 usWeightClass
= FWEIGHT_ULTRA_BOLD
;
532 pFaceName
->usWeightClass
= usWeightClass
;
534 switch (pFont
->GetStyle())
538 fsSelection
= FM_SEL_ITALIC
;
539 pFaceName
->flOptions
= FTYPE_ITALIC
;
543 wxFAIL_MSG(wxT("unknown font slant"));
551 wxStrlcpy(zFontFaceName
, sFaceName
.c_str(), WXSIZEOF(zFontFaceName
));
552 nPointSize
= pFont
->GetPointSize();
555 // Matching logic to find the right FM struct
558 for(i
= 0, nIs
= 0; i
< nNumFonts
; i
++)
560 anDiff
[0] = wxGpiStrcmp((wxChar
*)pFM
[i
].szFacename
, zFontFaceName
);
561 anDiff
[1] = abs(pFM
[i
].lEmHeight
- nPointSize
);
562 anDiff
[2] = abs(pFM
[i
].usWeightClass
- usWeightClass
);
563 anDiff
[3] = abs((pFM
[i
].fsSelection
& 0x2f) - fsSelection
);
566 if( (nIs
& 0x01) == 0)
570 anMinDiff
[1] = anDiff
[1];
571 anMinDiff
[2] = anDiff
[2];
572 anMinDiff
[3] = anDiff
[3];
574 else if(anDiff
[3] < anMinDiff
[3])
577 anMinDiff
[3] = anDiff
[3];
579 else if(anDiff
[2] < anMinDiff
[2])
582 anMinDiff
[2] = anDiff
[2];
584 else if(anDiff
[1] < anMinDiff
[1])
587 anMinDiff
[1] = anDiff
[1];
591 else if(anDiff
[0] < anMinDiff
[0])
595 anMinDiff
[3] = anDiff
[3];
596 anMinDiff
[2] = anDiff
[2];
597 anMinDiff
[1] = anDiff
[1];
598 anMinDiff
[0] = anDiff
[0];
600 else if(anDiff
[0] == anMinDiff
[0])
602 if(anDiff
[3] < anMinDiff
[3])
605 anMinDiff
[3] = anDiff
[3];
608 else if(anDiff
[2] < anMinDiff
[2])
611 anMinDiff
[2] = anDiff
[2];
614 else if(anDiff
[1] < anMinDiff
[1])
617 anMinDiff
[1] = anDiff
[1];
624 // Fill in the FATTRS with the best match from FONTMETRICS
626 pFattrs
->usRecordLength
= sizeof(FATTRS
); // Sets size of structure
627 pFattrs
->lMatch
= pFM
[nIndex
].lMatch
; // Force match
628 pFattrs
->idRegistry
= 0;
629 pFattrs
->usCodePage
= 0;
630 pFattrs
->fsFontUse
= 0;
632 pFattrs
->lMaxBaselineExt
= 0;
633 pFattrs
->lAveCharWidth
= 0;
634 wxStrcpy((wxChar
*)pFattrs
->szFacename
, (wxChar
*)pFM
[nIndex
].szFacename
);
635 if (pFont
->GetWeight() == wxNORMAL
)
636 pFattrs
->fsSelection
= 0;
638 pFattrs
->fsSelection
= FATTR_SEL_BOLD
;
640 if (pFont
->GetStyle() == wxITALIC
|| pFont
->GetStyle() == wxSLANT
)
641 pFattrs
->fsSelection
|= FATTR_SEL_ITALIC
;
643 if (pFont
->GetUnderlined())
644 pFattrs
->fsSelection
|= FATTR_SEL_UNDERSCORE
;
645 } // end of wxOS2SelectMatchingFontByName
647 wxFont
wxCreateFontFromLogFont(
648 const LOGFONT
* pLogFont
649 , const PFONTMETRICS pFM
650 , PFACENAMEDESC pFaceName
653 wxNativeFontInfo vInfo
;
655 vInfo
.fa
= *pLogFont
;
657 vInfo
.fn
= *pFaceName
;
658 return wxFont(vInfo
);
659 } // end of wxCreateFontFromLogFont
698 d1
= wxToupper(s0
[i
]) - wxToupper(s1
[i
]);