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

📄 renderer.c

📁 一个很有名的浏览器
💻 C
📖 第 1 页 / 共 4 页
字号:
	/* Take out all badly placed form items. */	foreach (form, document->forms) {		assertm(form->form_num <= form->form_end,			"%p [%d : %d]", form, form->form_num, form->form_end);		foreachsafe (fc, next, form->items) {			if (form->form_num <= fc->position			    && fc->position <= form->form_end)				continue;			del_from_list(fc);			add_to_list(form_controls, fc);		}	}	/* Re-insert the form items the correct places. */	foreachsafe (fc, next, form_controls) {		foreach (form, document->forms) {			if (fc->position < form->form_num			    || form->form_end < fc->position)				continue;			del_from_list(fc);			fc->form = form;			add_to_list(form->items, fc);			break;		}	}	assert(list_empty(form_controls));}static inline voidcolor_link_lines(struct document *document){	struct color_pair colors = INIT_COLOR_PAIR(par_format.bgcolor, 0x0);	enum color_mode color_mode = document->options.color_mode;	enum color_flags color_flags = document->options.color_flags;	int y;	for (y = 0; y < document->height; y++) {		int x;		for (x = 0; x < document->data[y].length; x++) {			struct screen_char *schar = &document->data[y].chars[x];			set_term_color(schar, &colors, color_flags, color_mode);			/* XXX: Entering hack zone! Change to clink color after			 * link text has been recolored. */			if (schar->data == ':' && colors.foreground == 0x0)				colors.foreground = format.clink;		}		colors.foreground = 0x0;	}}static void *html_special(struct part *part, enum html_special_type c, ...){	va_list l;	unsigned char *t;	struct document *document = part->document;	unsigned long seconds;	struct form *form;	struct form_control *fc;	assert(part);	if_assert_failed return NULL;	va_start(l, c);	switch (c) {		case SP_TAG:			t = va_arg(l, unsigned char *);			if (document)				html_special_tag(document, t, X(part->cx), Y(part->cy));			va_end(l);			break;		case SP_FORM:			form = va_arg(l, struct form *);			html_special_form(part, form);			va_end(l);			break;		case SP_CONTROL:			fc = va_arg(l, struct form_control *);			html_special_form_control(part, fc);			va_end(l);			break;		case SP_TABLE:			va_end(l);			return renderer_context.convert_table;		case SP_USED:			va_end(l);			return (void *) (long) !!document;		case SP_CACHE_CONTROL:		{			struct cache_entry *cached = renderer_context.cached;			cached->cache_mode = CACHE_MODE_NEVER;			cached->expire = 0;			va_end(l);			break;		}		case SP_CACHE_EXPIRES:		{			time_t expires = va_arg(l, time_t);			struct cache_entry *cached = renderer_context.cached;			va_end(l);			if (!expires || cached->cache_mode == CACHE_MODE_NEVER)				break;			cached->max_age = expires;			cached->expire = 1;			break;		}		case SP_FRAMESET:		{			struct frameset_param *fsp = va_arg(l, struct frameset_param *);			struct frameset_desc *frameset_desc;			va_end(l);			if (!fsp->parent && document->frame_desc) return NULL;			frameset_desc = create_frameset(fsp);			if (!fsp->parent && !document->frame_desc)				document->frame_desc = frameset_desc;			return frameset_desc;		}		case SP_FRAME:		{			struct frameset_desc *parent = va_arg(l, struct frameset_desc *);			unsigned char *name = va_arg(l, unsigned char *);			unsigned char *url = va_arg(l, unsigned char *);			va_end(l);			add_frameset_entry(parent, NULL, name, url);		}			break;		case SP_NOWRAP:			renderer_context.nowrap = va_arg(l, int);			va_end(l);			break;		case SP_REFRESH:			seconds = va_arg(l, unsigned long);			t = va_arg(l, unsigned char *);			va_end(l);			document->refresh = init_document_refresh(t, seconds);			break;		case SP_COLOR_LINK_LINES:			va_end(l);			if (document && use_document_bg_colors(&document->options))				color_link_lines(document);			break;		case SP_STYLESHEET:		{#ifdef CONFIG_CSS			struct uri *uri = va_arg(l, struct uri *);			if (document)				add_to_uri_list(&document->css_imports, uri);#endif			va_end(l);			break;		}		case SP_SCRIPT:		{#ifdef CONFIG_ECMASCRIPT			struct uri *uri = va_arg(l, struct uri *);			if (document)				add_to_uri_list(&document->ecmascript_imports, uri);#endif			va_end(l);			break;		}	}	return NULL;}voidfree_table_cache(void){	if (renderer_context.table_cache) {		struct hash_item *item;		int i;		/* We do not free key here. */		foreach_hash_item (item, *renderer_context.table_cache, i) {			mem_free_if(item->value);		}		free_hash(renderer_context.table_cache);	}	renderer_context.table_cache = NULL;	renderer_context.table_cache_entries = 0;}struct part *format_html_part(unsigned char *start, unsigned char *end,		 int align, int margin, int width, struct document *document,		 int x, int y, unsigned char *head,		 int link_num){	struct part *part;	struct html_element *html_state;	int llm = renderer_context.last_link_to_move;	struct tag *ltm = renderer_context.last_tag_to_move;	/*struct tag *ltn = last_tag_for_newline;*/	int lm = html_context.margin;	int ef = renderer_context.empty_format;	struct table_cache_entry *tce;	/* Hash creation if needed. */	if (!renderer_context.table_cache) {		renderer_context.table_cache = init_hash(8, &strhash);	} else if (!document) {		/* Search for cached entry. */		struct table_cache_entry_key key;		struct hash_item *item;		/* Clear key to prevent potential alignment problem		 * when keys are compared. */		memset(&key, 0, sizeof(key));		key.start = start;		key.end = end;		key.align = align;		key.margin = margin;		key.width = width;		key.x = x;		key.link_num = link_num;		item = get_hash_item(renderer_context.table_cache,				     (unsigned char *) &key,				     sizeof(key));		if (item) { /* We found it in cache, so just copy and return. */			part = mem_alloc(sizeof(*part));			if (part)  {				copy_struct(part, &((struct table_cache_entry *)						    item->value)->part);				return part;			}		}	}	assertm(y >= 0, "format_html_part: y == %d", y);	if_assert_failed return NULL;	if (document) {		struct node *node = mem_alloc(sizeof(*node));		if (node) {			int node_width = !html_context.table_level ? INT_MAX : width;			set_box(&node->box, x, y, node_width, 1);			add_to_list(document->nodes, node);		}		renderer_context.last_link_to_move = document->nlinks;		renderer_context.last_tag_to_move = (void *) &document->tags;		renderer_context.last_tag_for_newline = (void *) &document->tags;	} else {		renderer_context.last_link_to_move = 0;		renderer_context.last_tag_to_move = NULL;		renderer_context.last_tag_for_newline = NULL;	}	html_context.margin = margin;	renderer_context.empty_format = !document;	done_link_state_info();	renderer_context.nobreak = 1;	part = mem_calloc(1, sizeof(*part));	if (!part) goto ret;	part->document = document;	part->box.x = x;	part->box.y = y;	part->cx = -1;	part->cy = 0;	part->link_num = link_num;	html_state = init_html_parser_state(ELEMENT_IMMORTAL, align, margin, width);	parse_html(start, end, part, head);	done_html_parser_state(html_state);	int_lower_bound(&part->max_width, part->box.width);	renderer_context.nobreak = 0;	done_link_state_info();	mem_free_if(part->spaces);	if (document) {		struct node *node = document->nodes.next;		node->box.height = y - node->box.y + part->box.height;	}ret:	renderer_context.last_link_to_move = llm;	renderer_context.last_tag_to_move = ltm;	/* renderer_context.last_tag_for_newline = ltn; */	html_context.margin = lm;	renderer_context.empty_format = ef;	if (html_context.table_level > 1 && !document	    && renderer_context.table_cache	    && renderer_context.table_cache_entries < MAX_TABLE_CACHE_ENTRIES) {		/* Create a new entry. */		/* Clear memory to prevent bad key comparaison due to alignment		 * of key fields. */		tce = mem_calloc(1, sizeof(*tce));		/* A goto is used here to prevent a test or code		 * redundancy. */		if (!tce) goto end;		tce->key.start = start;		tce->key.end = end;		tce->key.align = align;		tce->key.margin = margin;		tce->key.width = width;		tce->key.x = x;		tce->key.link_num = link_num;		copy_struct(&tce->part, part);		if (!add_hash_item(renderer_context.table_cache,				   (unsigned char *) &tce->key,				   sizeof(tce->key), tce)) {			mem_free(tce);		} else {			renderer_context.table_cache_entries++;		}	}end:	return part;}voidrender_html_document(struct cache_entry *cached, struct document *document,		     struct string *buffer){	struct part *part;	unsigned char *start = NULL;	unsigned char *end = NULL;	struct string title;	struct string head;	int i;	assert(cached && document);	if_assert_failed return;	if (!init_string(&head)) return;	renderer_context.g_ctrl_num = 0;	renderer_context.cached = cached;	start = buffer->source;	end = buffer->source + buffer->length;	if (cached->head) add_to_string(&head, cached->head);	init_html_parser(cached->uri, &document->options, start, end, &head, &title,			 put_chars_conv, line_break, html_special);	renderer_context.convert_table = get_convert_table(head.source,							   document->options.cp,							   document->options.assume_cp,							   &document->cp,							   &document->cp_status,							   document->options.hard_assume);	if (title.length) {		document->title = convert_string(renderer_context.convert_table,						 title.source, title.length,						 CSM_DEFAULT, NULL, NULL, NULL);	}	done_string(&title);	part = format_html_part(start, end, par_format.align,			        par_format.leftmargin,				document->options.box.width, document,			        0, 0, head.source, 1);	/* Drop empty allocated lines at end of document if any	 * and adjust document height. */	for (i = document->height - 1; i >= 0 ; i--) {		if (!document->data[i].length) {			mem_free_if(document->data[i].chars);			document->height--;		} else break;	}	/* Calculate document width. */	document->width = 0;	for (i = 0; i < document->height; i++)		int_lower_bound(&document->width, document->data[i].length);#if 1	document->options.needs_width = 1;#else	/* FIXME: This needs more tuning since if we are centering stuff it	 * does not work. */	document->options.needs_width =				(document->width + (document->options.margin				 >= document->options.width));#endif	document->bgcolor = par_format.bgcolor;	done_html_parser();	/* Drop forms which has been serving as a placeholder for form items	 * added in the wrong order due to the ordering of table rendering. */	{		struct form *form;		foreach (form, document->forms) {			if (form->form_num)				continue;			if (list_empty(form->items))				done_form(form);			break;		}	}	/* @part was residing in html_context so it has to stay alive until	 * done_html_parser(). */	done_string(&head);	mem_free_if(part);#if 0 /* debug purpose */	{		FILE *f = fopen("forms", "ab");		struct form_control *form;		unsigned char *qq;		fprintf(f,"FORM:\n");		foreach (form, document->forms) {			fprintf(f, "g=%d f=%d c=%d t:%d\n",				form->g_ctrl_num, form->form_num,				form->ctrl_num, form->type);		}		fprintf(f,"fragment: \n");		for (qq = start; qq < end; qq++) fprintf(f, "%c", *qq);		fprintf(f,"----------\n\n");		fclose(f);	}#endif}intfind_tag(struct document *document, unsigned char *name, int namelen){	struct tag *tag;	foreach (tag, document->tags)		if (!strlcasecmp(tag->name, -1, name, namelen))			return tag->y;	return -1;}

⌨️ 快捷键说明

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