html_tbl.c

来自「this is the file used to browse web」· C语言 代码 · 共 1,263 行 · 第 1/3 页

C
1,263
字号
					c = 0;					for (l = i; l < i + s; l++) if (w[l] < t->w_c[k]) w[l]++, w[k]--, c = 1;					if (w[k] > t->w_c[k]) {						if (!c) internal("can't shrink cell");						else goto ag;					}				}*/			} else if (c->colspan > s && c->colspan < ns) ns = c->colspan;		}	} while ((s = ns) != MAXINT);	s = 0; ns = 0;	for (i = 0; i < t->x; i++) {		s += t->w_c[i], ns += w[i];		/*if (w[i] > t->w_c[i]) {			int k;			for (k = 0; k < t->x; k++) debug("%d, %d", t->w_c[k], w[k]);			debug("column %d: new width(%d) is larger than previous(%d)", i, w[i], t->w_c[i]);		}*/	}	if (ns > s) {		/*internal("new width(%d) is larger than previous(%d)", ns, s);*/		mem_free(w);		return;	}	m = -1;	for (i = 0; i < t->x; i++) {		/*if (table_level == 1) debug("%d: %d %d %d %d", i, t->max_c[i], t->min_c[i], t->w_c[i], w[i]);*/		if (t->max_c[i] > m) m = t->max_c[i], mi = i;	}	/*if (table_level == 1) debug("%d %d", mi, s - ns);*/	if (m != -1) {		w[mi] += s - ns;		if (w[mi] <= t->max_c[mi]) {			mem_free(t->w_c);			t->w_c = w;			return;		}	}	mem_free(w);}#endifvoid get_table_heights(struct table *t){	int s, ns;	int i, j;	for (j = 0; j < t->y; j++) {		for (i = 0; i < t->x; i++) {			struct table_cell *cell = CELL(t, i, j);			struct part *p;			int xw = 0, sp;			if (!cell->used || cell->spanned) continue;			for (sp = 0; sp < cell->colspan; sp++) {				xw += t->w_c[i + sp];				if (sp < cell->colspan - 1) xw += get_vline_width(t, i + sp + 1) >= 0;			}			if (!(p = format_html_part(cell->start, cell->end, cell->align, t->cellpd, xw, NULL, 2, 2, NULL, cell->link_num))) return;			cell->height = p->y;				/*debug("%d, %d.",xw, cell->height);*/			mem_free(p);		}	}	s = 1;	do {		ns = MAXINT;		for (j = 0; j < t->y; j++) {			for (i = 0; i < t->x; i++) {				struct table_cell *cell = CELL(t, i, j);				if (!cell->used || cell->spanned) continue;				if (cell->rowspan == s) {					int k, p = 0;					for (k = 1; k < s; k++) p += get_hline_width(t, j + k) >= 0;					dst_width(t->r_heights + j, s, cell->height - p, NULL);				} else if (cell->rowspan > s && cell->rowspan < ns) ns = cell->rowspan;			}		}	} while ((s = ns) != MAXINT);	t->rh = (!!(t->frame & F_ABOVE) + !!(t->frame & F_BELOW)) * !!t->border;	for (j = 0; j < t->y; j++) {		t->rh += t->r_heights[j];		if (j) t->rh += get_hline_width(t, j) >= 0;	}}void display_complicated_table(struct table *t, int x, int y, int *yy){	int i, j;	struct f_data *f = t->p->data;	int yp, xp = x + ((t->frame & F_LHS) && t->border);	for (i = 0; i < t->x; i++) {		yp = y + ((t->frame & F_ABOVE) && t->border);		for (j = 0; j < t->y; j++) {			struct table_cell *cell = CELL(t, i, j);			if (cell->start) {				int yt;				struct part *p = NULL;				int xw = 0, yw = 0, s;				for (s = 0; s < cell->colspan; s++) {					xw += t->w_c[i + s];					if (s < cell->colspan - 1) xw += get_vline_width(t, i + s + 1) >= 0;				}				for (s = 0; s < cell->rowspan; s++) {					yw += t->r_heights[j + s];					if (s < cell->rowspan - 1) yw += get_hline_width(t, j + s + 1) >= 0;				}				html_stack_dup();				html_top.dontkill = 1;				if (cell->b) format.attr |= AT_BOLD;				memcpy(&format.bg, &cell->bgcolor, sizeof(struct rgb));				memcpy(&par_format.bgcolor, &cell->bgcolor, sizeof(struct rgb));				p = format_html_part(cell->start, cell->end, cell->align, t->cellpd, xw, f, t->p->xp + xp, t->p->yp + yp + (cell->valign != VAL_MIDDLE && cell->valign != VAL_BOTTOM ? 0 : (yw - cell->height) / (cell->valign == VAL_MIDDLE ? 2 : 1)), NULL, cell->link_num);				cell->xpos = xp;				cell->ypos = yp;				cell->xw = xw;				cell->yw = yw;				for (yt = 0; yt < p->y; yt++) {					xxpand_lines(t->p, yp + yt);					xxpand_line(t->p, yp + yt, xp + t->w_c[i]);				}				kill_html_stack_item(&html_top);				mem_free(p);			}			cell->xpos = xp;			cell->ypos = yp;			cell->xw = t->w_c[i];			yp += t->r_heights[j];			if (j < t->y - 1) yp += (get_hline_width(t, j + 1) >= 0);		}		if (i < t->x - 1) xp += t->w_c[i] + (get_vline_width(t, i + 1) >= 0);	}	yp = y;	for (j = 0; j < t->y; j++) {		yp += t->r_heights[j];		if (j < t->y - 1) yp += (get_hline_width(t, j + 1) >= 0);	}	*yy = yp + (!!(t->frame & F_ABOVE) + !!(t->frame & F_BELOW)) * !!t->border;}/* !!! FIXME: background */#define draw_frame_point(xx, yy, ii, jj)	\if (H_LINE_X((ii-1), (jj)) >= 0 || H_LINE_X((ii), (jj)) >= 0 || V_LINE_X((ii), (jj-1)) >= 0 || V_LINE_X((ii), (jj)) >= 0) xset_hchar(t->p, (xx), (yy), frame_table[V_LINE((ii),(jj)-1)+3*H_LINE((ii),(jj))+9*H_LINE((ii)-1,(jj))+27*V_LINE((ii),(jj))] | ATTR_FRAME)#define draw_frame_hline(xx, yy, ll, ii, jj)	\if (H_LINE_X((ii), (jj)) >= 0) xset_hchars(t->p, (xx), (yy), (ll), hline_table[H_LINE((ii), (jj))] | ATTR_FRAME)#define draw_frame_vline(xx, yy, ll, ii, jj)	\{						\	int qq;					\	if (V_LINE_X((ii), (jj)) >= 0) for (qq = 0; qq < (ll); qq++) xset_hchar(t->p, (xx), (yy) + qq, vline_table[V_LINE((ii), (jj))] | ATTR_FRAME); }void display_table_frames(struct table *t, int x, int y){	signed char *fh, *fv;	int i, j;	int cx, cy;	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));	memset(fh, -1, (t->x + 2) * (t->y + 1));	fv = mem_alloc((t->x + 1) * (t->y + 2));	memset(fv, -1, (t->x + 1) * (t->y + 2));#ifndef DEBUG#define H_LINE_X(xx, yy) fh[(xx) + 1 + (t->x + 2) * (yy)]#define V_LINE_X(xx, yy) fv[(yy) + 1 + (t->y + 2) * (xx)]#else#define H_LINE_X(xx, yy) (*(xx < -1 || xx > t->x + 1 || yy < 0 || yy > t->y ? (signed char *)NULL : &fh[(xx) + 1 + (t->x + 2) * (yy)]))#define V_LINE_X(xx, yy) (*(xx < 0 || xx > t->x || yy < -1 || yy > t->y + 1 ? (signed char *)NULL : &fv[(yy) + 1 + (t->y + 2) * (xx)]))#endif#define H_LINE(xx, yy) (H_LINE_X((xx), (yy)) == -1 ? 0 : H_LINE_X((xx), (yy)))#define V_LINE(xx, yy) (V_LINE_X((xx), (yy)) == -1 ? 0 : V_LINE_X((xx), (yy)))	for (j = 0; j < t->y; j++) for (i = 0; i < t->x; i++) {		int x, y;		int xsp, ysp;		struct table_cell *cell = CELL(t, i, j);		if (!cell->used || cell->spanned) continue;		if ((xsp = cell->colspan) == 0) xsp = t->x - i;		if ((ysp = cell->rowspan) == 0) ysp = t->y - j;		if (t->rules != R_NONE && t->rules != R_COLS) for (x = 0; x < xsp; x++) {H_LINE_X(i + x, j) = t->cellsp; H_LINE_X(i + x, j + ysp) = t->cellsp;}		if (t->rules != R_NONE && t->rules != R_ROWS) for (y = 0; y < ysp; y++) {V_LINE_X(i, j + y) = t->cellsp; V_LINE_X(i + xsp, j + y) = t->cellsp;}	}	if (t->rules == R_GROUPS) {		for (i = 1; i < t->x; i++) {			if (/*i < t->xc &&*/ t->xcols[i]) continue;			for (j = 0; j < t->y; j++) V_LINE_X(i, j) = 0;		}		for (j = 1; j < t->y; j++) {			for (i = 0; i < t->x; i++) if (CELL(t, i, j)->group) goto c;			for (i = 0; i < t->x; i++) H_LINE_X(i, j) = 0;			c:;		}	}	for (i = 0; i < t->x; i++) {		H_LINE_X(i, 0) = t->border * !!(t->frame & F_ABOVE);		H_LINE_X(i, t->y) = t->border * !!(t->frame & F_BELOW);	}	for (j = 0; j < t->y; j++) {		V_LINE_X(0, j) = t->border * !!(t->frame & F_LHS);		V_LINE_X(t->x, j) = t->border * !!(t->frame & F_RHS);	}	cy = y;	for (j = 0; j <= t->y; j++) {		cx = x;		if ((j > 0 && j < t->y && get_hline_width(t, j) >= 0) || (j == 0 && t->border && (t->frame & F_ABOVE)) || (j == t->y && t->border && (t->frame & F_BELOW))) {			for (i = 0; i < t->x; i++) {				int w;				if (i > 0) w = get_vline_width(t, i);				else w = t->border && (t->frame & F_LHS) ? t->border : -1;				if (w >= 0) {					draw_frame_point(cx, cy, i, j);					if (j < t->y) draw_frame_vline(cx, cy + 1, t->r_heights[j], i, j);					cx++;				}				w = t->w_c[i];				draw_frame_hline(cx, cy, w, i, j);				cx += w;			}			if (t->border && (t->frame & F_RHS)) {				draw_frame_point(cx, cy, i, j);				if (j < t->y) draw_frame_vline(cx, cy + 1, t->r_heights[j], i, j);				cx++;			}			cy++;		} else if (j < t->y) {			for (i = 0; i <= t->x; i++) {				if ((i > 0 && i < t->x && get_vline_width(t, i) >= 0) || (i == 0 && t->border && (t->frame & F_LHS)) || (i == t->x && t->border && (t->frame & F_RHS))) {					draw_frame_vline(cx, cy, t->r_heights[j], i, j);					cx++;				}				if (i < t->x) cx += t->w_c[i];			}		}		if (j < t->y) cy += t->r_heights[j];		/*for (cyy = cy1; cyy < cy; cyy++) xxpand_line(t->p, cyy, cx - 1);*/	}	mem_free(fh);	mem_free(fv);}void format_table(unsigned char *attr, unsigned char *html, unsigned char *eof, unsigned char **end, void *f){	struct part *p = f;	int border, cellsp, vcellpd, cellpd, align;	int frame, rules, width, wf;	struct rgb bgcolor;	struct table *t;	char *al;	int cye;	int x;	int i;	/*int llm = last_link_to_move;*/	struct s_e *bad_html;	int bad_html_n;	struct node *n, *nn;	int cpd_pass, cpd_width, cpd_last;	/*if (!p->data) {		debug("nested tables not supported");		return;	}*/	table_level++;	memcpy(&bgcolor, &par_format.bgcolor, sizeof(struct rgb));	get_bgcolor(attr, &bgcolor);	if ((border = get_num(attr, "border")) == -1) border = has_attr(attr, "border") || has_attr(attr, "rules") || has_attr(attr, "frame");	/*if (!border) border = 1;*/	if ((cellsp = get_num(attr, "cellspacing")) == -1) cellsp = 1;	if ((cellpd = get_num(attr, "cellpadding")) == -1) {		vcellpd = 0;		cellpd = !!border;	} else {		vcellpd = cellpd >= HTML_CHAR_HEIGHT / 2 + 1;		cellpd = cellpd >= HTML_CHAR_WIDTH / 2 + 1;	}	if (!border) cellsp = 0;	else if (!cellsp) cellsp = 1;	if (border > 2) border = 2;	if (cellsp > 2) cellsp = 2;	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", p->data || p->xp)) == -1) {		width = par_format.width - par_format.leftmargin - par_format.rightmargin;		if (width < 0) width = 0;		wf = 1;	}	if (!(t = parse_table(html, eof, end, &bgcolor, p->data || p->xp, &bad_html, &bad_html_n))) {		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, p, NULL);	}	mem_free(bad_html);	html_stack_dup();	html_top.dontkill = 1;	par_format.align = AL_LEFT;	t->p = p;	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 (!p->data && !p->xp) {		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 > p->xmax) p->xmax = t->max_t + par_format.leftmargin + par_format.rightmargin;		if (t->min_t + par_format.leftmargin + par_format.rightmargin > p->x) p->x = t->min_t + par_format.leftmargin + par_format.rightmargin;		goto ret2;	}	if (!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 (!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	check_table_widths(t);#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);*/	get_table_heights(t);	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);	/*sdbg(p->data);*/	/*for (y = p->cy; y < cye; y++) {		last_link_to_move = llm;		align_line(p, y);	}*/	/*if (p->cy + t->rh != cye) internal("size does not match; 1:%d, 2:%d", p->cy + t->rh, cye);*/	p->cy = cye;	p->cx = -1;	ret2:	p->link_num = t->link_num;	if (p->cy > p->y) p->y = p->cy;	/*ret1:*/	free_table(t);	kill_html_stack_item(&html_top);	ret0:	/*ret:*/	table_level--;	if (!table_level) free_table_cache();}

⌨️ 快捷键说明

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