tFinish removing direct usage of pango in keys_basic.c - ledit - Text editor (W… | |
git clone git://lumidify.org/ledit.git (fast, but not encrypted) | |
git clone https://lumidify.org/git/ledit.git (encrypted, but very slow) | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit e76057dd60a70a13d5ede8274d504494d2ee70a8 | |
parent e80afa0ebd0f0fca40a797392db2a210ad466fa4 | |
Author: lumidify <[email protected]> | |
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 | |
t@@ -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… | |
+ 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… | |
+ /* 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 | |
t@@ -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… | |
int ledit_buffer_prev_cursor_pos(ledit_buffer *buffer, int line, int byte, int… | |
+int ledit_buffer_move_cursor_visually(ledit_buffer *buffer, int line, int pos,… | |
void ledit_buffer_next_word(ledit_buffer *buffer, int line, int byte, int num_… | |
void ledit_buffer_next_word_end(ledit_buffer *buffer, int line, int byte, int … | |
t@@ -86,6 +87,9 @@ void ledit_buffer_prev_word(ledit_buffer *buffer, int line, … | |
void ledit_buffer_prev_bigword(ledit_buffer *buffer, int line, int byte, int n… | |
void ledit_buffer_get_pos_softline_bounds(ledit_buffer *buffer, int line, int … | |
void ledit_buffer_get_softline_bounds(ledit_buffer *buffer, int line, int soft… | |
+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… | |
size_t ledit_buffer_textlen(ledit_buffer *buffer, int line1, int byte1, int li… | |
void ledit_buffer_copy_text(ledit_buffer *buffer, char *dst, int line1, int by… | |
diff --git a/keys_basic.c b/keys_basic.c | |
t@@ -1,3 +1,4 @@ | |
+/* FIXME: I guess hard_line_based should be updated for all buffers/windows wh… | |
/* 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 */ | |
t@@ -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" | |
t@@ -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, &soft… | |
+ int softline = ledit_buffer_pos_to_softline(buffer, cur_line, … | |
if (movement > 0) { | |
- int softlines = pango_layout_get_line_count(line->layo… | |
+ int softlines = ledit_buffer_get_softline_count(buffer… | |
if (softlines - softline > movement) { | |
*new_line_ret = cur_line; | |
*new_softline_ret = softline + movement; | |
t@@ -350,8 +348,7 @@ get_new_line_softline( | |
movement -= (softlines - softline - 1); | |
int endline = cur_line + 1; | |
while (movement > 0 && endline < buffer->lines… | |
- line = ledit_buffer_get_line(buffer, e… | |
- softlines = pango_layout_get_line_coun… | |
+ softlines = ledit_buffer_get_softline_… | |
movement -= softlines; | |
endline++; | |
} | |
t@@ -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, e… | |
- softlines = pango_layout_get_line_coun… | |
+ softlines = ledit_buffer_get_softline_… | |
movement += softlines; | |
endline--; | |
} | |
t@@ -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; | |
t@@ -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_… | |
ledit_line *ll = ledit_buffer_get_line(buffer, buffer->cur_lin… | |
- 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,… | |
/* if cursor is not on screen anymore, move to middle of scree… | |
if (ll->y_offset < buffer->display_offset || | |
- ll->y_offset + strong.height / PANGO_SCALE > buffer->displ… | |
+ 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, b… | |
t@@ -647,30 +642,34 @@ move_to_line(ledit_buffer *buffer, char *text, int len) { | |
} | |
/* FIXME: should these scrolling functions change behavior when hard_line_base… | |
+/* 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, &w… | |
- 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->cu… | |
+ 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, &w… | |
- 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… | |
+ buffer->cur_index = start; | |
+ ledit_buffer_get_cursor_pixel_pos(buffer, buffer->cur_line, buffer->cu… | |
+ long new_abs_pos = ll->y_offset + y; | |
ledit_buffer_scroll(buffer, buffer->display_offset + (new_abs_pos - ab… | |
ledit_buffer_set_line_cursor_attrs(buffer, buffer->cur_line, buffer->c… | |
} | |
t@@ -703,10 +702,9 @@ scroll_lines_down(ledit_buffer *buffer, char *text, int l… | |
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, &w… | |
- int pix_movement = movement * (strong.height / PANGO_SCALE); | |
+ int x, y, h; | |
+ ledit_buffer_get_cursor_pixel_pos(buffer, buffer->cur_line, buffer->cu… | |
+ 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; | |
t@@ -1461,36 +1459,12 @@ move_cursor_left_right(ledit_buffer *buffer, int dir, … | |
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) { | |
t@@ -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_illega… | |
- 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 | |
+ ); | |
} | |
} | |