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

📄 dip.c

📁 ELinks is an advanced and well-established feature-rich text mode web (HTTP/FTP/..) browser. ELinks
💻 C
📖 第 1 页 / 共 4 页
字号:
		apply_gamma_single_8_to_16(style->r1,user_gamma/sRGB_gamma),		apply_gamma_single_8_to_16(style->g1,user_gamma/sRGB_gamma),		apply_gamma_single_8_to_16(style->b1,user_gamma/sRGB_gamma)	);	if (display_optimize){		/* A correction for LCD */		new->bitmap.x/=3;		decimate_3(&primary_data,new->bitmap.x,new->bitmap.y);	}	/* We have a buffer with photons */	gd->get_empty_bitmap(&(new->bitmap));	if (dither_letters)		dither(primary_data, &(new->bitmap));	else		(*round_fn)(primary_data,&(new->bitmap));	mem_free(primary_data);	gd->register_bitmap(&(new->bitmap));	if (do_free){		mem_free(found->bitmap.data);		mem_free(found);	}	bytes_consumed=new->bitmap.x*new->bitmap.y*(gd->depth&7);	/* Number of bytes per pixel in passed bitmaps */	bytes_consumed+=sizeof(*new);	bytes_consumed+=sizeof(struct lru_entry);	lru_insert(&font_cache, new, &(letter->color_list),		bytes_consumed);	return new;}/* Prunes the cache to comply with maximum size */static inline void prune_font_cache(struct graphics_driver *gd){	struct font_cache_entry *bottom;	while(font_cache.bytes>font_cache.max_bytes){		/* Prune bottom entry of font cache */		bottom=lru_get_bottom(&font_cache);		if (!bottom){#ifdef DEBUG			if (font_cache.bytes||font_cache.items){				internal("font cache is empty and contains\some items or bytes at the same time.\n");			}#endif			break;		}		if (bottom->type==FC_COLOR){			gd->unregister_bitmap(&(bottom->bitmap));		}else{			mem_free(bottom->bitmap.data);		}		mem_free(bottom);		lru_destroy_bottom(&font_cache);	}}/* Prints a letter to the specified position and * returns the width of the printed letter */inline static int print_letter(struct graphics_driver *gd, struct	graphics_device *device, int x, int y, struct style *style,	int char_number){		struct font_cache_entry *found;	struct font_cache_entry template;	struct letter *letter;	/* Find a suitable letter */	letter=find_stored_letter(style->table,char_number);#ifdef DEBUG	if (!letter) internal("print_letter could not find a letter - even not the blotch!");#endif /* #ifdef DEBUG */	template.type=FC_COLOR;	template.r0=style->r0;	template.r1=style->r1;	template.g0=style->g0;	template.g1=style->g1;	template.b0=style->b0;	template.b1=style->b1;	template.bitmap.y=style->height;	template.mono_space=style->mono_space;	template.mono_height=style->mono_height;	found=lru_lookup(&font_cache, &template, letter->color_list);	if (!found) found=supply_color_cache_entry(gd, style, letter);	gd->draw_bitmap(device, &(found->bitmap), x, y);	prune_font_cache(gd);	return found->bitmap.x;}/* Must return values that are: * >=0 * <=height * at least 1 apart * Otherwise g_print_text will print nonsense (but won't segfault) */void get_underline_pos(int height, int *top, int *bottom){	int thickness, baseline;	thickness=(height+15)/16;	baseline=height/7;	if (baseline<=0) baseline=1;	if (thickness>baseline) thickness=baseline;	*top=height-baseline;	*bottom=*top+thickness;}/* *width will be advanced by the width of the text */void g_print_text(struct graphics_driver *gd, struct graphics_device *device,int x, int y, struct style *style, unsigned char *text, int *width){	int original_flags, top_underline, bottom_underline, original_width,		my_width;	struct rect saved_clip;	if (y+style->height<=device->clip.y1||y>=device->clip.y2) goto o;	if (style -> flags){		/* Underline */		if (!width){		       width=&my_width;		       *width=0;		}		original_flags=style->flags;		original_width=*width;		style -> flags=0;		get_underline_pos(style->height, &top_underline, &bottom_underline);		restrict_clip_area(device, &saved_clip, 0, 0, device->size.x2, y+			top_underline);		g_print_text(gd, device, x, y, style, text, width);		gd->set_clip_area(device, &saved_clip);		if (bottom_underline-top_underline==1){			/* Line */			drv->draw_hline(device, x, y+top_underline				, x+*width-original_width				, style->underline_color);		}else{			/* Area */			drv->fill_area(device, x, y+top_underline,					x+*width-original_width					,y+bottom_underline,					style->underline_color);		}		if (bottom_underline<style->height){			/* Do the bottom half only if the underline is above			 * the bottom of the letters.			 */			*width=original_width;			restrict_clip_area(device, &saved_clip, 0,				y+bottom_underline, device->size.x2,				device->size.y2);			g_print_text(gd, device, x, y, style, text, width);			gd->set_clip_area(device, &saved_clip);		}		style -> flags=original_flags;		return;	}	while (*text){		int p;		int u;		GET_UTF_8(text, u);		/* 00-09, 0b-1f, 80, 81, 84, 86-9f ignorovat		 * 0a = LF		 * 82 = ' '		 * 83 = nobrk		 * 85 = radkovy zlom		 * a0 = NBSP		 * ad = soft hyphen		 */		#if 0		if (	(u>=0x00&&u<=0x09)||			(u>=0x0b&&u<=0x1f)||			u==0x80||			u==0x82||			u==0x84||			(u>=0x86&&u<=0x9f)		)continue;		if (u==0x82)u=' ';		#endif		/* stare Mikulasovo patchovani, musim to opravit    -- Brain */		if (!u || u == 0xad) continue;		if (u == 0x01 || u == 0xa0) u = ' ';		p=print_letter(gd,device,x,y,style, u);		x += p;		if (width) {			*width += p;			continue;		}		if (x>=device->clip.x2) return;	}	return;	o:	if (width) *width += g_text_width(style, text);}/* 0=equality 1=inequality */int compare_font_entries(void *entry, void *template){	struct font_cache_entry*e1=entry;	struct font_cache_entry*e2=template;	if (e1->type==FC_COLOR){		return(		 (e1->r0!=e2->r0)||		 (e1->g0!=e2->g0)||		 (e1->b0!=e2->b0)||		 (e1->r1!=e2->r1)||		 (e1->g1!=e2->g1)||		 (e1->b1!=e2->b1)||		 (e1->bitmap.y!=e2->bitmap.y)||		 (e1->mono_space!=e2->mono_space)||		 (e1->mono_space>=0&&e1->mono_height!=e2->mono_height));	}else{		return e1->bitmap.y!=e2->bitmap.y;	}	}/* If the cache already exists, it is destroyed and reallocated. If you call it with the same * size argument, only a cache flush will yield. */void init_font_cache(int bytes){	lru_init(&font_cache, &compare_font_entries, bytes);}/* Ensures there are no lru_entry objects allocated - destroys them. * Also destroys the bitmaps asociated with them. Does not destruct the font_cache per se. */void destroy_font_cache(void){	struct font_cache_entry *bottom;		while((bottom=lru_get_bottom(&font_cache))){		if (bottom->type==FC_COLOR){			drv->unregister_bitmap(&(bottom->bitmap));		}else{			/* Then it must be FC_BW. */			mem_free(bottom->bitmap.data);		}		mem_free(bottom);		lru_destroy_bottom(&font_cache);	}}/* Returns 0 in case the char is not found. */static inline int g_get_width(struct style *style, int charcode){	int x, y, width;	if (!charcode || charcode == 0xad) return 0;	if (charcode == 0x01 || charcode == 0xa0) charcode = ' ';	if (style->mono_space>=0){		x=style->mono_space;		y=style->mono_height;	}else load_metric(&x,&y,charcode,style->table);	if (!(x&&y)) width=0;	else width=compute_width(x,y,style->height);	return width;}int g_text_width(struct style *style, unsigned char *text){	int w = 0;	while (*text) {		int u;		GET_UTF_8(text, u);		w += g_get_width(style, u);	}	return w;}int g_char_width(struct style *style, int charcode){	return g_get_width(style, charcode);}int g_wrap_text(struct wrap_struct *w){	while (*w->text) {		int u;		int s;		if (*w->text == ' ') w->last_wrap = w->text,				     w->last_wrap_obj = w->obj;		GET_UTF_8(w->text, u);		if (!u) continue;		if (u == 0x01 || u == 0xa0) u = ' ';		s = g_get_width(w->style, u);		if (u == 0xad) s = 0;		if ((w->pos += s) <= w->width) {			c:			if (u != 0xad || *w->text == ' ') continue;			s = g_char_width(w->style, '-');			if (w->pos + s <= w->width || (!w->last_wrap && !w->last_wrap_obj)) {				w->last_wrap = w->text;				w->last_wrap_obj = w->obj;				continue;			}		}		if (!w->last_wrap && !w->last_wrap_obj) goto c;		return 0;	}	return 1;}void update_aspect(void){	aspect=aspect_on?(aspect_native*bfu_aspect+0.5):65536UL;}void init_dip(void){	update_aspect();	/* Initializes to 2 MByte */	init_font_cache(2000000);}void shutdown_dip(void){	destroy_font_cache();}void recode_font_name(unsigned char **name){	int dashes=0;	unsigned char *p;	if (!strcmp(*name,"monospaced")) *name="courier-medium-roman-serif-mono";	if (!strcmp(*name,"monospace")) *name="courier-medium-roman-serif-mono";	else if (!strcmp(*name,"")) *name="century_school-medium-roman-serif-vari";	p=*name;	while(*p){		if (*p=='-')dashes++;		p++;	}	if (dashes!=4) *name="century_school-medium-roman-serif-vari";}/* Compares single=a multi=b-c-a as matching. * 0 matches * 1 doesn't match */int compare_family(unsigned char *single, unsigned char *multi){	unsigned char *p,*r;	int single_length=strlen(single);	r=multi;	while(1){		p=r;		while (*r&&*r!='-')r++;		if ((r-p==single_length)&&!strncmp(single,p,r-p)) return 0;		if (!*r) return 1;		r++;	}	return 1;}/* Input name must contain exactly 4 dashes, otherwise the * result is undefined (parsing into weight, slant, adstyl, spacing * will result deterministically random results). * Returns 1 if the font is monospaced or 0 if not. */int fill_style_table(int * table, unsigned char *name){	unsigned char *p;	unsigned char *family, *weight, *slant, *adstyl, *spacing;	int pass,result,f;	int masks[6]={0x1f,0x1f,0xf,0x7,0x3,0x1};	int xors[6]={0,0x10,0x8,0x4,0x2,0x1};	/* Top bit of the values belongs to family, bottom to spacing */	int monospaced;		/* Parse the name */	recode_font_name(&name);	family=stracpy(name);	p=family;	while(*p&&*p!='-') p++;	*p=0;	p++;	weight=p;	while(*p&&*p!='-') p++;	*p=0;	p++;	slant=p;	while(*p&&*p!='-') p++;	*p=0;	p++;	adstyl=p;	while(*p&&*p!='-') p++;	*p=0;	p++;	spacing=p;	monospaced=!strcmp(spacing,"mono");		for (pass=0;pass<6;pass++){		for (f=1;f<n_fonts;f++){			/* Font 0 must not be int style_table */			result=compare_family(family,font_table[f].family);			result<<=1;			result|=!!strcmp(weight,font_table[f].weight);			result<<=1;			result|=!!strcmp(slant,font_table[f].slant);			result<<=1;			result|=!!strcmp(adstyl,font_table[f].adstyl);			result<<=1;			result|=!!strcmp(spacing,font_table[f].spacing);			result^=xors[pass];			result&=masks[pass];			if (!result) /* Fot complies */				*table++=f;		}	}	mem_free(family);	return monospaced;}struct style *g_invert_style(struct style *old){	int length;	struct style *st;	st = mem_alloc(sizeof(struct style));	st->refcount=1;	st->r0=old->r1;	st->g0=old->g1;	st->b0=old->b1;	st->r1=old->r0;	st->g1=old->g0;	st->b1=old->b0;	st->height=old->height;	st->flags=old->flags;	if (st->flags)	{		/* We have to get a foreground color for underlining */		st->underline_color=dip_get_color_sRGB(			(st->r1<<16)|(st->g1<<8)|(st->b1));	}	if ((unsigned)n_fonts > MAXINT / sizeof(*st->table)) overalloc();	length=sizeof(*st->table)*(n_fonts-1);	st->table=mem_alloc(length);	memcpy(st->table,old->table,length);	st->mono_space=old->mono_space;	st->mono_height=old->mono_height;	return st;}/* Never returns NULL. */struct style *g_get_style(int fg, int bg, int size, unsigned char *font, int flags){	struct style *st;	st = mem_alloc(sizeof(struct style));	/* strcpy(st->font, font); */	st->refcount = 1;	st->r0 = bg >> 16;	st->g0 = (bg >> 8) & 255;	st->b0 = bg & 255;	st->r1 = fg >> 16;	st->g1 = (fg >> 8) & 255;	st->b1 = fg & 255;	if (size<=0) size=1;	st->height = size;	st->flags=flags&FF_UNDERLINE;	if (st->flags)	{		/* We have to get a foreground color for underlining */		st->underline_color=dip_get_color_sRGB(fg);	}	if ((unsigned)n_fonts > MAXINT / sizeof(*st->table)) overalloc();	st->table=mem_alloc(sizeof(*st->table)*(n_fonts-1));	if(fill_style_table(st->table, font))		load_metric(&(st->mono_space), &(st->mono_height),' ',st->table);	else		st->mono_space=-1;	return st;}struct style *g_clone_style(struct style *st){	st->refcount++;	return st;}void g_free_style(struct style *st){	if (--st->refcount) return;	mem_free(st->table);	mem_free(st);}long gamma_cache_color;int gamma_cache_rgb = -2;/* IEC 61966-2-1  * Input gamma: sRGB space (directly from HTML, i. e. unrounded) * Output: color index for graphics driver that is closest to the * given sRGB value. * We assume unsigned short holds at least 16 bits. */long real_dip_get_color_sRGB(int rgb){	unsigned short r,g,b;	int new_rgb;	round_color_sRGB_to_48(&r,&g,&b,rgb);	r=apply_gamma_single_16_to_8(r,1/display_red_gamma);	g=apply_gamma_single_16_to_8(g,1/display_green_gamma);	b=apply_gamma_single_16_to_8(b,1/display_blue_gamma);	new_rgb=b|(g<<8)|(r<<16);		gamma_cache_rgb = rgb;	/* The get_color takes values with gamma of display_*_gamma */	return gamma_cache_color = drv->get_color(new_rgb);}/* ATTENTION!!! allocates using malloc. Due to braindead Xlib, which * frees it using free and thus it is not possible to use mem_alloc. */void get_links_icon(unsigned char **data, int *width, int* height, int depth){	struct bitmap b;	unsigned short *tmp1;	double g=user_gamma/sRGB_gamma;	b.x=48;	b.y=48;	*width=b.x;	*height=b.y;	b.skip=b.x*(depth&7);	if (!(b.data=*data=malloc(b.skip*b.y))) {		malloc_oom();	}	tmp1=mem_alloc(6*b.y*b.x);        apply_gamma_exponent_24_to_48(tmp1,links_icon,b.x*b.y,g,g,g);	dither(tmp1, &b);	mem_free(tmp1);}#endif /* G */

⌨️ 快捷键说明

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