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