Make wxBitmap ctors consistent wrt passing scale for conversion from wxImage; HiDPI adaptation for propgrid buffer and wxRTC images

This commit is contained in:
JulianSmart
2015-11-15 12:49:25 +00:00
parent fdbed751dc
commit a797c9d956
13 changed files with 38 additions and 22 deletions

View File

@@ -31,7 +31,7 @@ public:
wxBitmap(const wxString &filename, wxBitmapType type = wxBITMAP_DEFAULT_TYPE); wxBitmap(const wxString &filename, wxBitmapType type = wxBITMAP_DEFAULT_TYPE);
wxBitmap(const char* const* bits); wxBitmap(const char* const* bits);
#if wxUSE_IMAGE #if wxUSE_IMAGE
wxBitmap(const wxImage& image, int depth = -1); wxBitmap(const wxImage& image, int depth = -1, double WXUNUSED(scale) = 1.0);
#endif #endif
bool Create(const wxIDirectFBSurfacePtr& surface); bool Create(const wxIDirectFBSurfacePtr& surface);

View File

@@ -79,7 +79,7 @@ public:
#endif #endif
wxBitmap( const wxString &filename, wxBitmapType type = wxBITMAP_DEFAULT_TYPE ); wxBitmap( const wxString &filename, wxBitmapType type = wxBITMAP_DEFAULT_TYPE );
#if wxUSE_IMAGE #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 #endif // wxUSE_IMAGE
wxBitmap(GdkPixbuf* pixbuf, int depth = 0); wxBitmap(GdkPixbuf* pixbuf, int depth = 0);
wxEXPLICIT wxBitmap(const wxCursor& cursor); wxEXPLICIT wxBitmap(const wxCursor& cursor);

View File

@@ -76,7 +76,7 @@ public:
} }
#endif #endif
wxBitmap( const wxString &filename, wxBitmapType type = wxBITMAP_DEFAULT_TYPE ); 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(); virtual ~wxBitmap();
bool Create(int width, int height, int depth = wxBITMAP_SCREEN_DEPTH); bool Create(int width, int height, int depth = wxBITMAP_SCREEN_DEPTH);

View File

@@ -81,7 +81,7 @@ public:
#if wxUSE_IMAGE #if wxUSE_IMAGE
// Convert from wxImage // 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); } { (void)CreateFromImage(image, depth); }
// Create a DDB compatible with the given DC from wxImage // Create a DDB compatible with the given DC from wxImage

View File

@@ -28,7 +28,7 @@ public:
wxBitmap(const wxSize& sz, int depth = wxBITMAP_SCREEN_DEPTH); wxBitmap(const wxSize& sz, int depth = wxBITMAP_SCREEN_DEPTH);
wxBitmap(const char* const* bits); wxBitmap(const char* const* bits);
wxBitmap(const wxString &filename, wxBitmapType type = wxBITMAP_TYPE_XPM); 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 // Convert from wxIcon / wxCursor
wxBitmap(const wxIcon& icon) { CopyFromIcon(icon); } wxBitmap(const wxIcon& icon) { CopyFromIcon(icon); }

View File

@@ -2499,6 +2499,12 @@ public:
bool GetDelayedImageLoading() const { return m_enableDelayedImageLoading; } bool GetDelayedImageLoading() const { return m_enableDelayedImageLoading; }
/**
Returns the buffer pointer.
*/
wxRichTextBuffer* GetBuffer() const { return m_buffer; }
wxRichTextBuffer* m_buffer; wxRichTextBuffer* m_buffer;
bool m_enableVirtualAttributes; bool m_enableVirtualAttributes;
bool m_enableImages; bool m_enableImages;
@@ -5064,7 +5070,7 @@ public:
/** /**
Do the loading and scaling 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. Gets the original image size.

View File

@@ -100,7 +100,7 @@ public:
int GetDepth() const; int GetDepth() const;
#if wxUSE_IMAGE #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; wxImage ConvertToImage() const;
bool CreateFromImage(const wxImage& image, int depth = -1); bool CreateFromImage(const wxImage& image, int depth = -1);
#endif // wxUSE_IMAGE #endif // wxUSE_IMAGE

View File

@@ -420,7 +420,7 @@ bool wxBitmap::CreateWithFormat(int width, int height, int dfbFormat)
} }
#if wxUSE_IMAGE #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") ); wxCHECK_RET( imageOrig.IsOk(), wxT("invalid image") );

View File

@@ -590,7 +590,7 @@ static void CopyImageData(
#if wxUSE_IMAGE #if wxUSE_IMAGE
#ifdef __WXGTK3__ #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"); wxCHECK_RET(image.IsOk(), "invalid image");
@@ -636,7 +636,7 @@ wxBitmap::wxBitmap(const wxImage& image, int depth)
} }
} }
#else #else
wxBitmap::wxBitmap(const wxImage& image, int depth) wxBitmap::wxBitmap(const wxImage& image, int depth, double WXUNUSED(scale))
{ {
wxCHECK_RET(image.IsOk(), "invalid image"); wxCHECK_RET(image.IsOk(), "invalid image");

View File

@@ -4660,13 +4660,15 @@ void wxPropertyGrid::OnResize( wxSizeEvent& event )
if ( !HasExtraStyle(wxPG_EX_NATIVE_DOUBLE_BUFFERING) ) if ( !HasExtraStyle(wxPG_EX_NATIVE_DOUBLE_BUFFERING) )
{ {
double scaleFactor = GetContentScaleFactor();
int dblh = (m_lineHeight*2); int dblh = (m_lineHeight*2);
if ( !m_doubleBuffer ) if ( !m_doubleBuffer )
{ {
// Create double buffer bitmap to draw on, if none // Create double buffer bitmap to draw on, if none
int w = wxMax(width, 250); int w = wxMax(width, 250);
int h = wxMax(height + dblh, 400); 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 else
{ {
@@ -4679,7 +4681,8 @@ void wxPropertyGrid::OnResize( wxSizeEvent& event )
if ( w < width ) w = width; if ( w < width ) w = width;
if ( h < (height+dblh) ) h = height + dblh; if ( h < (height+dblh) ) h = height + dblh;
delete m_doubleBuffer; delete m_doubleBuffer;
m_doubleBuffer = new wxBitmap( w, h ); m_doubleBuffer = new wxBitmap;
m_doubleBuffer->CreateScaled( w, h, wxBITMAP_SCREEN_DEPTH, scaleFactor );
} }
} }
} }

View File

@@ -220,7 +220,7 @@ wxBitmap::wxBitmap(const wxString &filename, wxBitmapType type )
LoadFile(filename, 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; Qt::ImageConversionFlags flags = 0;
if (depth == 1) if (depth == 1)

View File

@@ -12483,7 +12483,7 @@ bool wxRichTextImage::LoadImageCache(wxDC& dc, wxRichTextDrawingContext& context
// Don't repeat unless absolutely necessary // Don't repeat unless absolutely necessary
if (m_imageCache.IsOk() && !resetCache && !context.GetLayingOut()) 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; return true;
} }
@@ -12636,16 +12636,16 @@ bool wxRichTextImage::LoadImageCache(wxDC& dc, wxRichTextDrawingContext& context
retImageSize = wxSize(width, height); retImageSize = wxSize(width, height);
bool changed = false; bool changed = false;
return LoadAndScaleImageCache(image, retImageSize, context.GetDelayedImageLoading(), changed); return LoadAndScaleImageCache(image, retImageSize, context, changed);
} }
// Do the loading and scaling // 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 width = sz.x;
int height = sz.y; 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 // Do nothing, we didn't need to change the image cache
changed = false; changed = false;
@@ -12654,7 +12654,7 @@ bool wxRichTextImage::LoadAndScaleImageCache(wxImage& image, const wxSize& sz, b
{ {
changed = true; changed = true;
if (delayLoading) if (context.GetDelayedImageLoading())
{ {
if (m_imageCache.IsOk()) if (m_imageCache.IsOk())
m_imageCache = wxNullBitmap; m_imageCache = wxNullBitmap;
@@ -12680,6 +12680,10 @@ bool wxRichTextImage::LoadAndScaleImageCache(wxImage& image, const wxSize& sz, b
m_imageCache = wxBitmap(image); m_imageCache = wxBitmap(image);
else 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, // 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 // scale up and then down to improve image quality. This can make
// a big difference, with not much performance hit. // 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) if (image.GetWidth() <= upscaleThreshold || image.GetHeight() <= upscaleThreshold)
{ {
img = image.Scale(image.GetWidth()*2, image.GetHeight()*2); 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 else
img = image.Scale(width, height, wxIMAGE_QUALITY_HIGH); img = image.Scale(width*scaleFactor, height*scaleFactor, wxIMAGE_QUALITY_HIGH);
m_imageCache = wxBitmap(img);
// 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);
} }
} }

View File

@@ -5249,7 +5249,7 @@ bool wxRichTextCtrl::ProcessDelayedImageLoading(const wxRect& screenRect, wxRich
wxImage image; wxImage image;
bool changed = false; bool changed = false;
if (imageObj->LoadAndScaleImageCache(image, contentRect.GetSize(), false, changed) && changed) if (imageObj->LoadAndScaleImageCache(image, contentRect.GetSize(), context, changed) && changed)
{ {
loadCount ++; loadCount ++;
} }