⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 draw.c

📁 一个很有名的浏览器
💻 C
字号:
/* Public terminal drawing API. Frontend for the screen image in memory. *//* $Id: draw.c,v 1.107 2004/08/06 09:02:29 zas Exp $ */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include "elinks.h"#include "config/options.h"#include "terminal/color.h"#include "terminal/draw.h"#include "terminal/screen.h"#include "terminal/terminal.h"#include "util/color.h"#include "util/box.h"/* Makes sure that @x and @y are within the dimensions of the terminal. */#define check_range(term, x, y) \	do { \		int_bounds(&(x), 0, (term)->width - 1); \		int_bounds(&(y), 0, (term)->height - 1); \	} while (0)#ifdef CONFIG_256_COLORS#define clear_screen_char_color(schar) do { memset((schar)->color, 0, 2); } while (0)#else#define clear_screen_char_color(schar) do { (schar)->color[0] = 0; } while (0)#endifinline struct screen_char *get_char(struct terminal *term, int x, int y){	assert(term && term->screen && term->screen->image);	if_assert_failed return NULL;	check_range(term, x, y);	return &term->screen->image[x + term->width * y];}/* TODO: Clearify this piece of magic code. --jonas */voiddraw_border_cross(struct terminal *term, int x, int y,		  enum border_cross_direction dir, struct color_pair *color){	static unsigned char border_trans[2][4] = {		{ BORDER_SVLINE, BORDER_SRTEE, BORDER_SLTEE, BORDER_SCROSS },		{ BORDER_SHLINE, /* ? */ 0xc2, /* ? */ 0xc1, BORDER_SCROSS },	};	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;	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_trans[d][3];	}	set_term_color(screen_char, color, 0,		       get_opt_int_tree(term->spec, "colors"));}voiddraw_border_char(struct terminal *term, int x, int y,		 enum border_char border, struct color_pair *color){	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;	set_term_color(screen_char, color, 0,		       get_opt_int_tree(term->spec, "colors"));	set_screen_dirty(term->screen, y, y);}voiddraw_char_color(struct terminal *term, int x, int y, struct color_pair *color){	struct screen_char *screen_char = get_char(term, x, y);	if (!screen_char) return;	set_term_color(screen_char, color, 0,		       get_opt_int_tree(term->spec, "colors"));	set_screen_dirty(term->screen, y, y);}voiddraw_char_data(struct terminal *term, int x, int y, unsigned char data){	struct screen_char *screen_char = get_char(term, x, y);	if (!screen_char) return;	screen_char->data = data;	set_screen_dirty(term->screen, y, y);}/* Updates a line in the terms screen. *//* When doing frame drawing @x can be different than 0. */voiddraw_line(struct terminal *term, int x, int y, int l, struct screen_char *line){	struct screen_char *screen_char = get_char(term, x, y);	int size;	assert(line);	if_assert_failed return;	if (!screen_char) return;	size = int_min(l, term->width - x);	if (size == 0) return;	copy_screen_chars(screen_char, line, size);	set_screen_dirty(term->screen, y, y);}voiddraw_border(struct terminal *term, struct box *box,	    struct color_pair *color, int width){	static enum border_char p1[] = {		BORDER_SULCORNER,		BORDER_SURCORNER,		BORDER_SDLCORNER,		BORDER_SDRCORNER,		BORDER_SVLINE,		BORDER_SHLINE,	};	static enum border_char p2[] = {		BORDER_DULCORNER,		BORDER_DURCORNER,		BORDER_DDLCORNER,		BORDER_DDRCORNER,		BORDER_DVLINE,		BORDER_DHLINE,	};	enum border_char *p = (width > 1) ? p2 : p1;	struct box borderbox;	set_box(&borderbox, box->x - 1, box->y - 1,		box->width + 2, box->height + 2);	if (borderbox.width > 2) {		struct box bbox;		/* Horizontal top border */		set_box(&bbox, box->x, borderbox.y, box->width, 1);		draw_box(term, &bbox, p[5], SCREEN_ATTR_FRAME, color);		/* Horizontal bottom border */		bbox.y += borderbox.height - 1;		draw_box(term, &bbox, p[5], SCREEN_ATTR_FRAME, color);	}	if (borderbox.height > 2) {		struct box bbox;		/* Vertical left border */		set_box(&bbox, borderbox.x, box->y, 1, box->height);		draw_box(term, &bbox, p[4], SCREEN_ATTR_FRAME, color);		/* Vertical right border */		bbox.x += borderbox.width - 1;		draw_box(term, &bbox, p[4], SCREEN_ATTR_FRAME, color);	}	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(term, borderbox.x, borderbox.y, p[0], color);		/* Upper right corner */		draw_border_char(term, right, borderbox.y, p[1], color);		/* Lower left corner */		draw_border_char(term, borderbox.x, bottom, p[2], color);		/* Lower right corner */		draw_border_char(term, right, bottom, p[3], color);	}	set_screen_dirty(term->screen, borderbox.y, borderbox.y + borderbox.height);}voiddraw_char(struct terminal *term, int x, int y,	  unsigned char data, enum screen_char_attr attr,	  struct color_pair *color){	struct screen_char *screen_char = get_char(term, x, y);	if (!screen_char) return;	screen_char->data = data;	screen_char->attr = attr;	set_term_color(screen_char, color, 0,		       get_opt_int_tree(term->spec, "colors"));	set_screen_dirty(term->screen, y, y);}voiddraw_box(struct terminal *term, struct box *box,	 unsigned char data, enum screen_char_attr attr,	 struct color_pair *color){	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 (color) {		set_term_color(end, color, 0,			       get_opt_int_tree(term->spec, "colors"));	} 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);}voiddraw_shadow(struct terminal *term, struct box *box,	    struct color_pair *color, int width, int height){	struct box dbox;	/* (horizontal) */	set_box(&dbox, box->x + width, box->y + box->height,		box->width - width, height);	draw_box(term, &dbox, ' ', 0, color);	/* (vertical) */	set_box(&dbox, box->x + box->width, box->y + height,		width, box->height);	draw_box(term, &dbox, ' ', 0, color);}voiddraw_text(struct terminal *term, int x, int y,	  unsigned char *text, int length,	  enum screen_char_attr attr, struct color_pair *color){	struct screen_char *pos, *end;	assert(text && length >= 0);	if_assert_failed return;	if (length <= 0) return;	pos = get_char(term, x, y);	if (!pos) return;	end = &pos[int_min(length, term->width - x) - 1];	if (color) {		/* Use the last char as template. */		end->attr = attr;		set_term_color(end, color, 0,			       get_opt_int_tree(term->spec, "colors"));		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);}voidset_cursor(struct terminal *term, int x, int y, int blockable){	assert(term && term->screen);	if_assert_failed return;	if (blockable && get_opt_bool_tree(term->spec, "block_cursor")) {		x = term->width - 1;		y = term->height - 1;	}	if (term->screen->cx != x || term->screen->cy != y) {		check_range(term, x, y);		set_screen_dirty(term->screen, int_min(term->screen->cy, y),					       int_max(term->screen->cy, y));		term->screen->cx = x;		term->screen->cy = y;	}}voidclear_terminal(struct terminal *term){	struct box box;	set_box(&box, 0, 0, term->width, term->height);	draw_box(term, &box, ' ', 0, NULL);	set_cursor(term, 0, 0, 1);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -