Console: add support for displaying tab-stops
Without this it was necessary to convert pasted text into spaces for them to display properly. Since tabs are a valid part of a string, it's incorrect to assume tabs can always be expanded to spaces. Pasted text and console output now display tabs properly, the tab still uses spaces for indenting though.
This commit is contained in:
@@ -34,8 +34,7 @@ class _TempModuleOverride:
|
||||
|
||||
def add_scrollback(text, text_type):
|
||||
for l in text.split("\n"):
|
||||
bpy.ops.console.scrollback_append(text=l.replace("\t", " "),
|
||||
type=text_type)
|
||||
bpy.ops.console.scrollback_append(text=l, type=text_type)
|
||||
|
||||
|
||||
def replace_help(namespace):
|
||||
|
||||
@@ -122,7 +122,8 @@ void BLF_batch_draw_end(void);
|
||||
void BLF_draw_ex(int fontid, const char *str, size_t str_len, struct ResultBLF *r_info)
|
||||
ATTR_NONNULL(2);
|
||||
void BLF_draw(int fontid, const char *str, size_t str_len) ATTR_NONNULL(2);
|
||||
int BLF_draw_mono(int fontid, const char *str, size_t str_len, int cwidth) ATTR_NONNULL(2);
|
||||
int BLF_draw_mono(int fontid, const char *str, size_t str_len, int cwidth, int tab_columns)
|
||||
ATTR_NONNULL(2);
|
||||
|
||||
typedef bool (*BLF_GlyphBoundsFn)(const char *str,
|
||||
size_t str_step_ofs,
|
||||
|
||||
@@ -570,7 +570,7 @@ void BLF_draw(int fontid, const char *str, const size_t str_len)
|
||||
BLF_draw_ex(fontid, str, str_len, nullptr);
|
||||
}
|
||||
|
||||
int BLF_draw_mono(int fontid, const char *str, const size_t str_len, int cwidth)
|
||||
int BLF_draw_mono(int fontid, const char *str, const size_t str_len, int cwidth, int tab_columns)
|
||||
{
|
||||
if (str_len == 0 || str[0] == '\0') {
|
||||
return 0;
|
||||
@@ -581,7 +581,7 @@ int BLF_draw_mono(int fontid, const char *str, const size_t str_len, int cwidth)
|
||||
|
||||
if (font) {
|
||||
blf_draw_gl__start(font);
|
||||
columns = blf_font_draw_mono(font, str, str_len, cwidth);
|
||||
columns = blf_font_draw_mono(font, str, str_len, cwidth, tab_columns);
|
||||
blf_draw_gl__end(font);
|
||||
}
|
||||
|
||||
|
||||
@@ -464,7 +464,8 @@ void blf_font_draw(FontBLF *font, const char *str, const size_t str_len, ResultB
|
||||
blf_glyph_cache_release(font);
|
||||
}
|
||||
|
||||
int blf_font_draw_mono(FontBLF *font, const char *str, const size_t str_len, int cwidth)
|
||||
int blf_font_draw_mono(
|
||||
FontBLF *font, const char *str, const size_t str_len, int cwidth, int tab_columns)
|
||||
{
|
||||
GlyphBLF *g;
|
||||
int columns = 0;
|
||||
@@ -486,7 +487,8 @@ int blf_font_draw_mono(FontBLF *font, const char *str, const size_t str_len, int
|
||||
/* do not return this loop if clipped, we want every character tested */
|
||||
blf_glyph_draw(font, gc, g, ft_pix_to_int_floor(pen_x), ft_pix_to_int_floor(pen_y));
|
||||
|
||||
const int col = BLI_wcwidth_safe(char32_t(g->c));
|
||||
const int col = UNLIKELY(g->c == '\t') ? (tab_columns - (columns % tab_columns)) :
|
||||
BLI_wcwidth_safe(char32_t(g->c));
|
||||
columns += col;
|
||||
pen_x += cwidth_fpx * col;
|
||||
}
|
||||
|
||||
@@ -103,7 +103,8 @@ void blf_font_draw__wrap(struct FontBLF *font,
|
||||
/**
|
||||
* Use fixed column width, but an utf8 character may occupy multiple columns.
|
||||
*/
|
||||
int blf_font_draw_mono(struct FontBLF *font, const char *str, size_t str_len, int cwidth);
|
||||
int blf_font_draw_mono(
|
||||
struct FontBLF *font, const char *str, size_t str_len, int cwidth, int tab_columns);
|
||||
void blf_font_draw_buffer(struct FontBLF *font,
|
||||
const char *str,
|
||||
size_t str_len,
|
||||
|
||||
@@ -112,9 +112,11 @@ static void console_cursor_wrap_offset(
|
||||
const char *str, int width, int *row, int *column, const char *end)
|
||||
{
|
||||
int col;
|
||||
const int tab_width = 4;
|
||||
|
||||
for (; *str; str += BLI_str_utf8_size_safe(str)) {
|
||||
col = BLI_str_utf8_char_width_safe(str);
|
||||
col = UNLIKELY(*str == '\t') ? (tab_width - (*column % tab_width)) :
|
||||
BLI_str_utf8_char_width_safe(str);
|
||||
|
||||
if (*column + col > width) {
|
||||
(*row)++;
|
||||
|
||||
@@ -36,6 +36,8 @@
|
||||
|
||||
#include "console_intern.hh"
|
||||
|
||||
#define TAB_LENGTH 4
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Utilities
|
||||
* \{ */
|
||||
@@ -488,25 +490,13 @@ void CONSOLE_OT_move(wmOperatorType *ot)
|
||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
}
|
||||
|
||||
#define TAB_LENGTH 4
|
||||
static int console_insert_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
SpaceConsole *sc = CTX_wm_space_console(C);
|
||||
ARegion *region = CTX_wm_region(C);
|
||||
ConsoleLine *ci = console_history_verify(C);
|
||||
char *str = RNA_string_get_alloc(op->ptr, "text", nullptr, 0, nullptr);
|
||||
int len;
|
||||
|
||||
if (str[0] == '\t' && str[1] == '\0') {
|
||||
len = TAB_LENGTH;
|
||||
MEM_freeN(str);
|
||||
str = static_cast<char *>(MEM_mallocN(len + 1, "insert_exec"));
|
||||
memset(str, ' ', len);
|
||||
str[len] = '\0';
|
||||
}
|
||||
else {
|
||||
len = strlen(str);
|
||||
}
|
||||
int len = strlen(str);
|
||||
|
||||
/* Allow trailing newlines (but strip them). */
|
||||
while (len > 0 && str[len - 1] == '\n') {
|
||||
|
||||
@@ -69,8 +69,10 @@ static void textview_draw_sel(const char *str,
|
||||
const int lheight = tds->lheight;
|
||||
|
||||
if (sel[0] <= str_len_draw && sel[1] >= 0) {
|
||||
const int sta = BLI_str_utf8_offset_to_column(str, str_len_draw, max_ii(sel[0], 0));
|
||||
const int end = BLI_str_utf8_offset_to_column(str, str_len_draw, min_ii(sel[1], str_len_draw));
|
||||
const int sta = BLI_str_utf8_offset_to_column_with_tabs(
|
||||
str, str_len_draw, max_ii(sel[0], 0), TVC_TAB_COLUMNS);
|
||||
const int end = BLI_str_utf8_offset_to_column_with_tabs(
|
||||
str, str_len_draw, min_ii(sel[1], str_len_draw), TVC_TAB_COLUMNS);
|
||||
|
||||
GPU_blend(GPU_BLEND_ALPHA);
|
||||
|
||||
@@ -96,17 +98,20 @@ static int textview_wrap_offsets(
|
||||
{
|
||||
int i, end; /* Offset as unicode code-point. */
|
||||
int j; /* Offset as bytes. */
|
||||
const int tab_columns = TVC_TAB_COLUMNS;
|
||||
const int column_width_max = MAX2(tab_columns, BLI_UTF8_WIDTH_MAX);
|
||||
|
||||
*r_lines = 1;
|
||||
|
||||
*r_offsets = static_cast<int *>(MEM_callocN(
|
||||
sizeof(**r_offsets) *
|
||||
(str_len * BLI_UTF8_WIDTH_MAX / MAX2(1, width - (BLI_UTF8_WIDTH_MAX - 1)) + 1),
|
||||
__func__));
|
||||
*r_offsets = static_cast<int *>(
|
||||
MEM_callocN(sizeof(**r_offsets) *
|
||||
(str_len * column_width_max / MAX2(1, width - (column_width_max - 1)) + 1),
|
||||
__func__));
|
||||
(*r_offsets)[0] = 0;
|
||||
|
||||
for (i = 0, end = width, j = 0; j < str_len && str[j]; j += BLI_str_utf8_size_safe(str + j)) {
|
||||
int columns = BLI_str_utf8_char_width_safe(str + j);
|
||||
int columns = UNLIKELY(*(str + j) == '\t') ? (tab_columns - (i % tab_columns)) :
|
||||
BLI_str_utf8_char_width_safe(str + j);
|
||||
|
||||
if (i + columns > end) {
|
||||
(*r_offsets)[*r_lines] = j;
|
||||
@@ -157,8 +162,11 @@ static bool textview_draw_string(TextViewDrawState *tds,
|
||||
}
|
||||
|
||||
/* Last part. */
|
||||
ofs += BLI_str_utf8_offset_from_column(
|
||||
str + ofs, str_len - ofs, int(floor(float(tds->mval[0]) / tds->cwidth)));
|
||||
ofs += BLI_str_utf8_offset_from_column_with_tabs(
|
||||
str + ofs,
|
||||
str_len - ofs,
|
||||
int(floor(float(tds->mval[0]) / tds->cwidth)),
|
||||
TVC_TAB_COLUMNS);
|
||||
|
||||
CLAMP(ofs, 0, str_len);
|
||||
*tds->mval_pick_offset += str_len - ofs;
|
||||
@@ -255,7 +263,7 @@ static bool textview_draw_string(TextViewDrawState *tds,
|
||||
|
||||
BLF_position(tds->font_id, tds->xy[0], tds->lofs + line_bottom + tds->row_vpadding, 0);
|
||||
BLF_color4ubv(tds->font_id, fg);
|
||||
BLF_draw_mono(tds->font_id, s, len, tds->cwidth);
|
||||
BLF_draw_mono(tds->font_id, s, len, tds->cwidth, TVC_TAB_COLUMNS);
|
||||
|
||||
tds->xy[1] += tds->lheight;
|
||||
|
||||
@@ -271,7 +279,7 @@ static bool textview_draw_string(TextViewDrawState *tds,
|
||||
}
|
||||
|
||||
BLF_position(tds->font_id, tds->xy[0], tds->lofs + tds->xy[1], 0);
|
||||
BLF_draw_mono(tds->font_id, s, len, tds->cwidth);
|
||||
BLF_draw_mono(tds->font_id, s, len, tds->cwidth, TVC_TAB_COLUMNS);
|
||||
|
||||
tds->xy[1] += tds->lheight;
|
||||
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#define TVC_TAB_COLUMNS 4
|
||||
|
||||
enum eTextViewContext_LineFlag {
|
||||
TVC_LINE_FG = (1 << 0),
|
||||
TVC_LINE_BG = (1 << 1),
|
||||
|
||||
@@ -64,16 +64,19 @@ static void text_font_end(const TextDrawContext * /*tdc*/) {}
|
||||
|
||||
static int text_font_draw(const TextDrawContext *tdc, int x, int y, const char *str)
|
||||
{
|
||||
const char tab_columns = 1; /* Tab characters aren't used here. */
|
||||
BLF_position(tdc->font_id, x, y, 0);
|
||||
const int columns = BLF_draw_mono(tdc->font_id, str, BLF_DRAW_STR_DUMMY_MAX, tdc->cwidth_px);
|
||||
const int columns = BLF_draw_mono(
|
||||
tdc->font_id, str, BLF_DRAW_STR_DUMMY_MAX, tdc->cwidth_px, tab_columns);
|
||||
|
||||
return tdc->cwidth_px * columns;
|
||||
}
|
||||
|
||||
static int text_font_draw_character(const TextDrawContext *tdc, int x, int y, char c)
|
||||
{
|
||||
const char tab_columns = 1;
|
||||
BLF_position(tdc->font_id, x, y, 0);
|
||||
BLF_draw_mono(tdc->font_id, &c, 1, tdc->cwidth_px);
|
||||
BLF_draw_mono(tdc->font_id, &c, 1, tdc->cwidth_px, tab_columns);
|
||||
|
||||
return tdc->cwidth_px;
|
||||
}
|
||||
@@ -82,8 +85,9 @@ static int text_font_draw_character_utf8(
|
||||
const TextDrawContext *tdc, int x, int y, const char *c, const int c_len)
|
||||
{
|
||||
BLI_assert(c_len == BLI_str_utf8_size_safe(c));
|
||||
const char tab_columns = 1; /* Tab characters aren't used here. */
|
||||
BLF_position(tdc->font_id, x, y, 0);
|
||||
const int columns = BLF_draw_mono(tdc->font_id, c, c_len, tdc->cwidth_px);
|
||||
const int columns = BLF_draw_mono(tdc->font_id, c, c_len, tdc->cwidth_px, tab_columns);
|
||||
|
||||
return tdc->cwidth_px * columns;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user