Browse Source

stb_rect_pack: Fix two bugs.

stbrp__skyline_find_best_pos didn't correctly handle rects too
large to ever fit inside the context. Since that function also
pads the width up to a multiple of the alignment, it makes the
most sense to do that check right after (but before entering
the main packing loop).

While we're here, also fix an off-by-1 bug in the best-fit
heuristic where it didn't want to use the last row in
certain cases.

Fixes issue #701.
Fabian Giesen 6 years ago
parent
commit
ae431d75e0
1 changed files with 9 additions and 1 deletions
  1. 9 1
      stb_rect_pack.h

+ 9 - 1
stb_rect_pack.h

@@ -31,6 +31,7 @@
 //    
 //  Bugfixes / warning fixes
 //    Jeremy Jaussaud
+//    Fabian Giesen
 //
 // Version history:
 //
@@ -348,6 +349,13 @@ static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int widt
    width -= width % c->align;
    STBRP_ASSERT(width % c->align == 0);
 
+   // if it can't possibly fit, bail immediately
+   if (width > c->width || height > c->height) {
+      fr.prev_link = NULL;
+      fr.x = fr.y = 0;
+      return fr;
+   }
+
    node = c->active_head;
    prev = &c->active_head;
    while (node->x + width <= c->width) {
@@ -411,7 +419,7 @@ static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int widt
          }
          STBRP_ASSERT(node->next->x > xpos && node->x <= xpos);
          y = stbrp__skyline_find_min_y(c, node, xpos, width, &waste);
-         if (y + height < c->height) {
+         if (y + height <= c->height) {
             if (y <= best_y) {
                if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) {
                   best_x = xpos;