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

📄 renderer.c

📁 一个很有名的浏览器
💻 C
📖 第 1 页 / 共 2 页
字号:
	link->type = LINK_HYPERTEXT;	link->where = where;	link->color.background = document->options.default_bg;	link->color.foreground = fgcolor;	init_template(&template, link->color.background, link->color.foreground);	render_dom_text(renderer, &template, string, length);	for (point = link->points; length > 0; length--, point++, x++) {		point->x = x;		point->y = y;	}	document->nlinks++;	return link;}/* DOM Tree Renderer */#ifdef DOM_TREE_RENDERERstatic struct dom_node *render_dom_tree(struct dom_navigator *navigator, struct dom_node *node, void *data){	struct dom_renderer *renderer = navigator->data;	struct screen_char *template = &renderer->styles[node->type];	unsigned char *name, *value;	assert(node && renderer);	name  = get_dom_node_name(node);	value = memacpy(node->string, node->length);	render_dom_printf(renderer, template, "%-16s: %s\n", name, value);	if (name) mem_free(name);	if (value) mem_free(value);	return node;}static struct dom_node *render_dom_tree_id_leaf(struct dom_navigator *navigator, struct dom_node *node, void *data){	struct dom_renderer *renderer = navigator->data;	struct document *document = renderer->document;	struct screen_char *template = &renderer->styles[node->type];	unsigned char *name, *value, *id;	assert(node && document);	name	= get_dom_node_name(node);	value	= get_dom_node_value(node);	id	= get_dom_node_type_name(node->type);	renderer->canvas_x += navigator->depth;	render_dom_printf(renderer, template, "%-16s: %s -> %s\n", id, name, value);	if (name) mem_free(name);	if (value) mem_free(value);	return node;}static struct dom_node *render_dom_tree_leaf(struct dom_navigator *navigator, struct dom_node *node, void *data){	struct dom_renderer *renderer = navigator->data;	struct document *document = renderer->document;	struct screen_char *template = &renderer->styles[node->type];	unsigned char *name, *value;	assert(node && document);	name	= get_dom_node_name(node);	value	= get_dom_node_value(node);	renderer->canvas_x += navigator->depth;	render_dom_printf(renderer, template, "%-16s: %s\n", name, value);	if (name) mem_free(name);	if (value) mem_free(value);	return node;}static struct dom_node *render_dom_tree_branch(struct dom_navigator *navigator, struct dom_node *node, void *data){	struct dom_renderer *renderer = navigator->data;	struct document *document = renderer->document;	struct screen_char *template = &renderer->styles[node->type];	unsigned char *name, *id;	assert(node && document);	name	= get_dom_node_name(node);	id	= get_dom_node_type_name(node->type);	renderer->canvas_x += navigator->depth;	render_dom_printf(renderer, template, "%-16s: %s\n", id, name);	if (name) mem_free(name);	return node;}static dom_navigator_callback_T dom_tree_renderer_callbacks[DOM_NODES] = {	/*				*/ NULL,	/* DOM_NODE_ELEMENT		*/ render_dom_tree_branch,	/* DOM_NODE_ATTRIBUTE		*/ render_dom_tree_id_leaf,	/* DOM_NODE_TEXT		*/ render_dom_tree_leaf,	/* DOM_NODE_CDATA_SECTION	*/ render_dom_tree_id_leaf,	/* DOM_NODE_ENTITY_REFERENCE	*/ render_dom_tree_id_leaf,	/* DOM_NODE_ENTITY		*/ render_dom_tree_id_leaf,	/* DOM_NODE_PROC_INSTRUCTION	*/ render_dom_tree_id_leaf,	/* DOM_NODE_COMMENT		*/ render_dom_tree_leaf,	/* DOM_NODE_DOCUMENT		*/ render_dom_tree,	/* DOM_NODE_DOCUMENT_TYPE	*/ render_dom_tree_id_leaf,	/* DOM_NODE_DOCUMENT_FRAGMENT	*/ render_dom_tree_id_leaf,	/* DOM_NODE_NOTATION		*/ render_dom_tree_id_leaf,};#endif /* DOM_TREE_RENDERER *//* DOM Source Renderer */#define check_dom_node_source(renderer, str, len)	\	((renderer)->source <= (str) && (str) + (len) <= (renderer)->end)#define assert_source(renderer, str, len) \	assertm(check_dom_node_source(renderer, str, len), "renderer[%p : %p] str[%p : %p]", \		(renderer)->source, (renderer)->end, (str), (str) + (len))static inline voidrender_dom_flush(struct dom_renderer *renderer, unsigned char *string){	struct screen_char *template = &renderer->styles[DOM_NODE_TEXT];	int length = string - renderer->position;	assert_source(renderer, renderer->position, 0);	assert_source(renderer, string, 0);	if (length <= 0) return;	render_dom_text(renderer, template, renderer->position, length);	renderer->position = string;	assert_source(renderer, renderer->position, 0);}static inline voidrender_dom_node_text(struct dom_renderer *renderer, struct screen_char *template,		     struct dom_node *node){	unsigned char *string = node->string;	int length = node->length;	if (node->type == DOM_NODE_ENTITY_REFERENCE) {		string -= 1;		length += 2;	}	if (check_dom_node_source(renderer, string, length)) {		render_dom_flush(renderer, string);		renderer->position = string + length;		assert_source(renderer, renderer->position, 0);	}	render_dom_text(renderer, template, string, length);}static struct dom_node *render_dom_node_source(struct dom_navigator *navigator, struct dom_node *node, void *data){	struct dom_renderer *renderer = navigator->data;	assert(node && renderer && renderer->document);	/* TODO: For (atleast) text, CDATA section and comment nodes check	 * for URIs ala document->options.plain_display_links */	render_dom_node_text(renderer, &renderer->styles[node->type], node);	return node;}static struct dom_node *render_dom_proc_instr_source(struct dom_navigator *navigator, struct dom_node *node, void *data){	struct dom_renderer *renderer = navigator->data;	unsigned char *value;	int valuelen;	assert(node && renderer && renderer->document);	render_dom_node_text(renderer, &renderer->styles[node->type], node);	value	 = node->data.proc_instruction.instruction;	valuelen = node->data.proc_instruction.instructionlen;	if (!value || node->data.proc_instruction.map)		return node;	if (check_dom_node_source(renderer, node->string, node->length)) {		render_dom_flush(renderer, value);		renderer->position = value + valuelen;	}	render_dom_text(renderer, &renderer->styles[DOM_NODE_ATTRIBUTE], value, valuelen);	return node;}static struct dom_node *render_dom_element_source(struct dom_navigator *navigator, struct dom_node *node, void *data){	struct dom_renderer *renderer = navigator->data;	assert(node && renderer && renderer->document);	render_dom_node_text(renderer, &renderer->styles[node->type], node);	return node;}static struct dom_node *render_dom_attribute_source(struct dom_navigator *navigator, struct dom_node *node, void *data){	struct dom_navigator_state *state = get_dom_navigator_parent(navigator);	struct dom_renderer *renderer = navigator->data;	struct screen_char *template = &renderer->styles[node->type];	struct dom_node *attribute = NULL;	int i;	assert(node && renderer->document);	assert(state && state->list);	/* The attributes are sorted but we want them in the original order */	foreach_dom_node(i, node, state->list) {		if (node->string >= renderer->position		    && (!attribute || node->string < attribute->string))			attribute = node;	}	assert(attribute);	node = attribute;	render_dom_node_text(renderer, template, node);	if (node->data.attribute.value) {		int quoted = node->data.attribute.quoted == 1;		unsigned char *value = node->data.attribute.value - quoted;		int valuelen = node->data.attribute.valuelen + quoted * 2;		if (check_dom_node_source(renderer, value, 0)) {			render_dom_flush(renderer, value);			renderer->position = value + valuelen;			assert_source(renderer, renderer->position, 0);		}		if (node->data.attribute.reference		    && valuelen - quoted * 2 > 0) {			int skips;			/* Need to flush the first quoting delimiter and any			 * leading whitespace so that the renderers x position			 * is at the start of the value string. */			for (skips = 0; skips < valuelen; skips++) {				if ((quoted && skips == 0)				    || isspace(value[skips])				    || value[skips] < ' ')					continue;				break;			}			if (skips > 0) {				render_dom_text(renderer, template, value, skips);				value    += skips;				valuelen -= skips;			}			/* Figure out what should be skipped after the actual			 * link text. */			for (skips = 0; skips < valuelen; skips++) {				if ((quoted && skips == 0)				    || isspace(value[valuelen - skips - 1])				    || value[valuelen - skips - 1] < ' ')					continue;				break;			}			add_dom_link(renderer, value, valuelen - skips);			if (skips > 0) {				value += valuelen - skips;				render_dom_text(renderer, template, value, skips);			}		} else {			render_dom_text(renderer, template, value, valuelen);		}	}	return node;}static dom_navigator_callback_T dom_source_renderer_callbacks[DOM_NODES] = {	/*				*/ NULL,	/* DOM_NODE_ELEMENT		*/ render_dom_element_source,	/* DOM_NODE_ATTRIBUTE		*/ render_dom_attribute_source,	/* DOM_NODE_TEXT		*/ render_dom_node_source,	/* DOM_NODE_CDATA_SECTION	*/ render_dom_node_source,	/* DOM_NODE_ENTITY_REFERENCE	*/ render_dom_node_source,	/* DOM_NODE_ENTITY		*/ render_dom_node_source,	/* DOM_NODE_PROC_INSTRUCTION	*/ render_dom_proc_instr_source,	/* DOM_NODE_COMMENT		*/ render_dom_node_source,	/* DOM_NODE_DOCUMENT		*/ NULL,	/* DOM_NODE_DOCUMENT_TYPE	*/ render_dom_node_source,	/* DOM_NODE_DOCUMENT_FRAGMENT	*/ render_dom_node_source,	/* DOM_NODE_NOTATION		*/ render_dom_node_source,};/* Shared multiplexor between renderers */voidrender_dom_document(struct cache_entry *cached, struct document *document,		    struct string *buffer){	unsigned char *head = empty_string_or_(cached->head);	struct dom_node *root = parse_sgml(cached, document, buffer);	struct dom_renderer renderer;	struct conv_table *convert_table;	dom_navigator_callback_T *callbacks = dom_source_renderer_callbacks;	struct dom_navigator navigator;	assert(document->options.plain);	if (!root) return;	convert_table = get_convert_table(head, document->options.cp,					  document->options.assume_cp,					  &document->cp,					  &document->cp_status,					  document->options.hard_assume);	init_dom_renderer(&renderer, document, buffer, root, convert_table);	init_dom_navigator(&navigator, &renderer, callbacks, 0);	document->bgcolor = global_doc_opts->default_bg;	walk_dom_nodes(&navigator, root);	/* If there are no non-element nodes after the last element node make	 * sure that we flush to the end of the cache entry source including	 * the '>' of the last element tag if it has one. (bug 519) */	if (check_dom_node_source(&renderer, renderer.position, 0)) {		render_dom_flush(&renderer, renderer.end);	}	done_dom_node(root);	done_dom_navigator(&navigator);}

⌨️ 快捷键说明

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