parent
5a89e9ec7d
commit
6d8300f9d9
@ -0,0 +1,85 @@ |
|||||||
|
module ugui; |
||||||
|
|
||||||
|
import std::io; |
||||||
|
|
||||||
|
fault UgAtlasError { |
||||||
|
CANNOT_PLACE, |
||||||
|
INVALID_TYPE, |
||||||
|
} |
||||||
|
|
||||||
|
enum AtlasType { |
||||||
|
ATLAS_GRAYSCALE, |
||||||
|
} |
||||||
|
|
||||||
|
// black and white atlas |
||||||
|
struct Atlas { |
||||||
|
AtlasType type; |
||||||
|
Id id; |
||||||
|
|
||||||
|
ushort width, height; |
||||||
|
char[] buffer; |
||||||
|
|
||||||
|
Point row; |
||||||
|
ushort row_h; |
||||||
|
} |
||||||
|
|
||||||
|
// bytes per pixel |
||||||
|
macro usz AtlasType.bpp(type) |
||||||
|
{ |
||||||
|
switch (type) { |
||||||
|
case ATLAS_GRAYSCALE: return 1; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
fn void! Atlas.new(&atlas, Id id, AtlasType type, ushort width, ushort height) |
||||||
|
{ |
||||||
|
atlas.id = id; |
||||||
|
atlas.type = type; |
||||||
|
atlas.width = width; |
||||||
|
atlas.height = height; |
||||||
|
|
||||||
|
atlas.buffer = mem::new_array(char, (usz)atlas.width*atlas.height*type.bpp()); |
||||||
|
} |
||||||
|
|
||||||
|
fn void Atlas.free(&atlas) |
||||||
|
{ |
||||||
|
free(atlas.buffer); |
||||||
|
} |
||||||
|
|
||||||
|
// place a rect inside the atlas |
||||||
|
// uses a row first algorithm |
||||||
|
// TODO: use a skyline algorithm https://jvernay.fr/en/blog/skyline-2d-packer/implementation/ |
||||||
|
fn Point! Atlas.place(&atlas, char[] pixels, ushort w, ushort h) |
||||||
|
{ |
||||||
|
Point p; |
||||||
|
|
||||||
|
if (atlas.row.x + w <= atlas.width && atlas.row.y + h <= atlas.height) { |
||||||
|
p = atlas.row; |
||||||
|
} else { |
||||||
|
atlas.row.x = 0; |
||||||
|
atlas.row.y = atlas.row.y + atlas.row_h; |
||||||
|
atlas.row_h = 0; |
||||||
|
if (atlas.row.x + w <= atlas.width && atlas.row.y + h <= atlas.height) { |
||||||
|
p = atlas.row; |
||||||
|
} else { |
||||||
|
return UgAtlasError.CANNOT_PLACE?; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
for (usz y = 0; y < h; y++) { |
||||||
|
for (usz x = 0; x < w; x++) { |
||||||
|
char[] buf = atlas.buffer[(usz)(p.y+y)*atlas.width + (p.x+x) ..]; |
||||||
|
char[] pix = pixels[y*w + x ..]; |
||||||
|
usz bpp = atlas.type.bpp(); |
||||||
|
|
||||||
|
buf[0..bpp-1] = pix[0..bpp-1]; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
atlas.row.x += w; |
||||||
|
if (h > atlas.row_h) { |
||||||
|
atlas.row_h = h; |
||||||
|
} |
||||||
|
|
||||||
|
return p; |
||||||
|
} |
Loading…
Reference in new issue