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

📄 tables.c

📁 elinks下lynx是最重要的二个文本浏览器, 在linux下非常实用, elinks也是gentoo安装过程中默认使用的浏览器, 这是elinks源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	if (table->fragment_id)		add_fragment_identifier(html_context, 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(html_context, 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, html_context);			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(html_context, 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, struct html_context *html_context){	static enum border_char const border_chars[81] = {		BORDER_NONE,		BORDER_SVLINE,		BORDER_DVLINE,		BORDER_SHLINE,		BORDER_SDLCORNER,	BORDER_DSDLCORNER,		BORDER_DHLINE,		BORDER_SDDLCORNER,	BORDER_DDLCORNER,		BORDER_SHLINE,		BORDER_SDRCORNER,	BORDER_DSDRCORNER,		BORDER_SHLINE,		BORDER_SUTEE,		BORDER_DSUTEE,		BORDER_DHLINE,		BORDER_SDDLCORNER,	BORDER_DDLCORNER,		BORDER_DHLINE,		BORDER_SDDRCORNER,	BORDER_DDRCORNER,		BORDER_DHLINE,		BORDER_SDDRCORNER,	BORDER_DDRCORNER,		BORDER_DHLINE,		BORDER_SDUTEE,		BORDER_DUTEE,		BORDER_SVLINE,		BORDER_SVLINE,		BORDER_DVLINE,		BORDER_SULCORNER,	BORDER_SRTEE,		BORDER_DSDLCORNER,		BORDER_SDULCORNER,	BORDER_SDRTEE,		BORDER_DDLCORNER,		BORDER_SURCORNER,	BORDER_SLTEE,		BORDER_DSDRCORNER,		BORDER_SDTEE,		BORDER_SCROSS,		BORDER_DSUTEE,		BORDER_SDULCORNER,	BORDER_SDRTEE,		BORDER_DDLCORNER,		BORDER_SDURCORNER,	BORDER_SDLTEE,		BORDER_DDRCORNER,		BORDER_SDURCORNER,	BORDER_SDLTEE,		BORDER_DDRCORNER,		BORDER_SDDTEE,		BORDER_SDCROSS,		BORDER_DUTEE,		BORDER_DVLINE,		BORDER_DVLINE,		BORDER_DVLINE,		BORDER_DSULCORNER,	BORDER_DSULCORNER,	BORDER_DSRTEE,		BORDER_DULCORNER,	BORDER_DULCORNER,	BORDER_DRTEE,		BORDER_DSURCORNER,	BORDER_DSURCORNER,	BORDER_DSLTEE,		BORDER_DSDTEE,		BORDER_DSDTEE,		BORDER_DSCROSS,		BORDER_DULCORNER,	BORDER_DULCORNER,	BORDER_DRTEE,		BORDER_DURCORNER,	BORDER_DURCORNER,	BORDER_DLTEE,		BORDER_DURCORNER,	BORDER_DURCORNER,	BORDER_DLTEE,		BORDER_DDTEE,		BORDER_DDTEE,		BORDER_DCROSS,	};	/* 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, html_context);}static inline voiddraw_frame_hline(struct table *table, signed char *frame[2], int x, int y,		 int col, int row, struct html_context *html_context){	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, html_context);}static inline voiddraw_frame_vline(struct table *table, signed char *frame[2], int x, int y,		 int col, int row, struct html_context *html_context){	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, html_context);}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 html_context *html_context){	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,					                 html_context);					if (row < table->rows)						draw_frame_vline(table, frame, cx, cy + 1, col, row, html_context);					cx++;				}				draw_frame_hline(table, frame, cx, cy, col, row,				                 html_context);				cx += table->cols_widths[col];			}			if (table_frames.right) {				draw_frame_point(table, frame, cx, cy, col, row,				                 html_context);				if (row < table->rows)					draw_frame_vline(table, frame, cx, cy + 1, col, row, html_context);				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, html_context);					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 html_context *html_context, 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(html_context, start, end, table->align,		0, table->real_width, table->part->document, x, y,		NULL, table->link_num);	if (!part) return;	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 html_context *html_context, 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, html_context);	}}static voiddistribute_table_widths(struct table *table){	int width = table->width;	if (table->min_width >= width)		width = table->min_width;	else if (table->max_width < width && table->full_width)		width = table->max_width;	distribute_widths(table, width);}voidformat_table(unsigned char *attr, unsigned char *html, unsigned char *eof,	     unsigned char **end, struct html_context *html_context){	struct part *part = html_context->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),	                    html_context);	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(html_context, table);	state = init_html_parser_state(html_context, ELEMENT_DONT_KILL,	                               ALIGN_LEFT, 0, 0);	margins = par_format.leftmargin + par_format.rightmargin;	if (get_table_cellpadding(html_context, table)) goto ret2;	distribute_table_widths(table);	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(html_context, table);#endif	get_table_heights(html_context, 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(html_context, table);	/* FIXME: See bug 432. It should be possible to align the caption at	 * the top, bottom or the sides. */	draw_table_caption(html_context, table, indent + part->box.x, part->box.y + part->cy);	draw_table_cells(table, indent, part->cy, html_context);	draw_table_frames(table, indent, part->cy, html_context);	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(html_context, 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 + -