mirror of
https://github.com/rkd77/elinks.git
synced 2024-11-04 08:17:17 -05:00
[draw] Overloaded version draw functions.
Functions with suffix _node instead of struct color_pair * take as parameter node_number.
This commit is contained in:
parent
aab01cfae1
commit
89e314d510
@ -74,11 +74,46 @@ draw_border_cross(struct terminal *term, int x, int y,
|
||||
} else if (screen_char->data == border_trans[d][2 - (dir & 1)]) {
|
||||
screen_char->data = BORDER_SCROSS;
|
||||
}
|
||||
screen_char->is_node = 0;
|
||||
|
||||
set_term_color(screen_char, color, 0,
|
||||
get_opt_int_tree(term->spec, "colors", NULL));
|
||||
}
|
||||
|
||||
void
|
||||
draw_border_cross_node(struct terminal *term, int x, int y,
|
||||
enum border_cross_direction dir, unsigned int node_number)
|
||||
{
|
||||
static const unsigned char border_trans[2][4] = {
|
||||
/* Used for BORDER_X_{RIGHT,LEFT}: */
|
||||
{ BORDER_SVLINE, BORDER_SRTEE, BORDER_SLTEE },
|
||||
/* Used for BORDER_X_{DOWN,UP}: */
|
||||
{ BORDER_SHLINE, BORDER_SDTEE, BORDER_SUTEE },
|
||||
};
|
||||
struct screen_char *screen_char = get_char(term, x, y);
|
||||
unsigned int d;
|
||||
|
||||
if (!screen_char) return;
|
||||
if (!(screen_char->attr & SCREEN_ATTR_FRAME)) return;
|
||||
|
||||
/* First check if there is already a horizontal/vertical line, so that
|
||||
* we will have to replace with a T char. Example: if there is a '|'
|
||||
* and the direction is right, replace with a '|-' T char.
|
||||
*
|
||||
* If this is not the case check if there is a T char and we are adding
|
||||
* the direction so that we end up with a cross. Example : if there is
|
||||
* a '|-' and the direction is left, replace with a '+' (cross) char. */
|
||||
d = dir>>1;
|
||||
if (screen_char->data == border_trans[d][0]) {
|
||||
screen_char->data = border_trans[d][1 + (dir & 1)];
|
||||
|
||||
} else if (screen_char->data == border_trans[d][2 - (dir & 1)]) {
|
||||
screen_char->data = BORDER_SCROSS;
|
||||
}
|
||||
screen_char->c.node_number = node_number;
|
||||
screen_char->is_node = 1;
|
||||
}
|
||||
|
||||
void
|
||||
draw_border_char(struct terminal *term, int x, int y,
|
||||
border_char_T border, struct color_pair *color)
|
||||
@ -89,11 +124,28 @@ draw_border_char(struct terminal *term, int x, int y,
|
||||
|
||||
screen_char->data = (unsigned char) border;
|
||||
screen_char->attr = SCREEN_ATTR_FRAME;
|
||||
screen_char->is_node = 0;
|
||||
set_term_color(screen_char, color, 0,
|
||||
get_opt_int_tree(term->spec, "colors", NULL));
|
||||
set_screen_dirty(term->screen, y, y);
|
||||
}
|
||||
|
||||
void
|
||||
draw_border_char_node(struct terminal *term, int x, int y,
|
||||
border_char_T border, unsigned int node_number)
|
||||
{
|
||||
struct screen_char *screen_char = get_char(term, x, y);
|
||||
|
||||
if (!screen_char) return;
|
||||
|
||||
screen_char->data = (unsigned char) border;
|
||||
screen_char->attr = SCREEN_ATTR_FRAME;
|
||||
screen_char->c.node_number = node_number;
|
||||
screen_char->is_node = 1;
|
||||
set_screen_dirty(term->screen, y, y);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
draw_char_color(struct terminal *term, int x, int y, struct color_pair *color)
|
||||
{
|
||||
@ -103,6 +155,19 @@ draw_char_color(struct terminal *term, int x, int y, struct color_pair *color)
|
||||
|
||||
set_term_color(screen_char, color, 0,
|
||||
get_opt_int_tree(term->spec, "colors", NULL));
|
||||
screen_char->is_node = 0;
|
||||
set_screen_dirty(term->screen, y, y);
|
||||
}
|
||||
|
||||
void
|
||||
draw_char_color_node(struct terminal *term, int x, int y, unsigned int node_number)
|
||||
{
|
||||
struct screen_char *screen_char = get_char(term, x, y);
|
||||
|
||||
if (!screen_char) return;
|
||||
|
||||
screen_char->c.node_number = node_number;
|
||||
screen_char->is_node = 1;
|
||||
set_screen_dirty(term->screen, y, y);
|
||||
}
|
||||
|
||||
@ -259,6 +324,73 @@ draw_border(struct terminal *term, struct el_box *box,
|
||||
set_screen_dirty(term->screen, borderbox.y, borderbox.y + borderbox.height);
|
||||
}
|
||||
|
||||
void
|
||||
draw_border_node(struct terminal *term, struct el_box *box,
|
||||
unsigned int node_number, int width)
|
||||
{
|
||||
static const border_char_T p1[] = {
|
||||
BORDER_SULCORNER,
|
||||
BORDER_SURCORNER,
|
||||
BORDER_SDLCORNER,
|
||||
BORDER_SDRCORNER,
|
||||
BORDER_SVLINE,
|
||||
BORDER_SHLINE,
|
||||
};
|
||||
static const border_char_T p2[] = {
|
||||
BORDER_DULCORNER,
|
||||
BORDER_DURCORNER,
|
||||
BORDER_DDLCORNER,
|
||||
BORDER_DDRCORNER,
|
||||
BORDER_DVLINE,
|
||||
BORDER_DHLINE,
|
||||
};
|
||||
const border_char_T *p = (width > 1) ? p2 : p1;
|
||||
struct el_box borderbox;
|
||||
|
||||
set_box(&borderbox, box->x - 1, box->y - 1,
|
||||
box->width + 2, box->height + 2);
|
||||
|
||||
if (borderbox.width > 2) {
|
||||
struct el_box bbox;
|
||||
|
||||
/* Horizontal top border */
|
||||
set_box(&bbox, box->x, borderbox.y, box->width, 1);
|
||||
draw_box_node(term, &bbox, p[5], SCREEN_ATTR_FRAME, node_number);
|
||||
|
||||
/* Horizontal bottom border */
|
||||
bbox.y += borderbox.height - 1;
|
||||
draw_box_node(term, &bbox, p[5], SCREEN_ATTR_FRAME, node_number);
|
||||
}
|
||||
|
||||
if (borderbox.height > 2) {
|
||||
struct el_box bbox;
|
||||
|
||||
/* Vertical left border */
|
||||
set_box(&bbox, borderbox.x, box->y, 1, box->height);
|
||||
draw_box_node(term, &bbox, p[4], SCREEN_ATTR_FRAME, node_number);
|
||||
|
||||
/* Vertical right border */
|
||||
bbox.x += borderbox.width - 1;
|
||||
draw_box_node(term, &bbox, p[4], SCREEN_ATTR_FRAME, node_number);
|
||||
}
|
||||
|
||||
if (borderbox.width > 1 && borderbox.height > 1) {
|
||||
int right = borderbox.x + borderbox.width - 1;
|
||||
int bottom = borderbox.y + borderbox.height - 1;
|
||||
|
||||
/* Upper left corner */
|
||||
draw_border_char_node(term, borderbox.x, borderbox.y, p[0], node_number);
|
||||
/* Upper right corner */
|
||||
draw_border_char_node(term, right, borderbox.y, p[1], node_number);
|
||||
/* Lower left corner */
|
||||
draw_border_char_node(term, borderbox.x, bottom, p[2], node_number);
|
||||
/* Lower right corner */
|
||||
draw_border_char_node(term, right, bottom, p[3], node_number);
|
||||
}
|
||||
|
||||
set_screen_dirty(term->screen, borderbox.y, borderbox.y + borderbox.height);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_UTF8
|
||||
/** Checks cells left and right to the box for broken double-width chars.
|
||||
* Replace it with UCS_ORPHAN_CELL.
|
||||
@ -351,12 +483,37 @@ draw_char(struct terminal *term, int x, int y,
|
||||
|
||||
screen_char->data = data;
|
||||
screen_char->attr = attr;
|
||||
screen_char->is_node = 0;
|
||||
set_term_color(screen_char, color, 0,
|
||||
get_opt_int_tree(term->spec, "colors", NULL));
|
||||
|
||||
set_screen_dirty(term->screen, y, y);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_UTF8
|
||||
void
|
||||
draw_char_node(struct terminal *term, int x, int y,
|
||||
unicode_val_T data, int attr,
|
||||
unsigned int node_number)
|
||||
#else
|
||||
void
|
||||
draw_char_node(struct terminal *term, int x, int y,
|
||||
unsigned char data, int attr,
|
||||
unsigned int node_number)
|
||||
#endif /* CONFIG_UTF8 */
|
||||
{
|
||||
struct screen_char *screen_char = get_char(term, x, y);
|
||||
|
||||
if (!screen_char) return;
|
||||
|
||||
screen_char->data = data;
|
||||
screen_char->attr = attr;
|
||||
screen_char->is_node = 1;
|
||||
screen_char->c.node_number = node_number;
|
||||
set_screen_dirty(term->screen, y, y);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
draw_box(struct terminal *term, struct el_box *box,
|
||||
unsigned char data, int attr,
|
||||
@ -378,6 +535,7 @@ draw_box(struct terminal *term, struct el_box *box,
|
||||
end->attr = attr;
|
||||
end->data = data;
|
||||
if (color) {
|
||||
end->is_node = 0;
|
||||
set_term_color(end, color, 0,
|
||||
get_opt_int_tree(term->spec, "colors", NULL));
|
||||
} else {
|
||||
@ -400,6 +558,51 @@ draw_box(struct terminal *term, struct el_box *box,
|
||||
set_screen_dirty(term->screen, box->y, box->y + box->height);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
draw_box_node(struct terminal *term, struct el_box *box,
|
||||
unsigned char data, int attr,
|
||||
unsigned int node_number)
|
||||
{
|
||||
struct screen_char *line, *pos, *end;
|
||||
int width, height;
|
||||
|
||||
line = get_char(term, box->x, box->y);
|
||||
if (!line) return;
|
||||
|
||||
height = int_min(box->height, term->height - box->y);
|
||||
width = int_min(box->width, term->width - box->x);
|
||||
|
||||
if (height <= 0 || width <= 0) return;
|
||||
|
||||
/* Compose off the ending screen position in the areas first line. */
|
||||
end = &line[width - 1];
|
||||
end->attr = attr;
|
||||
end->data = data;
|
||||
if (node_number) {
|
||||
end->is_node = 1;
|
||||
end->c.node_number = node_number;
|
||||
} else {
|
||||
clear_screen_char_color(end);
|
||||
}
|
||||
|
||||
/* Draw the first area line. */
|
||||
for (pos = line; pos < end; pos++) {
|
||||
copy_screen_chars(pos, end, 1);
|
||||
}
|
||||
|
||||
/* Now make @end point to the last line */
|
||||
/* For the rest of the area use the first area line. */
|
||||
pos = line;
|
||||
while (--height) {
|
||||
pos += term->width;
|
||||
copy_screen_chars(pos, line, width);
|
||||
}
|
||||
|
||||
set_screen_dirty(term->screen, box->y, box->y + box->height);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
draw_shadow(struct terminal *term, struct el_box *box,
|
||||
struct color_pair *color, int width, int height)
|
||||
@ -419,6 +622,26 @@ draw_shadow(struct terminal *term, struct el_box *box,
|
||||
draw_box(term, &dbox, ' ', 0, color);
|
||||
}
|
||||
|
||||
void
|
||||
draw_shadow_node(struct terminal *term, struct el_box *box,
|
||||
unsigned int node_number, int width, int height)
|
||||
{
|
||||
struct el_box dbox;
|
||||
|
||||
/* (horizontal) */
|
||||
set_box(&dbox, box->x + width, box->y + box->height,
|
||||
box->width - width, height);
|
||||
|
||||
draw_box_node(term, &dbox, ' ', 0, node_number);
|
||||
|
||||
/* (vertical) */
|
||||
set_box(&dbox, box->x + box->width, box->y + height,
|
||||
width, box->height);
|
||||
|
||||
draw_box_node(term, &dbox, ' ', 0, node_number);
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_UTF8
|
||||
static void
|
||||
draw_text_utf8(struct terminal *term, int x, int y,
|
||||
@ -492,6 +715,79 @@ draw_text_utf8(struct terminal *term, int x, int y,
|
||||
set_screen_dirty(term->screen, y, y);
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
draw_text_utf8_node(struct terminal *term, int x, int y,
|
||||
const char *text2, int length,
|
||||
int attr, unsigned int node_number)
|
||||
{
|
||||
struct screen_char *start, *pos;
|
||||
char *text = (char *)text2;
|
||||
char *end = text + length;
|
||||
unicode_val_T data;
|
||||
|
||||
assert(text && length >= 0);
|
||||
if_assert_failed return;
|
||||
|
||||
if (length <= 0) return;
|
||||
if (x >= term->width) return;
|
||||
|
||||
data = utf8_to_unicode(&text, end);
|
||||
if (data == UCS_NO_CHAR) return;
|
||||
start = get_char(term, x, y);
|
||||
if (node_number) {
|
||||
start->attr = attr;
|
||||
start->is_node = 1;
|
||||
start->c.node_number = node_number;
|
||||
}
|
||||
|
||||
if (start->data == UCS_NO_CHAR && x - 1 > 0)
|
||||
draw_char_data(term, x - 1, y, UCS_ORPHAN_CELL);
|
||||
|
||||
pos = start;
|
||||
|
||||
if (unicode_to_cell(data) == 2) {
|
||||
/* Is there enough room for whole double-width char? */
|
||||
if (x + 1 < term->width) {
|
||||
pos->data = data;
|
||||
pos++;
|
||||
x++;
|
||||
|
||||
pos->data = UCS_NO_CHAR;
|
||||
pos->attr = 0;
|
||||
} else {
|
||||
pos->data = UCS_ORPHAN_CELL;
|
||||
}
|
||||
} else {
|
||||
pos->data = data;
|
||||
}
|
||||
pos++;
|
||||
x++;
|
||||
|
||||
for (; x < term->width; x++, pos++) {
|
||||
data = utf8_to_unicode(&text, end);
|
||||
if (data == UCS_NO_CHAR) break;
|
||||
if (node_number) copy_screen_chars(pos, start, 1);
|
||||
|
||||
if (unicode_to_cell(data) == 2) {
|
||||
/* Is there enough room for whole double-width char? */
|
||||
if (x + 1 < term->width) {
|
||||
pos->data = data;
|
||||
|
||||
x++;
|
||||
pos++;
|
||||
pos->data = UCS_NO_CHAR;
|
||||
pos->attr = 0;
|
||||
} else {
|
||||
pos->data = UCS_ORPHAN_CELL;
|
||||
}
|
||||
} else {
|
||||
pos->data = data;
|
||||
}
|
||||
}
|
||||
set_screen_dirty(term->screen, y, y);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_UTF8 */
|
||||
|
||||
void
|
||||
@ -560,6 +856,73 @@ draw_text(struct terminal *term, int x, int y,
|
||||
set_screen_dirty(term->screen, y, y);
|
||||
}
|
||||
|
||||
void
|
||||
draw_text_node(struct terminal *term, int x, int y,
|
||||
const char *text, int length,
|
||||
int attr, unsigned int node_number)
|
||||
{
|
||||
int end_pos;
|
||||
struct screen_char *pos, *end;
|
||||
|
||||
assert(text && length >= 0);
|
||||
if_assert_failed return;
|
||||
|
||||
if (x >= term->width || y >= term->height) return;
|
||||
|
||||
#ifdef CONFIG_UTF8
|
||||
if (term->utf8_cp) {
|
||||
draw_text_utf8_node(term, x, y, text, length, attr, node_number);
|
||||
return;
|
||||
}
|
||||
#endif /* CONFIG_UTF8 */
|
||||
|
||||
if (length <= 0) return;
|
||||
pos = get_char(term, x, y);
|
||||
if (!pos) return;
|
||||
|
||||
end_pos = int_min(length, term->width - x) - 1;
|
||||
|
||||
#ifdef CONFIG_DEBUG
|
||||
/* Detect attempt to set @end to a point outside @text,
|
||||
* it may occur in case of bad calculations. --Zas */
|
||||
if (end_pos < 0) {
|
||||
INTERNAL("end_pos < 0 !!");
|
||||
end_pos = 0;
|
||||
} else {
|
||||
int textlen = strlen(text);
|
||||
|
||||
if (end_pos >= textlen) {
|
||||
INTERNAL("end_pos (%d) >= text length (%d) !!", end_pos, textlen);
|
||||
end_pos = textlen - 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
end = &pos[int_max(0, end_pos)];
|
||||
|
||||
if (node_number) {
|
||||
/* Use the last char as template. */
|
||||
end->attr = attr;
|
||||
end->is_node = 1;
|
||||
end->c.node_number = node_number;
|
||||
|
||||
for (; pos < end && *text; text++, pos++) {
|
||||
end->data = *text;
|
||||
copy_screen_chars(pos, end, 1);
|
||||
}
|
||||
|
||||
end->data = *text;
|
||||
|
||||
} else {
|
||||
for (; pos <= end && *text; text++, pos++) {
|
||||
pos->data = *text;
|
||||
}
|
||||
}
|
||||
|
||||
set_screen_dirty(term->screen, y, y);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
draw_dlg_text(struct dialog_data *dlg_data, int x, int y,
|
||||
const char *text, int length,
|
||||
@ -577,6 +940,23 @@ draw_dlg_text(struct dialog_data *dlg_data, int x, int y,
|
||||
draw_text(term, x, y, text, length, attr, color);
|
||||
}
|
||||
|
||||
void
|
||||
draw_dlg_text_node(struct dialog_data *dlg_data, int x, int y,
|
||||
const char *text, int length,
|
||||
int attr, unsigned int node_number)
|
||||
{
|
||||
struct terminal *term = dlg_data->win->term;
|
||||
struct el_box *box = &dlg_data->real_box;
|
||||
|
||||
if (box->height) {
|
||||
int y_max = box->y + box->height;
|
||||
|
||||
y -= dlg_data->y;
|
||||
if (y < box->y || y >= y_max) return;
|
||||
}
|
||||
draw_text_node(term, x, y, text, length, attr, node_number);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
set_cursor(struct terminal *term, int x, int y, int blockable)
|
||||
|
@ -245,6 +245,8 @@ struct screen_char *get_char(struct terminal *, int x, int y);
|
||||
void draw_char_color(struct terminal *term, int x, int y,
|
||||
struct color_pair *color);
|
||||
|
||||
void draw_char_color_node(struct terminal *term, int x, int y, unsigned int node_number);
|
||||
|
||||
/** Sets the data of a screen position. */
|
||||
#ifdef CONFIG_UTF8
|
||||
void draw_char_data(struct terminal *term, int x, int y, unicode_val_T data);
|
||||
@ -256,19 +258,34 @@ void draw_char_data(struct terminal *term, int x, int y, unsigned char data);
|
||||
void draw_border_char(struct terminal *term, int x, int y,
|
||||
border_char_T border, struct color_pair *color);
|
||||
|
||||
void draw_border_char_node(struct terminal *term, int x, int y,
|
||||
border_char_T border, unsigned int node_number);
|
||||
|
||||
/** Sets the cross position of two borders. */
|
||||
void draw_border_cross(struct terminal *, int x, int y,
|
||||
enum border_cross_direction, struct color_pair *color);
|
||||
|
||||
void draw_border_cross_node(struct terminal *, int x, int y,
|
||||
enum border_cross_direction, unsigned int node_number);
|
||||
|
||||
/** Draws a char. */
|
||||
#ifdef CONFIG_UTF8
|
||||
void draw_char(struct terminal *term, int x, int y,
|
||||
unicode_val_T data, int attr,
|
||||
struct color_pair *color);
|
||||
|
||||
void draw_char_node(struct terminal *term, int x, int y,
|
||||
unicode_val_T data, int attr,
|
||||
unsigned int node_number);
|
||||
#else
|
||||
void draw_char(struct terminal *term, int x, int y,
|
||||
unsigned char data, int attr,
|
||||
struct color_pair *color);
|
||||
|
||||
void draw_char_node(struct terminal *term, int x, int y,
|
||||
unsigned char data, int attr,
|
||||
unsigned int node_number);
|
||||
|
||||
#endif /* CONFIG_UTF8 */
|
||||
|
||||
/** Draws area defined by @a box using the same colors and attributes. */
|
||||
@ -276,15 +293,25 @@ void draw_box(struct terminal *term, struct el_box *box,
|
||||
unsigned char data, int attr,
|
||||
struct color_pair *color);
|
||||
|
||||
void draw_box_node(struct terminal *term, struct el_box *box,
|
||||
unsigned char data, int attr,
|
||||
unsigned int node_number);
|
||||
|
||||
/** Draws a shadow of @a width and @a height with color @a color
|
||||
* around @a box. */
|
||||
void draw_shadow(struct terminal *term, struct el_box *box,
|
||||
struct color_pair *color, int width, int height);
|
||||
|
||||
void draw_shadow_node(struct terminal *term, struct el_box *box,
|
||||
unsigned int node_number, int width, int height);
|
||||
|
||||
/** Draw borders. */
|
||||
void draw_border(struct terminal *term, struct el_box *box,
|
||||
struct color_pair *color, int width);
|
||||
|
||||
void draw_border_node(struct terminal *term, struct el_box *box,
|
||||
unsigned int node_number, int width);
|
||||
|
||||
#ifdef CONFIG_UTF8
|
||||
void fix_dwchar_around_box(struct terminal *term, struct el_box *box, int border,
|
||||
int shadow_width, int shadow_height);
|
||||
@ -296,11 +323,20 @@ void draw_text(struct terminal *term, int x, int y,
|
||||
int attr,
|
||||
struct color_pair *color);
|
||||
|
||||
void draw_text_node(struct terminal *term, int x, int y,
|
||||
const char *text, int length,
|
||||
int attr,
|
||||
unsigned int node_number);
|
||||
|
||||
/** Draws text for dialogs. */
|
||||
void draw_dlg_text(struct dialog_data *dlg_data, int x, int y,
|
||||
const char *text, int length,
|
||||
int attr, struct color_pair *color);
|
||||
|
||||
void draw_dlg_text_node(struct dialog_data *dlg_data, int x, int y,
|
||||
const char *text, int length,
|
||||
int attr, unsigned int node_number);
|
||||
|
||||
|
||||
/** Draws @a length chars from @a line on the screen. */
|
||||
void draw_line(struct terminal *term, int x, int y, int length,
|
||||
|
Loading…
Reference in New Issue
Block a user