Allocate shape_buffer on the heap so it works with arbitrary input length

This commit is contained in:
Kovid Goyal
2025-02-16 11:03:47 +05:30
parent 4005fb5bfb
commit d02b0d5c06

View File

@@ -40,7 +40,7 @@ typedef struct RunFont {
static hb_buffer_t *harfbuzz_buffer = NULL;
static hb_feature_t hb_features[3] = {{0}};
static char_type shape_buffer[4096] = {0};
static struct { char_type *codepoints; size_t capacity; } shape_buffer = {0};
static size_t max_texture_size = 1024, max_array_len = 1024;
typedef enum { LIGA_FEATURE, DLIG_FEATURE, CALT_FEATURE } HBFeature;
@@ -1105,14 +1105,17 @@ static void
load_hb_buffer(CPUCell *first_cpu_cell, index_type num_cells, const TextCache *tc, ListOfChars *lc) {
size_t num = 0;
hb_buffer_clear_contents(harfbuzz_buffer);
// Although hb_buffer_add_codepoints is supposedly an append, we have to
// add all text in one call otherwise it breaks shaping, presumably because
// of context??
for (; num_cells; first_cpu_cell++, num_cells--) {
if (first_cpu_cell->is_multicell && first_cpu_cell->x) continue;
text_in_cell(first_cpu_cell, tc, lc);
const size_t count = MIN(lc->count, arraysz(shape_buffer) - num);
memcpy(shape_buffer + num, lc->chars, count * sizeof(shape_buffer[0]));
num += count;
ensure_space_for((&shape_buffer), codepoints, char_type, lc->count + num, capacity, 512, false);
memcpy(shape_buffer.codepoints + num, lc->chars, lc->count * sizeof(shape_buffer.codepoints[0]));
num += lc->count;
}
hb_buffer_add_codepoints(harfbuzz_buffer, shape_buffer, num, 0, num);
hb_buffer_add_codepoints(harfbuzz_buffer, shape_buffer.codepoints, num, 0, num);
hb_buffer_guess_segment_properties(harfbuzz_buffer);
if (OPT(force_ltr)) hb_buffer_set_direction(harfbuzz_buffer, HB_DIRECTION_LTR);
}
@@ -2055,6 +2058,7 @@ finalize(void) {
free(global_glyph_render_scratch.sprite_positions);
if (global_glyph_render_scratch.lc) { cleanup_list_of_chars(global_glyph_render_scratch.lc); free(global_glyph_render_scratch.lc); }
global_glyph_render_scratch = (GlyphRenderScratch){0};
free(shape_buffer.codepoints); zero_at_ptr(&shape_buffer);
}
static PyObject*