From: Vadim Zeitlin Date: Sat, 30 Oct 1999 00:08:04 +0000 (+0000) Subject: wxFontEnumerator mostly works for wxMSW X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/a1d58ddc1557d0bd454ed9ccd58d7761ed242d67 wxFontEnumerator mostly works for wxMSW git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@4269 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/include/wx/msw/font.h b/include/wx/msw/font.h index 78a836caac..f7596f241b 100644 --- a/include/wx/msw/font.h +++ b/include/wx/msw/font.h @@ -6,7 +6,7 @@ // Created: 01/02/97 // RCS-ID: $Id$ // Copyright: (c) Julian Smart -// Licence: wxWindows licence +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// #ifndef _WX_FONT_H_ @@ -16,9 +16,14 @@ #pragma interface "font.h" #endif -#include "wx/gdiobj.h" +// ---------------------------------------------------------------------------- +// public functions +// ---------------------------------------------------------------------------- -WXDLLEXPORT_DATA(extern const wxChar*) wxEmptyString; +// convert wxFontEncoding into one of Windows XXX_CHARSET constants (fill exact +// parameter if it's not NULL with TRUE if encoding is realyl supported under +// Windows and FALSE if not and we just chose something close to it) +extern int wxCharsetFromEncoding(wxFontEncoding encoding, bool *exact = NULL); // ---------------------------------------------------------------------------- // wxFont diff --git a/samples/font/font.cpp b/samples/font/font.cpp index 2873c93ef7..7aee6fac4a 100644 --- a/samples/font/font.cpp +++ b/samples/font/font.cpp @@ -95,6 +95,8 @@ protected: void DoEnumerateFamilies(bool fixedWidthOnly, wxFontEncoding encoding = wxFONTENCODING_SYSTEM); + void DoChangeFont(const wxFont& font, const wxColour& col = wxNullColour); + void Resize(const wxSize& size, const wxFont& font = wxNullFont); wxTextCtrl *m_textctrl; @@ -180,7 +182,7 @@ bool MyApp::OnInit() // frame constructor MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size) - : wxFrame((wxFrame *)NULL, -1, title, pos, size) + : wxFrame((wxFrame *)NULL, -1, title, pos, size), m_textctrl(NULL) { // create a menu bar wxMenu *menuFile = new wxMenu; @@ -219,8 +221,8 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size) m_canvas = new MyCanvas(this); // create a status bar just for fun (by default with 1 pane only) - CreateStatusBar(2); - SetStatusText("Welcome to wxWindows!"); + CreateStatusBar(); + SetStatusText("Welcome to wxWindows font demo!"); } @@ -263,35 +265,45 @@ void MyFrame::DoEnumerateFamilies(bool fixedWidthOnly, wxFontEncoding encoding) class MyFontEnumerator : public wxFontEnumerator { public: - MyFontEnumerator() { m_n = 0; } - - bool GotAny() const { return m_n; } + bool GotAny() const { return !m_facenames.IsEmpty(); } - const wxString& GetText() const { return m_text; } + const wxArrayString& GetFacenames() const { return m_facenames; } protected: virtual bool OnFontFamily(const wxString& family) { - wxString text; - text.Printf("Font family %d: %s\n", ++m_n, family.c_str()); - m_text += text; + m_facenames.Add(family); return TRUE; } private: - size_t m_n; - - wxString m_text; + wxArrayString m_facenames; } fontEnumerator; fontEnumerator.EnumerateFamilies(encoding, fixedWidthOnly); if ( fontEnumerator.GotAny() ) { - wxLogMessage("Enumerating %s font families:\n%s", - fixedWidthOnly ? "fixed width" : "all", - fontEnumerator.GetText().c_str()); + int n, nFacenames = fontEnumerator.GetFacenames().GetCount(); + wxLogStatus(this, "Found %d %sfonts", + nFacenames, fixedWidthOnly ? "fixed width " : ""); + + wxString *facenames = new wxString[nFacenames]; + for ( n = 0; n < nFacenames; n++ ) + facenames[n] = fontEnumerator.GetFacenames().Item(n); + + n = wxGetSingleChoiceIndex("Choose a facename", "Font demo", + nFacenames, facenames, this); + if ( n != -1 ) + { + wxFont font(14, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, + wxFONTWEIGHT_NORMAL, FALSE, facenames[n], encoding); + + DoChangeFont(font); + } + + delete [] facenames; } else { @@ -328,7 +340,8 @@ void MyFrame::OnEnumerateFamiliesForEncoding(wxCommandEvent& WXUNUSED(event)) }; int n = wxGetSingleChoiceIndex("Choose an encoding", "Font demo", - WXSIZEOF(encodingNames), encodingNames, + WXSIZEOF(encodingNames), + (char **)encodingNames, this); if ( n != -1 ) @@ -337,6 +350,20 @@ void MyFrame::OnEnumerateFamiliesForEncoding(wxCommandEvent& WXUNUSED(event)) } } +void MyFrame::DoChangeFont(const wxFont& font, const wxColour& col) +{ + Resize(GetSize(), font); + + m_canvas->SetTextFont(font); + if ( col.Ok() ) + m_canvas->SetColour(col); + m_canvas->Refresh(); + + m_textctrl->SetFont(font); + if ( col.Ok() ) + m_textctrl->SetForegroundColour(col); +} + void MyFrame::OnSelectFont(wxCommandEvent& WXUNUSED(event)) { wxFontData data; @@ -350,14 +377,7 @@ void MyFrame::OnSelectFont(wxCommandEvent& WXUNUSED(event)) wxFont font = retData.GetChosenFont(); wxColour colour = retData.GetColour(); - Resize(GetSize(), font); - - m_canvas->SetTextFont(font); - m_canvas->SetColour(colour); - m_canvas->Refresh(); - - m_textctrl->SetFont(font); - m_textctrl->SetForegroundColour(colour); + DoChangeFont(font, colour); } } @@ -384,6 +404,9 @@ void MyFrame::OnSize(wxSizeEvent& event) void MyFrame::Resize(const wxSize& size, const wxFont& font) { + if ( !m_textctrl ) + return; + wxCoord h; if ( font.Ok() ) { diff --git a/src/msw/font.cpp b/src/msw/font.cpp index 50daad4e83..0c45d9b9e8 100644 --- a/src/msw/font.cpp +++ b/src/msw/font.cpp @@ -328,69 +328,7 @@ bool wxFont::RealizeResource() BYTE ff_underline = M_FONTDATA->m_underlined; - wxFontEncoding encoding = M_FONTDATA->m_encoding; - if ( encoding == wxFONTENCODING_DEFAULT ) - { - encoding = wxFont::GetDefaultEncoding(); - } - - DWORD charset; - switch ( encoding ) - { - case wxFONTENCODING_ISO8859_1: - case wxFONTENCODING_ISO8859_15: - case wxFONTENCODING_CP1250: - charset = ANSI_CHARSET; - break; -#if !defined(__WIN16__) - case wxFONTENCODING_ISO8859_2: - case wxFONTENCODING_CP1252: - charset = EASTEUROPE_CHARSET; - break; - - case wxFONTENCODING_ISO8859_4: - case wxFONTENCODING_ISO8859_10: - charset = BALTIC_CHARSET; - break; - - case wxFONTENCODING_ISO8859_5: - case wxFONTENCODING_CP1251: - charset = RUSSIAN_CHARSET; - break; - - case wxFONTENCODING_ISO8859_6: - charset = ARABIC_CHARSET; - break; - - case wxFONTENCODING_ISO8859_7: - charset = GREEK_CHARSET; - break; - - case wxFONTENCODING_ISO8859_8: - charset = HEBREW_CHARSET; - break; - - case wxFONTENCODING_ISO8859_9: - charset = TURKISH_CHARSET; - break; - - case wxFONTENCODING_ISO8859_11: - charset = THAI_CHARSET; - break; -#endif // BC++ 16-bit - - case wxFONTENCODING_CP437: - charset = OEM_CHARSET; - break; - - default: - wxFAIL_MSG(wxT("unsupported encoding")); - // fall through - - case wxFONTENCODING_SYSTEM: - charset = ANSI_CHARSET; - } - + DWORD charset = wxCharsetFromEncoding(GetEncoding()); HFONT hFont = ::CreateFont ( nHeight, // height @@ -576,3 +514,80 @@ wxFontEncoding wxFont::GetEncoding() const { return M_FONTDATA->m_encoding; } + +// ---------------------------------------------------------------------------- +// public functions +// ---------------------------------------------------------------------------- + +int wxCharsetFromEncoding(wxFontEncoding encoding, bool *exact) +{ + if ( encoding == wxFONTENCODING_DEFAULT ) + { + encoding = wxFont::GetDefaultEncoding(); + } + + if ( exact ) + *exact = TRUE; + + int charset; + switch ( encoding ) + { + case wxFONTENCODING_ISO8859_1: + case wxFONTENCODING_ISO8859_15: + case wxFONTENCODING_CP1250: + charset = ANSI_CHARSET; + break; + +#if !defined(__WIN16__) + case wxFONTENCODING_ISO8859_2: + case wxFONTENCODING_CP1252: + charset = EASTEUROPE_CHARSET; + break; + + case wxFONTENCODING_ISO8859_4: + case wxFONTENCODING_ISO8859_10: + charset = BALTIC_CHARSET; + break; + + case wxFONTENCODING_ISO8859_5: + case wxFONTENCODING_CP1251: + charset = RUSSIAN_CHARSET; + break; + + case wxFONTENCODING_ISO8859_6: + charset = ARABIC_CHARSET; + break; + + case wxFONTENCODING_ISO8859_7: + charset = GREEK_CHARSET; + break; + + case wxFONTENCODING_ISO8859_8: + charset = HEBREW_CHARSET; + break; + + case wxFONTENCODING_ISO8859_9: + charset = TURKISH_CHARSET; + break; + + case wxFONTENCODING_ISO8859_11: + charset = THAI_CHARSET; + break; +#endif // BC++ 16-bit + + case wxFONTENCODING_CP437: + charset = OEM_CHARSET; + break; + + default: + if ( exact ) + *exact = FALSE; + // fall through + + case wxFONTENCODING_SYSTEM: + charset = ANSI_CHARSET; + } + + return charset; +} + diff --git a/src/msw/fontdlg.cpp b/src/msw/fontdlg.cpp index c68ffd6d2e..b15c904cc8 100644 --- a/src/msw/fontdlg.cpp +++ b/src/msw/fontdlg.cpp @@ -6,7 +6,7 @@ // Created: 01/02/97 // RCS-ID: $Id$ // Copyright: (c) Julian Smart and Markus Holzem -// Licence: wxWindows licence +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// #ifdef __GNUG__ @@ -149,7 +149,7 @@ void wxFillLogFont(LOGFONT *logFont, wxFont *font) break; case wxDEFAULT: default: ff_family = FF_SWISS; - ff_face = "MS Sans Serif" ; + ff_face = "MS Sans Serif" ; } if (font->GetStyle() == wxITALIC || font->GetStyle() == wxSLANT) @@ -194,7 +194,7 @@ void wxFillLogFont(LOGFONT *logFont, wxFont *font) logFont->lfItalic = ff_italic; logFont->lfUnderline = (BYTE)ff_underline; logFont->lfStrikeOut = 0; - logFont->lfCharSet = ANSI_CHARSET; + logFont->lfCharSet = wxCharsetFromEncoding(font->GetEncoding()); logFont->lfOutPrecision = OUT_DEFAULT_PRECIS; logFont->lfClipPrecision = CLIP_DEFAULT_PRECIS; logFont->lfQuality = PROOF_QUALITY; @@ -202,80 +202,127 @@ void wxFillLogFont(LOGFONT *logFont, wxFont *font) wxStrcpy(logFont->lfFaceName, ff_face); } -wxFont wxCreateFontFromLogFont(LOGFONT *logFont) // , bool createNew) +wxFont wxCreateFontFromLogFont(LOGFONT *logFont) { - int fontFamily = wxSWISS; - int fontStyle = wxNORMAL; - int fontWeight = wxNORMAL; - int fontPoints = 10; - bool fontUnderline = FALSE; - wxChar *fontFace = NULL; - -// int lfFamily = logFont->lfPitchAndFamily & 0xF0; - int lfFamily = logFont->lfPitchAndFamily; - if (lfFamily & FIXED_PITCH) - lfFamily -= FIXED_PITCH; - if (lfFamily & VARIABLE_PITCH) - lfFamily -= VARIABLE_PITCH; - - switch (lfFamily) - { - case FF_ROMAN: - fontFamily = wxROMAN; - break; - case FF_SWISS: - fontFamily = wxSWISS; - break; - case FF_SCRIPT: - fontFamily = wxSCRIPT; - break; - case FF_MODERN: - fontFamily = wxMODERN; - break; - case FF_DECORATIVE: - fontFamily = wxDECORATIVE; - break; - default: - fontFamily = wxSWISS; - break; - } - switch (logFont->lfWeight) - { - case FW_LIGHT: - fontWeight = wxLIGHT; - break; - case FW_NORMAL: - fontWeight = wxNORMAL; - break; - case FW_BOLD: - fontWeight = wxBOLD; - break; - default: - fontWeight = wxNORMAL; - break; - } - if (logFont->lfItalic) - fontStyle = wxITALIC; - else - fontStyle = wxNORMAL; - - if (logFont->lfUnderline) - fontUnderline = TRUE; - - if (logFont->lfFaceName) - fontFace = logFont->lfFaceName; - - HDC dc2 = ::GetDC(NULL); - - if ( logFont->lfHeight < 0 ) - logFont->lfHeight = - logFont->lfHeight; - fontPoints = abs(72*logFont->lfHeight/GetDeviceCaps(dc2, LOGPIXELSY)); - ::ReleaseDC(NULL, dc2); - -// if ( createNew ) - return wxFont(fontPoints, fontFamily, fontStyle, fontWeight, fontUnderline, fontFace); -// else -// return wxTheFontList->FindOrCreateFont(fontPoints, fontFamily, fontStyle, fontWeight, fontUnderline, fontFace); + int fontFamily = wxSWISS; + int fontStyle = wxNORMAL; + int fontWeight = wxNORMAL; + int fontPoints = 10; + bool fontUnderline = FALSE; + wxChar *fontFace = NULL; + + int lfFamily = logFont->lfPitchAndFamily; + if (lfFamily & FIXED_PITCH) + lfFamily -= FIXED_PITCH; + if (lfFamily & VARIABLE_PITCH) + lfFamily -= VARIABLE_PITCH; + + switch (lfFamily) + { + case FF_ROMAN: + fontFamily = wxROMAN; + break; + case FF_SWISS: + fontFamily = wxSWISS; + break; + case FF_SCRIPT: + fontFamily = wxSCRIPT; + break; + case FF_MODERN: + fontFamily = wxMODERN; + break; + case FF_DECORATIVE: + fontFamily = wxDECORATIVE; + break; + default: + fontFamily = wxSWISS; + break; + } + switch (logFont->lfWeight) + { + case FW_LIGHT: + fontWeight = wxLIGHT; + break; + case FW_NORMAL: + fontWeight = wxNORMAL; + break; + case FW_BOLD: + fontWeight = wxBOLD; + break; + default: + fontWeight = wxNORMAL; + break; + } + if (logFont->lfItalic) + fontStyle = wxITALIC; + else + fontStyle = wxNORMAL; + + if (logFont->lfUnderline) + fontUnderline = TRUE; + + if (logFont->lfFaceName) + fontFace = logFont->lfFaceName; + + wxFontEncoding fontEncoding; + switch ( logFont->lfCharSet ) + { + default: + wxFAIL_MSG(wxT("unsupported charset")); + // fall through + + case ANSI_CHARSET: + fontEncoding = wxFONTENCODING_ISO8859_1; + break; + + case EASTEUROPE_CHARSET: + fontEncoding = wxFONTENCODING_ISO8859_2; + break; + + case BALTIC_CHARSET: + fontEncoding = wxFONTENCODING_ISO8859_4; + break; + + case RUSSIAN_CHARSET: + fontEncoding = wxFONTENCODING_CP1251; + break; + + case ARABIC_CHARSET: + fontEncoding = wxFONTENCODING_ISO8859_6; + break; + + case GREEK_CHARSET: + fontEncoding = wxFONTENCODING_ISO8859_7; + break; + + case HEBREW_CHARSET: + fontEncoding = wxFONTENCODING_ISO8859_8; + break; + + case TURKISH_CHARSET: + fontEncoding = wxFONTENCODING_ISO8859_9; + break; + + case THAI_CHARSET: + fontEncoding = wxFONTENCODING_ISO8859_11; + break; + + + case OEM_CHARSET: + fontEncoding = wxFONTENCODING_CP437; + break; + } + + HDC dc2 = ::GetDC(NULL); + + if ( logFont->lfHeight < 0 ) + logFont->lfHeight = - logFont->lfHeight; + fontPoints = abs(72*logFont->lfHeight/GetDeviceCaps(dc2, LOGPIXELSY)); + ::ReleaseDC(NULL, dc2); + + return wxFont(fontPoints, fontFamily, fontStyle, + fontWeight, fontUnderline, fontFace, + fontEncoding); } diff --git a/src/msw/fontenum.cpp b/src/msw/fontenum.cpp index fe6fe19421..ed6a823992 100644 --- a/src/msw/fontenum.cpp +++ b/src/msw/fontenum.cpp @@ -1,13 +1,25 @@ -///////////////////////////////////////////////////////////////////////////// -// Name: fontenum.cpp +/////////////////////////////////////////////////////////////////////////////// +// Name: msw/fontenum.cpp // Purpose: wxFontEnumerator class for Windows // Author: Julian Smart -// Modified by: +// Modified by: Vadim Zeitlin to add support for font encodings // Created: 04/01/98 // RCS-ID: $Id$ // Copyright: (c) Julian Smart // Licence: wxWindows licence -///////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + +#ifdef __GNUG__ + #pragma implementation "fontenum.h" +#endif // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" @@ -20,44 +32,164 @@ #include "wx/font.h" #endif -#include +#include "wx/fontenum.h" -int CALLBACK wxFontEnumeratorProc(LPLOGFONT lplf, LPTEXTMETRIC lptm, - DWORD dwStyle, LONG lParam) +#include "wx/msw/private.h" + +// ---------------------------------------------------------------------------- +// private classes +// ---------------------------------------------------------------------------- + +class wxFontEnumeratorHelper { - // Get rid of any fonts that we don't want... - if (dwStyle != TRUETYPE_FONTTYPE) - return 1; +public: + wxFontEnumeratorHelper(wxFontEnumerator *fontEnum); + + // control what exactly are we enumerating + bool SetEncoding(wxFontEncoding encoding); + void SetFixedOnly(bool fixedOnly) + { m_fixedOnly = fixedOnly; } + + // call to start enumeration + void DoEnumerate(); + + // called by our font enumeration proc + bool OnFont(const LPLOGFONT lf, const LPTEXTMETRIC tm) const; + +private: + // the object we forward calls to OnFont() to + wxFontEnumerator *m_fontEnum; - wxFontEnumerator *fontEnum = (wxFontEnumerator *)lParam; + // if != -1, enum only fonts which have this encoding + int m_charset; - wxFont font = wxCreateFontFromLogFont(lplf); + // if TRUE, enum only fixed fonts + bool m_fixedOnly; +}; - if (fontEnum->OnFont(font)) - return 1 ; - else - return 0 ; +// ---------------------------------------------------------------------------- +// private functions +// ---------------------------------------------------------------------------- + +int CALLBACK wxFontEnumeratorProc(LPLOGFONT lplf, LPTEXTMETRIC lptm, + DWORD dwStyle, LONG lParam); + +// ============================================================================ +// implementation +// ============================================================================ + +// ---------------------------------------------------------------------------- +// wxFontEnumeratorHelper +// ---------------------------------------------------------------------------- + +wxFontEnumeratorHelper::wxFontEnumeratorHelper(wxFontEnumerator *fontEnum) +{ + m_fontEnum = fontEnum; + m_charset = -1; + m_fixedOnly = FALSE; } -IMPLEMENT_CLASS(wxFontEnumerator, wxObject) +bool wxFontEnumeratorHelper::SetEncoding(wxFontEncoding encoding) +{ + bool exact; + m_charset = wxCharsetFromEncoding(encoding, &exact); +#ifdef __WIN32__ + if ( !exact ) + { + m_charset = DEFAULT_CHARSET; + } +#endif // Win32 -bool wxFontEnumerator::Enumerate() + return exact; +} + +void wxFontEnumeratorHelper::DoEnumerate() { - m_faceNames.Clear(); + HDC hDC = ::GetDC(NULL); - HDC hDC = ::GetDC(NULL); #ifdef __WIN32__ - ::EnumFontFamilies(hDC, (LPTSTR) NULL, (FONTENUMPROC) wxFontEnumeratorProc, (LPARAM) (void*) this) ; -#else - ::EnumFonts(hDC, (LPTSTR) NULL, (FONTENUMPROC) wxFontEnumeratorProc, (LPARAM) (void*) this) ; -#endif - ::ReleaseDC(NULL, hDC); - return TRUE; -} + LOGFONT lf; + lf.lfCharSet = m_charset; + lf.lfFaceName[0] = _T('\0'); + lf.lfPitchAndFamily = 0; + ::EnumFontFamiliesEx(hDC, &lf, (FONTENUMPROC)wxFontEnumeratorProc, + (LPARAM)this, 0 /* reserved */) ; +#else // Win16 + ::EnumFonts(hDC, (LPTSTR)NULL, (FONTENUMPROC)wxFontEnumeratorProc, + (LPARAM) (void*) this) ; +#endif // Win32/16 -bool wxFontEnumerator::OnFont(const wxFont& font) + ::ReleaseDC(NULL, hDC); +} + +bool wxFontEnumeratorHelper::OnFont(const LPLOGFONT lf, + const LPTEXTMETRIC tm) const +{ + if ( m_fixedOnly ) + { + // check that it's a fixed pitch font (there is *no* error here, the + // flag name is misleading!) + if ( tm->tmPitchAndFamily & TMPF_FIXED_PITCH ) + { + // not a fixed pitch font + return TRUE; + } + } + + if ( m_charset != -1 ) + { + // check that we have the right encoding + if ( lf->lfCharSet != m_charset ) + { + return TRUE; + } + } + + return m_fontEnum->OnFontFamily(lf->lfFaceName); +} + +// ---------------------------------------------------------------------------- +// wxFontEnumerator +// ---------------------------------------------------------------------------- + +bool wxFontEnumerator::EnumerateFamilies(wxFontEncoding encoding, + bool fixedWidthOnly) { - m_faceNames.Add(font.GetFaceName()); + wxFontEnumeratorHelper fe(this); + if ( fe.SetEncoding(encoding) ) + { + fe.SetFixedOnly(fixedWidthOnly); + + fe.DoEnumerate(); + } + // else: no such fonts, unknown encoding + return TRUE; } +bool wxFontEnumerator::EnumerateEncodings(const wxString& family) +{ + wxFAIL_MSG(wxT("TODO")); + + return TRUE; +} + +// ---------------------------------------------------------------------------- +// Windows callbacks +// ---------------------------------------------------------------------------- + +int CALLBACK wxFontEnumeratorProc(LPLOGFONT lplf, LPTEXTMETRIC lptm, + DWORD dwStyle, LONG lParam) +{ + // Get rid of any fonts that we don't want... + if ( dwStyle != TRUETYPE_FONTTYPE ) + { + // continue enumeration + return TRUE; + } + + wxFontEnumeratorHelper *fontEnum = (wxFontEnumeratorHelper *)lParam; + + return fontEnum->OnFont(lplf, lptm); +} +