commit 77153a68ac84bb58a6b1ce8328e279453c70eebe
parent aed6b7ca52af0f276ca91bcf4d156469baf999d7
Author: lumidify <nobody@lumidify.org>
Date:   Tue, 19 May 2020 21:44:44 +0200
Slightly fix position to index mapping (no, this still doesn't work very well)
Diffstat:
3 files changed, 22 insertions(+), 18 deletions(-)
diff --git a/text_buffer.c b/text_buffer.c
@@ -313,12 +313,12 @@ ltk_render_text_line_new(
 }
 
 uint32_t
-ltk_soft_line_get_index_from_pos(int x, struct ltk_soft_line *sl, hb_direction_t dir, int *found_pos) {
+ltk_soft_line_get_index_from_pos(int x, struct ltk_text_line *tl, struct ltk_soft_line *sl, int *found_pos) {
 	/* FIXME: need par dir! for better guess! */
 	/* also need it to determine if insert should be before or after char */
 	/* FIXME: should I be messing around with casting between uint32_t and size_t? */
 	/* FIXME: handle negative x */
-	uint32_t guess = (int)(((double)x / sl->w) * (sl->len - 1));
+	int guess = (int)(((double)x / sl->w) * (sl->len - 1));
 	guess = guess >= sl->len ? sl->len - 1 : guess;
 	int delta = 0;
 	int i = 0;
@@ -336,22 +336,26 @@ ltk_soft_line_get_index_from_pos(int x, struct ltk_soft_line *sl, hb_direction_t
 		i = guess - 1;
 		last_dist = abs(sl->glyph_pos->buf[guess - 1] - x);
 	}
+	int final_index;
 	if (delta == 0) {
-		if (found_pos)
-			found_pos = sl->glyph_pos->buf[guess];
-		return guess;
-	}
-	int new_dist;
-	for (; i >= 0 && i < sl->len; i += delta) {
-		new_dist = abs(sl->glyph_pos->buf[i] - x);
-		if (last_dist < new_dist)
-			break;
-		last_dist = new_dist;
+		final_index = guess;
+	} else {
+		int new_dist;
+		for (; i >= 0 && i < sl->len; i += delta) {
+			new_dist = abs(sl->glyph_pos->buf[i] - x);
+			if (last_dist < new_dist)
+				break;
+			last_dist = new_dist;
+		}
+		final_index = i - delta;
 	}
-	i -= delta;
 	if (found_pos)
-		*found_pos = sl->glyph_pos->buf[i];
-	return sl->glyph_clusters->buf[i];
+		*found_pos = sl->glyph_pos->buf[final_index];
+	uint32_t cluster = sl->glyph_clusters->buf[final_index];
+	if (FRIBIDI_LEVEL_IS_RTL(tl->bidi_levels->buf[cluster]))
+		return cluster >= tl->log_buf->len - 1 ? tl->log_buf->len - 1 : cluster + 1;
+	else
+		return cluster;
 }
 
 /* Begin stuff stolen from raqm */
diff --git a/text_buffer.h b/text_buffer.h
@@ -100,7 +100,7 @@ struct ltk_text_buffer {
 void ltk_soft_line_destroy(struct ltk_soft_line *sl);
 struct ltk_array_line *ltk_render_text_line_new(struct ltk_text_line *tl, int max_width,
     Display *dpy, Window window, GC gc, Colormap colormap, XColor fg, XColor bg);
-uint32_t ltk_soft_line_get_index_from_pos(int x, struct ltk_soft_line *sl, hb_direction_t dir, int *found_pos);
+uint32_t ltk_soft_line_get_index_from_pos(int x, struct ltk_text_line *tl, struct ltk_soft_line *sl, int *found_pos);
 void ltk_text_line_insert_text(struct ltk_text_line *tl, uint32_t *text, size_t len);
 struct ltk_text_line *ltk_text_line_create(void);
 void ltk_text_line_destroy(struct ltk_text_line *tl);
diff --git a/text_edit.c b/text_edit.c
@@ -62,14 +62,14 @@ void
 ltk_text_edit_tmp(LtkTextEdit *te, XEvent event) {
 	/* this should never be negative, but just to be sure... */
 	int local_y = abs(event.xbutton.y - te->widget.rect.y);
-	int i = ((double)local_y / te->tl->h) * te->soft_lines->len;
+	int i = ((double)local_y / (te->tl->h * te->soft_lines->len)) * te->soft_lines->len;
 	i = i >= te->soft_lines->len ? te->soft_lines->len - 1 : i;
 	int x = event.xbutton.x - te->widget.rect.x;
 	if (te->tl->dir == HB_DIRECTION_RTL)
 		x -= (te->widget.rect.w - te->soft_lines->buf[i]->img->width);
 	int found_pos = 0;
 	te->cursor = ltk_soft_line_get_index_from_pos(
-	    x, te->soft_lines->buf[i], te->tl->dir, &found_pos);
+	    x, te->tl, te->soft_lines->buf[i], &found_pos);
 }
 
 LtkTextEdit *