1 /////////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/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 // For compilers that support precompilation, includes "wx.h". 
  21 #include "wx/wxprec.h" 
  30     #include "wx/gdicmn.h" 
  32     #include "wx/encinfo.h" 
  35 #include "wx/msw/private.h" 
  37 #include "wx/fontutil.h" 
  38 #include "wx/fontenum.h" 
  39 #include "wx/fontmap.h" 
  41 // ---------------------------------------------------------------------------- 
  43 // ---------------------------------------------------------------------------- 
  45 // the helper class which calls ::EnumFontFamilies() and whose OnFont() is 
  46 // called from the callback passed to this function and, in its turn, calls the 
  47 // appropariate wxFontEnumerator method 
  48 class wxFontEnumeratorHelper
 
  51     wxFontEnumeratorHelper(wxFontEnumerator 
*fontEnum
); 
  53     // control what exactly are we enumerating 
  54         // we enumerate fonts with given enocding 
  55     bool SetEncoding(wxFontEncoding encoding
); 
  56         // we enumerate fixed-width fonts 
  57     void SetFixedOnly(bool fixedOnly
) { m_fixedOnly 
= fixedOnly
; } 
  58         // we enumerate the encodings available in this family 
  59     void SetFamily(const wxString
& family
); 
  61     // call to start enumeration 
  64     // called by our font enumeration proc 
  65     bool OnFont(const LPLOGFONT lf
, const LPTEXTMETRIC tm
) const; 
  68     // the object we forward calls to OnFont() to 
  69     wxFontEnumerator 
*m_fontEnum
; 
  71     // if != -1, enum only fonts which have this encoding 
  74     // if not empty, enum only the fonts with this facename 
  77     // if not empty, enum only the fonts in this family 
  80     // if true, enum only fixed fonts 
  83     // if true, we enumerate the encodings, not fonts 
  86     // the list of charsets we already found while enumerating charsets 
  87     wxArrayInt m_charsets
; 
  89     // the list of facenames we already found while enumerating facenames 
  90     wxArrayString m_facenames
; 
  92     DECLARE_NO_COPY_CLASS(wxFontEnumeratorHelper
) 
  95 // ---------------------------------------------------------------------------- 
  97 // ---------------------------------------------------------------------------- 
  99 #ifndef __WXMICROWIN__ 
 100 int CALLBACK 
wxFontEnumeratorProc(LPLOGFONT lplf
, LPTEXTMETRIC lptm
, 
 101                                   DWORD dwStyle
, LONG lParam
); 
 104 // ============================================================================ 
 106 // ============================================================================ 
 108 // ---------------------------------------------------------------------------- 
 109 // wxFontEnumeratorHelper 
 110 // ---------------------------------------------------------------------------- 
 112 wxFontEnumeratorHelper::wxFontEnumeratorHelper(wxFontEnumerator 
*fontEnum
) 
 114     m_fontEnum 
= fontEnum
; 
 115     m_charset 
= DEFAULT_CHARSET
; 
 117     m_enumEncodings 
= false; 
 120 void wxFontEnumeratorHelper::SetFamily(const wxString
& family
) 
 122     m_enumEncodings 
= true; 
 126 bool wxFontEnumeratorHelper::SetEncoding(wxFontEncoding encoding
) 
 128     if ( encoding 
!= wxFONTENCODING_SYSTEM 
) 
 130         wxNativeEncodingInfo info
; 
 131         if ( !wxGetNativeFontEncoding(encoding
, &info
) ) 
 134             if ( !wxFontMapper::Get()->GetAltForEncoding(encoding
, &info
) ) 
 135 #endif // wxUSE_FONTMAP 
 137                 // no such encodings at all 
 142         m_charset 
= info
.charset
; 
 143         m_facename 
= info
.facename
; 
 149 #if defined(__GNUWIN32__) && !defined(__CYGWIN10__) && !wxCHECK_W32API_VERSION( 1, 1 ) && !wxUSE_NORLANDER_HEADERS 
 150     #define wxFONTENUMPROC int(*)(ENUMLOGFONTEX *, NEWTEXTMETRICEX*, int, LPARAM) 
 152     #define wxFONTENUMPROC FONTENUMPROC 
 155 void wxFontEnumeratorHelper::DoEnumerate() 
 157 #ifndef __WXMICROWIN__ 
 158     HDC hDC 
= ::GetDC(NULL
); 
 161     ::EnumFontFamilies(hDC
, 
 162                        m_facename
.empty() ? NULL 
: m_facename
.c_str(), 
 163                        (wxFONTENUMPROC
)wxFontEnumeratorProc
, 
 167     lf
.lfCharSet 
= (BYTE
)m_charset
; 
 168     wxStrncpy(lf
.lfFaceName
, m_facename
, WXSIZEOF(lf
.lfFaceName
)); 
 169     lf
.lfPitchAndFamily 
= 0; 
 170     ::EnumFontFamiliesEx(hDC
, &lf
, (wxFONTENUMPROC
)wxFontEnumeratorProc
, 
 171                          (LPARAM
)this, 0 /* reserved */) ; 
 174     ::ReleaseDC(NULL
, hDC
); 
 178 bool wxFontEnumeratorHelper::OnFont(const LPLOGFONT lf
, 
 179                                     const LPTEXTMETRIC tm
) const 
 181     if ( m_enumEncodings 
) 
 183         // is this a new charset? 
 184         int cs 
= lf
->lfCharSet
; 
 185         if ( m_charsets
.Index(cs
) == wxNOT_FOUND 
) 
 187             wxConstCast(this, wxFontEnumeratorHelper
)->m_charsets
.Add(cs
); 
 189             wxFontEncoding enc 
= wxGetFontEncFromCharSet(cs
); 
 190             return m_fontEnum
->OnFontEncoding(lf
->lfFaceName
, 
 191                                               wxFontMapper::GetEncodingName(enc
)); 
 195             // continue enumeration 
 202         // check that it's a fixed pitch font (there is *no* error here, the 
 203         // flag name is misleading!) 
 204         if ( tm
->tmPitchAndFamily 
& TMPF_FIXED_PITCH 
) 
 206             // not a fixed pitch font 
 211     if ( m_charset 
!= DEFAULT_CHARSET 
) 
 213         // check that we have the right encoding 
 214         if ( lf
->lfCharSet 
!= m_charset 
) 
 219     else // enumerating fonts in all charsets 
 221         // we can get the same facename twice or more in this case because it 
 222         // may exist in several charsets but we only want to return one copy of 
 223         // it (note that this can't happen for m_charset != DEFAULT_CHARSET) 
 224         if ( m_facenames
.Index(lf
->lfFaceName
) != wxNOT_FOUND 
) 
 226             // continue enumeration 
 230         wxConstCast(this, wxFontEnumeratorHelper
)-> 
 231             m_facenames
.Add(lf
->lfFaceName
); 
 234     return m_fontEnum
->OnFacename(lf
->lfFaceName
); 
 237 // ---------------------------------------------------------------------------- 
 239 // ---------------------------------------------------------------------------- 
 241 bool wxFontEnumerator::EnumerateFacenames(wxFontEncoding encoding
, 
 244     wxFontEnumeratorHelper 
fe(this); 
 245     if ( fe
.SetEncoding(encoding
) ) 
 247         fe
.SetFixedOnly(fixedWidthOnly
); 
 251     // else: no such fonts, unknown encoding 
 256 bool wxFontEnumerator::EnumerateEncodings(const wxString
& family
) 
 258     wxFontEnumeratorHelper 
fe(this); 
 259     fe
.SetFamily(family
); 
 265 // ---------------------------------------------------------------------------- 
 267 // ---------------------------------------------------------------------------- 
 269 #ifndef __WXMICROWIN__ 
 270 int CALLBACK 
wxFontEnumeratorProc(LPLOGFONT lplf
, LPTEXTMETRIC lptm
, 
 271                                   DWORD 
WXUNUSED(dwStyle
), LONG lParam
) 
 274     // we used to process TrueType fonts only, but there doesn't seem to be any 
 275     // reasons to restrict ourselves to them here 
 277     // Get rid of any fonts that we don't want... 
 278     if ( dwStyle 
!= TRUETYPE_FONTTYPE 
) 
 280         // continue enumeration 
 285     wxFontEnumeratorHelper 
*fontEnum 
= (wxFontEnumeratorHelper 
*)lParam
; 
 287     return fontEnum
->OnFont(lplf
, lptm
); 
 291 #endif // wxUSE_FONTMAP