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

📄 html_tbl.c

📁 ELinks is an advanced and well-established feature-rich text mode web (HTTP/FTP/..) browser. ELinks
💻 C
📖 第 1 页 / 共 4 页
字号:
	if (!F && border > 2) border = 2;	if (!F && cellsp > 2) cellsp = 2;	if (F && !cellsp && border) cellsp = 1;	align = par_format.align;	if (align == AL_NO || align == AL_BLOCK) align = AL_LEFT;	if ((al = get_attr_val(attr, "align"))) {		if (!strcasecmp(al, "left")) align = AL_LEFT;		if (!strcasecmp(al, "center")) align = AL_CENTER;		if (!strcasecmp(al, "right")) align = AL_RIGHT;		mem_free(al);	}	frame = F_BOX;	if ((al = get_attr_val(attr, "frame"))) {		if (!strcasecmp(al, "void")) frame = F_VOID;		if (!strcasecmp(al, "above")) frame = F_ABOVE;		if (!strcasecmp(al, "below")) frame = F_BELOW;		if (!strcasecmp(al, "hsides")) frame = F_HSIDES;		if (!strcasecmp(al, "vsides")) frame = F_VSIDES;		if (!strcasecmp(al, "lhs")) frame = F_LHS;		if (!strcasecmp(al, "rhs")) frame = F_RHS;		if (!strcasecmp(al, "box")) frame = F_BOX;		if (!strcasecmp(al, "border")) frame = F_BOX;		mem_free(al);	}	rules = border ? R_ALL : R_NONE;	if ((al = get_attr_val(attr, "rules"))) {		if (!strcasecmp(al, "none")) rules = R_NONE;		if (!strcasecmp(al, "groups")) rules = R_GROUPS;		if (!strcasecmp(al, "rows")) rules = R_ROWS;		if (!strcasecmp(al, "cols")) rules = R_COLS;		if (!strcasecmp(al, "all")) rules = R_ALL;		mem_free(al);	}	if (!border) frame = F_VOID;	wf = 0;	if ((width = get_width(attr, "width", gf_val(p->data || p->xp, !!gp->data))) == -1) {		width = par_format.width - (par_format.leftmargin + par_format.rightmargin) * gf_val(1, G_HTML_MARGIN);		if (width < 0) width = 0;		wf = 1;	}	if (!(t = parse_table(html, eof, end, &bgcolor, gf_val(p->data || p->xp, !!gp->data), &bad_html, &bad_html_n))) {		if (bad_html) mem_free(bad_html);		goto ret0;	}	for (i = 0; i < bad_html_n; i++) {		while (bad_html[i].s < bad_html[i].e && WHITECHAR(*bad_html[i].s)) bad_html[i].s++;		while (bad_html[i].s < bad_html[i].e && WHITECHAR(bad_html[i].e[-1])) bad_html[i].e--;		if (bad_html[i].s < bad_html[i].e) parse_html(bad_html[i].s, bad_html[i].e, put_chars_f, line_break_f, special_f, gf_val((void *)p, (void *)gp), NULL);	}	mem_free(bad_html);	html_stack_dup();	html_top.dontkill = 1;	par_format.align = AL_LEFT;#ifdef G	if (F) {		t->gp = gp;	} else#endif	{		t->p = p;	}	t->bordercolor = get_attr_val(attr, "bordercolor");	t->align = align;	t->border = border;	t->cellpd = cellpd;	t->vcellpd = vcellpd;	t->cellsp = cellsp;	t->frame = frame;	t->rules = rules;	t->width = width;	t->wf = wf;	cpd_pass = 0;	cpd_last = t->cellpd;	cpd_width = 0;	/* not needed, but let the warning go away */	again:	get_cell_widths(t);	if (get_column_widths(t)) goto ret2;	get_table_width(t);	if (gf_val(!p->data && !p->xp, !gp->data)) {		if (!wf && t->max_t > width) t->max_t = width;		if (t->max_t < t->min_t) t->max_t = t->min_t;		if (t->max_t + (par_format.leftmargin + par_format.rightmargin) * gf_val(1, G_HTML_MARGIN) > gf_val(p->xmax, gp->xmax)) *gf_val(&p->xmax, &gp->xmax) = t->max_t + (par_format.leftmargin + par_format.rightmargin) * gf_val(1, G_HTML_MARGIN);		if (t->min_t + (par_format.leftmargin + par_format.rightmargin) * gf_val(1, G_HTML_MARGIN) > gf_val(p->x, gp->x)) *gf_val(&p->x, &gp->x) = t->min_t + (par_format.leftmargin + par_format.rightmargin) * gf_val(1, G_HTML_MARGIN);		goto ret2;	}	if (!F && !cpd_pass && t->min_t > width && t->cellpd) {		t->cellpd = 0;		cpd_pass = 1;		cpd_width = t->min_t;		goto again;	}	if (cpd_pass == 1 && t->min_t > cpd_width) {		t->cellpd = cpd_last;		cpd_pass = 2;		goto again;	}	/*debug("%d %d %d", t->min_t, t->max_t, width);*/	if (t->min_t >= width) distribute_widths(t, t->min_t);	else if (t->max_t < width && wf) distribute_widths(t, t->max_t);	else distribute_widths(t, width);	if (!F && !p->data && p->xp == 1) {		int ww = t->rw + par_format.leftmargin + par_format.rightmargin;		if (ww > par_format.width) ww = par_format.width;		if (ww < t->rw) ww = t->rw;		if (ww > p->x) p->x = ww;		p->cy += t->rh;		goto ret2;	}#ifdef HTML_TABLE_2ND_PASS	if (!F) check_table_widths(t);#endif	get_table_heights(t);#ifdef G	if (F) {		gp->link_num = t->link_num;		process_g_table(gp, t);		t = NULL;		goto ret3;	}#endif	x = par_format.leftmargin;	if (align == AL_CENTER) x = (par_format.width + par_format.leftmargin - par_format.rightmargin - t->rw) / 2;	if (align == AL_RIGHT) x = par_format.width - par_format.rightmargin - t->rw;	if (x + t->rw > par_format.width) x = par_format.width - t->rw;	if (x < 0) x = 0;	/*display_table(t, x, p->cy, &cye);*/	if (!p->data) {		if (t->rw + par_format.leftmargin + par_format.rightmargin > p->x) p->x = t->rw + par_format.leftmargin + par_format.rightmargin;		p->cy += t->rh;		goto ret2;	}	n = p->data->nodes.next;	n->yw = p->yp - n->y + p->cy;	display_complicated_table(t, x, p->cy, &cye);	display_table_frames(t, x, p->cy);	nn = mem_alloc(sizeof(struct node));	nn->x = n->x;	nn->y = p->yp + cye;	nn->xw = n->xw;	add_to_list(p->data->nodes, nn);	/*if (p->cy + t->rh != cye) internal("size does not match; 1:%d, 2:%d", p->cy + t->rh, cye);*/	p->cy = cye;	ret2:	*gf_val(&p->link_num, &gp->link_num) = t->link_num;#ifdef G	ret3:#endif	if (!F) if (p->cy > p->y) p->y = p->cy;	if (t) free_table(t);	kill_html_stack_item(&html_top);	ret0:	table_level--;	if (!table_level) {		if (!F) free_table_cache();#ifdef G		else g_free_table_cache();#endif	}}#ifdef Gvoid add_to_rect_sets(struct rect_set ***s, int *n, struct rect *r){	int i, j;	for (i = r->y1 >> RECT_BOUND_BITS; i <= (r->y2 - 1) >> RECT_BOUND_BITS; i++) {		if (i >= *n) {			struct rect_set **ns;			if ((unsigned)i > MAXINT / sizeof(struct rect_set *) - 1) overalloc();			ns = mem_realloc(*s, (i + 1) * sizeof(struct rect_set *));			for (j = *n; j < i + 1; j++) ns[j] = init_rect_set();			*s = ns;			*n = i + 1;		}		add_to_rect_set(&(*s)[i], r);	}}void add_to_cell_sets(struct table_cell ****s, int **nn, int *n, struct rect *r, struct table_cell *c){	int i, j;	for (i = r->y1 >> RECT_BOUND_BITS; i <= (r->y2 - 1) >> RECT_BOUND_BITS; i++) {		if (i >= *n) {			struct table_cell ***ns;			int *nnn;			if ((unsigned)i > MAXINT / sizeof(struct table_cell ***) - 1) overalloc();			if ((unsigned)i > MAXINT / sizeof(int *) - 1) overalloc();			ns = mem_realloc(*s, (i + 1) * sizeof(struct table_cell ***));			nnn = mem_realloc(*nn, (i + 1) * sizeof(int *));			for (j = *n; j < i + 1; j++) ns[j] = DUMMY, nnn[j] = 0;			*s = ns;			*nn = nnn;			*n = i + 1;		}		{			struct table_cell **nc;			if ((unsigned)(*nn)[i]  > MAXINT / sizeof(struct table_cell *) - 1) overalloc();			nc = mem_realloc((*s)[i], ((*nn)[i] + 1) * sizeof(struct table_cell *));			nc[(*nn)[i]] = c;			(*s)[i] = nc;			(*nn)[i]++;		}	}}void table_mouse_event(struct f_data_c *fd, struct g_object_table *o, int x, int y, int b){	struct table *t = o->t;	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) if (g_forward_mouse(fd, (struct g_object *)c->root, x, y, b)) return;	}}void draw_rect_set(struct graphics_device *dev, struct background *bg, struct rect_set *rs, int x, int y){	int i;	for (i = 0; i < rs->m; i++) {		struct rect *r = &rs->r[i];		if (is_rect_valid(r))			g_draw_background(dev, bg, x + r->x1, y + r->y1, r->x2 - r->x1, r->y2 - r->y1);	}}void draw_rect_sets(struct graphics_device *dev, struct background *bg, struct rect_set **rs, int nrs, int x, int y){	int i;	for (i = (dev->clip.y1 - y) >> RECT_BOUND_BITS; i <= (dev->clip.y2 - y - 1) >> RECT_BOUND_BITS; i++) if (i >= 0 && i < nrs) {		draw_rect_set(dev, bg, rs[i], x, y);	}}void table_draw(struct f_data_c *fd, struct g_object_table *o, int x, int y){	static int dgen = 1;	int i, j;	struct table *t = o->t;	struct graphics_device *dev = fd->ses->term->dev;	dgen++;	/*	for (j = 0; j < t->y; j++) for (i = 0; i < t->x; i++) {		struct table_cell *c = CELL(t, i, j);*/	/*	fprintf(stderr, "Y: %d %d\n", x, y);	fprintf(stderr, "bounds: %d %d\n", dev->clip.y1 + y, dev->clip.y2 + y);	*/	for (i = (dev->clip.y1 - y) >> RECT_BOUND_BITS; i <= (dev->clip.y2 - y - 1) >> RECT_BOUND_BITS; i++) if (i >= 0 && i < t->nr_cells) for (j = 0; j < t->w_cells[i]; j++) {		struct table_cell *c = t->r_cells[i][j];		/*fprintf(stderr, "draw: %d %d\n", i, j);*/		if (c->root && c->dgen != dgen) {			struct rect clip;			memcpy(&clip, &c->rect, sizeof(struct rect));			clip.x1 += x;			clip.x2 += x;			clip.y1 += y;			clip.y2 += y;			if (!do_rects_intersect(&clip, &dev->clip)) continue;			draw_rect_set(dev, c->root->bg, c->brd, x, y);			restrict_clip_area(dev, &clip, x + c->root->x, y + c->root->y, x + c->root->x + c->root->xw/*c->g_width*/, y + c->root->y + c->root->yw);			c->root->draw(fd, c->root, x + c->root->x, y + c->root->y);			drv->set_clip_area(dev, &clip);			c->dgen = dgen;		}	}	draw_rect_sets(dev, t->bg, t->r_bg, t->nr_bg, x, y);	draw_rect_sets(dev, t->frame_bg, t->r_frame, t->nr_frame, x, y);}void table_destruct(struct g_object_table *o){	free_table(o->t);	mem_free(o);}void table_get_list(struct g_object_table *o, void (*fn)(struct g_object *parent, struct g_object *child)){	struct table *t = o->t;	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) fn((struct g_object *)o, (struct g_object *)c->root);	}}void table_bg(struct text_attrib *ta, char bgstr[8]){	if (ta->bg.r + ta->bg.g * 3 + ta->bg.b * 5 > 9 * 128) strcpy(bgstr, "#000000");	else if (ta->fg.r > G_HTML_TABLE_FRAME_COLOR && ta->fg.g > G_HTML_TABLE_FRAME_COLOR && ta->fg.b > G_HTML_TABLE_FRAME_COLOR) {		unsigned char max = ta->fg.r;		if (ta->fg.g > max) max = ta->fg.g;		if (ta->fg.b > max) max = ta->fg.b;		max &= 0xff;		sprintf(bgstr, "#%02x%02x%02x", max, max, max);	} else sprintf(bgstr, "#%02x%02x%02x", G_HTML_TABLE_FRAME_COLOR, G_HTML_TABLE_FRAME_COLOR, G_HTML_TABLE_FRAME_COLOR);}void process_g_table(struct g_part *gp, struct table *t){	int i, j;	int x, y;	struct g_object_table *o;	signed char *fv, *fh;	unsigned char bgstr[8];	struct text_attrib *ta;	struct rgb dummy;	y = 0;	for (j = 0; j < t->y; j++) {		x = 0;		y += g_get_hline_pad(t, j, NULL, NULL);		for (i = 0; i < t->x; i++) {			struct table_cell *c;			x += g_get_vline_pad(t, i, NULL, NULL);			c = CELL(t, i, j);			if (c->root) {				int s;				int yw = 0;				for (s = 0; s < c->rowspan; s++) {					yw += t->r_heights[j + s];					if (s < c->rowspan - 1) yw += g_get_hline_pad(t, j + s + 1, NULL, NULL);				}				c->root->x = x, c->root->y = y;				c->root->y += c->valign != VAL_MIDDLE && c->valign != VAL_BOTTOM ? 0 : (yw - c->root->yw) / (c->valign == VAL_MIDDLE ? 2 : 1);			}			x += t->w_c[i];		}		y += t->r_heights[j];	}	if (html_top.next != (struct html_element *)(void *)&html_stack) ta = &html_top.next->attr;	else ta = &format;	if (t->bordercolor && !decode_color(t->bordercolor, &dummy)) {		if (!(t->frame_bg = get_background(NULL, t->bordercolor))) {			free_table(t);			return;		}	} else {		table_bg(ta, bgstr);		if (!(t->frame_bg = get_background(NULL, bgstr))) {			free_table(t);			return;		}	}	if ((unsigned)t->x > MAXINT) overalloc();	if ((unsigned)t->y > MAXINT) overalloc();	if (((unsigned)t->x + 2) * ((unsigned)t->y + 2) / ((unsigned)t->x + 2) != ((unsigned)t->y + 2)) overalloc();	if (((unsigned)t->x + 2) * ((unsigned)t->y + 2) > MAXINT) overalloc();	fh = mem_alloc((t->x + 2) * (t->y + 1));	fv = mem_alloc((t->x + 1) * (t->y + 2));	get_table_frame(t, fv, fh);	y = 0;	for (j = 0; j <= t->y; j++) {		int ypad, ypos, ysize;		ypad = g_get_hline_pad(t, j, &ypos, &ysize);		x = 0;		for (i = 0; i <= t->x; i++) {			struct rect r;			int xpad, xpos, xsize;			xpad = g_get_vline_pad(t, i, &xpos, &xsize);			if (i < t->x && j < t->y) {				CELL(t, i, j)->xpos = x + xpos + xsize;				CELL(t, i, j)->ypos = y + ypos + ysize;			}			if (i > 0 && j > 0) {				struct table_cell *c = CELL(t, i - 1, j - 1);				c->xw = x + xpos - c->xpos;				c->yw = y + ypos - c->ypos;				/*debug("C: %d %d %d %d", c->xpos, c->ypos, c->xw, c->yw);*/				/*debug("%d %d %d", y, ypos, c->ypos);*/				if (!c->used && !c->spanned) {					r.x1 = c->xpos, r.x2 = c->xpos + c->xw;					r.y1 = c->ypos, r.y2 = c->ypos + c->yw;					add_to_rect_sets(&t->r_bg, &t->nr_bg, &r);				}			}			r.x1 = x + xpos, r.x2 = x + xpos + xsize;			r.y1 = y + ypos, r.y2 = y + ypos + ysize;			if (H_LINE(i-1,j) || H_LINE(i,j) || V_LINE(i,j-1) || V_LINE(i,j))				add_to_rect_sets(&t->r_frame, &t->nr_frame, &r);			else if (H_LINE_X(i-1,j) != -2 || H_LINE_X(i,j) != -2 || V_LINE_X(i,j-1) != -2 || V_LINE_X(i,j) != -2) add_to_rect_sets(&t->r_bg, &t->nr_bg, &r);			if (i < t->x) {				int l;				int b;				g_get_vline_pad(t, i + 1, &b, NULL);				r.x1 = r.x2;				r.x2 = x + xpad + t->w_c[i] + b;				l = H_LINE_X(i,j);				if (l == -2) ;				else if (l > 0) add_to_rect_sets(&t->r_frame, &t->nr_frame, &r);				else add_to_rect_sets(&t->r_bg, &t->nr_bg, &r);			}			r.x1 = x + xpos, r.x2 = x + xpos + xsize;			if (j < t->y) {				int l;				int b;				g_get_hline_pad(t, j + 1, &b, NULL);				r.y1 = r.y2;				r.y2 = y + ypad + t->r_heights[j] + b;				l = V_LINE_X(i,j);				if (l == -2) ;				else if (l > 0) add_to_rect_sets(&t->r_frame, &t->nr_frame, &r);				else add_to_rect_sets(&t->r_bg, &t->nr_bg, &r);			}			if (i < t->x) x += xpad + t->w_c[i];		}		if (j < t->y) y += ypad + t->r_heights[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->used && !c->spanned && c->root) {			struct table_cell *d = CELL(t, i + c->colspan - 1, j + c->rowspan - 1);			struct rect r;			r.x1 = c->xpos;			r.y1 = c->ypos;			r.x2 = d->xpos + d->xw;			r.y2 = d->ypos + d->yw;			add_to_cell_sets(&t->r_cells, &t->w_cells, &t->nr_cells, &r, c);			memcpy(&c->rect, &r, sizeof(struct rect));			c->brd = init_rect_set();			/*debug("%d,%d %d,%d", r.x1, r.y1, r.x2, r.y2);*/			add_to_rect_set(&c->brd, &r);			r.x1 = c->root->x;			r.y1 = c->root->y;			r.x2 = c->root->x + c->root->xw;			r.y2 = c->root->y + c->root->yw;			exclude_rect_from_set(&c->brd, &r);			/*debug("%d,%d %d,%d", r.x1, r.y1, r.x2, r.y2);*/		}	}	mem_free(fh);	mem_free(fv);	o = mem_calloc(sizeof(struct g_object_table));	o->mouse_event = table_mouse_event;	o->draw = table_draw;	o->destruct = table_destruct;	o->get_list = table_get_list;	o->xw = t->rw;	o->yw = t->rh;	o->t = t;	t->bg = gp->root->bg;	flush_pending_text_to_line(gp);	flush_pending_line_to_obj(gp, 0);	gp->cx = -1;	add_object_to_line(gp, &gp->line, (struct g_object *)o);	flush_pending_text_to_line(gp);	par_format.align = t->align;	flush_pending_line_to_obj(gp, 0);	gp->cx = -1;}#endif

⌨️ 快捷键说明

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