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];