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

📄 renderer.c

📁 elinks下lynx是最重要的二个文本浏览器, 在linux下非常实用, elinks也是gentoo安装过程中默认使用的浏览器, 这是elinks源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* DOM document renderer */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <sys/types.h> /* FreeBSD needs this before regex.h */#ifdef HAVE_REGEX_H#include <regex.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/renderer.h"#include "document/renderer.h"#include "dom/scanner.h"#include "dom/sgml/parser.h"#include "dom/sgml/html/html.h"#include "dom/node.h"#include "dom/stack.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 {	enum sgml_document_type doctype;	struct document *document;	struct conv_table *convert_table;	enum convert_string_mode convert_mode;	struct uri *base_uri;	unsigned char *source;	unsigned char *end;	unsigned char *position;	int canvas_x, canvas_y;#ifdef HAVE_REGEX_H	regex_t url_regex;	unsigned int find_url:1;#endif	struct screen_char styles[DOM_NODES];};#define URL_REGEX "(file://|((f|ht|nt)tp(s)?|smb)://[[:alnum:]]+([-@:.]?[[:alnum:]])*\\.[[:alpha:]]{2,4}(:[[:digit:]]+)?)(/(%[[:xdigit:]]{2}|[-_~&=;?.a-z0-9])*)*"#define URL_REGFLAGS (REG_ICASE | REG_EXTENDED)static voidinit_template(struct screen_char *template, struct document_options *options,	      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,		       options->color_flags, options->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 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->source	= buffer->source;	renderer->end		= buffer->source + buffer->length;	renderer->position	= renderer->source;	renderer->base_uri	= get_uri_reference(document->uri);#ifdef HAVE_REGEX_H	if (renderer->document->options.plain_display_links) {		if (regcomp(&renderer->url_regex, URL_REGEX, URL_REGFLAGS)) {			regfree(&renderer->url_regex);		} else {			renderer->find_url = 1;		}	}#endif	for (type = 0; type < DOM_NODES; type++) {		struct screen_char *template = &renderer->styles[type];		color_T background = document->options.default_bg;		color_T foreground = document->options.default_fg;		static int i_want_struct_module_for_dom;		struct dom_string *name = get_dom_node_type_name(type);		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 } "				"cdata-section	{ color: orange2 } ";			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)		if (is_dom_string_set(name))			selector = find_css_selector(&css->selectors,						     CST_ELEMENT, CSR_ROOT,						     name->string, name->length);		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, &document->options, 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, document->options.cp,	                        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;		}	}}#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, document->options.cp,	                           CSM_DEFAULT, NULL, NULL, NULL);	if (!uristring) return NULL;	where = join_urls(renderer->base_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;	link->type = LINK_HYPERTEXT;	link->where = where;	link->color.background = document->options.default_bg;	link->color.foreground = fgcolor;	link->number = document->nlinks;	init_template(&template, &document->options,		      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;

⌨️ 快捷键说明

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