// ----------------------------------------------- texture_atlas_get_region --- ivec4 texture_atlas_get_region( texture_atlas_t * self, const size_t width, const size_t height ) { int y, best_index; size_t best_height, best_width; ivec3 *node, *prev; ivec4 region = {{0,0,width,height}}; size_t i; assert( self ); best_height = UINT_MAX; best_index = -1; best_width = UINT_MAX; for( i=0; i<self->nodes->size; ++i ) { y = texture_atlas_fit( self, i, width, height ); if( y >= 0 ) { node = (ivec3 *) vector_get( self->nodes, i ); if( ( (y + height) < best_height ) || ( ((y + height) == best_height) && (node->z > 0 && (size_t)node->z < best_width)) ) { best_height = y + height; best_index = i; best_width = node->z; region.x = node->x; region.y = y; } } } if( best_index == -1 ) { region.x = -1; region.y = -1; region.width = 0; region.height = 0; return region; } node = (ivec3 *) malloc( sizeof(ivec3) ); if( node == NULL) { fprintf( stderr, "line %d: No more memory for allocating data\n", __LINE__ ); exit( EXIT_FAILURE ); } node->x = region.x; node->y = region.y + height; node->z = width; vector_insert( self->nodes, best_index, node ); free( node ); for(i = best_index+1; i < self->nodes->size; ++i) { node = (ivec3 *) vector_get( self->nodes, i ); prev = (ivec3 *) vector_get( self->nodes, i-1 ); if (node->x < (prev->x + prev->z) ) { int shrink = prev->x + prev->z - node->x; node->x += shrink; node->z -= shrink; if (node->z <= 0) { vector_erase( self->nodes, i ); --i; } else { break; } } else { break; } } texture_atlas_merge( self ); self->used += width * height; return region; }
/* ------------------------------------------------------------------------- */ Region texture_atlas_get_region( TextureAtlas *self, size_t width, size_t height ) { assert( self ); /* assert( width ); assert( height ); */ { int y, best_height, best_width, best_index; Node *node, *prev; Region region = {0,0,width,height}; size_t i; best_height = INT_MAX; best_index = -1; best_width = INT_MAX; for( i=0; i<self->nodes->size; ++i ) { y = texture_atlas_fit( self, i, width, height ); if( y >= 0 ) { node = (Node *) vector_get( self->nodes, i ); if( ( y + (int)height < best_height ) || ( y + height == best_height && node->width < best_width) ) { best_height = y + height; best_index = i; best_width = node->width; region.x = node->x; region.y = y; } } } if( best_index == -1 ) { region.x = -1; region.y = -1; region.width = 0; region.height = 0; return region; } node = (Node *) malloc( sizeof(Node) ); node->x = region.x; node->y = region.y + height; node->width = width; vector_insert( self->nodes, best_index, node ); free( node ); for(i = best_index+1; i < self->nodes->size; ++i) { node = (Node *) vector_get( self->nodes, i ); prev = (Node *) vector_get( self->nodes, i-1 ); if (node->x < (prev->x + prev->width) ) { int shrink = prev->x + prev->width - node->x; node->x += shrink; node->width -= shrink; if (node->width <= 0) { vector_erase( self->nodes, i ); --i; } else { break; } } else { break; } } texture_atlas_merge( self ); self->used += width * height; return region; } }