commit 6ffac25b7bc13b37867c6e52c6519389b46d951a
parent 6889fe73af2a0c518dfd29c77305704ad3a5e82b
Author: lumidify <nobody@lumidify.org>
Date:   Mon, 20 Apr 2020 18:19:57 +0200
Fix reference counting for glyphs and fonts
Diffstat:
2 files changed, 20 insertions(+), 6 deletions(-)
diff --git a/button.c b/button.c
@@ -181,7 +181,7 @@ void ltk_destroy_button(LtkButton *button)
 	if (button->text_pressed) XDestroyImage(button->text_pressed);
 	if (button->text_active) XDestroyImage(button->text_active);
 	if (button->text_disabled) XDestroyImage(button->text_disabled);
-	//ltk_destroy_text_segment(button->ts);
+	ltk_destroy_text_line(button->tl);
 	free(button);
 }
 
diff --git a/text-hb.c b/text-hb.c
@@ -160,6 +160,7 @@ ltk_create_glyph_info(LtkFont *font, unsigned int id, float scale)
 	}
 	
 	glyph->id = id;
+	glyph->refs = 0;
 	glyph->alphamap = stbtt_GetGlyphBitmap(
 		&font->info, scale, scale, id, &glyph->w,
 		&glyph->h, &glyph->xoff, &glyph->yoff
@@ -184,13 +185,11 @@ ltk_get_glyph_info(LtkFont *font, unsigned int id, float scale, khash_t(glyphinf
 	k = kh_get(glyphinfo, cache, id);
 	if (k == kh_end(cache)) {
 		glyph = ltk_create_glyph_info(font, id, scale);
-		glyph->refs = 0;
 		/* FIXME: error checking with ret */
 		k = kh_put(glyphinfo, cache, id, &ret);
 		kh_value(cache, k) = glyph;
 	} else {
 		glyph = kh_value(cache, k);
-		glyph->refs++;
 	}
 
 	return glyph;
@@ -444,6 +443,17 @@ ltk_create_text_line(LtkTextManager *tm, char *text, uint16_t fontid, uint16_t s
 	return tl;
 }
 
+void
+ltk_destroy_text_line(LtkTextLine *tl) {
+	LtkTextSegment *last_ts;
+	LtkTextSegment *cur_ts = tl->start_segment;
+	while (cur_ts) {
+		last_ts = cur_ts;
+		cur_ts = cur_ts->next;
+		ltk_destroy_text_segment(last_ts);
+	}
+}
+
 /* FIXME: could use unsigned int for fontid and size as long as there is code to check neither of them become too large
    -> in case I want to get rid of uint_16_t, etc. */
 LtkTextSegment *
@@ -457,9 +467,6 @@ ltk_create_text_segment(LtkTextManager *tm, uint32_t *text, unsigned int len, ui
 
 	k = kh_get(fontstruct, tm->font_cache, fontid);
 	font = kh_value(tm->font_cache, k);
-	/* FIXME: when should refs be increased? maybe only at the end in case
-	   it has to return for some other reason (out of memory, etc.) */
-	font->refs++;
 
 	uint32_t attr = fontid << 16 + size;
 	/* FIXME: turn this into ltk_get_glyph_cache */
@@ -494,6 +501,9 @@ ltk_create_text_segment(LtkTextManager *tm, uint32_t *text, unsigned int len, ui
 	hb_buffer_set_direction(buf, dir);
 	hb_buffer_set_script(buf, script);
 	hb_buffer_add_codepoints(buf, ts->str, len, 0, len);
+	/* According to https://harfbuzz.github.io/the-distinction-between-levels-0-and-1.html
+	 * this should be level 1 clustering instead of level 0 */
+	hb_buffer_set_cluster_level(buf, HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS);
 	hb_shape(font->hb, buf, NULL, 0);
 	ts->dir = hb_buffer_get_direction(buf);
 	ginf = hb_buffer_get_glyph_infos(buf, &text_len);
@@ -510,6 +520,7 @@ ltk_create_text_segment(LtkTextManager *tm, uint32_t *text, unsigned int len, ui
 		gp = &gpos[i];
 		glyph = malloc(sizeof(LtkGlyph));
 		glyph->info = ltk_get_glyph_info(font, gi->codepoint, scale, glyph_cache);
+		glyph->info->refs++;
 		/* FIXME: round instead of just casting */
 		glyph->x_offset = (int)(gp->x_offset * scale);
 		glyph->y_offset = (int)(gp->y_offset * scale);
@@ -559,6 +570,9 @@ ltk_create_text_segment(LtkTextManager *tm, uint32_t *text, unsigned int len, ui
 	ts->y_min = y_min;
 	ts->x_max = x_max;
 	ts->y_max = y_max;
+
+	font->refs++;
+
 	return ts;
 }