mirror of
https://github.com/rkd77/elinks.git
synced 2024-12-04 14:46:47 -05:00
Added support for correctly displaying double-width UTF-8 chars in buttons.
With UTF-8 support in terminal enabled it is possible to use double-width UTF-8 strings as margins of buttons. Although they are displayed wrong when UTF-8 support in terminal is disabled.
This commit is contained in:
parent
38db20b776
commit
dfe029bc27
125
src/bfu/button.c
125
src/bfu/button.c
@ -77,17 +77,34 @@ add_dlg_button_do(struct dialog *dlg, unsigned char *text, int flags,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_UTF_8
|
||||||
|
static void
|
||||||
|
buttons_width(struct widget_data *widget_data, int n,
|
||||||
|
int *minwidth, int *maxwidth, int utf8)
|
||||||
|
#else
|
||||||
static void
|
static void
|
||||||
buttons_width(struct widget_data *widget_data, int n,
|
buttons_width(struct widget_data *widget_data, int n,
|
||||||
int *minwidth, int *maxwidth)
|
int *minwidth, int *maxwidth)
|
||||||
|
#endif /* CONFIG_UTF_8 */
|
||||||
{
|
{
|
||||||
int maxw = -BUTTON_HSPACING;
|
int maxw = -BUTTON_HSPACING;
|
||||||
|
#ifdef CONFIG_UTF_8
|
||||||
|
int button_lr_len = utf8_ptr2cells(BUTTON_LEFT, NULL)
|
||||||
|
+ utf8_ptr2cells(BUTTON_RIGHT, NULL);
|
||||||
|
#endif /* CONFIG_UTF_8 */
|
||||||
|
|
||||||
assert(n > 0);
|
assert(n > 0);
|
||||||
if_assert_failed return;
|
if_assert_failed return;
|
||||||
|
|
||||||
while (n--) {
|
while (n--) {
|
||||||
int minw = (widget_data++)->widget->info.button.textlen
|
int minw;
|
||||||
|
#ifdef CONFIG_UTF_8
|
||||||
|
if (utf8)
|
||||||
|
minw = utf8_ptr2cells((widget_data++)->widget->text, NULL)
|
||||||
|
+ BUTTON_HSPACING + button_lr_len;
|
||||||
|
else
|
||||||
|
#endif /* CONFIG_UTF_8 */
|
||||||
|
minw = (widget_data++)->widget->info.button.textlen
|
||||||
+ BUTTON_HSPACING + BUTTON_LR_LEN;
|
+ BUTTON_HSPACING + BUTTON_LR_LEN;
|
||||||
|
|
||||||
maxw += minw;
|
maxw += minw;
|
||||||
@ -111,20 +128,41 @@ dlg_format_buttons(struct terminal *term,
|
|||||||
|
|
||||||
while (i2 < n) {
|
while (i2 < n) {
|
||||||
mw = 0;
|
mw = 0;
|
||||||
|
#ifdef CONFIG_UTF_8
|
||||||
|
buttons_width(widget_data1, i2 - i1 + 1, NULL, &mw,
|
||||||
|
term->utf8);
|
||||||
|
#else
|
||||||
buttons_width(widget_data1, i2 - i1 + 1, NULL, &mw);
|
buttons_width(widget_data1, i2 - i1 + 1, NULL, &mw);
|
||||||
|
#endif /* CONFIG_UTF_8 */
|
||||||
if (mw <= w) i2++;
|
if (mw <= w) i2++;
|
||||||
else break;
|
else break;
|
||||||
}
|
}
|
||||||
|
|
||||||
mw = 0;
|
mw = 0;
|
||||||
|
#ifdef CONFIG_UTF_8
|
||||||
|
buttons_width(widget_data1, i2 - i1, NULL, &mw, term->utf8);
|
||||||
|
#else
|
||||||
buttons_width(widget_data1, i2 - i1, NULL, &mw);
|
buttons_width(widget_data1, i2 - i1, NULL, &mw);
|
||||||
|
#endif /* CONFIG_UTF_8 */
|
||||||
if (rw) int_bounds(rw, mw, w);
|
if (rw) int_bounds(rw, mw, w);
|
||||||
|
|
||||||
if (!format_only) {
|
if (!format_only) {
|
||||||
int i;
|
int i;
|
||||||
int p = x + (align == ALIGN_CENTER ? (w - mw) / 2 : 0);
|
int p = x + (align == ALIGN_CENTER ? (w - mw) / 2 : 0);
|
||||||
|
#ifdef CONFIG_UTF_8
|
||||||
|
int button_lr_len = utf8_ptr2cells(BUTTON_LEFT, NULL)
|
||||||
|
+ utf8_ptr2cells(BUTTON_RIGHT, NULL);
|
||||||
|
#endif /* CONFIG_UTF_8 */
|
||||||
|
|
||||||
for (i = i1; i < i2; i++) {
|
for (i = i1; i < i2; i++) {
|
||||||
|
#ifdef CONFIG_UTF_8
|
||||||
|
if (term->utf8)
|
||||||
|
set_box(&widget_data[i].box,
|
||||||
|
p, *y,
|
||||||
|
utf8_ptr2cells(widget_data[i].widget->text, NULL)
|
||||||
|
+ button_lr_len, BUTTON_HEIGHT);
|
||||||
|
else
|
||||||
|
#endif /* CONFIG_UTF_8 */
|
||||||
set_box(&widget_data[i].box,
|
set_box(&widget_data[i].box,
|
||||||
p, *y,
|
p, *y,
|
||||||
widget_data[i].widget->info.button.textlen
|
widget_data[i].widget->info.button.textlen
|
||||||
@ -145,8 +183,7 @@ display_button(struct dialog_data *dlg_data, struct widget_data *widget_data)
|
|||||||
struct terminal *term = dlg_data->win->term;
|
struct terminal *term = dlg_data->win->term;
|
||||||
struct color_pair *color, *shortcut_color;
|
struct color_pair *color, *shortcut_color;
|
||||||
struct box *pos = &widget_data->box;
|
struct box *pos = &widget_data->box;
|
||||||
int len = widget_data->box.width - BUTTON_LR_LEN;
|
int len, x;
|
||||||
int x = pos->x + BUTTON_LEFT_LEN;
|
|
||||||
int sel = is_selected_widget(dlg_data, widget_data);
|
int sel = is_selected_widget(dlg_data, widget_data);
|
||||||
|
|
||||||
if (sel) {
|
if (sel) {
|
||||||
@ -158,6 +195,23 @@ display_button(struct dialog_data *dlg_data, struct widget_data *widget_data)
|
|||||||
}
|
}
|
||||||
if (!color || !shortcut_color) return EVENT_PROCESSED;
|
if (!color || !shortcut_color) return EVENT_PROCESSED;
|
||||||
|
|
||||||
|
#ifdef CONFIG_UTF_8
|
||||||
|
if (term->utf8) {
|
||||||
|
int button_left_len = utf8_ptr2cells(BUTTON_LEFT, NULL);
|
||||||
|
int button_right_len = utf8_ptr2cells(BUTTON_RIGHT, NULL);
|
||||||
|
|
||||||
|
x = pos->x + button_left_len;
|
||||||
|
len = widget_data->box.width -
|
||||||
|
(button_left_len + button_right_len);
|
||||||
|
|
||||||
|
} else
|
||||||
|
#endif /* CONFIG_UTF_8 */
|
||||||
|
{
|
||||||
|
x = pos->x + BUTTON_LEFT_LEN;
|
||||||
|
len = widget_data->box.width - BUTTON_LR_LEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
draw_text(term, pos->x, pos->y, BUTTON_LEFT, BUTTON_LEFT_LEN, 0, color);
|
draw_text(term, pos->x, pos->y, BUTTON_LEFT, BUTTON_LEFT_LEN, 0, color);
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
unsigned char *text = widget_data->widget->text;
|
unsigned char *text = widget_data->widget->text;
|
||||||
@ -169,30 +223,48 @@ display_button(struct dialog_data *dlg_data, struct widget_data *widget_data)
|
|||||||
|
|
||||||
#ifdef CONFIG_UTF_8
|
#ifdef CONFIG_UTF_8
|
||||||
if (term->utf8) {
|
if (term->utf8) {
|
||||||
unsigned char *text2 = text;
|
if (hk_pos >= 0) {
|
||||||
unsigned char *end = text
|
int hk_bytes = utf8charlen(&text[hk_pos+1]);
|
||||||
+ widget_data->widget->info.button.truetextlen;
|
int cells_to_hk = utf8_ptr2cells(text,
|
||||||
int hk_state = 0;
|
&text[hk_pos]);
|
||||||
int x1;
|
int right = widget_data->widget->info.button.truetextlen
|
||||||
|
- hk_pos
|
||||||
|
- hk_bytes;
|
||||||
|
|
||||||
for (x1 = 0; x1 - !!hk_state < len && *text2; x1++) {
|
int hk_cells = utf8_char2cells(&text[hk_pos
|
||||||
uint16_t data;
|
+ 1],
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (hk_pos)
|
||||||
|
draw_text(term, x, pos->y,
|
||||||
|
text, hk_pos, 0, color);
|
||||||
|
|
||||||
|
draw_text(term, x + cells_to_hk, pos->y,
|
||||||
|
&text[hk_pos + 1], hk_bytes,
|
||||||
|
attr, shortcut_color);
|
||||||
|
|
||||||
|
if (right > 1)
|
||||||
|
draw_text(term, x+cells_to_hk+hk_cells,
|
||||||
|
pos->y,
|
||||||
|
&text[hk_pos + hk_bytes + 1],
|
||||||
|
right - 1, 0, color);
|
||||||
|
|
||||||
data = (uint16_t)utf_8_to_unicode(&text2, end);
|
|
||||||
if (!hk_state && (int)(text2 - text) == hk_pos + 1) {
|
|
||||||
hk_state = 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (hk_state == 1) {
|
|
||||||
draw_char(term, x + x1 - 1, pos->y, data, attr, shortcut_color);
|
|
||||||
hk_state = 2;
|
|
||||||
} else {
|
} else {
|
||||||
draw_char(term, x + x1 - !!hk_state, pos->y, data, 0, color);
|
int hk_width = utf8_char2cells(text, NULL);
|
||||||
}
|
int hk_len = utf8charlen(text);
|
||||||
|
int len_to_display =
|
||||||
|
utf8_cells2bytes(&text[hk_len],
|
||||||
|
len - hk_width,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
draw_text(term, x, pos->y,
|
||||||
|
text, hk_len,
|
||||||
|
attr, shortcut_color);
|
||||||
|
|
||||||
|
draw_text(term, x + hk_width, pos->y,
|
||||||
|
&text[hk_len], len_to_display,
|
||||||
|
0, color);
|
||||||
}
|
}
|
||||||
len = x1 - !!hk_state;
|
|
||||||
} else
|
} else
|
||||||
#endif /* CONFIG_UTF_8 */
|
#endif /* CONFIG_UTF_8 */
|
||||||
if (hk_pos >= 0) {
|
if (hk_pos >= 0) {
|
||||||
@ -213,8 +285,17 @@ display_button(struct dialog_data *dlg_data, struct widget_data *widget_data)
|
|||||||
draw_text(term, x + 1, pos->y, &text[1], len - 1, 0, color);
|
draw_text(term, x + 1, pos->y, &text[1], len - 1, 0, color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
draw_text(term, x + len, pos->y, BUTTON_RIGHT, BUTTON_RIGHT_LEN, 0, color);
|
#ifdef CONFIG_UTF_8
|
||||||
|
if (term->utf8) {
|
||||||
|
int text_cells = utf8_ptr2cells(widget_data->widget->text, NULL);
|
||||||
|
int hk = (widget_data->widget->info.button.hotkey_pos >= 0);
|
||||||
|
|
||||||
|
draw_text(term, x + text_cells - hk, pos->y,
|
||||||
|
BUTTON_RIGHT, BUTTON_RIGHT_LEN, 0, color);
|
||||||
|
} else
|
||||||
|
#endif /* CONFIG_UTF_8 */
|
||||||
|
draw_text(term, x + len, pos->y, BUTTON_RIGHT,
|
||||||
|
BUTTON_RIGHT_LEN, 0, color);
|
||||||
if (sel) {
|
if (sel) {
|
||||||
set_cursor(term, x, pos->y, 1);
|
set_cursor(term, x, pos->y, 1);
|
||||||
set_window_ptr(dlg_data->win, pos->x, pos->y);
|
set_window_ptr(dlg_data->win, pos->x, pos->y);
|
||||||
|
Loading…
Reference in New Issue
Block a user