|
|
@ -270,11 +270,11 @@ void view_curses::mvwattrline(WINDOW *window,
|
|
|
|
int y,
|
|
|
|
int y,
|
|
|
|
int x,
|
|
|
|
int x,
|
|
|
|
attr_line_t &al,
|
|
|
|
attr_line_t &al,
|
|
|
|
const struct line_range &lr,
|
|
|
|
const struct line_range &lr_chars,
|
|
|
|
view_colors::role_t base_role)
|
|
|
|
view_colors::role_t base_role)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
attr_t text_attrs, attrs;
|
|
|
|
attr_t text_attrs, attrs;
|
|
|
|
int line_width;
|
|
|
|
int line_width_chars;
|
|
|
|
string_attrs_t & sa = al.get_attrs();
|
|
|
|
string_attrs_t & sa = al.get_attrs();
|
|
|
|
string & line = al.get_string();
|
|
|
|
string & line = al.get_string();
|
|
|
|
string_attrs_t::const_iterator iter;
|
|
|
|
string_attrs_t::const_iterator iter;
|
|
|
@ -285,16 +285,18 @@ void view_curses::mvwattrline(WINDOW *window,
|
|
|
|
int exp_offset = 0;
|
|
|
|
int exp_offset = 0;
|
|
|
|
string full_line;
|
|
|
|
string full_line;
|
|
|
|
|
|
|
|
|
|
|
|
require(lr.lr_end >= 0);
|
|
|
|
require(lr_chars.lr_end >= 0);
|
|
|
|
|
|
|
|
|
|
|
|
line_width = lr.length();
|
|
|
|
line_width_chars = lr_chars.length();
|
|
|
|
tab_count = count(line.begin(), line.end(), '\t');
|
|
|
|
tab_count = count(line.begin(), line.end(), '\t');
|
|
|
|
expanded_line = (char *)alloca(line.size() + tab_count * 8 + 1);
|
|
|
|
expanded_line = (char *)alloca(line.size() + tab_count * 8 + 1);
|
|
|
|
|
|
|
|
|
|
|
|
short *fg_color = (short *) alloca(line_width * sizeof(short));
|
|
|
|
short *fg_color = (short *) alloca(line_width_chars * sizeof(short));
|
|
|
|
bool has_fg = false;
|
|
|
|
bool has_fg = false;
|
|
|
|
short *bg_color = (short *) alloca(line_width * sizeof(short));
|
|
|
|
short *bg_color = (short *) alloca(line_width_chars * sizeof(short));
|
|
|
|
bool has_bg = false;
|
|
|
|
bool has_bg = false;
|
|
|
|
|
|
|
|
line_range lr_bytes{lr_chars.lr_start, lr_chars.lr_end};
|
|
|
|
|
|
|
|
int char_index = 0;
|
|
|
|
|
|
|
|
|
|
|
|
for (size_t lpc = 0; lpc < line.size(); lpc++) {
|
|
|
|
for (size_t lpc = 0; lpc < line.size(); lpc++) {
|
|
|
|
int exp_start_index = exp_index;
|
|
|
|
int exp_start_index = exp_index;
|
|
|
@ -305,14 +307,17 @@ void view_curses::mvwattrline(WINDOW *window,
|
|
|
|
do {
|
|
|
|
do {
|
|
|
|
expanded_line[exp_index] = ' ';
|
|
|
|
expanded_line[exp_index] = ' ';
|
|
|
|
exp_index += 1;
|
|
|
|
exp_index += 1;
|
|
|
|
|
|
|
|
char_index += 1;
|
|
|
|
} while (exp_index % 8);
|
|
|
|
} while (exp_index % 8);
|
|
|
|
utf_adjustments.emplace_back(lpc, exp_index - exp_start_index - 1);
|
|
|
|
utf_adjustments.emplace_back(lpc,
|
|
|
|
|
|
|
|
exp_index - exp_start_index - 1);
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case '\r':
|
|
|
|
case '\r':
|
|
|
|
case '\n':
|
|
|
|
case '\n':
|
|
|
|
expanded_line[exp_index] = ' ';
|
|
|
|
expanded_line[exp_index] = ' ';
|
|
|
|
exp_index += 1;
|
|
|
|
exp_index += 1;
|
|
|
|
|
|
|
|
char_index += 1;
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
default: {
|
|
|
|
default: {
|
|
|
@ -329,6 +334,12 @@ void view_curses::mvwattrline(WINDOW *window,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (offset) {
|
|
|
|
if (offset) {
|
|
|
|
|
|
|
|
if (char_index < lr_chars.lr_start) {
|
|
|
|
|
|
|
|
lr_bytes.lr_start += abs(offset);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (char_index < lr_chars.lr_end) {
|
|
|
|
|
|
|
|
lr_bytes.lr_end += abs(offset);
|
|
|
|
|
|
|
|
}
|
|
|
|
exp_offset += offset;
|
|
|
|
exp_offset += offset;
|
|
|
|
utf_adjustments.emplace_back(lpc, offset);
|
|
|
|
utf_adjustments.emplace_back(lpc, offset);
|
|
|
|
for (; offset && (lpc + 1) < line.size(); lpc++, offset++) {
|
|
|
|
for (; offset && (lpc + 1) < line.size(); lpc++, offset++) {
|
|
|
@ -336,6 +347,7 @@ void view_curses::mvwattrline(WINDOW *window,
|
|
|
|
exp_index += 1;
|
|
|
|
exp_index += 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
char_index += 1;
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -349,11 +361,11 @@ void view_curses::mvwattrline(WINDOW *window,
|
|
|
|
attrs = text_attrs;
|
|
|
|
attrs = text_attrs;
|
|
|
|
wmove(window, y, x);
|
|
|
|
wmove(window, y, x);
|
|
|
|
wattron(window, attrs);
|
|
|
|
wattron(window, attrs);
|
|
|
|
if (lr.lr_start < (int)full_line.size()) {
|
|
|
|
if (lr_bytes.lr_start < (int)full_line.size()) {
|
|
|
|
waddnstr(window, &full_line.c_str()[lr.lr_start], line_width);
|
|
|
|
waddnstr(window, &full_line.c_str()[lr_bytes.lr_start], lr_bytes.length());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (lr.lr_end > (int)full_line.size()) {
|
|
|
|
if (lr_bytes.lr_end > (int)full_line.size()) {
|
|
|
|
whline(window, ' ', lr.lr_end - (full_line.size() + exp_offset));
|
|
|
|
whline(window, ' ', lr_bytes.lr_end - (full_line.size() + exp_offset));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
wattroff(window, attrs);
|
|
|
|
wattroff(window, attrs);
|
|
|
|
|
|
|
|
|
|
|
@ -375,7 +387,7 @@ void view_curses::mvwattrline(WINDOW *window,
|
|
|
|
for (const auto &adj : utf_adjustments) {
|
|
|
|
for (const auto &adj : utf_adjustments) {
|
|
|
|
// If the UTF adjustment is in the viewport, we need to adjust this
|
|
|
|
// If the UTF adjustment is in the viewport, we need to adjust this
|
|
|
|
// attribute.
|
|
|
|
// attribute.
|
|
|
|
if (adj.uda_origin >= lr.lr_start &&
|
|
|
|
if (adj.uda_origin >= lr_chars.lr_start &&
|
|
|
|
adj.uda_origin < iter->sa_range.lr_start) {
|
|
|
|
adj.uda_origin < iter->sa_range.lr_start) {
|
|
|
|
attr_range.lr_start += adj.uda_offset;
|
|
|
|
attr_range.lr_start += adj.uda_offset;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -383,22 +395,22 @@ void view_curses::mvwattrline(WINDOW *window,
|
|
|
|
|
|
|
|
|
|
|
|
if (attr_range.lr_end != -1) {
|
|
|
|
if (attr_range.lr_end != -1) {
|
|
|
|
for (const auto &adj : utf_adjustments) {
|
|
|
|
for (const auto &adj : utf_adjustments) {
|
|
|
|
if (adj.uda_origin >= lr.lr_start &&
|
|
|
|
if (adj.uda_origin >= lr_chars.lr_start &&
|
|
|
|
adj.uda_origin < iter->sa_range.lr_end) {
|
|
|
|
adj.uda_origin < iter->sa_range.lr_end) {
|
|
|
|
attr_range.lr_end += adj.uda_offset;
|
|
|
|
attr_range.lr_end += adj.uda_offset;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
attr_range.lr_start = max(0, attr_range.lr_start - lr.lr_start);
|
|
|
|
attr_range.lr_start = max(0, attr_range.lr_start - lr_chars.lr_start);
|
|
|
|
if (attr_range.lr_start > line_width) {
|
|
|
|
if (attr_range.lr_start > line_width_chars) {
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (attr_range.lr_end == -1) {
|
|
|
|
if (attr_range.lr_end == -1) {
|
|
|
|
attr_range.lr_end = lr.lr_start + line_width;
|
|
|
|
attr_range.lr_end = lr_chars.lr_start + line_width_chars;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
attr_range.lr_end = min(line_width, attr_range.lr_end - lr.lr_start);
|
|
|
|
attr_range.lr_end = min(line_width_chars, attr_range.lr_end - lr_chars.lr_start);
|
|
|
|
|
|
|
|
|
|
|
|
if (iter->sa_type == &VC_GRAPHIC) {
|
|
|
|
if (iter->sa_type == &VC_GRAPHIC) {
|
|
|
|
for (int index = attr_range.lr_start;
|
|
|
|
for (int index = attr_range.lr_start;
|
|
|
@ -411,7 +423,7 @@ void view_curses::mvwattrline(WINDOW *window,
|
|
|
|
|
|
|
|
|
|
|
|
if (iter->sa_type == &VC_FOREGROUND) {
|
|
|
|
if (iter->sa_type == &VC_FOREGROUND) {
|
|
|
|
if (!has_fg) {
|
|
|
|
if (!has_fg) {
|
|
|
|
memset(fg_color, -1, line_width * sizeof(short));
|
|
|
|
memset(fg_color, -1, line_width_chars * sizeof(short));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fill(&fg_color[attr_range.lr_start], &fg_color[attr_range.lr_end], (short) iter->sa_value.sav_int);
|
|
|
|
fill(&fg_color[attr_range.lr_start], &fg_color[attr_range.lr_end], (short) iter->sa_value.sav_int);
|
|
|
|
has_fg = true;
|
|
|
|
has_fg = true;
|
|
|
@ -420,7 +432,7 @@ void view_curses::mvwattrline(WINDOW *window,
|
|
|
|
|
|
|
|
|
|
|
|
if (iter->sa_type == &VC_BACKGROUND) {
|
|
|
|
if (iter->sa_type == &VC_BACKGROUND) {
|
|
|
|
if (!has_bg) {
|
|
|
|
if (!has_bg) {
|
|
|
|
memset(bg_color, -1, line_width * sizeof(short));
|
|
|
|
memset(bg_color, -1, line_width_chars * sizeof(short));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fill(bg_color + attr_range.lr_start, bg_color + attr_range.lr_end, (short) iter->sa_value.sav_int);
|
|
|
|
fill(bg_color + attr_range.lr_start, bg_color + attr_range.lr_end, (short) iter->sa_value.sav_int);
|
|
|
|
has_bg = true;
|
|
|
|
has_bg = true;
|
|
|
@ -442,7 +454,7 @@ void view_curses::mvwattrline(WINDOW *window,
|
|
|
|
|
|
|
|
|
|
|
|
if (attrs || color_pair > 0) {
|
|
|
|
if (attrs || color_pair > 0) {
|
|
|
|
int x_pos = x + attr_range.lr_start;
|
|
|
|
int x_pos = x + attr_range.lr_start;
|
|
|
|
int ch_width = min(awidth, (line_width - attr_range.lr_start));
|
|
|
|
int ch_width = min(awidth, (line_width_chars - attr_range.lr_start));
|
|
|
|
cchar_t row_ch[ch_width + 1];
|
|
|
|
cchar_t row_ch[ch_width + 1];
|
|
|
|
|
|
|
|
|
|
|
|
mvwin_wchnstr(window, y, x_pos, row_ch, ch_width);
|
|
|
|
mvwin_wchnstr(window, y, x_pos, row_ch, ch_width);
|
|
|
@ -475,13 +487,13 @@ void view_curses::mvwattrline(WINDOW *window,
|
|
|
|
#if 1
|
|
|
|
#if 1
|
|
|
|
if (has_fg || has_bg) {
|
|
|
|
if (has_fg || has_bg) {
|
|
|
|
if (!has_fg) {
|
|
|
|
if (!has_fg) {
|
|
|
|
memset(fg_color, -1, line_width * sizeof(short));
|
|
|
|
memset(fg_color, -1, line_width_chars * sizeof(short));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!has_bg) {
|
|
|
|
if (!has_bg) {
|
|
|
|
memset(bg_color, -1, line_width * sizeof(short));
|
|
|
|
memset(bg_color, -1, line_width_chars * sizeof(short));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int ch_width = lr.length();
|
|
|
|
int ch_width = lr_chars.length();
|
|
|
|
cchar_t row_ch[ch_width + 1];
|
|
|
|
cchar_t row_ch[ch_width + 1];
|
|
|
|
|
|
|
|
|
|
|
|
mvwin_wchnstr(window, y, x, row_ch, ch_width);
|
|
|
|
mvwin_wchnstr(window, y, x, row_ch, ch_width);
|
|
|
|