1 /////////////////////////////////////////////////////////////////////////////// 
   2 // Name:        msw/fontenum.cpp 
   3 // Purpose:     wxFontEnumerator class for Windows 
   4 // Author:      Julian Smart 
   5 // Modified by: Vadim Zeitlin to add support for font encodings 
   8 // Copyright:   (c) Julian Smart 
   9 // Licence:     wxWindows licence 
  10 /////////////////////////////////////////////////////////////////////////////// 
  12 // ============================================================================ 
  14 // ============================================================================ 
  16 // ---------------------------------------------------------------------------- 
  18 // ---------------------------------------------------------------------------- 
  20 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) 
  21     #pragma implementation "fontenum.h" 
  24 // For compilers that support precompilation, includes "wx.h". 
  25 #include "wx/wxprec.h" 
  35     #include "wx/encinfo.h" 
  38 #include "wx/msw/private.h" 
  40 #include "wx/fontutil.h" 
  41 #include "wx/fontenum.h" 
  42 #include "wx/fontmap.h" 
  44 // ---------------------------------------------------------------------------- 
  46 // ---------------------------------------------------------------------------- 
  48 // the helper class which calls ::EnumFontFamilies() and whose OnFont() is 
  49 // called from the callback passed to this function and, in its turn, calls the 
  50 // appropariate wxFontEnumerator method 
  51 class wxFontEnumeratorHelper
 
  54     wxFontEnumeratorHelper(wxFontEnumerator 
*fontEnum
); 
  56     // control what exactly are we enumerating 
  57         // we enumerate fonts with given enocding 
  58     bool SetEncoding(wxFontEncoding encoding
); 
  59         // we enumerate fixed-width fonts 
  60     void SetFixedOnly(bool fixedOnly
) { m_fixedOnly 
= fixedOnly
; } 
  61         // we enumerate the encodings available in this family 
  62     void SetFamily(const wxString
& family
); 
  64     // call to start enumeration 
  67     // called by our font enumeration proc 
  68     bool OnFont(const LPLOGFONT lf
, const LPTEXTMETRIC tm
) const; 
  71     // the object we forward calls to OnFont() to 
  72     wxFontEnumerator 
*m_fontEnum
; 
  74     // if != -1, enum only fonts which have this encoding 
  77     // if not empty, enum only the fonts with this facename 
  80     // if not empty, enum only the fonts in this family 
  83     // if TRUE, enum only fixed fonts 
  86     // if TRUE, we enumerate the encodings, not fonts 
  89     // the list of charsets we already found while enumerating charsets 
  90     wxArrayInt m_charsets
; 
  92     // the list of facenames we already found while enumerating facenames 
  93     wxArrayString m_facenames
; 
  95     DECLARE_NO_COPY_CLASS(wxFontEnumeratorHelper
) 
  98 // ---------------------------------------------------------------------------- 
 100 // ---------------------------------------------------------------------------- 
 102 #ifndef __WXMICROWIN__ 
 103 int CALLBACK 
wxFontEnumeratorProc(LPLOGFONT lplf
, LPTEXTMETRIC lptm
, 
 104                                   DWORD dwStyle
, LONG lParam
); 
 107 // ============================================================================ 
 109 // ============================================================================ 
 111 // ---------------------------------------------------------------------------- 
 112 // wxFontEnumeratorHelper 
 113 // ---------------------------------------------------------------------------- 
 115 wxFontEnumeratorHelper::wxFontEnumeratorHelper(wxFontEnumerator 
*fontEnum
) 
 117     m_fontEnum 
= fontEnum
; 
 118     m_charset 
= DEFAULT_CHARSET
; 
 120     m_enumEncodings 
= FALSE
; 
 123 void wxFontEnumeratorHelper::SetFamily(const wxString
& family
) 
 125     m_enumEncodings 
= TRUE
; 
 129 bool wxFontEnumeratorHelper::SetEncoding(wxFontEncoding encoding
) 
 131     if ( encoding 
!= wxFONTENCODING_SYSTEM 
) 
 133         wxNativeEncodingInfo info
; 
 134         if ( !wxGetNativeFontEncoding(encoding
, &info
) ) 
 137             if ( !wxFontMapper::Get()->GetAltForEncoding(encoding
, &info
) ) 
 138 #endif // wxUSE_FONTMAP 
 140                 // no such encodings at all 
 145         m_charset 
= info
.charset
; 
 146         m_facename 
= info
.facename
; 
 152 #if defined(__GNUWIN32__) && !defined(__CYGWIN10__) && !wxCHECK_W32API_VERSION( 1, 1 ) && !wxUSE_NORLANDER_HEADERS 
 153     #define wxFONTENUMPROC int(*)(ENUMLOGFONTEX *, NEWTEXTMETRICEX*, int, LPARAM) 
 155     #define wxFONTENUMPROC FONTENUMPROC 
 158 void wxFontEnumeratorHelper::DoEnumerate() 
 160 #ifndef __WXMICROWIN__ 
 161     HDC hDC 
= ::GetDC(NULL
); 
 164     ::EnumFontFamilies(hDC
, m_facename
, (wxFONTENUMPROC
)wxFontEnumeratorProc
, 
 168     lf
.lfCharSet 
= m_charset
; 
 169     wxStrncpy(lf
.lfFaceName
, m_facename
, WXSIZEOF(lf
.lfFaceName
)); 
 170     lf
.lfPitchAndFamily 
= 0; 
 171     ::EnumFontFamiliesEx(hDC
, &lf
, (wxFONTENUMPROC
)wxFontEnumeratorProc
, 
 172                          (LPARAM
)this, 0 /* reserved */) ; 
 175     ::ReleaseDC(NULL
, hDC
); 
 179 bool wxFontEnumeratorHelper::OnFont(const LPLOGFONT lf
, 
 180                                     const LPTEXTMETRIC tm
) const 
 182     if ( m_enumEncodings 
) 
 184         // is this a new charset? 
 185         int cs 
= lf
->lfCharSet
; 
 186         if ( m_charsets
.Index(cs
) == wxNOT_FOUND 
) 
 188             wxConstCast(this, wxFontEnumeratorHelper
)->m_charsets
.Add(cs
); 
 190             wxFontEncoding enc 
= wxGetFontEncFromCharSet(cs
); 
 191             return m_fontEnum
->OnFontEncoding(lf
->lfFaceName
, 
 192                                               wxFontMapper::GetEncodingName(enc
)); 
 196             // continue enumeration 
 203         // check that it's a fixed pitch font (there is *no* error here, the 
 204         // flag name is misleading!) 
 205         if ( tm
->tmPitchAndFamily 
& TMPF_FIXED_PITCH 
) 
 207             // not a fixed pitch font 
 212     if ( m_charset 
!= DEFAULT_CHARSET 
) 
 214         // check that we have the right encoding 
 215         if ( lf
->lfCharSet 
!= m_charset 
) 
 220     else // enumerating fonts in all charsets 
 222         // we can get the same facename twice or more in this case because it 
 223         // may exist in several charsets but we only want to return one copy of 
 224         // it (note that this can't happen for m_charset != DEFAULT_CHARSET) 
 225         if ( m_facenames
.Index(lf
->lfFaceName
) != wxNOT_FOUND 
) 
 227             // continue enumeration 
 231         wxConstCast(this, wxFontEnumeratorHelper
)-> 
 232             m_facenames
.Add(lf
->lfFaceName
); 
 235     return m_fontEnum
->OnFacename(lf
->lfFaceName
); 
 238 // ---------------------------------------------------------------------------- 
 240 // ---------------------------------------------------------------------------- 
 242 bool wxFontEnumerator::EnumerateFacenames(wxFontEncoding encoding
, 
 245     wxFontEnumeratorHelper 
fe(this); 
 246     if ( fe
.SetEncoding(encoding
) ) 
 248         fe
.SetFixedOnly(fixedWidthOnly
); 
 252     // else: no such fonts, unknown encoding 
 257 bool wxFontEnumerator::EnumerateEncodings(const wxString
& family
) 
 259     wxFontEnumeratorHelper 
fe(this); 
 260     fe
.SetFamily(family
); 
 266 // ---------------------------------------------------------------------------- 
 268 // ---------------------------------------------------------------------------- 
 270 #ifndef __WXMICROWIN__ 
 271 int CALLBACK 
wxFontEnumeratorProc(LPLOGFONT lplf
, LPTEXTMETRIC lptm
, 
 272                                   DWORD 
WXUNUSED(dwStyle
), LONG lParam
) 
 275     // we used to process TrueType fonts only, but there doesn't seem to be any 
 276     // reasons to restrict ourselves to them here 
 278     // Get rid of any fonts that we don't want... 
 279     if ( dwStyle 
!= TRUETYPE_FONTTYPE 
) 
 281         // continue enumeration 
 286     wxFontEnumeratorHelper 
*fontEnum 
= (wxFontEnumeratorHelper 
*)lParam
; 
 288     return fontEnum
->OnFont(lplf
, lptm
); 
 292 #endif // wxUSE_FONTMAP