| 445 | } |
| 446 | |
| 447 | static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context* context, int width, int height) |
| 448 | { |
| 449 | // find best position according to heuristic |
| 450 | stbrp__findresult res = stbrp__skyline_find_best_pos(context, width, height); |
| 451 | stbrp_node* node, * cur; |
| 452 | |
| 453 | // bail if: |
| 454 | // 1. it failed |
| 455 | // 2. the best node doesn't fit (we don't always check this) |
| 456 | // 3. we're out of memory |
| 457 | if (res.prev_link == NULL || res.y + height > context->height || context->free_head == NULL) { |
| 458 | res.prev_link = NULL; |
| 459 | return res; |
| 460 | } |
| 461 | |
| 462 | // on success, create new node |
| 463 | node = context->free_head; |
| 464 | node->x = (stbrp_coord)res.x; |
| 465 | node->y = (stbrp_coord)(res.y + height); |
| 466 | |
| 467 | context->free_head = node->next; |
| 468 | |
| 469 | // insert the new node into the right starting point, and |
| 470 | // let 'cur' point to the remaining nodes needing to be |
| 471 | // stiched back in |
| 472 | |
| 473 | cur = *res.prev_link; |
| 474 | if (cur->x < res.x) { |
| 475 | // preserve the existing one, so start testing with the next one |
| 476 | stbrp_node* next = cur->next; |
| 477 | cur->next = node; |
| 478 | cur = next; |
| 479 | } |
| 480 | else { |
| 481 | *res.prev_link = node; |
| 482 | } |
| 483 | |
| 484 | // from here, traverse cur and free the nodes, until we get to one |
| 485 | // that shouldn't be freed |
| 486 | while (cur->next && cur->next->x <= res.x + width) { |
| 487 | stbrp_node* next = cur->next; |
| 488 | // move the current node to the free list |
| 489 | cur->next = context->free_head; |
| 490 | context->free_head = cur; |
| 491 | cur = next; |
| 492 | } |
| 493 | |
| 494 | // stitch the list back in |
| 495 | node->next = cur; |
| 496 | |
| 497 | if (cur->x < res.x + width) |
| 498 | cur->x = (stbrp_coord)(res.x + width); |
| 499 | |
| 500 | #ifdef _DEBUG |
| 501 | cur = context->active_head; |
| 502 | while (cur->x < context->width) { |
| 503 | STBRP_ASSERT(cur->x < cur->next->x); |
| 504 | cur = cur->next; |
no test coverage detected