Groups are stored in map instead of deque, so it allows easier adding & removing.

This commit is contained in:
Maciej Suminski 2013-06-27 11:54:49 +02:00
parent 58de62aacc
commit 332a7b4bd9
4 changed files with 98 additions and 46 deletions

View File

@ -31,6 +31,8 @@
#include <gal/cairo/cairo_gal.h>
#include <gal/definitions.h>
#include <limits>
using namespace KiGfx;
CAIRO_GAL::CAIRO_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener,
@ -50,6 +52,7 @@ CAIRO_GAL::CAIRO_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener,
isInitialized = false;
isDeleteSavedPixels = false;
zoomFactor = 1.0;
groupCounter = 0;
SetSize( aParent->GetSize() );
@ -200,6 +203,20 @@ void CAIRO_GAL::deinitSurface()
}
unsigned int CAIRO_GAL::getGroupNumber()
{
wxASSERT_MSG( groups.size() < std::numeric_limits<unsigned int>::max(),
wxT( "There are no free slots to store a group" ) );
while( groups.find( groupCounter ) != groups.end() )
{
groupCounter++;
}
return groupCounter++;
}
void CAIRO_GAL::BeginDrawing() throw( int )
{
initSurface();
@ -429,7 +446,7 @@ void CAIRO_GAL::SetIsFill( bool aIsFillEnabled )
GroupElement groupElement;
groupElement.command = CMD_SET_FILL;
groupElement.boolArgument = aIsFillEnabled;
groups.back().push_back( groupElement );
currentGroup->push_back( groupElement );
}
}
@ -444,7 +461,7 @@ void CAIRO_GAL::SetIsStroke( bool aIsStrokeEnabled )
GroupElement groupElement;
groupElement.command = CMD_SET_STROKE;
groupElement.boolArgument = aIsStrokeEnabled;
groups.back().push_back( groupElement );
currentGroup->push_back( groupElement );
}
}
@ -463,7 +480,7 @@ void CAIRO_GAL::SetStrokeColor( const COLOR4D& aColor )
groupElement.arguments[1] = strokeColor.g;
groupElement.arguments[2] = strokeColor.b;
groupElement.arguments[3] = strokeColor.a;
groups.back().push_back( groupElement );
currentGroup->push_back( groupElement );
}
}
@ -481,7 +498,7 @@ void CAIRO_GAL::SetFillColor( const COLOR4D& aColor )
groupElement.arguments[1] = fillColor.g;
groupElement.arguments[2] = fillColor.b;
groupElement.arguments[3] = fillColor.a;
groups.back().push_back( groupElement );
currentGroup->push_back( groupElement );
}
}
@ -498,7 +515,7 @@ void CAIRO_GAL::SetLineWidth( double aLineWidth )
GroupElement groupElement;
groupElement.command = CMD_SET_LINE_WIDTH;
groupElement.arguments[0] = aLineWidth;
groups.back().push_back( groupElement );
currentGroup->push_back( groupElement );
}
}
@ -516,7 +533,7 @@ void CAIRO_GAL::SetLineCap( LineCap aLineCap )
GroupElement groupElement;
groupElement.command = CMD_SET_LINE_CAP;
groupElement.intArgument = (int) aLineCap;
groups.back().push_back( groupElement );
currentGroup->push_back( groupElement );
}
}
@ -534,7 +551,7 @@ void CAIRO_GAL::SetLineJoin( LineJoin aLineJoin )
GroupElement groupElement;
groupElement.command = CMD_SET_LINE_JOIN;
groupElement.intArgument = (int) aLineJoin;
groups.back().push_back( groupElement );
currentGroup->push_back( groupElement );
}
}
@ -592,7 +609,7 @@ void CAIRO_GAL::Rotate( double aAngle )
GroupElement groupElement;
groupElement.command = CMD_ROTATE;
groupElement.arguments[0] = aAngle;
groups.back().push_back( groupElement );
currentGroup->push_back( groupElement );
}
}
@ -609,7 +626,7 @@ void CAIRO_GAL::Translate( const VECTOR2D& aTranslation )
groupElement.command = CMD_TRANSLATE;
groupElement.arguments[0] = aTranslation.x;
groupElement.arguments[1] = aTranslation.y;
groups.back().push_back( groupElement );
currentGroup->push_back( groupElement );
}
}
@ -626,7 +643,7 @@ void CAIRO_GAL::Scale( const VECTOR2D& aScale )
groupElement.command = CMD_SCALE;
groupElement.arguments[0] = aScale.x;
groupElement.arguments[1] = aScale.y;
groups.back().push_back( groupElement );
currentGroup->push_back( groupElement );
}
}
@ -641,7 +658,7 @@ void CAIRO_GAL::Save()
{
GroupElement groupElement;
groupElement.command = CMD_SAVE;
groups.back().push_back( groupElement );
currentGroup->push_back( groupElement );
}
}
@ -656,7 +673,7 @@ void CAIRO_GAL::Restore()
{
GroupElement groupElement;
groupElement.command = CMD_RESTORE;
groups.back().push_back( groupElement );
currentGroup->push_back( groupElement );
}
}
@ -668,10 +685,14 @@ int CAIRO_GAL::BeginGroup()
// 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();
Group group;
groups.push_back( group );
int groupNumber = getGroupNumber();
groups.insert( std::make_pair( groupNumber, group ) );
currentGroup = &groups[groupNumber];
isGrouping = true;
return groups.size() - 1;
return groupNumber;
}
@ -708,7 +729,7 @@ void CAIRO_GAL::DeleteGroup( int aGroupNumber )
}
// Delete the group
groups.erase( groups.begin() + aGroupNumber );
groups.erase( aGroupNumber );
}
@ -879,15 +900,12 @@ void CAIRO_GAL::storePath()
// Copy the actual path, append it to the global path list
// then check, if the path needs to be stroked/filled and
// add this command to the group list;
// pathList.push_back( path ); // FIXME: it's not used anywhere else?
if( isStrokeEnabled )
{
GroupElement groupElement;
groupElement.cairoPath = cairo_copy_path( cairoImage );
groupElement.command = CMD_STROKE_PATH;
groups.back().push_back( groupElement );
currentGroup->push_back( groupElement );
}
if( isFillEnabled )
@ -895,7 +913,7 @@ void CAIRO_GAL::storePath()
GroupElement groupElement;
groupElement.cairoPath = cairo_copy_path( cairoImage );
groupElement.command = CMD_FILL_PATH;
groups.back().push_back( groupElement );
currentGroup->push_back( groupElement );
}
}

View File

@ -38,6 +38,8 @@
#include <profile.h>
#endif /* __WXDEBUG__ */
#include <limits>
#ifndef CALLBACK
#define CALLBACK
#endif
@ -77,9 +79,11 @@ OPENGL_GAL::OPENGL_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener,
isVboInitialized = false;
vboNeedsUpdate = false;
curVboItem = NULL;
currentGroup = NULL;
groupCounter = 0;
transform = glm::mat4( 1.0f ); // Identity matrix
SetSize( parentSize );
screenSize.x = parentSize.x;
@ -723,6 +727,20 @@ inline void OPENGL_GAL::drawLineCap( const VECTOR2D& aStartPoint, const VECTOR2D
}
unsigned int OPENGL_GAL::getGroupNumber()
{
wxASSERT_MSG( groups.size() < std::numeric_limits<unsigned int>::max(),
wxT( "There are no free slots to store a group" ) );
while( groups.find( groupCounter ) != groups.end() )
{
groupCounter++;
}
return groupCounter++;
}
void OPENGL_GAL::DrawLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint )
{
if( isFillEnabled )
@ -1138,7 +1156,7 @@ void OPENGL_GAL::DrawCircle( const VECTOR2D& aCenterPoint, double aRadius )
memcpy( circle, verticesCircle->GetVertices(),
VBO_ITEM::VertByteSize * CIRCLE_POINTS * 3 );
curVboItem->PushVertices( circle, CIRCLE_POINTS * 3 );
currentGroup->PushVertices( circle, CIRCLE_POINTS * 3 );
delete[] circle;
}
@ -1195,7 +1213,7 @@ void OPENGL_GAL::drawSemiCircle( const VECTOR2D& aCenterPoint, double aRadius, d
memcpy( semiCircle, verticesSemiCircle->GetVertices(),
VBO_ITEM::VertByteSize * CIRCLE_POINTS / 2 * 3 );
curVboItem->PushVertices( semiCircle, CIRCLE_POINTS / 2 * 3 );
currentGroup->PushVertices( semiCircle, CIRCLE_POINTS / 2 * 3 );
delete[] semiCircle;
}
@ -1373,7 +1391,7 @@ void OPENGL_GAL::DrawPolygon( const std::deque<VECTOR2D>& aPointList )
glShadeModel( GL_FLAT );
TessParams params = { curVboItem, tessIntersects };
TessParams params = { currentGroup, tessIntersects };
gluTessBeginPolygon( tesselator, &params );
gluTessBeginContour( tesselator );
@ -1578,39 +1596,38 @@ int OPENGL_GAL::BeginGroup()
vboNeedsUpdate = true;
// Save the pointer for caching the current item
curVboItem = new VBO_ITEM( vboContainer );
vboItems.push_back( curVboItem );
currentGroup = new VBO_ITEM( vboContainer );
int groupNumber = getGroupNumber();
groups.insert( std::make_pair( groupNumber, currentGroup ) );
return vboItems.size() - 1;
return groupNumber;
}
void OPENGL_GAL::EndGroup()
{
curVboItem->Finish();
curVboItem = NULL;
currentGroup->Finish();
isGrouping = false;
}
void OPENGL_GAL::ClearCache()
{
std::deque<VBO_ITEM*>::iterator it, end;
for( it = vboItems.begin(), end = vboItems.end(); it != end; it++ )
std::map<unsigned int, VBO_ITEM*>::iterator it, end;
for( it = groups.begin(), end = groups.end(); it != end; it++ )
{
delete *it;
delete it->second;
}
vboItems.clear();
groups.clear();
}
void OPENGL_GAL::DeleteGroup( int aGroupNumber )
{
VBO_ITEM* item = vboItems[aGroupNumber];
vboItems[aGroupNumber] = NULL;
delete item;
delete groups[aGroupNumber];
groups.erase( aGroupNumber );
vboNeedsUpdate = true;
}
@ -1618,8 +1635,8 @@ void OPENGL_GAL::DeleteGroup( int aGroupNumber )
void OPENGL_GAL::DrawGroup( int aGroupNumber )
{
int size = vboItems[aGroupNumber]->GetSize();
int offset = vboItems[aGroupNumber]->GetOffset();
int size = groups[aGroupNumber]->GetSize();
int offset = groups[aGroupNumber]->GetOffset();
// Copy indices of items that should be drawn to GPU memory
for( int i = offset; i < offset + size; *indicesPtr++ = i++ );
@ -1630,14 +1647,14 @@ void OPENGL_GAL::DrawGroup( int aGroupNumber )
void OPENGL_GAL::ChangeGroupColor( int aGroupNumber, const COLOR4D& aNewColor )
{
vboItems[aGroupNumber]->ChangeColor( aNewColor );
groups[aGroupNumber]->ChangeColor( aNewColor );
vboNeedsUpdate = true;
}
void OPENGL_GAL::ChangeGroupDepth( int aGroupNumber, int aDepth )
{
vboItems[aGroupNumber]->ChangeDepth( aDepth );
groups[aGroupNumber]->ChangeDepth( aDepth );
vboNeedsUpdate = true;
}

View File

@ -322,7 +322,6 @@ private:
int actualGroupIndex; ///< The index of the actual group
bool isGrouping; ///< Is grouping enabled ?
bool isElementAdded; ///< Was an graphic element added ?
std::deque<cairo_path_t*> pathList; ///< List of stored paths
/// Maximum number of arguments for one command
static const int MAX_CAIRO_ARGUMENTS = 6;
@ -359,7 +358,9 @@ private:
} GroupElement;
typedef std::deque<GroupElement> Group; ///< A graphic group type definition
std::deque<Group> groups; ///< List of graphic groups
std::map<int, Group> groups; ///< List of graphic groups
unsigned int groupCounter; ///< Counter used for generating keys for groups
Group* currentGroup; ///< Currently used group
// Variables related to Cairo <-> wxWidgets
cairo_matrix_t cairoWorldScreenMatrix; ///< Cairo world to screen transformation matrix
@ -410,6 +411,13 @@ private:
// Destroy Cairo surfaces when are not needed anymore
void deinitSurface();
/**
* @brief Returns a valid key that can be used as a group number.
*
* @return An unique group number that is not used by any other group.
*/
unsigned int getGroupNumber();
};
} // namespace KiGfx

View File

@ -361,12 +361,14 @@ private:
VBO_ITEM* verticesSemiCircle;
// Vertex buffer objects related fields
std::deque<VBO_ITEM*> vboItems; ///< Stores informations about VBO objects
VBO_ITEM* curVboItem; ///< Currently used VBO_ITEM (for grouping)
std::map<unsigned int, VBO_ITEM*> groups; ///< Stores informations about VBO objects (groups)
unsigned int groupCounter; ///< Counter used for generating keys for groups
VBO_ITEM* currentGroup; ///< Currently used VBO_ITEM (for grouping)
VBO_CONTAINER* vboContainer; ///< Container for storing VBO_ITEMs
GLuint vboVertices; ///< Currently used vertices VBO handle
GLuint vboIndices; ///< Currently used indices VBO handle
bool vboNeedsUpdate; ///< Flag indicating if VBO should be rebuilt
glm::mat4 transform; ///< Current transformation matrix
std::stack<glm::mat4> transformStack; ///< Stack of transformation matrices
int indicesSize; ///< Number of indices to be drawn
@ -530,6 +532,13 @@ private:
*/
inline void drawLineCap( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint );
/**
* @brief Returns a valid key that can be used as a group number.
*
* @return An unique group number that is not used by any other group.
*/
unsigned int getGroupNumber();
///< OpenGL replacement functions (that are working both in immediate and VBO modes)
/**
* @brief Starts drawing in immediate mode or does nothing if an item's caching has started.
@ -562,7 +571,7 @@ private:
{
// New vertex coordinates for VBO
VBO_VERTEX vertex = { aX, aY, aZ };
curVboItem->PushVertex( &vertex );
currentGroup->PushVertex( &vertex );
}
else
{