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     strncpy(vLogFont
.szFacename
, rInfo
.facename
.c_str(), sizeof(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 
< 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 
= 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     char                            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(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(pFattrs
->szFacename
, 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 
= toupper(s0
[i
]) - toupper(s1
[i
]);