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

📄 html_tbl.c

📁 ELinks is an advanced and well-established feature-rich text mode web (HTTP/FTP/..) browser. ELinks
💻 C
📖 第 1 页 / 共 4 页
字号:
/* html_tbl.c * Tables in HTML * (c) 2002 Mikulas Patocka * This file is a part of the Links program, released under GPL. */#include "links.h"#define format format_#ifdef DEBUG#undef DEBUG#endif/*#define DEBUG*/#define RECT_BOUND_BITS	10	/* --- bound at 1024 pixels */#define AL_TR		-1#define VAL_TR		-1#define VAL_TOP		0#define VAL_MIDDLE	1#define VAL_BOTTOM	2#define W_AUTO		-1#define W_REL		-2#define F_VOID		0#define F_ABOVE		1#define F_BELOW		2#define F_HSIDES	3#define F_LHS		4#define F_RHS		8#define F_VSIDES	12#define F_BOX		15#define R_NONE		0#define R_ROWS		1#define R_COLS		2#define R_ALL		3#define R_GROUPS	4void get_align(char *, int *);void get_valign(char *, int *);void get_c_width(char *, int *, int);void get_align(char *attr, int *a){	char *al;	if ((al = get_attr_val(attr, "align"))) {		if (!(strcasecmp(al, "left"))) *a = AL_LEFT;		if (!(strcasecmp(al, "right"))) *a = AL_RIGHT;		if (!(strcasecmp(al, "center"))) *a = AL_CENTER;		if (!(strcasecmp(al, "justify"))) *a = AL_BLOCK;		if (!(strcasecmp(al, "char"))) *a = AL_RIGHT; /* NOT IMPLEMENTED */		mem_free(al);	}}void get_valign(char *attr, int *a){	char *al;	if ((al = get_attr_val(attr, "valign"))) {		if (!(strcasecmp(al, "top"))) *a = VAL_TOP;		if (!(strcasecmp(al, "middle"))) *a = VAL_MIDDLE;		if (!(strcasecmp(al, "bottom"))) *a = VAL_BOTTOM;		if (!(strcasecmp(al, "baseline"))) *a = VAL_TOP; /* NOT IMPLEMENTED */		mem_free(al);	}}void get_c_width(char *attr, int *w, int sh){	char *al;	if ((al = get_attr_val(attr, "width"))) {		if (*al && al[strlen(al) - 1] == '*') {			char *en;			unsigned long n;			al[strlen(al) - 1] = 0;			n = strtoul(al, &en, 10);			if (n < 10000 && !*en) *w = W_REL - n;		} else {			int p = get_width(attr, "width", sh);			if (p >= 0) *w = p;		}		mem_free(al);	}}#define INIT_X		8#define INIT_Y		8struct table_cell {	int used;	int spanned;	int mx, my;	unsigned char *start;	unsigned char *end;	int align;	int valign;	int b;	struct rgb bgcolor;	int group;	int colspan;	int rowspan;	int min_width;	int max_width;	int x_width;	int height;	int xpos, ypos, xw, yw;	int link_num;#ifdef G	unsigned char bgcolor_str[8];	struct g_object_area *root;	struct rect_set *brd;	int g_width;	struct rect rect;	int dgen;#endif};struct table_column {	int group;	int align;	int valign;	int width;};struct table {	struct part *p;#ifdef G	struct g_part *gp;#endif	int x, y;	int rx, ry;	int align;	int border, cellpd, vcellpd, cellsp;	int frame, rules, width, wf;	unsigned char *bordercolor;	int *min_c, *max_c;	int *w_c;	int rw;	int min_t, max_t;	struct table_cell *cells;	int c, rc;	struct table_column *cols;	int xc;	int *xcols;	int *r_heights;	int rh;	int link_num;	struct rgb bgcolor;#ifdef G	struct background *bg;	struct background *frame_bg;	struct rect_set **r_bg;	int nr_bg;	struct rect_set **r_frame;	int nr_frame;	struct table_cell ***r_cells;	int *w_cells;	int nr_cells;#endif};/* prototype */void free_table(struct table *);void expand_cells(struct table *, int, int);struct table_cell *new_cell(struct table *, int, int);void new_columns(struct table *, int, int, int, int, int);void set_td_width(struct table *, int, int, int);void get_cell_widths(struct table *);void dst_width(int *, int, int, int *);int get_vline_width(struct table *, int);int get_hline_width(struct table *, int);int g_get_vline_pad(struct table *, int, int *, int *);int g_get_hline_pad(struct table *, int, int *, int *);int get_column_widths(struct table *);void get_table_width(struct table *);void distribute_widths(struct table *, int);void check_table_widths(struct table *);void get_table_heights(struct table *);void display_complicated_table(struct table *, int, int, int *);void get_table_frame(struct table *, signed char *, signed char *);void display_table_frames(struct table *, int, int);#ifdef Gvoid add_to_rect_sets(struct rect_set ***, int *, struct rect *);void add_to_cell_sets(struct table_cell ****, int **, int *, struct rect *, struct table_cell *);void table_mouse_event(struct f_data_c *, struct g_object_table *, int, int, int);void draw_rect_set(struct graphics_device *, struct background *, struct rect_set *, int, int);void draw_rect_sets(struct graphics_device *, struct background *, struct rect_set **, int, int, int);void table_draw(struct f_data_c *, struct g_object_table *, int, int);void table_destruct(struct g_object_table *);void table_get_list(struct g_object_table *, void (*)(struct g_object *, struct g_object *));#endifstruct table *new_table(void);void get_cell_width(char *, char *, int, int, int, int *, int *, int, int *, unsigned char *);#ifdef DEBUG#define CELL(t, x, y) (((x) < 0 || (x) >= (t)->rx || (y) < 0 || (y) >= (t)->ry) ? (internal("accessing cell out of table (%d,%d) - limit (%d,%d)", (x), (y), (t)->rx, (t)->ry), (t)->cells) : &(t)->cells[(y) * (t)->rx + (x)])#else#define CELL(t, x, y) (&(t)->cells[(y) * (t)->rx + (x)])#endifunsigned char frame_table[81] = {	0x00, 0xb3, 0xba,	0xc4, 0xc0, 0xd3,	0xcd, 0xd4, 0xc8,	0xc4, 0xd9, 0xbd,	0xc4, 0xc1, 0xd0,	0xcd, 0xd4, 0xc8,	0xcd, 0xbe, 0xbc,	0xcd, 0xbe, 0xbc,	0xcd, 0xcf, 0xca,	0xb3, 0xb3, 0xba,	0xda, 0xc3, 0xd3,	0xd5, 0xc6, 0xc8,	0xbf, 0xb4, 0xbd,	0xc2, 0xc5, 0xd0,	0xd5, 0xc6, 0xc8,	0xb8, 0xb5, 0xbc,	0xb8, 0xb5, 0xbc,	0xd1, 0xd8, 0xca,	0xba, 0xba, 0xba,	0xd6, 0xd6, 0xc7,	0xc9, 0xc9, 0xcc,	0xb7, 0xb7, 0xb6,	0xd2, 0xd2, 0xd7,	0xc9, 0xc9, 0xcc,	0xbb, 0xbb, 0xb9,	0xbb, 0xbb, 0xb9,	0xcb, 0xcb, 0xce,};unsigned char hline_table[3] = { 0x20, 0xc4, 0xcd };unsigned char vline_table[3] = { 0x20, 0xb3, 0xba };struct table *new_table(void){	struct table *t;	t = mem_calloc(sizeof(struct table));	t->p = NULL;#ifdef G	t->gp = NULL;	t->r_frame = DUMMY;	t->nr_frame = 0;	t->r_bg = DUMMY;	t->nr_bg = 0;	t->r_cells = DUMMY;	t->w_cells = DUMMY;	t->nr_cells = 0;#endif	t->x = t->y = 0;	t->rx = INIT_X;	t->ry = INIT_Y;	t->cells = mem_calloc(INIT_X * INIT_Y * sizeof(struct table_cell));	t->c = 0;	t->rc = INIT_X;	t->cols = mem_calloc(INIT_X * sizeof(struct table_column));	t->xcols = DUMMY;	t->xc = 0;	t->r_heights = DUMMY;	return t;}void free_table(struct table *t){#ifdef G	if (F) {		int i, j;		for (j = 0; j < t->y; j++) for (i = 0; i < t->x; i++) {			struct table_cell *c = CELL(t, i, j);			if (c->root) c->root->destruct(c->root);			if (c->brd) mem_free(c->brd);		}		for (i = 0; i < t->nr_frame; i++) mem_free(t->r_frame[i]);		if (t->r_frame) mem_free(t->r_frame);		for (i = 0; i < t->nr_bg; i++) mem_free(t->r_bg[i]);		if (t->r_bg) mem_free(t->r_bg);		for (i = 0; i < t->nr_cells; i++) mem_free(t->r_cells[i]);		mem_free(t->r_cells), mem_free(t->w_cells);		if (t->frame_bg) g_release_background(t->frame_bg);	}#endif	if (t->bordercolor) mem_free(t->bordercolor);	if (t->min_c) mem_free(t->min_c);	if (t->max_c) mem_free(t->max_c);	if (t->w_c) mem_free(t->w_c);	mem_free(t->r_heights);	mem_free(t->cols);	mem_free(t->xcols);	mem_free(t->cells);	mem_free(t);}void expand_cells(struct table *t, int x, int y){	int i, j;	if (x >= t->x) {		if (t->x) {			for (i = 0; i < t->y; i++) if (CELL(t, t->x - 1, i)->colspan == -1) {				for (j = t->x; j <= x; j++) {					CELL(t, j, i)->used = 1;					CELL(t, j, i)->spanned = 1;					CELL(t, j, i)->rowspan = CELL(t, t->x - 1, i)->rowspan;					CELL(t, j, i)->colspan = -1;					CELL(t, j, i)->mx = CELL(t, t->x - 1, i)->mx;					CELL(t, j, i)->my = CELL(t, t->x - 1, i)->my;				}			}		}		t->x = x + 1;	}	if (y >= t->y) {		if (t->y) {			for (i = 0; i < t->x; i++) if (CELL(t, i, t->y - 1)->rowspan == -1) {				for (j = t->y; j <= y; j++) {					CELL(t, i, j)->used = 1;					CELL(t, i, j)->spanned = 1;					CELL(t, i, j)->rowspan = -1;					CELL(t, i, j)->colspan = CELL(t, i, t->y - 1)->colspan;					CELL(t, i, j)->mx = CELL(t, i, t->y - 1)->mx;					CELL(t, i, j)->my = CELL(t, i, t->y - 1)->my;				}			}		}		t->y = y + 1;	}}struct table_cell *new_cell(struct table *t, int x, int y){	struct table nt;	int i, j;	if (x < t->x && y < t->y) goto ret;	rep:	if (x < t->rx && y < t->ry) {		expand_cells(t, x, y);		goto ret;	}	nt.rx = t->rx;	nt.ry = t->ry;	while (x >= nt.rx) {		if ((unsigned)nt.rx > MAXINT / 2) overalloc();		nt.rx *= 2;	}	while (y >= nt.ry) {		if ((unsigned)nt.ry > MAXINT / 2) overalloc();		nt.ry *= 2;	}	if ((unsigned)nt.rx * (unsigned)nt.ry / (unsigned)nt.rx != (unsigned)nt.ry) overalloc();	if ((unsigned)nt.rx * (unsigned)nt.ry > MAXINT / sizeof(struct table_cell)) overalloc();	nt.cells = mem_calloc(nt.rx * nt.ry * sizeof(struct table_cell));	for (i = 0; i < t->x; i++)		for (j = 0; j < t->y; j++)			memcpy(CELL(&nt, i, j), CELL(t, i, j), sizeof(struct table_cell));	mem_free(t->cells);	t->cells = nt.cells;	t->rx = nt.rx;	t->ry = nt.ry;	goto rep;	ret:	return CELL(t, x, y);}void new_columns(struct table *t, int span, int width, int align, int valign, int group){	if ((unsigned)t->c + (unsigned)span > MAXINT) overalloc();	if (t->c + span > t->rc) {		int n = t->rc;		struct table_column *nc;		while (t->c + span > n) {			if ((unsigned)n > MAXINT / 2) overalloc();			n *= 2;		}		if ((unsigned)n > MAXINT / sizeof(struct table_column)) overalloc();		nc = mem_realloc(t->cols, n * sizeof(struct table_column));		t->rc = n;		t->cols = nc;	}	while (span--) {		t->cols[t->c].align = align;		t->cols[t->c].valign = valign;		t->cols[t->c].width = width;		t->cols[t->c++].group = group;		group = 0;	}}void set_td_width(struct table *t, int x, int width, int f){	if (x >= t->xc) {		int n = t->xc ? t->xc : 1;		int i;		int *nc;		while (x >= n) {			if ((unsigned)n > MAXINT / 2) overalloc();			n *= 2;		}		if ((unsigned)n > MAXINT / sizeof(int)) overalloc();		nc = mem_realloc(t->xcols, n * sizeof(int));		for (i = t->xc; i < n; i++) nc[i] = W_AUTO;		t->xc = n;		t->xcols = nc;	}	if (t->xcols[x] == W_AUTO || f) {		set:		t->xcols[x] = width;		return;	}	if (width == W_AUTO) return;	if (width < 0 && t->xcols[x] >= 0) goto set;	if (width >= 0 && t->xcols[x] < 0) return;	t->xcols[x] = (t->xcols[x] + width) / 2;}unsigned char *skip_element(unsigned char *html, unsigned char *eof, unsigned char *what, int sub){	int l = strlen(what);	int level = 1;	unsigned char *name;	int namelen;	r:	while (html < eof && (*html != '<')) rr:html++;	if (html + 2 <= eof && (html[1] == '!' || html[1] == '?')) {		html = skip_comment(html, eof);		goto r;	}	if (html >= eof) return eof;	if (parse_element(html, eof, &name, &namelen, NULL, &html)) goto rr;	if (namelen == l && !casecmp(name, what, l) && sub) level++;	if (namelen == l + 1 && name[0] == '/' && !casecmp(name + 1, what, l)) if (!--level) return html;	goto r;}struct s_e {	unsigned char *s, *e;};struct table *parse_table(unsigned char *, unsigned char *, unsigned char **, struct rgb *, int, struct s_e **, int *);  /* prototype */struct table *parse_table(unsigned char *html, unsigned char *eof, unsigned char **end, struct rgb *bgcolor, int sh, struct s_e **bad_html, int *bhp){	int qqq;	struct table *t;	struct table_cell *cell;	unsigned char *t_name, *t_attr, *en;	int t_namelen;	int x = 0, y = -1;	int p = 0;	unsigned char *lbhp = NULL;	int l_al = AL_LEFT;	int l_val = VAL_MIDDLE;	int csp, rsp;	int group = 0;	int i, j, k;	struct rgb l_col;	int c_al = AL_TR, c_val = VAL_TR, c_width = W_AUTO, c_span = 0;	memcpy(&l_col, bgcolor, sizeof(struct rgb));	*end = html;	if (bad_html) {		*bad_html = DUMMY;		*bhp = 0;	}	if (!(t = new_table())) return NULL;	memcpy(&t->bgcolor, bgcolor, sizeof(struct rgb));	se:	en = html;	see:	html = en;	if (bad_html && !p && !lbhp) {		if (!(*bhp & (ALLOC_GR-1))) {			if ((unsigned)*bhp > MAXINT / sizeof(struct s_e) - ALLOC_GR) overalloc();

⌨️ 快捷键说明

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