mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-15 05:00:09 +00:00
192 lines
6.0 KiB
C
192 lines
6.0 KiB
C
|
// stb_rect_pack.h - v0.99 - public domain - rectangle packing
|
||
|
// Sean Barrett 2014
|
||
|
//
|
||
|
// Useful for e.g. packing rectangular textures into an atlas.
|
||
|
// Does not do rotation.
|
||
|
//
|
||
|
// Not necessarily the awesomest packing method, but better than
|
||
|
// the totally naive one in stb_truetype (which is primarily what
|
||
|
// this is meant to replace).
|
||
|
//
|
||
|
// Has only had a few tests run, may have issues.
|
||
|
//
|
||
|
// More docs to come.
|
||
|
//
|
||
|
// No memory allocations; uses qsort() and assert() from stdlib.
|
||
|
// Can override those by defining STBRP_SORT and STBRP_ASSERT.
|
||
|
//
|
||
|
// This library currently uses the Skyline Bottom-Left algorithm.
|
||
|
//
|
||
|
// Please note: better rectangle packers are welcome! Please
|
||
|
// implement them to the same API, but with a different init
|
||
|
// function.
|
||
|
//
|
||
|
// Credits
|
||
|
//
|
||
|
// Library
|
||
|
// Sean Barrett
|
||
|
// Minor features
|
||
|
// Martins Mozeiko
|
||
|
// github:IntellectualKitty
|
||
|
//
|
||
|
// Bugfixes / warning fixes
|
||
|
// Jeremy Jaussaud
|
||
|
//
|
||
|
// Version history:
|
||
|
//
|
||
|
// 0.99 (2019-02-07) warning fixes
|
||
|
// 0.11 (2017-03-03) return packing success/fail result
|
||
|
// 0.10 (2016-10-25) remove cast-away-const to avoid warnings
|
||
|
// 0.09 (2016-08-27) fix compiler warnings
|
||
|
// 0.08 (2015-09-13) really fix bug with empty rects (w=0 or h=0)
|
||
|
// 0.07 (2015-09-13) fix bug with empty rects (w=0 or h=0)
|
||
|
// 0.06 (2015-04-15) added STBRP_SORT to allow replacing qsort
|
||
|
// 0.05: added STBRP_ASSERT to allow replacing assert
|
||
|
// 0.04: fixed minor bug in STBRP_LARGE_RECTS support
|
||
|
// 0.01: initial release
|
||
|
//
|
||
|
// LICENSE
|
||
|
//
|
||
|
// See end of file for license information.
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// INCLUDE SECTION
|
||
|
//
|
||
|
|
||
|
#ifndef STB_INCLUDE_STB_RECT_PACK_H
|
||
|
#define STB_INCLUDE_STB_RECT_PACK_H
|
||
|
|
||
|
#define STB_RECT_PACK_VERSION 1
|
||
|
|
||
|
#ifdef STBRP_STATIC
|
||
|
#define STBRP_DEF static
|
||
|
#else
|
||
|
#define STBRP_DEF extern
|
||
|
#endif
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
extern "C" {
|
||
|
#endif
|
||
|
|
||
|
typedef struct stbrp_context stbrp_context;
|
||
|
typedef struct stbrp_node stbrp_node;
|
||
|
typedef struct stbrp_rect stbrp_rect;
|
||
|
|
||
|
#ifdef STBRP_LARGE_RECTS
|
||
|
typedef int stbrp_coord;
|
||
|
#else
|
||
|
typedef unsigned short stbrp_coord;
|
||
|
#endif
|
||
|
|
||
|
STBRP_DEF int stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int num_rects);
|
||
|
// Assign packed locations to rectangles. The rectangles are of type
|
||
|
// 'stbrp_rect' defined below, stored in the array 'rects', and there
|
||
|
// are 'num_rects' many of them.
|
||
|
//
|
||
|
// Rectangles which are successfully packed have the 'was_packed' flag
|
||
|
// set to a non-zero value and 'x' and 'y' store the minimum location
|
||
|
// on each axis (i.e. bottom-left in cartesian coordinates, top-left
|
||
|
// if you imagine y increasing downwards). Rectangles which do not fit
|
||
|
// have the 'was_packed' flag set to 0.
|
||
|
//
|
||
|
// You should not try to access the 'rects' array from another thread
|
||
|
// while this function is running, as the function temporarily reorders
|
||
|
// the array while it executes.
|
||
|
//
|
||
|
// To pack into another rectangle, you need to call stbrp_init_target
|
||
|
// again. To continue packing into the same rectangle, you can call
|
||
|
// this function again. Calling this multiple times with multiple rect
|
||
|
// arrays will probably produce worse packing results than calling it
|
||
|
// a single time with the full rectangle array, but the option is
|
||
|
// available.
|
||
|
//
|
||
|
// The function returns 1 if all of the rectangles were successfully
|
||
|
// packed and 0 otherwise.
|
||
|
|
||
|
struct stbrp_rect
|
||
|
{
|
||
|
// reserved for your use:
|
||
|
int id;
|
||
|
|
||
|
// input:
|
||
|
stbrp_coord w, h;
|
||
|
|
||
|
// output:
|
||
|
stbrp_coord x, y;
|
||
|
int was_packed; // non-zero if valid packing
|
||
|
|
||
|
}; // 16 bytes, nominally
|
||
|
|
||
|
|
||
|
STBRP_DEF void stbrp_init_target (stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes);
|
||
|
// Initialize a rectangle packer to:
|
||
|
// pack a rectangle that is 'width' by 'height' in dimensions
|
||
|
// using temporary storage provided by the array 'nodes', which is 'num_nodes' long
|
||
|
//
|
||
|
// You must call this function every time you start packing into a new target.
|
||
|
//
|
||
|
// There is no "shutdown" function. The 'nodes' memory must stay valid for
|
||
|
// the following stbrp_pack_rects() call (or calls), but can be freed after
|
||
|
// the call (or calls) finish.
|
||
|
//
|
||
|
// Note: to guarantee best results, either:
|
||
|
// 1. make sure 'num_nodes' >= 'width'
|
||
|
// or 2. call stbrp_allow_out_of_mem() defined below with 'allow_out_of_mem = 1'
|
||
|
//
|
||
|
// If you don't do either of the above things, widths will be quantized to multiples
|
||
|
// of small integers to guarantee the algorithm doesn't run out of temporary storage.
|
||
|
//
|
||
|
// If you do #2, then the non-quantized algorithm will be used, but the algorithm
|
||
|
// may run out of temporary storage and be unable to pack some rectangles.
|
||
|
|
||
|
STBRP_DEF void stbrp_setup_allow_out_of_mem (stbrp_context *context, int allow_out_of_mem);
|
||
|
// Optionally call this function after init but before doing any packing to
|
||
|
// change the handling of the out-of-temp-memory scenario, described above.
|
||
|
// If you call init again, this will be reset to the default (false).
|
||
|
|
||
|
|
||
|
STBRP_DEF void stbrp_setup_heuristic (stbrp_context *context, int heuristic);
|
||
|
// Optionally select which packing heuristic the library should use. Different
|
||
|
// heuristics will produce better/worse results for different data sets.
|
||
|
// If you call init again, this will be reset to the default.
|
||
|
|
||
|
enum
|
||
|
{
|
||
|
STBRP_HEURISTIC_Skyline_default=0,
|
||
|
STBRP_HEURISTIC_Skyline_BL_sortHeight = STBRP_HEURISTIC_Skyline_default,
|
||
|
STBRP_HEURISTIC_Skyline_BF_sortHeight
|
||
|
};
|
||
|
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// the details of the following structures don't matter to you, but they must
|
||
|
// be visible so you can handle the memory allocations for them
|
||
|
|
||
|
struct stbrp_node
|
||
|
{
|
||
|
stbrp_coord x,y;
|
||
|
stbrp_node *next;
|
||
|
};
|
||
|
|
||
|
struct stbrp_context
|
||
|
{
|
||
|
int width;
|
||
|
int height;
|
||
|
int align;
|
||
|
int init_mode;
|
||
|
int heuristic;
|
||
|
int num_nodes;
|
||
|
stbrp_node *active_head;
|
||
|
stbrp_node *free_head;
|
||
|
stbrp_node extra[2]; // we allocate two extra nodes so optimal user-node-count is 'width' not 'width+2'
|
||
|
};
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#endif
|
||
|
|