Merge branch 'msw-font-dpi'
Various wxFont-related fixes and refactorings in preparation for adding per-monitor DPI support. Closes https://github.com/wxWidgets/wxWidgets/pull/1408
This commit is contained in:
@@ -118,7 +118,20 @@ public:
|
|||||||
// set the XFLD
|
// set the XFLD
|
||||||
void SetXFontName(const wxString& xFontName);
|
void SetXFontName(const wxString& xFontName);
|
||||||
#elif defined(__WXMSW__)
|
#elif defined(__WXMSW__)
|
||||||
wxNativeFontInfo(const LOGFONT& lf_) : lf(lf_), pointSize(0.0f) { }
|
wxNativeFontInfo(const LOGFONT& lf_);
|
||||||
|
|
||||||
|
// MSW-specific: get the height value in pixels using LOGFONT convention
|
||||||
|
// (i.e. negative) corresponding to the given size in points and DPI.
|
||||||
|
static int GetLogFontHeightAtPPI(float size, int ppi)
|
||||||
|
{
|
||||||
|
return -wxRound(size * ppi / 72.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// And the same thing for the size of this font.
|
||||||
|
int GetLogFontHeightAtPPI(int ppi) const
|
||||||
|
{
|
||||||
|
return GetLogFontHeightAtPPI(pointSize, ppi);
|
||||||
|
}
|
||||||
|
|
||||||
LOGFONT lf;
|
LOGFONT lf;
|
||||||
|
|
||||||
|
@@ -961,10 +961,14 @@ extern const wxCursor *wxGetGlobalCursor(); // from msw/cursor.cpp
|
|||||||
WXDLLIMPEXP_CORE void wxGetCursorPosMSW(POINT* pt);
|
WXDLLIMPEXP_CORE void wxGetCursorPosMSW(POINT* pt);
|
||||||
|
|
||||||
WXDLLIMPEXP_CORE void wxGetCharSize(WXHWND wnd, int *x, int *y, const wxFont& the_font);
|
WXDLLIMPEXP_CORE void wxGetCharSize(WXHWND wnd, int *x, int *y, const wxFont& the_font);
|
||||||
WXDLLIMPEXP_CORE void wxFillLogFont(LOGFONT *logFont, const wxFont *font);
|
|
||||||
WXDLLIMPEXP_CORE wxFont wxCreateFontFromLogFont(const LOGFONT *logFont);
|
|
||||||
WXDLLIMPEXP_CORE wxFontEncoding wxGetFontEncFromCharSet(int charset);
|
WXDLLIMPEXP_CORE wxFontEncoding wxGetFontEncFromCharSet(int charset);
|
||||||
|
|
||||||
|
inline void wxSetWindowFont(HWND hwnd, const wxFont& font)
|
||||||
|
{
|
||||||
|
::SendMessage(hwnd, WM_SETFONT,
|
||||||
|
(WPARAM)GetHfontOf(font), MAKELPARAM(TRUE, 0));
|
||||||
|
}
|
||||||
|
|
||||||
WXDLLIMPEXP_CORE void wxSliderEvent(WXHWND control, WXWORD wParam, WXWORD pos);
|
WXDLLIMPEXP_CORE void wxSliderEvent(WXHWND control, WXWORD wParam, WXWORD pos);
|
||||||
WXDLLIMPEXP_CORE void wxScrollBarEvent(WXHWND hbar, WXWORD wParam, WXWORD pos);
|
WXDLLIMPEXP_CORE void wxScrollBarEvent(WXHWND hbar, WXWORD wParam, WXWORD pos);
|
||||||
|
|
||||||
|
@@ -113,14 +113,11 @@ public:
|
|||||||
// set font for all windows
|
// set font for all windows
|
||||||
void SetFont(const wxFont& font)
|
void SetFont(const wxFont& font)
|
||||||
{
|
{
|
||||||
HFONT hfont = GetHfontOf(font);
|
|
||||||
wxCHECK_RET( hfont, wxT("invalid font") );
|
|
||||||
|
|
||||||
for ( size_t n = 0; n < m_count; n++ )
|
for ( size_t n = 0; n < m_count; n++ )
|
||||||
{
|
{
|
||||||
if ( m_hwnds[n] )
|
if ( m_hwnds[n] )
|
||||||
{
|
{
|
||||||
::SendMessage(m_hwnds[n], WM_SETFONT, (WPARAM)hfont, 0);
|
wxSetWindowFont(m_hwnds[n], font);
|
||||||
|
|
||||||
// otherwise the window might not be redrawn correctly
|
// otherwise the window might not be redrawn correctly
|
||||||
::InvalidateRect(m_hwnds[n], NULL, FALSE /* don't erase bg */);
|
::InvalidateRect(m_hwnds[n], NULL, FALSE /* don't erase bg */);
|
||||||
|
@@ -152,6 +152,16 @@ public:
|
|||||||
return m_hFont != 0;
|
return m_hFont != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int GetLogFontHeight() const
|
||||||
|
{
|
||||||
|
return m_nativeFontInfo.lf.lfHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetLogFontHeightAtPPI(int ppi) const
|
||||||
|
{
|
||||||
|
return m_nativeFontInfo.GetLogFontHeightAtPPI(ppi);
|
||||||
|
}
|
||||||
|
|
||||||
// ... and setters: notice that all of them invalidate the currently
|
// ... and setters: notice that all of them invalidate the currently
|
||||||
// allocated HFONT, if any, so that the next call to GetHFONT() recreates a
|
// allocated HFONT, if any, so that the next call to GetHFONT() recreates a
|
||||||
// new one
|
// new one
|
||||||
@@ -223,6 +233,13 @@ public:
|
|||||||
m_nativeFontInfo.SetEncoding(encoding);
|
m_nativeFontInfo.SetEncoding(encoding);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetLogFontHeight(int height)
|
||||||
|
{
|
||||||
|
Free();
|
||||||
|
|
||||||
|
m_nativeFontInfo.lf.lfHeight = height;
|
||||||
|
}
|
||||||
|
|
||||||
const wxNativeFontInfo& GetNativeFontInfo() const
|
const wxNativeFontInfo& GetNativeFontInfo() const
|
||||||
{
|
{
|
||||||
// we need to create the font now to get the corresponding LOGFONT if
|
// we need to create the font now to get the corresponding LOGFONT if
|
||||||
@@ -385,6 +402,15 @@ void wxFontRefData::Free()
|
|||||||
// wxNativeFontInfo
|
// wxNativeFontInfo
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
wxNativeFontInfo::wxNativeFontInfo(const LOGFONT& lf_)
|
||||||
|
: lf(lf_)
|
||||||
|
{
|
||||||
|
// Determine the size in points using the primary screen DPI as we don't
|
||||||
|
// have anything else here.
|
||||||
|
const float ppi = ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY);
|
||||||
|
pointSize = 72.0f * abs(lf.lfHeight) / ppi;
|
||||||
|
}
|
||||||
|
|
||||||
void wxNativeFontInfo::Init()
|
void wxNativeFontInfo::Init()
|
||||||
{
|
{
|
||||||
wxZeroMemory(lf);
|
wxZeroMemory(lf);
|
||||||
@@ -402,14 +428,7 @@ void wxNativeFontInfo::Init()
|
|||||||
|
|
||||||
float wxNativeFontInfo::GetFractionalPointSize() const
|
float wxNativeFontInfo::GetFractionalPointSize() const
|
||||||
{
|
{
|
||||||
if ( pointSize != 0.0f )
|
return pointSize;
|
||||||
return pointSize;
|
|
||||||
|
|
||||||
// FIXME: using the screen here results in incorrect font size calculation
|
|
||||||
// for printing!
|
|
||||||
const int ppInch = ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY);
|
|
||||||
|
|
||||||
return (72.0*abs(lf.lfHeight)) / (double) ppInch;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wxSize wxNativeFontInfo::GetPixelSize() const
|
wxSize wxNativeFontInfo::GetPixelSize() const
|
||||||
@@ -490,17 +509,14 @@ wxFontEncoding wxNativeFontInfo::GetEncoding() const
|
|||||||
return wxGetFontEncFromCharSet(lf.lfCharSet);
|
return wxGetFontEncFromCharSet(lf.lfCharSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxNativeFontInfo::SetFractionalPointSize(float pointsize)
|
void wxNativeFontInfo::SetFractionalPointSize(float pointSizeNew)
|
||||||
{
|
{
|
||||||
// Store it to be able to return it from GetFractionalPointSize() later
|
// We don't have the correct DPI to use here, so use that of the
|
||||||
// exactly.
|
// primary screen.
|
||||||
pointSize = pointsize;
|
const int ppi = ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY);
|
||||||
|
lf.lfHeight = GetLogFontHeightAtPPI(pointSizeNew, ppi);
|
||||||
|
|
||||||
// FIXME: using the screen here results in incorrect font size calculation
|
pointSize = pointSizeNew;
|
||||||
// for printing!
|
|
||||||
const int ppInch = ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY);
|
|
||||||
|
|
||||||
lf.lfHeight = -wxRound(pointsize*((double)ppInch)/72.0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxNativeFontInfo::SetPixelSize(const wxSize& pixelSize)
|
void wxNativeFontInfo::SetPixelSize(const wxSize& pixelSize)
|
||||||
@@ -516,6 +532,11 @@ void wxNativeFontInfo::SetPixelSize(const wxSize& pixelSize)
|
|||||||
// versions by passing a negative value explicitly itself.
|
// versions by passing a negative value explicitly itself.
|
||||||
lf.lfHeight = -abs(pixelSize.GetHeight());
|
lf.lfHeight = -abs(pixelSize.GetHeight());
|
||||||
lf.lfWidth = pixelSize.GetWidth();
|
lf.lfWidth = pixelSize.GetWidth();
|
||||||
|
|
||||||
|
// We don't have the right DPI to use here neither, but we need to update
|
||||||
|
// the point size too, so fall back to the default.
|
||||||
|
const float ppi = ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY);
|
||||||
|
pointSize = 72.0f * pixelSize.GetHeight() / ppi;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxNativeFontInfo::SetStyle(wxFontStyle style)
|
void wxNativeFontInfo::SetStyle(wxFontStyle style)
|
||||||
@@ -855,7 +876,6 @@ void wxFont::SetFractionalPointSize(float pointSize)
|
|||||||
{
|
{
|
||||||
AllocExclusive();
|
AllocExclusive();
|
||||||
|
|
||||||
M_FONTDATA->Free();
|
|
||||||
M_FONTDATA->SetFractionalPointSize(pointSize);
|
M_FONTDATA->SetFractionalPointSize(pointSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -36,6 +36,8 @@
|
|||||||
#include "wx/math.h"
|
#include "wx/math.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "wx/fontutil.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@@ -118,7 +120,7 @@ int wxFontDialog::ShowModal()
|
|||||||
if ( m_fontData.m_initialFont.IsOk() )
|
if ( m_fontData.m_initialFont.IsOk() )
|
||||||
{
|
{
|
||||||
flags |= CF_INITTOLOGFONTSTRUCT;
|
flags |= CF_INITTOLOGFONTSTRUCT;
|
||||||
wxFillLogFont(&logFont, &m_fontData.m_initialFont);
|
logFont = m_fontData.m_initialFont.GetNativeFontInfo()->lf;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( m_fontData.m_fontColour.IsOk() )
|
if ( m_fontData.m_fontColour.IsOk() )
|
||||||
@@ -150,7 +152,7 @@ int wxFontDialog::ShowModal()
|
|||||||
if ( ChooseFont(&chooseFontStruct) != 0 )
|
if ( ChooseFont(&chooseFontStruct) != 0 )
|
||||||
{
|
{
|
||||||
wxRGBToColour(m_fontData.m_fontColour, chooseFontStruct.rgbColors);
|
wxRGBToColour(m_fontData.m_fontColour, chooseFontStruct.rgbColors);
|
||||||
m_fontData.m_chosenFont = wxCreateFontFromLogFont(&logFont);
|
m_fontData.m_chosenFont = wxFont(wxNativeFontInfo(logFont));
|
||||||
m_fontData.EncodingInfo().facename = logFont.lfFaceName;
|
m_fontData.EncodingInfo().facename = logFont.lfFaceName;
|
||||||
m_fontData.EncodingInfo().charset = logFont.lfCharSet;
|
m_fontData.EncodingInfo().charset = logFont.lfCharSet;
|
||||||
|
|
||||||
|
@@ -264,35 +264,3 @@ wxFontEncoding wxGetFontEncFromCharSet(int cs)
|
|||||||
|
|
||||||
return fontEncoding;
|
return fontEncoding;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// wxFont <-> LOGFONT conversion
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void wxFillLogFont(LOGFONT *logFont, const wxFont *font)
|
|
||||||
{
|
|
||||||
wxNativeFontInfo fi;
|
|
||||||
|
|
||||||
// maybe we already have LOGFONT for this font?
|
|
||||||
const wxNativeFontInfo *pFI = font->GetNativeFontInfo();
|
|
||||||
if ( !pFI )
|
|
||||||
{
|
|
||||||
// use wxNativeFontInfo methods to build a LOGFONT for this font
|
|
||||||
fi.InitFromFont(*font);
|
|
||||||
|
|
||||||
pFI = &fi;
|
|
||||||
}
|
|
||||||
|
|
||||||
// transfer all the data to LOGFONT
|
|
||||||
*logFont = pFI->lf;
|
|
||||||
}
|
|
||||||
|
|
||||||
wxFont wxCreateFontFromLogFont(const LOGFONT *logFont)
|
|
||||||
{
|
|
||||||
wxNativeFontInfo info;
|
|
||||||
|
|
||||||
info.lf = *logFont;
|
|
||||||
|
|
||||||
return wxFont(info);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@@ -620,8 +620,7 @@ bool wxListCtrl::SetHeaderAttr(const wxItemAttr& attr)
|
|||||||
|
|
||||||
// We need to tell the header about its new font to let it compute
|
// We need to tell the header about its new font to let it compute
|
||||||
// its new height.
|
// its new height.
|
||||||
::SendMessage(hwndHdr, WM_SETFONT,
|
wxSetWindowFont(hwndHdr, font);
|
||||||
(WPARAM)GetHfontOf(font), MAKELPARAM(TRUE, 0));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refreshing the listview makes it notice the change in height of its
|
// Refreshing the listview makes it notice the change in height of its
|
||||||
|
@@ -552,7 +552,8 @@ int wxRendererMSW::GetHeaderButtonHeight(wxWindow * win)
|
|||||||
font = win->GetFont();
|
font = win->GetFont();
|
||||||
if ( !font.IsOk() )
|
if ( !font.IsOk() )
|
||||||
wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
|
wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
|
||||||
::SendMessage(hwndHeader, WM_SETFONT, (WPARAM)GetHfontOf(font), 0);
|
|
||||||
|
wxSetWindowFont(hwndHeader, font);
|
||||||
|
|
||||||
// initialize the struct filled with the values by Header_Layout()
|
// initialize the struct filled with the values by Header_Layout()
|
||||||
RECT parentRect = { 0, 0, 100, 100 };
|
RECT parentRect = { 0, 0, 100, 100 };
|
||||||
|
@@ -345,7 +345,7 @@ extern wxFont wxGetCCDefaultFont()
|
|||||||
0
|
0
|
||||||
) )
|
) )
|
||||||
{
|
{
|
||||||
return wxFont(wxCreateFontFromLogFont(&lf));
|
return wxFont(lf);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@@ -564,8 +564,7 @@ bool wxSpinCtrl::SetFont(const wxFont& font)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
WXHANDLE hFont = GetFont().GetResourceHandle();
|
wxSetWindowFont(GetBuddyHwnd(), GetFont());
|
||||||
(void)::SendMessage(GetBuddyHwnd(), WM_SETFONT, (WPARAM)hFont, TRUE);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@@ -40,6 +40,7 @@
|
|||||||
#include "wx/wxcrtvararg.h"
|
#include "wx/wxcrtvararg.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "wx/fontutil.h"
|
||||||
#include "wx/scopedptr.h"
|
#include "wx/scopedptr.h"
|
||||||
#include "wx/stack.h"
|
#include "wx/stack.h"
|
||||||
#include "wx/sysopt.h"
|
#include "wx/sysopt.h"
|
||||||
@@ -2829,14 +2830,13 @@ bool wxTextCtrl::MSWSetCharFormat(const wxTextAttr& style, long start, long end)
|
|||||||
CFM_ITALIC | CFM_BOLD | CFM_UNDERLINE | CFM_STRIKEOUT;
|
CFM_ITALIC | CFM_BOLD | CFM_UNDERLINE | CFM_STRIKEOUT;
|
||||||
|
|
||||||
// fill in data from LOGFONT but recalculate lfHeight because we need
|
// fill in data from LOGFONT but recalculate lfHeight because we need
|
||||||
// the real height in twips and not the negative number which
|
// the real height in twips and not the negative number used inside
|
||||||
// wxFillLogFont() returns (this is correct in general and works with
|
// LOGFONT returns (this is correct in general and works with
|
||||||
// the Windows font mapper, but not here)
|
// the Windows font mapper, but not here)
|
||||||
|
|
||||||
wxFont font(style.GetFont());
|
wxFont font(style.GetFont());
|
||||||
|
|
||||||
LOGFONT lf;
|
LOGFONT lf = font.GetNativeFontInfo()->lf;
|
||||||
wxFillLogFont(&lf, &font);
|
|
||||||
cf.yHeight = 20*font.GetPointSize(); // 1 pt = 20 twips
|
cf.yHeight = 20*font.GetPointSize(); // 1 pt = 20 twips
|
||||||
cf.bCharSet = lf.lfCharSet;
|
cf.bCharSet = lf.lfCharSet;
|
||||||
cf.bPitchAndFamily = lf.lfPitchAndFamily;
|
cf.bPitchAndFamily = lf.lfPitchAndFamily;
|
||||||
@@ -3126,8 +3126,9 @@ bool wxTextCtrl::GetStyle(long position, wxTextAttr& style)
|
|||||||
LOGFONT lf;
|
LOGFONT lf;
|
||||||
// Convert the height from the units of 1/20th of the point in which
|
// Convert the height from the units of 1/20th of the point in which
|
||||||
// CHARFORMAT stores it to pixel-based units used by LOGFONT.
|
// CHARFORMAT stores it to pixel-based units used by LOGFONT.
|
||||||
const wxCoord ppi = wxClientDC(this).GetPPI().y;
|
// Note that RichEdit seems to always use standard DPI of 96, even when the
|
||||||
lf.lfHeight = -MulDiv(cf.yHeight/20, ppi, 72);
|
// window is a monitor using a higher DPI.
|
||||||
|
lf.lfHeight = wxNativeFontInfo::GetLogFontHeightAtPPI(cf.yHeight/20.0f, 96);
|
||||||
lf.lfWidth = 0;
|
lf.lfWidth = 0;
|
||||||
lf.lfCharSet = ANSI_CHARSET; // FIXME: how to get correct charset?
|
lf.lfCharSet = ANSI_CHARSET; // FIXME: how to get correct charset?
|
||||||
lf.lfClipPrecision = 0;
|
lf.lfClipPrecision = 0;
|
||||||
@@ -3160,7 +3161,7 @@ bool wxTextCtrl::GetStyle(long position, wxTextAttr& style)
|
|||||||
else
|
else
|
||||||
lf.lfWeight = FW_NORMAL;
|
lf.lfWeight = FW_NORMAL;
|
||||||
|
|
||||||
wxFont font = wxCreateFontFromLogFont(& lf);
|
wxFont font(lf);
|
||||||
if (font.IsOk())
|
if (font.IsOk())
|
||||||
{
|
{
|
||||||
style.SetFont(font);
|
style.SetFont(font);
|
||||||
|
@@ -827,11 +827,7 @@ bool wxWindowMSW::SetFont(const wxFont& font)
|
|||||||
// just been reset and in this case we need to change the font used by
|
// just been reset and in this case we need to change the font used by
|
||||||
// the native window to the default for this class, i.e. exactly what
|
// the native window to the default for this class, i.e. exactly what
|
||||||
// GetFont() returns
|
// GetFont() returns
|
||||||
WXHANDLE hFont = GetFont().GetResourceHandle();
|
wxSetWindowFont(hWnd, GetFont());
|
||||||
|
|
||||||
wxASSERT_MSG( hFont, wxT("should have valid font") );
|
|
||||||
|
|
||||||
::SendMessage(hWnd, WM_SETFONT, (WPARAM)hFont, MAKELPARAM(TRUE, 0));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -7425,7 +7421,12 @@ static TEXTMETRIC wxGetTextMetrics(const wxWindowMSW *win)
|
|||||||
|
|
||||||
#if !wxDIALOG_UNIT_COMPATIBILITY
|
#if !wxDIALOG_UNIT_COMPATIBILITY
|
||||||
// and select the current font into it
|
// and select the current font into it
|
||||||
HFONT hfont = GetHfontOf(win->GetFont());
|
|
||||||
|
// Note that it's important to extend the lifetime of the possibly
|
||||||
|
// temporary wxFont returned by GetFont() to ensure that its HFONT remains
|
||||||
|
// valid.
|
||||||
|
const wxFont& f(win->GetFont());
|
||||||
|
HFONT hfont = GetHfontOf(f);
|
||||||
if ( hfont )
|
if ( hfont )
|
||||||
{
|
{
|
||||||
hfont = (HFONT)::SelectObject(hdc, hfont);
|
hfont = (HFONT)::SelectObject(hdc, hfont);
|
||||||
|
Reference in New Issue
Block a user