First shot at wxBitmap based wxCanvas.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@8346 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robert Roebling
2000-09-13 08:04:28 +00:00
parent bdb310a720
commit 33ebcd800c
3 changed files with 162 additions and 46 deletions

View File

@@ -20,9 +20,13 @@
#include "wx/image.h"
#include "wx/txtstrm.h"
class wxCanvas;
//----------------------------------------------------------------------------
// decls
//----------------------------------------------------------------------------
// WDR: class declarations
#define IMAGE_CANVAS 0
class wxCanvas;
//----------------------------------------------------------------------------
// wxCanvasObject
@@ -241,7 +245,11 @@ private:
double m_height;
wxImage m_image;
#if IMAGE_CANVAS
wxImage m_tmp;
#else
wxBitmap m_tmp;
#endif
};
//----------------------------------------------------------------------------
@@ -331,7 +339,12 @@ public:
// ... and call this to tell all objets to recreate then
virtual void Recreate();
#if IMAGE_CANVAS
inline wxImage *GetBuffer() { return &m_buffer; }
#else
inline wxBitmap *GetBuffer() { return &m_buffer; }
inline wxMemoryDC *GetDC() { return m_renderDC; }
#endif
inline int GetBufferX() { return m_bufferX; }
inline int GetBufferY() { return m_bufferY; }
inline int GetBufferWidth() { return m_buffer.GetWidth(); }
@@ -348,7 +361,12 @@ public:
const wxRect* rect = (wxRect *) NULL );
private:
#if IMAGE_CANVAS
wxImage m_buffer;
#else
wxBitmap m_buffer;
wxMemoryDC *m_renderDC;
#endif
int m_bufferX;
int m_bufferY;
bool m_needUpdate;
@@ -357,7 +375,6 @@ private:
unsigned char m_green,m_red,m_blue;
bool m_frozen;
bool m_requestNewBuffer;
wxCanvasObject *m_lastMouse;
wxCanvasObject *m_captureMouse;

View File

@@ -209,7 +209,7 @@ MyFrame::MyFrame()
wxBitmap bitmap( smile_xpm );
wxImage image( bitmap );
m_sm1 = new wxCanvasImage( image, 0,70,16,16 );
m_sm1 = new wxCanvasImage( image, 0,70,32,32 );
m_canvas->Append( m_sm1 );
int i;
@@ -241,13 +241,13 @@ MyFrame::MyFrame()
// m_canvas->Append( new wxCanvasLine( 10,-1500e6,50,300000e6, 0,255,0 ) );
// m_canvas->Append( new wxCanvasLine( 10,-150000,50,300000, 0,255,0 ) );
/*
//make a group of wxCanvasObjects
wxCanvasObjectGroup* group1 = new wxCanvasObjectGroup();
group1->Prepend( new wxCanvasLine( 10,-35,50,190,100,255,0 ) );
group1->Prepend( new wxCanvasImage( image, 4,38,32,32 ) );
group1->Prepend( new wxCanvasRect(20,-20,50,170,0,20,240 ) );
//make another group of wxCanvasObjects
wxCanvasObjectGroup* group2 = new wxCanvasObjectGroup();
group2->Prepend( new wxCanvasImage( image, 60,38,52,32 ) );
@@ -258,13 +258,12 @@ MyFrame::MyFrame()
group1->Prepend( m_subref );
//now make two refrences to group1 into root group of the canvas
/*
m_ref = new MywxCanvasObjectGroupRef(40,200, group1);
m_canvas->Prepend( m_ref );
*/
m_ref2 = new MywxCanvasObjectGroupRef(80,350, group1);
m_canvas->Prepend( m_ref2 );
*/
m_log = new wxTextCtrl( this, -1, "", wxPoint(0,0), wxSize(100,100), wxTE_MULTILINE );
wxLog *old_log = wxLog::SetActiveTarget( new wxLogTextCtrl( m_log ) );

View File

@@ -284,12 +284,12 @@ bool wxCanvasObjectGroup::IsHit( int x, int y, int margin )
{
if (obj->IsHit(x,y,margin))
{
return true;
return TRUE;
}
}
node = node->Previous();
}
return false;
return FALSE;
}
wxCanvasObject* wxCanvasObjectGroup::IsHitObject( int x, int y, int margin )
@@ -322,7 +322,7 @@ wxCanvasObjectGroupRef::wxCanvasObjectGroupRef(double x, double y, wxCanvasObjec
{
m_x = x;
m_y = y;
m_validbounds=false;
m_validbounds = FALSE;
m_group = group;
}
@@ -343,19 +343,18 @@ void wxCanvasObjectGroupRef::ExtendArea(int x, int y)
}
else
{
m_validbounds = true;
m_validbounds = TRUE;
m_minx = x;
m_miny = y;
m_maxx = x;
m_maxy = y;
}
}
void wxCanvasObjectGroupRef::Recreate()
{
m_validbounds=false;
m_validbounds = FALSE;
m_group->Recreate();
ExtendArea(m_group->GetXMin(),m_group->GetYMin());
ExtendArea(m_group->GetXMax(),m_group->GetYMax());
@@ -467,10 +466,12 @@ void wxCanvasRect::Recreate()
void wxCanvasRect::Render(int xabs, int yabs, int clip_x, int clip_y, int clip_width, int clip_height )
{
wxImage *image = m_owner->GetBuffer();
int buffer_x = m_owner->GetBufferX();
int buffer_y = m_owner->GetBufferY();
#if IMAGE_CANVAS
wxImage *image = m_owner->GetBuffer();
int start_y = clip_y - buffer_y;
int end_y = clip_y+clip_height - buffer_y;
@@ -481,6 +482,14 @@ void wxCanvasRect::Render(int xabs, int yabs, int clip_x, int clip_y, int clip_w
for (int y = start_y; y < end_y; y++)
for (int x = start_x; x < end_x; x++)
image->SetRGB( x, y, m_red, m_green, m_blue );
#else
wxMemoryDC *dc = m_owner->GetDC();
dc->SetPen( *wxTRANSPARENT_PEN );
wxBrush brush( wxColour( m_red,m_green,m_blue), wxSOLID );
dc->SetBrush( brush );
dc->DrawRectangle( clip_x-buffer_x, clip_y-buffer_y, clip_width, clip_height );
#endif
}
void wxCanvasRect::WriteSVG( wxTextOutputStream &stream )
@@ -528,21 +537,22 @@ void wxCanvasLine::Recreate()
void wxCanvasLine::Render(int xabs, int yabs, int clip_x, int clip_y, int clip_width, int clip_height )
{
wxImage *image = m_owner->GetBuffer();
int buffer_x = m_owner->GetBufferX();
int buffer_y = m_owner->GetBufferY();
int x1 = xabs + m_owner->GetDeviceX( m_x1 );
int y1 = yabs + m_owner->GetDeviceY( m_y1 );
int x2 = xabs + m_owner->GetDeviceX( m_x2 );
int y2 = yabs + m_owner->GetDeviceY( m_y2 );
#if IMAGE_CANVAS
wxImage *image = m_owner->GetBuffer();
if ((m_area.width == 0) && (m_area.height == 0))
{
image->SetRGB( m_area.x-buffer_x, m_area.y-buffer_y, m_red, m_green, m_blue );
}
else
{
int x1 = xabs + m_owner->GetDeviceX( m_x1 );
int y1 = yabs + m_owner->GetDeviceY( m_y1 );
int x2 = xabs + m_owner->GetDeviceX( m_x2 );
int y2 = yabs + m_owner->GetDeviceY( m_y2 );
wxInt32 d, ii, jj, di, ai, si, dj, aj, sj;
di = x1 - x2;
ai = abs(di) << 1;
@@ -597,6 +607,16 @@ void wxCanvasLine::Render(int xabs, int yabs, int clip_x, int clip_y, int clip_w
}
}
}
#else
wxMemoryDC *dc = m_owner->GetDC();
dc->SetClippingRegion( clip_x-buffer_x, clip_y-buffer_y, clip_width, clip_height );
wxPen pen( wxColour(m_red,m_green,m_blue), 0, wxSOLID );
dc->SetPen( pen );
dc->DrawLine( x1-buffer_x, y1-buffer_y, x2-buffer_x, y2-buffer_y );
dc->DestroyClippingRegion();
#endif
}
void wxCanvasLine::WriteSVG( wxTextOutputStream &stream )
@@ -627,18 +647,36 @@ void wxCanvasImage::Recreate()
m_owner->GetDeviceWidth( m_width ),
m_owner->GetDeviceHeight( m_height ) );
#if IMAGE_CANVAS
if ((m_area.width == m_image.GetWidth()) &&
(m_area.width == m_image.GetWidth()))
{
m_tmp = m_image;
}
else
{
m_tmp = m_image.Scale( m_area.width, m_area.height );
}
#else
if ((m_area.width == m_image.GetWidth()) &&
(m_area.width == m_image.GetWidth()))
{
m_tmp = m_image.ConvertToBitmap();
}
else
{
wxImage tmp( m_image.Scale( m_area.width, m_area.height ) );
m_tmp = tmp.ConvertToBitmap();
}
#endif
}
void wxCanvasImage::Render(int xabs, int yabs, int clip_x, int clip_y, int clip_width, int clip_height )
{
int buffer_x = m_owner->GetBufferX();
int buffer_y = m_owner->GetBufferY();
#if IMAGE_CANVAS
if ((clip_x == xabs + m_area.x) &&
(clip_y == yabs + m_area.y) &&
(clip_width == m_area.width) &&
@@ -656,6 +694,28 @@ void wxCanvasImage::Render(int xabs, int yabs, int clip_x, int clip_y, int clip_
wxImage sub_image( m_tmp.GetSubImage( rect ) );
m_owner->GetBuffer()->Paste( sub_image, clip_x-buffer_x, clip_y-buffer_y );
}
#else
wxMemoryDC *dc = m_owner->GetDC();
if ((clip_x == xabs + m_area.x) &&
(clip_y == yabs + m_area.y) &&
(clip_width == m_area.width) &&
(clip_height == m_area.height))
{
dc->DrawBitmap( m_tmp, clip_x-buffer_x, clip_y-buffer_y, TRUE );
}
else
{
// local coordinates
int start_x = clip_x - (xabs + m_area.x);
int start_y = clip_y - (yabs + m_area.y);
// Clipping region faster ?
wxRect rect( start_x, start_y, clip_width, clip_height );
wxBitmap sub_bitmap( m_tmp.GetSubBitmap( rect ) );
dc->DrawBitmap( sub_bitmap, clip_x-buffer_x, clip_y-buffer_y, TRUE );
}
#endif
}
void wxCanvasImage::WriteSVG( wxTextOutputStream &stream )
@@ -763,6 +823,7 @@ void wxCanvasText::Render(int xabs, int yabs, int clip_x, int clip_y, int clip_w
{
if (!m_alpha) return;
#if IMAGE_CANVAS
wxImage *image = m_owner->GetBuffer();
int buffer_x = m_owner->GetBufferX();
int buffer_y = m_owner->GetBufferY();
@@ -801,6 +862,7 @@ void wxCanvasText::Render(int xabs, int yabs, int clip_x, int clip_y, int clip_w
image->SetRGB( image_x, image_y, red1+red2, green1+green2, blue1+blue2 );
}
}
#endif
}
void wxCanvasText::WriteSVG( wxTextOutputStream &stream )
@@ -884,7 +946,6 @@ wxCanvas::wxCanvas( wxWindow *parent, wxWindowID id,
m_lastMouse = (wxCanvasObject*)NULL;
m_captureMouse = (wxCanvasObject*)NULL;
m_frozen = TRUE;
m_requestNewBuffer = TRUE;
//root group always at 0,0
m_root = new wxCanvasObjectGroup();
@@ -919,6 +980,7 @@ void wxCanvas::SetColour( unsigned char red, unsigned char green, unsigned char
if (m_frozen) return;
#if IMAGE_CANVAS
unsigned char *data = m_buffer.GetData();
for (int y = 0; y < m_buffer.GetHeight(); y++)
@@ -931,6 +993,15 @@ void wxCanvas::SetColour( unsigned char red, unsigned char green, unsigned char
data[0] = blue;
data++;
}
#else
wxMemoryDC dc;
dc.SelectObject( m_buffer );
dc.SetPen( *wxTRANSPARENT_PEN );
wxBrush brush( wxColour( red,green,blue), wxSOLID );
dc.SetBrush( brush );
dc.DrawRectangle( 0, 0, m_buffer.GetWidth(), m_buffer.GetHeight() );
dc.SelectObject( wxNullBitmap );
#endif
}
void wxCanvas::SetCaptureMouse( wxCanvasObject *obj )
@@ -979,26 +1050,26 @@ void wxCanvas::Update( int x, int y, int width, int height, bool blit )
width -= m_bufferX-x;
x = m_bufferX;
}
if (width < 0) return;
if (width <= 0) return;
if (y < m_bufferY)
{
height -= m_bufferY-y;
y = m_bufferY;
}
if (height < 0) return;
if (height <= 0) return;
if (x+width > m_bufferX+m_buffer.GetWidth())
{
width = m_bufferX+m_buffer.GetWidth() - x;
}
if (width < 0) return;
if (width <= 0) return;
if (y+height > m_bufferY+m_buffer.GetHeight())
{
height = m_bufferY+m_buffer.GetHeight() - y;
}
if (height < 0) return;
if (height <= 0) return;
// update is within the buffer
m_needUpdate = TRUE;
@@ -1010,6 +1081,7 @@ void wxCanvas::Update( int x, int y, int width, int height, bool blit )
(wxObject*) new wxRect( x,y,width,height ) );
}
#if IMAGE_CANVAS
// speed up with direct access, maybe add wxImage::Clear(x,y,w,h,r,g,b)
int start_y = y - m_bufferY;
int end_y = y+height - m_bufferY;
@@ -1020,7 +1092,19 @@ void wxCanvas::Update( int x, int y, int width, int height, bool blit )
m_buffer.SetRGB( xx, yy, m_red, m_green, m_blue );
m_root->Render(0,0, x, y, width, height );
#else
wxMemoryDC dc;
dc.SelectObject( m_buffer );
dc.SetPen( *wxTRANSPARENT_PEN );
wxBrush brush( wxColour( m_red,m_green,m_blue), wxSOLID );
dc.SetBrush( brush );
dc.DrawRectangle( x-m_bufferX, y-m_bufferY, width, height );
m_renderDC = &dc;
m_root->Render(0,0, x, y, width, height );
dc.SelectObject( wxNullBitmap );
#endif
}
void wxCanvas::BlitBuffer( wxDC &dc )
@@ -1034,8 +1118,9 @@ void wxCanvas::BlitBuffer( wxDC &dc )
sub_rect.x -= m_bufferX;
sub_rect.y -= m_bufferY;
wxImage sub_image( m_buffer.GetSubImage( sub_rect ) );
#if IMAGE_CANVAS
wxImage sub_image( m_buffer.GetSubImage( sub_rect ) );
#ifdef __WXGTK__
int bpp = wxDisplayDepth();
if (bpp > 8)
@@ -1062,13 +1147,19 @@ void wxCanvas::BlitBuffer( wxDC &dc )
wxBitmap bitmap( sub_image.ConvertToBitmap() );
dc.DrawBitmap( bitmap, rect->x, rect->y );
}
#endif
#ifndef __WXGTK__
#else
wxBitmap bitmap( sub_image.ConvertToBitmap() );
dc.DrawBitmap( bitmap, rect->x, rect->y );
#endif
#else // IMAGE_CANVAS
// Maybe clipping use SetClipping() is faster than
// getting the subrect first and drawing it then?
wxBitmap sub_bitmap( m_buffer.GetSubBitmap( sub_rect ) );
dc.DrawBitmap( sub_bitmap, rect->x, rect->y );
#endif
delete rect;
m_updateRects.DeleteNode( node );
node = m_updateRects.First();
@@ -1208,6 +1299,7 @@ void wxCanvas::ScrollWindow( int dx, int dy, const wxRect* rect )
// client area. Indeed, it is the client area.
CalcUnscrolledPosition( 0, 0, &m_bufferX, &m_bufferY );
#if IMAGE_CANVAS
unsigned char* data = m_buffer.GetData();
if (dy != 0)
@@ -1271,6 +1363,10 @@ void wxCanvas::ScrollWindow( int dx, int dy, const wxRect* rect )
Update( m_bufferX+m_buffer.GetWidth()+dx, m_bufferY, -dx, m_buffer.GetHeight(), FALSE );
}
}
#else
// Update everything, TODO: scrolling
Update( m_bufferX, m_bufferY, m_buffer.GetWidth(), m_buffer.GetHeight(), FALSE );
#endif
wxWindow::ScrollWindow( dx, dy, rect );
}
@@ -1408,7 +1504,11 @@ void wxCanvas::OnSize(wxSizeEvent &event)
{
int w,h;
GetClientSize( &w, &h );
#if IMAGE_CANVAS
m_buffer = wxImage( w, h );
#else
m_buffer = wxBitmap( w, h );
#endif
CalcUnscrolledPosition( 0, 0, &m_bufferX, &m_bufferY );