Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/text.c
| Context not available. | |||||
| i++; | i++; | ||||
| return i; | return i; | ||||
| } | } | ||||
| void text_line_char_to_screen_pos(SpaceText *st, ARegion *ar, int line_char[2], int screen_pos[2]) | |||||
campbellbarton: `line_char` can be `const` | |||||
campbellbartonAuthorUnsubmitted Not Done Inline Actionsthink it would be good to return true/false based on weather the line_char exists. campbellbarton: think it would be good to return true/false based on weather the `line_char` exists. | |||||
| { | |||||
| TextLine* line = NULL; | |||||
| if (st && st->text) { | |||||
| /*ensure line, char are valid text positions (hmm, why... does it matter here?) */ | |||||
| if ((line_char[0] < 0) || (line_char[0] > BLI_listbase_count(&st->text->lines))) { | |||||
campbellbartonAuthorUnsubmitted Not Done Inline Actionscounting the entire list seems unnecessary, just allow BLI_findlink below to fail. campbellbarton: counting the entire list seems unnecessary, just allow `BLI_findlink` below to fail. | |||||
| screen_pos[0] = screen_pos[1] = 0; | |||||
| } | |||||
| else { | |||||
| line = (TextLine*)BLI_findlink(&st->text->lines, line_char[0]); | |||||
campbellbartonAuthorUnsubmitted Not Done Inline Actionsno need to cast. campbellbarton: no need to cast. | |||||
| if (!line || (line_char[1] > line->len)) { | |||||
| screen_pos[0] = screen_pos[1] = 0; | |||||
| } | |||||
| else { | |||||
| int offl = 0, offc = 0; | |||||
| if (st->wordwrap) { | |||||
| wrap_offset(st, ar, line, line_char[1], &offl, &offc); | |||||
| } | |||||
| screen_pos[0] = (line_char[1] + offc - st->left) * st->cwidth; | |||||
| screen_pos[1] = (line_char[0] + offl - st->top) * (st->lheight_dpi + TXT_LINE_SPACING); | |||||
| } | |||||
| } | |||||
| } | |||||
| else { | |||||
| screen_pos[0] = screen_pos[1] = 0; | |||||
| } | |||||
| } | |||||
| int wrap_width(SpaceText *st, ARegion *ar) | |||||
| { | |||||
| int winx = ar->winx - TXT_SCROLL_WIDTH; | |||||
| int x, max; | |||||
| x = st->showlinenrs ? TXT_OFFSET + TEXTXLOC : TXT_OFFSET; | |||||
| max = st->cwidth ? (winx - x) / st->cwidth : 0; | |||||
| return max > 8 ? max : 8; | |||||
| } | |||||
| int text_get_visible_lines(SpaceText *st, ARegion *ar, const char *str) | |||||
| { | |||||
| int i, j, start, end, max, lines, chars; | |||||
| char ch; | |||||
| max = wrap_width(st, ar); | |||||
| lines = 1; | |||||
| start = 0; | |||||
| end = max; | |||||
| for (i = 0, j = 0; str[j]; j += BLI_str_utf8_size_safe(str + j)) { | |||||
| int columns = BLI_str_utf8_char_width_safe(str + j); /* = 1 for tab */ | |||||
| /* Mimic replacement of tabs */ | |||||
| ch = str[j]; | |||||
| if (ch == '\t') { | |||||
| chars = st->tabnumber - i % st->tabnumber; | |||||
| ch = ' '; | |||||
| } | |||||
| else { | |||||
| chars = 1; | |||||
| } | |||||
| while (chars--) { | |||||
| if (i + columns - start > max) { | |||||
| lines++; | |||||
| start = MIN2(end, i); | |||||
| end += max; | |||||
| } | |||||
| else if (ch == ' ' || ch == '-') { | |||||
| end = i + 1; | |||||
| } | |||||
| i += columns; | |||||
| } | |||||
| } | |||||
| return lines; | |||||
| } | |||||
| /* Sets (offl, offc) for transforming (line, curs) to its wrapped position */ | |||||
| void wrap_offset(SpaceText *st, ARegion *ar, TextLine *linein, int cursin, int *offl, int *offc) | |||||
| { | |||||
| Text *text; | |||||
| TextLine *linep; | |||||
| int i, j, start, end, max, chop; | |||||
| char ch; | |||||
| *offl = *offc = 0; | |||||
| if (!st->text) return; | |||||
| if (!st->wordwrap) return; | |||||
| text = st->text; | |||||
| /* Move pointer to first visible line (top) */ | |||||
| linep = text->lines.first; | |||||
| i = st->top; | |||||
| while (i > 0 && linep) { | |||||
| int lines = text_get_visible_lines(st, ar, linep->line); | |||||
| /* Line before top */ | |||||
| if (linep == linein) { | |||||
| if (lines <= i) | |||||
| /* no visible part of line */ | |||||
| return; | |||||
| } | |||||
| if (i - lines < 0) { | |||||
| break; | |||||
| } | |||||
| else { | |||||
| linep = linep->next; | |||||
| (*offl) += lines - 1; | |||||
| i -= lines; | |||||
| } | |||||
| } | |||||
| max = wrap_width(st, ar); | |||||
| cursin = txt_utf8_offset_to_column(linein->line, cursin); | |||||
| while (linep) { | |||||
| start = 0; | |||||
| end = max; | |||||
| chop = 1; | |||||
| *offc = 0; | |||||
| for (i = 0, j = 0; linep->line[j]; 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; | |||||
| if (linep == linein && i < cursin) cursin += chars - 1; | |||||
| ch = ' '; | |||||
| } | |||||
| else { | |||||
| chars = 1; | |||||
| } | |||||
| while (chars--) { | |||||
| if (i + columns - start > max) { | |||||
| end = MIN2(end, i); | |||||
| if (chop && linep == linein && i >= cursin) { | |||||
| if (i == cursin) { | |||||
| (*offl)++; | |||||
| *offc -= end - start; | |||||
| } | |||||
| return; | |||||
| } | |||||
| (*offl)++; | |||||
| *offc -= end - start; | |||||
| start = end; | |||||
| end += max; | |||||
| chop = 1; | |||||
| } | |||||
| else if (ch == ' ' || ch == '-') { | |||||
| end = i + 1; | |||||
| chop = 0; | |||||
| if (linep == linein && i >= cursin) | |||||
| return; | |||||
| } | |||||
| i += columns; | |||||
| } | |||||
| } | |||||
| if (linep == linein) break; | |||||
| linep = linep->next; | |||||
| } | |||||
| } | |||||
| Context not available. | |||||
line_char can be const