1 module stb.rectpack;
2 
3 import
4 		std.typecons,
5 		std.algorithm,
6 
7 		stb,
8 		stb.rectpack.binding;
9 
10 
11 struct TexturePacker
12 {
13 	this(stbrp_rect[] rects)
14 	{
15  		_rects = rects;
16  		_nodes = new stbrp_node[TEX_MAX];
17  	}
18 
19 	auto process()
20 	{
21 		auto w = binarySearch(0, TEX_MAX,	a => canPack(a, a) ? -1 : 1);
22 		auto h = binarySearch(0, w,			a => canPack(w, a) ? -1 : 1);
23 
24 		// call once more because binarySearch can do some extra failing tries
25 		canPack(w, h);
26 
27 		return tuple!(`w`, `h`)(w, h);
28 
29 	}
30 
31 private:
32 	enum TEX_MAX = 16384;
33 
34 	bool canPack(int w, int h)
35 	{
36 		stbrp_init_target(&_context, w, h, _nodes.ptr, cast(uint)_nodes.length);
37 		return !!stbrp_pack_rects(&_context, _rects.ptr, cast(uint)_rects.length);
38 	}
39 
40 	stbrp_rect[] _rects;
41 	stbrp_node[] _nodes;
42 	stbrp_context _context;
43 }
44 
45 unittest
46 {
47 	stbrp_rect[3] arr;
48 
49 	arr[0] = stbrp_rect(0, 10, 20); // id, w, h
50 	arr[1] = stbrp_rect(1, 20, 20);
51 	arr[2] = stbrp_rect(2, 40, 20);
52 
53 	auto res = TexturePacker(arr).process;
54 
55 	assert(res.w == 40 && res.h == 40);
56 	assert(arr[].all!(a => a.was_packed));
57 }