renderer.c

来自「一个很有名的浏览器」· C语言 代码 · 共 590 行 · 第 1/2 页

C
590
字号
		assert(vs->doc_view->vs == vs);		vs->doc_view->used = 0; /* A bit risky, but... */		vs->doc_view->vs = NULL;		vs->doc_view = NULL;#ifdef CONFIG_ECMASCRIPT		vs->ecmascript_fragile = 1; /* And is this good? ;-) */#endif	}#endif	vs->doc_view = doc_view;	cached = find_in_cache(vs->uri);	if (!cached) {		INTERNAL("document %s to format not found", struri(vs->uri));		return;	}	document = get_cached_document(cached, options);	if (document) {		doc_view->document = document;	} else {		document = init_document(cached, options);		if (!document) return;		doc_view->document = document;		shrink_memory(0);		render_encoded_document(cached, document);		sort_links(document);		if (!document->title) {			enum uri_component components;			if (document->uri->protocol == PROTOCOL_FILE) {				components = URI_PATH;			} else {				components = URI_PUBLIC;			}			document->title = get_uri_string(document->uri, components);			if (document->title)				decode_uri_for_display(document->title);		}#ifdef CONFIG_CSS		document->css_magic = get_document_css_magic(document);#endif	}#ifdef CONFIG_ECMASCRIPT	if (!vs->ecmascript_fragile)		assert(vs->ecmascript);	if (!options->gradual_rerendering) {		/* We also reset the state if the underlying document changed		 * from the last time we did the snippets. This may be		 * triggered i.e. when redrawing a document which has been		 * reloaded in a different tab meanwhile (OTOH we don't want		 * to reset the state if we are redrawing a document we have		 * already drawn before).		 *		 * (vs->ecmascript->onload_snippets_owner) check may be		 * superfluous since we should always have		 * vs->ecmascript_fragile set in those cases; that's why we		 * don't ever bother to re-zero it if we are suddenly doing		 * gradual rendering again.		 *		 * XXX: What happens if a document is still loading in the		 * other tab when we press ^L here? */		if (vs->ecmascript_fragile		    || (vs->ecmascript && vs->ecmascript->onload_snippets_owner		       && document->id != vs->ecmascript->onload_snippets_owner))			ecmascript_reset_state(vs);		assert(vs->ecmascript);		vs->ecmascript->onload_snippets_owner = document->id;		/* Passing of the onload_snippets pointers gives *_snippets()		 * some feeling of universality, shall we ever get any other		 * snippets (?). */		add_snippets(vs->ecmascript,		             &document->onload_snippets,		             &vs->ecmascript->onload_snippets);		process_snippets(vs->ecmascript, &vs->ecmascript->onload_snippets,		                 &vs->ecmascript->current_onload_snippet);	}#endif	/* If we do not care about the height and width of the document	 * just use the setup values. */	copy_box(&doc_view->box, &document->options.box);	if (!document->options.needs_width)		doc_view->box.width = options->box.width;	if (!document->options.needs_height)		doc_view->box.height = options->box.height;}voidrender_document_frames(struct session *ses, int no_cache){	struct document_options doc_opts;	struct document_view *doc_view;	struct document_view *current_doc_view = NULL;	struct view_state *vs = NULL;	if (!ses->doc_view) {		ses->doc_view = mem_calloc(1, sizeof(*ses->doc_view));		if (!ses->doc_view) return;		ses->doc_view->session = ses;		ses->doc_view->search_word = &ses->search_word;	}	if (have_location(ses)) vs = &cur_loc(ses)->vs;	init_document_options(&doc_opts);	set_box(&doc_opts.box, 0, 0,		ses->tab->term->width, ses->tab->term->height);	if (ses->status.show_title_bar) {		doc_opts.box.y++;		doc_opts.box.height--;	}	if (ses->status.show_status_bar) doc_opts.box.height--;	if (ses->status.show_tabs_bar) doc_opts.box.height--;	doc_opts.color_mode = get_opt_int_tree(ses->tab->term->spec, "colors");	if (!get_opt_bool_tree(ses->tab->term->spec, "underline"))		doc_opts.color_flags |= COLOR_ENHANCE_UNDERLINE;	doc_opts.cp = get_opt_codepage_tree(ses->tab->term->spec, "charset");	doc_opts.no_cache = no_cache & 1;	doc_opts.gradual_rerendering = !!(no_cache & 2);	if (vs) {		if (vs->plain < 0) vs->plain = 0;		doc_opts.plain = vs->plain;		doc_opts.wrap = vs->wrap;	} else {		doc_opts.plain = 1;	}	foreach (doc_view, ses->scrn_frames) doc_view->used = 0;	if (vs) render_document(vs, ses->doc_view, &doc_opts);	if (document_has_frames(ses->doc_view->document)) {		current_doc_view = current_frame(ses);		format_frames(ses, ses->doc_view->document->frame_desc, &doc_opts, 0);	}	foreach (doc_view, ses->scrn_frames) {		struct document_view *prev_doc_view = doc_view->prev;		if (doc_view->used) continue;		detach_formatted(doc_view);		del_from_list(doc_view);		mem_free(doc_view);		doc_view = prev_doc_view;	}	if (current_doc_view) {		int n = 0;		foreach (doc_view, ses->scrn_frames) {			if (document_has_frames(doc_view->document)) continue;			if (doc_view == current_doc_view) {				cur_loc(ses)->vs.current_link = n;				break;			}			n++;		}	}}static intcomp_links(struct link *l1, struct link *l2){	assert(l1 && l2);	if_assert_failed return 0;	return (l1->number - l2->number);}static voidsort_links(struct document *document){	int i;	assert(document);	if_assert_failed return;	if (!document->nlinks) return;	assert(document->links);	if_assert_failed return;	qsort(document->links, document->nlinks, sizeof(*document->links),	      (void *) comp_links);	if (!document->height) return;	document->lines1 = mem_calloc(document->height, sizeof(*document->lines1));	if (!document->lines1) return;	document->lines2 = mem_calloc(document->height, sizeof(*document->lines2));	if (!document->lines2) {		mem_free(document->lines1);		return;	}	for (i = 0; i < document->nlinks; i++) {		struct link *link = &document->links[i];		int p, q, j;		if (!link->npoints) {			done_link_members(link);			memmove(link, link + 1,				(document->nlinks - i - 1) * sizeof(*link));			document->nlinks--;			i--;			continue;		}		p = link->points[0].y;		q = link->points[link->npoints - 1].y;		if (p > q) j = p, p = q, q = j;		for (j = p; j <= q; j++) {			assertm(j < document->height, "link out of screen");			if_assert_failed continue;			document->lines2[j] = &document->links[i];			if (!document->lines1[j])				document->lines1[j] = &document->links[i];		}	}}struct conv_table *get_convert_table(unsigned char *head, int to_cp,		  int default_cp, int *from_cp,		  enum cp_status *cp_status, int ignore_server_cp){	unsigned char *part = head;	int cp_index = -1;	assert(head);	if_assert_failed return NULL;	if (ignore_server_cp) {		if (cp_status) *cp_status = CP_STATUS_IGNORED;		if (from_cp) *from_cp = default_cp;		return get_translation_table(default_cp, to_cp);	}	while (cp_index == -1) {		unsigned char *ct_charset;		unsigned char *a = parse_header(part, "Content-Type", &part);		if (!a) break;		ct_charset = parse_header_param(a, "charset");		if (ct_charset) {			cp_index = get_cp_index(ct_charset);			mem_free(ct_charset);		}		mem_free(a);	}	if (cp_index == -1) {		unsigned char *a = parse_header(head, "Content-Charset", NULL);		if (a) {			cp_index = get_cp_index(a);			mem_free(a);		}	}	if (cp_index == -1) {		unsigned char *a = parse_header(head, "Charset", NULL);		if (a) {			cp_index = get_cp_index(a);			mem_free(a);		}	}	if (cp_index == -1) {		cp_index = default_cp;		if (cp_status) *cp_status = CP_STATUS_ASSUMED;	} else {		if (cp_status) *cp_status = CP_STATUS_SERVER;	}	if (from_cp) *from_cp = cp_index;	return get_translation_table(cp_index, to_cp);}

⌨️ 快捷键说明

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