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

@ -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

View File

@ -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_facenames.IsEmpty(); }
bool GotAny() const { return m_n; }
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() )
{

View File

@ -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;
}

View File

@ -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 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;
int lfFamily = logFont->lfPitchAndFamily;
if (lfFamily & FIXED_PITCH)
lfFamily -= FIXED_PITCH;
if (lfFamily & VARIABLE_PITCH)
lfFamily -= VARIABLE_PITCH;
if (logFont->lfUnderline)
fontUnderline = TRUE;
if (logFont->lfFaceName)
fontFace = logFont->lfFaceName;
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;
HDC dc2 = ::GetDC(NULL);
if (logFont->lfUnderline)
fontUnderline = TRUE;
if ( logFont->lfHeight < 0 )
logFont->lfHeight = - logFont->lfHeight;
fontPoints = abs(72*logFont->lfHeight/GetDeviceCaps(dc2, LOGPIXELSY));
::ReleaseDC(NULL, dc2);
if (logFont->lfFaceName)
fontFace = logFont->lfFaceName;
// if ( createNew )
return wxFont(fontPoints, fontFamily, fontStyle, fontWeight, fontUnderline, fontFace);
// else
// return wxTheFontList->FindOrCreateFont(fontPoints, fontFamily, fontStyle, fontWeight, fontUnderline, fontFace);
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);
}

View File

@ -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 <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)
DWORD dwStyle, LONG lParam);
// ============================================================================
// implementation
// ============================================================================
// ----------------------------------------------------------------------------
// wxFontEnumeratorHelper
// ----------------------------------------------------------------------------
wxFontEnumeratorHelper::wxFontEnumeratorHelper(wxFontEnumerator *fontEnum)
{
// Get rid of any fonts that we don't want...
if (dwStyle != TRUETYPE_FONTTYPE)
return 1;
wxFontEnumerator *fontEnum = (wxFontEnumerator *)lParam;
wxFont font = wxCreateFontFromLogFont(lplf);
if (fontEnum->OnFont(font))
return 1 ;
else
return 0 ;
m_fontEnum = fontEnum;
m_charset = -1;
m_fixedOnly = FALSE;
}
IMPLEMENT_CLASS(wxFontEnumerator, wxObject)
bool wxFontEnumerator::Enumerate()
bool wxFontEnumeratorHelper::SetEncoding(wxFontEncoding encoding)
{
m_faceNames.Clear();
HDC hDC = ::GetDC(NULL);
bool exact;
m_charset = wxCharsetFromEncoding(encoding, &exact);
#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;
}
if ( !exact )
{
m_charset = DEFAULT_CHARSET;
}
#endif // Win32
bool wxFontEnumerator::OnFont(const wxFont& font)
return exact;
}
void wxFontEnumeratorHelper::DoEnumerate()
{
m_faceNames.Add(font.GetFaceName());
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,
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);
}