Merge branch 'fontdlg-dpi'
Fix font sizes in MSW font dialog in high DPI. See #22322.
This commit is contained in:
commit
3439087685
@ -35,22 +35,21 @@ class AutoSystemDpiAware
|
||||
|
||||
public:
|
||||
AutoSystemDpiAware()
|
||||
: m_prevContext(WXDPI_AWARENESS_CONTEXT_UNAWARE),
|
||||
m_pfnSetThreadDpiAwarenessContext((SetThreadDpiAwarenessContext_t)-1)
|
||||
: m_prevContext(WXDPI_AWARENESS_CONTEXT_UNAWARE)
|
||||
{
|
||||
if ( m_pfnSetThreadDpiAwarenessContext == (SetThreadDpiAwarenessContext_t)-1)
|
||||
if ( ms_pfnSetThreadDpiAwarenessContext == (SetThreadDpiAwarenessContext_t)-1)
|
||||
{
|
||||
wxLoadedDLL dllUser32("user32.dll");
|
||||
wxDL_INIT_FUNC(m_pfn, SetThreadDpiAwarenessContext, dllUser32);
|
||||
wxDL_INIT_FUNC(ms_pfn, SetThreadDpiAwarenessContext, dllUser32);
|
||||
}
|
||||
|
||||
if ( m_pfnSetThreadDpiAwarenessContext )
|
||||
if ( ms_pfnSetThreadDpiAwarenessContext )
|
||||
{
|
||||
m_prevContext = m_pfnSetThreadDpiAwarenessContext(
|
||||
m_prevContext = ms_pfnSetThreadDpiAwarenessContext(
|
||||
WXDPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED);
|
||||
if ( !m_prevContext )
|
||||
{
|
||||
m_prevContext = m_pfnSetThreadDpiAwarenessContext(
|
||||
m_prevContext = ms_pfnSetThreadDpiAwarenessContext(
|
||||
WXDPI_AWARENESS_CONTEXT_SYSTEM_AWARE);
|
||||
}
|
||||
}
|
||||
@ -59,16 +58,17 @@ public:
|
||||
|
||||
~AutoSystemDpiAware()
|
||||
{
|
||||
if ( m_pfnSetThreadDpiAwarenessContext )
|
||||
if ( ms_pfnSetThreadDpiAwarenessContext )
|
||||
{
|
||||
m_pfnSetThreadDpiAwarenessContext(m_prevContext);
|
||||
ms_pfnSetThreadDpiAwarenessContext(m_prevContext);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
WXDPI_AWARENESS_CONTEXT m_prevContext;
|
||||
|
||||
SetThreadDpiAwarenessContext_t m_pfnSetThreadDpiAwarenessContext;
|
||||
// This static member is defined in src/msw/window.cpp.
|
||||
static SetThreadDpiAwarenessContext_t ms_pfnSetThreadDpiAwarenessContext;
|
||||
};
|
||||
|
||||
#else // !wxUSE_DYNLIB_CLASS
|
||||
|
@ -432,7 +432,7 @@ bool MyApp::OnInit()
|
||||
#endif // wxUSE_COLOURDLG
|
||||
|
||||
#if wxUSE_FONTDLG
|
||||
choices_menu->Append(DIALOGS_CHOOSE_FONT, "Choose &font");
|
||||
choices_menu->Append(DIALOGS_CHOOSE_FONT, "Choose &font\tShift-Ctrl-N");
|
||||
#endif // wxUSE_FONTDLG
|
||||
|
||||
#if wxUSE_CHOICEDLG
|
||||
|
@ -34,6 +34,7 @@
|
||||
#endif
|
||||
|
||||
#include "wx/fontutil.h"
|
||||
#include "wx/display.h"
|
||||
#include "wx/msw/private/dpiaware.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
@ -88,6 +89,14 @@ wxString wxFontDialog::GetTitle() const
|
||||
return m_title;
|
||||
}
|
||||
|
||||
// Tiny wrapper calling ::ChooseFont() with system DPI awareness, as the
|
||||
// standard dialog doesn't work correctly when using per-monitor awareness.
|
||||
static BOOL wxMSWChooseFont(CHOOSEFONT* pCF)
|
||||
{
|
||||
wxMSWImpl::AutoSystemDpiAware dpiAwareness;
|
||||
return ::ChooseFont(pCF);
|
||||
}
|
||||
|
||||
int wxFontDialog::ShowModal()
|
||||
{
|
||||
WX_HOOK_MODAL_DIALOG();
|
||||
@ -121,6 +130,17 @@ int wxFontDialog::ShowModal()
|
||||
{
|
||||
flags |= CF_INITTOLOGFONTSTRUCT;
|
||||
logFont = m_fontData.m_initialFont.GetNativeFontInfo()->lf;
|
||||
|
||||
// The standard dialog seems to always use the default DPI for
|
||||
// converting LOGFONT height to the value in points shown in the
|
||||
// dialog (and this happens even when not using AutoSystemDpiAware),
|
||||
// so we need to convert it to standard (not even system, because the
|
||||
// dialog doesn't take it into account neither) DPI.
|
||||
logFont.lfHeight = wxNativeFontInfo::GetLogFontHeightAtPPI
|
||||
(
|
||||
m_fontData.m_initialFont.GetFractionalPointSize(),
|
||||
wxDisplay::GetStdPPIValue()
|
||||
);
|
||||
}
|
||||
|
||||
if ( m_fontData.m_fontColour.IsOk() )
|
||||
@ -153,12 +173,51 @@ int wxFontDialog::ShowModal()
|
||||
|
||||
chooseFontStruct.Flags = flags;
|
||||
|
||||
wxMSWImpl::AutoSystemDpiAware dpiAwareness;
|
||||
|
||||
if ( ChooseFont(&chooseFontStruct) != 0 )
|
||||
if ( wxMSWChooseFont(&chooseFontStruct) != 0 )
|
||||
{
|
||||
wxRGBToColour(m_fontData.m_fontColour, chooseFontStruct.rgbColors);
|
||||
m_fontData.m_chosenFont = wxFont(wxNativeFontInfo(logFont, this));
|
||||
|
||||
// Don't trust the LOGFONT height returned by the native dialog because
|
||||
// it doesn't use the correct DPI.
|
||||
//
|
||||
// Note that we must use our parent and not this window itself, as it
|
||||
// doesn't have any valid HWND and so its DPI can't be determined.
|
||||
if ( parent )
|
||||
{
|
||||
// We can't just adjust lfHeight directly to the correct DPI here
|
||||
// as doing this would introduce rounding problems, e.g. 8pt font
|
||||
// corresponds to lfHeight == 11px and scaling this up for 150% DPI
|
||||
// would result in 17px height which would then map to 8.5pt at
|
||||
// 150% DPI and end up being rounded to 9pt, which would be wrong.
|
||||
//
|
||||
// So find the point size itself first:
|
||||
const int pointSize = wxRound(wxNativeFontInfo::GetPointSizeAtPPI
|
||||
(
|
||||
logFont.lfHeight,
|
||||
wxDisplay::GetStdPPIValue()
|
||||
));
|
||||
|
||||
// And then compute the pixel height that results in this point
|
||||
// size at the actual DPI being used.
|
||||
logFont.lfHeight = wxNativeFontInfo::GetLogFontHeightAtPPI
|
||||
(
|
||||
pointSize,
|
||||
parent->GetDPI().y
|
||||
);
|
||||
}
|
||||
|
||||
wxFont f(wxNativeFontInfo(logFont, parent));
|
||||
|
||||
// The native dialog allows selecting only integer font sizes in
|
||||
// points, but converting them to pixel height loses precision and so
|
||||
// converting them back to points may result in a fractional value
|
||||
// different from the value selected in the dialog. So ensure that we
|
||||
// use exactly the same font size in points as what was selected in the
|
||||
// dialog by rounding the possibly fractional value to the integer ones
|
||||
// entered there.
|
||||
f.SetPointSize(wxRound(f.GetFractionalPointSize()));
|
||||
|
||||
m_fontData.m_chosenFont = f;
|
||||
m_fontData.EncodingInfo().facename = logFont.lfFaceName;
|
||||
m_fontData.EncodingInfo().charset = logFont.lfCharSet;
|
||||
|
||||
|
@ -76,6 +76,7 @@
|
||||
#endif
|
||||
|
||||
#include "wx/msw/private.h"
|
||||
#include "wx/msw/private/dpiaware.h"
|
||||
#include "wx/msw/private/keyboard.h"
|
||||
#include "wx/msw/private/paint.h"
|
||||
#include "wx/msw/private/winstyle.h"
|
||||
@ -4758,6 +4759,19 @@ wxWindowMSW::MSWOnMeasureItem(int id, WXMEASUREITEMSTRUCT *itemStruct)
|
||||
// DPI
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#if wxUSE_DYNLIB_CLASS
|
||||
|
||||
namespace wxMSWImpl
|
||||
{
|
||||
|
||||
AutoSystemDpiAware::SetThreadDpiAwarenessContext_t
|
||||
AutoSystemDpiAware::ms_pfnSetThreadDpiAwarenessContext =
|
||||
(AutoSystemDpiAware::SetThreadDpiAwarenessContext_t)-1;
|
||||
|
||||
} // namespace wxMSWImpl
|
||||
|
||||
#endif // wxUSE_DYNLIB_CLASS
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user