Fixed Cairo issues and some possible memory leaks

This commit is contained in:
Maciej Suminski 2013-05-13 10:55:35 +02:00
parent e8f33ac903
commit bce9f685ea
4 changed files with 49 additions and 31 deletions

View File

@ -40,7 +40,7 @@ CAIRO_GAL::CAIRO_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener,
// Default values
fillColor = COLOR4D( 0, 0, 0, 1 );
strokeColor = COLOR4D( 1, 1, 1, 1 );
screenSize = VECTOR2D( 20, 20 ); // window will be soon resized
screenSize = VECTOR2D( aParent->GetSize() );
parentWindow = aParent;
mouseListener = aMouseListener;
@ -101,7 +101,11 @@ CAIRO_GAL::~CAIRO_GAL()
delete cursorPixels;
delete cursorPixelsSaved;
// TODO Deleting of list contents like groups and paths
for( int i = groups.size() - 1; i >= 0; --i )
{
DeleteGroup( i );
}
deleteBitmaps();
}
@ -133,7 +137,7 @@ void CAIRO_GAL::skipMouseEvent( wxMouseEvent& aEvent )
}
void CAIRO_GAL::BeginDrawing() throw( int )
void CAIRO_GAL::initSurface()
{
// The size of the client area needs to be greater than zero
clientRectangle = parentWindow->GetClientRect();
@ -141,13 +145,15 @@ void CAIRO_GAL::BeginDrawing() throw( int )
if( clientRectangle.width == 0 || clientRectangle.height == 0 )
throw EXCEPTION_ZERO_CLIENT_RECTANGLE;
// clientDC = new wxClientDC( this );
// Create the CAIRO surface
// Create the Cairo surface
cairoSurface = cairo_image_surface_create_for_data( (unsigned char*) bitmapBuffer,
CAIRO_FORMAT_RGB24, clientRectangle.width,
clientRectangle.height, stride );
cairoImage = cairo_create( cairoSurface );
cairoImage = cairo_create ( cairoSurface );
#ifdef __WXDEBUG__
cairo_status_t status = cairo_status( cairoImage );
wxASSERT_MSG( status == CAIRO_STATUS_SUCCESS, "Cairo context creation error" );
#endif /* __WXDEBUG__ */
// -----------------------------------------------------------------
@ -178,6 +184,20 @@ void CAIRO_GAL::BeginDrawing() throw( int )
lineWidth = 0;
isDeleteSavedPixels = true;
}
void CAIRO_GAL::deinitSurface()
{
// Destroy Cairo objects
cairo_destroy( cairoImage );
cairo_surface_destroy( cairoSurface );
}
void CAIRO_GAL::BeginDrawing() throw( int )
{
initSurface();
cairo_push_group( cairoImage );
}
@ -211,9 +231,7 @@ void CAIRO_GAL::EndDrawing()
wxBufferedDC dc;
dc.Init( &client_dc, bmp );
// Destroy Cairo objects
cairo_destroy( cairoImage );
cairo_surface_destroy( cairoSurface );
deinitSurface();
}
@ -637,6 +655,8 @@ void CAIRO_GAL::Restore()
int CAIRO_GAL::BeginGroup()
{
initSurface();
// If the grouping is started: the actual path is stored in the group, when
// a attribute was changed or when grouping stops with the end group method.
storePath();
@ -651,6 +671,8 @@ void CAIRO_GAL::EndGroup()
{
storePath();
isGrouping = false;
deinitSurface();
}
@ -659,12 +681,13 @@ void CAIRO_GAL::DeleteGroup( int aGroupNumber )
storePath();
// Delete the Cairo paths
for( std::deque<GroupElement>::iterator it = groups[aGroupNumber].begin();
it != groups[aGroupNumber].end(); ++it )
for( std::deque<GroupElement>::iterator it = groups[aGroupNumber].begin(), end = groups[aGroupNumber].end();
it != end; ++it )
{
if( it->command == CMD_FILL_PATH || it->command == CMD_STROKE_PATH )
{
cairo_path_destroy( it->cairoPath );
if( it->cairoPath->status == CAIRO_STATUS_SUCCESS )
cairo_path_destroy( it->cairoPath );
}
}
@ -817,7 +840,7 @@ void CAIRO_GAL::storePath()
// add this command to the group list;
cairo_path_t* path = cairo_copy_path( cairoImage );
pathList.push_back( path );
// pathList.push_back( path ); // FIXME: it's not used anywhere else?
if( isStrokeEnabled )
{
@ -924,7 +947,7 @@ void CAIRO_GAL::DrawGridLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndP
void CAIRO_GAL::allocateBitmaps()
{
// Create buffer, use the system independent CAIRO image back end
// Create buffer, use the system independent Cairo image backend
stride = cairo_format_stride_for_width( CAIRO_FORMAT_RGB24, screenSize.x );
bufferSize = stride * screenSize.y;

View File

@ -1488,19 +1488,15 @@ void OPENGL_GAL::EndGroup()
void OPENGL_GAL::DeleteGroup( int aGroupNumber )
{
if( aGroupNumber >= vboItems.size() )
{
// This should not happen
wxLogDebug( wxT( "Tried to delete not existing group" ) );
return;
}
wxASSERT_MSG( aGroupNumber < vboItems.size(),
"OPENGL_GAL: Tried to delete not existing group" );
std::deque<VBO_ITEM*>::iterator it = vboItems.begin();
std::advance( it, aGroupNumber );
//vboSize -= it->GetSize(); // FIXME?
delete *it;
//vboItems.erase( it );
//vboItems.erase( it ); // makes change to group numbers - that's veeery bad
vboNeedsUpdate = true;
}

View File

@ -469,8 +469,8 @@ struct VIEW::recacheItem
if( immediately )
{
int group = gal->BeginGroup();
view->m_painter->Draw( static_cast<EDA_ITEM*>( aItem ), layer );
aItem->setGroup( layer, group );
view->m_painter->Draw( static_cast<EDA_ITEM*>( aItem ), layer );
gal->EndGroup();
}
else
@ -603,9 +603,6 @@ void VIEW::RecacheAllItems( bool aImmediately )
r.SetMaximum();
//if( aImmediately )
m_gal->BeginDrawing();
wxLogDebug( wxT( "RecacheAllItems::immediately: %u" ), aImmediately );
for( LayerMapIter i = m_layers.begin(); i != m_layers.end(); ++i )
@ -614,7 +611,4 @@ void VIEW::RecacheAllItems( bool aImmediately )
recacheItem visitor( this, m_gal, l->id, aImmediately );
l->items->Query( r, visitor );
}
//if( aImmediately )
m_gal->EndDrawing();
}

View File

@ -359,14 +359,13 @@ private:
unsigned int* bitmapBuffer; ///< Storage of the cairo image
unsigned int* bitmapBufferBackup; ///< Backup storage of the cairo image
int stride; ///< Stride value for Cairo
// wxClientDC* clientDC; ///< Pointer to the clientDC
// Mapping between Cairo and GAL line attributes
std::map<LineCap, cairo_line_cap_t> lineCapMap; ///< Line cap style mapping
std::map<LineJoin, cairo_line_join_t> lineJoinMap; ///< Line join style mapping
// Methods
void storePath(); ///< Store the actual path
void storePath(); ///< Store the actual path
// Event handlers
/**
@ -395,6 +394,12 @@ private:
/// Allocate the bitmaps for drawing
void deleteBitmaps();
/// Prepare Cairo surfaces for drawing
void initSurface();
// Destroy Cairo surfaces when are not needed anymore
void deinitSurface();
};
} // namespace KiGfx