56 #ifndef STB_INCLUDE_STB_RECT_PACK_H 57 #define STB_INCLUDE_STB_RECT_PACK_H 59 #define STB_RECT_PACK_VERSION 1 62 #define STBRP_DEF static 64 #define STBRP_DEF extern 75 #ifdef STBRP_LARGE_RECTS 196 #ifdef STB_RECT_PACK_IMPLEMENTATION 199 #define STBRP_SORT qsort 204 #define STBRP_ASSERT assert 208 #define STBRP__NOTUSED(v) (void)(v) 209 #define STBRP__CDECL __cdecl 211 #define STBRP__NOTUSED(v) (void)sizeof(v) 217 STBRP__INIT_skyline = 1
223 case STBRP__INIT_skyline:
234 if (allow_out_of_mem)
255 #ifndef STBRP_LARGE_RECTS 259 for (i=0; i < num_nodes-1; ++i)
260 nodes[i].next = &nodes[i+1];
261 nodes[i].
next = NULL;
262 context->
init_mode = STBRP__INIT_skyline;
266 context->
width = width;
276 #ifdef STBRP_LARGE_RECTS 277 context->
extra[1].
y = (1<<30);
279 context->
extra[1].
y = 65535;
289 int min_y, visited_width, waste_area;
297 while (node->
next->
x <= x0)
308 while (node->
x < x1) {
309 if (node->
y > min_y) {
313 waste_area += visited_width * (node->
y - min_y);
317 visited_width += node->
next->
x - x0;
319 visited_width += node->
next->
x - node->
x;
322 int under_width = node->
next->
x - node->
x;
323 if (under_width + visited_width > width)
324 under_width = width - visited_width;
325 waste_area += under_width * (min_y - node->
y);
326 visited_width += under_width;
331 *pwaste = waste_area;
341 static stbrp__findresult stbrp__skyline_find_best_pos(
stbrp_context *c,
int width,
int height)
343 int best_waste = (1<<30), best_x, best_y = (1 << 30);
344 stbrp__findresult fr;
345 stbrp_node **prev, *node, *tail, **best = NULL;
348 width = (width + c->
align - 1);
349 width -= width % c->
align;
354 while (node->
x + width <= c->width) {
356 y = stbrp__skyline_find_min_y(c, node, node->
x, width, &waste);
365 if (y + height <= c->height) {
367 if (y < best_y || (y == best_y && waste < best_waste)) {
378 best_x = (best == NULL) ? 0 : (*best)->
x;
402 while (tail->
x < width)
405 int xpos = tail->
x - width;
409 while (node->
next->
x <= xpos) {
414 y = stbrp__skyline_find_min_y(c, node, xpos, width, &waste);
415 if (y + height < c->height) {
417 if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) {
436 static stbrp__findresult stbrp__skyline_pack_rectangle(
stbrp_context *context,
int width,
int height)
439 stbrp__findresult res = stbrp__skyline_find_best_pos(context, width, height);
446 if (res.prev_link == NULL || res.y + height > context->
height || context->
free_head == NULL) {
447 res.prev_link = NULL;
462 cur = *res.prev_link;
463 if (cur->
x < res.x) {
469 *res.prev_link = node;
474 while (cur->
next && cur->
next->
x <= res.x + width) {
485 if (cur->
x < res.x + width)
490 while (cur->
x < context->
width) {
515 static int STBRP__CDECL rect_height_compare(
const void *a,
const void *b)
523 return (p->
w > q->
w) ? -1 : (p->
w < q->
w);
526 static int STBRP__CDECL rect_original_order(
const void *a,
const void *b)
533 #ifdef STBRP_LARGE_RECTS 534 #define STBRP__MAXVAL 0xffffffff 536 #define STBRP__MAXVAL 0xffff 541 int i, all_rects_packed = 1;
544 for (i=0; i < num_rects; ++i) {
546 #ifndef STBRP_LARGE_RECTS 552 STBRP_SORT(rects, num_rects,
sizeof(rects[0]), rect_height_compare);
554 for (i=0; i < num_rects; ++i) {
555 if (rects[i].
w == 0 || rects[i].
h == 0) {
556 rects[i].
x = rects[i].
y = 0;
558 stbrp__findresult fr = stbrp__skyline_pack_rectangle(context, rects[i].
w, rects[i].
h);
563 rects[i].
x = rects[i].
y = STBRP__MAXVAL;
569 STBRP_SORT(rects, num_rects,
sizeof(rects[0]), rect_original_order);
572 for (i=0; i < num_rects; ++i) {
573 rects[i].
was_packed = !(rects[i].
x == STBRP__MAXVAL && rects[i].
y == STBRP__MAXVAL);
575 all_rects_packed = 0;
579 return all_rects_packed;
STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes)
unsigned short stbrp_coord
STBRP_DEF void stbrp_setup_allow_out_of_mem(stbrp_context *context, int allow_out_of_mem)
STBRP_DEF void stbrp_setup_heuristic(stbrp_context *context, int heuristic)
STBRP_DEF int stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects)