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

📄 link.c

📁 一个很有名的浏览器
💻 C
📖 第 1 页 / 共 3 页
字号:
	assert(doc_view && doc_view->vs);	if_assert_failed return 0;	link = get_current_link(doc_view);	return (link && link_in_view(doc_view, link));}/* Look for the first and the last link currently visible in our * viewport. */static voidget_visible_links_range(struct document_view *doc_view, int *first, int *last){	struct document *document = doc_view->document;	int height = int_min(doc_view->vs->y + doc_view->box.height,	                     document->height);	int y;	*first = document->nlinks - 1;	*last = 0;	for (y = int_max(0, doc_view->vs->y); y < height; y++) {		if (document->lines1[y])			int_upper_bound(first, document->lines1[y]					       - document->links);		if (document->lines2[y])			int_lower_bound(last, document->lines2[y]					      - document->links);	}}intnext_link_in_view(struct document_view *doc_view, int current, int direction,	          int (*fn)(struct document_view *, struct link *),	          void (*cntr)(struct document_view *, struct link *)){	struct document *document;	struct view_state *vs;	int start, end;	assert(doc_view && doc_view->document && doc_view->vs && fn);	if_assert_failed return 0;	document = doc_view->document;	vs = doc_view->vs;	get_visible_links_range(doc_view, &start, &end);	current_link_blur(doc_view);	/* Go from the @current link in @direction until either	 * fn() is happy or we would leave the current viewport. */	while (current >= start && current <= end) {		if (fn(doc_view, &document->links[current])) {			vs->current_link = current;			if (cntr) cntr(doc_view, &document->links[current]);			current_link_hover(doc_view);			return 1;		}		current += direction;	}	vs->current_link = -1;	return 0;}/* Get the bounding columns of @link at line @y (or all lines if @y == -1). */static voidget_link_x_bounds(struct link *link, int y, int *min_x, int *max_x){	int point;	if (min_x) *min_x = INT_MAX;	if (max_x) *max_x = 0;	for (point = 0; point < link->npoints; point++) {		if (y >= 0 && link->points[point].y != y)			continue;		if (min_x) int_upper_bound(min_x, link->points[point].x);		if (max_x) int_lower_bound(max_x, link->points[point].x);	}}/* Check whether there is any point between @min_x and @max_x at the line @y * in link @link. */static intget_link_x_intersect(struct link *link, int y, int min_x, int max_x){	int point;	for (point = 0; point < link->npoints; point++) {		if (link->points[point].y != y)			continue;		if (link->points[point].x >= min_x		    && link->points[point].x <= max_x)			return link->points[point].x + 1;	}	return 0;}/* Check whether there is any point between @min_y and @max_y in the column @x * in link @link. */static intget_link_y_intersect(struct link *link, int x, int min_y, int max_y){	int point;	for (point = 0; point < link->npoints; point++) {		if (link->points[point].x != x)			continue;		if (link->points[point].y >= min_y		    && link->points[point].y <= max_y)			return link->points[point].y + 1;	}	return 0;}intnext_link_in_dir(struct document_view *doc_view, int dir_x, int dir_y){	struct document *document;	struct view_state *vs;	struct link *link;	int min_x = INT_MAX, max_x = 0;	int min_y, max_y;	assert(doc_view && doc_view->document && doc_view->vs);	if_assert_failed return 0;	assert(dir_x || dir_y);	if_assert_failed return 0;	document = doc_view->document;	vs = doc_view->vs;	link = get_current_link(doc_view);	if (!link) return 0;	/* Find the link's "bounding box" coordinates. */	get_link_x_bounds(link, -1, &min_x, &max_x);	min_y = link->points[0].y;	max_y = link->points[link->npoints - 1].y;	/* Now go from the bounding box edge in the appropriate	 * direction and find the nearest link. */	if (dir_y) {		/* Vertical movement */		/* The current line number */		int y = (dir_y > 0 ? max_y : min_y) + dir_y;		/* The bounding line numbers */		int top = int_max(0, doc_view->vs->y);		int bottom = int_min(doc_view->vs->y + doc_view->box.height,				     document->height);		for (; dir_y > 0 ? y < bottom : y >= top; y += dir_y) {			/* @backup points to the nearest link from the left			 * to the desired position. */			struct link *backup = NULL;			link = document->lines1[y];			if (!link) continue;			/* Go through all the links on line. */			for (; link <= document->lines2[y]; link++) {				int l_min_x, l_max_x;				/* Some links can be totally out of order here,				 * ie. in tables or when using tabindex. */				if (y < link->points[0].y				    || y > link->points[link->npoints - 1].y)					continue;				get_link_x_bounds(link, y, &l_min_x, &l_max_x);				if (l_min_x > max_x) {					/* This link is too at the right. */					if (!backup)						backup = link;					continue;				}				if (l_max_x < min_x) {					/* This link is too at the left. */					backup = link;					continue;				}				/* This link is aligned with the current one. */				goto chose_link;			}			if (backup) {				link = backup;				goto chose_link;			}		}		if (!y || y == document->height) {			/* We just stay at the same place, do not invalidate			 * the link number. */			return 0;		}	} else {		/* Horizontal movement */		/* The current column number */		int x = (dir_x > 0 ? max_x : min_x) + dir_x;		/* How many lines are already past their last link */		int last = 0;		while ((last < max_y - min_y + 1) && (x += dir_x) >= 0) {			int y;			last = 0;			/* Go through all the lines */			for (y = min_y; y <= max_y; y++) {				link = document->lines1[y];				if (!link) continue;				/* Go through all the links on line. */				while (link <= document->lines2[y]) {					if (get_link_y_intersect(link, x,					                         min_y,					                         max_y))						goto chose_link;					link++;				}				/* Check if we already aren't past the last				 * link on this line. */				if (!get_link_x_intersect(document->lines2[y],				                          y, x, INT_MAX))					last++;			}		}		/* We just stay  */		return 0;	}	current_link_blur(doc_view);	vs->current_link = -1;	return 0;chose_link:	/* The link is in bounds, take it. */	current_link_blur(doc_view);	vs->current_link = get_link_index(document, link);	set_pos_x(doc_view, link);	current_link_hover(doc_view);	return 1;}voidset_pos_x(struct document_view *doc_view, struct link *link){	int xm = 0;	int xl = INT_MAX;	int i;	assert(doc_view && link);	if_assert_failed return;	for (i = 0; i < link->npoints; i++) {		int y = link->points[i].y - doc_view->vs->y;		if (y >= 0 && y < doc_view->box.height) {			int_lower_bound(&xm, link->points[i].x + 1);			int_upper_bound(&xl, link->points[i].x);		}	}	if (xl != INT_MAX)		int_bounds(&doc_view->vs->x, xm - doc_view->box.width, xl);}voidset_pos_y(struct document_view *doc_view, struct link *link){	int ym = 0;	int height;	int i;	assert(doc_view && doc_view->document && doc_view->vs && link);	if_assert_failed return;	height = doc_view->document->height;	for (i = 0; i < link->npoints; i++) {		int_lower_bound(&ym, link->points[i].y + 1);		int_upper_bound(&height, link->points[i].y);	}	doc_view->vs->y = (ym + height - doc_view->box.height) / 2;	int_bounds(&doc_view->vs->y, 0,		   doc_view->document->height - doc_view->box.height);}/* direction == 1 -> DOWN * direction == -1 -> UP */static voidfind_link(struct document_view *doc_view, int direction, int page_mode){	struct link **line;	struct link *link = NULL;	int link_pos;	int y, ymin, ymax;	assert(doc_view && doc_view->document && doc_view->vs);	if_assert_failed return;	if (direction == -1) {		/* UP */		line = doc_view->document->lines2;		if (!line) goto nolink;		y = doc_view->vs->y + doc_view->box.height - 1;		int_upper_bound(&y, doc_view->document->height - 1);		if (y < 0) goto nolink;	} else {		/* DOWN */		line = doc_view->document->lines1;		if (!line) goto nolink;		y = doc_view->vs->y;		int_lower_bound(&y, 0);		if (y >= doc_view->document->height) goto nolink;	}	ymin = int_max(0, doc_view->vs->y);	ymax = int_min(doc_view->document->height,		       doc_view->vs->y + doc_view->box.height);	if (direction == -1) {		/* UP */		do {			struct link *cur = line[y--];			if (cur && (!link || cur > link))				link = cur;		} while (y >= ymin && y < ymax);	} else {		/* DOWN */		do {			struct link *cur = line[y++];			if (cur && (!link || cur < link))				link = cur;		} while (y >= ymin && y < ymax);	}	if (!link) goto nolink;	link_pos = link - doc_view->document->links;	if (page_mode) {		/* PAGE */		next_link_in_view(doc_view, link_pos, direction, link_in_view, NULL);		return;	}	current_link_blur(doc_view);	doc_view->vs->current_link = link_pos;	set_pos_x(doc_view, link);	current_link_hover(doc_view);	return;nolink:	current_link_blur(doc_view);	doc_view->vs->current_link = -1;}voidfind_link_up(struct document_view *doc_view){	find_link(doc_view, -1, 0);}voidfind_link_page_up(struct document_view *doc_view){	find_link(doc_view, -1, 1);}voidfind_link_down(struct document_view *doc_view){	find_link(doc_view, 1, 0);}voidfind_link_page_down(struct document_view *doc_view){	find_link(doc_view, 1, 1);}struct uri *get_link_uri(struct session *ses, struct document_view *doc_view,	     struct link *link){	assert(ses && doc_view && link);	if_assert_failed return NULL;	switch (link->type) {		case LINK_HYPERTEXT:		case LINK_MAP:			if (link->where) return get_uri(link->where, 0);			return get_uri(link->where_img, 0);		case LINK_BUTTON:		case LINK_FIELD:			return get_form_uri(ses, doc_view,					    get_link_form_control(link));		default:			return NULL;	}}struct link *goto_current_link(struct session *ses, struct document_view *doc_view, int do_reload){	struct link *link;	struct uri *uri;	assert(doc_view && ses);	if_assert_failed return NULL;	link = get_current_link(doc_view);	if (!link) return NULL;	if (link_is_form(link))		uri = get_form_uri(ses, doc_view, get_link_form_control(link));	else

⌨️ 快捷键说明

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