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

📄 renderer.c

📁 一个很有名的浏览器
💻 C
📖 第 1 页 / 共 4 页
字号:
	if (tag) {		tag->x = x;		tag->y = y;		memcpy(tag->name, t, tag_len + 1);		add_to_list(document->tags, tag);		if ((void *) renderer_context.last_tag_for_newline == &document->tags)			renderer_context.last_tag_for_newline = tag;	}}static voidput_chars_conv(struct part *part, unsigned char *chars, int charslen){	assert(part && chars && charslen);	if_assert_failed return;	if (format.style.attr & AT_GRAPHICS) {		put_chars(part, chars, charslen);		return;	}	convert_string(renderer_context.convert_table, chars, charslen,	               CSM_DEFAULT, NULL, (void (*)(void *, unsigned char *, int)) put_chars, part);}static inline voidput_link_number(struct part *part){	unsigned char s[64];	unsigned char *fl = format.link;	unsigned char *ft = format.target;	unsigned char *fi = format.image;	struct form_control *ff = format.form;	int slen = 0;	format.link = format.target = format.image = NULL;	format.form = NULL;	s[slen++] = '[';	ulongcat(s, &slen, part->link_num, sizeof(s) - 3, 0);	s[slen++] = ']';	s[slen] = '\0';	renderer_context.nosearchable = 1;	put_chars(part, s, slen);	renderer_context.nosearchable = 0;	if (ff && ff->type == FC_TEXTAREA) line_break(part);	/* We might have ended up on a new line after the line breaking	 * or putting the link number chars. */	if (part->cx == -1) part->cx = par_format.leftmargin;	format.link = fl;	format.target = ft;	format.image = fi;	format.form = ff;}#define assert_link_variable(old, new) \	assertm(!(old), "Old link value [%s]. New value [%s]", old, new);static inline voidinit_link_state_info(unsigned char *link, unsigned char *target,		     unsigned char *image, struct form_control *form){	assert_link_variable(renderer_context.link_state_info.image, image);	assert_link_variable(renderer_context.link_state_info.target, target);	assert_link_variable(renderer_context.link_state_info.link, link);	renderer_context.link_state_info.link = null_or_stracpy(link);	renderer_context.link_state_info.target = null_or_stracpy(target);	renderer_context.link_state_info.image = null_or_stracpy(image);	renderer_context.link_state_info.form = format.form;}static inline voiddone_link_state_info(void){	mem_free_if(renderer_context.link_state_info.link);	mem_free_if(renderer_context.link_state_info.target);	mem_free_if(renderer_context.link_state_info.image);	memset(&renderer_context.link_state_info, 0,	       sizeof(renderer_context.link_state_info));}static inline voidprocess_link(struct part *part, enum link_state link_state,	     unsigned char *chars, int charslen){	struct link *link;	int x_offset = 0;	switch (link_state) {	case LINK_STATE_SAME: {		unsigned char *name;		if (!part->document) return;		assertm(part->document->nlinks > 0, "no link");		if_assert_failed return;		link = &part->document->links[part->document->nlinks - 1];		name = get_link_name(link);		if (name) {			unsigned char *new_name;			new_name = straconcat(name, chars, NULL);			if (new_name) {				mem_free(name);				link->data.name = new_name;			}		}		/* FIXME: Concatenating two adjectent <a> elements to a single		 * link is broken since we lose the event handlers for the		 * second one.  OTOH simply appending them here won't fly since		 * we may get here multiple times for even a single link. We		 * will probably need some SP_ for creating a new link or so.		 * --pasky */		break;	}	case LINK_STATE_NEW:		part->link_num++;		init_link_state_info(format.link, format.target,				     format.image, format.form);		if (!part->document) return;		/* Trim leading space from the link text */		while (x_offset < charslen && chars[x_offset] <= ' ')			x_offset++;		if (x_offset) {			charslen -= x_offset;			chars += x_offset;		}		link = new_link(part->document, part->link_num,				chars, charslen);		if (!link) return;		break;	case LINK_STATE_NONE:	default:		INTERNAL("bad link_state %i", (int) link_state);		return;	}	/* Add new canvas positions to the link. */	if (realloc_points(link, link->npoints + charslen)) {		struct point *point = &link->points[link->npoints];		int x = X(part->cx) + x_offset;		int y = Y(part->cy);		link->npoints += charslen;		for (; charslen > 0; charslen--, point++, x++) {			point->x = x;			point->y = y;		}	}}static inline enum link_stateget_link_state(void){	enum link_state state;	if (!(format.link || format.image || format.form)) {		state = LINK_STATE_NONE;	} else if ((renderer_context.link_state_info.link		    || renderer_context.link_state_info.image		    || renderer_context.link_state_info.form)		   && !xstrcmp(format.link, renderer_context.link_state_info.link)		   && !xstrcmp(format.target, renderer_context.link_state_info.target)		   && !xstrcmp(format.image, renderer_context.link_state_info.image)		   && format.form == renderer_context.link_state_info.form) {		return LINK_STATE_SAME;	} else {		state = LINK_STATE_NEW;	}	done_link_state_info();	return state;}voidprocess_hidden_link(struct part *part){	enum link_state state = get_link_state();	process_link(part, state, NULL, 0);}#define is_drawing_subs_or_sups() \	((format.style.attr & AT_SUBSCRIPT && global_doc_opts->display_subs) \	 || (format.style.attr & AT_SUPERSCRIPT && global_doc_opts->display_sups))static inline inthtml_has_non_space_chars(unsigned char *chars, int charslen){	int pos = 0;	while (pos < charslen)		if (!isspace(chars[pos++]))			return 1;	return 0;}voidput_chars(struct part *part, unsigned char *chars, int charslen){	enum link_state link_state;	int update_after_subscript = renderer_context.did_subscript;	assert(part);	if_assert_failed return;	assert(chars && charslen);	if_assert_failed return;	/* If we are not handling verbatim aligning and we are at the begining	 * of a line trim whitespace. */	if (part->cx == -1) {		/* If we are not handling verbatim aligning trim leading		 * whitespaces. */		if (!html_is_preformatted()) {			while (charslen && *chars == ' ') {				chars++;				charslen--;			}			if (charslen < 1) return;		}		part->cx = par_format.leftmargin;	}	/* For preformatted html always update 'the last tag' so we never end	 * up moving tags to the wrong line (Fixes bug 324). For all other html	 * it is moved only when the line being rendered carry some real	 * non-whitespace content. */	if (html_is_preformatted()	    || html_has_non_space_chars(chars, charslen)) {		renderer_context.last_tag_for_newline = (void *) &part->document->tags;	}	int_lower_bound(&part->box.height, part->cy + 1);	link_state = get_link_state();	if (link_state == LINK_STATE_NEW) {		int x_offset = 0;		/* Don't add inaccessible links. It seems to be caused		 * by the parser putting a space char after stuff like		 * <img>-tags or comments wrapped in <a>-tags. See bug		 * 30 for test case. */		while (x_offset < charslen && chars[x_offset] <= ' ')			x_offset++;		/* For pure spaces reset the link state */		if (x_offset == charslen)			link_state = LINK_STATE_NONE;		else if (global_doc_opts->num_links_display)			put_link_number(part);	}	set_hline(part, chars, charslen, link_state);	if (link_state != LINK_STATE_NONE) {		/* We need to update the current @link_state because <sub> and		 * <sup> tags will output to the canvas using an inner		 * put_chars() call which results in their process_link() call		 * will ``update'' the @link_state. */		if (link_state == LINK_STATE_NEW		    && (is_drawing_subs_or_sups()			|| update_after_subscript != renderer_context.did_subscript)) {			link_state = get_link_state();		}		process_link(part, link_state, chars, charslen);	}	if (renderer_context.nowrap	    && part->cx + charslen > overlap(par_format))		return;	part->cx += charslen;	renderer_context.nobreak = 0;	if (!html_is_preformatted()) {		while (part->cx > overlap(par_format)		       && part->cx > par_format.leftmargin) {			int x = split_line(part);			if (!x) break;			if (part->document)				align_line(part, part->cy - 1, 0);			renderer_context.nobreak = x - 1;		}	}	assert(charslen > 0);	part->xa += charslen;	int_lower_bound(&part->max_width, part->xa			+ par_format.leftmargin + par_format.rightmargin			- (chars[charslen - 1] == ' '			   && !html_is_preformatted()));	return;}#undef overlapvoidline_break(struct part *part){	struct tag *tag;	assert(part);	if_assert_failed return;	int_lower_bound(&part->box.width, part->cx + par_format.rightmargin);	if (renderer_context.nobreak) {		renderer_context.nobreak = 0;		part->cx = -1;		part->xa = 0;		return;	}	if (!part->document || !part->document->data) goto end;	if (!realloc_lines(part->document, part->box.height + part->cy + 1))		return;	if (part->cx > par_format.leftmargin && LEN(part->cy) > part->cx - 1	    && POS(part->cx - 1, part->cy).data == ' ') {		del_chars(part, part->cx - 1, part->cy);		part->cx--;	}	if (part->cx > 0) align_line(part, part->cy, 1);	for (tag = renderer_context.last_tag_for_newline;	     tag && (void *) tag != &part->document->tags;	     tag = tag->prev) {		tag->x = X(0);		tag->y = Y(part->cy + 1);	}end:	part->cy++;	part->cx = -1;	part->xa = 0;   	memset(part->spaces, 0, part->spaces_len);}static voidhtml_special_form(struct part *part, struct form *form){	assert(part && form);	if_assert_failed return;	if (!part->document) {		done_form(form);		return;	}	if (!list_empty(part->document->forms)) {		struct form *nform;		/* Make sure the new form ``claims'' its slice of the form range		 * maintained in the form_num and form_end variables. */		foreach (nform, part->document->forms) {			if (form->form_num < nform->form_num			    || nform->form_end < form->form_num)				continue;			/* First check if the form has identical form numbers.			 * That should only be the case when the form being			 * added is in fact the same form in which case it			 * should be dropped. The fact that this can happen			 * suggests that the table renderering can be confused.			 * See bug 647 for a test case. */			if (nform->form_num == form->form_num			    && nform->form_end == form->form_end) {				done_form(form);				return;			}			/* The form start is inside an already added form, so			 * partition the space of the existing form and get			 * |old|new|. */			nform->form_end = form->form_num - 1;			assertm(nform->form_num <= nform->form_end,				"[%d:%d] [%d:%d]", nform->form_num, nform->form_end,				form->form_num, form->form_end);			break;		}	} else {		/* If it is the first form make sure it eats the whole form		 * range. */#if 0		/* Disabled because in tables the parse order may lead to a		 * later form being parsed before a preceeding one causing the		 * wrong order if we set it to zero. Let's hope it doesn't break		 * anything else. */		form->form_num = 0;#endif	}	add_to_list(part->document->forms, form);}static voidhtml_special_form_control(struct part *part, struct form_control *fc){	struct form *form;	assert(part && fc);	if_assert_failed return;	if (!part->document) {		done_form_control(fc);		mem_free(fc);		return;	}	fc->g_ctrl_num = renderer_context.g_ctrl_num++;	/* We don't want to recode hidden fields. */	if (fc->type == FC_TEXT || fc->type == FC_PASSWORD ||	    fc->type == FC_TEXTAREA) {		unsigned char *dv = convert_string(renderer_context.convert_table,						   fc->default_value,						   strlen(fc->default_value),						   CSM_QUERY, NULL, NULL, NULL);		if (dv) mem_free_set(&fc->default_value, dv);	}	if (list_empty(part->document->forms)) {		/* No forms encountered yet, that means a homeless form		 * control. Generate a dummy form for those Flying		 * Dutchmans. */		form = init_form();		form->form_num = 0;		add_to_list(part->document->forms, form);	}	/* Attach this form control to the last form encountered. */	form = part->document->forms.next;	fc->form = form;	add_to_list(form->items, fc);}/* Reparents form items based on position in the source. */voidcheck_html_form_hierarchy(struct part *part){	struct document *document = part->document;	INIT_LIST_HEAD(form_controls);	struct form *form;	struct form_control *fc, *next;	if (list_empty(document->forms))		return;

⌨️ 快捷键说明

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