ltkx

GUI toolkit for X11 (WIP)
git clone git://lumidify.org/ltkx.git
Log | Files | Refs | README | LICENSE

commit a6128237108e74682b8ca427a01dd6762cb95891
parent ffa1263fd4b66ae32adb6a2fd0274f226022d9f8
Author: lumidify <nobody@lumidify.org>
Date:   Sun, 17 May 2020 19:39:39 +0200

Change cur->len to cur->num_glyphs; allow to disallow wrapping

Diffstat:
Mtext_buffer.c | 54++++++++++++++++++++++++++++++------------------------
1 file changed, 30 insertions(+), 24 deletions(-)

diff --git a/text_buffer.c b/text_buffer.c @@ -54,7 +54,6 @@ ltk_soft_line_destroy(struct ltk_soft_line *sl) { struct ltk_array_line * ltk_text_line_wrap(struct ltk_text_line *tl, int max_width) { - /* FIXME: if max_width == -1, don't wrap */ struct ltk_array_line *soft_lines = ltk_array_create_line(1); int par_is_rtl = tl->dir == HB_DIRECTION_RTL; @@ -62,39 +61,45 @@ ltk_text_line_wrap(struct ltk_text_line *tl, int max_width) { LtkGlyph *glyph; struct ltk_soft_line *sl = malloc(sizeof(struct ltk_soft_line)); if (!sl) goto error; - sl->glyph_index = cur->dir == HB_DIRECTION_RTL ? cur->len - 1 : 0; + sl->glyph_index = cur->dir == HB_DIRECTION_RTL ? cur->num_glyphs - 1 : 0; sl->run = cur; sl->len = 0; sl->w = 0; ltk_array_append_line(soft_lines, sl); + if (max_width == -1) { + cur = tl->first_run; + while (cur) { + sl->len += cur->num_glyphs; + sl->w += cur->w; + cur = cur->next; + } + return soft_lines; + } int last_linebreak = par_is_rtl ? tl->w : 0; int cur_start = 0; /* FIXME: also calculate max height of each line */ while (cur) { if (sl->w + cur->w <= max_width) { sl->w += cur->w; - sl->len += cur->len; + sl->len += cur->num_glyphs; cur = par_is_rtl ? cur->last : cur->next; continue; } if (cur->dir == HB_DIRECTION_RTL) { - cur_start = cur->glyphs[cur->len - 1].x_abs + cur->glyphs[cur->len - 1].x_advance; - int i = cur->len - 1; + cur_start = cur->glyphs[cur->num_glyphs - 1].x_abs + cur->glyphs[cur->num_glyphs - 1].x_advance; + int i = cur->num_glyphs - 1; while (i >= 0) { glyph = &cur->glyphs[i]; int cur_w = sl->w + cur_start - glyph->x_abs; if (cur_w > max_width) { /* FIXME: fix behavior when line isn't wide enough for single char */ - for (int j = i; j < cur->len; j++) { - if (cur->glyphs[j].cluster != glyph->cluster || j == cur->len - 1) { - int new_index; - if (j == cur->len - 1 && + for (int j = i; j < cur->num_glyphs; j++) { + if (cur->glyphs[j].cluster != glyph->cluster || j == cur->num_glyphs - 1) { + if (j == cur->num_glyphs - 1 && cur->glyphs[j].cluster == glyph->cluster) { - new_index = j; i = j; last_linebreak = cur_start; } else { - new_index = j - 1; i = j - 1; last_linebreak = cur->glyphs[j].x_abs; sl->len++; @@ -103,7 +108,7 @@ ltk_text_line_wrap(struct ltk_text_line *tl, int max_width) { cur_start = last_linebreak; sl = malloc(sizeof(struct ltk_soft_line)); if (!sl) goto error; - sl->glyph_index = new_index; + sl->glyph_index = i; sl->run = cur; sl->len = 0; sl->w = 0; @@ -125,19 +130,16 @@ ltk_text_line_wrap(struct ltk_text_line *tl, int max_width) { } else { cur_start = cur->glyphs[0].x_abs; int i = 0; - while (i < cur->len) { + while (i < cur->num_glyphs) { glyph = &cur->glyphs[i]; int cur_w = sl->w + glyph->x_abs + glyph->info->w - cur_start; if (cur_w > max_width) { for (int j = i; j >= 0; j--) { if (cur->glyphs[j].cluster != glyph->cluster || j == 0) { - int new_index; if (j == 0 && cur->glyphs[j].cluster == glyph->cluster) { - new_index = j; i = j; last_linebreak = cur_start; } else { - new_index = j + 1; i = j + 1; last_linebreak = cur->glyphs[j + 1].x_abs; sl->len++; @@ -146,7 +148,7 @@ ltk_text_line_wrap(struct ltk_text_line *tl, int max_width) { cur_start = last_linebreak; sl = malloc(sizeof(struct ltk_soft_line)); if (!sl) goto error; - sl->glyph_index = new_index; + sl->glyph_index = i; sl->run = cur; sl->len = 0; sl->w = 0; @@ -163,7 +165,7 @@ ltk_text_line_wrap(struct ltk_text_line *tl, int max_width) { } if (sl->run == cur) - sl->w = cur->glyphs[cur->len - 1].x_abs + cur->glyphs[cur->len - 1].x_advance - last_linebreak; + sl->w = cur->glyphs[cur->num_glyphs - 1].x_abs + cur->glyphs[cur->num_glyphs - 1].x_advance - last_linebreak; else sl->w += cur->w; } @@ -246,7 +248,7 @@ ltk_render_text_line_new( x_abs + glyph->info->w, which may not be the same thing as the actual x_abs of the bordering glyph */ if (cur->dir == HB_DIRECTION_RTL) { - start_index = cur == sl->run ? sl->glyph_index : cur->len - 1; + start_index = cur == sl->run ? sl->glyph_index : cur->num_glyphs - 1; int local_border = cur->glyphs[start_index].x_abs + cur->glyphs[start_index].x_advance; int end_index; if (start_index + 1 < sl->len - cur_len) { @@ -272,12 +274,12 @@ ltk_render_text_line_new( start_index = cur == sl->run ? sl->glyph_index : 0; int local_border = cur->glyphs[start_index].x_abs; int end_index; - if (cur->len - start_index < sl->len - cur_len) { - end_index = cur->len - 1; + if (cur->num_glyphs - start_index < sl->len - cur_len) { + end_index = cur->num_glyphs - 1; } else { end_index = start_index + sl->len - cur_len - 1; } - for (int i = start_index; i < cur->len && cur_len < sl->len; i++) { + for (int i = start_index; i < cur->num_glyphs && cur_len < sl->len; i++) { cur_len++; int x; if (par_is_rtl) { @@ -288,9 +290,9 @@ ltk_render_text_line_new( ltk_draw_glyph(&cur->glyphs[i], sl->img, x, cur->glyphs[i].y_abs, fg); } if (par_is_rtl) - cur_border -= cur->glyphs[cur->len - 1].x_abs + cur->glyphs[cur->len - 1].x_advance - local_border; + cur_border -= cur->glyphs[cur->num_glyphs - 1].x_abs + cur->glyphs[cur->num_glyphs - 1].x_advance - local_border; else - cur_border += cur->glyphs[cur->len - 1].x_abs + cur->glyphs[cur->len - 1].x_advance - local_border; + cur_border += cur->glyphs[cur->num_glyphs - 1].x_abs + cur->glyphs[cur->num_glyphs - 1].x_advance - local_border; } cur = par_is_rtl ? cur->last : cur->next; } @@ -299,6 +301,10 @@ ltk_render_text_line_new( return soft_lines; } +size_t +ltk_soft_line_get_index_from_pos(int x, struct ltk_soft_line *sl) { +} + /* Begin stuff stolen from raqm */ /* Special paired characters for script detection */