commit e76057dd60a70a13d5ede8274d504494d2ee70a8
parent e80afa0ebd0f0fca40a797392db2a210ad466fa4
Author: lumidify <nobody@lumidify.org>
Date: Wed, 17 Nov 2021 22:39:43 +0100
Finish removing direct usage of pango in keys_basic.c
Diffstat:
M | buffer.c | | | 77 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
M | buffer.h | | | 4 | ++++ |
M | keys_basic.c | | | 111 | +++++++++++++++++++++++++++++-------------------------------------------------- |
3 files changed, 121 insertions(+), 71 deletions(-)
diff --git a/buffer.c b/buffer.c
@@ -1284,6 +1284,83 @@ ledit_buffer_get_softline_bounds(
*end_byte_ret = pl->start_index + pl->length;
}
+int
+ledit_buffer_get_softline_count(ledit_buffer *buffer, int line) {
+ assert(line >= 0 && line < buffer->lines_num);
+ ledit_line *ll = ledit_buffer_get_line(buffer, line);
+ return pango_layout_get_line_count(ll->layout);
+}
+
+int
+ledit_buffer_pos_to_softline(ledit_buffer *buffer, int line, int pos) {
+ assert(line >= 0 && line < buffer->lines_num);
+ ledit_line *ll = ledit_buffer_get_line(buffer, line);
+ assert(pos >= 0 && pos <= ll->len);
+ int x, sli;
+ pango_layout_index_to_line_x(ll->layout, pos, 0, &sli, &x);
+ return sli;
+}
+
+void
+ledit_buffer_get_cursor_pixel_pos(ledit_buffer *buffer, int line, int pos, int *x_ret, int *y_ret, int *h_ret) {
+ assert(line >= 0 && line < buffer->lines_num);
+ ledit_line *ll = ledit_buffer_get_line(buffer, line);
+ assert(pos >= 0 && pos <= ll->len);
+ PangoRectangle strong, weak;
+ pango_layout_get_cursor_pos(ll->layout, 0, &strong, &weak);
+ *x_ret = strong.x / PANGO_SCALE;
+ *y_ret = strong.y / PANGO_SCALE;
+ *h_ret = strong.height / PANGO_SCALE;
+}
+
+/* prev_index_ret is used instead of just calling get_legal_normal_pos
+ because weird things happen otherwise
+ -> in certain cases, this is still weird because prev_index_ret sometimes
+ is not at the end of the line, but this is the best I could come up
+ with for now */
+int
+ledit_buffer_move_cursor_visually(ledit_buffer *buffer, int line, int pos, int movement, int *prev_index_ret) {
+ /* FIXME: trailing */
+ int trailing = 0, tmp_index;
+ ledit_line *cur_line = ledit_buffer_get_line(buffer, line);
+ int new_index = pos, last_index = pos;
+ int dir = 1;
+ int num = movement;
+ if (movement < 0) {
+ dir = -1;
+ num = -movement;
+ }
+ while (num > 0) {
+ tmp_index = new_index;
+ pango_layout_move_cursor_visually(
+ cur_line->layout, TRUE,
+ new_index, trailing, dir,
+ &new_index, &trailing
+ );
+ /* for some reason, this is necessary */
+ if (new_index < 0)
+ new_index = 0;
+ else if (new_index > cur_line->len)
+ new_index = cur_line->len;
+ num--;
+ if (tmp_index != new_index)
+ last_index = tmp_index;
+ }
+ /* FIXME: Allow cursor to be at end of soft line */
+ /* we don't currently support a difference between the cursor being at
+ the end of a soft line and the beginning of the next line */
+ /* FIXME: spaces at end of softlines are weird in normal mode */
+ while (trailing > 0) {
+ trailing--;
+ new_index = ledit_line_next_utf8(cur_line, new_index);
+ }
+ if (new_index < 0)
+ new_index = 0;
+ if (prev_index_ret)
+ *prev_index_ret = last_index;
+ return new_index;
+}
+
/* FIXME: implement */
/*
int
diff --git a/buffer.h b/buffer.h
@@ -77,6 +77,7 @@ int ledit_line_next_utf8(ledit_line *line, int index);
int ledit_line_prev_utf8(ledit_line *line, int index);
int ledit_buffer_next_cursor_pos(ledit_buffer *buffer, int line, int byte, int num);
int ledit_buffer_prev_cursor_pos(ledit_buffer *buffer, int line, int byte, int num);
+int ledit_buffer_move_cursor_visually(ledit_buffer *buffer, int line, int pos, int movement, int *prev_index_ret);
void ledit_buffer_next_word(ledit_buffer *buffer, int line, int byte, int num_repeat, int *line_ret, int *byte_ret, int *real_byte_ret);
void ledit_buffer_next_word_end(ledit_buffer *buffer, int line, int byte, int num_repeat, int *line_ret, int *byte_ret, int *real_byte_ret);
@@ -86,6 +87,9 @@ void ledit_buffer_prev_word(ledit_buffer *buffer, int line, int byte, int num_re
void ledit_buffer_prev_bigword(ledit_buffer *buffer, int line, int byte, int num_repeat, int *line_ret, int *byte_ret, int *real_byte_ret);
void ledit_buffer_get_pos_softline_bounds(ledit_buffer *buffer, int line, int pos, int *start_byte_ret, int *end_byte_ret);
void ledit_buffer_get_softline_bounds(ledit_buffer *buffer, int line, int softline, int *start_byte_ret, int *end_byte_ret);
+int ledit_buffer_get_softline_count(ledit_buffer *buffer, int line);
+int ledit_buffer_pos_to_softline(ledit_buffer *buffer, int line, int pos);
+void ledit_buffer_get_cursor_pixel_pos(ledit_buffer *buffer, int line, int pos, int *x_ret, int *y_ret, int *h_ret);
size_t ledit_buffer_textlen(ledit_buffer *buffer, int line1, int byte1, int line2, int byte2);
void ledit_buffer_copy_text(ledit_buffer *buffer, char *dst, int line1, int byte1, int line2, int byte2);
diff --git a/keys_basic.c b/keys_basic.c
@@ -1,3 +1,4 @@
+/* FIXME: I guess hard_line_based should be updated for all buffers/windows when that gets supported */
/* FIXME: cursor isn't shown on spaces at end of softlines */
/* FIXME: selection is sometimes not reset when it is "clicked away" */
/* FIXME: use weak cursor */
@@ -19,7 +20,6 @@
#include <X11/XF86keysym.h>
#include <X11/cursorfont.h>
-#include "pango-compat.h"
#include "memory.h"
#include "common.h"
#include "txtbuf.h"
@@ -338,11 +338,9 @@ get_new_line_softline(
*new_line_ret = buffer->lines_num - 1;
*new_softline_ret = 0;
} else {
- ledit_line *line = ledit_buffer_get_line(buffer, cur_line);
- int x, softline;
- pango_layout_index_to_line_x(line->layout, cur_index, 0, &softline, &x);
+ int softline = ledit_buffer_pos_to_softline(buffer, cur_line, cur_index);
if (movement > 0) {
- int softlines = pango_layout_get_line_count(line->layout);
+ int softlines = ledit_buffer_get_softline_count(buffer, cur_line);
if (softlines - softline > movement) {
*new_line_ret = cur_line;
*new_softline_ret = softline + movement;
@@ -350,8 +348,7 @@ get_new_line_softline(
movement -= (softlines - softline - 1);
int endline = cur_line + 1;
while (movement > 0 && endline < buffer->lines_num) {
- line = ledit_buffer_get_line(buffer, endline);
- softlines = pango_layout_get_line_count(line->layout);
+ softlines = ledit_buffer_get_softline_count(buffer, endline);
movement -= softlines;
endline++;
}
@@ -372,8 +369,7 @@ get_new_line_softline(
movement += softline;
int endline = cur_line - 1;
while (movement < 0 && endline >= 0) {
- line = ledit_buffer_get_line(buffer, endline);
- softlines = pango_layout_get_line_count(line->layout);
+ softlines = ledit_buffer_get_softline_count(buffer, endline);
movement += softlines;
endline--;
}
@@ -610,7 +606,6 @@ append_after_eol(ledit_buffer *buffer, char *text, int len) {
return (struct action){ACTION_NONE, NULL};
}
-/* FIXME: allow motion callback! */
static struct action
move_to_line(ledit_buffer *buffer, char *text, int len) {
(void)text;
@@ -631,13 +626,13 @@ move_to_line(ledit_buffer *buffer, char *text, int len) {
buffer->cur_line = line - 1;
buffer->cur_index = 0;
int text_w, text_h;
- PangoRectangle strong, weak;
ledit_window_get_textview_size(buffer->window, &text_w, &text_h);
ledit_line *ll = ledit_buffer_get_line(buffer, buffer->cur_line);
- pango_layout_get_cursor_pos(ll->layout, 0, &strong, &weak);
+ int x, y, h;
+ ledit_buffer_get_cursor_pixel_pos(buffer, buffer->cur_line, 0, &x, &y, &h);
/* if cursor is not on screen anymore, move to middle of screen */
if (ll->y_offset < buffer->display_offset ||
- ll->y_offset + strong.height / PANGO_SCALE > buffer->display_offset + text_h) {
+ ll->y_offset + h > buffer->display_offset + text_h) {
ledit_buffer_scroll(buffer, ll->y_offset - text_h / 2);
}
ledit_buffer_set_line_cursor_attrs(buffer, buffer->cur_line, buffer->cur_index);
@@ -647,30 +642,34 @@ move_to_line(ledit_buffer *buffer, char *text, int len) {
}
/* FIXME: should these scrolling functions change behavior when hard_line_based == 1? */
+/* FIXME: preserve x position on these scrolling functions */
static void
scroll_lines(ledit_buffer *buffer, int lines, int dir) {
int final_lines;
int text_w, text_h;
- PangoRectangle strong, weak;
ledit_line *ll = ledit_buffer_get_line(buffer, buffer->cur_line);
- pango_layout_get_cursor_pos(ll->layout, buffer->cur_index, &strong, &weak);
- long abs_pos = ll->y_offset + strong.y / PANGO_SCALE;
+ int x, y, h;
+ ledit_buffer_get_cursor_pixel_pos(buffer, buffer->cur_line, buffer->cur_index, &x, &y, &h);
+ long abs_pos = ll->y_offset + y;
ledit_window_get_textview_size(buffer->window, &text_w, &text_h);
if (lines > 0)
final_lines = last_lines_scrolled = lines;
else if (last_lines_scrolled > 0)
final_lines = last_lines_scrolled;
else
- final_lines = text_h / (strong.height / PANGO_SCALE);
+ final_lines = text_h / h / 2;
ledit_buffer_wipe_line_cursor_attrs(buffer, buffer->cur_line);
+ int sli; /* FIXME: set proper cursor position */
get_new_line_softline(
buffer, buffer->cur_line, buffer->cur_index,
dir < 0 ? -final_lines : final_lines,
- &buffer->cur_line, &buffer->cur_index
+ &buffer->cur_line, &sli
);
- ll = ledit_buffer_get_line(buffer, buffer->cur_line);
- pango_layout_get_cursor_pos(ll->layout, buffer->cur_index, &strong, &weak);
- long new_abs_pos = ll->y_offset + strong.y / PANGO_SCALE;
+ int start, end;
+ ledit_buffer_get_softline_bounds(buffer, buffer->cur_line, sli, &start, &end);
+ buffer->cur_index = start;
+ ledit_buffer_get_cursor_pixel_pos(buffer, buffer->cur_line, buffer->cur_index, &x, &y, &h);
+ long new_abs_pos = ll->y_offset + y;
ledit_buffer_scroll(buffer, buffer->display_offset + (new_abs_pos - abs_pos));
ledit_buffer_set_line_cursor_attrs(buffer, buffer->cur_line, buffer->cur_index);
}
@@ -703,10 +702,9 @@ scroll_lines_down(ledit_buffer *buffer, char *text, int len) {
static void
scroll_with_cursor(ledit_buffer *buffer, int movement) {
- PangoRectangle strong, weak;
- ledit_line *ll = ledit_buffer_get_line(buffer, buffer->cur_line);
- pango_layout_get_cursor_pos(ll->layout, buffer->cur_index, &strong, &weak);
- int pix_movement = movement * (strong.height / PANGO_SCALE);
+ int x, y, h;
+ ledit_buffer_get_cursor_pixel_pos(buffer, buffer->cur_line, buffer->cur_index, &x, &y, &h);
+ int pix_movement = movement * h;
ledit_buffer_scroll(buffer, buffer->display_offset + pix_movement);
int old_line = buffer->cur_line;
int old_index = buffer->cur_index;
@@ -1461,36 +1459,12 @@ move_cursor_left_right(ledit_buffer *buffer, int dir, int allow_illegal_index) {
if (num == 0)
num = 1;
- /* FIXME: trailing */
- int trailing = 0, tmp_index;
ledit_line *cur_line = ledit_buffer_get_line(buffer, buffer->cur_line);
- int new_index = buffer->cur_index, last_index = buffer->cur_index;
- while (num > 0) {
- tmp_index = new_index;
- pango_layout_move_cursor_visually(
- cur_line->layout, TRUE,
- new_index, trailing, dir,
- &new_index, &trailing
- );
- /* for some reason, this is necessary */
- if (new_index < 0)
- new_index = 0;
- else if (new_index > cur_line->len)
- new_index = cur_line->len;
- num--;
- if (tmp_index != new_index)
- last_index = tmp_index;
- }
- /* FIXME: Allow cursor to be at end of soft line */
- /* we don't currently support a difference between the cursor being at
- the end of a soft line and the beginning of the next line */
- /* FIXME: spaces at end of softlines are weird in normal mode */
- while (trailing > 0) {
- trailing--;
- new_index = ledit_line_next_utf8(cur_line, new_index);
- }
- if (new_index < 0)
- new_index = 0;
+ /* FIXME: standardize interface - num * dir or separately? */
+ int last_index;
+ int new_index = ledit_buffer_move_cursor_visually(
+ buffer, buffer->cur_line, buffer->cur_index, num * dir, &last_index
+ );
/* when in normal mode, the cursor cannot be at the very end
of the line because it's always covering a character */
if (new_index >= cur_line->len) {
@@ -1553,26 +1527,21 @@ return_key(ledit_buffer *buffer, char *text, int len) {
return (struct action){ACTION_NONE, NULL};
}
-/* FIXME: just just ledit_buffer_prev_cursor_pos */
static void
move_cursor_logically(ledit_buffer *buffer, int movement_dir, int allow_illegal_index) {
- PangoDirection dir = PANGO_DIRECTION_LTR;
- int tmp_index = buffer->cur_index;
- ledit_line *cur_line = ledit_buffer_get_line(buffer, buffer->cur_line);
- if (buffer->cur_index >= cur_line->len)
- tmp_index--;
- if (tmp_index >= 0)
- dir = pango_layout_get_direction(cur_line->layout, tmp_index);
- if (dir == PANGO_DIRECTION_RTL || dir == PANGO_DIRECTION_WEAK_RTL) {
- if (movement_dir < 0)
- move_cursor_left_right(buffer, 1, allow_illegal_index);
- else
- move_cursor_left_right(buffer, -1, allow_illegal_index);
+ if (movement_dir < 0) {
+ buffer->cur_index = ledit_buffer_prev_cursor_pos(
+ buffer, buffer->cur_line, buffer->cur_index, 1
+ );
} else {
- if (movement_dir < 0)
- move_cursor_left_right(buffer, -1, allow_illegal_index);
- else
- move_cursor_left_right(buffer, 1, allow_illegal_index);
+ buffer->cur_index = ledit_buffer_next_cursor_pos(
+ buffer, buffer->cur_line, buffer->cur_index, 1
+ );
+ }
+ if (!allow_illegal_index) {
+ buffer->cur_index = ledit_buffer_get_legal_normal_pos(
+ buffer, buffer->cur_line, buffer->cur_index
+ );
}
}