Skip to content

Commit 2a08e01

Browse files
committed
Slim down stb_rect_pack/stb_truetype
1 parent 7fc8026 commit 2a08e01

2 files changed

Lines changed: 206 additions & 1313 deletions

File tree

deps/stb/stb_rect_pack.h

Lines changed: 49 additions & 155 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@
1313
*
1414
* More docs to come.
1515
*
16-
* No memory allocations; uses qsort() and assert() from stdlib.
17-
* Can override those by defining STBRP_SORT and STBRP_ASSERT.
16+
* No memory allocations; uses qsort() from stdlib.
1817
*
1918
* This library currently uses the Skyline Bottom-Left algorithm.
2019
*
@@ -30,13 +29,6 @@
3029
* Martins Mozeiko
3130
* Bugfixes / warning fixes
3231
* [your name could be here]
33-
*
34-
* Version history:
35-
*
36-
* 0.06 (2015-04-15) added STBRP_SORT to allow replacing qsort
37-
* 0.05: added STBRP_ASSERT to allow replacing assert
38-
* 0.04: fixed minor bug in STBRP_LARGE_RECTS support
39-
* 0.01: initial release
4032
*/
4133

4234
#ifndef STB_INCLUDE_STB_RECT_PACK_H
@@ -58,12 +50,6 @@ typedef struct stbrp_context stbrp_context;
5850
typedef struct stbrp_node stbrp_node;
5951
typedef struct stbrp_rect stbrp_rect;
6052

61-
#ifdef STBRP_LARGE_RECTS
62-
typedef int stbrp_coord;
63-
#else
64-
typedef unsigned short stbrp_coord;
65-
#endif
66-
6753
STBRP_DEF void stbrp_pack_rects (stbrp_context *context,
6854
stbrp_rect *rects, int num_rects);
6955

@@ -92,8 +78,8 @@ STBRP_DEF void stbrp_pack_rects (stbrp_context *context,
9278
struct stbrp_rect
9379
{
9480
int id; /* reserved for your use: */
95-
stbrp_coord w, h; /* input: */
96-
stbrp_coord x, y; /* output: */
81+
uint16_t w, h; /* input: */
82+
uint16_t x, y; /* output: */
9783
int was_packed; /* non-zero if valid packing */
9884
}; /* 16 bytes, nominally */
9985

@@ -122,21 +108,6 @@ STBRP_DEF void stbrp_init_target (stbrp_context *context,
122108
* may run out of temporary storage and be unable to pack some rectangles.
123109
*/
124110

125-
STBRP_DEF void stbrp_setup_allow_out_of_mem (stbrp_context *context, int allow_out_of_mem);
126-
127-
/* Optionally call this function after init but before doing any packing to
128-
* change the handling of the out-of-temp-memory scenario, described above.
129-
* If you call init again, this will be reset to the default (false).
130-
*/
131-
132-
133-
STBRP_DEF void stbrp_setup_heuristic (stbrp_context *context, int heuristic);
134-
135-
/* Optionally select which packing heuristic the library should use. Different
136-
* heuristics will produce better/worse results for different data sets.
137-
* If you call init again, this will be reset to the default.
138-
*/
139-
140111
enum
141112
{
142113
STBRP_HEURISTIC_Skyline_default=0,
@@ -150,7 +121,7 @@ enum
150121

151122
struct stbrp_node
152123
{
153-
stbrp_coord x,y;
124+
uint16_t x,y;
154125
stbrp_node *next;
155126
};
156127

@@ -176,63 +147,16 @@ struct stbrp_context
176147
/* IMPLEMENTATION SECTION */
177148

178149
#ifdef STB_RECT_PACK_IMPLEMENTATION
179-
#ifndef STBRP_SORT
180150
#include <stdlib.h>
181-
#define STBRP_SORT qsort
182-
#endif
183-
184-
#ifndef STBRP_ASSERT
185-
#include <assert.h>
186-
#define STBRP_ASSERT assert
187-
#endif
188151

189152
enum
190153
{
191154
STBRP__INIT_skyline = 1
192155
};
193156

194-
STBRP_DEF void stbrp_setup_heuristic(stbrp_context *context, int heuristic)
195-
{
196-
switch (context->init_mode)
197-
{
198-
case STBRP__INIT_skyline:
199-
STBRP_ASSERT(heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight || heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight);
200-
context->heuristic = heuristic;
201-
break;
202-
default:
203-
STBRP_ASSERT(0);
204-
}
205-
}
206-
207-
STBRP_DEF void stbrp_setup_allow_out_of_mem(stbrp_context *context, int allow_out_of_mem)
208-
{
209-
/* if it's ok to run out of memory, then don't bother aligning them;
210-
* this gives better packing, but may fail due to OOM (even though
211-
* the rectangles easily fit). @TODO a smarter approach would be to only
212-
* quantize once we've hit OOM, then we could get rid of this parameter.
213-
*/
214-
if (allow_out_of_mem)
215-
context->align = 1;
216-
else
217-
{
218-
/* if it's not ok to run out of memory, then quantize the widths
219-
* so that num_nodes is always enough nodes.
220-
*
221-
* I.e. num_nodes * align >= width
222-
* align >= width / num_nodes
223-
* align = ceil(width/num_nodes)
224-
*/
225-
context->align = (context->width + context->num_nodes-1) / context->num_nodes;
226-
}
227-
}
228-
229157
STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes)
230158
{
231159
int i;
232-
#ifndef STBRP_LARGE_RECTS
233-
STBRP_ASSERT(width <= 0xffff && height <= 0xffff);
234-
#endif
235-
236160
for (i=0; i < num_nodes-1; ++i)
237161
nodes[i].next = &nodes[i+1];
238162
nodes[i].next = NULL;
@@ -243,19 +167,15 @@ STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height,
243167
context->width = width;
244168
context->height = height;
245169
context->num_nodes = num_nodes;
246-
stbrp_setup_allow_out_of_mem(context, 0);
170+
context->align = (context->width + context->num_nodes-1) / context->num_nodes;
247171

248172
/* node 0 is the full width,
249173
* node 1 is the sentinel (lets us not store width explicitly) */
250174
context->extra[0].x = 0;
251175
context->extra[0].y = 0;
252176
context->extra[0].next = &context->extra[1];
253-
context->extra[1].x = (stbrp_coord) width;
254-
#ifdef STBRP_LARGE_RECTS
255-
context->extra[1].y = (1<<30);
256-
#else
177+
context->extra[1].x = (uint16_t) width;
257178
context->extra[1].y = 65535;
258-
#endif
259179
context->extra[1].next = NULL;
260180
}
261181

@@ -266,11 +186,6 @@ static int stbrp__skyline_find_min_y(stbrp_context *c,
266186
int min_y, visited_width, waste_area;
267187
stbrp_node *node = first;
268188
int x1 = x0 + width;
269-
270-
STBRP_ASSERT(first->x <= x0);
271-
STBRP_ASSERT(node->next->x > x0);
272-
STBRP_ASSERT(node->x <= x0);
273-
274189
min_y = 0;
275190
waste_area = 0;
276191
visited_width = 0;
@@ -322,7 +237,6 @@ static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int widt
322237
/* align to multiple of c->align */
323238
width = (width + c->align - 1);
324239
width -= width % c->align;
325-
STBRP_ASSERT(width % c->align == 0);
326240

327241
node = c->active_head;
328242
prev = &c->active_head;
@@ -390,7 +304,6 @@ static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int widt
390304
{
391305
int xpos = tail->x - width;
392306
int y,waste;
393-
STBRP_ASSERT(xpos >= 0);
394307

395308
/* find the left position that matches this */
396309
while (node->next->x <= xpos)
@@ -399,7 +312,6 @@ static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int widt
399312
node = node->next;
400313
}
401314

402-
STBRP_ASSERT(node->next->x > xpos && node->x <= xpos);
403315
y = stbrp__skyline_find_min_y(c, node, xpos, width, &waste);
404316

405317
if (y + height < c->height)
@@ -409,7 +321,6 @@ static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int widt
409321
if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x))
410322
{
411323
best_x = xpos;
412-
STBRP_ASSERT(y <= best_y);
413324
best_y = y;
414325
best_waste = waste;
415326
best = prev;
@@ -429,7 +340,6 @@ static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int widt
429340
static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context, int width, int height)
430341
{
431342
/* find best position according to heuristic */
432-
stbrp_node *node, *cur;
433343
stbrp__findresult res = stbrp__skyline_find_best_pos(context, width, height);
434344

435345
/* bail if:
@@ -438,52 +348,51 @@ static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context, i
438348
* 3. we're out of memory
439349
*/
440350
if (res.prev_link == NULL || res.y + height > context->height || context->free_head == NULL)
441-
{
442351
res.prev_link = NULL;
443-
return res;
444-
}
445-
446-
/* on success, create new node */
447-
node = context->free_head;
448-
node->x = (stbrp_coord) res.x;
449-
node->y = (stbrp_coord) (res.y + height);
450-
451-
context->free_head = node->next;
352+
else
353+
{
354+
stbrp_node *cur;
355+
/* on success, create new node */
356+
stbrp_node *node = context->free_head;
357+
node->x = (uint16_t) res.x;
358+
node->y = (uint16_t) (res.y + height);
452359

453-
/* insert the new node into the right starting point, and
454-
* let 'cur' point to the remaining nodes needing to be
455-
* stiched back in
456-
*/
360+
context->free_head = node->next;
457361

458-
cur = *res.prev_link;
459-
if (cur->x < res.x)
460-
{
461-
/* preserve the existing one, so start testing with the next one */
462-
stbrp_node *next = cur->next;
463-
cur->next = node;
464-
cur = next;
465-
}
466-
else
467-
*res.prev_link = node;
362+
/* insert the new node into the right starting point, and
363+
* let 'cur' point to the remaining nodes needing to be
364+
* stiched back in
365+
*/
468366

469-
/* from here, traverse cur and free the nodes, until we get to one
470-
* that shouldn't be freed */
471-
while (cur->next && cur->next->x <= res.x + width)
472-
{
473-
stbrp_node *next = cur->next;
367+
cur = *res.prev_link;
368+
if (cur->x < res.x)
369+
{
370+
/* preserve the existing one, so start testing with the next one */
371+
stbrp_node *next = cur->next;
372+
cur->next = node;
373+
cur = next;
374+
}
375+
else
376+
*res.prev_link = node;
474377

475-
/* move the current node to the free list */
476-
cur->next = context->free_head;
477-
context->free_head = cur;
478-
cur = next;
479-
}
378+
/* from here, traverse cur and free the nodes, until we get to one
379+
* that shouldn't be freed */
380+
while (cur->next && cur->next->x <= res.x + width)
381+
{
382+
stbrp_node *next = cur->next;
480383

481-
/* stitch the list back in */
482-
node->next = cur;
384+
/* move the current node to the free list */
385+
cur->next = context->free_head;
386+
context->free_head = cur;
387+
cur = next;
388+
}
483389

484-
if (cur->x < res.x + width)
485-
cur->x = (stbrp_coord) (res.x + width);
390+
/* stitch the list back in */
391+
node->next = cur;
486392

393+
if (cur->x < res.x + width)
394+
cur->x = (uint16_t) (res.x + width);
395+
}
487396
return res;
488397
}
489398

@@ -498,29 +407,14 @@ static int rect_height_compare(const void *a, const void *b)
498407
return (p->w > q->w) ? -1 : (p->w < q->w);
499408
}
500409

501-
STBRP_DEF int rect_width_compare(const void *a, const void *b)
502-
{
503-
stbrp_rect *p = (stbrp_rect *) a;
504-
stbrp_rect *q = (stbrp_rect *) b;
505-
if (p->w > q->w)
506-
return -1;
507-
if (p->w < q->w)
508-
return 1;
509-
return (p->h > q->h) ? -1 : (p->h < q->h);
510-
}
511-
512410
static int rect_original_order(const void *a, const void *b)
513411
{
514412
stbrp_rect *p = (stbrp_rect *) a;
515413
stbrp_rect *q = (stbrp_rect *) b;
516414
return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed);
517415
}
518416

519-
#ifdef STBRP_LARGE_RECTS
520-
#define STBRP__MAXVAL 0xffffffff
521-
#else
522417
#define STBRP__MAXVAL 0xffff
523-
#endif
524418

525419
STBRP_DEF void stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects)
526420
{
@@ -531,22 +425,22 @@ STBRP_DEF void stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int n
531425
rects[i].was_packed = i;
532426

533427
/* sort according to heuristic */
534-
STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_height_compare);
428+
qsort(rects, num_rects, sizeof(rects[0]), rect_height_compare);
535429

536430
for (i=0; i < num_rects; ++i)
537431
{
538432
stbrp__findresult fr = stbrp__skyline_pack_rectangle(context, rects[i].w, rects[i].h);
539433
if (fr.prev_link)
540434
{
541-
rects[i].x = (stbrp_coord) fr.x;
542-
rects[i].y = (stbrp_coord) fr.y;
543-
} else {
544-
rects[i].x = rects[i].y = STBRP__MAXVAL;
435+
rects[i].x = (uint16_t) fr.x;
436+
rects[i].y = (uint16_t) fr.y;
545437
}
438+
else
439+
rects[i].x = rects[i].y = STBRP__MAXVAL;
546440
}
547441

548442
/* unsort */
549-
STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_original_order);
443+
qsort(rects, num_rects, sizeof(rects[0]), rect_original_order);
550444

551445
/* set was_packed flags */
552446
for (i=0; i < num_rects; ++i)

0 commit comments

Comments
 (0)