1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-06-12 23:10:51 +00:00

Merge with utf8. src/document/plain/renderer.c replaced by utf8 version

This commit is contained in:
Witold Filipczyk 2006-07-21 13:12:06 +02:00 committed by Witold Filipczyk
commit 2a6125e3d0
48 changed files with 3021 additions and 500 deletions

View File

@ -156,6 +156,7 @@ CONFIG_SPIDERMONKEY = @CONFIG_SPIDERMONKEY@
CONFIG_SSL = @CONFIG_SSL@
CONFIG_SYSMOUSE = @CONFIG_SYSMOUSE@
CONFIG_URI_REWRITE = @CONFIG_URI_REWRITE@
CONFIG_UTF_8 = @CONFIG_UTF_8@
CONFIG_XBEL_BOOKMARKS = @CONFIG_XBEL_BOOKMARKS@
CONFIG_XMLTO = @CONFIG_XMLTO@
CONFIG_GSSAPI = @CONFIG_GSSAPI@

View File

@ -168,6 +168,7 @@ AC_HEADER_STDC
AC_HEADER_SYS_WAIT
AC_HEADER_TIME
AC_CHECK_HEADERS(wctype.h)
AC_CHECK_HEADERS(fcntl.h limits.h time.h unistd.h)
AC_CHECK_HEADERS(sigaction.h)
AC_CHECK_HEADERS(arpa/inet.h)
@ -1283,6 +1284,10 @@ EL_ARG_ENABLE(CONFIG_OWN_LIBC, own-libc, [Own libc stubs],
EL_ARG_ENABLE(CONFIG_SMALL, small, [Small binary],
[ --enable-small reduce binary size as far as possible (but see the bottom of doc/small.txt!)])
EL_ARG_ENABLE(CONFIG_UTF_8, utf-8, [UTF-8],
[ --enable-utf-8 enable UTF-8 support])
AC_ARG_ENABLE(weehoofooboomookerchoo,
[
Also check out the features.conf file for more information about features!

View File

@ -77,18 +77,35 @@ 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
buttons_width(struct widget_data *widget_data, int n,
int *minwidth, int *maxwidth)
#endif /* CONFIG_UTF_8 */
{
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);
if_assert_failed return;
while (n--) {
int minw = (widget_data++)->widget->info.button.textlen
+ BUTTON_HSPACING + BUTTON_LR_LEN;
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;
maxw += minw;
if (minwidth) int_lower_bound(minwidth, minw);
@ -100,7 +117,7 @@ buttons_width(struct widget_data *widget_data, int n,
void
dlg_format_buttons(struct terminal *term,
struct widget_data *widget_data, int n,
int x, int *y, int w, int *rw, enum format_align align)
int x, int *y, int w, int *rw, enum format_align align, int format_only)
{
int i1 = 0;
@ -111,24 +128,45 @@ dlg_format_buttons(struct terminal *term,
while (i2 < n) {
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);
#endif /* CONFIG_UTF_8 */
if (mw <= w) i2++;
else break;
}
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);
#endif /* CONFIG_UTF_8 */
if (rw) int_bounds(rw, mw, w);
if (term) {
if (!format_only) {
int i;
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++) {
set_box(&widget_data[i].box,
p, *y,
widget_data[i].widget->info.button.textlen
+ BUTTON_LR_LEN, BUTTON_HEIGHT);
#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,
p, *y,
widget_data[i].widget->info.button.textlen
+ BUTTON_LR_LEN, BUTTON_HEIGHT);
p += widget_data[i].box.width + BUTTON_HSPACING;
}
@ -145,8 +183,7 @@ display_button(struct dialog_data *dlg_data, struct widget_data *widget_data)
struct terminal *term = dlg_data->win->term;
struct color_pair *color, *shortcut_color;
struct box *pos = &widget_data->box;
int len = widget_data->box.width - BUTTON_LR_LEN;
int x = pos->x + BUTTON_LEFT_LEN;
int len, x;
int sel = is_selected_widget(dlg_data, widget_data);
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;
#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);
if (len > 0) {
unsigned char *text = widget_data->widget->text;
@ -167,6 +221,52 @@ display_button(struct dialog_data *dlg_data, struct widget_data *widget_data)
attr = get_opt_bool("ui.dialogs.underline_button_shortcuts")
? SCREEN_ATTR_UNDERLINE : 0;
#ifdef CONFIG_UTF_8
if (term->utf8) {
if (hk_pos >= 0) {
int hk_bytes = utf8charlen(&text[hk_pos+1]);
int cells_to_hk = utf8_ptr2cells(text,
&text[hk_pos]);
int right = widget_data->widget->info.button.truetextlen
- hk_pos
- hk_bytes;
int hk_cells = utf8_char2cells(&text[hk_pos
+ 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);
} else {
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);
}
} else
#endif /* CONFIG_UTF_8 */
if (hk_pos >= 0) {
int right = widget_data->widget->info.button.truetextlen - hk_pos - 1;
@ -185,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 + 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) {
set_cursor(term, x, pos->y, 1);
set_window_ptr(dlg_data->win, pos->x, pos->y);

View File

@ -48,6 +48,6 @@ void add_dlg_button_do(struct dialog *dlg, unsigned char *text, int flags, widge
#endif
extern struct widget_ops button_ops;
void dlg_format_buttons(struct terminal *, struct widget_data *, int, int, int *, int, int *, enum format_align);
void dlg_format_buttons(struct terminal *, struct widget_data *, int, int, int *, int, int *, enum format_align, int);
#endif

View File

@ -39,7 +39,7 @@ void
dlg_format_checkbox(struct terminal *term,
struct widget_data *widget_data,
int x, int *y, int w, int *rw,
enum format_align align)
enum format_align align, int format_only)
{
unsigned char *text = widget_data->widget->text;
@ -52,7 +52,7 @@ dlg_format_checkbox(struct terminal *term,
dlg_format_text_do(term, text, x + CHECKBOX_LS, y,
w - CHECKBOX_LS, rw,
get_bfu_color(term, "dialog.checkbox-label"),
align);
align, format_only);
if (rw) *rw += CHECKBOX_LS;
}
}

View File

@ -33,7 +33,7 @@ void
dlg_format_checkbox(struct terminal *term,
struct widget_data *widget_data,
int x, int *y, int w, int *rw,
enum format_align align);
enum format_align align, int format_only);
#define widget_has_group(widget_data) ((widget_data)->widget->type == WIDGET_CHECKBOX \
? (widget_data)->widget->info.checkbox.gid : -1)

View File

@ -12,6 +12,7 @@
#include "bfu/dialog.h"
#include "config/kbdbind.h"
#include "config/options.h"
#include "intl/charsets.h"
#include "intl/gettext/libintl.h"
#include "terminal/draw.h"
#include "main/timer.h"
@ -96,13 +97,33 @@ redraw_dialog(struct dialog_data *dlg_data, int layout)
title_color = get_bfu_color(term, "dialog.title");
if (title_color && box.width > 2) {
unsigned char *title = dlg_data->dlg->title;
int titlelen = int_min(box.width - 2, strlen(title));
int x = (box.width - titlelen) / 2 + box.x;
int y = box.y - 1;
int titlelen = strlen(title);
int titlecells = titlelen;
int x, y;
#ifdef CONFIG_UTF_8
if (term->utf8)
titlecells = utf8_ptr2cells(title,
&title[titlelen]);
#endif /* CONFIG_UTF_8 */
titlecells = int_min(box.width - 2, titlecells);
#ifdef CONFIG_UTF_8
if (term->utf8) {
titlelen = utf8_cells2bytes(title,
titlecells,
NULL);
}
#endif /* CONFIG_UTF_8 */
x = (box.width - titlecells) / 2 + box.x;
y = box.y - 1;
draw_text(term, x - 1, y, " ", 1, 0, title_color);
draw_text(term, x, y, title, titlelen, 0, title_color);
draw_text(term, x + titlelen, y, " ", 1, 0, title_color);
draw_text(term, x + titlecells, y, " ", 1, 0,
title_color);
}
}
@ -499,7 +520,7 @@ clear_dialog(struct dialog_data *dlg_data, struct widget_data *xxx)
static void
format_widgets(struct terminal *term, struct dialog_data *dlg_data,
int x, int *y, int w, int h, int *rw)
int x, int *y, int w, int h, int *rw, int format_only)
{
struct widget_data *wdata = dlg_data->widgets_data;
int widgets = dlg_data->number_of_widgets;
@ -509,15 +530,18 @@ format_widgets(struct terminal *term, struct dialog_data *dlg_data,
switch (wdata->widget->type) {
case WIDGET_FIELD_PASS:
case WIDGET_FIELD:
dlg_format_field(term, wdata, x, y, w, rw, ALIGN_LEFT);
dlg_format_field(term, wdata, x, y, w, rw, ALIGN_LEFT,
format_only);
break;
case WIDGET_LISTBOX:
dlg_format_listbox(term, wdata, x, y, w, h, rw, ALIGN_LEFT);
dlg_format_listbox(term, wdata, x, y, w, h, rw,
ALIGN_LEFT, format_only);
break;
case WIDGET_TEXT:
dlg_format_text(term, wdata, x, y, w, rw, h);
dlg_format_text(term, wdata, x, y, w, rw, h,
format_only);
break;
case WIDGET_CHECKBOX:
@ -535,14 +559,16 @@ format_widgets(struct terminal *term, struct dialog_data *dlg_data,
break;
}
dlg_format_group(term, wdata, size, x, y, w, rw);
dlg_format_group(term, wdata, size, x, y, w, rw,
format_only);
wdata += size - 1;
} else {
/* No horizontal space between checkboxes belonging to
* the same group. */
dlg_format_checkbox(term, wdata, x, y, w, rw, ALIGN_LEFT);
dlg_format_checkbox(term, wdata, x, y, w, rw,
ALIGN_LEFT, format_only);
if (widgets > 1
&& group == widget_has_group(&wdata[1]))
(*y)--;
@ -554,7 +580,7 @@ format_widgets(struct terminal *term, struct dialog_data *dlg_data,
* of the dialog. */
case WIDGET_BUTTON:
dlg_format_buttons(term, wdata, widgets,
x, y, w, rw, ALIGN_CENTER);
x, y, w, rw, ALIGN_CENTER, format_only);
return;
}
}
@ -566,11 +592,17 @@ generic_dialog_layouter(struct dialog_data *dlg_data)
struct terminal *term = dlg_data->win->term;
int w = dialog_max_width(term);
int height = dialog_max_height(term);
int rw = int_min(w, strlen(dlg_data->dlg->title));
int rw;
#ifdef CONFIG_UTF_8
if (term->utf8)
rw = int_min(w, utf8_ptr2cells(dlg_data->dlg->title, NULL));
else
#endif /* CONFIG_UTF_8 */
rw = int_min(w, strlen(dlg_data->dlg->title));
int y = dlg_data->dlg->layout.padding_top ? 0 : -1;
int x = 0;
format_widgets(NULL, dlg_data, x, &y, w, height, &rw);
format_widgets(term, dlg_data, x, &y, w, height, &rw, 1);
/* Update the width to respond to the required minimum width */
if (dlg_data->dlg->layout.fit_datalen) {
@ -585,7 +617,7 @@ generic_dialog_layouter(struct dialog_data *dlg_data)
y = dlg_data->box.y + DIALOG_TB + dlg_data->dlg->layout.padding_top;
x = dlg_data->box.x + DIALOG_LB;
format_widgets(term, dlg_data, x, &y, w, height, NULL);
format_widgets(term, dlg_data, x, &y, w, height, NULL, 0);
}
@ -607,7 +639,15 @@ draw_dialog(struct dialog_data *dlg_data, int width, int height)
/* Draw shadow */
draw_shadow(term, &dlg_data->box,
get_bfu_color(term, "dialog.shadow"), 2, 1);
#ifdef CONFIG_UTF_8
if (term->utf8)
fix_dwchar_around_box(term, &dlg_data->box, 0, 2, 1);
#endif /* CONFIG_UTF_8 */
}
#ifdef CONFIG_UTF_8
else if(term->utf8)
fix_dwchar_around_box(term, &dlg_data->box, 0, 0, 0);
#endif /* CONFIG_UTF_8 */
}
static void

View File

@ -16,10 +16,13 @@
#include "terminal/terminal.h"
#include "util/color.h"
/* Same as in src/bfu/checkbox.c */
#define CHECKBOX_LEN 3 /* "[X]" or "(X)" */
void
dlg_format_group(struct terminal *term,
struct widget_data *widget_data,
int n, int x, int *y, int w, int *rw)
int n, int x, int *y, int w, int *rw, int format_only)
{
int space_between_widgets = 1;
int line_width = 0;
@ -33,13 +36,31 @@ dlg_format_group(struct terminal *term,
int widget_width;
int width;
unsigned char *text = widget_data->widget->text;
int label_length = (text && *text) ? strlen(text) : 0;
int label_padding = (label_length > 0);
int label_length;
int label_padding;
#ifdef CONFIG_UTF_8
if (term->utf8) {
if (text && *text)
label_length = utf8_ptr2cells(text, NULL);
else
label_length = 0;
} else
#endif /* CONFIG_UTF_8 */
label_length = (text && *text) ? strlen(text) : 0;
label_padding = (label_length > 0);
if (widget_data->widget->type == WIDGET_CHECKBOX) {
width = 3;
width = CHECKBOX_LEN;
} else if (widget_is_textfield(widget_data)) {
width = widget_data->widget->datalen;
#ifdef CONFIG_UTF_8
if (term->utf8) {
width = utf8_ptr2cells(widget_data->widget->data,
NULL);
} else
#endif /* CONFIG_UTF_8 */
width = widget_data->widget->datalen;
} else {
/* TODO: handle all widget types. */
widget_data++;
@ -56,22 +77,52 @@ dlg_format_group(struct terminal *term,
xpos = x + line_width;
if (term) {
if (!format_only) {
if (widget_data->widget->type == WIDGET_CHECKBOX) {
/* Draw text at right of checkbox. */
if (label_length)
draw_text(term, xpos + width + label_padding, *y,
text, label_length,
0, color);
if (label_length) {
#ifdef CONFIG_UTF_8
if (term->utf8) {
int lb = utf8_cells2bytes(
text,
label_length,
NULL);
draw_text(term, xpos + width
+ label_padding,
*y, text, lb, 0,
color);
} else
#endif /* CONFIG_UTF_8 */
{
draw_text(term, xpos + width
+ label_padding,
*y, text,
label_length, 0,
color);
}
}
set_box(&widget_data->box, xpos, *y, width, 1);
} else if (widget_is_textfield(widget_data)) {
/* Draw label at left of widget. */
if (label_length)
draw_text(term, xpos, *y,
text, label_length,
0, color);
if (label_length) {
#ifdef CONFIG_UTF_8
if (term->utf8) {
int lb = utf8_cells2bytes(
text,
label_length,
NULL);
draw_text(term, xpos, *y,
text, lb, 0, color);
} else
#endif /* CONFIG_UTF_8 */
{
draw_text(term, xpos, *y,
text, label_length,
0, color);
}
}
set_box(&widget_data->box,
xpos + label_padding + label_length, *y,
@ -93,16 +144,23 @@ group_layouter(struct dialog_data *dlg_data)
{
struct terminal *term = dlg_data->win->term;
int w = dialog_max_width(term);
int rw = int_min(w, strlen(dlg_data->dlg->title));
int rw;
int y = 0;
int n = dlg_data->number_of_widgets - 2;
dlg_format_group(NULL, dlg_data->widgets_data, n,
0, &y, w, &rw);
#ifdef CONFIG_UTF_8
if (term->utf8)
rw = int_min(w, utf8_ptr2cells(dlg_data->dlg->title, NULL));
else
#endif /* CONFIG_UTF_8 */
rw = int_min(w, strlen(dlg_data->dlg->title));
dlg_format_group(term, dlg_data->widgets_data, n,
0, &y, w, &rw, 1);
y++;
dlg_format_buttons(NULL, dlg_data->widgets_data + n, 2, 0, &y, w,
&rw, ALIGN_CENTER);
dlg_format_buttons(term, dlg_data->widgets_data + n, 2, 0, &y, w,
&rw, ALIGN_CENTER, 1);
w = rw;
@ -110,9 +168,9 @@ group_layouter(struct dialog_data *dlg_data)
y = dlg_data->box.y + DIALOG_TB + 1;
dlg_format_group(term, dlg_data->widgets_data, n,
dlg_data->box.x + DIALOG_LB, &y, w, NULL);
dlg_data->box.x + DIALOG_LB, &y, w, NULL, 0);
y++;
dlg_format_buttons(term, dlg_data->widgets_data + n, 2,
dlg_data->box.x + DIALOG_LB, &y, w, &rw, ALIGN_CENTER);
dlg_data->box.x + DIALOG_LB, &y, w, &rw, ALIGN_CENTER, 0);
}

View File

@ -7,7 +7,7 @@ struct widget_data;
void dlg_format_group(struct terminal *term,
struct widget_data *widget_data,
int n, int x, int *y, int w, int *rw);
int n, int x, int *y, int w, int *rw, int format_only);
void group_layouter(struct dialog_data *);

View File

@ -17,6 +17,7 @@
#include "bfu/msgbox.h"
#include "bfu/text.h"
#include "config/kbdbind.h"
#include "intl/charsets.h"
#include "intl/gettext/libintl.h"
#include "osdep/osdep.h"
#include "session/session.h"
@ -104,7 +105,7 @@ check_nonempty(struct dialog_data *dlg_data, struct widget_data *widget_data)
void
dlg_format_field(struct terminal *term,
struct widget_data *widget_data,
int x, int *y, int w, int *rw, enum format_align align)
int x, int *y, int w, int *rw, enum format_align align, int format_only)
{
static int max_label_width;
static int *prev_y; /* Assert the uniqueness of y */ /* TODO: get rid of this !! --Zas */
@ -129,9 +130,9 @@ dlg_format_field(struct terminal *term,
}
if (label && *label) {
if (term) text_color = get_bfu_color(term, "dialog.text");
if (!format_only) text_color = get_bfu_color(term, "dialog.text");
dlg_format_text_do(term, label, x, y, w, rw, text_color, ALIGN_LEFT);
dlg_format_text_do(term, label, x, y, w, rw, text_color, ALIGN_LEFT, format_only);
}
/* XXX: We want the field and label on the same line if the terminal
@ -141,7 +142,7 @@ dlg_format_field(struct terminal *term,
(*y) -= INPUTFIELD_HEIGHT;
dlg_format_text_do(term, INPUTFIELD_FLOAT_SEPARATOR,
x + label_width, y, w, rw,
text_color, ALIGN_LEFT);
text_color, ALIGN_LEFT, format_only);
w -= INPUTFIELD_FLOAT_SEPARATOR_LEN + INPUTFIELD_FLOATLABEL_PADDING;
x += INPUTFIELD_FLOAT_SEPARATOR_LEN + INPUTFIELD_FLOATLABEL_PADDING;
}
@ -265,11 +266,27 @@ display_field_do(struct dialog_data *dlg_data, struct widget_data *widget_data,
struct terminal *term = dlg_data->win->term;
struct color_pair *color;
int sel = is_selected_widget(dlg_data, widget_data);
#ifdef CONFIG_UTF_8
int len = 0, left = 0;
#endif /* CONFIG_UTF_8 */
int_bounds(&widget_data->info.field.vpos,
#ifdef CONFIG_UTF_8
if (term->utf8) {
unsigned char *t = widget_data->cdata;
int p = widget_data->info.field.cpos;
len = utf8_ptr2cells(t, &t[p]);
int_bounds(&left, len - widget_data->box.width + 1, len);
int_lower_bound(&left, 0);
widget_data->info.field.vpos = utf8_cells2bytes(t, left, NULL);
} else
#endif /* CONFIG_UTF_8 */
{
int_bounds(&widget_data->info.field.vpos,
widget_data->info.field.cpos - widget_data->box.width + 1,
widget_data->info.field.cpos);
int_lower_bound(&widget_data->info.field.vpos, 0);
int_lower_bound(&widget_data->info.field.vpos, 0);
}
color = get_bfu_color(term, "dialog.field");
if (color)
@ -277,13 +294,26 @@ display_field_do(struct dialog_data *dlg_data, struct widget_data *widget_data,
color = get_bfu_color(term, "dialog.field-text");
if (color) {
int len = strlen(widget_data->cdata + widget_data->info.field.vpos);
int w = int_min(len, widget_data->box.width);
unsigned char *text = widget_data->cdata + widget_data->info.field.vpos;
int len, w;
#ifdef CONFIG_UTF_8
if (term->utf8 && !hide)
len = utf8_ptr2cells(text, NULL);
else if (term->utf8)
len = utf8_ptr2chars(text, NULL);
else
#endif /* CONFIG_UTF_8 */
len = strlen(text);
w = int_min(len, widget_data->box.width);
if (!hide) {
#ifdef CONFIG_UTF_8
if (term->utf8)
w = utf8_cells2bytes(text, w, NULL);
#endif /* CONFIG_UTF_8 */
draw_text(term, widget_data->box.x, widget_data->box.y,
widget_data->cdata + widget_data->info.field.vpos, w,
0, color);
text, w, 0, color);
} else {
struct box box;
@ -295,7 +325,14 @@ display_field_do(struct dialog_data *dlg_data, struct widget_data *widget_data,
}
if (sel) {
int x = widget_data->box.x + widget_data->info.field.cpos - widget_data->info.field.vpos;
int x;
#ifdef CONFIG_UTF_8
if (term->utf8)
x = widget_data->box.x + len - left;
else
#endif /* CONFIG_UTF_8 */
x = widget_data->box.x + widget_data->info.field.cpos - widget_data->info.field.vpos;
set_cursor(term, x, widget_data->box.y, 0);
set_window_ptr(dlg_data->win, widget_data->box.x, widget_data->box.y);
@ -435,13 +472,39 @@ kbd_field(struct dialog_data *dlg_data, struct widget_data *widget_data)
break;
case ACT_EDIT_RIGHT:
if (widget_data->info.field.cpos < strlen(widget_data->cdata))
widget_data->info.field.cpos++;
if (widget_data->info.field.cpos < strlen(widget_data->cdata)) {
#ifdef CONFIG_UTF_8
if (term->utf8) {
unsigned char *next = widget_data->cdata + widget_data->info.field.cpos;
unsigned char *end = strchr(next, '\0');
utf_8_to_unicode(&next, end);
widget_data->info.field.cpos = (int)(next - widget_data->cdata);
} else
#endif /* CONFIG_UTF_8 */
{
widget_data->info.field.cpos++;
}
}
goto display_field;
case ACT_EDIT_LEFT:
if (widget_data->info.field.cpos > 0)
widget_data->info.field.cpos--;
#ifdef CONFIG_UTF_8
if (widget_data->info.field.cpos && term->utf8) {
unsigned char *t = widget_data->cdata;
unsigned char *t2 = t;
int p = widget_data->info.field.cpos;
unsigned char tmp = t[p];
t[p] = '\0';
strlen_utf8(&t2);
t[p] = tmp;
widget_data->info.field.cpos = (int)(t2 - t);
}
#endif /* CONFIG_UTF_8 */
goto display_field;
case ACT_EDIT_HOME:
@ -453,6 +516,34 @@ kbd_field(struct dialog_data *dlg_data, struct widget_data *widget_data)
goto display_field;
case ACT_EDIT_BACKSPACE:
#ifdef CONFIG_UTF_8
if (widget_data->info.field.cpos && term->utf8) {
/* XXX: stolen from src/viewer/text/form.c */
/* FIXME: This isn't nice. We remove last byte
* from UTF-8 character to detect
* character before it. */
unsigned char *text = widget_data->cdata;
unsigned char *end = widget_data->cdata + widget_data->info.field.cpos - 1;
unicode_val_T data;
int old = widget_data->info.field.cpos;
while(1) {
data = utf_8_to_unicode(&text, end);
if (data == UCS_NO_CHAR)
break;
}
widget_data->info.field.cpos = (int)(text - widget_data->cdata);
if (old != widget_data->info.field.cpos) {
int length;
text = widget_data->cdata;
length = strlen(text + old) + 1;
memmove(text + widget_data->info.field.cpos, text + old, length);
}
goto display_field;
}
#endif /* CONFIG_UTF_8 */
if (widget_data->info.field.cpos) {
memmove(widget_data->cdata + widget_data->info.field.cpos - 1,
widget_data->cdata + widget_data->info.field.cpos,
@ -467,6 +558,20 @@ kbd_field(struct dialog_data *dlg_data, struct widget_data *widget_data)
if (widget_data->info.field.cpos >= cdata_len) goto display_field;
#ifdef CONFIG_UTF_8
if (term->utf8) {
unsigned char *end = widget_data->cdata + cdata_len;
unsigned char *text = widget_data->cdata + widget_data->info.field.cpos;
unsigned char *old = text;
utf_8_to_unicode(&text, end);
if (old != text) {
memmove(old, text,
(int)(end - text) + 1);
}
goto display_field;
}
#endif /* CONFIG_UTF_8 */
memmove(widget_data->cdata + widget_data->info.field.cpos,
widget_data->cdata + widget_data->info.field.cpos + 1,
cdata_len - widget_data->info.field.cpos + 1);
@ -585,7 +690,22 @@ kbd_field(struct dialog_data *dlg_data, struct widget_data *widget_data)
memmove(text + 1, text, textlen + 1);
*text = get_kbd_key(ev);
#ifdef CONFIG_UTF_8
if (term->utf8) {
static unsigned char buf[7];
unsigned char *t = buf;
static int i = 0;
unicode_val_T data;
buf[i++] = *text;
buf[i] = '\0';
data = utf_8_to_unicode(&t, buf + i);
if (i == 6) i = 0;
if (data == UCS_NO_CHAR)
return EVENT_PROCESSED;
else i = 0;
}
#endif /* CONFIG_UTF_8 */
goto display_field;
}
}
@ -641,7 +761,7 @@ input_line_layouter(struct dialog_data *dlg_data)
- ses->status.show_tabs_bar;
dlg_format_field(win->term, dlg_data->widgets_data, 0,
&y, win->term->width, NULL, ALIGN_LEFT);
&y, win->term->width, NULL, ALIGN_LEFT, 0);
}
static widget_handler_status_T

View File

@ -62,7 +62,7 @@ extern struct widget_ops field_pass_ops;
widget_handler_status_T check_number(struct dialog_data *, struct widget_data *);
widget_handler_status_T check_nonempty(struct dialog_data *, struct widget_data *);
void dlg_format_field(struct terminal *, struct widget_data *, int, int *, int, int *, enum format_align);
void dlg_format_field(struct terminal *, struct widget_data *, int, int *, int, int *, enum format_align, int format_only);
void input_field(struct terminal *, struct memory_list *, int, unsigned char *,
unsigned char *, unsigned char *, unsigned char *, void *,

View File

@ -43,7 +43,7 @@ get_listbox_widget_data(struct widget_data *widget_data)
void
dlg_format_listbox(struct terminal *term, struct widget_data *widget_data,
int x, int *y, int w, int max_height, int *rw,
enum format_align align)
enum format_align align, int format_only)
{
int min, optimal_h, height;
@ -453,6 +453,7 @@ display_listbox_item(struct listbox_item *item, void *data_, int *offset)
} else {
unsigned char *text;
struct listbox_ops *ops = data->box->ops;
int len_bytes;
assert(ops && ops->get_info);
@ -461,8 +462,14 @@ display_listbox_item(struct listbox_item *item, void *data_, int *offset)
len = strlen(text);
int_upper_bound(&len, int_max(0, data->widget_data->box.width - depth * 5));
#ifdef CONFIG_UTF_8
if (data->term->utf8)
len_bytes = utf8_cells2bytes(text, len, NULL);
else
#endif /* CONFIG_UTF_8 */
len_bytes = len;
draw_text(data->term, x, y, text, len, 0, text_color);
draw_text(data->term, x, y, text, len_bytes, 0, text_color);
mem_free(text);
}

View File

@ -133,7 +133,7 @@ struct listbox_item {
extern struct widget_ops listbox_ops;
void dlg_format_listbox(struct terminal *, struct widget_data *, int, int *, int, int, int *, enum format_align);
void dlg_format_listbox(struct terminal *, struct widget_data *, int, int *, int, int, int *, enum format_align, int format_only);
struct listbox_item *traverse_listbox_items_list(struct listbox_item *, struct listbox_data *, int, int, int (*)(struct listbox_item *, void *, int *), void *);

View File

@ -200,7 +200,14 @@ get_menuitem_text_width(struct terminal *term, struct menu_item *mi)
if (!text[0]) return 0;
return L_TEXT_SPACE + strlen(text) - !!mi->hotkey_pos + R_TEXT_SPACE;
#ifdef CONFIG_UTF_8
if (term->utf8)
return L_TEXT_SPACE + utf8_ptr2cells(text, NULL)
- !!mi->hotkey_pos + R_TEXT_SPACE;
else
#endif /* CONFIG_UTF_8 */
return L_TEXT_SPACE + strlen(text)
- !!mi->hotkey_pos + R_TEXT_SPACE;
}
/* Get desired width for right text in menu item, accounting spacing. */
@ -360,17 +367,31 @@ set_menu_selection(struct menu *menu, int pos)
int_bounds(&menu->first, 0, menu->size - height);
}
/* width - number of standard terminal cells to be displayed (text + whitespace
* separators). For double-width glyph width == 2.
* len - length of text in bytes */
static inline void
draw_menu_left_text(struct terminal *term, unsigned char *text, int len,
int x, int y, int width, struct color_pair *color)
{
int w = width - (L_TEXT_SPACE + R_TEXT_SPACE);
int max_len;
if (w <= 0) return;
if (len < 0) len = strlen(text);
if (!len) return;
if (len > w) len = w;
#ifdef CONFIG_UTF_8
if (term->utf8) {
max_len = utf8_cells2bytes(text, w, NULL);
if (max_len <= 0)
return;
} else
#endif /* CONFIG_UTF_8 */
max_len = w;
if (len > max_len) len = max_len;
draw_text(term, x + L_TEXT_SPACE, y, text, len, 0, color);
}
@ -389,6 +410,7 @@ draw_menu_left_text_hk(struct terminal *term, unsigned char *text,
int xbase = x + L_TEXT_SPACE;
int w = width - (L_TEXT_SPACE + R_TEXT_SPACE);
int hk_state = 0;
#ifdef CONFIG_DEBUG
/* For redundant hotkeys highlighting. */
int double_hk = 0;
@ -405,6 +427,10 @@ draw_menu_left_text_hk(struct terminal *term, unsigned char *text,
hk_color_sel = tmp;
}
#ifdef CONFIG_UTF_8
if (term->utf8) goto utf8;
#endif /* CONFIG_UTF_8 */
for (x = 0; x - !!hk_state < w && (c = text[x]); x++) {
if (!hk_state && x == hotkey_pos - 1) {
hk_state = 1;
@ -417,12 +443,78 @@ draw_menu_left_text_hk(struct terminal *term, unsigned char *text,
(double_hk ? hk_color_sel : hk_color));
#else
draw_char(term, xbase + x - 1, y, c, hk_attr, hk_color);
#endif
#endif /* CONFIG_DEBUG */
hk_state = 2;
} else {
draw_char(term, xbase + x - !!hk_state, y, c, 0, color);
}
}
return;
#ifdef CONFIG_UTF_8
unsigned char *text2, *end;
utf8:
end = strchr(text, '\0');
text2 = text;
for (x = 0; x - !!hk_state < w && *text2; x++) {
unicode_val_T data;
data = utf_8_to_unicode(&text2, end);
if (!hk_state && (int)(text2 - text) == hotkey_pos) {
hk_state = 1;
continue;
}
if (hk_state == 1) {
if (unicode_to_cell(data) == 2) {
if (x < w && xbase + x < term->width) {
#ifdef CONFIG_DEBUG
draw_char(term, xbase + x - 1, y,
data, hk_attr,
(double_hk ? hk_color_sel
: hk_color));
#else
draw_char(term, xbase + x - 1, y,
data, hk_attr, hk_color);
#endif /* CONFIG_DEBUG */
x++;
draw_char(term, xbase + x - 1, y,
UCS_NO_CHAR, 0, hk_color);
} else {
draw_char(term, xbase + x - 1, y,
' ', 0, hk_color);
}
} else {
#ifdef CONFIG_DEBUG
draw_char(term, xbase + x - 1, y,
data, hk_attr,
(double_hk ? hk_color_sel
: hk_color));
#else
draw_char(term, xbase + x - 1, y,
data, hk_attr, hk_color);
#endif /* CONFIG_DEBUG */
}
hk_state = 2;
} else {
if (unicode_to_cell(data) == 2) {
if (x - !!hk_state + 1 < w &&
xbase + x - !!hk_state + 1 < term->width) {
draw_char(term, xbase + x - !!hk_state,
y, data, 0, color);
x++;
draw_char(term, xbase + x - !!hk_state,
y, UCS_NO_CHAR, 0, color);
} else {
draw_char(term, xbase + x - !!hk_state,
y, ' ', 0, color);
}
} else {
draw_char(term, xbase + x - !!hk_state,
y, data, 0, color);
}
}
}
#endif /* CONFIG_UTF_8 */
}
static inline void
@ -465,7 +557,15 @@ display_menu(struct terminal *term, struct menu *menu)
/* Draw shadow */
draw_shadow(term, &menu->box,
get_bfu_color(term, "dialog.shadow"), 2, 1);
#ifdef CONFIG_UTF_8
if (term->utf8)
fix_dwchar_around_box(term, &box, 1, 2, 1);
#endif /* CONFIG_UTF_8 */
}
#ifdef CONFIG_UTF_8
else if(term->utf8)
fix_dwchar_around_box(term, &box, 1, 0, 0);
#endif /* CONFIG_UTF_8 */
menu_height = box.height;
box.height = 1;
@ -1005,18 +1105,33 @@ display_mainmenu(struct terminal *term, struct menu *menu)
int l = mi->hotkey_pos;
int textlen;
int selected = (i == menu->selected);
int screencnt;
if (mi_text_translate(mi))
text = _(text, term);
textlen = strlen(text) - !!l;
#ifdef CONFIG_UTF_8
if (term->utf8)
screencnt = utf8_ptr2cells(text, NULL) - !!l;
else
#endif /* CONFIG_UTF_8 */
screencnt = textlen;
if (selected) {
color = selected_color;
box.x = p;
box.width = L_MAINTEXT_SPACE + L_TEXT_SPACE
+ textlen
+ R_TEXT_SPACE + R_MAINTEXT_SPACE;
#ifdef CONFIG_UTF_8
if (term->utf8)
box.width = L_MAINTEXT_SPACE + L_TEXT_SPACE
+ screencnt
+ R_TEXT_SPACE + R_MAINTEXT_SPACE;
else
#endif /* CONFIG_UTF_8 */
box.width = L_MAINTEXT_SPACE + L_TEXT_SPACE
+ textlen
+ R_TEXT_SPACE + R_MAINTEXT_SPACE;
draw_box(term, &box, ' ', 0, color);
set_cursor(term, p, 0, 1);
set_window_ptr(menu->win, p, 1);
@ -1034,7 +1149,7 @@ display_mainmenu(struct terminal *term, struct menu *menu)
color);
}
p += textlen;
p += screencnt;
if (p >= term->width - R_MAINMENU_SPACE)
break;
@ -1045,6 +1160,22 @@ display_mainmenu(struct terminal *term, struct menu *menu)
menu->last = i - 1;
int_lower_bound(&menu->last, menu->first);
if (menu->last < menu->size - 1) {
#ifdef CONFIG_UTF_8
if (term->utf8) {
struct screen_char *schar;
schar = get_char(term, term->width - R_MAINMENU_SPACE, 0);
/* Is second cell of double-width char on the place where
* first char of the R_MAINMENU_SPACE will be displayed? */
if (schar->data == UCS_NO_CHAR) {
/* Replace double-width char with ' '. */
schar++;
draw_char_data(term, term->width - R_MAINMENU_SPACE - 1,
0, ' ');
}
}
#endif
set_box(&box,
term->width - R_MAINMENU_SPACE, 0,
R_MAINMENU_SPACE, 1);

View File

@ -19,6 +19,7 @@
#include "terminal/terminal.h"
#include "util/color.h"
/* FIXME: For UTF-8 strings we need better function than isspace. */
#define is_unsplitable(pos) (*(pos) && *(pos) != '\n' && !isspace(*(pos)))
void
@ -35,48 +36,106 @@ add_dlg_text(struct dialog *dlg, unsigned char *text,
}
/* Returns length of substring (from start of @text) before a split. */
#ifdef CONFIG_UTF_8
static inline int
split_line(unsigned char *text, int max_width)
split_line(unsigned char *text, int max_width, int *cells, int utf8)
#else
static inline int
split_line(unsigned char *text, int max_width, int *cells)
#endif /* CONFIG_UTF_8 */
{
unsigned char *split = text;
int cells_save = *cells;
if (max_width <= 0) return 0;
while (*split && *split != '\n') {
unsigned char *next_split = split + 1;
unsigned char *next_split;
#ifdef CONFIG_UTF_8
if (utf8) {
unsigned char *next_char_begin = split
+ utf8charlen(split);
while (is_unsplitable(next_split))
next_split++;
next_split = split;
if (next_split - text > max_width) {
*cells += utf8_char2cells(split, NULL);
while (*next_split && next_split != next_char_begin)
next_split++;
next_char_begin = next_split;
while (is_unsplitable(next_split))
{
if (next_split < next_char_begin) {
next_split++;
continue;
}
*cells += utf8_char2cells(next_split, NULL);
next_char_begin += utf8charlen(next_split);
}
} else
#endif /* CONFIG_UTF_8 */
{
next_split = split + 1;
while (is_unsplitable(next_split))
next_split++;
*cells = next_split - text;
}
if (*cells > max_width) {
/* Force a split if no position was found yet,
* meaning there's no splittable substring under
* requested width. */
if (split == text) {
split = &text[max_width];
#ifdef CONFIG_UTF_8
if (utf8) {
int m_bytes = utf8_cells2bytes(text,
max_width,
NULL);
split = &text[m_bytes];
} else
#endif /* CONFIG_UTF_8 */
split = &text[max_width];
/* Give preference to split on a punctuation
* if any. Note that most of the time
* punctuation char is followed by a space so
* this rule will not match often.
* We match dash and quotes too. */
while (--split != text) {
if (!ispunct(*split)) continue;
split++;
break;
/* FIXME: Function ispunct won't work correctly
* with UTF-8 characters. We need some similar
* function for UTF-8 characters. */
#ifdef CONFIG_UTF_8
if (!utf8)
#endif /* CONFIG_UTF_8 */
{
/* Give preference to split on a
* punctuation if any. Note that most
* of the time punctuation char is
* followed by a space so this rule
* will not match often. We match dash
* and quotes too. */
cells_save--;
while (--split != text) {
cells_save--;
if (!ispunct(*split)) continue;
split++;
cells_save++;
break;
}
}
/* If no way to do a clean split, just return
* requested maximal width. */
if (split == text)
if (split == text) {
*cells = max_width;
return max_width;
}
}
break;
}
cells_save = *cells;
split = next_split;
}
*cells = cells_save;
return split - text;
}
@ -86,8 +145,13 @@ split_line(unsigned char *text, int max_width)
#define realloc_lines(x, o, n) mem_align_alloc(x, o, n, LINES_GRANULARITY)
/* Find the start of each line with the current max width */
#ifdef CONFIG_UTF_8
static unsigned char **
split_lines(struct widget_data *widget_data, int max_width, int utf8)
#else
static unsigned char **
split_lines(struct widget_data *widget_data, int max_width)
#endif /* CONFIG_UTF_8 */
{
unsigned char *text = widget_data->widget->text;
unsigned char **lines = (unsigned char **) widget_data->cdata;
@ -100,19 +164,27 @@ split_lines(struct widget_data *widget_data, int max_width)
while (*text) {
int width;
int cells = 0;
/* Skip first leading \n or space. */
if (isspace(*text)) text++;
if (!*text) break;
width = split_line(text, max_width);
#ifdef CONFIG_UTF_8
width = split_line(text, max_width, &cells, utf8);
#else
width = split_line(text, max_width, &cells);
#endif
/* split_line() may return 0. */