diff --git a/include/wx/dc.h b/include/wx/dc.h index 847b7f64e5..cc0a48238e 100644 --- a/include/wx/dc.h +++ b/include/wx/dc.h @@ -269,6 +269,8 @@ public: wxWindow* GetWindow() const { return m_window; } + void SetWindow(wxWindow* w) { m_window = w; } + virtual bool IsOk() const { return m_ok; } // query capabilities @@ -1364,6 +1366,9 @@ protected: wxDCImpl * const m_pimpl; + void SetWindow(wxWindow* w) + { return m_pimpl->SetWindow(w); } + private: wxDECLARE_ABSTRACT_CLASS(wxDC); wxDECLARE_NO_COPY_CLASS(wxDC); diff --git a/include/wx/dcbuffer.h b/include/wx/dcbuffer.h index 4a29fda820..8fc23d66cd 100644 --- a/include/wx/dcbuffer.h +++ b/include/wx/dcbuffer.h @@ -153,6 +153,8 @@ public: wxBufferedPaintDC(wxWindow *window, wxBitmap& buffer, int style = wxBUFFER_CLIENT_AREA) : m_paintdc(window) { + SetWindow(window); + // If we're buffering the virtual window, scale the paint DC as well if (style & wxBUFFER_VIRTUAL_AREA) window->PrepareDC( m_paintdc ); @@ -167,6 +169,8 @@ public: wxBufferedPaintDC(wxWindow *window, int style = wxBUFFER_CLIENT_AREA) : m_paintdc(window) { + SetWindow(window); + // If we're using the virtual window, scale the paint DC as well if (style & wxBUFFER_VIRTUAL_AREA) window->PrepareDC( m_paintdc ); diff --git a/include/wx/graphics.h b/include/wx/graphics.h index 059d11c62d..415b8c9e83 100644 --- a/include/wx/graphics.h +++ b/include/wx/graphics.h @@ -727,7 +727,7 @@ public: } // returns the resolution of the graphics context in device points per inch - virtual void GetDPI( wxDouble* dpiX, wxDouble* dpiY); + virtual void GetDPI( wxDouble* dpiX, wxDouble* dpiY) const; #if 0 // sets the current alpha on this context @@ -1038,6 +1038,9 @@ public: const wxString& facename, int flags = wxFONTFLAG_DEFAULT, const wxColour& col = *wxBLACK) = 0; + virtual wxGraphicsFont CreateFontAtDPI(const wxFont& font, + const wxRealPoint& dpi, + const wxColour& col = *wxBLACK) = 0; // create a native bitmap representation virtual wxGraphicsBitmap CreateBitmap( const wxBitmap &bitmap ) = 0; diff --git a/include/wx/propgrid/propgrid.h b/include/wx/propgrid/propgrid.h index 5b2c5a52d0..0e9daa0ad7 100644 --- a/include/wx/propgrid/propgrid.h +++ b/include/wx/propgrid/propgrid.h @@ -1766,6 +1766,8 @@ protected: void OnSysColourChanged( wxSysColourChangedEvent &event ); + void OnDPIChanged(wxDPIChangedEvent& event); + void OnTLPClose( wxCloseEvent& event ); protected: diff --git a/include/wx/stc/stc.h b/include/wx/stc/stc.h index 0ab59936ef..0bc3ea10d3 100644 --- a/include/wx/stc/stc.h +++ b/include/wx/stc/stc.h @@ -5479,6 +5479,7 @@ protected: void OnKeyDown(wxKeyEvent& evt); void OnLoseFocus(wxFocusEvent& evt); void OnGainFocus(wxFocusEvent& evt); + void OnDPIChanged(wxDPIChangedEvent& evt); void OnSysColourChanged(wxSysColourChangedEvent& evt); void OnEraseBackground(wxEraseEvent& evt); void OnMenu(wxCommandEvent& evt); diff --git a/interface/wx/graphics.h b/interface/wx/graphics.h index 7e09c7d6ee..16b294209a 100644 --- a/interface/wx/graphics.h +++ b/interface/wx/graphics.h @@ -1116,7 +1116,7 @@ public: /** Returns the resolution of the graphics context in device points per inch. */ - virtual void GetDPI( wxDouble* dpiX, wxDouble* dpiY); + virtual void GetDPI( wxDouble* dpiX, wxDouble* dpiY) const; /** Returns the associated window if any. @@ -1459,6 +1459,17 @@ public: int flags = wxFONTFLAG_DEFAULT, const wxColour& col = *wxBLACK) = 0; + /** + Creates a native graphics font from a wxFont and a text colour. + + The specified DPI is used to convert the (fractional) wxFont point-size + to a fractional pixel-size. + + @since 3.1.3 + */ + virtual wxGraphicsFont CreateFontAtDPI(const wxFont& font, + const wxRealPoint& dpi, + const wxColour& col = *wxBLACK) = 0; /** Creates a native brush with a linear gradient. diff --git a/src/common/graphcmn.cpp b/src/common/graphcmn.cpp index 540dc4042e..bc44f0b270 100644 --- a/src/common/graphcmn.cpp +++ b/src/common/graphcmn.cpp @@ -619,7 +619,7 @@ wxDouble wxGraphicsContext::GetAlpha() const } #endif -void wxGraphicsContext::GetDPI( wxDouble* dpiX, wxDouble* dpiY) +void wxGraphicsContext::GetDPI( wxDouble* dpiX, wxDouble* dpiY) const { if ( m_window ) { @@ -944,16 +944,18 @@ wxGraphicsContext::CreateRadialGradientBrush( wxGraphicsFont wxGraphicsContext::CreateFont( const wxFont &font , const wxColour &col ) const { - return GetRenderer()->CreateFont(font,col); + wxRealPoint dpi; + GetDPI(&dpi.x, &dpi.y); + return GetRenderer()->CreateFontAtDPI(font, dpi, col); } wxGraphicsFont -wxGraphicsContext::CreateFont(double size, +wxGraphicsContext::CreateFont(double sizeInPixels, const wxString& facename, int flags, const wxColour& col) const { - return GetRenderer()->CreateFont(size, facename, flags, col); + return GetRenderer()->CreateFont(sizeInPixels, facename, flags, col); } wxGraphicsBitmap wxGraphicsContext::CreateBitmap( const wxBitmap& bmp ) const diff --git a/src/generic/graphicc.cpp b/src/generic/graphicc.cpp index c6586c98e8..60c09fa4da 100644 --- a/src/generic/graphicc.cpp +++ b/src/generic/graphicc.cpp @@ -3009,6 +3009,9 @@ public : const wxString& facename, int flags = wxFONTFLAG_DEFAULT, const wxColour& col = *wxBLACK) wxOVERRIDE; + virtual wxGraphicsFont CreateFontAtDPI(const wxFont& font, + const wxRealPoint& dpi, + const wxColour& col) wxOVERRIDE; // create a native bitmap representation virtual wxGraphicsBitmap CreateBitmap( const wxBitmap &bitmap ) wxOVERRIDE; @@ -3238,6 +3241,14 @@ wxCairoRenderer::CreateFont(double sizeInPixels, return font; } +wxGraphicsFont +wxCairoRenderer::CreateFontAtDPI(const wxFont& font, + const wxRealPoint& WXUNUSED(dpi), + const wxColour& col) +{ + return CreateFont(font, col); +} + wxGraphicsBitmap wxCairoRenderer::CreateBitmap( const wxBitmap& bmp ) { wxGraphicsBitmap p; diff --git a/src/msw/anybutton.cpp b/src/msw/anybutton.cpp index db61042824..df5e2eee1a 100644 --- a/src/msw/anybutton.cpp +++ b/src/msw/anybutton.cpp @@ -431,8 +431,15 @@ wxSize wxMSWButton::IncreaseToStdSizeAndCache(wxControl *btn, const wxSize& size // // Note that we intentionally don't use GetDefaultSize() here, because // it's inexact -- dialog units depend on this dialog's font. - const wxSize sizeDef = btn->ConvertDialogToPixels(btn->FromDIP(wxSize(50, 14))); - + wxSize sizeDef = btn->ConvertDialogToPixels(wxSize(50, 14)); + if ( btn->GetContentScaleFactor() > 1.0 ) + { + // At higher DPI, the returned height is too big compared to + // standard Windows buttons (like Save, Open, OK). FromDIP(25) + // matches the size of the buttons in standard Windows dialogs, see + // https://trac.wxwidgets.org/ticket/18528 for the discussion. + sizeDef.y = btn->FromDIP(25); + } sizeBtn.IncTo(sizeDef); } else // wxBU_EXACTFIT case diff --git a/src/msw/dc.cpp b/src/msw/dc.cpp index 0b9cc660b4..cd31f1ba18 100644 --- a/src/msw/dc.cpp +++ b/src/msw/dc.cpp @@ -1503,7 +1503,18 @@ void wxMSWDCImpl::DoDrawRotatedText(const wxString& text, // NB: don't take DEFAULT_GUI_FONT (a.k.a. wxSYS_DEFAULT_GUI_FONT) // because it's not TrueType and so can't have non zero // orientation/escapement - wxFont font = m_font.IsOk() ? m_font : *wxSWISS_FONT; + wxFont font; + if ( m_font.IsOk() ) + { + font = m_font; + } + else // Use default font appropriate for rotated text. + { + font = *wxSWISS_FONT; + if ( m_window ) + font.WXAdjustToPPI(m_window->GetDPI()); + } + LOGFONT lf; if ( ::GetObject(GetHfontOf(font), sizeof(lf), &lf) == 0 ) { @@ -1630,7 +1641,11 @@ void wxMSWDCImpl::SetFont(const wxFont& font) if ( font.IsOk() ) { - HGDIOBJ hfont = ::SelectObject(GetHdc(), GetHfontOf(font)); + wxFont f(font); + if ( m_window ) + f.WXAdjustToPPI(m_window->GetDPI()); + + HGDIOBJ hfont = ::SelectObject(GetHdc(), GetHfontOf(f)); if ( hfont == HGDI_ERROR ) { wxLogLastError(wxT("SelectObject(font)")); @@ -1640,7 +1655,7 @@ void wxMSWDCImpl::SetFont(const wxFont& font) if ( !m_oldFont ) m_oldFont = (WXHFONT)hfont; - m_font = font; + m_font = f; } } else // invalid font, reset the current font @@ -2502,10 +2517,24 @@ void wxMSWDCImpl::DoGetSizeMM(int *w, int *h) const wxSize wxMSWDCImpl::GetPPI() const { - int x = ::GetDeviceCaps(GetHdc(), LOGPIXELSX); - int y = ::GetDeviceCaps(GetHdc(), LOGPIXELSY); + // As documented by MSDN, GetDeviceCaps() returns the same value for all + // HDCs on the system, and so can't be used to retrieve the correct value + // for the HDCs associated with the windows on monitors other than the + // primary one if they use different DPI. Hence prefer to get this + // information from the associated window, if possible. + wxSize ppi; + if ( m_window ) + { + ppi = m_window->GetDPI(); + } - return wxSize(x, y); + if ( !ppi.x || !ppi.y ) + { + ppi.x = ::GetDeviceCaps(GetHdc(), LOGPIXELSX); + ppi.y = ::GetDeviceCaps(GetHdc(), LOGPIXELSY); + } + + return ppi; } double wxMSWDCImpl::GetContentScaleFactor() const diff --git a/src/msw/gauge.cpp b/src/msw/gauge.cpp index af7cefdee5..ac03441790 100644 --- a/src/msw/gauge.cpp +++ b/src/msw/gauge.cpp @@ -122,9 +122,9 @@ wxSize wxGauge::DoGetBestSize() const // the smaller one. if (HasFlag(wxGA_VERTICAL)) - return ConvertDialogToPixels(FromDIP(wxSize(8, 107))); + return ConvertDialogToPixels(wxSize(8, 107)); else - return ConvertDialogToPixels(FromDIP(wxSize(107, 8))); + return ConvertDialogToPixels(wxSize(107, 8)); } // ---------------------------------------------------------------------------- diff --git a/src/msw/graphics.cpp b/src/msw/graphics.cpp index eaced69010..4af45bb4b0 100644 --- a/src/msw/graphics.cpp +++ b/src/msw/graphics.cpp @@ -342,17 +342,18 @@ class wxGDIPlusFontData : public wxGraphicsObjectRefData public: wxGDIPlusFontData( wxGraphicsRenderer* renderer, const wxFont &font, + const wxRealPoint& dpi, const wxColour& col ); wxGDIPlusFontData(wxGraphicsRenderer* renderer, const wxString& name, - REAL size, + REAL sizeInPixels, int style, const wxColour& col); // This ctor takes ownership of the brush. wxGDIPlusFontData(wxGraphicsRenderer* renderer, const wxString& name, - REAL size, + REAL sizeInPixels, int style, Brush* textBrush); @@ -365,17 +366,17 @@ private : // Common part of all ctors, flags here is a combination of values of // FontStyle GDI+ enum. void Init(const wxString& name, - REAL size, + REAL sizeInPixels, int style, Brush* textBrush); // Common part of ctors taking wxColour. void Init(const wxString& name, - REAL size, + REAL sizeInPixels, int style, const wxColour& col) { - Init(name, size, style, new SolidBrush(wxColourToColor(col))); + Init(name, sizeInPixels, style, new SolidBrush(wxColourToColor(col))); } Brush* m_textBrush; @@ -457,6 +458,7 @@ public: virtual void GetPartialTextExtents(const wxString& text, wxArrayDouble& widths) const wxOVERRIDE; virtual bool ShouldOffset() const wxOVERRIDE; virtual void GetSize( wxDouble* width, wxDouble *height ); + virtual void GetDPI(wxDouble* dpiX, wxDouble* dpiY) const wxOVERRIDE; Graphics* GetGraphics() const { return m_context; } @@ -534,40 +536,7 @@ class wxGDIPlusPrintingContext : public wxGDIPlusContext public: wxGDIPlusPrintingContext( wxGraphicsRenderer* renderer, const wxDC& dc ); - // Override to scale the font proportionally to the DPI. - virtual void SetFont(const wxGraphicsFont& font) wxOVERRIDE - { - // The casts here are safe because we're only supposed to be passed - // fonts created by this renderer. - Font* const f = static_cast(font.GetRefData())->GetGDIPlusFont(); - Brush* const b = static_cast(font.GetRefData())->GetGDIPlusBrush(); - - // To scale the font, we need to create a new one which means - // retrieving all the parameters originally used to create the font. - FontFamily ffamily; - f->GetFamily(&ffamily); - - WCHAR familyName[LF_FACESIZE]; - ffamily.GetFamilyName(familyName); - - wxGraphicsFont fontScaled; - fontScaled.SetRefData(new wxGDIPlusFontData - ( - GetRenderer(), - familyName, - f->GetSize() / m_fontScaleRatio, - f->GetStyle(), - b->Clone() - )); - wxGDIPlusContext::SetFont(fontScaled); - } - -private: - // This is logically const ratio between this context DPI and the standard - // one which is used for scaling the fonts used with this context: without - // this, the fonts wouldn't have the correct size, even though we - // explicitly create them using UnitPoint units. - wxDouble m_fontScaleRatio; + void GetDPI(wxDouble* dpiX, wxDouble* dpiY) const wxOVERRIDE; }; //----------------------------------------------------------------------------- @@ -656,11 +625,15 @@ public : virtual wxGraphicsFont CreateFont( const wxFont& font, const wxColour& col) wxOVERRIDE; - virtual wxGraphicsFont CreateFont(double size, + virtual wxGraphicsFont CreateFont(double sizeInPixels, const wxString& facename, int flags = wxFONTFLAG_DEFAULT, const wxColour& col = *wxBLACK) wxOVERRIDE; + virtual wxGraphicsFont CreateFontAtDPI(const wxFont& font, + const wxRealPoint& dpi, + const wxColour& col) wxOVERRIDE; + // create a graphics bitmap from a native bitmap virtual wxGraphicsBitmap CreateBitmapFromNativeBitmap( void* bitmap ) wxOVERRIDE; @@ -1105,7 +1078,7 @@ extern const wxArrayString& wxGetPrivateFontFileNames(); void wxGDIPlusFontData::Init(const wxString& name, - REAL size, + REAL sizeInPixels, int style, Brush* textBrush) { @@ -1127,7 +1100,7 @@ wxGDIPlusFontData::Init(const wxString& name, int rc = gs_pFontFamily[j].GetFamilyName(familyName); if ( rc == 0 && name == familyName ) { - m_font = new Font(&gs_pFontFamily[j], size, style, UnitPoint); + m_font = new Font(&gs_pFontFamily[j], sizeInPixels, style, UnitPixel); break; } } @@ -1136,7 +1109,7 @@ wxGDIPlusFontData::Init(const wxString& name, if ( !m_font ) #endif // wxUSE_PRIVATE_FONTS { - m_font = new Font(name.wc_str(), size, style, UnitPoint); + m_font = new Font(name.wc_str(), sizeInPixels, style, UnitPixel); } m_textBrush = textBrush; @@ -1144,6 +1117,7 @@ wxGDIPlusFontData::Init(const wxString& name, wxGDIPlusFontData::wxGDIPlusFontData( wxGraphicsRenderer* renderer, const wxFont &font, + const wxRealPoint& dpi, const wxColour& col ) : wxGraphicsObjectRefData( renderer ) { @@ -1157,27 +1131,31 @@ wxGDIPlusFontData::wxGDIPlusFontData( wxGraphicsRenderer* renderer, if ( font.GetWeight() == wxFONTWEIGHT_BOLD ) style |= FontStyleBold; - Init(font.GetFaceName(), font.GetFractionalPointSize(), style, col); + REAL fontSize = (REAL)(!dpi.y + ? font.GetPixelSize().GetHeight() + : (font.GetFractionalPointSize() * dpi.y / 72.0f)); + + Init(font.GetFaceName(), fontSize, style, col); } wxGDIPlusFontData::wxGDIPlusFontData(wxGraphicsRenderer* renderer, const wxString& name, - REAL size, + REAL sizeInPixels, int style, const wxColour& col) : wxGraphicsObjectRefData(renderer) { - Init(name, size, style, col); + Init(name, sizeInPixels, style, col); } wxGDIPlusFontData::wxGDIPlusFontData(wxGraphicsRenderer* renderer, const wxString& name, - REAL size, + REAL sizeInPixels, int style, Brush* brush) : wxGraphicsObjectRefData(renderer) { - Init(name, size, style, brush); + Init(name, sizeInPixels, style, brush); } wxGDIPlusFontData::~wxGDIPlusFontData() @@ -2387,6 +2365,26 @@ void wxGDIPlusContext::GetSize( wxDouble* width, wxDouble *height ) *height = m_height; } +void wxGDIPlusContext::GetDPI(wxDouble* dpiX, wxDouble* dpiY) const +{ + if ( GetWindow() ) + { + const wxSize dpi = GetWindow()->GetDPI(); + + if ( dpiX ) + *dpiX = dpi.x; + if ( dpiY ) + *dpiY = dpi.y; + } + else + { + if ( dpiX ) + *dpiX = GetGraphics()->GetDpiX(); + if ( dpiY ) + *dpiY = GetGraphics()->GetDpiY(); + } +} + //----------------------------------------------------------------------------- // wxGDIPlusPrintingContext implementation //----------------------------------------------------------------------------- @@ -2407,10 +2405,16 @@ wxGDIPlusPrintingContext::wxGDIPlusPrintingContext( wxGraphicsRenderer* renderer // wxEnhMetaFileDC). REAL dpiRatio = 100.0 / context->GetDpiY(); context->SetPageScale(dpiRatio); +} - // We use this modifier when measuring fonts. It is needed because the - // page scale is modified above. - m_fontScaleRatio = context->GetDpiY() / 96.0; +void wxGDIPlusPrintingContext::GetDPI(wxDouble* dpiX, wxDouble* dpiY) const +{ + // override to use same scaling as wxWindowsPrintPreview::DetermineScaling + ScreenHDC hdc; + if ( dpiX ) + *dpiX = ::GetDeviceCaps(hdc, LOGPIXELSX); + if ( dpiY ) + *dpiY = ::GetDeviceCaps(hdc, LOGPIXELSY); } //----------------------------------------------------------------------------- @@ -2720,19 +2724,11 @@ wxGraphicsFont wxGDIPlusRenderer::CreateFont( const wxFont &font, const wxColour &col ) { - ENSURE_LOADED_OR_RETURN(wxNullGraphicsFont); - if ( font.IsOk() ) - { - wxGraphicsFont p; - p.SetRefData(new wxGDIPlusFontData( this, font, col )); - return p; - } - else - return wxNullGraphicsFont; + return CreateFontAtDPI(font, wxRealPoint(), col); } wxGraphicsFont -wxGDIPlusRenderer::CreateFont(double size, +wxGDIPlusRenderer::CreateFont(double sizeInPixels, const wxString& facename, int flags, const wxColour& col) @@ -2752,10 +2748,26 @@ wxGDIPlusRenderer::CreateFont(double size, wxGraphicsFont f; - f.SetRefData(new wxGDIPlusFontData(this, facename, size, style, col)); + f.SetRefData(new wxGDIPlusFontData(this, facename, sizeInPixels, style, col)); return f; } +wxGraphicsFont +wxGDIPlusRenderer::CreateFontAtDPI(const wxFont& font, + const wxRealPoint& dpi, + const wxColour& col) +{ + ENSURE_LOADED_OR_RETURN(wxNullGraphicsFont); + if ( font.IsOk() ) + { + wxGraphicsFont p; + p.SetRefData(new wxGDIPlusFontData( this, font, dpi, col )); + return p; + } + else + return wxNullGraphicsFont; +} + wxGraphicsBitmap wxGDIPlusRenderer::CreateBitmap( const wxBitmap &bitmap ) { ENSURE_LOADED_OR_RETURN(wxNullGraphicsBitmap); diff --git a/src/msw/graphicsd2d.cpp b/src/msw/graphicsd2d.cpp index 19fa4b1411..b84bfa0d1d 100644 --- a/src/msw/graphicsd2d.cpp +++ b/src/msw/graphicsd2d.cpp @@ -2792,7 +2792,7 @@ wxD2DPenData* wxGetD2DPenData(const wxGraphicsPen& pen) class wxD2DFontData : public wxGraphicsObjectRefData { public: - wxD2DFontData(wxGraphicsRenderer* renderer, const wxFont& font, const wxColor& color); + wxD2DFontData(wxGraphicsRenderer* renderer, const wxFont& font, const wxRealPoint& dpi, const wxColor& color); wxCOMPtr CreateTextLayout(const wxString& text) const; @@ -2817,7 +2817,7 @@ private: bool m_strikethrough; }; -wxD2DFontData::wxD2DFontData(wxGraphicsRenderer* renderer, const wxFont& font, const wxColor& color) : +wxD2DFontData::wxD2DFontData(wxGraphicsRenderer* renderer, const wxFont& font, const wxRealPoint& dpi, const wxColor& color) : wxGraphicsObjectRefData(renderer), m_brushData(renderer, wxBrush(color)), m_underlined(font.GetUnderlined()), m_strikethrough(font.GetStrikethrough()) { @@ -2870,15 +2870,17 @@ wxD2DFontData::wxD2DFontData(wxGraphicsRenderer* renderer, const wxFont& font, c hr = familyNames->GetString(0, name, length+1); wxCHECK_HRESULT_RET(hr); + FLOAT fontSize = (FLOAT)(!dpi.y + ? font.GetPixelSize().GetHeight() + : (font.GetFractionalPointSize() * dpi.y / 72.0f)); + hr = wxDWriteFactory()->CreateTextFormat( name, NULL, m_font->GetWeight(), m_font->GetStyle(), m_font->GetStretch(), - // We need to use DIP units for the font size, with 1dip = 1/96in, - // while wxFont uses points with 1pt = 1/72in. - font.GetFractionalPointSize()*96/72, + fontSize, L"en-us", &m_textFormat); @@ -3646,7 +3648,7 @@ public: void Flush() wxOVERRIDE; - void GetDPI(wxDouble* dpiX, wxDouble* dpiY) wxOVERRIDE; + void GetDPI(wxDouble* dpiX, wxDouble* dpiY) const wxOVERRIDE; wxD2DContextSupplier::ContextType GetContext() wxOVERRIDE { @@ -4572,12 +4574,27 @@ void wxD2DContext::Flush() GetRenderTarget()->SetTransform(&currTransform); } -void wxD2DContext::GetDPI(wxDouble* dpiX, wxDouble* dpiY) +void wxD2DContext::GetDPI(wxDouble* dpiX, wxDouble* dpiY) const { - FLOAT x, y; - GetRenderTarget()->GetDpi(&x, &y); - if (dpiX != NULL) *dpiX = x; - if (dpiY != NULL) *dpiY = y; + if ( GetWindow() ) + { + const wxSize dpi = GetWindow()->GetDPI(); + + if ( dpiX ) + *dpiX = dpi.x; + if ( dpiY ) + *dpiY = dpi.y; + } + else + { + FLOAT x, y; + GetRenderTarget()->GetDpi(&x, &y); + + if ( dpiX ) + *dpiX = x; + if ( dpiY ) + *dpiY = y; + } } //----------------------------------------------------------------------------- @@ -4651,10 +4668,14 @@ public : wxGraphicsFont CreateFont(const wxFont& font, const wxColour& col) wxOVERRIDE; wxGraphicsFont CreateFont( - double size, const wxString& facename, + double sizeInPixels, const wxString& facename, int flags = wxFONTFLAG_DEFAULT, const wxColour& col = *wxBLACK) wxOVERRIDE; + virtual wxGraphicsFont CreateFontAtDPI(const wxFont& font, + const wxRealPoint& dpi, + const wxColour& col) wxOVERRIDE; + // create a graphics bitmap from a native bitmap wxGraphicsBitmap CreateBitmapFromNativeBitmap(void* bitmap) wxOVERRIDE; @@ -4888,7 +4909,30 @@ wxImage wxD2DRenderer::CreateImageFromBitmap(const wxGraphicsBitmap& bmp) wxGraphicsFont wxD2DRenderer::CreateFont(const wxFont& font, const wxColour& col) { - wxD2DFontData* fontData = new wxD2DFontData(this, font, col); + return CreateFontAtDPI(font, wxRealPoint(), col); +} + +wxGraphicsFont wxD2DRenderer::CreateFont( + double sizeInPixels, const wxString& facename, + int flags, + const wxColour& col) +{ + // Use the same DPI as wxFont will use in SetPixelSize, so these cancel + // each other out and we are left with the actual pixel size. + ScreenHDC hdc; + wxRealPoint dpi(::GetDeviceCaps(hdc, LOGPIXELSX), + ::GetDeviceCaps(hdc, LOGPIXELSY)); + + return CreateFontAtDPI( + wxFontInfo(wxSize(sizeInPixels, sizeInPixels)).AllFlags(flags).FaceName(facename), + dpi, col); +} + +wxGraphicsFont wxD2DRenderer::CreateFontAtDPI(const wxFont& font, + const wxRealPoint& dpi, + const wxColour& col) +{ + wxD2DFontData* fontData = new wxD2DFontData(this, font, dpi, col); if ( !fontData->GetFont() ) { // Apparently a non-TrueType font is given and hence @@ -4903,16 +4947,6 @@ wxGraphicsFont wxD2DRenderer::CreateFont(const wxFont& font, const wxColour& col return graphicsFont; } -wxGraphicsFont wxD2DRenderer::CreateFont( - double size, const wxString& facename, - int flags, - const wxColour& col) -{ - return CreateFont( - wxFontInfo(size).AllFlags(flags).FaceName(facename), - col); -} - // create a sub-image from a native image representation wxGraphicsBitmap wxD2DRenderer::CreateSubBitmap(const wxGraphicsBitmap& bitmap, wxDouble x, wxDouble y, wxDouble w, wxDouble h) { diff --git a/src/msw/menuitem.cpp b/src/msw/menuitem.cpp index 3163cd5575..e18f457317 100644 --- a/src/msw/menuitem.cpp +++ b/src/msw/menuitem.cpp @@ -29,7 +29,6 @@ #include "wx/stockitem.h" #ifndef WX_PRECOMP - #include "wx/app.h" #include "wx/dcmemory.h" #include "wx/font.h" #include "wx/bitmap.h" @@ -235,28 +234,41 @@ public: bool Theme; // is data initialized for FullTheme? - static const MenuDrawData* Get() + int dpi; // DPI used for calculating sizes + + static const MenuDrawData* Get(wxMenu* menu) { + const wxWindow* window = menu->GetWindow(); // notice that s_menuData can't be created as a global variable because // it needs a window to initialize and no windows exist at the time of // globals initialization yet if ( !ms_instance ) { - static MenuDrawData s_menuData; + static MenuDrawData s_menuData(window); ms_instance = &s_menuData; } #if wxUSE_UXTHEME bool theme = MenuLayout() == FullTheme; if ( ms_instance->Theme != theme ) - ms_instance->Init(); + { + ms_instance->Init(window); + } + else #endif // wxUSE_UXTHEME + { + if ( ms_instance->dpi != window->GetDPI().y ) + { + ms_instance->Init(window); + menu->ResetMaxAccelWidth(); + } + } return ms_instance; } - MenuDrawData() + MenuDrawData(const wxWindow* window) { - Init(); + Init(window); } @@ -296,17 +308,16 @@ public: } private: - void Init(); + void Init(wxWindow const* window); static MenuDrawData* ms_instance; }; MenuDrawData* MenuDrawData::ms_instance = NULL; -void MenuDrawData::Init() +void MenuDrawData::Init(wxWindow const* window) { #if wxUSE_UXTHEME - const wxWindow* window = wxTheApp ? wxTheApp->GetTopWindow() : NULL; if ( IsUxThemeActive() ) { wxUxThemeHandle hTheme(window, L"MENU"); @@ -348,7 +359,8 @@ void MenuDrawData::Init() wxUxThemeFont themeFont; ::GetThemeSysFont(hTheme, TMT_MENUFONT, themeFont.GetPtr()); - Font = wxFont(wxNativeFontInfo(themeFont.GetLOGFONT(), window)); + // Use NULL window for wxNativeFontInfo, height it is already at the correct ppi + Font = wxFont(wxNativeFontInfo(themeFont.GetLOGFONT(), NULL)); Theme = true; @@ -407,6 +419,7 @@ void MenuDrawData::Init() AlwaysShowCues = value == 1; + dpi = window->GetDPI().y; } } // anonymous namespace @@ -783,7 +796,7 @@ wxString wxMenuItem::GetName() const bool wxMenuItem::OnMeasureItem(size_t *width, size_t *height) { - const MenuDrawData* data = MenuDrawData::Get(); + const MenuDrawData* data = MenuDrawData::Get(GetMenu()); if ( IsOwnerDrawn() ) { @@ -875,7 +888,7 @@ bool wxMenuItem::OnMeasureItem(size_t *width, size_t *height) bool wxMenuItem::OnDrawItem(wxDC& dc, const wxRect& rc, wxODAction WXUNUSED(act), wxODStatus stat) { - const MenuDrawData* data = MenuDrawData::Get(); + const MenuDrawData* data = MenuDrawData::Get(GetMenu()); wxMSWDCImpl *impl = (wxMSWDCImpl*) dc.GetImpl(); HDC hdc = GetHdcOf(*impl); @@ -1167,7 +1180,7 @@ void wxMenuItem::DrawStdCheckMark(WXHDC hdc_, const RECT* rc, wxODStatus stat) { wxUxThemeHandle hTheme(GetMenu()->GetWindow(), L"MENU"); - const MenuDrawData* data = MenuDrawData::Get(); + const MenuDrawData* data = MenuDrawData::Get(GetMenu()); // rect for background must be without check margins RECT rcBg = *rc; @@ -1234,7 +1247,8 @@ void wxMenuItem::GetFontToUse(wxFont& font) const { font = GetFont(); if ( !font.IsOk() ) - font = MenuDrawData::Get()->Font; + font = MenuDrawData::Get(GetMenu())->Font; + font.WXAdjustToPPI(GetMenu()->GetWindow()->GetDPI()); } void wxMenuItem::GetColourToUse(wxODStatus stat, wxColour& colText, wxColour& colBack) const diff --git a/src/osx/carbon/graphics.cpp b/src/osx/carbon/graphics.cpp index 2ded6cf21f..1b3012d5d9 100644 --- a/src/osx/carbon/graphics.cpp +++ b/src/osx/carbon/graphics.cpp @@ -2778,6 +2778,9 @@ public : const wxString& facename, int flags = wxFONTFLAG_DEFAULT, const wxColour& col = *wxBLACK) wxOVERRIDE; + virtual wxGraphicsFont CreateFontAtDPI(const wxFont& font, + const wxRealPoint& dpi, + const wxColour& col) wxOVERRIDE; // create a native bitmap representation virtual wxGraphicsBitmap CreateBitmap( const wxBitmap &bitmap ) wxOVERRIDE ; @@ -3073,6 +3076,14 @@ wxMacCoreGraphicsRenderer::CreateFont(double sizeInPixels, return f; } +wxGraphicsFont +wxMacCoreGraphicsRenderer::CreateFontAtDPI(const wxFont& font, + const wxRealPoint& WXUNUSED(dpi), + const wxColour& col) +{ + return CreateFont(font, col); +} + // // CoreGraphics Helper Methods // diff --git a/src/propgrid/propgrid.cpp b/src/propgrid/propgrid.cpp index 7102b85170..b2944a98d5 100644 --- a/src/propgrid/propgrid.cpp +++ b/src/propgrid/propgrid.cpp @@ -260,6 +260,7 @@ wxBEGIN_EVENT_TABLE(wxPropertyGrid, wxControl) EVT_SET_FOCUS(wxPropertyGrid::OnFocusEvent) EVT_KILL_FOCUS(wxPropertyGrid::OnFocusEvent) EVT_SYS_COLOUR_CHANGED(wxPropertyGrid::OnSysColourChanged) + EVT_DPI_CHANGED(wxPropertyGrid::OnDPIChanged) EVT_MOTION(wxPropertyGrid::OnMouseMove) EVT_LEFT_DOWN(wxPropertyGrid::OnMouseClick) EVT_LEFT_UP(wxPropertyGrid::OnMouseUp) @@ -453,9 +454,9 @@ void wxPropertyGrid::Init2() m_cursorSizeWE = new wxCursor( wxCURSOR_SIZEWE ); // adjust bitmap icon y position so they are centered - m_vspacing = wxPG_DEFAULT_VSPACING; + m_vspacing = FromDIP(wxPG_DEFAULT_VSPACING); - CalculateFontAndBitmapStuff( wxPG_DEFAULT_VSPACING ); + CalculateFontAndBitmapStuff( m_vspacing ); // Allocate cell data m_propertyDefaultCell.SetEmptyData(); @@ -1167,7 +1168,7 @@ void wxPropertyGrid::SetExtraStyle( long exStyle ) // returns the best acceptable minimal size wxSize wxPropertyGrid::DoGetBestSize() const { - int lineHeight = wxMax(15, m_lineHeight); + int lineHeight = wxMax(FromDIP(15), m_lineHeight); // don't make the grid too tall (limit height to 10 items) but don't // make it too small neither @@ -1301,7 +1302,7 @@ void wxPropertyGrid::CalculateFontAndBitmapStuff( int vspacing ) m_fontHeight = y; #if wxPG_USE_RENDERER_NATIVE - m_iconWidth = wxPG_ICON_WIDTH; + m_iconWidth = FromDIP(wxPG_ICON_WIDTH); #elif wxPG_ICON_WIDTH // scale icon m_iconWidth = (m_fontHeight * wxPG_ICON_WIDTH) / 13; @@ -1356,6 +1357,13 @@ void wxPropertyGrid::OnSysColourChanged( wxSysColourChangedEvent &WXUNUSED(event } } +void wxPropertyGrid::OnDPIChanged(wxDPIChangedEvent &WXUNUSED(event)) +{ + m_vspacing = FromDIP(wxPG_DEFAULT_VSPACING); + CalculateFontAndBitmapStuff(m_vspacing); + Refresh(); +} + // ----------------------------------------------------------------------- static wxColour wxPGAdjustColour(const wxColour& src, int ra, diff --git a/src/qt/graphics.cpp b/src/qt/graphics.cpp index c427099b08..9e0614807d 100644 --- a/src/qt/graphics.cpp +++ b/src/qt/graphics.cpp @@ -1154,6 +1154,9 @@ public: const wxString& facename, int flags = wxFONTFLAG_DEFAULT, const wxColour& col = *wxBLACK) wxOVERRIDE; + virtual wxGraphicsFont CreateFontAtDPI(const wxFont& font, + const wxRealPoint& dpi, + const wxColour& col) wxOVERRIDE; // create a native bitmap representation virtual wxGraphicsBitmap CreateBitmap(const wxBitmap& bitmap) wxOVERRIDE; @@ -1321,6 +1324,14 @@ wxGraphicsFont wxQtGraphicsRenderer::CreateFont( return font; } +wxGraphicsFont +wxQtGraphicsRenderer::CreateFontAtDPI(const wxFont& font, + const wxRealPoint& WXUNUSED(dpi), + const wxColour& col) +{ + return CreateFont(font, col); +} + wxGraphicsBitmap wxQtGraphicsRenderer::CreateBitmap(const wxBitmap& bmp) { wxGraphicsBitmap p; diff --git a/src/stc/stc.cpp b/src/stc/stc.cpp index a397d65673..df2bd96efb 100644 --- a/src/stc/stc.cpp +++ b/src/stc/stc.cpp @@ -159,6 +159,7 @@ wxBEGIN_EVENT_TABLE(wxStyledTextCtrl, wxControl) EVT_KEY_DOWN (wxStyledTextCtrl::OnKeyDown) EVT_KILL_FOCUS (wxStyledTextCtrl::OnLoseFocus) EVT_SET_FOCUS (wxStyledTextCtrl::OnGainFocus) + EVT_DPI_CHANGED (wxStyledTextCtrl::OnDPIChanged) EVT_SYS_COLOUR_CHANGED (wxStyledTextCtrl::OnSysColourChanged) EVT_ERASE_BACKGROUND (wxStyledTextCtrl::OnEraseBackground) EVT_MENU_RANGE (10, 16, wxStyledTextCtrl::OnMenu) @@ -239,6 +240,18 @@ bool wxStyledTextCtrl::Create(wxWindow *parent, SetFontQuality(wxSTC_EFF_QUALITY_DEFAULT); #endif +#ifdef __WXMSW__ + // Set initial zoom for active DPI + const HDC hdc = ::GetDC(parent->GetHWND()); + const int baseDPI = ::GetDeviceCaps(hdc, LOGPIXELSY); + const int activeDPI = parent->GetDPI().y; + ::ReleaseDC(parent->GetHWND(), hdc); + + const int ptSizeOld = StyleGetSize(wxSTC_STYLE_DEFAULT); + const int ptSizeNew = (int)wxMulDivInt32(ptSizeOld, activeDPI, baseDPI); + SetZoom(GetZoom() + (ptSizeNew - ptSizeOld)); +#endif + return true; } @@ -5432,6 +5445,19 @@ void wxStyledTextCtrl::OnGainFocus(wxFocusEvent& evt) { } +void wxStyledTextCtrl::OnDPIChanged(wxDPIChangedEvent& evt) +{ + int ptSizeOld = StyleGetSize(wxSTC_STYLE_DEFAULT); + int ptSizeNew = (int)wxMulDivInt32(ptSizeOld, evt.GetNewDPI().y, evt.GetOldDPI().y); + SetZoom(GetZoom() + (ptSizeNew - ptSizeOld)); + + for ( int i = 0; i < SC_MAX_MARGIN; ++i ) + { + SetMarginWidth(i, (int)wxMulDivInt32(GetMarginWidth(i), evt.GetNewDPI().y, evt.GetOldDPI().y)); + } +} + + void wxStyledTextCtrl::OnSysColourChanged(wxSysColourChangedEvent& WXUNUSED(evt)) { m_swx->DoSysColourChange(); } @@ -5467,7 +5493,7 @@ wxSize wxStyledTextCtrl::DoGetBestSize() const { // What would be the best size for a wxSTC? // Just give a reasonable minimum until something else can be figured out. - return wxSize(200,100); + return FromDIP(wxSize(200,100)); } diff --git a/src/stc/stc.cpp.in b/src/stc/stc.cpp.in index 7a211c5545..d2a256e20c 100644 --- a/src/stc/stc.cpp.in +++ b/src/stc/stc.cpp.in @@ -159,6 +159,7 @@ wxBEGIN_EVENT_TABLE(wxStyledTextCtrl, wxControl) EVT_KEY_DOWN (wxStyledTextCtrl::OnKeyDown) EVT_KILL_FOCUS (wxStyledTextCtrl::OnLoseFocus) EVT_SET_FOCUS (wxStyledTextCtrl::OnGainFocus) + EVT_DPI_CHANGED (wxStyledTextCtrl::OnDPIChanged) EVT_SYS_COLOUR_CHANGED (wxStyledTextCtrl::OnSysColourChanged) EVT_ERASE_BACKGROUND (wxStyledTextCtrl::OnEraseBackground) EVT_MENU_RANGE (10, 16, wxStyledTextCtrl::OnMenu) @@ -239,6 +240,18 @@ bool wxStyledTextCtrl::Create(wxWindow *parent, SetFontQuality(wxSTC_EFF_QUALITY_DEFAULT); #endif +#ifdef __WXMSW__ + // Set initial zoom for active DPI + const HDC hdc = ::GetDC(parent->GetHWND()); + const int baseDPI = ::GetDeviceCaps(hdc, LOGPIXELSY); + const int activeDPI = parent->GetDPI().y; + ::ReleaseDC(parent->GetHWND(), hdc); + + const int ptSizeOld = StyleGetSize(wxSTC_STYLE_DEFAULT); + const int ptSizeNew = (int)wxMulDivInt32(ptSizeOld, activeDPI, baseDPI); + SetZoom(GetZoom() + (ptSizeNew - ptSizeOld)); +#endif + return true; } @@ -959,6 +972,19 @@ void wxStyledTextCtrl::OnGainFocus(wxFocusEvent& evt) { } +void wxStyledTextCtrl::OnDPIChanged(wxDPIChangedEvent& evt) +{ + int ptSizeOld = StyleGetSize(wxSTC_STYLE_DEFAULT); + int ptSizeNew = (int)wxMulDivInt32(ptSizeOld, evt.GetNewDPI().y, evt.GetOldDPI().y); + SetZoom(GetZoom() + (ptSizeNew - ptSizeOld)); + + for ( int i = 0; i < SC_MAX_MARGIN; ++i ) + { + SetMarginWidth(i, (int)wxMulDivInt32(GetMarginWidth(i), evt.GetNewDPI().y, evt.GetOldDPI().y)); + } +} + + void wxStyledTextCtrl::OnSysColourChanged(wxSysColourChangedEvent& WXUNUSED(evt)) { m_swx->DoSysColourChange(); } @@ -994,7 +1020,7 @@ wxSize wxStyledTextCtrl::DoGetBestSize() const { // What would be the best size for a wxSTC? // Just give a reasonable minimum until something else can be figured out. - return wxSize(200,100); + return FromDIP(wxSize(200,100)); } diff --git a/src/stc/stc.h.in b/src/stc/stc.h.in index 0713ec6212..925f4b9b1d 100644 --- a/src/stc/stc.h.in +++ b/src/stc/stc.h.in @@ -597,6 +597,7 @@ protected: void OnKeyDown(wxKeyEvent& evt); void OnLoseFocus(wxFocusEvent& evt); void OnGainFocus(wxFocusEvent& evt); + void OnDPIChanged(wxDPIChangedEvent& evt); void OnSysColourChanged(wxSysColourChangedEvent& evt); void OnEraseBackground(wxEraseEvent& evt); void OnMenu(wxCommandEvent& evt);