diff options
Diffstat (limited to 'source/blender/editors/space_text')
-rw-r--r-- | source/blender/editors/space_text/text_ops.c | 108 |
1 files changed, 56 insertions, 52 deletions
diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c index 543fa0a0f72..060bf241bcf 100644 --- a/source/blender/editors/space_text/text_ops.c +++ b/source/blender/editors/space_text/text_ops.c @@ -2367,21 +2367,23 @@ static int flatten_column_to_offset(SpaceText *st, const char *str, int index) return j; } -static TextLine *get_first_visible_line(SpaceText *st, ARegion *ar, int *y) +static TextLine *get_line_pos_wrapped(SpaceText *st, ARegion *ar, int *y) { TextLine *linep = st->text->lines.first; - int i; - for (i = st->top; i > 0 && linep; ) { - int lines = text_get_visible_lines(st, ar, linep->line); - - if (i - lines < 0) { - *y += i; + int i, lines; + + if (*y < -st->top) { + return NULL; /* We are beyond the first line... */ + } + + for (i = -st->top; i <= *y && linep; linep = linep->next, i += lines) { + lines = text_get_visible_lines(st, ar, linep->line); + + if (i + lines > *y) { + /* We found the line matching given vertical 'coordinate', now set y relative to this line's start. */ + *y -= i; break; } - else { - linep = linep->next; - i -= lines; - } } return linep; } @@ -2391,23 +2393,22 @@ static void text_cursor_set_to_pos_wrapped(SpaceText *st, ARegion *ar, int x, in Text *text = st->text; int max = wrap_width(st, ar); /* column */ int charp = -1; /* mem */ - int loop = 1, found = 0; /* flags */ - char ch; - - /* Point to first visible line */ - TextLine *linep = get_first_visible_line(st, ar, &y); + bool found = false; /* flags */ - while (loop && linep) { + /* Point to line matching given y position, if any. */ + TextLine *linep = get_line_pos_wrapped(st, ar, &y); + + if (linep) { int i = 0, start = 0, end = max; /* column */ - int j = 0, curs = 0, endj = 0; /* mem */ - int chop = 1; /* flags */ - - for (; loop; j += BLI_str_utf8_size_safe(linep->line + j)) { + int j, curs = 0, endj = 0; /* mem */ + bool chop = true; /* flags */ + char ch; + + for (j = 0 ; !found && ((ch = linep->line[j]) != '\0'); j += BLI_str_utf8_size_safe(linep->line + j)) { int chars; int columns = BLI_str_utf8_char_width_safe(linep->line + j); /* = 1 for tab */ /* Mimic replacement of tabs */ - ch = linep->line[j]; if (ch == '\t') { chars = st->tabnumber - i % st->tabnumber; ch = ' '; @@ -2420,7 +2421,8 @@ static void text_cursor_set_to_pos_wrapped(SpaceText *st, ARegion *ar, int x, in /* Gone too far, go back to last wrap point */ if (y < 0) { charp = endj; - loop = 0; + y = 0; + found = true; break; /* Exactly at the cursor */ } @@ -2428,7 +2430,7 @@ static void text_cursor_set_to_pos_wrapped(SpaceText *st, ARegion *ar, int x, in /* current position could be wrapped to next line */ /* this should be checked when end of current line would be reached */ charp = curs = j; - found = 1; + found = true; /* Prepare curs for next wrap */ } else if (i - end <= x && i + columns - end > x) { @@ -2438,68 +2440,70 @@ static void text_cursor_set_to_pos_wrapped(SpaceText *st, ARegion *ar, int x, in end = MIN2(end, i); if (found) { - /* exact cursor position was found, check if it's */ - /* still on needed line (hasn't been wrapped) */ - if (charp > endj && !chop && ch != '\0') charp = endj; - loop = 0; + /* exact cursor position was found, check if it's still on needed line (hasn't been wrapped) */ + if (charp > endj && !chop && ch != '\0') + charp = endj; break; } - if (chop) endj = j; + if (chop) + endj = j; start = end; end += max; if (j < linep->len) y--; - chop = 1; + chop = true; if (y == 0 && i + columns - start > x) { charp = curs; - loop = 0; + found = true; break; } } else if (ch == ' ' || ch == '-' || ch == '\0') { if (found) { - loop = 0; break; } if (y == 0 && i + columns - start > x) { charp = curs; - loop = 0; + found = true; break; } end = i + 1; endj = j; - chop = 0; + chop = false; } i += columns; } - - if (ch == '\0') break; - } - - if (!loop || found) break; - - if (!linep->next) { - charp = linep->len; - break; } + + BLI_assert(y == 0); - /* On correct line but didn't meet cursor, must be at end */ - if (y == 0) { + if (!found) { + /* On correct line but didn't meet cursor, must be at end */ charp = linep->len; - break; } - linep = linep->next; - - y--; + } + else if (y < 0) { /* Before start of text. */ + linep = st->text->lines.first; + charp = 0; + } + else { /* Beyond end of text */ + linep = st->text->lines.last; + charp = linep->len; } - if (linep && charp != -1) { - if (sel) { text->sell = linep; text->selc = charp; } - else { text->curl = linep; text->curc = charp; } + BLI_assert(linep && charp != -1); + + if (sel) { + text->sell = linep; + text->selc = charp; + } + else { + text->curl = linep; + text->curc = charp; } } |