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

📄 tables.c

📁 一个很有名的浏览器
💻 C
📖 第 1 页 / 共 3 页
字号:
		 * whole cell width. */		expand_lines(table->part, x + width - 1, y, height, cell->bgcolor);		if (cell->fragment_id)			add_fragment_identifier(part, cell->fragment_id);	}	done_html_parser_state(state);	if (part) mem_free(part);}static voiddraw_table_cells(struct table *table, int x, int y){	int col, row;	int xp;	color_t bgcolor = par_format.bgcolor;	struct table_frames table_frames;	get_table_frames(table, &table_frames);	if (table->fragment_id)		add_fragment_identifier(table->part, table->fragment_id);	/* Expand using the background color of the ``parent context'' all the	 * way down the start of the left edge of the table. */	expand_lines(table->part, x - 1, y, table->real_height, bgcolor);	xp = x + table_frames.left;	for (col = 0; col < table->cols; col++) {		int yp = y + table_frames.top;		for (row = 0; row < table->rows; row++) {			int row_height = table->rows_heights[row] +				(row < table->rows - 1 && has_hline_width(table, row + 1));			draw_table_cell(table, col, row, xp, yp);			yp += row_height;		}		if (col < table->cols - 1) {			xp += table->cols_widths[col] + has_vline_width(table, col + 1);		}	}	/* Finish the table drawing by aligning the right and bottom edge of	 * the table */	x += table->real_width - 1;	expand_lines(table->part, x, y, table->real_height, table->bgcolor);	/* Tables are renderer column-wise which breaks forms where the	 * form items appears in a column before the actual form tag is	 * parsed. Consider the folloing example:	 *	 *	+--------+--------+	Where cell 2 has a <form>-tag	 *	| cell 1 | cell 2 |	and cell 3 has an <input>-tag.	 *	+--------+--------+	 *	| cell 3 | cell 4 |	The table is rendered by drawing	 *	+--------+--------+	the cells in the order: 1, 3, 2, 4.	 *	 * That is the <input>-tag form-item is added before the <form>-tag,	 * which means a ``dummy'' form to hold it is added too.	 * Calling check_html_form_hierarchy() will join the the form-item	 * to the correct form from cell 2. */	check_html_form_hierarchy(table->part);	/* Do a sanity check whether the height is correct */	check_table_height(table, &table_frames, y);}static inline intget_frame_pos(int a, int a_size, int b, int b_size){	assert(a >= -1 || a < a_size + 2 || b >= 0 || b <= b_size);	if_assert_failed return 0;	return a + 1 + (a_size + 2) * b;}#define H_FRAME_POSITION(table, col, row) frame[0][get_frame_pos(col, (table)->cols, row, (table)->rows)]#define V_FRAME_POSITION(table, col, row) frame[1][get_frame_pos(row, (table)->rows, col, (table)->cols)]static inline voiddraw_frame_point(struct table *table, signed char *frame[2], int x, int y,		 int col, int row){	/* TODO: Use /BORDER._.* / macros ! --pasky */	static unsigned char const border_chars[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,	};	/* Note: I have no clue wether any of these names are suitable but they	 * should give an idea of what is going on. --jonas */	signed char left   = H_FRAME_POSITION(table, col - 1,     row);	signed char right  = H_FRAME_POSITION(table,     col,     row);	signed char top    = V_FRAME_POSITION(table,     col, row - 1);	signed char bottom = V_FRAME_POSITION(table,     col,     row);	int pos;	if (left < 0 && right < 0 && top < 0 && bottom < 0) return;	pos =      int_max(top,    0)	    +  3 * int_max(right,  0)	    +  9 * int_max(left,   0)	    + 27 * int_max(bottom, 0);	draw_frame_hchars(table->part, x, y, 1, border_chars[pos],			  par_format.bgcolor, table->bordercolor);}static inline voiddraw_frame_hline(struct table *table, signed char *frame[2], int x, int y,		 int col, int row){	static unsigned char const hltable[] = { ' ', BORDER_SHLINE, BORDER_DHLINE };	int pos = H_FRAME_POSITION(table, col, row);	assertm(pos < 3, "Horizontal table position out of bound [%d]", pos);	if_assert_failed return;	if (pos < 0 || table->cols_widths[col] <= 0) return;	draw_frame_hchars(table->part, x, y, table->cols_widths[col], hltable[pos],			  par_format.bgcolor, table->bordercolor);}static inline voiddraw_frame_vline(struct table *table, signed char *frame[2], int x, int y,		 int col, int row){	static unsigned char const vltable[] = { ' ', BORDER_SVLINE, BORDER_DVLINE };	int pos = V_FRAME_POSITION(table, col, row);	assertm(pos < 3, "Vertical table position out of bound [%d]", pos);	if_assert_failed return;	if (pos < 0 || table->rows_heights[row] <= 0) return;	draw_frame_vchars(table->part, x, y, table->rows_heights[row], vltable[pos],			  par_format.bgcolor, table->bordercolor);}static inline inttable_row_has_group(struct table *table, int row){	int col;	for (col = 0; col < table->cols; col++)		if (CELL(table, col, row)->is_group)			return 1;	return 0;}static voidinit_table_rules(struct table *table, signed char *frame[2]){	int col, row;	for (row = 0; row < table->rows; row++) for (col = 0; col < table->cols; col++) {		int xsp, ysp;		struct table_cell *cell = CELL(table, col, row);		if (!cell->is_used || cell->is_spanned) continue;		xsp = cell->colspan ? cell->colspan : table->cols - col;		ysp = cell->rowspan ? cell->rowspan : table->rows - row;		if (table->rules != TABLE_RULE_COLS) {			memset(&H_FRAME_POSITION(table, col, row), table->cellspacing, xsp);			memset(&H_FRAME_POSITION(table, col, row + ysp), table->cellspacing, xsp);		}		if (table->rules != TABLE_RULE_ROWS) {			memset(&V_FRAME_POSITION(table, col, row), table->cellspacing, ysp);			memset(&V_FRAME_POSITION(table, col + xsp, row), table->cellspacing, ysp);		}	}	if (table->rules == TABLE_RULE_GROUPS) {		for (col = 1; col < table->cols; col++) {			if (table->cols_x[col])				continue;			memset(&V_FRAME_POSITION(table, col, 0), 0, table->rows);		}		for (row = 1; row < table->rows; row++) {			if (table_row_has_group(table, row))				continue;			memset(&H_FRAME_POSITION(table, 0, row), 0, table->cols);		}	}}static voiddraw_table_frames(struct table *table, int indent, int y){	struct table_frames table_frames;	signed char *frame[2];	int col, row;	int cx, cy;	int fh_size = (table->cols + 2) * (table->rows + 1);	int fv_size = (table->cols + 1) * (table->rows + 2);	frame[0] = fmem_alloc(fh_size + fv_size);	if (!frame[0]) return;	memset(frame[0], -1, fh_size + fv_size);	frame[1] = &frame[0][fh_size];	if (table->rules != TABLE_RULE_NONE)		init_table_rules(table, frame);	get_table_frames(table, &table_frames);	memset(&H_FRAME_POSITION(table, 0, 0), table_frames.top, table->cols);	memset(&H_FRAME_POSITION(table, 0, table->rows), table_frames.bottom, table->cols);	memset(&V_FRAME_POSITION(table, 0, 0), table_frames.left, table->rows);	memset(&V_FRAME_POSITION(table, table->cols, 0), table_frames.right, table->rows);	cy = y;	for (row = 0; row <= table->rows; row++) {		cx = indent;		if ((row > 0 && row < table->rows && has_hline_width(table, row))		    || (row == 0 && table_frames.top)		    || (row == table->rows && table_frames.bottom)) {			int w = table_frames.left ? table->border : -1;			for (col = 0; col < table->cols; col++) {				if (col > 0)					w = get_vline_width(table, col);				if (w >= 0) {					draw_frame_point(table, frame, cx, cy, col, row);					if (row < table->rows)						draw_frame_vline(table, frame, cx, cy + 1, col, row);					cx++;				}				draw_frame_hline(table, frame, cx, cy, col, row);				cx += table->cols_widths[col];			}			if (table_frames.right) {				draw_frame_point(table, frame, cx, cy, col, row);				if (row < table->rows)					draw_frame_vline(table, frame, cx, cy + 1, col, row);				cx++;			}			cy++;		} else if (row < table->rows) {			for (col = 0; col <= table->cols; col++) {				if ((col > 0 && col < table->cols && has_vline_width(table, col))				    || (col == 0 && table_frames.left)				    || (col == table->cols && table_frames.right)) {					draw_frame_vline(table, frame, cx, cy, col, row);					cx++;				}				if (col < table->cols) cx += table->cols_widths[col];			}		}		if (row < table->rows) cy += table->rows_heights[row];	}	fmem_free(frame[0]);}static voiddraw_table_caption(struct table *table, int x, int y){	unsigned char *start = table->caption.start;	unsigned char *end = table->caption.end;	struct part *part;	if (!start || !end) return;	while (start < end && isspace(*start))		start++;	while (start < end && isspace(end[-1]))		end--;	if (start >= end) return;	part = format_html_part(start, end, table->align,		0, table->real_width, table->part->document, x, y,		NULL, table->link_num);	if (part) {		table->part->cy += part->box.height;		table->part->cx = -1;		table->part->link_num = part->link_num;		mem_free(part);	}}/* This renders tag soup elements that the parser detected while chewing it's * way through the table HTML. */static voiddraw_table_bad_html(struct table *table){	int i;	for (i = 0; i < table->bad_html_size; i++) {		struct html_start_end *html = &table->bad_html[i];		unsigned char *start = html->start;		unsigned char *end = html->end;		while (start < end && isspace(*start))			start++;		while (start < end && isspace(end[-1]))			end--;		if (start >= end) continue;		parse_html(start, end, table->part, NULL);	}}voidformat_table(unsigned char *attr, unsigned char *html, unsigned char *eof,	     unsigned char **end, struct part *part){	struct table *table;	struct node *node, *new_node;	struct html_element *state;	int indent, margins;	html_context.table_level++;	table = parse_table(html, eof, end, attr, (part->document || part->box.x));	if (!table) goto ret0;	table->part = part;	/* XXX: This tag soup handling needs to be done outside the create	 * parser state. Something to do with link numbering. */	/* It needs to be done _before_ processing the actual table, too.	 * Otherwise i.e. <form> tags between <table> and <tr> are broken. */	draw_table_bad_html(table);	state = init_html_parser_state(ELEMENT_DONT_KILL, ALIGN_LEFT, 0, 0);	margins = par_format.leftmargin + par_format.rightmargin;	if (get_table_cellpadding(table)) goto ret2;	/* DBG("%d %d %d", t->min_width, t->max_width, table->width); */	if (table->min_width >= table->width)		distribute_widths(table, table->min_width);	else if (table->max_width < table->width && table->full_width)		distribute_widths(table, table->max_width);	else		distribute_widths(table, table->width);	if (!part->document && part->box.x == 1) {		int total_width = table->real_width + margins;		int_bounds(&total_width, table->real_width, par_format.width);		int_lower_bound(&part->box.width, total_width);		part->cy += table->real_height;		goto ret2;	}#ifdef HTML_TABLE_2ND_PASS	check_table_widths(table);#endif	get_table_heights(table);	if (!part->document) {		int_lower_bound(&part->box.width, table->real_width + margins);		part->cy += table->real_height;		goto ret2;	}	node = part->document->nodes.next;	node->box.height = part->box.y - node->box.y + part->cy;	indent = get_table_indent(table);	/* FIXME: See bug 432. It should be possible to align the caption at	 * the top, bottom or the sides. */	draw_table_caption(table, indent + part->box.x, part->box.y + part->cy);	draw_table_cells(table, indent, part->cy);	draw_table_frames(table, indent, part->cy);	part->cy += table->real_height;	part->cx = -1;	new_node = mem_alloc(sizeof(*new_node));	if (new_node) {		set_box(&new_node->box, node->box.x, part->box.y + part->cy,			node->box.width, 0);		add_to_list(part->document->nodes, new_node);	}ret2:	part->link_num = table->link_num;	int_lower_bound(&part->box.height, part->cy);	html_context.part = part; /* Might've changed in draw_table_cells(). */	done_html_parser_state(state);	free_table(table);ret0:	html_context.table_level--;	if (!html_context.table_level) free_table_cache();}

⌨️ 快捷键说明

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