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

📄 html_gr.c

📁 ELinks is an advanced and well-established feature-rich text mode web (HTTP/FTP/..) browser. ELinks
💻 C
📖 第 1 页 / 共 3 页
字号:
void g_put_chars(struct g_part *p, unsigned char *s, int l){	struct g_object_text *t = NULL;	struct link *link;	if (putchars_link_ptr) {		link = NULL;		goto check_link;	}	while (par_format.align != AL_NO && p->cx == -1 && l && *s == ' ') s++, l--;	if (!l) return;	g_nobreak = 0;	if (p->cx < par_format.leftmargin * G_HTML_MARGIN) p->cx = par_format.leftmargin * G_HTML_MARGIN;	if (html_format_changed) {		if (memcmp(&ta_cache, &format, sizeof(struct text_attrib_beginning)) || xstrcmp(cached_font_face, format.fontface) || cached_font_face == to_je_ale_prasarna ||	xstrcmp(format.link, last_link) || xstrcmp(format.target, last_target) ||	    xstrcmp(format.image, last_image) || format.form != last_form	    || ((format.js_event || last_js_event) && compare_js_event_spec(format.js_event, last_js_event))	) {			/*if (!html_format_changed) internal("html_format_changed not set");*/			flush_pending_text_to_line(p);			if (xstrcmp(cached_font_face, format.fontface) || cached_font_face == to_je_ale_prasarna) {				if (cached_font_face && cached_font_face != to_je_ale_prasarna) mem_free(cached_font_face);				cached_font_face = stracpy(format.fontface);			}			memcpy(&ta_cache, &format, sizeof(struct text_attrib_beginning));			if (p->current_style) g_free_style(p->current_style);			p->current_style = get_style_by_ta(&format);		}		html_format_changed = 0;	}	/*if (p->cx <= par_format.leftmargin * G_HTML_MARGIN && *s == ' ' && par_format.align != AL_NO) s++, l--;*/	if (!p->text) {		link = NULL;		t = mem_calloc(sizeof(struct g_object_text) + ALLOC_GR);		t->mouse_event = g_text_mouse;		t->draw = g_text_draw;		t->destruct = g_text_destruct;		t->get_list = NULL;		/*t->style = get_style_by_ta(format);*/		t->style = g_clone_style(p->current_style);		t->bg = NULL; /* FIXME!!! */		t->yw = t->style->height;		/*t->xw = 0;		t->y = 0;*/		if (format.baseline) {			if (format.baseline < 0) t->y = -(t->style->height / 3);			if (format.baseline > 0) t->y = get_real_font_size(format.baseline) - (t->style->height / 2);		}		check_link:		if (last_link || last_image || last_form || format.link || format.image || format.form 		|| format.js_event || last_js_event		) goto process_link;		back_link:		if (putchars_link_ptr) {			*putchars_link_ptr = link;			return;		}		if (!link) t->link_num = -1;		else {			t->link_num = link - p->data->links;			t->link_order = link->obj_order++;		}		t->text[0] = 0;		p->pending_text_len = 0;		p->text = t;	}	if (p->pending_text_len == -1) {		p->pending_text_len = strlen(p->text->text);		goto a1;	}	if ((p->pending_text_len & ~(ALLOC_GR - 1)) != ((p->pending_text_len + l) & ~(ALLOC_GR - 1))) a1:{		struct g_object_text *t;		if ((unsigned)l > MAXINT) overalloc();		if ((unsigned)p->pending_text_len + (unsigned)l > MAXINT - ALLOC_GR) overalloc();		t = mem_realloc(p->text, sizeof(struct g_object_text) + ((p->pending_text_len + l + ALLOC_GR) & ~(ALLOC_GR - 1)));		if (p->w.last_wrap >= p->text->text && p->w.last_wrap < p->text->text + p->pending_text_len) p->w.last_wrap += (unsigned char *)t - (unsigned char *)p->text;		if (p->w.last_wrap_obj == p->text) p->w.last_wrap_obj = t;		p->text = t;	}	memcpy(p->text->text + p->pending_text_len, s, l), p->text->text[p->pending_text_len += l] = 0;	p->text->xw += g_text_width(p->text->style, p->text->text + p->pending_text_len - l); /* !!! FIXME: move to g_wrap_text */	if (par_format.align != AL_NO) {		p->w.text = p->text->text + p->pending_text_len - l;		p->w.style = p->text->style;		p->w.obj = p->text;		p->w.width = rm(par_format) - par_format.leftmargin * G_HTML_MARGIN;		if (p->w.width < 0) p->w.width = 0;		if (!g_wrap_text(&p->w)) {			split_line_object(p, p->w.last_wrap_obj, p->w.last_wrap);		}	}	return;	/* !!! WARNING: THE FOLLOWING CODE IS SHADOWED IN HTML_R.C */	process_link:	if ((last_link /*|| last_target*/ || last_image || last_form) &&	    !putchars_link_ptr &&	    !xstrcmp(format.link, last_link) && !xstrcmp(format.target, last_target) &&	    !xstrcmp(format.image, last_image) && format.form == last_form	    && ((!format.js_event && !last_js_event) || !compare_js_event_spec(format.js_event, last_js_event))) {		if (!p->data) goto back_link;		if (!p->data->nlinks) {			internal("no link");			goto back_link;		}		link = &p->data->links[p->data->nlinks - 1];		goto back_link;	} else {		if (last_link) mem_free(last_link);		if (last_target) mem_free(last_target);		if (last_image) mem_free(last_image);		free_js_event_spec(last_js_event);		last_link = last_target = last_image = NULL;		last_form = NULL;		last_js_event = NULL;		if (!(format.link || format.image || format.form || format.js_event)) goto back_link;		/*if (d_opt->num_links) {			unsigned char s[64];			unsigned char *fl = format.link, *ft = format.target, *fi = format.image;			struct form_control *ff = format.form;			struct js_event_spec *js = format.js_event;			format.link = format.target = format.image = NULL;			format.form = NULL;			format.js_event = NULL;			s[0] = '[';			snzprint(s + 1, 62, p->link_num);			strcat(s, "]");			g_put_chars(p, s, strlen(s));			if (ff && ff->type == FC_TEXTAREA) g_line_break(p);			if (p->cx < par_format.leftmargin * G_HTML_MARGIN) p->cx = par_format.leftmargin * G_HTML_MARGIN;			format.link = fl, format.target = ft, format.image = fi;			format.form = ff;			format.js_event = js;		}*/		p->link_num++;		last_link = stracpy(format.link);		last_target = stracpy(format.target);		last_image = stracpy(format.image);		last_form = format.form;		copy_js_event_spec(&last_js_event, format.js_event);		if (!p->data) goto back_link;		if (!(link = new_link(p->data))) goto back_link;		link->num = p->link_num - 1;		link->pos = DUMMY;		copy_js_event_spec(&link->js_event, format.js_event);		if (!last_form) {			link->type = L_LINK;			link->where = stracpy(last_link);			link->target = stracpy(last_target);		} else {			link->type = last_form->type == FC_TEXT || last_form->type == FC_PASSWORD || last_form->type == FC_FILE ? L_FIELD : last_form->type == FC_TEXTAREA ? L_AREA : last_form->type == FC_CHECKBOX || last_form->type == FC_RADIO ? L_CHECKBOX : last_form->type == FC_SELECT ? L_SELECT : L_BUTTON;			link->form = last_form;			link->target = stracpy(last_form->target);		}		link->where_img = stracpy(last_image);		link->sel_color = 0;		link->n = 0;	}	goto back_link;}void g_do_format(char *start, char *end, struct g_part *part, unsigned char *head){	pr(	parse_html(start, end, (int (*)(void *, unsigned char *, int)) g_put_chars_conv, (void (*)(void *)) g_line_break, (void *(*)(void *, int, ...)) g_html_special, part, head);	/*if ((part->y -= line_breax) < 0) part->y = 0;*/	flush_pending_text_to_line(part);	flush_pending_line_to_obj(part, 0);	) {};}struct g_table_cache_entry {	struct g_table_cache_entry *next;	struct g_table_cache_entry *prev;	unsigned char *start;	unsigned char *end;	int align;	int m;	int width;	int link_num;	struct g_part p;};struct list_head g_table_cache = { &g_table_cache, &g_table_cache };void g_free_table_cache(void){	free_list(g_table_cache);}struct g_part *g_format_html_part(unsigned char *start, unsigned char *end, int align, int m, int width, unsigned char *head, int link_num, unsigned char *bg, unsigned char *bgcolor, struct f_data *f_d){	int wa;	struct g_part *p;	struct html_element *e;	struct form_control *fc;	int lm = margin;	struct g_table_cache_entry *tce;	if (!f_d) foreach(tce, g_table_cache) {		if (tce->start == start && tce->end == end && tce->align == align && tce->m == m && tce->width == width && tce->link_num == link_num) {			p = mem_alloc(sizeof(struct g_part));			memcpy(p, &tce->p, sizeof(struct part));			return p;		}	}	margin = m;	/*d_opt->tables = 0;*/	if (last_link) mem_free(last_link);	if (last_image) mem_free(last_image);	if (last_target) mem_free(last_target);	free_js_event_spec(last_js_event);	last_link = last_image = last_target = NULL;	last_form = NULL;	last_js_event = NULL;	cached_font_face = to_je_ale_prasarna;	p = mem_calloc(sizeof(struct g_part));	{		struct g_object_area *a;		a = mem_calloc(sizeof(struct g_object_area) + sizeof(struct g_object_line *));		a->bg = get_background(bg, bgcolor);		if (bgcolor) decode_color(bgcolor, &format.bg);		if (bgcolor) decode_color(bgcolor, &par_format.bgcolor);		a->mouse_event = g_area_mouse;		a->draw = g_area_draw;		a->destruct = g_area_destruct;		a->get_list = g_area_get_list;		a->lfo = DUMMY;		a->rfo = DUMMY;		a->n_lines = 0;		p->root = a;		init_list(p->uf);	}	p->data = f_d;	p->x = p->y = 0;	p->xmax = 0;	html_stack_dup();	e = &html_top;	html_top.dontkill = 2;	html_top.namelen = 0;	par_format.align = align;	par_format.leftmargin = m;	par_format.rightmargin = m;	par_format.width = width;	par_format.list_level = 0;	par_format.list_number = 0;	par_format.dd_margin = 0;	p->cx = -1;	g_nobreak = 1;	g_do_format(start, end, p, head);	g_nobreak = 0;	line_breax = 1;	while (&html_top != e) {		kill_html_stack_item(&html_top);		if (!&html_top || (void *)&html_top == (void *)&html_stack) {			internal("html stack trashed");			break;		}	}	html_top.dontkill = 0;	wa = g_get_area_width(p->root);	if (wa > p->x) p->x = wa;	g_x_extend_area(p->root, p->x, 0);	if (p->x > p->xmax) p->xmax = p->x;	p->y = p->root->yw;	/*debug("WIDTH: obj (%d, %d), p (%d %d)", p->root->xw, p->root->yw, p->x, p->y);*/	kill_html_stack_item(&html_top);	if (!f_d) g_release_part(p), p->root = NULL;	if (cached_font_face && cached_font_face != to_je_ale_prasarna) mem_free(cached_font_face);	cached_font_face = to_je_ale_prasarna;	foreach(fc, p->uf) destroy_fc(fc);	free_list(p->uf);	margin = lm;	if (last_link) mem_free(last_link);	if (last_image) mem_free(last_image);	if (last_target) mem_free(last_target);	free_js_event_spec(last_js_event);	last_link = last_image = last_target = NULL;	last_form = NULL;	last_js_event = NULL;	if (table_level > 1 && !f_d) {		tce = mem_alloc(sizeof(struct g_table_cache_entry));		tce->start = start;		tce->end = end;		tce->align = align;		tce->m = m;		tce->width = width;		tce->link_num = link_num;		memcpy(&tce->p, p, sizeof(struct g_part));		add_to_list(g_table_cache, tce);	}	return p;}void g_release_part(struct g_part *p){	if (p->text) p->text->destruct(p->text);	if (p->line) p->line->destruct(p->line);	if (p->root) p->root->destruct(p->root);	if (p->current_style) g_free_style(p->current_style);}void g_scan_width(struct g_object **o, int n, int *w){	while (n--) {		if ((*o)->x + (*o)->xw > *w) *w = (*o)->x + (*o)->xw;		o++;	}}void g_scan_lines(struct g_object_line **o, int n, int *w){	while (n--) {		if ((*o)->n_entries) {			struct g_object *oo = (*o)->entries[(*o)->n_entries - 1];			if ((*o)->x + oo->x + oo->xw > *w) *w = (*o)->x + oo->x + oo->xw;		}		o++;	}}int g_get_area_width(struct g_object_area *a){	int w = 0;	g_scan_width(a->lfo, a->n_lfo, &w);	g_scan_width(a->rfo, a->n_rfo, &w);	g_scan_lines(a->lines, a->n_lines, &w);	return w;}void g_x_extend_area(struct g_object_area *a, int width, int height){	struct g_object_line *l;	int i;	a->xw = width;	for (i = 0; i < a->n_lines; i++) {		a->lines[i]->xw = width;	}	for (i = a->n_lines - 1; i >= 0; i--) {		l = a->lines[i];		if (!l->n_entries) {			a->yw -= l->yw;			l->destruct(l);			a->n_lines--;			continue;		}		break;	}	if (a->yw >= height) return;	l = mem_calloc(sizeof(struct g_object_line));	l->mouse_event = g_line_mouse;	l->draw = g_line_draw;	l->destruct = g_line_destruct;	l->get_list = g_line_get_list;	l->x = 0;	l->y = a->yw;	l->xw = width;	l->yw = height - a->yw;	l->bg = a->bg;	l->n_entries = 0;	a->lines[a->n_lines] = l;	a->n_lines++;}#endif

⌨️ 快捷键说明

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