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
, wxT(";")); 
  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
, wxT("%u"), &charset
) != 1 ) 
  79             // should be a number! 
  84 } // end of wxNativeEncodingInfo::FromString 
  86 wxString 
wxNativeEncodingInfo::ToString() const 
  90     sStr 
<< (long)encoding 
<< wxT(';') << facename
; 
  94         sStr 
<< wxT(';') << charset
; 
  97 } // end of wxNativeEncodingInfo::ToString 
  99 // ---------------------------------------------------------------------------- 
 101 // ---------------------------------------------------------------------------- 
 103 bool wxGetNativeFontEncoding( wxFontEncoding vEncoding
, 
 104                               wxNativeEncodingInfo
* pInfo 
) 
 106     wxCHECK_MSG(pInfo
, FALSE
, wxT("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     wxStrlcpy((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     // multiply first to avoid getting vSizef.cx,cy = 0 since fxPointSize 
 285     // is normally < 72 and FontResolution is typically ca. 100 
 286     vSizef
.cx 
= (FIXED
)( (fxPointSize 
* lXFontResolution
) / 72 ); 
 287     vSizef
.cy 
= (FIXED
)( (fxPointSize 
* lYFontResolution
) / 72 ); 
 291         pFattrs
->lMaxBaselineExt 
= MAKELONG( HIUSHORT( vSizef
.cy 
), 0 ); 
 292         pFattrs
->lAveCharWidth   
= MAKELONG( HIUSHORT( vSizef
.cx 
), 0 ); 
 296 } // end of wxConvertVectorPointSize 
 298 void wxFillLogFont( LOGFONT
*      pFattrs
,  // OS2 GPI FATTRS 
 299                     PFACENAMEDESC pFaceName
, 
 306     LONG         lNumFonts 
= 0L;       // For system font count 
 307     ERRORID      vError
;               // For logging API errors 
 309     bool         bInternalPS 
= false;  // if we have to create one 
 310     PFONTMETRICS pFM 
= NULL
; 
 313     // Initial house cleaning to free data buffers and ensure we have a 
 314     // functional PS to work with 
 318         *phPS 
= ::WinGetPS(HWND_DESKTOP
); 
 323     // Determine the number of fonts. 
 325     if((lNumFonts 
= ::GpiQueryFonts( *phPS
 
 326                                     ,QF_PUBLIC 
| QF_PRIVATE
 
 329                                     ,(LONG
) sizeof(FONTMETRICS
) 
 336         vError 
= ::WinGetLastError(wxGetInstance()); 
 337         sError 
= wxPMErrorToStr(vError
); 
 342     // Allocate space for the font metrics. 
 344     pFM 
= new FONTMETRICS
[lNumFonts 
+ 1]; 
 347     // Retrieve the font metrics. 
 350     lTemp 
= ::GpiQueryFonts( *phPS
 
 354                             ,(LONG
) sizeof(FONTMETRICS
) 
 362     // Initialize FATTR and FACENAMEDESC 
 364     pFattrs
->usRecordLength 
= sizeof(FATTRS
); 
 365     pFattrs
->fsFontUse 
= FATTR_FONTUSE_OUTLINE
;       // only outline fonts allowed 
 367     pFattrs
->lMaxBaselineExt 
= pFattrs
->lAveCharWidth 
= 0; 
 368     pFattrs
->idRegistry 
= 0; 
 371     pFaceName
->usSize 
= sizeof(FACENAMEDESC
); 
 372     pFaceName
->usWeightClass 
= FWEIGHT_DONT_CARE
; 
 373     pFaceName
->usWidthClass 
= FWIDTH_DONT_CARE
; 
 374     pFaceName
->usReserved 
= 0; 
 375     pFaceName
->flOptions 
= 0; 
 378     // This does the actual selection of fonts 
 380     wxOS2SelectMatchingFontByName( pFattrs
 
 387     // We should now have the correct FATTRS set with the selected 
 388     // font, so now we need to generate an ID 
 390     long                            lNumLids 
= ::GpiQueryNumberSetIds(*phPS
); 
 398         memset(alIds
, 0, sizeof(long) * 255); 
 399         if(!::GpiQuerySetIds( *phPS
 
 407                 ::WinReleasePS(*phPS
); 
 412         for(unsigned long LCNum 
= 0; LCNum 
< (unsigned long)lNumLids
; LCNum
++) 
 413             if(alIds
[LCNum
] == *pflId
) 
 415         if(*pflId 
> 254)  // wow, no id available! 
 418                ::WinReleasePS(*phPS
); 
 425     // Release and delete the current font 
 427     ::GpiSetCharSet(*phPS
, LCID_DEFAULT
);/* release the font before deleting */ 
 428     ::GpiDeleteSetId(*phPS
, 1L);         /* delete the logical font          */ 
 431     // Now build a facestring 
 435     strcpy(zFacename
, pFattrs
->szFacename
); 
 437     if(::GpiQueryFaceString( *phPS
 
 444         vError 
= ::WinGetLastError(vHabmain
); 
 446     sFaceName 
= (wxChar
*)zFacename
; 
 447     *pbInternalPS 
= bInternalPS
; 
 450     // That's it, we now have everything we need to actually create the font 
 452 } // end of wxFillLogFont 
 454 void wxOS2SelectMatchingFontByName( 
 456 , PFACENAMEDESC                     pFaceName
 
 459 , const wxFont
*                     pFont
 
 469     wxChar                          zFontFaceName
[FACESIZE
]; 
 471     USHORT                          usWeightClass
; 
 475     for(i 
= 0;i 
< 16; i
++) 
 476         anMinDiff
[i
] = nMinDiff0
; 
 478     switch (pFont
->GetFamily()) 
 481             sFaceName 
= wxT("Tms Rmn"); 
 485             sFaceName 
= wxT("WarpSans"); 
 489             sFaceName 
= wxT("Tms Rmn"); 
 493             sFaceName 
= wxT("Courier") ; 
 497             sFaceName 
= wxT("System VIO") ; 
 501             sFaceName 
= wxT("Helv") ; 
 506             sFaceName 
= wxT("System VIO") ; 
 509     switch (pFont
->GetWeight()) 
 512             wxFAIL_MSG(wxT("unknown font weight")); 
 514             usWeightClass 
= FWEIGHT_DONT_CARE
; 
 518             usWeightClass 
= FWEIGHT_NORMAL
; 
 522             usWeightClass 
= FWEIGHT_LIGHT
; 
 526             usWeightClass 
= FWEIGHT_BOLD
; 
 529          case wxFONTWEIGHT_MAX
: 
 530             usWeightClass 
= FWEIGHT_ULTRA_BOLD
; 
 533     pFaceName
->usWeightClass 
= usWeightClass
; 
 535     switch (pFont
->GetStyle()) 
 539             fsSelection 
= FM_SEL_ITALIC
; 
 540             pFaceName
->flOptions 
= FTYPE_ITALIC
; 
 544             wxFAIL_MSG(wxT("unknown font slant")); 
 552     wxStrlcpy(zFontFaceName
, sFaceName
.c_str(), WXSIZEOF(zFontFaceName
)); 
 553     nPointSize 
= pFont
->GetPointSize(); 
 556     // Matching logic to find the right FM struct 
 559     for(i 
= 0, nIs 
= 0; i 
< nNumFonts
; i
++) 
 564         anDiff
[0] = wxGpiStrcmp((wxChar
*)pFM
[i
].szFacename
, zFontFaceName
); 
 565         anDiff
[1] = abs(pFM
[i
].lEmHeight 
- nPointSize
); 
 566         anDiff
[2] = abs(pFM
[i
].usWeightClass 
-  usWeightClass
); 
 567         anDiff
[3] = abs((pFM
[i
].fsSelection 
& 0x2f) -  fsSelection
); 
 570             nEmHeight 
= (int)pFM
[i
].lEmHeight
; 
 571             nXHeight  
=(int)pFM
[i
].lXHeight
; 
 572             if( (nIs 
& 0x01) == 0) 
 576                 anMinDiff
[1] = anDiff
[1]; 
 577                 anMinDiff
[2] = anDiff
[2]; 
 578                 anMinDiff
[3] = anDiff
[3]; 
 580             else if(anDiff
[3] < anMinDiff
[3]) 
 583                 anMinDiff
[3] = anDiff
[3]; 
 585             else if(anDiff
[2] < anMinDiff
[2]) 
 588                 anMinDiff
[2] = anDiff
[2]; 
 590             else if(anDiff
[1] < anMinDiff
[1]) 
 593                 anMinDiff
[1] = anDiff
[1]; 
 597         else if(anDiff
[0] < anMinDiff
[0]) 
 601               anMinDiff
[3] = anDiff
[3]; 
 602               anMinDiff
[2] = anDiff
[2]; 
 603               anMinDiff
[1] = anDiff
[1]; 
 604               anMinDiff
[0] = anDiff
[0]; 
 606         else if(anDiff
[0] == anMinDiff
[0]) 
 608             if(anDiff
[3] < anMinDiff
[3]) 
 611                 anMinDiff
[3] = anDiff
[3]; 
 614             else if(anDiff
[2] < anMinDiff
[2]) 
 617                 anMinDiff
[2] = anDiff
[2]; 
 620             else if(anDiff
[1] < anMinDiff
[1]) 
 623                 anMinDiff
[1] = anDiff
[1]; 
 630     // Fill in the FATTRS with the best match from FONTMETRICS 
 632     pFattrs
->usRecordLength  
= sizeof(FATTRS
);              // Sets size of structure 
 633     pFattrs
->lMatch          
= pFM
[nIndex
].lMatch
;          // Force match 
 634     pFattrs
->idRegistry      
= 0; 
 635     pFattrs
->usCodePage      
= 0; 
 636     pFattrs
->fsFontUse       
= 0; 
 638     pFattrs
->lMaxBaselineExt 
= 0; 
 639     pFattrs
->lAveCharWidth   
= 0; 
 640     wxStrcpy((wxChar
*)pFattrs
->szFacename
, (wxChar
*)pFM
[nIndex
].szFacename
); 
 641     if (pFont
->GetWeight() == wxNORMAL
) 
 642         pFattrs
->fsSelection 
= 0; 
 644         pFattrs
->fsSelection 
= FATTR_SEL_BOLD
; 
 646     if (pFont
->GetStyle() == wxITALIC 
|| pFont
->GetStyle() == wxSLANT
) 
 647         pFattrs
->fsSelection 
|= FATTR_SEL_ITALIC
; 
 649     if (pFont
->GetUnderlined()) 
 650         pFattrs
->fsSelection 
|= FATTR_SEL_UNDERSCORE
; 
 651 } // end of wxOS2SelectMatchingFontByName 
 653 wxFont 
wxCreateFontFromLogFont( 
 654   const LOGFONT
*                    pLogFont
 
 655 , const PFONTMETRICS                pFM
 
 656 , PFACENAMEDESC                     pFaceName
 
 659     wxNativeFontInfo                vInfo
; 
 661     vInfo
.fa 
= *pLogFont
; 
 663     vInfo
.fn 
= *pFaceName
; 
 664     return wxFont(vInfo
); 
 665 } // end of wxCreateFontFromLogFont 
 704         d1 
= wxToupper(s0
[i
]) - wxToupper(s1
[i
]);