summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFabrice <fabrice@schaub-dev.xyz>2026-02-11 22:50:21 +0100
committerFabrice <fabrice@schaub-dev.xyz>2026-02-11 22:50:21 +0100
commita0a68b7b3a5430fea5aaa2ad1da75fdda5cd5c7a (patch)
treef30c9d90ce0d864dc65cb1307a7196b80e63d71c /src
parent64b0664a648ec4a6c424e932b605f09dc4ee6151 (diff)
packing corrections
Diffstat (limited to 'src')
-rw-r--r--src/rendering.cc28
-rw-r--r--src/rendering.h12
-rw-r--r--src/text.cc17
-rw-r--r--src/text.h3
-rw-r--r--src/utils.h5
5 files changed, 56 insertions, 9 deletions
diff --git a/src/rendering.cc b/src/rendering.cc
index 89a64ac..65a89b1 100644
--- a/src/rendering.cc
+++ b/src/rendering.cc
@@ -4,6 +4,7 @@
#include <cstring>
+#include "cglm/types.h"
#include "utils.h"
bool wayc_image_init(texture_t* texture, image_type_e type,
@@ -126,3 +127,30 @@ void wayc_atlas_deinit(atlas_s* atlas) {
wayc_sampler_deinit(&atlas->sampler);
wayc_image_deinit(&atlas->texture);
}
+
+static inline void wayc_atlas_packer_wrap(struct atlas_packer_s* packer) {
+ WAYC_X(packer->cursor) = 0;
+ WAYC_Y(packer->cursor) += packer->row_height;
+ packer->row_height = 0;
+}
+
+bool wayc_atlas_packer_allocate(struct atlas_packer_s* packer, u32 width,
+ u32 height, ivec2 out) {
+ wayc_notnull(packer);
+
+ struct atlas_s* atlas = packer->atlas;
+ wayc_notnull(atlas);
+
+ if (width > atlas->width || height > atlas->height) return false;
+
+ if (WAYC_X(packer->cursor) + width > atlas->width)
+ wayc_atlas_packer_wrap(packer);
+
+ if (WAYC_Y(packer->cursor) + height > atlas->height) return false;
+
+ glm_ivec2_copy(packer->cursor, out);
+ WAYC_X(packer->cursor) += width;
+ packer->row_height = wayc_max(packer->row_height, height);
+
+ return true;
+} \ No newline at end of file
diff --git a/src/rendering.h b/src/rendering.h
index 98f70ce..f8db68e 100644
--- a/src/rendering.h
+++ b/src/rendering.h
@@ -67,3 +67,15 @@ void wayc_atlas_use(atlas_s* atlas, u32 slot);
bool wayc_atlas_set(atlas_s* atlas, image_data_type_e data_type, ivec2 offset,
u32 width, u32 height, i32 alignment, const u8* data);
void wayc_atlas_deinit(atlas_s* atlas);
+
+struct atlas_packer_s {
+ struct atlas_s* atlas;
+ u32 row_height;
+ ivec2 cursor;
+};
+
+#define WAYC_ATLAS_PACKER_INIT(atlas) \
+ atlas_packer_s { atlas, 0, {0, 0} }
+
+bool wayc_atlas_packer_allocate(struct atlas_packer_s* packer, u32 width,
+ u32 height, ivec2 out);
diff --git a/src/text.cc b/src/text.cc
index 2bfc7a3..d02cc77 100644
--- a/src/text.cc
+++ b/src/text.cc
@@ -5,7 +5,7 @@
#include <unistd.h>
#include <utils.h>
-#include "cglm/ivec2.h"
+#include "cglm/types.h"
#include "freetype/freetype.h"
#include "hash.h"
#include "rendering.h"
@@ -72,13 +72,13 @@ enum font_error_e wayc_font_init(struct font_s* font,
font->data = data;
wayc_hashmap_init(&font->cache);
- glm_ivec2_zero(font->cursor);
success = true;
return FONT_ERROR_NONE;
}
enum font_error_e wayc_font_lookup(struct font_s* font, struct atlas_s* atlas,
+ struct atlas_packer_s* packer,
codepoint_t codepoint, struct glyph_s* out) {
wayc_notnull(font);
wayc_notnull(atlas);
@@ -100,20 +100,21 @@ enum font_error_e wayc_font_lookup(struct font_s* font, struct atlas_s* atlas,
if (bitmap.pitch != (i32)bitmap.width) wayc_panic("unsupported pitch");
ivec2 size = {(i32)bitmap.width, (i32)bitmap.rows};
+ ivec2 uv0;
- wayc_atlas_set(atlas, IMAGE_DATA_TYPE_UNSIGNED_BYTE, font->cursor, size[0],
- size[1], IMAGE_FORMAT_RED_ALIGNMENT, bitmap.buffer);
+ bool ok = wayc_atlas_packer_allocate(packer, WAYC_X(size), WAYC_Y(size), uv0);
+ if (!ok) return FONT_ERROR_ATLAS_FULL;
+
+ ok = wayc_atlas_set(atlas, IMAGE_DATA_TYPE_UNSIGNED_BYTE, uv0, WAYC_X(size),
+ WAYC_Y(size), IMAGE_FORMAT_RED_ALIGNMENT, bitmap.buffer);
+ if (!ok) return FONT_ERROR_ATLAS_FULL;
struct glyph_s glyph = {};
glyph.bearing_x = slot->bitmap_left;
glyph.bearing_y = slot->bitmap_top;
glyph.advance = (f32)slot->advance.x / WAYC_SCALE;
- glm_ivec2(font->cursor, glyph.uv0);
- glm_ivec2_add(glyph.uv0, size, glyph.uv1);
-
wayc_font_cache_insert(font, codepoint, glyph);
- glm_ivec2_add(font->cursor, size, font->cursor);
*out = glyph;
return FONT_ERROR_NONE;
diff --git a/src/text.h b/src/text.h
index a04fa99..73b4e03 100644
--- a/src/text.h
+++ b/src/text.h
@@ -32,18 +32,19 @@ enum font_error_e {
FONT_ERROR_FILE_LOAD,
FONT_ERROR_FONT_LOAD,
FONT_ERROR_NOT_MATCH,
+ FONT_ERROR_ATLAS_FULL,
};
struct font_s {
u8* data;
FT_Face face;
struct hashmap_s<codepoint_t, struct glyph_s> cache;
- ivec2 cursor;
};
enum font_error_e wayc_font_init(struct font_s* font,
struct font_context_s* ctx, u32 fsize,
const char* path);
enum font_error_e wayc_font_lookup(struct font_s* font, struct atlas_s* atlas,
+ struct atlas_packer_s* packer,
codepoint_t codepoint, struct glyph_s* out);
void wayc_font_deinit(struct font_s* font);
diff --git a/src/utils.h b/src/utils.h
index 10bdd88..00be767 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -74,6 +74,11 @@ static inline u32 wayc_min(u32 a, u32 b) { return a > b ? a : b; }
#define WAYC_FRAC_BITS 6
#define WAYC_SCALE (1 << WAYC_FRAC_BITS)
+#define WAYC_X(v) ((v)[0])
+#define WAYC_Y(v) ((v)[1])
+
+static inline usize wayc_max(usize a, usize b) { return a > b ? a : b; }
+
template <typename A, typename B>
struct is_same {
static constexpr bool value = false;