70#ifndef STB_INCLUDE_STB_RECT_PACK_H
71#define STB_INCLUDE_STB_RECT_PACK_H
73#define STB_RECT_PACK_VERSION 1
76#define STBRP_DEF static
78#define STBRP_DEF extern
89typedef int stbrp_coord;
91#define STBRP__MAXVAL 0x7fffffff
134STBRP_DEF
void stbrp_init_target (
stbrp_context *context,
int width,
int height,
stbrp_node *nodes,
int num_nodes);
155STBRP_DEF
void stbrp_setup_allow_out_of_mem (
stbrp_context *context,
int allow_out_of_mem);
161STBRP_DEF
void stbrp_setup_heuristic (
stbrp_context *context,
int heuristic);
168 STBRP_HEURISTIC_Skyline_default=0,
169 STBRP_HEURISTIC_Skyline_BL_sortHeight = STBRP_HEURISTIC_Skyline_default,
170 STBRP_HEURISTIC_Skyline_BF_sortHeight
209#ifdef STB_RECT_PACK_IMPLEMENTATION
212#define STBRP_SORT qsort
217#define STBRP_ASSERT assert
221#define STBRP__NOTUSED(v) (void)(v)
222#define STBRP__CDECL __cdecl
224#define STBRP__NOTUSED(v) (void)sizeof(v)
230 STBRP__INIT_skyline = 1
233STBRP_DEF
void stbrp_setup_heuristic(
stbrp_context *context,
int heuristic)
236 case STBRP__INIT_skyline:
237 STBRP_ASSERT(heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight || heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight);
245STBRP_DEF
void stbrp_setup_allow_out_of_mem(
stbrp_context *context,
int allow_out_of_mem)
247 if (allow_out_of_mem)
265STBRP_DEF
void stbrp_init_target(
stbrp_context *context,
int width,
int height,
stbrp_node *nodes,
int num_nodes)
269 for (i=0; i < num_nodes-1; ++i)
270 nodes[i].next = &nodes[i+1];
271 nodes[i].
next = NULL;
272 context->
init_mode = STBRP__INIT_skyline;
273 context->
heuristic = STBRP_HEURISTIC_Skyline_default;
276 context->
width = width;
279 stbrp_setup_allow_out_of_mem(context, 0);
285 context->
extra[1].
x = (stbrp_coord) width;
286 context->
extra[1].
y = (1<<30);
295 int min_y, visited_width, waste_area;
299 STBRP_ASSERT(first->
x <= x0);
303 while (node->
next->
x <= x0)
306 STBRP_ASSERT(node->
next->
x > x0);
309 STBRP_ASSERT(node->
x <= x0);
314 while (node->
x < x1) {
315 if (node->
y > min_y) {
319 waste_area += visited_width * (node->
y - min_y);
323 visited_width += node->
next->
x - x0;
325 visited_width += node->
next->
x - node->
x;
328 int under_width = node->
next->
x - node->
x;
329 if (under_width + visited_width > width)
330 under_width = width - visited_width;
331 waste_area += under_width * (min_y - node->
y);
332 visited_width += under_width;
337 *pwaste = waste_area;
347static stbrp__findresult stbrp__skyline_find_best_pos(
stbrp_context *c,
int width,
int height)
349 int best_waste = (1<<30), best_x, best_y = (1 << 30);
350 stbrp__findresult fr;
351 stbrp_node **prev, *node, *tail, **best = NULL;
354 width = (width + c->
align - 1);
355 width -= width % c->
align;
356 STBRP_ASSERT(width % c->
align == 0);
367 while (node->
x + width <= c->width) {
369 y = stbrp__skyline_find_min_y(c, node, node->
x, width, &waste);
370 if (c->
heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight) {
378 if (y + height <= c->height) {
380 if (y < best_y || (y == best_y && waste < best_waste)) {
391 best_x = (best == NULL) ? 0 : (*best)->x;
410 if (c->
heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight) {
411 tail = c->active_head;
412 node = c->active_head;
413 prev = &c->active_head;
415 while (tail->x < width)
418 int xpos = tail->x - width;
420 STBRP_ASSERT(xpos >= 0);
422 while (node->next->x <= xpos) {
426 STBRP_ASSERT(node->next->x > xpos && node->x <= xpos);
427 y = stbrp__skyline_find_min_y(c, node, xpos, width, &waste);
428 if (y + height <= c->height) {
430 if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) {
449static stbrp__findresult stbrp__skyline_pack_rectangle(
stbrp_context *context,
int width,
int height)
452 stbrp__findresult res = stbrp__skyline_find_best_pos(context, width, height);
459 if (res.prev_link == NULL || res.y + height > context->
height || context->
free_head == NULL) {
460 res.prev_link = NULL;
466 node->
x = (stbrp_coord) res.x;
467 node->
y = (stbrp_coord) (res.y + height);
475 cur = *res.prev_link;
476 if (cur->
x < res.x) {
482 *res.prev_link = node;
487 while (cur->
next && cur->
next->
x <= res.x + width) {
498 if (cur->
x < res.x + width)
499 cur->
x = (stbrp_coord) (res.x + width);
503 while (cur->
x < context->
width) {
504 STBRP_ASSERT(cur->
x < cur->
next->
x);
507 STBRP_ASSERT(cur->
next == NULL);
521 STBRP_ASSERT(count == context->
num_nodes+2);
528static int STBRP__CDECL rect_height_compare(
const void *a,
const void *b)
536 return (p->
w > q->
w) ? -1 : (p->
w < q->
w);
539static int STBRP__CDECL rect_original_order(
const void *a,
const void *b)
548 int i, all_rects_packed = 1;
551 for (i=0; i < num_rects; ++i) {
556 STBRP_SORT(rects, num_rects,
sizeof(rects[0]), rect_height_compare);
558 for (i=0; i < num_rects; ++i) {
559 if (rects[i].w == 0 || rects[i].h == 0) {
560 rects[i].
x = rects[i].
y = 0;
562 stbrp__findresult fr = stbrp__skyline_pack_rectangle(context, rects[i].w, rects[i].h);
564 rects[i].
x = (stbrp_coord) fr.x;
565 rects[i].
y = (stbrp_coord) fr.y;
567 rects[i].
x = rects[i].
y = STBRP__MAXVAL;
573 STBRP_SORT(rects, num_rects,
sizeof(rects[0]), rect_original_order);
576 for (i=0; i < num_rects; ++i) {
577 rects[i].
was_packed = !(rects[i].
x == STBRP__MAXVAL && rects[i].
y == STBRP__MAXVAL);
578 if (!rects[i].was_packed)
579 all_rects_packed = 0;
583 return all_rects_packed;
Definition imstb_rectpack.h:186
int init_mode
Definition imstb_rectpack.h:190
stbrp_node extra[2]
Definition imstb_rectpack.h:195
stbrp_node * active_head
Definition imstb_rectpack.h:193
stbrp_node * free_head
Definition imstb_rectpack.h:194
int heuristic
Definition imstb_rectpack.h:191
int width
Definition imstb_rectpack.h:187
int align
Definition imstb_rectpack.h:189
int height
Definition imstb_rectpack.h:188
int num_nodes
Definition imstb_rectpack.h:192
Definition imstb_rectpack.h:180
stbrp_coord x
Definition imstb_rectpack.h:181
stbrp_node * next
Definition imstb_rectpack.h:182
stbrp_coord y
Definition imstb_rectpack.h:181
Definition imstb_rectpack.h:120
stbrp_coord w
Definition imstb_rectpack.h:125
stbrp_coord x
Definition imstb_rectpack.h:128
int was_packed
Definition imstb_rectpack.h:129
int id
Definition imstb_rectpack.h:122
stbrp_coord y
Definition imstb_rectpack.h:128
stbrp_coord h
Definition imstb_rectpack.h:125