From 880d870ea4133fc81dff875d54d14f1e9bb0268f Mon Sep 17 00:00:00 2001 From: Robert Roebling Date: Tue, 28 Nov 2000 21:01:20 +0000 Subject: [PATCH] Speed-up for wxCanvasImage. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@8858 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- contrib/include/wx/canvas/canvas.h | 10 ++- contrib/samples/canvas/simple/simple.cpp | 27 +++++--- contrib/samples/canvas/simple/simple.h | 4 ++ contrib/src/canvas/canvas.cpp | 80 ++++++++++++++---------- 4 files changed, 79 insertions(+), 42 deletions(-) diff --git a/contrib/include/wx/canvas/canvas.h b/contrib/include/wx/canvas/canvas.h index c3c1fe81c6..f0a08a707a 100644 --- a/contrib/include/wx/canvas/canvas.h +++ b/contrib/include/wx/canvas/canvas.h @@ -490,7 +490,7 @@ public: double GetPosX() { return m_x; } double GetPosY() { return m_y; } - void SetPosXY( double x, double y) {m_x=x; m_y=y;CalcBoundingBox(); }; + void SetPosXY( double x, double y); void TransLate( double x, double y ); @@ -507,7 +507,13 @@ private: wxImage m_image; int m_orgw,m_orgh; - wxImage m_tmp; + + // cache + wxBitmap m_cBitmap; + wxImage m_cImage; + int m_cW; + int m_cH; + double m_cR; }; //---------------------------------------------------------------------------- diff --git a/contrib/samples/canvas/simple/simple.cpp b/contrib/samples/canvas/simple/simple.cpp index 26390ed9cb..bc1516c41e 100644 --- a/contrib/samples/canvas/simple/simple.cpp +++ b/contrib/samples/canvas/simple/simple.cpp @@ -38,6 +38,7 @@ BEGIN_EVENT_TABLE(MyFrame,wxFrame) EVT_MENU(ID_QUIT, MyFrame::OnQuit) EVT_CLOSE(MyFrame::OnCloseWindow) + EVT_TIMER(-1, MyFrame::OnTimer) END_EVENT_TABLE() MyFrame::MyFrame( wxWindow *parent, wxWindowID id, const wxString &title, @@ -75,11 +76,10 @@ MyFrame::MyFrame( wxWindow *parent, wxWindowID id, const wxString &title, m_smile1 = new wxCanvasImage( image, 0,70,32,32 ); root->Append( m_smile1 ); - wxCanvasRect *rect = new wxCanvasRect( 20,20,100,100 ); - rect->SetBrush( *wxRED_BRUSH ); - root->Append( rect ); + wxCanvasCircle *circ = new wxCanvasCircle( 170,70,50 ); + circ->SetBrush( *wxBLUE_BRUSH ); + root->Append( circ ); -/* int i; for (i = 10; i < 300; i+=10) { @@ -87,19 +87,16 @@ MyFrame::MyFrame( wxWindow *parent, wxWindowID id, const wxString &title, r->SetBrush( *wxRED_BRUSH ); root->Append( r ); } -*/ m_smile2 = new wxCanvasImage( image, 0,110,32,32 ); root->Append( m_smile2 ); -/* for (i = 15; i < 300; i+=10) { wxCanvasRect *r = new wxCanvasRect( i,50,3,140 ); r->SetBrush( *wxRED_BRUSH ); root->Append( r ); } -*/ // This will call all object and children recursivly so // all know what their wxCanvasAdmin is. Call at the end. @@ -107,6 +104,14 @@ MyFrame::MyFrame( wxWindow *parent, wxWindowID id, const wxString &title, // One object group is the root object. canvas->SetRoot( root ); + + m_timer = new wxTimer( this ); + m_timer->Start( 80, FALSE ); +} + +MyFrame::~MyFrame() +{ + delete m_timer; } void MyFrame::CreateMyMenuBar() @@ -134,6 +139,14 @@ void MyFrame::OnCloseWindow( wxCloseEvent &event ) Destroy(); } +void MyFrame::OnTimer( wxTimerEvent &event ) +{ + m_smile1->MoveRelative( 1, 0); + m_smile2->MoveRelative( 1, 0); + + wxWakeUpIdle(); +} + //------------------------------------------------------------------------------ // MyApp //------------------------------------------------------------------------------ diff --git a/contrib/samples/canvas/simple/simple.h b/contrib/samples/canvas/simple/simple.h index ab9e6ffb5c..eadf3f741b 100644 --- a/contrib/samples/canvas/simple/simple.h +++ b/contrib/samples/canvas/simple/simple.h @@ -19,6 +19,7 @@ #endif #include "wx/canvas/canvas.h" +#include "wx/timer.h" //---------------------------------------------------------------------------- // constants @@ -40,6 +41,7 @@ public: const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_FRAME_STYLE ); + ~MyFrame(); private: // WDR: method declarations for MyFrame @@ -50,11 +52,13 @@ private: wxCanvasImage *m_smile1; wxCanvasImage *m_smile2; wxCanvasAdmin *m_admin; + wxTimer *m_timer; private: // WDR: handler declarations for MyFrame void OnQuit( wxCommandEvent &event ); void OnCloseWindow( wxCloseEvent &event ); + void OnTimer( wxTimerEvent &event ); private: DECLARE_EVENT_TABLE() diff --git a/contrib/src/canvas/canvas.cpp b/contrib/src/canvas/canvas.cpp index bb33ecd1ba..55cb94d21a 100644 --- a/contrib/src/canvas/canvas.cpp +++ b/contrib/src/canvas/canvas.cpp @@ -676,7 +676,7 @@ wxCanvasObject* wxCanvasObjectGroup::IsHitWorld( double x, double y, double marg if (!obj->IsControl() ) { - if (obj->IsHitWorld(x,y,margin)) + if (obj->IsHitWorld(xh,yh,margin)) { return obj; } @@ -1321,6 +1321,13 @@ wxCanvasImage::wxCanvasImage( const wxImage &image, double x, double y, double w CalcBoundingBox(); } +void wxCanvasImage::SetPosXY( double x, double y) +{ + m_x = x; + m_y = y; + CalcBoundingBox(); +} + void wxCanvasImage::TransLate( double x, double y ) { m_x += x; @@ -1337,7 +1344,7 @@ void wxCanvasImage::CalcBoundingBox() void wxCanvasImage::Render(wxTransformMatrix* cworld, int clip_x, int clip_y, int clip_width, int clip_height ) { if (!m_visible) return; - + wxRect tmparea; tmparea.x = m_admin->LogicalToDeviceXRel( m_bbox.GetMinX()); @@ -1352,6 +1359,7 @@ void wxCanvasImage::Render(wxTransformMatrix* cworld, int clip_x, int clip_y, in y = m_admin->LogicalToDeviceY(y); + // What is this??? if ( m_orgw*5 < m_admin->LogicalToDeviceXRel( m_bbox.GetWidth() ) || m_orgw/5 > m_admin->LogicalToDeviceXRel( m_bbox.GetWidth() ) || m_orgh*5 < m_admin->LogicalToDeviceYRel( m_bbox.GetHeight() ) || @@ -1375,29 +1383,54 @@ void wxCanvasImage::Render(wxTransformMatrix* cworld, int clip_x, int clip_y, in dc->DestroyClippingRegion(); return; } + + wxImage tmp; + bool is_cashed = FALSE; - if ((m_admin->LogicalToDeviceXRel( m_bbox.GetWidth() ) == m_image.GetWidth()) && - (m_admin->LogicalToDeviceYRel( m_bbox.GetHeight() ) == m_image.GetHeight())) + if (m_cImage.Ok() && (m_cW == m_bbox.GetWidth()) && (m_cH == m_bbox.GetHeight())) { - m_tmp = m_image; + // use cached image + tmp = m_cImage; + is_cashed = TRUE; } else { - m_tmp = m_image.Scale( m_admin->LogicalToDeviceXRel( m_bbox.GetWidth()), - m_admin->LogicalToDeviceYRel( m_bbox.GetHeight()) ); + if ((m_admin->LogicalToDeviceXRel( m_bbox.GetWidth() ) == m_image.GetWidth()) && + (m_admin->LogicalToDeviceYRel( m_bbox.GetHeight() ) == m_image.GetHeight())) + { + tmp = m_image; + } + else + { + tmp = m_image.Scale( m_admin->LogicalToDeviceXRel( m_bbox.GetWidth()), + m_admin->LogicalToDeviceYRel( m_bbox.GetHeight()) ); + } + + // create cached image + m_cImage = tmp; + m_cW = tmp.GetWidth(); + m_cH = tmp.GetHeight(); } - wxBitmap bmp; // wxPoint centr(m_admin->LogicalToDeviceX(m_x),m_admin->LogicalToDeviceY(m_y)); wxPoint centr(0,0); - if (cworld->GetRotation()) + wxBitmap bmp; + + if (m_cBitmap.Ok() && is_cashed && (m_cR == cworld->GetRotation())) { - bmp=m_tmp.Rotate(-cworld->GetRotation()/180.0 * pi,centr, TRUE, NULL).ConvertToBitmap(); + bmp = m_cBitmap; } else { - bmp = m_tmp.ConvertToBitmap(); + if (cworld->GetRotation()) + tmp = tmp.Rotate(-cworld->GetRotation()/180.0 * pi, centr, TRUE, NULL ); + + bmp = tmp.ConvertToBitmap(); + + // create cached bitmap + m_cBitmap = bmp; + m_cR = cworld->GetRotation(); } wxDC *dc = m_admin->GetActive()->GetDC(); @@ -1423,28 +1456,9 @@ void wxCanvasImage::Render(wxTransformMatrix* cworld, int clip_x, int clip_y, in } else { - //TODO clipping not right -// dc->DrawPoint(centr2); -// dc->DrawPoint(x,y); - - if ((clip_x == x) && - (clip_y == y) && - (clip_width == tmparea.width) && - (clip_height == tmparea.height)) - { - dc->DrawBitmap( m_tmp, clip_x, clip_y, TRUE ); - } - else - { - int start_x = clip_x - (int)x; - int start_y = clip_y - (int)y; - - //dc->DrawBitmap( bmp, x, y, TRUE ); - wxMemoryDC dcm; - dcm.SelectObject(bmp); - dc->Blit(clip_x, clip_y,clip_width, clip_height,&dcm,start_x,start_y,wxCOPY,TRUE); - dcm.SelectObject(wxNullBitmap); - } + dc->SetClippingRegion( clip_x, clip_y, clip_width, clip_height ); + dc->DrawBitmap( bmp, x, y, TRUE ); + dc->DestroyClippingRegion(); } } -- 2.45.2