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
]);