static void text_draw( const SpaceText *st, const TextDrawContext *tdc, char *str, int cshift, int maxwidth, int x, int y, const char *format) { const bool use_syntax = (st->showsyntax && format); FlattenString fs; int columns, size, n, w = 0, padding, amount = 0; const char *in = NULL; for (n = flatten_string(st, &fs, str), str = fs.buf; n > 0; n--) { columns = BLI_str_utf8_char_width_safe(str); size = BLI_str_utf8_size_safe(str); if (!in) { if (w >= cshift) { padding = w - cshift; in = str; } else if (format) format++; } if (in) { if (maxwidth && w + columns > cshift + maxwidth) break; amount++; } w += columns; str += size; } if (!in) { flatten_string_free(&fs); return; /* String is shorter than shift or ends with a padding */ } x += tdc->cwidth * padding; if (use_syntax) { int a, str_shift = 0; char fmt_prev = 0xff; for (a = 0; a < amount; a++) { if (format[a] != fmt_prev) format_draw_color(fmt_prev = format[a]); x += text_font_draw_character_utf8(tdc, x, y, in + str_shift); str_shift += BLI_str_utf8_size_safe(in + str_shift); } } else { text_font_draw(tdc, x, y, in); } flatten_string_free(&fs); }
int text_get_char_pos(SpaceText *st, const char *line, int cur) { int a = 0, i; for (i = 0; i < cur && line[i]; i += BLI_str_utf8_size_safe(line + i)) { if (line[i] == '\t') a += st->tabnumber - a % st->tabnumber; else a += BLI_str_utf8_char_width_safe(line + i); } return a; }
static void console_cursor_wrap_offset(const char *str, int width, int *row, int *column, const char *end) { int col; for (; *str; str += BLI_str_utf8_size_safe(str)) { col = BLI_str_utf8_char_width_safe(str); if (*column + col > width) { (*row)++; *column = 0; } if (end && str >= end) break; *column += col; } return; }
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; }
/* warning: allocated memory for 'offsets' must be freed by caller */ static int console_wrap_offsets(const char *str, int len, int width, int *lines, int **offsets) { int i, end; /* column */ int j; /* mem */ *lines = 1; *offsets = MEM_callocN(sizeof(**offsets) * (len * BLI_UTF8_WIDTH_MAX / MAX2(1, width - (BLI_UTF8_WIDTH_MAX - 1)) + 1), "console_wrap_offsets"); (*offsets)[0] = 0; for (i = 0, end = width, j = 0; j < len && str[j]; j += BLI_str_utf8_size_safe(str + j)) { int columns = BLI_str_utf8_char_width_safe(str + j); if (i + columns > end) { (*offsets)[*lines] = j; (*lines)++; end = i + width; } i += columns; } return j; /* return actual length */ }
static int text_draw_wrapped(SpaceText *st, const char *str, int x, int y, int w, const char *format, int skip) { FlattenString fs; int basex, lines; int i, wrap, end, max, columns, padding; /* column */ int a, fstart, fpos; /* utf8 chars */ int mi, ma, mstart, mend; /* mem */ char fmt_prev = 0xff; flatten_string(st, &fs, str); str = fs.buf; max = w / st->cwidth; if (max < 8) max = 8; basex = x; lines = 1; fpos = fstart = 0; mstart = 0; mend = txt_utf8_forward_columns(str, max, &padding) - str; end = wrap = max - padding; for (i = 0, mi = 0; str[mi]; i += columns, mi += BLI_str_utf8_size_safe(str + mi)) { columns = BLI_str_utf8_char_width_safe(str + mi); if (i + columns > end) { /* skip hidden part of line */ if (skip) { skip--; fstart = fpos; mstart = mend; mend = txt_utf8_forward_columns(str + mend, max, &padding) - str; end = (wrap += max - padding); continue; } /* Draw the visible portion of text on the overshot line */ for (a = fstart, ma = mstart; ma < mend; a++, ma += BLI_str_utf8_size_safe(str + ma)) { if (st->showsyntax && format) { if (fmt_prev != format[a]) format_draw_color(fmt_prev = format[a]); } x += text_font_draw_character_utf8(st, x, y, str + ma); fpos++; } y -= st->lheight_dpi + TXT_LINE_SPACING; x = basex; lines++; fstart = fpos; mstart = mend; mend = txt_utf8_forward_columns(str + mend, max, &padding) - str; end = (wrap += max - padding); if (y <= 0) break; } else if (str[mi] == ' ' || str[mi] == '-') { wrap = i + 1; mend = mi + 1; } } /* Draw the remaining text */ for (a = fstart, ma = mstart; str[ma] && y > 0; a++, ma += BLI_str_utf8_size_safe(str + ma)) { if (st->showsyntax && format) { if (fmt_prev != format[a]) format_draw_color(fmt_prev = format[a]); } x += text_font_draw_character_utf8(st, x, y, str + ma); } flatten_string_free(&fs); return lines; }
/* cursin - mem, offc - view */ void wrap_offset_in_line(SpaceText *st, ARegion *ar, TextLine *linein, int cursin, int *offl, int *offc) { int i, j, start, end, chars, max, chop; char ch; *offl = *offc = 0; if (!st->text) return; if (!st->wordwrap) return; max = wrap_width(st, ar); start = 0; end = max; chop = 1; *offc = 0; cursin = txt_utf8_offset_to_column(linein->line, cursin); for (i = 0, j = 0; linein->line[j]; j += BLI_str_utf8_size_safe(linein->line + j)) { int columns = BLI_str_utf8_char_width_safe(linein->line + j); /* = 1 for tab */ /* Mimic replacement of tabs */ ch = linein->line[j]; if (ch == '\t') { chars = st->tabnumber - i % st->tabnumber; if (i < cursin) cursin += chars - 1; ch = ' '; } else chars = 1; while (chars--) { if (i + columns - start > max) { end = MIN2(end, i); if (chop && 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 (i >= cursin) return; } i += columns; } } }
/* 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; } }
static int text_draw_wrapped( const SpaceText *st, const TextDrawContext *tdc, const char *str, int x, int y, int w, const char *format, int skip) { const bool use_syntax = (st->showsyntax && format); FlattenString fs; int basex, lines; int i, wrap, end, max, columns, padding; /* column */ /* warning, only valid when 'use_syntax' is set */ int a, fstart, fpos; /* utf8 chars */ int mi, ma, mstart, mend; /* mem */ char fmt_prev = 0xff; /* don't draw lines below this */ const int clip_min_y = -(int)(st->lheight_dpi - 1); flatten_string(st, &fs, str); str = fs.buf; max = w / st->cwidth; if (max < 8) max = 8; basex = x; lines = 1; fpos = fstart = 0; mstart = 0; mend = txt_utf8_forward_columns(str, max, &padding) - str; end = wrap = max - padding; for (i = 0, mi = 0; str[mi]; i += columns, mi += BLI_str_utf8_size_safe(str + mi)) { columns = BLI_str_utf8_char_width_safe(str + mi); if (i + columns > end) { /* skip hidden part of line */ if (skip) { skip--; if (use_syntax) { /* currently fpos only used when formatting */ fpos += BLI_strnlen_utf8(str + mstart, mend - mstart); } fstart = fpos; mstart = mend; mend = txt_utf8_forward_columns(str + mend, max, &padding) - str; end = (wrap += max - padding); continue; } /* Draw the visible portion of text on the overshot line */ for (a = fstart, ma = mstart; ma < mend; a++, ma += BLI_str_utf8_size_safe(str + ma)) { if (use_syntax) { if (fmt_prev != format[a]) format_draw_color(fmt_prev = format[a]); } x += text_font_draw_character_utf8(tdc, x, y, str + ma); fpos++; } y -= st->lheight_dpi + TXT_LINE_SPACING; x = basex; lines++; fstart = fpos; mstart = mend; mend = txt_utf8_forward_columns(str + mend, max, &padding) - str; end = (wrap += max - padding); if (y <= clip_min_y) break; } else if (str[mi] == ' ' || str[mi] == '-') { wrap = i + 1; mend = mi + 1; } } /* Draw the remaining text */ for (a = fstart, ma = mstart; str[ma] && y > clip_min_y; a++, ma += BLI_str_utf8_size_safe(str + ma)) { if (use_syntax) { if (fmt_prev != format[a]) format_draw_color(fmt_prev = format[a]); } x += text_font_draw_character_utf8(tdc, x, y, str + ma); } flatten_string_free(&fs); return lines; }