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

📄 html_r.c

📁 ELinks is an advanced and well-established feature-rich text mode web (HTTP/FTP/..) browser. ELinks
💻 C
📖 第 1 页 / 共 3 页
字号:
/* html_r.c * (c) 2002 Mikulas Patocka * This file is a part of the Links program, released under GPL. */#include "links.h"#define format format_struct f_data *init_formatted(struct document_options *opt){	struct f_data *scr;	scr = mem_calloc(sizeof(struct f_data));	copy_opt(&scr->opt, opt);	scr->data = DUMMY;	scr->nlinks = 0;	scr->links = DUMMY;	scr->nlink_events = 0;	scr->link_events = DUMMY;	init_list(scr->forms);	init_list(scr->tags);	init_list(scr->nodes);#ifdef G	scr->n_images=0;	init_list(scr->images);	scr->search_positions = DUMMY;	scr->search_lengths = DUMMY;	init_list(scr->image_refresh);	scr->start_highlight_x = -1;	scr->start_highlight_y = -1;	scr->hlt_pos = -1;#endif	return scr;}/* prototypes */void clear_formatted(struct f_data *);void r_xpand_spaces(struct part *, int);int split_line(struct part *);int put_chars_conv(struct part *, unsigned char *, int);void html_form_control(struct part *, struct form_control *);void add_frameset_entry(struct frameset_desc *, struct frameset_desc *, unsigned char *, unsigned char *, int, int, unsigned char);void *html_special(struct part *, int, ...);void do_format(char *, char *, struct part *, unsigned char *);void release_part(struct part *);void push_base_format(unsigned char *, struct document_options *, int);void add_srch_chr(struct f_data *, unsigned char, int, int, int);void sort_srch(struct f_data *);int get_srch(struct f_data *);void destroy_fc(struct form_control *fc){	int i;	if (fc->action) mem_free(fc->action);	if (fc->target) mem_free(fc->target);	if (fc->form_name) mem_free(fc->form_name);	if (fc->onsubmit) mem_free(fc->onsubmit);	if (fc->name) mem_free(fc->name);	if (fc->alt) mem_free(fc->alt);	if (fc->default_value) mem_free(fc->default_value);	for (i = 0; i < fc->nvalues; i++) {		if (fc->values[i]) mem_free(fc->values[i]);		if (fc->labels[i]) mem_free(fc->labels[i]);	}	if (fc->values) mem_free(fc->values);	if (fc->labels) mem_free(fc->labels);	if (fc->menu) free_menu(fc->menu);}void free_frameset_desc(struct frameset_desc *fd){	int i;	for (i = 0; i < fd->n; i++) {		if (fd->f[i].subframe) free_frameset_desc(fd->f[i].subframe);		if (fd->f[i].name) mem_free(fd->f[i].name);		if (fd->f[i].url) mem_free(fd->f[i].url);	}#ifdef JS	if (fd->onload_code)mem_free(fd->onload_code);#endif	mem_free(fd);}struct frameset_desc *copy_frameset_desc(struct frameset_desc *fd){	int i;	struct frameset_desc *new;	if ((unsigned)fd->n > MAXINT / sizeof(struct frame_desc)) overalloc();	new = mem_alloc(sizeof(struct frameset_desc) + fd->n * sizeof(struct frame_desc));	memcpy(new, fd, sizeof(struct frameset_desc) + fd->n * sizeof(struct frame_desc));#ifdef JS	if (new->onload_code) new->onload_code = stracpy(new->onload_code);#endif	for (i = 0; i < new->n; i++) {		if (new->f[i].subframe) new->f[i].subframe = copy_frameset_desc(new->f[i].subframe);		if (new->f[i].name) new->f[i].name = stracpy(new->f[i].name);		if (new->f[i].url) new->f[i].url = stracpy(new->f[i].url);	}	return new;}void free_additional_files(struct additional_files **a){	struct additional_file *af;	if (!*a) return;	if (--(*a)->refcount) {		*a = NULL;		return;	}	foreach(af, (*a)->af) release_object(&af->rq);	free_list((*a)->af);	mem_free(*a);	*a = NULL;}void clear_formatted(struct f_data *scr){	int n;	int y;	struct form_control *fc;	if (!scr) return;#ifdef G	if (scr->root) scr->root->destruct(scr->root);#endif	release_object(&scr->rq);	free_additional_files(&scr->af);	if (scr->title) mem_free(scr->title);	if (/*!scr->frame_desc_link &&*/ scr->frame_desc) {		free_frameset_desc(scr->frame_desc);	}	for (n = 0; n < scr->nlinks; n++) {		struct link *l = &scr->links[n];		if (l->where) mem_free(l->where);		if (l->target) mem_free(l->target);		if (l->where_img) mem_free(l->where_img);		if (l->img_alt) mem_free(l->img_alt);		if (l->pos) mem_free(l->pos);		free_js_event_spec(l->js_event);	}	mem_free(scr->links);	for (n = 0; n < scr->nlink_events; n++) {		free_js_event_spec(scr->link_events[n]);	}	mem_free(scr->link_events);	if (!F) for (y = 0; y < scr->y; y++) mem_free(scr->data[y].d);	mem_free(scr->data);	if (scr->lines1) mem_free(scr->lines1);	if (scr->lines2) mem_free(scr->lines2);	if (scr->opt.framename) mem_free(scr->opt.framename);	foreach(fc, scr->forms) {		destroy_fc(fc);	}	free_list(scr->forms);	free_list(scr->tags);	free_list(scr->nodes);	if (scr->search) mem_free(scr->search);	if (scr->slines1) mem_free(scr->slines1);	if (scr->slines2) mem_free(scr->slines2);#ifdef G	free_list(scr->image_refresh);	if (scr->srch_string) mem_free(scr->srch_string);	if (scr->last_search) mem_free(scr->last_search);	if (scr->search_positions) mem_free(scr->search_positions);	if (scr->search_lengths) mem_free(scr->search_lengths);#endif	if (scr->refresh) mem_free(scr->refresh);	jsint_destroy_document_description(scr);	if (scr->script_href_base) mem_free(scr->script_href_base);	free_js_event_spec(scr->js_event);}void destroy_formatted(struct f_data *scr){	if (scr->fd) {		internal("trying to free locked formatted data");		return;	}	clear_formatted(scr);	/*del_from_list(scr);*/	mem_free(scr);}static inline int color_distance(struct rgb *c1, struct rgb *c2){	return		3 * (c1->r - c2->r) * (c1->r - c2->r) +		4 * (c1->g - c2->g) * (c1->g - c2->g) +		2 * (c1->b - c2->b) * (c1->b - c2->b);}struct rgb palette[] = {/*	{0x00, 0x00, 0x00, 0},	{0x80, 0x00, 0x00, 0},	{0x00, 0x80, 0x00, 0},	{0x80, 0x80, 0x00, 0},	{0x00, 0x00, 0x80, 0},	{0x80, 0x00, 0x80, 0},	{0x00, 0x80, 0x80, 0},	{0xC0, 0xC0, 0xC0, 0},	{0x80, 0x80, 0x80, 0},	{0xff, 0x00, 0x00, 0},	{0x00, 0xff, 0x00, 0},	{0xff, 0xff, 0x00, 0},	{0x00, 0x00, 0xff, 0},	{0xff, 0x00, 0xff, 0},	{0x00, 0xff, 0xff, 0},	{0xff, 0xff, 0xff, 0},*/	/*{0x00, 0x00, 0x00, 0},	{0xaa, 0x00, 0x00, 0},	{0x00, 0xaa, 0x00, 0},	{0xaa, 0x55, 0x00, 0},	{0x00, 0x00, 0xaa, 0},	{0xaa, 0x00, 0xaa, 0},	{0x00, 0xaa, 0xaa, 0},	{0xaa, 0xaa, 0xaa, 0},	{0x55, 0x55, 0x55, 0},	{0xff, 0x55, 0x55, 0},	{0x55, 0xff, 0x55, 0},	{0xff, 0xff, 0x55, 0},	{0x55, 0x55, 0xff, 0},	{0xff, 0x55, 0xff, 0},	{0x55, 0xff, 0xff, 0},	{0xff, 0xff, 0xff, 0},*/	{0x00, 0x00, 0x00, 0},	{0x80, 0x00, 0x00, 0},	{0x00, 0x80, 0x00, 0},	{0xaa, 0x55, 0x00, 0},	{0x00, 0x00, 0x80, 0},	{0x80, 0x00, 0x80, 0},	{0x00, 0x80, 0x80, 0},	{0xaa, 0xaa, 0xaa, 0},	{0x55, 0x55, 0x55, 0},	{0xff, 0x55, 0x55, 0},	{0x55, 0xff, 0x55, 0},	{0xff, 0xff, 0x55, 0},	{0x55, 0x55, 0xff, 0},	{0xff, 0x55, 0xff, 0},	{0x55, 0xff, 0xff, 0},	{0xff, 0xff, 0xff, 0},	{-1, -1, -1, 0}};/*struct rgb rgbcache = {0, 0, 0};int rgbcache_c = 0;static inline int find_nearest_color(struct rgb *r, int l){	int dist, dst, min, i;	if (r->r == rgbcache.r && r->g == rgbcache.g && r->b == rgbcache.b) return rgbcache_c;	dist = 0xffffff;	min = 0;	for (i = 0; i < l; i++) if ((dst = color_distance(r, &palette[i])) < dist)		dist = dst, min = i;	return min;}*/struct rgb_cache_entry {	int color;	int l;	struct rgb rgb;};#define RGB_HASH_SIZE 4096#define HASH_RGB(r, l) ((((r)->r << 3) + ((r)->g << 2) + (r)->b + (l)) & (RGB_HASH_SIZE - 1))static inline int find_nearest_color(struct rgb *r, int l){	int dist, dst, min, i;	static struct rgb_cache_entry rgb_cache[RGB_HASH_SIZE];	static int cache_init = 0;	int h;	if (!cache_init) goto initialize;	back:	h = HASH_RGB(r, l);	if (rgb_cache[h].color != -1 && rgb_cache[h].l == l && rgb_cache[h].rgb.r == r->r && rgb_cache[h].rgb.g == r->g && rgb_cache[h].rgb.b == r->b) return rgb_cache[h].color;	dist = 0xffffff;	min = 0;	for (i = 0; i < l; i++) if ((dst = color_distance(r, &palette[i])) < dist)		dist = dst, min = i;	rgb_cache[h].color = min;	rgb_cache[h].l = l;	rgb_cache[h].rgb.r = r->r;	rgb_cache[h].rgb.g = r->g;	rgb_cache[h].rgb.b = r->b;	return min;	initialize:	for (h = 0; h < RGB_HASH_SIZE; h++) rgb_cache[h].color = -1;	cache_init = 1;	goto back;}static inline int fg_color(int fg, int bg){	int l = bg < fg ? bg : fg;	int h = bg < fg ? fg : bg;	if (l == h || (!l && (h == 4 || h == 8 || h == 12)) ||	   (l == 1 && (h == 3 || h == 5 || h == 8 || h == 12)) ||	   (l == 2 && h == 6) || (l == 3 && (h == 5 || h == 12)) ||	   (l == 4 && (h == 8 || h == 12)) || (l == 5 && (h == 8 || h == 12)))		return (fg == 4 || fg == 12) && (bg == 0 || bg == 8) ? 6 : (7 - 7 * (bg == 2 || bg == 6 || bg == 7));	return fg;}#define XALIGN(x) (((x)+0x7f)&~0x7f)int nowrap = 0;static inline void xpand_lines(struct part *p, int y){	/*if (y >= p->y) p->y = y + 1;*/	if (!p->data) return;	if (XALIGN((unsigned)y + (unsigned)p->yp) > MAXINT) overalloc();	y += p->yp;	if (y >= p->data->y) {		int i;		if (XALIGN(y + 1) > XALIGN(p->data->y)) {			if (XALIGN((unsigned)y + 1) > MAXINT / sizeof(struct line)) overalloc();			p->data->data = mem_realloc(p->data->data, XALIGN(y+1)*sizeof(struct line));		}		for (i = p->data->y; i <= y; i++) {			p->data->data[i].l = 0;			p->data->data[i].c = p->bgcolor;			p->data->data[i].d = DUMMY;		}		p->data->y = i;	}}static inline void xpand_line(struct part *p, int y, int x){	if (!p->data) return;	if (XALIGN((unsigned)x + (unsigned)p->xp) > MAXINT) overalloc();	x += p->xp;	y += p->yp;#ifdef DEBUG	if (y >= p->data->y) {		internal("line does not exist");		return;	}#endif	if (x >= p->data->data[y].l) {		int i;		if (XALIGN(x+1) > XALIGN(p->data->data[y].l)) {			if (XALIGN((unsigned)x + 1) > MAXINT / sizeof(chr)) overalloc();			p->data->data[y].d = mem_realloc(p->data->data[y].d, XALIGN(x+1)*sizeof(chr));		}		for (i = p->data->data[y].l; i <= x; i++)			p->data->data[y].d[i] = (p->data->data[y].c << 11) | ' ';		p->data->data[y].c = p->bgcolor;		p->data->data[y].l = i;	}}void r_xpand_spaces(struct part *p, int l){	unsigned char *c;	if ((unsigned)l >= MAXINT) overalloc();	c = mem_realloc(p->spaces, l + 1);	memset(c + p->spl, 0, l - p->spl + 1);	p->spl = l + 1;	p->spaces = c;}static inline void xpand_spaces(struct part *p, int l){	if ((unsigned)l >= (unsigned)p->spl) r_xpand_spaces(p, l);}#define POS(x, y) (p->data->data[p->yp + (y)].d[p->xp + (x)])#define LEN(y) (p->data->data[p->yp + (y)].l - p->xp < 0 ? 0 : p->data->data[p->yp + (y)].l - p->xp)#define SLEN(y, x) p->data->data[p->yp + (y)].l = p->xp + x;#define X(x) (p->xp + (x))#define Y(y) (p->yp + (y))static inline void set_hchar(struct part *p, int x, int y, unsigned c){	xpand_lines(p, y);	xpand_line(p, y, x);	POS(x, y) = c;}static inline void set_hchars(struct part *p, int x, int y, int xl, unsigned c){	xpand_lines(p, y);	xpand_line(p, y, x+xl-1);	for (; xl; xl--, x++) POS(x, y) = c;}void xset_hchar(struct part *p, int x, int y, unsigned c){	set_hchar(p, x, y, c);}void xset_hchars(struct part *p, int x, int y, int xl, unsigned c){	set_hchars(p, x, y, xl, c);}void xxpand_lines(struct part *p, int y){	xpand_lines(p, y);}void xxpand_line(struct part *p, int y, int x){	xpand_line(p, y, x);}static inline void set_hline(struct part *p, int x, int y, int xl, unsigned char *d, unsigned c, int spc){	xpand_lines(p, y);	xpand_line(p, y, x+xl-1);	if (spc) xpand_spaces(p, x+xl-1);	for (; xl; xl--, x++, d++) {		if (spc) p->spaces[x] = *d == ' ';		if (p->data) POS(x, y) = *d | c;	}}int last_link_to_move;struct tag *last_tag_to_move;struct tag *last_tag_for_newline;static inline void move_links(struct part *p, int xf, int yf, int xt, int yt){	int n;	struct tag *t;	int w = 0;	if (!p->data) return;	xpand_lines(p, yt);	for (n = last_link_to_move; n < p->data->nlinks; n++) {		int i;		struct link *link = &p->data->links[n];			/*printf("ml: %d %d %d %d",link->pos[0].x,link->pos[0].y,X(xf),Y(yf));fflush(stdout);sleep(1);*/		/*for (i = 0; i < link->n; i++) fprintf(stderr, "%d.%d -> %d.%d: %d.%d : %d %d\n", X(xf), Y(yf), X(xt), yt != -1 ? Y(yt) : -1, n, i, link->pos[i].x, link->pos[i].y);*/		for (i = 0; i < link->n; i++) if (link->pos[i].y >= Y(yf)) {			w = 1;			if (link->pos[i].y == Y(yf) && link->pos[i].x >= X(xf)) {				if (yt >= 0) link->pos[i].y = Y(yt), link->pos[i].x += -xf + xt;				else memmove(&link->pos[i], &link->pos[i+1], (link->n-i-1) * sizeof(struct point)), link->n--, i--;			}		}		/*if (!link->n) {			if (link->where) mem_free(link->where);			if (link->target) mem_free(link->target);			if (link->where_img) mem_free(link->where_img);			if (link->img_alt) mem_free(link->img_alt);			if (link->pos) mem_free(link->pos);			memmove(link, link + 1, (p->data->nlinks - n - 1) * sizeof(struct link));			p->data->nlinks --;			n--;		}*/		if (!w /*&& n >= 0*/) last_link_to_move = n;	}	w = 0;	if (yt >= 0) for (t = last_tag_to_move->next; (void *)t != &p->data->tags; t = t->next) {		if (t->y == Y(yf)) {			w = 1;			if (t->x >= X(xf)) {				t->y = Y(yt), t->x += -xf + xt;			}		}		if (!w) last_tag_to_move = t;	}}static inline void copy_chars(struct part *p, int x, int y, int xl, chr *d){	if (xl <= 0) return;	xpand_lines(p, y);	xpand_line(p, y, x+xl-1);	for (; xl; xl--, x++, d++) POS(x, y) = *d;}static inline void move_chars(struct part *p, int x, int y, int nx, int ny){	if (LEN(y) - x <= 0) return;	copy_chars(p, nx, ny, LEN(y) - x, &POS(x, y));	SLEN(y, x);	move_links(p, x, y, nx, ny);}static inline void shift_chars(struct part *p, int y, int s){	chr *a;	int l = LEN(y);	if ((unsigned)l > MAXINT / sizeof(chr)) overalloc();	a = mem_alloc(l * sizeof(chr));	memcpy(a, &POS(0, y), l * sizeof(chr));	set_hchars(p, 0, y, s, (p->data->data[y].c << 11) | ' ');	copy_chars(p, s, y, l, a);	mem_free(a);	move_links(p, 0, y, s, y);}static inline void del_chars(struct part *p, int x, int y){

⌨️ 快捷键说明

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