mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-27 18:51:41 +02:00
move sprite position map to verstable
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user