commit 487c86781fe1af79c0677565dea2aa35049c082c
parent b7cef33142db6ea0ca0df918b86eae9c282b6230
Author: lumidify <nobody@lumidify.org>
Date:   Wed, 13 May 2020 17:07:40 +0200
Somewhat implement wrapped line rendering
Diffstat:
| M | textedit_wip.c |  |  | 73 | +++++++++++++++++++++++++++++++++---------------------------------------- | 
1 file changed, 33 insertions(+), 40 deletions(-)
diff --git a/textedit_wip.c b/textedit_wip.c
@@ -73,7 +73,7 @@ ltk_render_text_line(
 			if (cur_x > max_width) {
 				int j = 0;
 				for (j = i; j >= 0; j--) {
-					if (glyphs[j]->cluster != glyphs[i]->cluster) {
+					if (cur->glyphs[j]->cluster != cur->glyphs[i]->cluster) {
 						/* must increase one again so the actual
 						   next character is used */
 						j++;
@@ -107,46 +107,37 @@ ltk_render_text_line(
 	}
 
 	cur = tl->first_run;
-	int x = 0;
-	int y = 0;
-	do {
-		y = tl->h - tl->y_max;
-		ltk_render_text_segment(ts, x + ts->start_x, y, img, fg);
-		x += ts->w;
-	} while (ts = ts->next);
-
-	return img;
-}
-
-void
-ltk_render_text_segment(
-	LtkTextSegment *ts,
-	unsigned int start_x,
-	unsigned int start_y,
-	XImage *img,
-	XColor fg)
-{
-	LtkGlyph *glyph = ts->start_glyph;
-	int x_cur = start_x;
-	int y_cur = start_y;
 	int x, y;
-	double a;
-	int b;
-	do {
-		x = x_cur + glyph->info->xoff + glyph->x_offset;
-		y = y_cur + glyph->info->yoff - glyph->y_offset;
-		for (int i = 0; i < glyph->info->h; i++) {
-			for (int j = 0; j < glyph->info->w; j++) {
-				b = (y + i) * img->bytes_per_line + (x + j) * 4;
-				a = glyph->info->alphamap[i * glyph->info->w + j] / 255.0;
-				img->data[b] = (fg.blue * a + (1 - a) * (uint16_t)img->data[b] * 257) / 257;
-				img->data[b + 1] = (fg.green * a + (1 - a) * (uint16_t)img->data[b + 1] * 257) / 257;
-				img->data[b + 2] = (fg.red * a + (1 - a) * (uint16_t)img->data[b + 2] * 257) / 257;
+	int cur_line_x = 0;
+	int cur_line = 0;
+	LtkGlyph *glyph;
+	/* FIXME: how should an empty line be handled? This doesn't use a do-for
+	   loop in case tl->first_run is NULL, but I should probably decide what
+	   to do in that case */
+	while (cur) {
+		for (int k = 0; k < cur->len; k++) {
+			glyph = cur->glyphs[k];
+			if (cur_line < tl->wrap_indeces->len - 1 &&
+			    glyph->cluster >= tl->wrap_indeces->buf[cur_line + 1]) {
+				cur_line++;
+				cur_line_x += glyph->x_abs - cur_line_x;
+			}
+			x = glyph->x_abs - cur_line_x;
+			y = glyph->y_abs + tl->h * cur_line;
+			for (int i = 0; i < glyph->info->h; i++) {
+				for (int j = 0; j < glyph->info->w; j++) {
+					b = (y + i) * img->bytes_per_line + (x + j) * 4;
+					a = glyph->info->alphamap[i * glyph->info->w + j] / 255.0;
+					img->data[b] = (fg.blue * a + (1 - a) * (uint16_t)img->data[b] * 257) / 257;
+					img->data[b + 1] = (fg.green * a + (1 - a) * (uint16_t)img->data[b + 1] * 257) / 257;
+					img->data[b + 2] = (fg.red * a + (1 - a) * (uint16_t)img->data[b + 2] * 257) / 257;
+				}
 			}
 		}
-		x_cur += glyph->x_advance;
-		y_cur -= glyph->y_advance;
-	} while (glyph = glyph->next);
+		cur = cur->next;
+	}
+
+	return img;
 }
 
 /*
@@ -365,8 +356,7 @@ ltk_text_line_itemize(struct ltk_text_line *tl) {
 /* FIXME: return start_x, etc. instead of saving in struct text run */
 static void
 ltk_text_run_shape(LtkTextManager *tm, struct ltk_text_run *tr,
-    struct ltk_text_line *tl, uint16_t font_size, uint16_t font_id,
-    int *ret_x_max, int *ret_y_max) {
+    struct ltk_text_line *tl, uint16_t font_size, uint16_t font_id, int *ret_y_max) {
 	khash_t(glyphinfo) *glyph_cache;
 	khint_t k;
 
@@ -404,6 +394,9 @@ ltk_text_run_shape(LtkTextManager *tm, struct ltk_text_run *tr,
 		(void)fprintf("Cannot allocate space for glyphs.\n");
 		exit(1);
 	}
+	/* FIXME: should x_max be calculated using glyph->info->w?
+	   The advance might be different and not represent where pixels
+	   will actually have to be drawn. */
 	LtkGlyph *glyph;
 	for (int i = 0; i < tr->num_glyphs; i++) {
 		gi = &ginf[i];