diff --git a/include/wx/dfb/bitmap.h b/include/wx/dfb/bitmap.h index 5be025381d..4d718fabbc 100644 --- a/include/wx/dfb/bitmap.h +++ b/include/wx/dfb/bitmap.h @@ -31,7 +31,7 @@ public: wxBitmap(const wxString &filename, wxBitmapType type = wxBITMAP_DEFAULT_TYPE); wxBitmap(const char* const* bits); #if wxUSE_IMAGE - wxBitmap(const wxImage& image, int depth = -1); + wxBitmap(const wxImage& image, int depth = -1, double WXUNUSED(scale) = 1.0); #endif bool Create(const wxIDirectFBSurfacePtr& surface); diff --git a/include/wx/gtk/bitmap.h b/include/wx/gtk/bitmap.h index f472b87448..ed5b731bda 100644 --- a/include/wx/gtk/bitmap.h +++ b/include/wx/gtk/bitmap.h @@ -79,7 +79,7 @@ public: #endif wxBitmap( const wxString &filename, wxBitmapType type = wxBITMAP_DEFAULT_TYPE ); #if wxUSE_IMAGE - wxBitmap(const wxImage& image, int depth = wxBITMAP_SCREEN_DEPTH); + wxBitmap(const wxImage& image, int depth = wxBITMAP_SCREEN_DEPTH, double scale = 1.0); #endif // wxUSE_IMAGE wxBitmap(GdkPixbuf* pixbuf, int depth = 0); wxEXPLICIT wxBitmap(const wxCursor& cursor); diff --git a/include/wx/gtk1/bitmap.h b/include/wx/gtk1/bitmap.h index f4154fe317..2aad167c93 100644 --- a/include/wx/gtk1/bitmap.h +++ b/include/wx/gtk1/bitmap.h @@ -76,7 +76,7 @@ public: } #endif wxBitmap( const wxString &filename, wxBitmapType type = wxBITMAP_DEFAULT_TYPE ); - wxBitmap( const wxImage& image, int depth = -1 ) { (void)CreateFromImage(image, depth); } + wxBitmap( const wxImage& image, int depth = -1, double WXUNUSED(scale) = 1.0 ) { (void)CreateFromImage(image, depth); } virtual ~wxBitmap(); bool Create(int width, int height, int depth = wxBITMAP_SCREEN_DEPTH); diff --git a/include/wx/msw/bitmap.h b/include/wx/msw/bitmap.h index 33e78e87fc..4ebc108894 100644 --- a/include/wx/msw/bitmap.h +++ b/include/wx/msw/bitmap.h @@ -81,7 +81,7 @@ public: #if wxUSE_IMAGE // Convert from wxImage - wxBitmap(const wxImage& image, int depth = -1) + wxBitmap(const wxImage& image, int depth = -1, double WXUNUSED(scale) = 1.0) { (void)CreateFromImage(image, depth); } // Create a DDB compatible with the given DC from wxImage diff --git a/include/wx/qt/bitmap.h b/include/wx/qt/bitmap.h index 13d5b80745..b804551bf6 100644 --- a/include/wx/qt/bitmap.h +++ b/include/wx/qt/bitmap.h @@ -28,7 +28,7 @@ public: wxBitmap(const wxSize& sz, int depth = wxBITMAP_SCREEN_DEPTH); wxBitmap(const char* const* bits); wxBitmap(const wxString &filename, wxBitmapType type = wxBITMAP_TYPE_XPM); - wxBitmap(const wxImage& image, int depth = wxBITMAP_SCREEN_DEPTH); + wxBitmap(const wxImage& image, int depth = wxBITMAP_SCREEN_DEPTH, double scale = 1.0); // Convert from wxIcon / wxCursor wxBitmap(const wxIcon& icon) { CopyFromIcon(icon); } diff --git a/include/wx/richtext/richtextbuffer.h b/include/wx/richtext/richtextbuffer.h index bf53ffa7b4..3320f27ba1 100644 --- a/include/wx/richtext/richtextbuffer.h +++ b/include/wx/richtext/richtextbuffer.h @@ -2499,6 +2499,12 @@ public: bool GetDelayedImageLoading() const { return m_enableDelayedImageLoading; } + /** + Returns the buffer pointer. + */ + + wxRichTextBuffer* GetBuffer() const { return m_buffer; } + wxRichTextBuffer* m_buffer; bool m_enableVirtualAttributes; bool m_enableImages; @@ -5064,7 +5070,7 @@ public: /** Do the loading and scaling */ - virtual bool LoadAndScaleImageCache(wxImage& image, const wxSize& sz, bool delayLoading, bool& changed); + virtual bool LoadAndScaleImageCache(wxImage& image, const wxSize& sz, wxRichTextDrawingContext& context, bool& changed); /** Gets the original image size. diff --git a/include/wx/x11/bitmap.h b/include/wx/x11/bitmap.h index 4652074402..c5cc209a3a 100644 --- a/include/wx/x11/bitmap.h +++ b/include/wx/x11/bitmap.h @@ -100,7 +100,7 @@ public: int GetDepth() const; #if wxUSE_IMAGE - wxBitmap( const wxImage& image, int depth = -1 ) { (void)CreateFromImage(image, depth); } + wxBitmap( const wxImage& image, int depth = -1, double WXUNUSED(scale) = 1.0 ) { (void)CreateFromImage(image, depth); } wxImage ConvertToImage() const; bool CreateFromImage(const wxImage& image, int depth = -1); #endif // wxUSE_IMAGE diff --git a/src/dfb/bitmap.cpp b/src/dfb/bitmap.cpp index 7a5d75beb3..913587aa4f 100644 --- a/src/dfb/bitmap.cpp +++ b/src/dfb/bitmap.cpp @@ -420,7 +420,7 @@ bool wxBitmap::CreateWithFormat(int width, int height, int dfbFormat) } #if wxUSE_IMAGE -wxBitmap::wxBitmap(const wxImage& imageOrig, int depth) +wxBitmap::wxBitmap(const wxImage& imageOrig, int depth, double WXUNUSED(scale)) { wxCHECK_RET( imageOrig.IsOk(), wxT("invalid image") ); diff --git a/src/gtk/bitmap.cpp b/src/gtk/bitmap.cpp index 0a739f30a6..38a3416167 100644 --- a/src/gtk/bitmap.cpp +++ b/src/gtk/bitmap.cpp @@ -590,7 +590,7 @@ static void CopyImageData( #if wxUSE_IMAGE #ifdef __WXGTK3__ -wxBitmap::wxBitmap(const wxImage& image, int depth) +wxBitmap::wxBitmap(const wxImage& image, int depth, double WXUNUSED(scale)) { wxCHECK_RET(image.IsOk(), "invalid image"); @@ -636,7 +636,7 @@ wxBitmap::wxBitmap(const wxImage& image, int depth) } } #else -wxBitmap::wxBitmap(const wxImage& image, int depth) +wxBitmap::wxBitmap(const wxImage& image, int depth, double WXUNUSED(scale)) { wxCHECK_RET(image.IsOk(), "invalid image"); diff --git a/src/propgrid/propgrid.cpp b/src/propgrid/propgrid.cpp index 8ed706f8e3..eb39b8b999 100644 --- a/src/propgrid/propgrid.cpp +++ b/src/propgrid/propgrid.cpp @@ -4660,13 +4660,15 @@ void wxPropertyGrid::OnResize( wxSizeEvent& event ) if ( !HasExtraStyle(wxPG_EX_NATIVE_DOUBLE_BUFFERING) ) { + double scaleFactor = GetContentScaleFactor(); int dblh = (m_lineHeight*2); if ( !m_doubleBuffer ) { // Create double buffer bitmap to draw on, if none int w = wxMax(width, 250); int h = wxMax(height + dblh, 400); - m_doubleBuffer = new wxBitmap( w, h ); + m_doubleBuffer = new wxBitmap; + m_doubleBuffer->CreateScaled( w, h, wxBITMAP_SCREEN_DEPTH, scaleFactor ); } else { @@ -4679,7 +4681,8 @@ void wxPropertyGrid::OnResize( wxSizeEvent& event ) if ( w < width ) w = width; if ( h < (height+dblh) ) h = height + dblh; delete m_doubleBuffer; - m_doubleBuffer = new wxBitmap( w, h ); + m_doubleBuffer = new wxBitmap; + m_doubleBuffer->CreateScaled( w, h, wxBITMAP_SCREEN_DEPTH, scaleFactor ); } } } diff --git a/src/qt/bitmap.cpp b/src/qt/bitmap.cpp index e17876527a..60417f44bf 100644 --- a/src/qt/bitmap.cpp +++ b/src/qt/bitmap.cpp @@ -220,7 +220,7 @@ wxBitmap::wxBitmap(const wxString &filename, wxBitmapType type ) LoadFile(filename, type); } -wxBitmap::wxBitmap(const wxImage& image, int depth ) +wxBitmap::wxBitmap(const wxImage& image, int depth, double WXUNUSED(scale) ) { Qt::ImageConversionFlags flags = 0; if (depth == 1) diff --git a/src/richtext/richtextbuffer.cpp b/src/richtext/richtextbuffer.cpp index ff189902f9..5eca53a888 100644 --- a/src/richtext/richtextbuffer.cpp +++ b/src/richtext/richtextbuffer.cpp @@ -12483,7 +12483,7 @@ bool wxRichTextImage::LoadImageCache(wxDC& dc, wxRichTextDrawingContext& context // Don't repeat unless absolutely necessary if (m_imageCache.IsOk() && !resetCache && !context.GetLayingOut()) { - retImageSize = wxSize(m_imageCache.GetWidth(), m_imageCache.GetHeight()); + retImageSize = wxSize(m_imageCache.GetScaledWidth(), m_imageCache.GetScaledHeight()); return true; } @@ -12636,16 +12636,16 @@ bool wxRichTextImage::LoadImageCache(wxDC& dc, wxRichTextDrawingContext& context retImageSize = wxSize(width, height); bool changed = false; - return LoadAndScaleImageCache(image, retImageSize, context.GetDelayedImageLoading(), changed); + return LoadAndScaleImageCache(image, retImageSize, context, changed); } // Do the loading and scaling -bool wxRichTextImage::LoadAndScaleImageCache(wxImage& image, const wxSize& sz, bool delayLoading, bool& changed) +bool wxRichTextImage::LoadAndScaleImageCache(wxImage& image, const wxSize& sz, wxRichTextDrawingContext& context, bool& changed) { int width = sz.x; int height = sz.y; - if (m_imageCache.IsOk() && m_imageCache.GetWidth() == width && m_imageCache.GetHeight() == height) + if (m_imageCache.IsOk() && m_imageCache.GetScaledWidth() == width && m_imageCache.GetScaledHeight() == height) { // Do nothing, we didn't need to change the image cache changed = false; @@ -12654,7 +12654,7 @@ bool wxRichTextImage::LoadAndScaleImageCache(wxImage& image, const wxSize& sz, b { changed = true; - if (delayLoading) + if (context.GetDelayedImageLoading()) { if (m_imageCache.IsOk()) m_imageCache = wxNullBitmap; @@ -12680,6 +12680,10 @@ bool wxRichTextImage::LoadAndScaleImageCache(wxImage& image, const wxSize& sz, b m_imageCache = wxBitmap(image); else { + double scaleFactor = 1.0; + if (context.GetBuffer() && context.GetBuffer()->GetRichTextCtrl()) + scaleFactor = context.GetBuffer()->GetRichTextCtrl()->GetContentScaleFactor(); + // If the original width and height is small, e.g. 400 or below, // scale up and then down to improve image quality. This can make // a big difference, with not much performance hit. @@ -12688,11 +12692,14 @@ bool wxRichTextImage::LoadAndScaleImageCache(wxImage& image, const wxSize& sz, b if (image.GetWidth() <= upscaleThreshold || image.GetHeight() <= upscaleThreshold) { img = image.Scale(image.GetWidth()*2, image.GetHeight()*2); - img.Rescale(width, height, wxIMAGE_QUALITY_HIGH); + img.Rescale(width*scaleFactor, height*scaleFactor, wxIMAGE_QUALITY_HIGH); } else - img = image.Scale(width, height, wxIMAGE_QUALITY_HIGH); - m_imageCache = wxBitmap(img); + img = image.Scale(width*scaleFactor, height*scaleFactor, wxIMAGE_QUALITY_HIGH); + + // On Mac, this will create a bitmap that is twice as big as the required dimensions, + // with a scale factor that indicates that the extra detail should be used on HiDPI displays. + m_imageCache = wxBitmap(img, wxBITMAP_SCREEN_DEPTH, scaleFactor); } } diff --git a/src/richtext/richtextctrl.cpp b/src/richtext/richtextctrl.cpp index ddb19402a9..6d6a65cbfa 100644 --- a/src/richtext/richtextctrl.cpp +++ b/src/richtext/richtextctrl.cpp @@ -5249,7 +5249,7 @@ bool wxRichTextCtrl::ProcessDelayedImageLoading(const wxRect& screenRect, wxRich wxImage image; bool changed = false; - if (imageObj->LoadAndScaleImageCache(image, contentRect.GetSize(), false, changed) && changed) + if (imageObj->LoadAndScaleImageCache(image, contentRect.GetSize(), context, changed) && changed) { loadCount ++; }