Fix several problem with wxMemoryDC in wxQt
Under wxQT, wxMemoryDC was previously rendering to a temporary image which was only being blitted back to the original wxBitmap when either the DC wx destroyed or a new bitmap was selected (via SelectObject). With these change wxMemoryDCImpl now draws directly to the bitmap managed by wxBitmap, this makes the behaviour more consistent with the MSW and GTK implementations. Closes https://github.com/wxWidgets/wxWidgets/pull/1083
This commit is contained in:
committed by
Vadim Zeitlin
parent
80904d1bc7
commit
ae20edb539
@@ -111,10 +111,10 @@ public:
|
|||||||
virtual void* GetHandle() const { return (void*) m_qtPainter; }
|
virtual void* GetHandle() const { return (void*) m_qtPainter; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual QImage *GetQImage() { return m_qtImage; }
|
virtual QPixmap *GetQPixmap() { return m_qtPixmap; }
|
||||||
|
|
||||||
QPainter *m_qtPainter;
|
QPainter *m_qtPainter;
|
||||||
QImage *m_qtImage;
|
QPixmap *m_qtPixmap;
|
||||||
|
|
||||||
wxRegion *m_clippingRegion;
|
wxRegion *m_clippingRegion;
|
||||||
private:
|
private:
|
||||||
|
@@ -19,9 +19,7 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void DoGetSize(int *width, int *height) const wxOVERRIDE;
|
virtual void DoGetSize(int *width, int *height) const wxOVERRIDE;
|
||||||
virtual bool DoGetPixel(wxCoord x, wxCoord y, wxColour *col) const;
|
virtual QPixmap *GetQPixmap() wxOVERRIDE;
|
||||||
|
|
||||||
virtual QImage *GetQImage();
|
|
||||||
|
|
||||||
wxDECLARE_ABSTRACT_CLASS(wxScreenDCImpl);
|
wxDECLARE_ABSTRACT_CLASS(wxScreenDCImpl);
|
||||||
};
|
};
|
||||||
|
@@ -47,7 +47,7 @@ wxQtDCImpl::wxQtDCImpl( wxDC *owner )
|
|||||||
: wxDCImpl( owner )
|
: wxDCImpl( owner )
|
||||||
{
|
{
|
||||||
m_clippingRegion = new wxRegion;
|
m_clippingRegion = new wxRegion;
|
||||||
m_qtImage = NULL;
|
m_qtPixmap = NULL;
|
||||||
m_rasterColourOp = wxQtNONE;
|
m_rasterColourOp = wxQtNONE;
|
||||||
m_qtPenColor = new QColor;
|
m_qtPenColor = new QColor;
|
||||||
m_qtBrushColor = new QColor;
|
m_qtBrushColor = new QColor;
|
||||||
@@ -474,15 +474,18 @@ bool wxQtDCImpl::DoGetPixel(wxCoord x, wxCoord y, wxColour *col) const
|
|||||||
|
|
||||||
if ( col )
|
if ( col )
|
||||||
{
|
{
|
||||||
wxCHECK_MSG( m_qtImage != NULL, false, "This DC doesn't support GetPixel()" );
|
wxCHECK_MSG( m_qtPixmap != NULL, false, "This DC doesn't support GetPixel()" );
|
||||||
|
QPixmap pixmap1px = m_qtPixmap->copy( x, y, 1, 1 );
|
||||||
QColor pixel = m_qtImage->pixel( x, y );
|
QImage image = pixmap1px.toImage();
|
||||||
|
QColor pixel = image.pixel( 0, 0 );
|
||||||
col->Set( pixel.red(), pixel.green(), pixel.blue(), pixel.alpha() );
|
col->Set( pixel.red(), pixel.green(), pixel.blue(), pixel.alpha() );
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxQtDCImpl::DoDrawPoint(wxCoord x, wxCoord y)
|
void wxQtDCImpl::DoDrawPoint(wxCoord x, wxCoord y)
|
||||||
@@ -739,23 +742,31 @@ bool wxQtDCImpl::DoBlit(wxCoord xdest, wxCoord ydest,
|
|||||||
{
|
{
|
||||||
wxQtDCImpl *implSource = (wxQtDCImpl*)source->GetImpl();
|
wxQtDCImpl *implSource = (wxQtDCImpl*)source->GetImpl();
|
||||||
|
|
||||||
QImage *qtSource = implSource->GetQImage();
|
QPixmap *qtSource = implSource->GetQPixmap();
|
||||||
|
|
||||||
// Not a CHECK on purpose
|
// Not a CHECK on purpose
|
||||||
if ( !qtSource )
|
if ( !qtSource )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
QImage qtSourceConverted = *qtSource;
|
|
||||||
if ( !useMask )
|
|
||||||
qtSourceConverted = qtSourceConverted.convertToFormat( QImage::Format_RGB32 );
|
|
||||||
|
|
||||||
// Change logical function
|
// Change logical function
|
||||||
wxRasterOperationMode savedMode = GetLogicalFunction();
|
wxRasterOperationMode savedMode = GetLogicalFunction();
|
||||||
SetLogicalFunction( rop );
|
SetLogicalFunction( rop );
|
||||||
|
|
||||||
m_qtPainter->drawImage( QRect( xdest, ydest, width, height ),
|
if ( useMask )
|
||||||
qtSourceConverted,
|
{
|
||||||
QRect( xsrc, ysrc, width, height ) );
|
m_qtPainter->drawPixmap( QRect( xdest, ydest, width, height ),
|
||||||
|
*qtSource,
|
||||||
|
QRect( xsrc, ysrc, width, height ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QImage qtSourceConverted = qtSource->toImage();
|
||||||
|
qtSourceConverted = qtSourceConverted.convertToFormat(QImage::Format_RGB32);
|
||||||
|
|
||||||
|
m_qtPainter->drawImage( QRect( xdest, ydest, width, height ),
|
||||||
|
qtSourceConverted,
|
||||||
|
QRect( xsrc, ysrc, width, height ) );
|
||||||
|
}
|
||||||
|
|
||||||
SetLogicalFunction( savedMode );
|
SetLogicalFunction( savedMode );
|
||||||
|
|
||||||
|
@@ -31,7 +31,6 @@ wxWindowDCImpl::wxWindowDCImpl( wxDC *owner )
|
|||||||
: wxQtDCImpl( owner )
|
: wxQtDCImpl( owner )
|
||||||
{
|
{
|
||||||
m_window = NULL;
|
m_window = NULL;
|
||||||
m_qtImage = NULL;
|
|
||||||
m_ok = false;
|
m_ok = false;
|
||||||
m_qtPainter = new QPainter();
|
m_qtPainter = new QPainter();
|
||||||
}
|
}
|
||||||
@@ -40,7 +39,6 @@ wxWindowDCImpl::wxWindowDCImpl( wxDC *owner, wxWindow *win )
|
|||||||
: wxQtDCImpl( owner )
|
: wxQtDCImpl( owner )
|
||||||
{
|
{
|
||||||
m_window = win;
|
m_window = win;
|
||||||
m_qtImage = NULL;
|
|
||||||
m_qtPainter = m_window->QtGetPainter();
|
m_qtPainter = m_window->QtGetPainter();
|
||||||
// if we're not inside a Paint event, painter will invalid
|
// if we're not inside a Paint event, painter will invalid
|
||||||
m_ok = m_qtPainter != NULL;
|
m_ok = m_qtPainter != NULL;
|
||||||
|
@@ -16,7 +16,6 @@
|
|||||||
wxMemoryDCImpl::wxMemoryDCImpl( wxMemoryDC *owner )
|
wxMemoryDCImpl::wxMemoryDCImpl( wxMemoryDC *owner )
|
||||||
: wxQtDCImpl( owner )
|
: wxQtDCImpl( owner )
|
||||||
{
|
{
|
||||||
m_qtImage = NULL;
|
|
||||||
m_ok = false;
|
m_ok = false;
|
||||||
m_qtPainter = new QPainter();
|
m_qtPainter = new QPainter();
|
||||||
}
|
}
|
||||||
@@ -24,7 +23,6 @@ wxMemoryDCImpl::wxMemoryDCImpl( wxMemoryDC *owner )
|
|||||||
wxMemoryDCImpl::wxMemoryDCImpl( wxMemoryDC *owner, wxBitmap& bitmap )
|
wxMemoryDCImpl::wxMemoryDCImpl( wxMemoryDC *owner, wxBitmap& bitmap )
|
||||||
: wxQtDCImpl( owner )
|
: wxQtDCImpl( owner )
|
||||||
{
|
{
|
||||||
m_qtImage = NULL;
|
|
||||||
m_ok = false;
|
m_ok = false;
|
||||||
m_qtPainter = new QPainter();
|
m_qtPainter = new QPainter();
|
||||||
DoSelect( bitmap );
|
DoSelect( bitmap );
|
||||||
@@ -33,7 +31,6 @@ wxMemoryDCImpl::wxMemoryDCImpl( wxMemoryDC *owner, wxBitmap& bitmap )
|
|||||||
wxMemoryDCImpl::wxMemoryDCImpl( wxMemoryDC *owner, wxDC *WXUNUSED(dc) )
|
wxMemoryDCImpl::wxMemoryDCImpl( wxMemoryDC *owner, wxDC *WXUNUSED(dc) )
|
||||||
: wxQtDCImpl( owner )
|
: wxQtDCImpl( owner )
|
||||||
{
|
{
|
||||||
m_qtImage = NULL;
|
|
||||||
m_ok = false;
|
m_ok = false;
|
||||||
m_qtPainter = new QPainter();
|
m_qtPainter = new QPainter();
|
||||||
}
|
}
|
||||||
@@ -50,34 +47,21 @@ void wxMemoryDCImpl::DoSelect( const wxBitmap& bitmap )
|
|||||||
{
|
{
|
||||||
// Finish the painting in the intermediate image device:
|
// Finish the painting in the intermediate image device:
|
||||||
m_qtPainter->end();
|
m_qtPainter->end();
|
||||||
|
|
||||||
if (m_selected.IsOk() && !m_selected.GetHandle()->isNull())
|
|
||||||
{
|
|
||||||
// Copy intermediate image to the bitmap
|
|
||||||
m_qtPainter->begin( m_selected.GetHandle() );
|
|
||||||
m_qtPainter->drawImage( QPoint( 0, 0 ), *m_qtImage );
|
|
||||||
m_qtPainter->end();
|
|
||||||
}
|
|
||||||
m_ok = false;
|
m_ok = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// clean up the intermediate image device:
|
// clean up the intermediate image device:
|
||||||
if ( m_qtImage )
|
|
||||||
{
|
|
||||||
delete m_qtImage;
|
|
||||||
m_qtImage = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_selected = bitmap;
|
m_selected = bitmap;
|
||||||
if ( bitmap.IsOk() && !bitmap.GetHandle()->isNull() ) {
|
m_qtPixmap = bitmap.GetHandle();
|
||||||
QPixmap pixmap(*bitmap.GetHandle());
|
if ( bitmap.IsOk() && !m_qtPixmap->isNull() )
|
||||||
// apply mask before converting to image
|
{
|
||||||
if ( bitmap.GetMask() && bitmap.GetMask()->GetHandle() )
|
// apply mask before drawing
|
||||||
pixmap.setMask(*bitmap.GetMask()->GetHandle());
|
wxMask *mask = bitmap.GetMask();
|
||||||
// create the intermediate image for the pixmap:
|
if ( mask && mask->GetHandle() )
|
||||||
m_qtImage = new QImage( pixmap.toImage() );
|
m_qtPixmap->setMask(*mask->GetHandle());
|
||||||
|
|
||||||
// start drawing on the intermediary device:
|
// start drawing on the intermediary device:
|
||||||
m_ok = m_qtPainter->begin( m_qtImage );
|
m_ok = m_qtPainter->begin( m_qtPixmap );
|
||||||
|
|
||||||
SetPen(m_pen);
|
SetPen(m_pen);
|
||||||
SetBrush(m_brush);
|
SetBrush(m_brush);
|
||||||
|
@@ -21,12 +21,11 @@ wxIMPLEMENT_ABSTRACT_CLASS(wxScreenDCImpl, wxWindowDCImpl);
|
|||||||
wxScreenDCImpl::wxScreenDCImpl( wxScreenDC *owner )
|
wxScreenDCImpl::wxScreenDCImpl( wxScreenDC *owner )
|
||||||
: wxWindowDCImpl( owner )
|
: wxWindowDCImpl( owner )
|
||||||
{
|
{
|
||||||
m_qtImage = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wxScreenDCImpl::~wxScreenDCImpl( )
|
wxScreenDCImpl::~wxScreenDCImpl( )
|
||||||
{
|
{
|
||||||
delete m_qtImage;
|
delete m_qtPixmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxScreenDCImpl::DoGetSize(int *width, int *height) const
|
void wxScreenDCImpl::DoGetSize(int *width, int *height) const
|
||||||
@@ -34,19 +33,10 @@ void wxScreenDCImpl::DoGetSize(int *width, int *height) const
|
|||||||
wxDisplaySize(width, height);
|
wxDisplaySize(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxScreenDCImpl::DoGetPixel(wxCoord x, wxCoord y, wxColour *col) const
|
|
||||||
{
|
|
||||||
// const_cast<wxScreenDCImpl*>(this)->GetQImage();
|
|
||||||
// return wxQtDCImpl::DoGetPixel(x, y, col);
|
|
||||||
x = y = 0;
|
|
||||||
col = 0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// defered allocation for blit
|
// defered allocation for blit
|
||||||
QImage *wxScreenDCImpl::GetQImage()
|
QPixmap *wxScreenDCImpl::GetQPixmap()
|
||||||
{
|
{
|
||||||
if ( !m_qtImage )
|
if ( !m_qtPixmap )
|
||||||
m_qtImage = new QImage(QApplication::primaryScreen()->grabWindow(QApplication::desktop()->winId()).toImage());
|
m_qtPixmap = new QPixmap(QApplication::primaryScreen()->grabWindow(QApplication::desktop()->winId()));
|
||||||
return m_qtImage;
|
return m_qtPixmap;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user