Files
Mikemon/src/smol-atlas.h
T
2025-02-27 18:01:06 +01:00

67 lines
2.5 KiB
C

// SPDX-License-Identifier: MIT OR Unlicense
// smol-atlas: https://github.com/aras-p/smol-atlas
#pragma once
// 2D rectangular bin packing utility that uses the Shelf Best Height Fit
// heuristic, and supports item removal. You could also call it a
// dynamic texture atlas allocator.
//
// The shelf packing algorithm works well when there is a high number of items
// with similar sizes, for example dynamic glyph or thumbnail atlases.
//
// - Incoming items are placed into horizontal "shelves" based on item heights.
// - Within each shelf, there is a sorted list of free spans.
// - When an item is added, needed portion of the first suitable free span
// is used.
// - When an item is removed, resulting free span is joined with any
// neighboring spans.
// - Shelves, once created, stay at their height and location. Even if they
// become empty, they are not removed nor joined with nearby shelves.
//
// Implementation uses STL <vector>, and some manual memory allocation
// with just regular `new` and `delete`. Custom allocators might be nice to
// do someday.
//
// At least C++11 is required.
struct smol_atlas_t;
struct smol_atlas_item_t;
/// Create atlas of given size.
smol_atlas_t* sma_atlas_create(int width, int height);
/// Destroy the atlas.
void sma_atlas_destroy(smol_atlas_t* atlas);
/// Get atlas width.
int sma_atlas_width(const smol_atlas_t* atlas);
/// Get atlas height.
int sma_atlas_height(const smol_atlas_t* atlas);
/// Add an item of (width x height) size into the atlas.
/// Use `sma_item_x` and `sma_item_y` to query the resulting item location.
/// Item can later be removed with `sma_item_remove`.
/// Returned pointer is valid until atlas is cleared or destroyed, or the item is removed.
/// Returns NULL if there is no more space left.
smol_atlas_item_t* sma_item_add(smol_atlas_t* atlas, int width, int height);
/// Remove a previously added item from the atlas.
/// The item pointer becomes invalid and can no longer be used.
void sma_item_remove(smol_atlas_t* atlas, smol_atlas_item_t* item);
/// Clear the atlas. This invalidates any previously returned item pointers.
/// If passed width and height are positive, the atlas size is also set
/// to the new values.
void sma_atlas_clear(smol_atlas_t* atlas, int new_width = 0, int new_height = 0);
/// Get item X coordinate.
int sma_item_x(const smol_atlas_item_t* item);
/// Get item Y coordinate.
int sma_item_y(const smol_atlas_item_t* item);
/// Get item width.
int sma_item_width(const smol_atlas_item_t* item);
/// Get item height.
int sma_item_height(const smol_atlas_item_t* item);