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

📄 renderer.c

📁 一个很有名的浏览器
💻 C
📖 第 1 页 / 共 2 页
字号:
/* DOM document renderer *//* $Id: renderer.c,v 1.17.2.4 2005/05/01 21:09:35 jonas Exp $ */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <string.h>#include "elinks.h"#include "bookmarks/bookmarks.h"	/* get_bookmark() */#include "cache/cache.h"#include "document/css/css.h"#include "document/css/parser.h"#include "document/css/property.h"#include "document/css/stylesheet.h"#include "document/docdata.h"#include "document/document.h"#include "document/dom/navigator.h"#include "document/dom/node.h"#include "document/dom/renderer.h"#include "document/renderer.h"#include "document/sgml/parser.h"#include "intl/charsets.h"#include "globhist/globhist.h"		/* get_global_history_item() */#include "protocol/uri.h"#include "terminal/draw.h"#include "util/box.h"#include "util/error.h"#include "util/memory.h"#include "util/snprintf.h"#include "util/string.h"struct dom_renderer {	struct document *document;	struct conv_table *convert_table;	enum convert_string_mode convert_mode;	struct dom_node *root;	unsigned char *source;	unsigned char *end;	unsigned char *position;	int canvas_x, canvas_y;	struct screen_char styles[DOM_NODES];};static voidinit_template(struct screen_char *template, color_t background, color_t foreground){	struct color_pair colors = INIT_COLOR_PAIR(background, foreground);	template->attr = 0;	template->data = ' ';	set_term_color(template, &colors, global_doc_opts->color_flags, global_doc_opts->color_mode);}static inline struct css_property *get_css_property(struct list_head *list, enum css_property_type type){	struct css_property *property;	foreach (property, *list)		if (property->type == type)			return property;	return NULL;}/* Checks the user CSS for properties for each DOM node type name */static inline voidinit_dom_renderer(struct dom_renderer *renderer, struct document *document,		  struct string *buffer, struct dom_node *root,		  struct conv_table *convert_table){	enum dom_node_type type;	struct css_stylesheet *css = &default_stylesheet;	memset(renderer, 0, sizeof(*renderer));	renderer->document	= document;	renderer->convert_table = convert_table;	renderer->convert_mode	= document->options.plain ? CSM_NONE : CSM_DEFAULT;	renderer->root		= root;	renderer->source	= buffer->source;	renderer->end		= buffer->source + buffer->length;	renderer->position	= renderer->source;	for (type = 0; type < DOM_NODES; type++) {		struct screen_char *template = &renderer->styles[type];		color_t background = global_doc_opts->default_bg;		color_t foreground = global_doc_opts->default_fg;		static int i_want_struct_module_for_dom;		unsigned char *name = get_dom_node_type_name(type);		int namelen = name ? strlen(name) : 0;		struct css_selector *selector = NULL;		if (!i_want_struct_module_for_dom) {			static const unsigned char default_colors[] =				"document	{ color: yellow } "				"element	{ color: lightgreen } "				"entity-reference { color: red } "				"proc-instruction { color: red } "				"attribute	{ color: magenta } "				"comment	{ color: aqua } ";			unsigned char *styles = (unsigned char *) default_colors;			i_want_struct_module_for_dom = 1;			/* When someone will get here earlier than at 4am,			 * this will be done in some init function, perhaps			 * not overriding the user's default stylesheet. */			css_parse_stylesheet(css, NULL, styles, styles + sizeof(default_colors) + 1);		}		if (name)			selector = find_css_selector(&css->selectors,						     CST_ELEMENT, CSR_ROOT,						     name, namelen);		if (selector) {			struct list_head *properties = &selector->properties;			struct css_property *property;			property = get_css_property(properties, CSS_PT_BACKGROUND_COLOR);			if (!property)				property = get_css_property(properties, CSS_PT_BACKGROUND);			if (property && property->value_type == CSS_VT_COLOR)				background = property->value.color;			property = get_css_property(properties, CSS_PT_COLOR);			if (property) foreground = property->value.color;		}		init_template(template, background, foreground);	}}/* Document maintainance */static struct screen_char *realloc_line(struct document *document, int x, int y){	struct line *line = realloc_lines(document, y);	if (!line) return NULL;	if (x > line->length) {		if (!ALIGN_LINE(&line->chars, line->length, x))			return NULL;		for (; line->length < x; line->length++) {			line->chars[line->length].data = ' ';		}		if (x > document->width) document->width = x;	}	return line->chars;}static struct node *add_search_node(struct dom_renderer *renderer, int width){	struct node *node = mem_alloc(sizeof(*node));	if (node) {		set_box(&node->box, renderer->canvas_x, renderer->canvas_y,			width, 1);		add_to_list(renderer->document->nodes, node);	}	return node;}#define X(renderer)		((renderer)->canvas_x)#define Y(renderer)		((renderer)->canvas_y)#define POS(renderer)		(&(renderer)->document->data[Y(renderer)].chars[X(renderer)])#define WIDTH(renderer, add)	((renderer)->canvas_x + (add))static voidrender_dom_line(struct dom_renderer *renderer, struct screen_char *template,		unsigned char *string, int length){	struct document *document = renderer->document;	struct conv_table *convert = renderer->convert_table;	enum convert_string_mode mode = renderer->convert_mode;	int x;	assert(renderer && template && string && length);	string = convert_string(convert, string, length, mode, &length, NULL, NULL);	if (!string) return;	if (!realloc_line(document, WIDTH(renderer, length), Y(renderer))) {		mem_free(string);		return;	}	add_search_node(renderer, length);	for (x = 0; x < length; x++, renderer->canvas_x++) {		unsigned char data = string[x];		/* This is mostly to be able to break out so the indentation		 * level won't get to high. */		switch (data) {		case ASCII_TAB:		{			int tab_width = 7 - (X(renderer) & 7);			int width = WIDTH(renderer, length - x + tab_width);			template->data = ' ';			if (!realloc_line(document, width, Y(renderer)))				break;			/* Only loop over the expanded tab chars and let the			 * ``main loop'' add the actual tab char. */			for (; tab_width-- > 0; renderer->canvas_x++)				copy_screen_chars(POS(renderer), template, 1);			break;		}		default:			template->data = isscreensafe(data) ? data : '.';		}		copy_screen_chars(POS(renderer), template, 1);	}	mem_free(string);}static inline unsigned char *split_dom_line(unsigned char *line, int length, int *linelen){	unsigned char *end = line + length;	unsigned char *pos;	/* End of line detection.	 * We handle \r, \r\n and \n types here. */	for (pos = line; pos < end; pos++) {		int step = 0;		if (pos[step] == ASCII_CR)			step++;		if (pos[step] == ASCII_LF)			step++;		if (step) {			*linelen = pos - line;			return pos + step;		}	}	*linelen = length;	return NULL;}static voidrender_dom_text(struct dom_renderer *renderer, struct screen_char *template,		unsigned char *string, int length){	int linelen;	for (; length > 0; string += linelen, length -= linelen) {		unsigned char *newline = split_dom_line(string, length, &linelen);		if (linelen)			render_dom_line(renderer, template, string, linelen);		if (newline) {			renderer->canvas_y++;			renderer->canvas_x = 0;			linelen = newline - string;		}	}}#ifdef DOM_TREE_RENDERERstatic voidrender_dom_printf(struct dom_renderer *renderer, struct screen_char *template,		  unsigned char *format, ...){	unsigned char *text;	int textlen;	va_list ap, ap2;	va_start(ap, format);	VA_COPY(ap2, ap);	textlen = vsnprintf(NULL, 0, format, ap2);	text = mem_alloc(textlen + 1);	if (!text) goto free_va_args;	if (vsnprintf((char *) text, textlen + 1, format, ap) == textlen)		render_dom_text(renderer, template, text, textlen);	mem_free(text);free_va_args:	va_end(ap);}#endif /* DOM_TREE_RENDERER */#define realloc_document_links(doc, size) \	ALIGN_LINK(&(doc)->links, (doc)->nlinks, size)static inline struct link *add_dom_link(struct dom_renderer *renderer, unsigned char *string, int length){	struct document *document = renderer->document;	int x = renderer->canvas_x;	int y = renderer->canvas_y;	unsigned char *where;	struct link *link;	struct point *point;	struct screen_char template;	unsigned char *uristring;	color_t fgcolor;	if (!realloc_document_links(document, document->nlinks + 1))		return NULL;	link = &document->links[document->nlinks];	if (!realloc_points(link, length))		return NULL;	uristring = convert_string(renderer->convert_table,				   string, length, CSM_DEFAULT,				   NULL, NULL, NULL);	if (!uristring) return NULL;	where = join_urls(document->uri, uristring);	mem_free(uristring);	if (!where)		return NULL;#ifdef CONFIG_GLOBHIST	else if (get_global_history_item(where))		fgcolor = document->options.default_vlink;#endif#ifdef CONFIG_BOOKMARKS	else if (get_bookmark(where))		fgcolor = document->options.default_bookmark_link;#endif	else		fgcolor = document->options.default_link;	link->npoints = length;

⌨️ 快捷键说明

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