move sprite position map to verstable

This commit is contained in:
Kovid Goyal
2024-07-08 22:05:44 +05:30
parent c9a07f2406
commit 94ebc972ce
4 changed files with 76 additions and 50 deletions

View File

@@ -58,7 +58,7 @@ typedef enum { SPACER_STRATEGY_UNKNOWN, SPACERS_BEFORE, SPACERS_AFTER, SPACERS_I
typedef struct {
PyObject *face;
// Map glyphs to sprite map co-ords
SpritePosition *sprite_position_hash_table;
SPRITE_POSITION_MAP_HANDLE sprite_position_hash_table;
hb_feature_t* ffs_hb_features;
size_t num_ffs_hb_features;
GlyphProperties *glyph_properties_hash_table;
@@ -142,9 +142,7 @@ font_group_is_unused(FontGroup *fg) {
void
free_maps(Font *font) {
free_sprite_position_hash_table(&font->sprite_position_hash_table);
font->sprite_position_hash_table = NULL;
free_glyph_properties_hash_table(&font->glyph_properties_hash_table);
font->glyph_properties_hash_table = NULL;
}
static void
@@ -169,7 +167,7 @@ del_font_group(FontGroup *fg) {
fg->fallback_font_map = NULL;
}
for (size_t i = 0; i < fg->fonts_count; i++) del_font(fg->fonts + i);
free(fg->fonts); fg->fonts = NULL;
free(fg->fonts); fg->fonts = NULL; fg->fonts_count = 0;
}
static void
@@ -256,7 +254,7 @@ do_increment(FontGroup *fg, int *error) {
static SpritePosition*
sprite_position_for(FontGroup *fg, Font *font, glyph_index *glyphs, unsigned glyph_count, uint8_t ligature_index, unsigned cell_count, int *error) {
bool created;
SpritePosition *s = find_or_create_sprite_position(&font->sprite_position_hash_table, glyphs, glyph_count, ligature_index, cell_count, &created);
SpritePosition *s = find_or_create_sprite_position(font->sprite_position_hash_table, glyphs, glyph_count, ligature_index, cell_count, &created);
if (!s) { *error = 1; return NULL; }
if (created) {
s->x = fg->sprite_tracker.x; s->y = fg->sprite_tracker.y; s->z = fg->sprite_tracker.z;
@@ -360,6 +358,8 @@ static bool
init_font(Font *f, PyObject *face, bool bold, bool italic, bool emoji_presentation) {
f->face = face; Py_INCREF(f->face);
f->bold = bold; f->italic = italic; f->emoji_presentation = emoji_presentation;
f->sprite_position_hash_table = create_sprite_position_hash_table();
if (!f->sprite_position_hash_table) { PyErr_NoMemory(); return false; }
const FontFeatures *features = features_for_face(face);
f->ffs_hb_features = calloc(1 + features->count, sizeof(hb_feature_t));
if (!f->ffs_hb_features) { PyErr_NoMemory(); return false; }
@@ -1278,6 +1278,7 @@ test_shape(PyObject UNUSED *self, PyObject *args) {
if (face == NULL) return NULL;
font = calloc(1, sizeof(Font));
font->face = face;
font->sprite_position_hash_table = create_sprite_position_hash_table();
} else {
FontGroup *fg = font_groups;
font = fg->fonts + fg->medium_font_idx;
@@ -1537,6 +1538,8 @@ initialize_font_group(FontGroup *fg) {
fg->fonts = calloc(fg->fonts_capacity, sizeof(Font));
if (fg->fonts == NULL) fatal("Out of memory allocating fonts array");
fg->fonts_count = 1; // the 0 index font is the box font
fg->fonts[0].sprite_position_hash_table = create_sprite_position_hash_table();
if (!fg->fonts[0].sprite_position_hash_table) fatal("Out of memory");
#define I(attr) if (descriptor_indices.attr) fg->attr##_font_idx = initialize_font(fg, descriptor_indices.attr, #attr); else fg->attr##_font_idx = -1;
fg->medium_font_idx = initialize_font(fg, 0, "medium");
I(bold); I(italic); I(bi);

View File

@@ -6,62 +6,90 @@
*/
#include "glyph-cache.h"
#include "kitty-uthash.h"
typedef struct SpritePosItem {
SpritePositionHead
UT_hash_handle hh;
typedef struct SpritePosKey {
size_t keysz_in_bytes;
glyph_index key[];
} SpritePosItem;
} SpritePosKey;
static glyph_index *scratch = NULL;
static unsigned scratch_sz = 0;
#define NAME sprite_pos_map
#define KEY_TY const SpritePosKey*
#define VAL_TY SpritePosition*
static uint64_t sprite_pos_map_hash(KEY_TY key);
#define HASH_FN sprite_pos_map_hash
static bool sprite_pos_map_cmpr(KEY_TY a, KEY_TY b);
#define CMPR_FN sprite_pos_map_cmpr
static void free_const(const void* x) { free((void*)x); }
#define KEY_DTOR_FN free_const
#define VAL_DTOR_FN free_const
#include "kitty-verstable.h"
static uint64_t
sprite_pos_map_hash(const SpritePosKey *key) {
return vt_hash_bytes(key->key, key->keysz_in_bytes);
}
static bool
sprite_pos_map_cmpr(const SpritePosKey *a, const SpritePosKey *b) {
return a->keysz_in_bytes == b->keysz_in_bytes && memcmp(a->key, b->key, a->keysz_in_bytes) == 0;
}
static SpritePosKey *scratch = NULL;
static size_t scratch_key_capacity = 0;
void
free_glyph_cache_global_resources(void) {
free(scratch);
scratch = NULL; scratch_sz = 0;
free(scratch); scratch = NULL; scratch_key_capacity = 0;
}
static unsigned
key_size_for_glyph_count(unsigned count) { return count + 3; }
SPRITE_POSITION_MAP_HANDLE
create_sprite_position_hash_table(void) {
sprite_pos_map *ans = calloc(1, sizeof(sprite_pos_map));
if (ans) vt_init(ans);
return (SPRITE_POSITION_MAP_HANDLE)ans;
}
SpritePosition*
find_or_create_sprite_position(SpritePosition **head_, glyph_index *glyphs, glyph_index count, glyph_index ligature_index, glyph_index cell_count, bool *created) {
SpritePosItem **head = (SpritePosItem**)head_, *p;
const unsigned key_sz = key_size_for_glyph_count(count);
if (key_sz > scratch_sz) {
scratch = realloc(scratch, sizeof(glyph_index) * (key_sz + 16));
if (!scratch) return NULL;
scratch_sz = key_sz + 16;
find_or_create_sprite_position(SPRITE_POSITION_MAP_HANDLE map_, glyph_index *glyphs, glyph_index count, glyph_index ligature_index, glyph_index cell_count, bool *created) {
sprite_pos_map *map = (sprite_pos_map*)map_;
const size_t keysz_in_bytes = key_size_for_glyph_count(count) * sizeof(glyph_index);
if (!scratch || keysz_in_bytes > scratch_key_capacity) {
scratch = realloc(scratch, sizeof(scratch[0]) + keysz_in_bytes + 64);
if (!scratch) { scratch_key_capacity = 0; return NULL; }
scratch_key_capacity = keysz_in_bytes + 64;
}
const unsigned key_sz_bytes = key_sz * sizeof(glyph_index);
scratch[0] = count; scratch[1] = ligature_index; scratch[2] = cell_count;
memcpy(scratch + 3, glyphs, count * sizeof(glyph_index));
HASH_FIND(hh, *head, scratch, key_sz_bytes, p);
if (p) { *created = false; return (SpritePosition*)p; }
scratch->keysz_in_bytes = keysz_in_bytes;
scratch->key[0] = count; scratch->key[1] = ligature_index; scratch->key[2] = cell_count;
memcpy(scratch->key + 3, glyphs, count * sizeof(glyph_index));
sprite_pos_map_itr n = vt_get(map, scratch);
if (!vt_is_end(n)) { *created = false; return n.data->val; }
p = calloc(1, sizeof(SpritePosItem) + key_sz_bytes);
if (!p) return NULL;
memcpy(p->key, scratch, key_sz_bytes);
HASH_ADD(hh, *head, key, key_sz_bytes, p);
SpritePosition *val = calloc(1, sizeof(SpritePosition));
SpritePosKey *key = malloc(sizeof(SpritePosKey) + scratch->keysz_in_bytes);
if (!val || ! key) return NULL;
memcpy(key, scratch, sizeof(scratch[0]) + scratch->keysz_in_bytes);
if (vt_is_end(vt_insert(map, key, val))) return NULL;
*created = true;
return (SpritePosition*)p;
return val;
}
void
free_sprite_position_hash_table(SpritePosition **head_) {
SpritePosItem **head = (SpritePosItem**)head_, *s, *tmp;
HASH_ITER(hh, *head, s, tmp) {
HASH_DEL(*head, s);
free(s);
free_sprite_position_hash_table(SPRITE_POSITION_MAP_HANDLE *map) {
sprite_pos_map **mapref = (sprite_pos_map**)map;
if (*mapref) {
vt_cleanup(*mapref); *mapref = NULL;
}
}
#include "kitty-uthash.h"
typedef struct GlyphPropertiesItem {
GlyphPropertiesHead
UT_hash_handle hh;

View File

@@ -10,18 +10,19 @@
void free_glyph_cache_global_resources(void);
#define SpritePositionHead \
bool rendered, colored; \
sprite_index x, y, z; \
typedef struct SpritePosition {
SpritePositionHead
bool rendered, colored;
sprite_index x, y, z;
} SpritePosition;
typedef struct {int x;} *SPRITE_POSITION_MAP_HANDLE;
void free_sprite_position_hash_table(SpritePosition **head);
SPRITE_POSITION_MAP_HANDLE
create_sprite_position_hash_table(void);
void
free_sprite_position_hash_table(SPRITE_POSITION_MAP_HANDLE *handle);
SpritePosition*
find_or_create_sprite_position(SpritePosition **head, glyph_index *glyphs, glyph_index count, glyph_index ligature_index, glyph_index cell_count, bool *created);
find_or_create_sprite_position(SPRITE_POSITION_MAP_HANDLE map, glyph_index *glyphs, glyph_index count, glyph_index ligature_index, glyph_index cell_count, bool *created);
#define GlyphPropertiesHead \
uint8_t data;

View File

@@ -18,10 +18,4 @@ vt_hash_bytes(const void *data, const size_t size) {
return hash;
}
#define vt_hash_struct(s) vt_hash_bytes(&s, sizeof(s))
#define vt_cmpr_struct(s) memcmp(&s, &s, sizeof(s))
#define vt_hash_ptr(s) vt_hash_bytes(s, sizeof(s[0]))
#define vt_cmpr_ptr(s) memcmp(s, s, sizeof(s[0]))
#endif