X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/872f1044c8f086bc983bf7fbb1fb5a467365039d..83b968da1a1e9c8b4e3965093629a6164a301378:/contrib/src/canvas/canvas.cpp diff --git a/contrib/src/canvas/canvas.cpp b/contrib/src/canvas/canvas.cpp index f2284c9ed7..1be997526a 100644 --- a/contrib/src/canvas/canvas.cpp +++ b/contrib/src/canvas/canvas.cpp @@ -77,7 +77,7 @@ void wxCanvasObject::Move( int x, int y ) { int old_x = m_area.x; int old_y = m_area.y; - + m_area.x = x; m_area.y = y; @@ -153,7 +153,7 @@ void wxCanvasObjectGroup::SetOwner(wxCanvas* canvas) } } -void wxCanvasObjectGroup::ExtendArea(int x, int y) +void wxCanvasObjectGroup::ExtendArea(double x, double y) { if (m_validbounds) { @@ -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 ) @@ -309,7 +309,7 @@ wxCanvasObject* wxCanvasObjectGroup::IsHitObject( int x, int y, int margin ) } node = node->Previous(); } - + return (wxCanvasObject*) NULL; } @@ -322,40 +322,39 @@ wxCanvasObjectGroupRef::wxCanvasObjectGroupRef(double x, double y, wxCanvasObjec { m_x = x; m_y = y; - m_validbounds=false; - m_group=group; + m_validbounds = FALSE; + m_group = group; } void wxCanvasObjectGroupRef::SetOwner(wxCanvas* canvas) { - m_owner=canvas; + m_owner = canvas; m_group->SetOwner(canvas); } -void wxCanvasObjectGroupRef::ExtendArea(int x, int y) +void wxCanvasObjectGroupRef::ExtendArea(double x, double y) { - if (m_validbounds) - { - if ( x < m_minx ) m_minx = x; - if ( y < m_miny ) m_miny = y; - if ( x > m_maxx ) m_maxx = x; - if ( y > m_maxy ) m_maxy = y; - } - else - { - m_validbounds = true; - - m_minx = x; - m_miny = y; - m_maxx = x; - m_maxy = y; - } + if (m_validbounds) + { + if (x < m_minx) m_minx = x; + if (y < m_miny) m_miny = y; + if (x > m_maxx) m_maxx = x; + if (y > m_maxy) m_maxy = y; + } + else + { + 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()); @@ -369,8 +368,8 @@ void wxCanvasObjectGroupRef::Recreate() void wxCanvasObjectGroupRef::Render(int xabs, int yabs, int x, int y, int width, int height ) { - xabs += m_owner->GetDeviceX(GetPosX()); - yabs += m_owner->GetDeviceY(GetPosY()); + xabs += m_area.x; + yabs += m_area.y; int clip_x = xabs + m_group->GetXMin(); int clip_width = m_group->GetXMax()-m_group->GetXMin(); @@ -424,27 +423,223 @@ void wxCanvasObjectGroupRef::Move( int x, int y ) m_x = x; m_y = y; - if (!m_isControl) + int old_area_x = m_area.x; + int old_area_y = m_area.y; + + m_area.x=m_owner->GetDeviceX( m_x + m_minx ); + m_area.y=m_owner->GetDeviceY( m_y + m_miny ); + + int leftu,rightu,bottomu,topu ; + leftu = wxMin (m_area.x, old_area_x ) ; + rightu = wxMax (old_area_x + m_area.width, m_area.x + m_area.width) ; + topu = wxMin (m_area.y,old_area_y) ; + bottomu = wxMax (old_area_y + m_area.height, m_area.y + m_area.height) ; + + if ( rightu - leftu < 2*m_area.width && bottomu - topu < 2*m_area.height ) { - // TODO: sometimes faster to merge into 1 Update or - // to break up into four - m_owner->Update(m_area.x, m_area.y, m_area.width, m_area.height ); - //calculate the new area in pixels relative to the parent - SetArea( m_owner->GetDeviceX( m_x + m_minx ), - m_owner->GetDeviceY( m_y + m_miny ), - m_owner->GetDeviceWidth( m_maxx-m_minx ), - m_owner->GetDeviceHeight( m_maxy-m_miny ) ); + m_owner->Update(leftu,topu,rightu - leftu,bottomu - topu); + } + else + { + m_owner->Update(old_area_x, old_area_y, m_area.width, m_area.height ); m_owner->Update( m_area.x, m_area.y, m_area.width, m_area.height ); } } +//---------------------------------------------------------------------------- +// wxCanvasPolyline +//---------------------------------------------------------------------------- + +wxCanvasPolyline::wxCanvasPolyline( int n, wxPoint2DDouble points[]) + : wxCanvasObject() +{ + m_n = n; + m_points = points; + m_pen = *wxBLACK_PEN; +} + +wxCanvasPolyline::~wxCanvasPolyline() +{ + delete m_points; +} + +void wxCanvasPolyline::ExtendArea(double x, double y) +{ + if (m_validbounds) + { + if (x < m_minx) m_minx = x; + if (y < m_miny) m_miny = y; + if (x > m_maxx) m_maxx = x; + if (y > m_maxy) m_maxy = y; + } + else + { + m_validbounds = TRUE; + + m_minx = x; + m_miny = y; + m_maxx = x; + m_maxy = y; + } +} + +void wxCanvasPolyline::Recreate() +{ + + m_validbounds=FALSE; + int i; + for (i=0; i < m_n;i++) + { + ExtendArea(m_points[i].m_x,m_points[i].m_y); + } + + //include the pen width also + ExtendArea(m_minx -m_pen.GetWidth(),m_miny-m_pen.GetWidth()); + ExtendArea(m_maxx+m_pen.GetWidth()*2,m_maxy+m_pen.GetWidth()*2); + + //set the area in pixels relative to the parent + SetArea( m_owner->GetDeviceX(m_minx ), + m_owner->GetDeviceY(m_miny ), + m_owner->GetDeviceWidth( m_maxx-m_minx ), + m_owner->GetDeviceHeight( m_maxy-m_miny ) ); +} + +void wxCanvasPolyline::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(); + + int start_y = clip_y - buffer_y; + int end_y = clip_y+clip_height - buffer_y; + + int start_x = clip_x - buffer_x; + int end_x = clip_x+clip_width - buffer_x; + +#if IMAGE_CANVAS +#else + wxPoint *cpoints = new wxPoint[m_n]; + int i; + for (i = 0; i < m_n; i++) + { + cpoints[i].x = m_owner->GetDeviceX(m_points[i].m_x+xabs); + cpoints[i].y = m_owner->GetDeviceY(m_points[i].m_y+yabs); + } + wxMemoryDC *dc = m_owner->GetDC(); + dc->SetClippingRegion(start_x,start_y,end_x-start_x,end_y-start_y); + dc->SetPen(m_pen); + dc->DrawLines(m_n, cpoints, 0,0); + delete [] cpoints; + dc->SetPen(wxNullPen); + dc->DestroyClippingRegion(); +#endif +} + +void wxCanvasPolyline::WriteSVG( wxTextOutputStream &stream ) +{ +} + +//---------------------------------------------------------------------------- +// wxCanvasPolygon +//---------------------------------------------------------------------------- + +wxCanvasPolygon::wxCanvasPolygon( int n, wxPoint2DDouble points[]) + : wxCanvasObject() +{ + m_n = n; + m_points = points; + m_brush = *wxBLACK_BRUSH; + m_pen = *wxTRANSPARENT_PEN; +} + +wxCanvasPolygon::~wxCanvasPolygon() +{ + delete m_points; +} + +void wxCanvasPolygon::ExtendArea(double x, double y) +{ + if (m_validbounds) + { + if (x < m_minx) m_minx = x; + if (y < m_miny) m_miny = y; + if (x > m_maxx) m_maxx = x; + if (y > m_maxy) m_maxy = y; + } + else + { + m_validbounds = TRUE; + + m_minx = x; + m_miny = y; + m_maxx = x; + m_maxy = y; + } +} + +void wxCanvasPolygon::Recreate() +{ + + m_validbounds=FALSE; + int i; + for (i=0; i < m_n;i++) + { + ExtendArea(m_points[i].m_x,m_points[i].m_y); + } + + //include the pen width also + ExtendArea(m_minx -m_pen.GetWidth(),m_miny-m_pen.GetWidth()); + ExtendArea(m_maxx+m_pen.GetWidth()*2,m_maxy+m_pen.GetWidth()*2); + + //set the area in pixels relative to the parent + SetArea( m_owner->GetDeviceX( m_minx ), + m_owner->GetDeviceY( m_miny ), + m_owner->GetDeviceWidth( m_maxx-m_minx ), + m_owner->GetDeviceHeight( m_maxy-m_miny ) ); +} + +void wxCanvasPolygon::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(); + + int start_y = clip_y - buffer_y; + int end_y = clip_y+clip_height - buffer_y; + + int start_x = clip_x - buffer_x; + int end_x = clip_x+clip_width - buffer_x; + +#if IMAGE_CANVAS +#else + wxPoint *cpoints = new wxPoint[m_n]; + int i; + for (i = 0; i < m_n; i++) + { + cpoints[i].x = m_owner->GetDeviceX(m_points[i].m_x+xabs); + cpoints[i].y = m_owner->GetDeviceY(m_points[i].m_y+yabs); + } + wxMemoryDC *dc = m_owner->GetDC(); + dc->SetClippingRegion(start_x,start_y,end_x-start_x,end_y-start_y); + dc->SetBrush(m_brush); + dc->SetPen(m_pen); + dc->DrawPolygon(m_n, cpoints, 0,0,wxWINDING_RULE); + delete [] cpoints; + dc->SetBrush(wxNullBrush); + dc->SetPen(wxNullPen); + dc->DestroyClippingRegion(); +#endif +} + +void wxCanvasPolygon::WriteSVG( wxTextOutputStream &stream ) +{ +} + + //---------------------------------------------------------------------------- // wxCanvasRect //---------------------------------------------------------------------------- -wxCanvasRect::wxCanvasRect( double x, double y, double w, double h, - unsigned char red, unsigned char green, unsigned char blue ) +wxCanvasRect::wxCanvasRect( double x, double y, double w, double h ) : wxCanvasObject() { m_x = x; @@ -452,9 +647,8 @@ wxCanvasRect::wxCanvasRect( double x, double y, double w, double h, m_width = w; m_height = h; - m_red = red; - m_green = green; - m_blue = blue; + m_brush = *wxBLACK_BRUSH; + m_pen = *wxTRANSPARENT_PEN; } void wxCanvasRect::Recreate() @@ -467,10 +661,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 +677,12 @@ 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( m_pen ); + dc->SetBrush( m_brush ); + dc->DrawRectangle( clip_x-buffer_x, clip_y-buffer_y, clip_width, clip_height ); +#endif } void wxCanvasRect::WriteSVG( wxTextOutputStream &stream ) @@ -491,8 +693,7 @@ void wxCanvasRect::WriteSVG( wxTextOutputStream &stream ) // wxCanvasLine //---------------------------------------------------------------------------- -wxCanvasLine::wxCanvasLine( double x1, double y1, double x2, double y2, - unsigned char red, unsigned char green, unsigned char blue ) +wxCanvasLine::wxCanvasLine( double x1, double y1, double x2, double y2 ) : wxCanvasObject() { m_x1 = x1; @@ -500,9 +701,7 @@ wxCanvasLine::wxCanvasLine( double x1, double y1, double x2, double y2, m_x2 = x2; m_y2 = y2; - m_red = red; - m_green = green; - m_blue = blue; + m_pen = *wxBLACK_PEN; } void wxCanvasLine::Recreate() @@ -528,21 +727,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 +797,14 @@ 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 ); + dc->SetPen( m_pen ); + dc->DrawLine( x1-buffer_x, y1-buffer_y, x2-buffer_x, y2-buffer_y ); + + dc->DestroyClippingRegion(); +#endif } void wxCanvasLine::WriteSVG( wxTextOutputStream &stream ) @@ -627,11 +835,28 @@ 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 ) @@ -639,6 +864,7 @@ void wxCanvasImage::Render(int xabs, int yabs, int clip_x, int clip_y, int clip_ 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 +882,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 ) @@ -728,7 +976,7 @@ wxCanvasText::wxCanvasText( const wxString &text, double x, double y, const wxSt m_fontFileName, 0, &(data->m_face) ); - + error = FT_Set_Char_Size( data->m_face, 0, m_size*64, @@ -763,9 +1011,11 @@ void wxCanvasText::Render(int xabs, int yabs, int clip_x, int clip_y, int clip_w { if (!m_alpha) return; - 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(); // local coordinates int start_x = clip_x - m_area.x; @@ -801,6 +1051,53 @@ 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 ); } } +#else + wxBitmap *bitmap = m_owner->GetBuffer(); + wxRect sub_rect( clip_x-buffer_x, clip_y-buffer_y, clip_width, clip_height ); + wxBitmap sub_bitmap( bitmap->GetSubBitmap( sub_rect ) ); + + wxImage image( sub_bitmap ); + + // local coordinates + int start_x = clip_x - m_area.x; + int end_x = clip_width + start_x; + int start_y = clip_y - m_area.y; + int end_y = clip_height + start_y; + + for (int y = start_y; y < end_y; y++) + for (int x = start_x; x < end_x; x++) + { + int alpha = m_alpha[y*m_area.width + x]; + if (alpha) + { + int image_x = x - start_x; + int image_y = y - start_y; + if (alpha == 255) + { + image.SetRGB( image_x, image_y, m_red, m_green, m_blue ); + continue; + } + int red1 = (m_red * alpha) / 255; + int green1 = (m_green * alpha) / 255; + int blue1 = (m_blue * alpha) / 255; + + alpha = 255-alpha; + int red2 = image.GetRed( image_x, image_y ); + int green2 = image.GetGreen( image_x, image_y ); + int blue2 = image.GetBlue( image_x, image_y ); + red2 = (red2 * alpha) / 255; + green2 = (green2 * alpha) / 255; + blue2 = (blue2 * alpha) / 255; + + image.SetRGB( image_x, image_y, red1+red2, green1+green2, blue1+blue2 ); + } + } + + sub_bitmap = image.ConvertToBitmap(); + + wxMemoryDC *dc = m_owner->GetDC(); + dc->DrawBitmap( sub_bitmap, clip_x-buffer_x, clip_y-buffer_y ); +#endif } void wxCanvasText::WriteSVG( wxTextOutputStream &stream ) @@ -814,9 +1111,9 @@ void wxCanvasText::Recreate() m_area.x = m_owner->GetDeviceX( m_x ); m_area.y = m_owner->GetDeviceY( m_y ); - m_area.width = 100; // TODO, calculate length - m_area.height = m_size; - m_alpha = new unsigned char[100*m_size]; + m_area.width = 100; // TODO calculate length + m_area.height = m_size + (m_size/2); // TODO space for sub-baseline (pgypq) + m_alpha = new unsigned char[m_area.width*m_area.height]; memset( m_alpha, 0, m_area.width*m_area.height ); #if wxUSE_FREETYPE @@ -884,8 +1181,9 @@ wxCanvas::wxCanvas( wxWindow *parent, wxWindowID id, m_lastMouse = (wxCanvasObject*)NULL; m_captureMouse = (wxCanvasObject*)NULL; m_frozen = TRUE; - m_requestNewBuffer = TRUE; - + m_oldDeviceX = 0; + m_oldDeviceY = 0; + //root group always at 0,0 m_root = new wxCanvasObjectGroup(); m_root->DeleteContents( TRUE ); @@ -919,6 +1217,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 +1230,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 ) @@ -971,6 +1279,8 @@ void wxCanvas::Thaw() void wxCanvas::Update( int x, int y, int width, int height, bool blit ) { + CalcScrolledPosition( 0, 0, &m_oldDeviceX, &m_oldDeviceY ); + if (m_frozen) return; // clip to buffer @@ -979,26 +1289,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 +1320,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 +1331,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 +1357,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 +1386,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(); @@ -1201,13 +1531,17 @@ void wxCanvas::OnPaint(wxPaintEvent &event) void wxCanvas::ScrollWindow( int dx, int dy, const wxRect* rect ) { // If any updates are pending, do them now since they will - // expect the previous m_bufferX and m_bufferY values. - UpdateNow(); + // expect the previous m_bufferX and m_bufferY as well as + // the previous device origin values. + wxClientDC dc( this ); + dc.SetDeviceOrigin( m_oldDeviceX, m_oldDeviceY ); + BlitBuffer( dc ); // The buffer always starts at the top left corner of the // 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 +1605,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 +1746,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 );