wxFontEnumerator mostly works for wxMSW

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@4269 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
1999-10-30 00:08:04 +00:00
parent 740c28d5e8
commit a1d58ddc15
5 changed files with 417 additions and 195 deletions

View File

@@ -16,9 +16,14 @@
#pragma interface "font.h" #pragma interface "font.h"
#endif #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 // wxFont

View File

@@ -95,6 +95,8 @@ protected:
void DoEnumerateFamilies(bool fixedWidthOnly, void DoEnumerateFamilies(bool fixedWidthOnly,
wxFontEncoding encoding = wxFONTENCODING_SYSTEM); wxFontEncoding encoding = wxFONTENCODING_SYSTEM);
void DoChangeFont(const wxFont& font, const wxColour& col = wxNullColour);
void Resize(const wxSize& size, const wxFont& font = wxNullFont); void Resize(const wxSize& size, const wxFont& font = wxNullFont);
wxTextCtrl *m_textctrl; wxTextCtrl *m_textctrl;
@@ -180,7 +182,7 @@ bool MyApp::OnInit()
// frame constructor // frame constructor
MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size) 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 // create a menu bar
wxMenu *menuFile = new wxMenu; wxMenu *menuFile = new wxMenu;
@@ -219,8 +221,8 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
m_canvas = new MyCanvas(this); m_canvas = new MyCanvas(this);
// create a status bar just for fun (by default with 1 pane only) // create a status bar just for fun (by default with 1 pane only)
CreateStatusBar(2); CreateStatusBar();
SetStatusText("Welcome to wxWindows!"); SetStatusText("Welcome to wxWindows font demo!");
} }
@@ -263,35 +265,45 @@ void MyFrame::DoEnumerateFamilies(bool fixedWidthOnly, wxFontEncoding encoding)
class MyFontEnumerator : public wxFontEnumerator class MyFontEnumerator : public wxFontEnumerator
{ {
public: public:
MyFontEnumerator() { m_n = 0; } bool GotAny() const { return !m_facenames.IsEmpty(); }
bool GotAny() const { return m_n; } const wxArrayString& GetFacenames() const { return m_facenames; }
const wxString& GetText() const { return m_text; }
protected: protected:
virtual bool OnFontFamily(const wxString& family) virtual bool OnFontFamily(const wxString& family)
{ {
wxString text; m_facenames.Add(family);
text.Printf("Font family %d: %s\n", ++m_n, family.c_str());
m_text += text;
return TRUE; return TRUE;
} }
private: private:
size_t m_n; wxArrayString m_facenames;
wxString m_text;
} fontEnumerator; } fontEnumerator;
fontEnumerator.EnumerateFamilies(encoding, fixedWidthOnly); fontEnumerator.EnumerateFamilies(encoding, fixedWidthOnly);
if ( fontEnumerator.GotAny() ) if ( fontEnumerator.GotAny() )
{ {
wxLogMessage("Enumerating %s font families:\n%s", int n, nFacenames = fontEnumerator.GetFacenames().GetCount();
fixedWidthOnly ? "fixed width" : "all", wxLogStatus(this, "Found %d %sfonts",
fontEnumerator.GetText().c_str()); 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 else
{ {
@@ -328,7 +340,8 @@ void MyFrame::OnEnumerateFamiliesForEncoding(wxCommandEvent& WXUNUSED(event))
}; };
int n = wxGetSingleChoiceIndex("Choose an encoding", "Font demo", int n = wxGetSingleChoiceIndex("Choose an encoding", "Font demo",
WXSIZEOF(encodingNames), encodingNames, WXSIZEOF(encodingNames),
(char **)encodingNames,
this); this);
if ( n != -1 ) 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)) void MyFrame::OnSelectFont(wxCommandEvent& WXUNUSED(event))
{ {
wxFontData data; wxFontData data;
@@ -350,14 +377,7 @@ void MyFrame::OnSelectFont(wxCommandEvent& WXUNUSED(event))
wxFont font = retData.GetChosenFont(); wxFont font = retData.GetChosenFont();
wxColour colour = retData.GetColour(); wxColour colour = retData.GetColour();
Resize(GetSize(), font); DoChangeFont(font, colour);
m_canvas->SetTextFont(font);
m_canvas->SetColour(colour);
m_canvas->Refresh();
m_textctrl->SetFont(font);
m_textctrl->SetForegroundColour(colour);
} }
} }
@@ -384,6 +404,9 @@ void MyFrame::OnSize(wxSizeEvent& event)
void MyFrame::Resize(const wxSize& size, const wxFont& font) void MyFrame::Resize(const wxSize& size, const wxFont& font)
{ {
if ( !m_textctrl )
return;
wxCoord h; wxCoord h;
if ( font.Ok() ) if ( font.Ok() )
{ {

View File

@@ -328,69 +328,7 @@ bool wxFont::RealizeResource()
BYTE ff_underline = M_FONTDATA->m_underlined; BYTE ff_underline = M_FONTDATA->m_underlined;
wxFontEncoding encoding = M_FONTDATA->m_encoding; DWORD charset = wxCharsetFromEncoding(GetEncoding());
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;
}
HFONT hFont = ::CreateFont HFONT hFont = ::CreateFont
( (
nHeight, // height nHeight, // height
@@ -576,3 +514,80 @@ wxFontEncoding wxFont::GetEncoding() const
{ {
return M_FONTDATA->m_encoding; 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;
}

View File

@@ -194,7 +194,7 @@ void wxFillLogFont(LOGFONT *logFont, wxFont *font)
logFont->lfItalic = ff_italic; logFont->lfItalic = ff_italic;
logFont->lfUnderline = (BYTE)ff_underline; logFont->lfUnderline = (BYTE)ff_underline;
logFont->lfStrikeOut = 0; logFont->lfStrikeOut = 0;
logFont->lfCharSet = ANSI_CHARSET; logFont->lfCharSet = wxCharsetFromEncoding(font->GetEncoding());
logFont->lfOutPrecision = OUT_DEFAULT_PRECIS; logFont->lfOutPrecision = OUT_DEFAULT_PRECIS;
logFont->lfClipPrecision = CLIP_DEFAULT_PRECIS; logFont->lfClipPrecision = CLIP_DEFAULT_PRECIS;
logFont->lfQuality = PROOF_QUALITY; logFont->lfQuality = PROOF_QUALITY;
@@ -202,7 +202,7 @@ void wxFillLogFont(LOGFONT *logFont, wxFont *font)
wxStrcpy(logFont->lfFaceName, ff_face); wxStrcpy(logFont->lfFaceName, ff_face);
} }
wxFont wxCreateFontFromLogFont(LOGFONT *logFont) // , bool createNew) wxFont wxCreateFontFromLogFont(LOGFONT *logFont)
{ {
int fontFamily = wxSWISS; int fontFamily = wxSWISS;
int fontStyle = wxNORMAL; int fontStyle = wxNORMAL;
@@ -211,7 +211,6 @@ wxFont wxCreateFontFromLogFont(LOGFONT *logFont) // , bool createNew)
bool fontUnderline = FALSE; bool fontUnderline = FALSE;
wxChar *fontFace = NULL; wxChar *fontFace = NULL;
// int lfFamily = logFont->lfPitchAndFamily & 0xF0;
int lfFamily = logFont->lfPitchAndFamily; int lfFamily = logFont->lfPitchAndFamily;
if (lfFamily & FIXED_PITCH) if (lfFamily & FIXED_PITCH)
lfFamily -= FIXED_PITCH; lfFamily -= FIXED_PITCH;
@@ -265,6 +264,55 @@ wxFont wxCreateFontFromLogFont(LOGFONT *logFont) // , bool createNew)
if (logFont->lfFaceName) if (logFont->lfFaceName)
fontFace = 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); HDC dc2 = ::GetDC(NULL);
if ( logFont->lfHeight < 0 ) if ( logFont->lfHeight < 0 )
@@ -272,10 +320,9 @@ wxFont wxCreateFontFromLogFont(LOGFONT *logFont) // , bool createNew)
fontPoints = abs(72*logFont->lfHeight/GetDeviceCaps(dc2, LOGPIXELSY)); fontPoints = abs(72*logFont->lfHeight/GetDeviceCaps(dc2, LOGPIXELSY));
::ReleaseDC(NULL, dc2); ::ReleaseDC(NULL, dc2);
// if ( createNew ) return wxFont(fontPoints, fontFamily, fontStyle,
return wxFont(fontPoints, fontFamily, fontStyle, fontWeight, fontUnderline, fontFace); fontWeight, fontUnderline, fontFace,
// else fontEncoding);
// return wxTheFontList->FindOrCreateFont(fontPoints, fontFamily, fontStyle, fontWeight, fontUnderline, fontFace);
} }

View File

@@ -1,13 +1,25 @@
///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Name: fontenum.cpp // Name: msw/fontenum.cpp
// Purpose: wxFontEnumerator class for Windows // Purpose: wxFontEnumerator class for Windows
// Author: Julian Smart // Author: Julian Smart
// Modified by: // Modified by: Vadim Zeitlin to add support for font encodings
// Created: 04/01/98 // Created: 04/01/98
// RCS-ID: $Id$ // RCS-ID: $Id$
// Copyright: (c) Julian Smart // Copyright: (c) Julian Smart
// Licence: wxWindows licence // Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// ============================================================================
// declarations
// ============================================================================
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
#ifdef __GNUG__
#pragma implementation "fontenum.h"
#endif
// For compilers that support precompilation, includes "wx.h". // For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h" #include "wx/wxprec.h"
@@ -20,44 +32,164 @@
#include "wx/font.h" #include "wx/font.h"
#endif #endif
#include <wx/msw/private.h> #include "wx/fontenum.h"
#include "wx/msw/private.h"
// ----------------------------------------------------------------------------
// private classes
// ----------------------------------------------------------------------------
class wxFontEnumeratorHelper
{
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;
// if != -1, enum only fonts which have this encoding
int m_charset;
// if TRUE, enum only fixed fonts
bool m_fixedOnly;
};
// ----------------------------------------------------------------------------
// 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;
}
bool wxFontEnumeratorHelper::SetEncoding(wxFontEncoding encoding)
{
bool exact;
m_charset = wxCharsetFromEncoding(encoding, &exact);
#ifdef __WIN32__
if ( !exact )
{
m_charset = DEFAULT_CHARSET;
}
#endif // Win32
return exact;
}
void wxFontEnumeratorHelper::DoEnumerate()
{
HDC hDC = ::GetDC(NULL);
#ifdef __WIN32__
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
::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)
{
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, int CALLBACK wxFontEnumeratorProc(LPLOGFONT lplf, LPTEXTMETRIC lptm,
DWORD dwStyle, LONG lParam) DWORD dwStyle, LONG lParam)
{ {
// Get rid of any fonts that we don't want... // Get rid of any fonts that we don't want...
if ( dwStyle != TRUETYPE_FONTTYPE ) if ( dwStyle != TRUETYPE_FONTTYPE )
return 1;
wxFontEnumerator *fontEnum = (wxFontEnumerator *)lParam;
wxFont font = wxCreateFontFromLogFont(lplf);
if (fontEnum->OnFont(font))
return 1 ;
else
return 0 ;
}
IMPLEMENT_CLASS(wxFontEnumerator, wxObject)
bool wxFontEnumerator::Enumerate()
{ {
m_faceNames.Clear(); // continue enumeration
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; return TRUE;
} }
bool wxFontEnumerator::OnFont(const wxFont& font) wxFontEnumeratorHelper *fontEnum = (wxFontEnumeratorHelper *)lParam;
{
m_faceNames.Add(font.GetFaceName()); return fontEnum->OnFont(lplf, lptm);
return TRUE;
} }