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

📄 view_gr.c

📁 ELinks is an advanced and well-established feature-rich text mode web (HTTP/FTP/..) browser. ELinks
💻 C
📖 第 1 页 / 共 4 页
字号:
/* view_gr.c * (c) 2002 Mikulas Patocka * This file is a part of the Links program, released under GPL. */#include "cfg.h"#ifdef G#include "links.h"int *highlight_positions = NULL;int *highlight_lengths = NULL;int n_highlight_positions = 0;static int root_x = 0;static int root_y = 0;void g_get_search_data(struct f_data *f);struct g_object_text * g_find_nearest_object(struct f_data *f, int x, int y);int g_find_text_pos(struct g_object_text *, int);void g_get_search(struct f_data *, unsigned char *);void get_parents_sub(struct g_object *, struct g_object *);void g_set_current_link(struct f_data_c *, struct g_object_text *, int, int, int);void process_sb_event(struct f_data_c *, int, int);void process_sb_move(struct f_data_c *, int);static inline int ev_in_rect(struct event *, int, int, int, int);int skip_link(struct f_data_c *, int);int lr_link(struct f_data_c *, int);int g_next_link(struct f_data_c *, int);void unset_link(struct f_data_c *);void get_searched_sub(struct g_object *, struct g_object *);void find_nearest_sub(struct g_object *, struct g_object *);void find_next_sub(struct g_object *, struct g_object *);void g_find_next_str(struct f_data *);static int previous_link=-1;	/* for mouse event handlers */void g_draw_background(struct graphics_device *dev, struct background *bg, int x, int y, int xw, int yw){	if (xw > 4096) {		int halfx = x + xw / 2;		if (dev->clip.x1 < halfx) g_draw_background(dev, bg, x, y, halfx - x, yw);		if (dev->clip.x2 > halfx) g_draw_background(dev, bg, halfx, y, x + xw - halfx, yw);		return;	}	if (yw > 4096) {		int halfy = y + yw / 2;		if (dev->clip.y1 < halfy) g_draw_background(dev, bg, x, y, xw, halfy - y);		if (dev->clip.y2 > halfy) g_draw_background(dev, bg, x, halfy, xw, y + yw - halfy);		return;	}	if (bg->img) {		img_draw_decoded_image(dev, bg->u.img, x, y, xw, yw, x - root_x, y - root_y);	} else {		drv->fill_area(dev, x, y, x + xw, y + yw			       , dip_get_color_sRGB(bg->u.sRGB));	}}void g_release_background(struct background *bg){	if (bg->img) img_release_decoded_image(bg->u.img);	mem_free(bg);}void g_dummy_draw(struct f_data_c *fd, struct g_object *t, int x, int y){}void g_tag_destruct(struct g_object *t){	mem_free(t);}void g_dummy_mouse(struct f_data_c *fd, struct g_object *a, int x, int y, int b){}int print_all_textarea = 0;/* returns byte index of x in t->text *//* x is relative coordinate within the text (can be out of bounds) */int g_find_text_pos(struct g_object_text *t, int x){	int i=0, p=0;	unsigned char *text=t->text;	int ox, oy;	get_object_pos((struct g_object *)t, &ox, &oy);	x -= ox;	if (x<0) x=0;	if (x>t->xw) x=t->xw;	while(1)	{		unsigned c;		unsigned char *old_text;		int w;				old_text=text;		GET_UTF_8(text, c);		if (!c) break;		w=g_char_width(t->style, c);		if (/*p<x&&*/x<(p+(w>>1))) break;		p+=w;		i+=text-old_text;		if (p>=x) break;	}	return i;}void g_text_draw(struct f_data_c *fd, struct g_object_text *t, int x, int y){	struct form_control *form;	struct form_state *fs;	struct link *link = t->link_num >= 0 ? fd->f_data->links + t->link_num : NULL;	int l;	int ll;	int i, j;	int yy;	int cur;	struct line_info *ln, *lnx;	if (link && ((form = link->form)) && ((fs = find_form_state(fd, form)))) {		switch (form->type) {			struct style *inv;			int in;			case FC_RADIO:				if (link && fd->active && fd->vs->g_display_link && fd->vs->current_link == link - fd->f_data->links) inv = g_invert_style(t->style), in = 1;				else inv = t->style, in = 0;				g_print_text(drv, fd->ses->term->dev, x, y, inv, fs->state ? "[X]" : "[ ]", NULL);				if (in) g_free_style(inv);				return;			case FC_CHECKBOX:				if (link && fd->active && fd->vs->g_display_link && fd->vs->current_link == link - fd->f_data->links) inv = g_invert_style(t->style), in = 1;				else inv = t->style, in = 0;				g_print_text(drv, fd->ses->term->dev, x, y, inv, fs->state ? "[X]" : "[ ]", NULL);				if (in) g_free_style(inv);				return;			case FC_SELECT:				if (link && fd->active && fd->vs->g_display_link && fd->vs->current_link == link - fd->f_data->links) inv = g_invert_style(t->style), in = 1;				else inv = t->style, in = 0;				fixup_select_state(form, fs);				l = 0;				if (fs->state < form->nvalues) g_print_text(drv, fd->ses->term->dev, x, y, inv, form->labels[fs->state], &l);				while (l < t->xw) g_print_text(drv, fd->ses->term->dev, x + l, y, inv, "_", &l);				if (in) g_free_style(inv);				return;			case FC_TEXT:			case FC_PASSWORD:			case FC_FILE:				/*				if (fs->state >= fs->vpos + form->size) fs->vpos = fs->state - form->size + 1;				if (fs->state < fs->vpos) fs->vpos = fs->state;				*/				while ((size_t)fs->vpos < strlen(fs->value) && utf8_diff(fs->value + fs->state, fs->value + fs->vpos) >= form->size) {					unsigned char *p = fs->value + fs->vpos;					FWD_UTF_8(p);					fs->vpos = p - fs->value;				}				while (fs->vpos > fs->state) {					unsigned char *p = fs->value + fs->vpos;					BACK_UTF_8(p, fs->value);					fs->vpos = p - fs->value;				}				l = 0;				i = 0;				ll = strlen(fs->value);				while (l < t->xw) {					struct style *st = t->style;					int sm = 0;					unsigned char tx[11];					if (fs->state == fs->vpos + i && t->link_num == fd->vs->current_link && fd->ses->locked_link) {						st = g_invert_style(t->style);						sm = 1;					}					tx[1] = 0;					if (fs->vpos + i >= ll) tx[0] = '_', tx[1] = 0, i++;					else {						unsigned char *p = fs->value + fs->vpos + i;						unsigned char *pp = p;						FWD_UTF_8(p);						if (p - pp > 10) {							i++;							goto xy;						}						memcpy(tx, pp, p - pp);						tx[p - pp] = 0;						i += strlen(tx);						if (form->type == FC_PASSWORD) xy:tx[0] = '*';					}					g_print_text(drv, fd->ses->term->dev, x + l, y, st, tx, &l);					if (sm) g_free_style(st);				}				return;			case FC_TEXTAREA:				cur = _area_cursor(form, fs);				if (!(lnx = format_text(fs->value, form->cols, form->wrap))) break;				ln = lnx;				yy = y - t->link_order * t->style->height;				for (j = 0; j < fs->vypos; j++) if (ln->st) ln++;				for (j = 0; j < form->rows; j++) {					unsigned char *pp = ln->st;					int xx = fs->vpos;					while (pp < ln->en && xx > 0) {						FWD_UTF_8(pp);						xx--;					}					if (cur >= 0 && cur < form->cols && t->link_num == fd->vs->current_link && fd->ses->locked_link && fd->active) {						unsigned char tx[11];						int xx = x;						if (print_all_textarea || j == t->link_order) while (xx < x + t->xw) {							struct style *st = t->style;							unsigned char *ppp = pp;							if (ln->st && pp < ln->en) {								FWD_UTF_8(pp);								memcpy(tx, ppp, pp - ppp);								tx[pp - ppp] = 0;							} else {								tx[0] = '_';								tx[1] = 0;							}							if (!cur) {								st = g_invert_style(t->style);							}							g_print_text(drv, fd->ses->term->dev, xx, yy + j * t->style->height, st, tx, &xx);							if (!cur) {								g_free_style(st);							}							cur--;						} else cur -= form->cols;					} else {						if (print_all_textarea || j == t->link_order) {							int aa;							unsigned char *a;							struct rect old;							if (ln->st && pp < ln->en) a = memacpy(pp, ln->en - pp);							else a = stracpy("");							for (aa = 0; aa < form->cols; aa += 4) add_to_strn(&a, "____");							restrict_clip_area(fd->ses->term->dev, &old, x, 0, x + t->xw, fd->ses->term->dev->size.y2);							g_print_text(drv, fd->ses->term->dev, x, yy + j * t->style->height, t->style, a, NULL);							drv->set_clip_area(fd->ses->term->dev, &old);							mem_free(a);						}						cur -= form->cols;					}					if (ln->st) ln++;				}				mem_free(lnx);				return;		}	}	if (link && fd->active && fd->vs->g_display_link && fd->vs->current_link == link - fd->f_data->links) {		struct style *inv;		inv = g_invert_style(t->style);		g_print_text(drv, fd->ses->term->dev, x, y, inv, t->text, NULL);		g_free_style(inv);	} else if ( (!fd->f_data->hlt_len) && (!highlight_positions || !n_highlight_positions)) {		prn:		g_print_text(drv, fd->ses->term->dev, x, y, t->style, t->text, NULL);	} else {		size_t tlen = strlen(t->text);		int found;		int start = t->srch_pos;		int end = t->srch_pos + tlen;		int hl_start, hl_len;		unsigned char *mask;		unsigned char *tx;		int txl;		int pmask;		size_t ii;		struct style *inv;		intersect(fd->f_data->hlt_pos, fd->f_data->hlt_len, start, tlen, &hl_start, &hl_len);		#define B_EQUAL(t, m) (highlight_positions[t] + highlight_lengths[t] > start && highlight_positions[t] < end)#define B_ABOVE(t, m) (highlight_positions[t] >= end)		BIN_SEARCH(n_highlight_positions, B_EQUAL, B_ABOVE, *, found);		mask = mem_calloc(tlen);		if (found != -1)		{			while (found > 0 && B_EQUAL(found - 1, *)) found--;			while (found < n_highlight_positions && !B_ABOVE(found, *)) {				int pos = highlight_positions[found] - t->srch_pos;				int ii = 0;				for (ii = 0; ii < highlight_lengths[found]; ii++) {					if (pos >= 0 && (size_t)pos < tlen) mask[pos] = 1;					pos++;				}				found++;			}			if (hl_len) goto hl;		}		else if (hl_len)		{			int x;			hl:			for (x = 0; x < hl_len; x++) mask[hl_start - t->srch_pos + x] ^= 1;			/*memset(mask+hl_start-t->srch_pos, 1, hl_len*sizeof(char));*/		}		else		{			mem_free(mask);			goto prn;		}		inv = g_invert_style(t->style);		tx = init_str();;		txl = 0;		pmask = -1;		for (ii = 0; ii < tlen; ii++) {			if (mask[ii] != pmask) {				g_print_text(drv, fd->ses->term->dev, x, y, pmask ? inv : t->style, tx, &x);				mem_free(tx);				tx = init_str();				txl = 0;			}			add_chr_to_str(&tx, &txl, t->text[ii]);			pmask = mask[ii];		}		g_print_text(drv, fd->ses->term->dev, x, y, pmask ? inv : t->style, tx, &x);		mem_free(tx);		g_free_style(inv);		mem_free(mask);	}}void g_text_destruct(struct g_object_text *t){	release_image_map(t->map);	g_free_style(t->style);	mem_free(t);}void g_line_draw(struct f_data_c *fd, struct g_object_line *l, int xx, int yy){	struct graphics_device *dev = fd->ses->term->dev;	int i;	int x = 0;	for (i = 0; i < l->n_entries; i++) {		struct g_object *o = (struct g_object *)l->entries[i];		if (o->x > x) g_draw_background(dev, l->bg, xx + x, yy, o->x - x, l->yw);		if (o->y > 0) g_draw_background(dev, l->bg, xx + o->x, yy, o->xw, o->y);		if (o->y + o->yw < l->yw) g_draw_background(dev, l->bg, xx + o->x, yy + o->y + o->yw, o->xw, l->yw - o->y - o->yw);		o->draw(fd, o, xx + o->x, yy + o->y);		x = o->x + o->xw;	}	if (x < l->xw) g_draw_background(dev, l->bg, xx + x, yy, l->xw - x, l->yw);}void g_line_destruct(struct g_object_line *l){	int i;	for (i = 0; i < l->n_entries; i++) l->entries[i]->destruct(l->entries[i]);	mem_free(l);}void g_line_bg_destruct(struct g_object_line *l){	g_release_background(l->bg);	g_line_destruct(l);}void g_line_get_list(struct g_object_line *l, void (*f)(struct g_object *parent, struct g_object *child)){	int i;	for (i = 0; i < l->n_entries; i++) f((struct g_object *)l, l->entries[i]);}#define OBJ_EQ(n, b)	(*a[n]).y <= (b) && (*a[n]).y + (*a[n]).yw > (b)#define OBJ_ABOVE(n, b)	(*a[n]).y > (b)static inline struct g_object **g_find_line(struct g_object **a, int n, int p){	int res = -1;	BIN_SEARCH(n, OBJ_EQ, OBJ_ABOVE, p, res);	if (res == -1) return NULL;	return &a[res];}void g_area_draw(struct f_data_c *fd, struct g_object_area *a, int xx, int yy){	struct g_object **i;	int rx = root_x, ry = root_y;	int y1 = fd->ses->term->dev->clip.y1 - yy;	int y2 = fd->ses->term->dev->clip.y2 - yy - 1;	struct g_object **l1;	struct g_object **l2;	if (fd->ses->term->dev->clip.y1 == fd->ses->term->dev->clip.y2 || fd->ses->term->dev->clip.x1 == fd->ses->term->dev->clip.x2) return;

⌨️ 快捷键说明

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