Changeset e66fd66 in opengl-game for IMGUI/imstb_rectpack.h


Ignore:
Timestamp:
Dec 5, 2020, 7:14:31 PM (4 years ago)
Author:
Dmitry Portnoy <dportnoy@…>
Branches:
feature/imgui-sdl, master
Children:
95c657f
Parents:
78c3045
Message:

In OpenGLReference, change all enums to enum classes and update IMGUI to the latest version

File:
1 moved

Legend:

Unmodified
Added
Removed
  • IMGUI/imstb_rectpack.h

    r78c3045 re66fd66  
    1 // stb_rect_pack.h - v0.11 - public domain - rectangle packing
     1// [DEAR IMGUI]
     2// This is a slightly modified version of stb_rect_pack.h 1.00.
     3// Those changes would need to be pushed into nothings/stb:
     4// - Added STBRP__CDECL
     5// Grep for [DEAR IMGUI] to find the changes.
     6
     7// stb_rect_pack.h - v1.00 - public domain - rectangle packing
    28// Sean Barrett 2014
    39//
     
    3238//  Bugfixes / warning fixes
    3339//    Jeremy Jaussaud
     40//    Fabian Giesen
    3441//
    3542// Version history:
    3643//
     44//     1.00  (2019-02-25)  avoid small space waste; gracefully fail too-wide rectangles
     45//     0.99  (2019-02-07)  warning fixes
    3746//     0.11  (2017-03-03)  return packing success/fail result
    3847//     0.10  (2016-10-25)  remove cast-away-const to avoid warnings
     
    6978#endif
    7079
    71    typedef struct stbrp_context stbrp_context;
    72    typedef struct stbrp_node    stbrp_node;
    73    typedef struct stbrp_rect    stbrp_rect;
     80typedef struct stbrp_context stbrp_context;
     81typedef struct stbrp_node    stbrp_node;
     82typedef struct stbrp_rect    stbrp_rect;
    7483
    7584#ifdef STBRP_LARGE_RECTS
    76    typedef int            stbrp_coord;
     85typedef int            stbrp_coord;
    7786#else
    78    typedef unsigned short stbrp_coord;
    79 #endif
    80 
    81    STBRP_DEF int stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects);
    82    // Assign packed locations to rectangles. The rectangles are of type
    83    // 'stbrp_rect' defined below, stored in the array 'rects', and there
    84    // are 'num_rects' many of them.
    85    //
    86    // Rectangles which are successfully packed have the 'was_packed' flag
    87    // set to a non-zero value and 'x' and 'y' store the minimum location
    88    // on each axis (i.e. bottom-left in cartesian coordinates, top-left
    89    // if you imagine y increasing downwards). Rectangles which do not fit
    90    // have the 'was_packed' flag set to 0.
    91    //
    92    // You should not try to access the 'rects' array from another thread
    93    // while this function is running, as the function temporarily reorders
    94    // the array while it executes.
    95    //
    96    // To pack into another rectangle, you need to call stbrp_init_target
    97    // again. To continue packing into the same rectangle, you can call
    98    // this function again. Calling this multiple times with multiple rect
    99    // arrays will probably produce worse packing results than calling it
    100    // a single time with the full rectangle array, but the option is
    101    // available.
    102    //
    103    // The function returns 1 if all of the rectangles were successfully
    104    // packed and 0 otherwise.
    105 
    106    struct stbrp_rect
    107    {
    108       // reserved for your use:
    109       int            id;
    110 
    111       // input:
    112       stbrp_coord    w, h;
    113 
    114       // output:
    115       stbrp_coord    x, y;
    116       int            was_packed;  // non-zero if valid packing
    117 
    118    }; // 16 bytes, nominally
    119 
    120 
    121    STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes);
    122    // Initialize a rectangle packer to:
    123    //    pack a rectangle that is 'width' by 'height' in dimensions
    124    //    using temporary storage provided by the array 'nodes', which is 'num_nodes' long
    125    //
    126    // You must call this function every time you start packing into a new target.
    127    //
    128    // There is no "shutdown" function. The 'nodes' memory must stay valid for
    129    // the following stbrp_pack_rects() call (or calls), but can be freed after
    130    // the call (or calls) finish.
    131    //
    132    // Note: to guarantee best results, either:
    133    //       1. make sure 'num_nodes' >= 'width'
    134    //   or  2. call stbrp_allow_out_of_mem() defined below with 'allow_out_of_mem = 1'
    135    //
    136    // If you don't do either of the above things, widths will be quantized to multiples
    137    // of small integers to guarantee the algorithm doesn't run out of temporary storage.
    138    //
    139    // If you do #2, then the non-quantized algorithm will be used, but the algorithm
    140    // may run out of temporary storage and be unable to pack some rectangles.
    141 
    142    STBRP_DEF void stbrp_setup_allow_out_of_mem(stbrp_context *context, int allow_out_of_mem);
    143    // Optionally call this function after init but before doing any packing to
    144    // change the handling of the out-of-temp-memory scenario, described above.
    145    // If you call init again, this will be reset to the default (false).
    146 
    147 
    148    STBRP_DEF void stbrp_setup_heuristic(stbrp_context *context, int heuristic);
    149    // Optionally select which packing heuristic the library should use. Different
    150    // heuristics will produce better/worse results for different data sets.
    151    // If you call init again, this will be reset to the default.
    152 
    153    enum
    154    {
    155       STBRP_HEURISTIC_Skyline_default = 0,
    156       STBRP_HEURISTIC_Skyline_BL_sortHeight = STBRP_HEURISTIC_Skyline_default,
    157       STBRP_HEURISTIC_Skyline_BF_sortHeight
    158    };
    159 
    160 
    161    //////////////////////////////////////////////////////////////////////////////
    162    //
    163    // the details of the following structures don't matter to you, but they must
    164    // be visible so you can handle the memory allocations for them
    165 
    166    struct stbrp_node
    167    {
    168       stbrp_coord  x, y;
    169       stbrp_node  *next;
    170    };
    171 
    172    struct stbrp_context
    173    {
    174       int width;
    175       int height;
    176       int align;
    177       int init_mode;
    178       int heuristic;
    179       int num_nodes;
    180       stbrp_node *active_head;
    181       stbrp_node *free_head;
    182       stbrp_node extra[2]; // we allocate two extra nodes so optimal user-node-count is 'width' not 'width+2'
    183    };
     87typedef unsigned short stbrp_coord;
     88#endif
     89
     90STBRP_DEF int stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int num_rects);
     91// Assign packed locations to rectangles. The rectangles are of type
     92// 'stbrp_rect' defined below, stored in the array 'rects', and there
     93// are 'num_rects' many of them.
     94//
     95// Rectangles which are successfully packed have the 'was_packed' flag
     96// set to a non-zero value and 'x' and 'y' store the minimum location
     97// on each axis (i.e. bottom-left in cartesian coordinates, top-left
     98// if you imagine y increasing downwards). Rectangles which do not fit
     99// have the 'was_packed' flag set to 0.
     100//
     101// You should not try to access the 'rects' array from another thread
     102// while this function is running, as the function temporarily reorders
     103// the array while it executes.
     104//
     105// To pack into another rectangle, you need to call stbrp_init_target
     106// again. To continue packing into the same rectangle, you can call
     107// this function again. Calling this multiple times with multiple rect
     108// arrays will probably produce worse packing results than calling it
     109// a single time with the full rectangle array, but the option is
     110// available.
     111//
     112// The function returns 1 if all of the rectangles were successfully
     113// packed and 0 otherwise.
     114
     115struct stbrp_rect
     116{
     117   // reserved for your use:
     118   int            id;
     119
     120   // input:
     121   stbrp_coord    w, h;
     122
     123   // output:
     124   stbrp_coord    x, y;
     125   int            was_packed;  // non-zero if valid packing
     126
     127}; // 16 bytes, nominally
     128
     129
     130STBRP_DEF void stbrp_init_target (stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes);
     131// Initialize a rectangle packer to:
     132//    pack a rectangle that is 'width' by 'height' in dimensions
     133//    using temporary storage provided by the array 'nodes', which is 'num_nodes' long
     134//
     135// You must call this function every time you start packing into a new target.
     136//
     137// There is no "shutdown" function. The 'nodes' memory must stay valid for
     138// the following stbrp_pack_rects() call (or calls), but can be freed after
     139// the call (or calls) finish.
     140//
     141// Note: to guarantee best results, either:
     142//       1. make sure 'num_nodes' >= 'width'
     143//   or  2. call stbrp_allow_out_of_mem() defined below with 'allow_out_of_mem = 1'
     144//
     145// If you don't do either of the above things, widths will be quantized to multiples
     146// of small integers to guarantee the algorithm doesn't run out of temporary storage.
     147//
     148// If you do #2, then the non-quantized algorithm will be used, but the algorithm
     149// may run out of temporary storage and be unable to pack some rectangles.
     150
     151STBRP_DEF void stbrp_setup_allow_out_of_mem (stbrp_context *context, int allow_out_of_mem);
     152// Optionally call this function after init but before doing any packing to
     153// change the handling of the out-of-temp-memory scenario, described above.
     154// If you call init again, this will be reset to the default (false).
     155
     156
     157STBRP_DEF void stbrp_setup_heuristic (stbrp_context *context, int heuristic);
     158// Optionally select which packing heuristic the library should use. Different
     159// heuristics will produce better/worse results for different data sets.
     160// If you call init again, this will be reset to the default.
     161
     162enum
     163{
     164   STBRP_HEURISTIC_Skyline_default=0,
     165   STBRP_HEURISTIC_Skyline_BL_sortHeight = STBRP_HEURISTIC_Skyline_default,
     166   STBRP_HEURISTIC_Skyline_BF_sortHeight
     167};
     168
     169
     170//////////////////////////////////////////////////////////////////////////////
     171//
     172// the details of the following structures don't matter to you, but they must
     173// be visible so you can handle the memory allocations for them
     174
     175struct stbrp_node
     176{
     177   stbrp_coord  x,y;
     178   stbrp_node  *next;
     179};
     180
     181struct stbrp_context
     182{
     183   int width;
     184   int height;
     185   int align;
     186   int init_mode;
     187   int heuristic;
     188   int num_nodes;
     189   stbrp_node *active_head;
     190   stbrp_node *free_head;
     191   stbrp_node extra[2]; // we allocate two extra nodes so optimal user-node-count is 'width' not 'width+2'
     192};
    184193
    185194#ifdef __cplusplus
     
    205214#endif
    206215
     216// [DEAR IMGUI] Added STBRP__CDECL
    207217#ifdef _MSC_VER
    208218#define STBRP__NOTUSED(v)  (void)(v)
     
    221231{
    222232   switch (context->init_mode) {
    223    case STBRP__INIT_skyline:
    224       STBRP_ASSERT(heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight || heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight);
    225       context->heuristic = heuristic;
    226       break;
    227    default:
    228       STBRP_ASSERT(0);
     233      case STBRP__INIT_skyline:
     234         STBRP_ASSERT(heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight || heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight);
     235         context->heuristic = heuristic;
     236         break;
     237      default:
     238         STBRP_ASSERT(0);
    229239   }
    230240}
     
    246256      //                  align = ceil(width/num_nodes)
    247257
    248       context->align = (context->width + context->num_nodes - 1) / context->num_nodes;
     258      context->align = (context->width + context->num_nodes-1) / context->num_nodes;
    249259   }
    250260}
     
    257267#endif
    258268
    259    for (i = 0; i < num_nodes - 1; ++i)
    260       nodes[i].next = &nodes[i + 1];
     269   for (i=0; i < num_nodes-1; ++i)
     270      nodes[i].next = &nodes[i+1];
    261271   nodes[i].next = NULL;
    262272   context->init_mode = STBRP__INIT_skyline;
     
    273283   context->extra[0].y = 0;
    274284   context->extra[0].next = &context->extra[1];
    275    context->extra[1].x = (stbrp_coord)width;
     285   context->extra[1].x = (stbrp_coord) width;
    276286#ifdef STBRP_LARGE_RECTS
    277    context->extra[1].y = (1 << 30);
     287   context->extra[1].y = (1<<30);
    278288#else
    279289   context->extra[1].y = 65535;
     
    293303   STBRP_ASSERT(first->x <= x0);
    294304
    295 #if 0
     305   #if 0
    296306   // skip in case we're past the node
    297307   while (node->next->x <= x0)
    298308      ++node;
    299 #else
     309   #else
    300310   STBRP_ASSERT(node->next->x > x0); // we ended up handling this in the caller for efficiency
    301 #endif
     311   #endif
    302312
    303313   STBRP_ASSERT(node->x <= x0);
     
    318328         else
    319329            visited_width += node->next->x - node->x;
    320       }
    321       else {
     330      } else {
    322331         // add waste area
    323332         int under_width = node->next->x - node->x;
     
    336345typedef struct
    337346{
    338    int x, y;
     347   int x,y;
    339348   stbrp_node **prev_link;
    340349} stbrp__findresult;
     
    342351static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int width, int height)
    343352{
    344    int best_waste = (1 << 30), best_x, best_y = (1 << 30);
     353   int best_waste = (1<<30), best_x, best_y = (1 << 30);
    345354   stbrp__findresult fr;
    346355   stbrp_node **prev, *node, *tail, **best = NULL;
     
    351360   STBRP_ASSERT(width % c->align == 0);
    352361
     362   // if it can't possibly fit, bail immediately
     363   if (width > c->width || height > c->height) {
     364      fr.prev_link = NULL;
     365      fr.x = fr.y = 0;
     366      return fr;
     367   }
     368
    353369   node = c->active_head;
    354370   prev = &c->active_head;
    355371   while (node->x + width <= c->width) {
    356       int y, waste;
     372      int y,waste;
    357373      y = stbrp__skyline_find_min_y(c, node, node->x, width, &waste);
    358374      if (c->heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight) { // actually just want to test BL
    359                                                                    // bottom left
     375         // bottom left
    360376         if (y < best_y) {
    361377            best_y = y;
    362378            best = prev;
    363379         }
    364       }
    365       else {
     380      } else {
    366381         // best-fit
    367382         if (y + height <= c->height) {
     
    406421      while (tail) {
    407422         int xpos = tail->x - width;
    408          int y, waste;
     423         int y,waste;
    409424         STBRP_ASSERT(xpos >= 0);
    410425         // find the left position that matches this
     
    415430         STBRP_ASSERT(node->next->x > xpos && node->x <= xpos);
    416431         y = stbrp__skyline_find_min_y(c, node, xpos, width, &waste);
    417          if (y + height < c->height) {
     432         if (y + height <= c->height) {
    418433            if (y <= best_y) {
    419                if (y < best_y || waste < best_waste || (waste == best_waste && xpos < best_x)) {
     434               if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) {
    420435                  best_x = xpos;
    421436                  STBRP_ASSERT(y <= best_y);
     
    427442         }
    428443         tail = tail->next;
    429       }
     444      }         
    430445   }
    431446
     
    453468   // on success, create new node
    454469   node = context->free_head;
    455    node->x = (stbrp_coord)res.x;
    456    node->y = (stbrp_coord)(res.y + height);
     470   node->x = (stbrp_coord) res.x;
     471   node->y = (stbrp_coord) (res.y + height);
    457472
    458473   context->free_head = node->next;
     
    468483      cur->next = node;
    469484      cur = next;
    470    }
    471    else {
     485   } else {
    472486      *res.prev_link = node;
    473487   }
     
    487501
    488502   if (cur->x < res.x + width)
    489       cur->x = (stbrp_coord)(res.x + width);
     503      cur->x = (stbrp_coord) (res.x + width);
    490504
    491505#ifdef _DEBUG
     
    498512
    499513   {
    500       int count = 0;
     514      int count=0;
    501515      cur = context->active_head;
    502516      while (cur) {
     
    509523         ++count;
    510524      }
    511       STBRP_ASSERT(count == context->num_nodes + 2);
     525      STBRP_ASSERT(count == context->num_nodes+2);
    512526   }
    513527#endif
     
    516530}
    517531
     532// [DEAR IMGUI] Added STBRP__CDECL
    518533static int STBRP__CDECL rect_height_compare(const void *a, const void *b)
    519534{
    520    const stbrp_rect *p = (const stbrp_rect *)a;
    521    const stbrp_rect *q = (const stbrp_rect *)b;
     535   const stbrp_rect *p = (const stbrp_rect *) a;
     536   const stbrp_rect *q = (const stbrp_rect *) b;
    522537   if (p->h > q->h)
    523538      return -1;
     
    527542}
    528543
     544// [DEAR IMGUI] Added STBRP__CDECL
    529545static int STBRP__CDECL rect_original_order(const void *a, const void *b)
    530546{
    531    const stbrp_rect *p = (const stbrp_rect *)a;
    532    const stbrp_rect *q = (const stbrp_rect *)b;
     547   const stbrp_rect *p = (const stbrp_rect *) a;
     548   const stbrp_rect *q = (const stbrp_rect *) b;
    533549   return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed);
    534550}
     
    545561
    546562   // we use the 'was_packed' field internally to allow sorting/unsorting
    547    for (i = 0; i < num_rects; ++i) {
     563   for (i=0; i < num_rects; ++i) {
    548564      rects[i].was_packed = i;
    549 #ifndef STBRP_LARGE_RECTS
    550       STBRP_ASSERT(rects[i].w <= 0xffff && rects[i].h <= 0xffff);
    551 #endif
    552565   }
    553566
     
    555568   STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_height_compare);
    556569
    557    for (i = 0; i < num_rects; ++i) {
     570   for (i=0; i < num_rects; ++i) {
    558571      if (rects[i].w == 0 || rects[i].h == 0) {
    559572         rects[i].x = rects[i].y = 0;  // empty rect needs no space
    560       }
    561       else {
     573      } else {
    562574         stbrp__findresult fr = stbrp__skyline_pack_rectangle(context, rects[i].w, rects[i].h);
    563575         if (fr.prev_link) {
    564             rects[i].x = (stbrp_coord)fr.x;
    565             rects[i].y = (stbrp_coord)fr.y;
    566          }
    567          else {
     576            rects[i].x = (stbrp_coord) fr.x;
     577            rects[i].y = (stbrp_coord) fr.y;
     578         } else {
    568579            rects[i].x = rects[i].y = STBRP__MAXVAL;
    569580         }
     
    575586
    576587   // set was_packed flags and all_rects_packed status
    577    for (i = 0; i < num_rects; ++i) {
     588   for (i=0; i < num_rects; ++i) {
    578589      rects[i].was_packed = !(rects[i].x == STBRP__MAXVAL && rects[i].y == STBRP__MAXVAL);
    579590      if (!rects[i].was_packed)
     
    592603ALTERNATIVE A - MIT License
    593604Copyright (c) 2017 Sean Barrett
    594 Permission is hereby granted, free of charge, to any person obtaining a copy of
    595 this software and associated documentation files (the "Software"), to deal in
    596 the Software without restriction, including without limitation the rights to
    597 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
    598 of the Software, and to permit persons to whom the Software is furnished to do
     605Permission is hereby granted, free of charge, to any person obtaining a copy of 
     606this software and associated documentation files (the "Software"), to deal in 
     607the Software without restriction, including without limitation the rights to 
     608use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 
     609of the Software, and to permit persons to whom the Software is furnished to do 
    599610so, subject to the following conditions:
    600 The above copyright notice and this permission notice shall be included in all
     611The above copyright notice and this permission notice shall be included in all 
    601612copies or substantial portions of the Software.
    602 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    603 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    604 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    605 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    606 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    607 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     613THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
     614IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
     615FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
     616AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
     617LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
     618OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
    608619SOFTWARE.
    609620------------------------------------------------------------------------------
    610621ALTERNATIVE B - Public Domain (www.unlicense.org)
    611622This is free and unencumbered software released into the public domain.
    612 Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
    613 software, either in source code form or as a compiled binary, for any purpose,
     623Anyone is free to copy, modify, publish, use, compile, sell, or distribute this 
     624software, either in source code form or as a compiled binary, for any purpose, 
    614625commercial or non-commercial, and by any means.
    615 In jurisdictions that recognize copyright laws, the author or authors of this
    616 software dedicate any and all copyright interest in the software to the public
    617 domain. We make this dedication for the benefit of the public at large and to
    618 the detriment of our heirs and successors. We intend this dedication to be an
    619 overt act of relinquishment in perpetuity of all present and future rights to
     626In jurisdictions that recognize copyright laws, the author or authors of this 
     627software dedicate any and all copyright interest in the software to the public 
     628domain. We make this dedication for the benefit of the public at large and to 
     629the detriment of our heirs and successors. We intend this dedication to be an 
     630overt act of relinquishment in perpetuity of all present and future rights to 
    620631this software under copyright law.
    621 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    622 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    623 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    624 AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
    625 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
     632THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
     633IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
     634FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
     635AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 
     636ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 
    626637WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    627638------------------------------------------------------------------------------
Note: See TracChangeset for help on using the changeset viewer.