diff --git a/include/wx/bitmap.h b/include/wx/bitmap.h index f5ccd8397b..1442c75a36 100644 --- a/include/wx/bitmap.h +++ b/include/wx/bitmap.h @@ -22,10 +22,12 @@ class WXDLLIMPEXP_FWD_CORE wxBitmap; class WXDLLIMPEXP_FWD_CORE wxBitmapHandler; +class WXDLLIMPEXP_FWD_CORE wxCursor; +class WXDLLIMPEXP_FWD_CORE wxDC; class WXDLLIMPEXP_FWD_CORE wxIcon; class WXDLLIMPEXP_FWD_CORE wxMask; class WXDLLIMPEXP_FWD_CORE wxPalette; -class WXDLLIMPEXP_FWD_CORE wxDC; +class WXDLLIMPEXP_FWD_CORE wxPixelDataBase; // ---------------------------------------------------------------------------- // wxVariant support diff --git a/include/wx/dfb/bitmap.h b/include/wx/dfb/bitmap.h index cb0e4f0551..c3967b168a 100644 --- a/include/wx/dfb/bitmap.h +++ b/include/wx/dfb/bitmap.h @@ -27,11 +27,15 @@ public: wxBitmap(const wxIDirectFBSurfacePtr& surface) { Create(surface); } wxBitmap(int width, int height, int depth = -1) { Create(width, height, depth); } wxBitmap(const wxSize& sz, int depth = -1) { Create(sz, depth); } + wxBitmap(int width, int height, const wxDC& dc) { Create(width, height, dc); } wxBitmap(const char bits[], int width, int height, int depth = 1); wxBitmap(const wxString &filename, wxBitmapType type = wxBITMAP_DEFAULT_TYPE); wxBitmap(const char* const* bits); #if wxUSE_IMAGE - wxBitmap(const wxImage& image, int depth = -1, double WXUNUSED(scale) = 1.0); + wxBitmap(const wxImage& image, int depth = -1, double scale = 1.0) + { InitFromImage(image, depth, scale); } + wxBitmap(const wxImage& image, const wxDC& WXUNUSED(dc)) + { InitFromImage(image, -1, 1.0); } #endif bool Create(const wxIDirectFBSurfacePtr& surface); @@ -85,6 +89,8 @@ protected: virtual wxGDIRefData *CreateGDIRefData() const; virtual wxGDIRefData *CloneGDIRefData(const wxGDIRefData *data) const; + void InitFromImage(const wxImage& image, int depth, double scale); + bool CreateWithFormat(int width, int height, int dfbFormat); wxDECLARE_DYNAMIC_CLASS(wxBitmap); diff --git a/include/wx/gtk/bitmap.h b/include/wx/gtk/bitmap.h index 2919fc80d9..e53186dc16 100644 --- a/include/wx/gtk/bitmap.h +++ b/include/wx/gtk/bitmap.h @@ -14,8 +14,6 @@ typedef struct _cairo cairo_t; typedef struct _cairo_surface cairo_surface_t; #endif typedef struct _GdkPixbuf GdkPixbuf; -class WXDLLIMPEXP_FWD_CORE wxPixelDataBase; -class WXDLLIMPEXP_FWD_CORE wxCursor; //----------------------------------------------------------------------------- // wxMask @@ -70,11 +68,14 @@ public: { Create(width, height, depth); } wxBitmap( const wxSize& sz, int depth = wxBITMAP_SCREEN_DEPTH ) { Create(sz, depth); } + wxBitmap( int width, int height, const wxDC& dc ) + { Create(width, height, dc); } wxBitmap( const char bits[], int width, int height, int depth = 1 ); wxBitmap( const char* const* bits ); wxBitmap( const wxString &filename, wxBitmapType type = wxBITMAP_DEFAULT_TYPE ); #if wxUSE_IMAGE wxBitmap(const wxImage& image, int depth = wxBITMAP_SCREEN_DEPTH, double scale = 1.0); + wxBitmap(const wxImage& image, const wxDC& dc); #endif // wxUSE_IMAGE wxBitmap(GdkPixbuf* pixbuf, int depth = 0); explicit wxBitmap(const wxCursor& cursor); @@ -147,11 +148,12 @@ public: bool HasAlpha() const; protected: -#ifndef __WXGTK3__ #if wxUSE_IMAGE + void InitFromImage(const wxImage& image, int depth, double scale); +#ifndef __WXGTK3__ bool CreateFromImage(const wxImage& image, int depth); -#endif // wxUSE_IMAGE #endif +#endif // wxUSE_IMAGE virtual wxGDIRefData* CreateGDIRefData() const wxOVERRIDE; virtual wxGDIRefData* CloneGDIRefData(const wxGDIRefData* data) const wxOVERRIDE; diff --git a/include/wx/gtk1/bitmap.h b/include/wx/gtk1/bitmap.h index 00f592de92..8c3111d588 100644 --- a/include/wx/gtk1/bitmap.h +++ b/include/wx/gtk1/bitmap.h @@ -10,14 +10,9 @@ #ifndef __GTKBITMAPH__ #define __GTKBITMAPH__ -#include "wx/defs.h" -#include "wx/object.h" -#include "wx/string.h" #include "wx/palette.h" #include "wx/gdiobj.h" -class WXDLLIMPEXP_FWD_CORE wxPixelDataBase; - //----------------------------------------------------------------------------- // classes //----------------------------------------------------------------------------- @@ -69,10 +64,12 @@ public: wxBitmap() {} wxBitmap( int width, int height, int depth = -1 ) { Create( width, height, depth ); } wxBitmap( const wxSize& sz, int depth = -1 ) { Create( sz, depth ); } + wxBitmap( int width, int height, const wxDC& dc ) { Create(width, height, dc); } wxBitmap( const char bits[], int width, int height, int depth = 1 ); wxBitmap( const char* const* bits ); wxBitmap( const wxString &filename, wxBitmapType type = wxBITMAP_DEFAULT_TYPE ); wxBitmap( const wxImage& image, int depth = -1, double WXUNUSED(scale) = 1.0 ) { (void)CreateFromImage(image, depth); } + wxBitmap( const wxImage& image, const wxDC& WXUNUSED(dc) ) { (void)CreateFromImage(image); } explicit wxBitmap(const wxCursor& cursor); virtual ~wxBitmap(); diff --git a/include/wx/msw/bitmap.h b/include/wx/msw/bitmap.h index 90401db1e2..c055716fcd 100644 --- a/include/wx/msw/bitmap.h +++ b/include/wx/msw/bitmap.h @@ -15,19 +15,10 @@ #include "wx/math.h" #include "wx/palette.h" -class WXDLLIMPEXP_FWD_CORE wxBitmap; -class WXDLLIMPEXP_FWD_CORE wxBitmapHandler; class WXDLLIMPEXP_FWD_CORE wxBitmapRefData; -class WXDLLIMPEXP_FWD_CORE wxControl; -class WXDLLIMPEXP_FWD_CORE wxCursor; -class WXDLLIMPEXP_FWD_CORE wxDC; #if wxUSE_WXDIB class WXDLLIMPEXP_FWD_CORE wxDIB; #endif -class WXDLLIMPEXP_FWD_CORE wxIcon; -class WXDLLIMPEXP_FWD_CORE wxMask; -class WXDLLIMPEXP_FWD_CORE wxPalette; -class WXDLLIMPEXP_FWD_CORE wxPixelDataBase; // What kind of transparency should a bitmap copied from an icon or cursor // have? diff --git a/include/wx/osx/bitmap.h b/include/wx/osx/bitmap.h index cef7860f1c..59008b119f 100644 --- a/include/wx/osx/bitmap.h +++ b/include/wx/osx/bitmap.h @@ -14,15 +14,7 @@ #include "wx/palette.h" // Bitmap -class WXDLLIMPEXP_FWD_CORE wxBitmap; class wxBitmapRefData ; -class WXDLLIMPEXP_FWD_CORE wxBitmapHandler; -class WXDLLIMPEXP_FWD_CORE wxControl; -class WXDLLIMPEXP_FWD_CORE wxCursor; -class WXDLLIMPEXP_FWD_CORE wxDC; -class WXDLLIMPEXP_FWD_CORE wxIcon; -class WXDLLIMPEXP_FWD_CORE wxImage; -class WXDLLIMPEXP_FWD_CORE wxPixelDataBase; // A mask is a bitmap used for drawing bitmaps // Internally it is stored as a 8 bit deep memory chunk, 0 = black means the source will be drawn @@ -122,6 +114,7 @@ public: // Convert from wxImage: wxBitmap(const wxImage& image, int depth = -1, double scale = 1.0); + wxBitmap(const wxImage& image, const wxDC& dc); // Convert from wxIcon wxBitmap(const wxIcon& icon) { CopyFromIcon(icon); } @@ -244,6 +237,9 @@ protected: virtual wxGDIRefData *CloneGDIRefData(const wxGDIRefData *data) const wxOVERRIDE; virtual bool DoCreate(const wxSize& sz, double scale, int depth) wxOVERRIDE; + +private: + void InitFromImage(const wxImage& image, int depth, double scale); }; #endif // _WX_BITMAP_H_ diff --git a/include/wx/qt/bitmap.h b/include/wx/qt/bitmap.h index d9451ce4b8..11c4ec81e9 100644 --- a/include/wx/qt/bitmap.h +++ b/include/wx/qt/bitmap.h @@ -8,12 +8,7 @@ #ifndef _WX_QT_BITMAP_H_ #define _WX_QT_BITMAP_H_ -class WXDLLIMPEXP_FWD_CORE wxPixelDataBase; - -class WXDLLIMPEXP_FWD_CORE wxImage; -class WXDLLIMPEXP_FWD_CORE wxCursor; class QImage; - class QPixmap; class QBitmap; @@ -25,9 +20,11 @@ public: wxBitmap(const char bits[], int width, int height, int depth = 1); wxBitmap(int width, int height, int depth = wxBITMAP_SCREEN_DEPTH); wxBitmap(const wxSize& sz, int depth = wxBITMAP_SCREEN_DEPTH); + wxBitmap(int width, int height, const wxDC& dc); wxBitmap(const char* const* bits); wxBitmap(const wxString &filename, wxBitmapType type = wxBITMAP_TYPE_XPM); wxBitmap(const wxImage& image, int depth = wxBITMAP_SCREEN_DEPTH, double scale = 1.0); + wxBitmap(const wxImage& image, const wxDC& dc); // Convert from wxIcon / wxCursor wxBitmap(const wxIcon& icon) { CopyFromIcon(icon); } @@ -37,7 +34,7 @@ public: virtual bool Create(int width, int height, int depth = wxBITMAP_SCREEN_DEPTH) wxOVERRIDE; virtual bool Create(const wxSize& sz, int depth = wxBITMAP_SCREEN_DEPTH) wxOVERRIDE; - virtual bool Create(int width, int height, const wxDC& WXUNUSED(dc)); + virtual bool Create(int width, int height, const wxDC& dc); virtual int GetHeight() const wxOVERRIDE; virtual int GetWidth() const wxOVERRIDE; @@ -81,6 +78,9 @@ protected: virtual wxGDIRefData *CreateGDIRefData() const wxOVERRIDE; virtual wxGDIRefData *CloneGDIRefData(const wxGDIRefData *data) const wxOVERRIDE; +private: + void InitFromImage(const wxImage& image, int depth, double WXUNUSED(scale)); + wxDECLARE_DYNAMIC_CLASS(wxBitmap); }; diff --git a/include/wx/x11/bitmap.h b/include/wx/x11/bitmap.h index 4c0e6ce3b6..c7cf0616ff 100644 --- a/include/wx/x11/bitmap.h +++ b/include/wx/x11/bitmap.h @@ -11,20 +11,9 @@ #ifndef _WX_BITMAP_H_ #define _WX_BITMAP_H_ -#include "wx/defs.h" -#include "wx/object.h" -#include "wx/string.h" #include "wx/palette.h" #include "wx/gdiobj.h" -//----------------------------------------------------------------------------- -// classes -//----------------------------------------------------------------------------- - -class WXDLLIMPEXP_FWD_CORE wxMask; -class WXDLLIMPEXP_FWD_CORE wxBitmap; -class WXDLLIMPEXP_FWD_CORE wxImage; - //----------------------------------------------------------------------------- // wxMask //----------------------------------------------------------------------------- @@ -69,6 +58,7 @@ public: wxBitmap() {} wxBitmap( int width, int height, int depth = -1 ) { Create( width, height, depth ); } wxBitmap( const wxSize& sz, int depth = -1 ) { Create( sz, depth ); } + wxBitmap( int width, int height, const wxDC& dc ) { Create(width, height, dc); } wxBitmap( const char bits[], int width, int height, int depth = 1 ); wxBitmap( const char* const* bits ); @@ -94,6 +84,7 @@ public: #if wxUSE_IMAGE wxBitmap( const wxImage& image, int depth = -1, double WXUNUSED(scale) = 1.0 ) { (void)CreateFromImage(image, depth); } + wxBitmap( const wxImage& image, const wxDC& WXUNUSED(dc) ) { (void)CreateFromImage(image); } wxImage ConvertToImage() const; bool CreateFromImage(const wxImage& image, int depth = -1); #endif // wxUSE_IMAGE diff --git a/interface/wx/bitmap.h b/interface/wx/bitmap.h index b39d1a6faa..0faae1d891 100644 --- a/interface/wx/bitmap.h +++ b/interface/wx/bitmap.h @@ -306,6 +306,20 @@ public: */ wxBitmap(const wxSize& sz, int depth = wxBITMAP_SCREEN_DEPTH); + /** + Create a bitmap compatible with the given DC, inheriting its magnification factor + + @param width + The width of the bitmap in pixels, must be strictly positive. + @param height + The height of the bitmap in pixels, must be strictly positive. + @param dc + DC from which the scaling factor is inherited + + @since 3.1.7 (previously available only in wxMSW and wxOSX ports). + */ + wxBitmap(int width, int height, const wxDC& dc); + /** Creates a bitmap from XPM data. @@ -353,6 +367,23 @@ public: */ wxBitmap(const wxImage& img, int depth = wxBITMAP_SCREEN_DEPTH); + /** + Creates a bitmap compatible with the given DC from the given image. + + This constructor initializes the bitmap with the data of the given + image, which must be valid, but inherits the scaling factor from the + given device context instead of simply using the default factor of 1. + + @param img + Platform-independent wxImage object. + @param dc + DC from which the scaling factor is inherited + + @since 3.1.7 (previously this constructor overload was only available + in wxMSW port) + */ + wxBitmap(const wxImage& img, const wxDC& dc); + /** Creates bitmap corresponding to the given cursor. diff --git a/src/dfb/bitmap.cpp b/src/dfb/bitmap.cpp index 98a0167eb4..47ed640950 100644 --- a/src/dfb/bitmap.cpp +++ b/src/dfb/bitmap.cpp @@ -417,7 +417,7 @@ bool wxBitmap::CreateWithFormat(int width, int height, int dfbFormat) } #if wxUSE_IMAGE -wxBitmap::wxBitmap(const wxImage& imageOrig, int depth, double WXUNUSED(scale)) +void wxBitmap::InitFromImage(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 095b09b78c..7cb3e7bb63 100644 --- a/src/gtk/bitmap.cpp +++ b/src/gtk/bitmap.cpp @@ -16,15 +16,12 @@ #include "wx/image.h" #include "wx/colour.h" #include "wx/cursor.h" + #include "wx/dc.h" #endif #include "wx/math.h" #include "wx/rawbmp.h" -#ifdef __WXGTK3__ -#include "wx/dc.h" -#endif - #include "wx/gtk/private/object.h" #include "wx/gtk/private.h" @@ -593,7 +590,7 @@ static void CopyImageData( #if wxUSE_IMAGE #ifdef __WXGTK3__ -wxBitmap::wxBitmap(const wxImage& image, int depth, double scale) +void wxBitmap::InitFromImage(const wxImage& image, int depth, double scale) { wxCHECK_RET(image.IsOk(), "invalid image"); @@ -640,7 +637,7 @@ wxBitmap::wxBitmap(const wxImage& image, int depth, double scale) } } #else -wxBitmap::wxBitmap(const wxImage& image, int depth, double WXUNUSED(scale)) +void wxBitmap::InitFromImage(const wxImage& image, int depth, double WXUNUSED(scale)) { wxCHECK_RET(image.IsOk(), "invalid image"); @@ -786,6 +783,16 @@ bool wxBitmap::CreateFromImageAsPixbuf(const wxImage& image) } #endif +wxBitmap::wxBitmap(const wxImage& image, int depth, double scale) +{ + InitFromImage(image, depth, scale); +} + +wxBitmap::wxBitmap(const wxImage& image, const wxDC& dc) +{ + InitFromImage(image, -1, dc.GetContentScaleFactor()); +} + wxImage wxBitmap::ConvertToImage() const { #ifdef __WXGTK3__ diff --git a/src/msw/bitmap.cpp b/src/msw/bitmap.cpp index 91e1c281b4..e22f43c98f 100644 --- a/src/msw/bitmap.cpp +++ b/src/msw/bitmap.cpp @@ -755,12 +755,14 @@ bool wxBitmap::Create(int width, int height, const wxDC& dc) { wxCHECK_MSG( dc.IsOk(), false, wxT("invalid HDC in wxBitmap::Create()") ); - const wxMSWDCImpl *impl = wxDynamicCast( dc.GetImpl(), wxMSWDCImpl ); + const double scale = dc.GetContentScaleFactor(); - if (impl) - return DoCreate(width, height, -1, impl->GetHDC()); - else + if ( !DoCreate(wxRound(width*scale), wxRound(height*scale), -1, dc.GetHDC()) ) return false; + + GetBitmapData()->m_scaleFactor = scale; + + return true; } bool wxBitmap::CreateWithDIPSize(const wxSize& size, double scale, int depth) @@ -854,12 +856,12 @@ bool wxBitmap::CreateFromImage(const wxImage& image, const wxDC& dc) wxCHECK_MSG( dc.IsOk(), false, wxT("invalid HDC in wxBitmap::CreateFromImage()") ); - const wxMSWDCImpl *impl = wxDynamicCast( dc.GetImpl(), wxMSWDCImpl ); - - if (impl) - return CreateFromImage(image, -1, impl->GetHDC()); - else + if ( !CreateFromImage(image, -1, dc.GetHDC()) ) return false; + + GetBitmapData()->m_scaleFactor = dc.GetContentScaleFactor(); + + return true; } #if wxUSE_WXDIB diff --git a/src/osx/core/bitmap.cpp b/src/osx/core/bitmap.cpp index 9ffe066f9c..0f8824d81a 100644 --- a/src/osx/core/bitmap.cpp +++ b/src/osx/core/bitmap.cpp @@ -1134,7 +1134,7 @@ bool wxBitmap::Create(const void* data, wxBitmapType type, int width, int height #if wxUSE_IMAGE -wxBitmap::wxBitmap(const wxImage& image, int depth, double scale) +void wxBitmap::InitFromImage(const wxImage& image, int depth, double scale) { wxCHECK_RET( image.IsOk(), wxT("invalid image") ); @@ -1235,6 +1235,16 @@ wxBitmap::wxBitmap(const wxImage& image, int depth, double scale) } } +wxBitmap::wxBitmap(const wxImage& image, int depth, double scale) +{ + InitFromImage(image, depth, scale); +} + +wxBitmap::wxBitmap(const wxImage& image, const wxDC& dc) +{ + InitFromImage(image, -1, dc.GetContentScaleFactor()); +} + wxImage wxBitmap::ConvertToImage() const { wxImage image; diff --git a/src/qt/bitmap.cpp b/src/qt/bitmap.cpp index 349b044504..46e7707036 100644 --- a/src/qt/bitmap.cpp +++ b/src/qt/bitmap.cpp @@ -14,6 +14,7 @@ #include #ifndef WX_PRECOMP + #include "wx/dc.h" #include "wx/icon.h" #include "wx/image.h" #endif // WX_PRECOMP @@ -192,6 +193,11 @@ wxBitmap::wxBitmap(const wxSize& sz, int depth ) Create(sz, depth); } +wxBitmap::wxBitmap(int width, int height, const wxDC& dc) +{ + Create(width, height, dc); +} + // Create a wxBitmap from xpm data wxBitmap::wxBitmap(const char* const* bits) { @@ -204,7 +210,7 @@ wxBitmap::wxBitmap(const wxString &filename, wxBitmapType type ) LoadFile(filename, type); } -wxBitmap::wxBitmap(const wxImage& image, int depth, double WXUNUSED(scale) ) +void wxBitmap::InitFromImage(const wxImage& image, int depth, double WXUNUSED(scale) ) { Qt::ImageConversionFlags flags = 0; if (depth == 1) @@ -212,6 +218,16 @@ wxBitmap::wxBitmap(const wxImage& image, int depth, double WXUNUSED(scale) ) m_refData = new wxBitmapRefData(QPixmap::fromImage(ConvertImage(image), flags)); } +wxBitmap::wxBitmap(const wxImage& image, int depth, double scale) +{ + InitFromImage(image, depth, scale); +} + +wxBitmap::wxBitmap(const wxImage& image, const wxDC& dc) +{ + InitFromImage(image, -1, dc.GetContentScaleFactor()); +} + wxBitmap::wxBitmap(const wxCursor& cursor) { // note that pixmap could be invalid if is not a pixmap cursor diff --git a/tests/graphics/bitmap.cpp b/tests/graphics/bitmap.cpp index 432f45cd95..dde38ad8c4 100644 --- a/tests/graphics/bitmap.cpp +++ b/tests/graphics/bitmap.cpp @@ -18,6 +18,7 @@ #include "wx/bitmap.h" #include "wx/rawbmp.h" #include "wx/dcmemory.h" +#include "wx/dcsvg.h" #if wxUSE_GRAPHICS_CONTEXT #include "wx/graphics.h" #endif // wxUSE_GRAPHICS_CONTEXT @@ -1690,6 +1691,50 @@ TEST_CASE("DC::Clear", "[bitmap][dc]") } } +TEST_CASE("Bitmap::DC", "[bitmap][dc]") +{ +#if wxUSE_SVG + TempFile dummySVG("dummy.svg"); + wxSVGFileDC dc(dummySVG.GetName()); + wxBitmap bmp(10, 10, dc); + CHECK( bmp.IsOk() ); + + wxImage image(10, 10); + wxBitmap bmpFromImage(image, dc); + CHECK( bmpFromImage.IsOk() ); +#endif // wxUSE_SVG +} + +#if defined(wxHAS_DPI_INDEPENDENT_PIXELS) || defined(__WXMSW__) + +TEST_CASE("Bitmap::ScaleFactor", "[bitmap][dc][scale]") +{ + // Create a bitmap with scale factor != 1. + wxBitmap bmp; + bmp.CreateWithDIPSize(8, 8, 2); + REQUIRE( bmp.GetScaleFactor() == 2 ); + CHECK( bmp.GetSize() == wxSize(16, 16) ); + + // wxMemoryDC should use the same scale factor as the bitmap. + wxMemoryDC dc(bmp); + CHECK( dc.GetContentScaleFactor() == 2 ); + + // A bitmap "compatible" with this DC should also use the same scale factor. + wxBitmap bmp2(4, 4, dc); + CHECK( bmp2.GetScaleFactor() == 2 ); + CHECK( bmp2.GetSize() == wxSize(8, 8) ); + + // A compatible bitmap created from wxImage and this DC should also inherit + // the same scale factor, but its size should be still the same as that of + // the image. + wxImage img(16, 16); + wxBitmap bmp3(img, dc); + CHECK( bmp3.GetScaleFactor() == 2 ); + CHECK( bmp3.GetSize() == wxSize(16, 16) ); +} + +#endif // ports with scaled bitmaps support + #if wxUSE_GRAPHICS_CONTEXT inline void DrawScaledBmp(wxBitmap& bmp, float scale, wxGraphicsRenderer* renderer)