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 license
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"
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(
60 wxStringTokenizer
vTokenizer(rsStr
, _T(";"));
61 wxString sEncid
= vTokenizer
.GetNextToken();
64 if (!sEncid
.ToLong(&lEnc
))
66 encoding
= (wxFontEncoding
)lEnc
;
67 facename
= vTokenizer
.GetNextToken();
71 wxString sTmp
= vTokenizer
.GetNextToken();
79 if ( wxSscanf(sTmp
, _T("%u"), &charset
) != 1 )
81 // should be a number!
86 } // end of wxNativeEncodingInfo::FromString
88 wxString
wxNativeEncodingInfo::ToString() const
92 sStr
<< (long)encoding
<< _T(';') << facename
;
96 sStr
<< _T(';') << charset
;
99 } // end of wxNativeEncodingInfo::ToString
101 // ----------------------------------------------------------------------------
103 // ----------------------------------------------------------------------------
105 bool wxGetNativeFontEncoding(
106 wxFontEncoding vEncoding
107 , wxNativeEncodingInfo
* pInfo
110 wxCHECK_MSG(pInfo
, FALSE
, _T("bad pointer in wxGetNativeFontEncoding") );
111 if (vEncoding
== wxFONTENCODING_DEFAULT
)
113 vEncoding
= wxFont::GetDefaultEncoding();
117 case wxFONTENCODING_ISO8859_1
:
118 case wxFONTENCODING_ISO8859_15
:
119 case wxFONTENCODING_CP1250
:
120 pInfo
->charset
= 1250;
123 case wxFONTENCODING_ISO8859_2
:
124 case wxFONTENCODING_CP1252
:
125 pInfo
->charset
= 1252;
128 case wxFONTENCODING_ISO8859_4
:
129 case wxFONTENCODING_ISO8859_10
:
130 pInfo
->charset
= 921; // what is baltic?
133 case wxFONTENCODING_ISO8859_5
:
134 case wxFONTENCODING_CP1251
:
135 pInfo
->charset
= 1251;
138 case wxFONTENCODING_ISO8859_6
:
139 pInfo
->charset
= 864;
142 case wxFONTENCODING_ISO8859_7
:
143 pInfo
->charset
= 869;
146 case wxFONTENCODING_ISO8859_8
:
147 pInfo
->charset
= 862;
150 case wxFONTENCODING_ISO8859_9
:
151 pInfo
->charset
= 857;
154 case wxFONTENCODING_ISO8859_11
:
155 pInfo
->charset
= 874; // what is thai
158 case wxFONTENCODING_CP437
:
159 pInfo
->charset
= 437;
163 wxFAIL_MSG(wxT("unsupported encoding"));
166 case wxFONTENCODING_SYSTEM
:
167 pInfo
->charset
= 850;
171 } // end of wxGetNativeFontEncoding
173 wxFontEncoding
wxGetFontEncFromCharSet(
177 wxFontEncoding eFontEncoding
;
183 eFontEncoding
= wxFONTENCODING_CP1250
;
187 eFontEncoding
= wxFONTENCODING_CP1252
;
191 eFontEncoding
= wxFONTENCODING_ISO8859_4
;
195 eFontEncoding
= wxFONTENCODING_CP1251
;
199 eFontEncoding
= wxFONTENCODING_ISO8859_6
;
203 eFontEncoding
= wxFONTENCODING_ISO8859_7
;
207 eFontEncoding
= wxFONTENCODING_ISO8859_8
;
211 eFontEncoding
= wxFONTENCODING_ISO8859_9
;
215 eFontEncoding
= wxFONTENCODING_ISO8859_11
;
219 eFontEncoding
= wxFONTENCODING_CP437
;
222 return eFontEncoding
;
223 } // end of wxGetNativeFontEncoding
225 bool wxTestFontEncoding(
226 const wxNativeEncodingInfo
& rInfo
232 hPS
= ::WinGetPS(HWND_DESKTOP
);
234 memset(&vLogFont
, '\0', sizeof(FATTRS
)); // all default values
235 vLogFont
.usRecordLength
= sizeof(FATTRS
);
236 vLogFont
.usCodePage
= rInfo
.charset
;
237 vLogFont
.lMaxBaselineExt
= 0L; // Outline fonts should use 0
238 vLogFont
.lAveCharWidth
= 0L; // Outline fonts should use 0
239 vLogFont
.fsFontUse
= FATTR_FONTUSE_OUTLINE
| // only outline fonts allowed
240 FATTR_FONTUSE_TRANSFORMABLE
; // may be transformed
242 strncpy(vLogFont
.szFacename
, rInfo
.facename
.c_str(), sizeof(vLogFont
.szFacename
));
244 if (!::GpiCreateLogFont( hPS
255 } // end of wxTestFontEncoding
257 // ----------------------------------------------------------------------------
258 // wxFont <-> LOGFONT conversion
259 // ----------------------------------------------------------------------------
262 LOGFONT
* pFattrs
// OS2 GPI FATTRS
263 , PFACENAMEDESC pFaceName
266 , wxString
& sFaceName
270 LONG lNumFonts
= 0L; // For system font count
271 ERRORID vError
; // For logging API errors
273 bool bInternalPS
= FALSE
; // if we have to create one
274 PFONTMETRICS pFM
= NULL
;
277 // Initial house cleaning to free data buffers and ensure we have a
278 // functional PS to work with
282 *phPS
= ::WinGetPS(HWND_DESKTOP
);
287 // Determine the number of fonts.
289 if((lNumFonts
= ::GpiQueryFonts( *phPS
293 ,(LONG
) sizeof(FONTMETRICS
)
300 vError
= ::WinGetLastError(wxGetInstance());
301 sError
= wxPMErrorToStr(vError
);
306 // Allocate space for the font metrics.
308 pFM
= new FONTMETRICS
[lNumFonts
+ 1];
311 // Retrieve the font metrics.
314 lTemp
= ::GpiQueryFonts( *phPS
318 ,(LONG
) sizeof(FONTMETRICS
)
327 for (int i
= 0; i
< lNumFonts
; i
++)
329 sVals
<< "Face: " << pFM
[i
].szFacename
330 << "Family: " << pFM
[i
].szFamilyname
331 << " PointSize: " << pFM
[i
].lEmHeight
332 << " Height: " << pFM
[i
].lXHeight
338 // Initialize FATTR and FACENAMEDESC
340 pFattrs
->usRecordLength
= sizeof(FATTRS
);
341 pFattrs
->fsFontUse
= FATTR_FONTUSE_OUTLINE
| // only outline fonts allowed
342 FATTR_FONTUSE_TRANSFORMABLE
; // may be transformed
344 pFattrs
->lMaxBaselineExt
= pFattrs
->lAveCharWidth
= 0;
345 pFattrs
->idRegistry
= 0;
348 pFaceName
->usSize
= sizeof(FACENAMEDESC
);
349 pFaceName
->usWidthClass
= FWIDTH_NORMAL
;
350 pFaceName
->usReserved
= 0;
351 pFaceName
->flOptions
= 0;
354 // This does the actual selection of fonts
356 wxOS2SelectMatchingFontByName( pFattrs
363 // We should now have the correct FATTRS set with the selected
364 // font, so now we need to generate an ID
366 long lNumLids
= ::GpiQueryNumberSetIds(*phPS
);
375 if(!::GpiQuerySetIds( *phPS
383 ::WinReleasePS(*phPS
);
387 for(unsigned long LCNum
= 0; LCNum
< lNumLids
; LCNum
++)
388 if(alIds
[LCNum
] == *pflId
)
390 if(*pflId
> 254) // wow, no id available!
393 ::WinReleasePS(*phPS
);
400 // Release and delete the current font
402 ::GpiSetCharSet(*phPS
, LCID_DEFAULT
);/* release the font before deleting */
403 ::GpiDeleteSetId(*phPS
, 1L); /* delete the logical font */
406 // Now build a facestring
410 strcpy(zFacename
, pFattrs
->szFacename
);
412 if(::GpiQueryFaceString( *phPS
419 vError
= ::WinGetLastError(vHabmain
);
421 sFaceName
= zFacename
;
424 // That's it, we now have everything we need to actually create the font
426 } // end of wxFillLogFont
428 void wxOS2SelectMatchingFontByName(
430 , PFACENAMEDESC pFaceName
433 , const wxFont
* pFont
448 char zFontFaceName
[FACESIZE
];
450 USHORT usWeightClass
;
454 for(i
= 0;i
< 16; i
++)
455 anMinDiff
[i
] = nMinDiff0
;
457 switch (pFont
->GetFamily())
460 sFaceName
= wxT("Script");
465 sFaceName
= wxT("Times New Roman");
470 sFaceName
= wxT("Courier") ;
474 sFaceName
= wxT("WarpSans") ;
479 sFaceName
= wxT("Helv") ;
482 switch (pFont
->GetWeight())
485 wxFAIL_MSG(_T("unknown font weight"));
487 usWeightClass
= FWEIGHT_DONT_CARE
;
491 usWeightClass
= FWEIGHT_NORMAL
;
495 usWeightClass
= FWEIGHT_LIGHT
;
499 usWeightClass
= FWEIGHT_BOLD
;
502 case wxFONTWEIGHT_MAX
:
503 usWeightClass
= FWEIGHT_ULTRA_BOLD
;
506 pFaceName
->usWeightClass
= usWeightClass
;
508 switch (pFont
->GetStyle())
512 fsSelection
= FM_SEL_ITALIC
;
513 pFaceName
->flOptions
= FTYPE_ITALIC
;
517 wxFAIL_MSG(wxT("unknown font slant"));
525 wxStrncpy(zFontFaceName
, sFaceName
.c_str(), WXSIZEOF(zFontFaceName
));
526 nPointSize
= pFont
->GetPointSize();
529 // Matching logic to find the right FM struct
532 for(i
= 0, nIs
= 0; i
< nNumFonts
; i
++)
537 anDiff
[0] = wxGpiStrcmp(pFM
[i
].szFamilyname
, zFontFaceName
);
538 anDiff
[1] = abs(pFM
[i
].lEmHeight
- nPointSize
);
539 anDiff
[2] = abs(pFM
[i
].usWeightClass
- usWeightClass
);
540 anDiff
[3] = abs((pFM
[i
].fsSelection
& 0x2f) - fsSelection
);
543 nEmHeight
= (int)pFM
[i
].lEmHeight
;
544 nXHeight
=(int)pFM
[i
].lXHeight
;
545 if( (nIs
& 0x01) == 0)
549 anMinDiff
[1] = anDiff
[1];
550 anMinDiff
[2] = anDiff
[2];
551 anMinDiff
[3] = anDiff
[3];
553 else if(anDiff
[3] < anMinDiff
[3])
556 anMinDiff
[3] = anDiff
[3];
558 else if(anDiff
[2] < anMinDiff
[2])
561 anMinDiff
[2] = anDiff
[2];
563 else if(anDiff
[1] < anMinDiff
[1])
566 anMinDiff
[1] = anDiff
[1];
570 else if(anDiff
[0] < anMinDiff
[0])
574 anMinDiff
[3] = anDiff
[3];
575 anMinDiff
[2] = anDiff
[2];
576 anMinDiff
[1] = anDiff
[1];
577 anMinDiff
[0] = anDiff
[0];
579 else if(anDiff
[0] == anMinDiff
[0])
581 if(anDiff
[3] < anMinDiff
[3])
584 anMinDiff
[3] = anDiff
[3];
587 else if(anDiff
[2] < anMinDiff
[2])
590 anMinDiff
[2] = anDiff
[2];
593 else if(anDiff
[1] < anMinDiff
[1])
596 anMinDiff
[1] = anDiff
[1];
603 // Fill in the FATTRS with the best match from FONTMETRICS
605 pFattrs
->usRecordLength
= sizeof(FATTRS
); // sets size of structure
606 pFattrs
->fsSelection
= pFM
[nIndex
].fsSelection
; // uses default selection
607 pFattrs
->lMatch
= pFM
[nIndex
].lMatch
; // force match
608 pFattrs
->idRegistry
= pFM
[nIndex
].idRegistry
; // uses default registry
609 pFattrs
->usCodePage
= pFM
[nIndex
].usCodePage
; // code-page
610 if(pFM
[nIndex
].lMatch
)
612 pFattrs
->lMaxBaselineExt
= pFM
[nIndex
].lMaxBaselineExt
; // requested font height
613 pFattrs
->lAveCharWidth
= pFM
[nIndex
].lAveCharWidth
; // requested font width
617 pFattrs
->lMaxBaselineExt
= 0;
618 pFattrs
->lAveCharWidth
= 0;
620 pFattrs
->fsType
= 0;// pfm->fsType; /* uses default type */
621 pFattrs
->fsFontUse
= 0;
623 wxStrcpy(pFattrs
->szFacename
, pFM
[nIndex
].szFacename
);
625 strcpy(zFontFaceName
, pFM
[nIndex
].szFacename
);
626 strcpy(zFontFaceName
, pFattrs
->szFacename
);
628 if(usWeightClass
>= FWEIGHT_BOLD
)
629 pFattrs
->fsSelection
|= FATTR_SEL_BOLD
;
630 if(pFont
->GetUnderlined())
631 pFattrs
->fsSelection
|= FATTR_SEL_UNDERSCORE
;
632 if(fsSelection
& FM_SEL_ITALIC
)
633 pFattrs
->fsSelection
|= FATTR_SEL_ITALIC
;
634 } // end of wxOS2SelectMatchingFontByName
636 wxFont
wxCreateFontFromLogFont(
637 const LOGFONT
* pLogFont
638 , const PFONTMETRICS pFM
639 , PFACENAMEDESC pFaceName
643 // Extract family from facename
647 if (strcmp(pLogFont
->szFacename
, "Times New Roman") == 0)
648 nFontFamily
= wxROMAN
;
649 else if (strcmp(pLogFont
->szFacename
, "WarpSans") == 0)
650 nFontFamily
= wxSWISS
;
651 else if (strcmp(pLogFont
->szFacename
, "Script") == 0)
652 nFontFamily
= wxSCRIPT
;
653 else if (strcmp(pLogFont
->szFacename
, "Courier New") == 0)
654 nFontFamily
= wxMODERN
;
656 nFontFamily
= wxSWISS
;
661 int nFontWeight
= wxNORMAL
;
663 switch (pFaceName
->usWeightClass
)
666 nFontWeight
= wxLIGHT
;
671 nFontWeight
= wxNORMAL
;
675 nFontWeight
= wxBOLD
;
681 if(pLogFont
->fsSelection
& FATTR_SEL_ITALIC
)
682 nFontStyle
= wxITALIC
;
684 nFontStyle
= wxNORMAL
;
686 bool bFontUnderline
= (pLogFont
->fsSelection
& FATTR_SEL_UNDERSCORE
);
687 wxString sFontFace
= pLogFont
->szFacename
;
688 int nFontPoints
= pFM
->lEmHeight
;
689 wxFontEncoding vFontEncoding
;
691 switch (pLogFont
->usCodePage
)
694 wxFAIL_MSG(wxT("unsupported charset"));
698 vFontEncoding
= wxFONTENCODING_CP1252
;
702 vFontEncoding
= wxFONTENCODING_CP1250
;
706 vFontEncoding
= wxFONTENCODING_CP1257
;
710 vFontEncoding
= wxFONTENCODING_CP1251
;
714 vFontEncoding
= wxFONTENCODING_CP1256
;
718 vFontEncoding
= wxFONTENCODING_CP1253
;
722 vFontEncoding
= wxFONTENCODING_CP1255
;
726 vFontEncoding
= wxFONTENCODING_CP1254
;
730 vFontEncoding
= wxFONTENCODING_CP437
;
734 vFontEncoding
= wxFONTENCODING_CP437
;
738 return wxFont( nFontPoints
746 } // end of wxCreateFontFromLogFont
785 d1
= toupper(s0
[i
]) - toupper(s1
[i
]);