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 6// Created: 04/01/98 7// RCS-ID: $Id: fontenum.cpp 47549 2007-07-18 15:03:10Z VS $ 8// Copyright: (c) Julian Smart 9// Licence: wxWindows licence 10/////////////////////////////////////////////////////////////////////////////// 11 12// ============================================================================ 13// declarations 14// ============================================================================ 15 16// ---------------------------------------------------------------------------- 17// headers 18// ---------------------------------------------------------------------------- 19 20// For compilers that support precompilation, includes "wx.h". 21#include "wx/wxprec.h" 22 23#ifdef __BORLANDC__ 24 #pragma hdrstop 25#endif 26 27#if wxUSE_FONTMAP 28 29#ifndef WX_PRECOMP 30 #include "wx/gdicmn.h" 31 #include "wx/font.h" 32 #include "wx/encinfo.h" 33 #include "wx/dynarray.h" 34#endif 35 36#include "wx/msw/private.h" 37 38#include "wx/fontutil.h" 39#include "wx/fontenum.h" 40#include "wx/fontmap.h" 41 42// ---------------------------------------------------------------------------- 43// private classes 44// ---------------------------------------------------------------------------- 45 46// the helper class which calls ::EnumFontFamilies() and whose OnFont() is 47// called from the callback passed to this function and, in its turn, calls the 48// appropariate wxFontEnumerator method 49class wxFontEnumeratorHelper 50{ 51public: 52 wxFontEnumeratorHelper(wxFontEnumerator *fontEnum); 53 54 // control what exactly are we enumerating 55 // we enumerate fonts with given enocding 56 bool SetEncoding(wxFontEncoding encoding); 57 // we enumerate fixed-width fonts 58 void SetFixedOnly(bool fixedOnly) { m_fixedOnly = fixedOnly; } 59 // we enumerate the encodings available in this family 60 void SetFamily(const wxString& family); 61 62 // call to start enumeration 63 void DoEnumerate(); 64 65 // called by our font enumeration proc 66 bool OnFont(const LPLOGFONT lf, const LPTEXTMETRIC tm) const; 67 68private: 69 // the object we forward calls to OnFont() to 70 wxFontEnumerator *m_fontEnum; 71 72 // if != -1, enum only fonts which have this encoding 73 int m_charset; 74 75 // if not empty, enum only the fonts with this facename 76 wxString m_facename; 77 78 // if not empty, enum only the fonts in this family 79 wxString m_family; 80 81 // if true, enum only fixed fonts 82 bool m_fixedOnly; 83 84 // if true, we enumerate the encodings, not fonts 85 bool m_enumEncodings; 86 87 // the list of charsets we already found while enumerating charsets 88 wxArrayInt m_charsets; 89 90 // the list of facenames we already found while enumerating facenames 91 wxArrayString m_facenames; 92 93 DECLARE_NO_COPY_CLASS(wxFontEnumeratorHelper) 94}; 95 96// ---------------------------------------------------------------------------- 97// private functions 98// ---------------------------------------------------------------------------- 99 100#ifndef __WXMICROWIN__ 101int CALLBACK wxFontEnumeratorProc(LPLOGFONT lplf, LPTEXTMETRIC lptm, 102 DWORD dwStyle, LONG lParam); 103#endif 104 105// ============================================================================ 106// implementation 107// ============================================================================ 108 109// ---------------------------------------------------------------------------- 110// wxFontEnumeratorHelper 111// ---------------------------------------------------------------------------- 112 113wxFontEnumeratorHelper::wxFontEnumeratorHelper(wxFontEnumerator *fontEnum) 114{ 115 m_fontEnum = fontEnum; 116 m_charset = DEFAULT_CHARSET; 117 m_fixedOnly = false; 118 m_enumEncodings = false; 119} 120 121void wxFontEnumeratorHelper::SetFamily(const wxString& family) 122{ 123 m_enumEncodings = true; 124 m_family = family; 125} 126 127bool wxFontEnumeratorHelper::SetEncoding(wxFontEncoding encoding) 128{ 129 if ( encoding != wxFONTENCODING_SYSTEM ) 130 { 131 wxNativeEncodingInfo info; 132 if ( !wxGetNativeFontEncoding(encoding, &info) ) 133 { 134#if wxUSE_FONTMAP 135 if ( !wxFontMapper::Get()->GetAltForEncoding(encoding, &info) ) 136#endif // wxUSE_FONTMAP 137 { 138 // no such encodings at all 139 return false; 140 } 141 } 142 143 m_charset = info.charset; 144 m_facename = info.facename; 145 } 146 147 return true; 148} 149 150#if defined(__GNUWIN32__) && !defined(__CYGWIN10__) && !wxCHECK_W32API_VERSION( 1, 1 ) && !wxUSE_NORLANDER_HEADERS 151 #define wxFONTENUMPROC int(*)(ENUMLOGFONTEX *, NEWTEXTMETRICEX*, int, LPARAM) 152#else 153 #define wxFONTENUMPROC FONTENUMPROC 154#endif 155 156void wxFontEnumeratorHelper::DoEnumerate() 157{ 158#ifndef __WXMICROWIN__ 159 HDC hDC = ::GetDC(NULL); 160 161#ifdef __WXWINCE__ 162 ::EnumFontFamilies(hDC, 163 m_facename.empty() ? NULL : m_facename.c_str(), 164 (wxFONTENUMPROC)wxFontEnumeratorProc, 165 (LPARAM)this) ; 166#else // __WIN32__ 167 LOGFONT lf; 168 lf.lfCharSet = (BYTE)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 */) ; 173#endif // Win32/CE 174 175 ::ReleaseDC(NULL, hDC); 176#endif 177} 178 179bool wxFontEnumeratorHelper::OnFont(const LPLOGFONT lf, 180 const LPTEXTMETRIC tm) const 181{ 182 if ( m_enumEncodings ) 183 { 184 // is this a new charset? 185 int cs = lf->lfCharSet; 186 if ( m_charsets.Index(cs) == wxNOT_FOUND ) 187 { 188 wxConstCast(this, wxFontEnumeratorHelper)->m_charsets.Add(cs); 189 190 wxFontEncoding enc = wxGetFontEncFromCharSet(cs); 191 return m_fontEnum->OnFontEncoding(lf->lfFaceName, 192 wxFontMapper::GetEncodingName(enc)); 193 } 194 else 195 { 196 // continue enumeration 197 return true; 198 } 199 } 200 201 if ( m_fixedOnly ) 202 { 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 ) 206 { 207 // not a fixed pitch font 208 return true; 209 } 210 } 211 212 if ( m_charset != DEFAULT_CHARSET ) 213 { 214 // check that we have the right encoding 215 if ( lf->lfCharSet != m_charset ) 216 { 217 return true; 218 } 219 } 220 else // enumerating fonts in all charsets 221 { 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 ) 226 { 227 // continue enumeration 228 return true; 229 } 230 231 wxConstCast(this, wxFontEnumeratorHelper)-> 232 m_facenames.Add(lf->lfFaceName); 233 } 234 235 return m_fontEnum->OnFacename(lf->lfFaceName); 236} 237 238// ---------------------------------------------------------------------------- 239// wxFontEnumerator 240// ---------------------------------------------------------------------------- 241 242bool wxFontEnumerator::EnumerateFacenames(wxFontEncoding encoding, 243 bool fixedWidthOnly) 244{ 245 wxFontEnumeratorHelper fe(this); 246 if ( fe.SetEncoding(encoding) ) 247 { 248 fe.SetFixedOnly(fixedWidthOnly); 249 250 fe.DoEnumerate(); 251 } 252 // else: no such fonts, unknown encoding 253 254 return true; 255} 256 257bool wxFontEnumerator::EnumerateEncodings(const wxString& family) 258{ 259 wxFontEnumeratorHelper fe(this); 260 fe.SetFamily(family); 261 fe.DoEnumerate(); 262 263 return true; 264} 265 266// ---------------------------------------------------------------------------- 267// Windows callbacks 268// ---------------------------------------------------------------------------- 269 270#ifndef __WXMICROWIN__ 271int CALLBACK wxFontEnumeratorProc(LPLOGFONT lplf, LPTEXTMETRIC lptm, 272 DWORD WXUNUSED(dwStyle), LONG lParam) 273{ 274 275 // we used to process TrueType fonts only, but there doesn't seem to be any 276 // reasons to restrict ourselves to them here 277#if 0 278 // Get rid of any fonts that we don't want... 279 if ( dwStyle != TRUETYPE_FONTTYPE ) 280 { 281 // continue enumeration 282 return TRUE; 283 } 284#endif // 0 285 286 wxFontEnumeratorHelper *fontEnum = (wxFontEnumeratorHelper *)lParam; 287 288 return fontEnum->OnFont(lplf, lptm); 289} 290#endif 291 292#endif // wxUSE_FONTMAP 293