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

📄 gdttf.c

📁 php-4.4.7学习linux时下载的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
static intglyphTest ( void *element, void *key ){	glyph_t *a=(glyph_t *)element;	glyphkey_t *b=(glyphkey_t *)key;	return (a->character == b->character		&& a->hinting == b->hinting		&& a->gray_render == b->gray_render);}static void *glyphFetch ( char **error, void *key ){	glyph_t				*a;	glyphkey_t			*b=(glyphkey_t *)key;	short				glyph_code;	int					flags, err;	int					crect[8], xmin, xmax, ymin, ymax;	double				cos_a, sin_a;	a = (glyph_t *)pemalloc(sizeof(glyph_t), 1);	a->character = b->character;	a->hinting = b->hinting;	a->gray_render = b->gray_render;	a->oldx = a->oldy = 0;	/* create glyph container */	if ((TT_New_Glyph(b->font->face, &a->glyph))) {		*error = "Could not create glyph container";		pefree(a, 1);		return NULL;	}	flags = TTLOAD_SCALE_GLYPH;	if (a->hinting && b->font->angle == 0.0) {		flags |= TTLOAD_HINT_GLYPH;	}	if (b->font->have_char_map_Unicode) {		glyph_code = TT_Char_Index(b->font->char_map_Unicode, a->character);	} else if (a->character < 161 && b->font->have_char_map_Roman) {		glyph_code = TT_Char_Index(b->font->char_map_Roman, a->character);	} else if ( b->font->have_char_map_Big5) {		glyph_code = TT_Char_Index(b->font->char_map_Big5, a->character);	}	if ((err=TT_Load_Glyph(b->font->instance, a->glyph, glyph_code, flags))) {		*error = "TT_Load_Glyph problem";		pefree(a, 1);		return NULL;	}	TT_Get_Glyph_Metrics(a->glyph, &a->metrics);	if (b->font->angle != 0.0) {		TT_Get_Glyph_Outline(a->glyph, &a->outline);		TT_Transform_Outline(&a->outline, &b->font->matrix);	}	/* calculate bitmap size */	xmin = a->metrics.bbox.xMin -64;	ymin = a->metrics.bbox.yMin -64;	xmax = a->metrics.bbox.xMax +64;	ymax = a->metrics.bbox.yMax +64;	cos_a = b->font->cos_a;	sin_a = b->font->sin_a;	crect[0] = (int)(xmin * cos_a - ymin * sin_a);	crect[1] = (int)(xmin * sin_a + ymin * cos_a);	crect[2] = (int)(xmax * cos_a - ymin * sin_a);	crect[3] = (int)(xmax * sin_a + ymin * cos_a);	crect[4] = (int)(xmax * cos_a - ymax * sin_a);	crect[5] = (int)(xmax * sin_a + ymax * cos_a);	crect[6] = (int)(xmin * cos_a - ymax * sin_a);	crect[7] = (int)(xmin * sin_a + ymax * cos_a);	a->xmin = MIN(MIN(crect[0], crect[2]), MIN(crect[4], crect[6]));	a->xmax = MAX(MAX(crect[0], crect[2]), MAX(crect[4], crect[6]));	a->ymin = MIN(MIN(crect[1], crect[3]), MIN(crect[5], crect[7]));	a->ymax = MAX(MAX(crect[1], crect[3]), MAX(crect[5], crect[7]));	/* allocate bitmap large enough for character */	a->Bit.rows = (a->ymax - a->ymin + 32 + 64) / 64;	a->Bit.width = (a->xmax - a->xmin + 32 + 64) / 64;	a->Bit.flow = TT_Flow_Up;	if (a->gray_render) {		a->Bit.cols = a->Bit.width;               /* 1 byte per pixel */	}	else {		a->Bit.cols = (a->Bit.width + 7) / 8;     /* 1 bit per pixel */	}	a->Bit.cols = (a->Bit.cols + 3) & ~3;         /* pad to 32 bits */	a->Bit.size = a->Bit.rows * a->Bit.cols;      /* # of bytes in buffer */	a->Bit.bitmap = NULL;	a->bitmapCache = gdCacheCreate( BITMAPCACHESIZE,					bitmapTest, bitmapFetch, bitmapRelease);	return (void *)a;}static voidglyphRelease( void *element ){	glyph_t *a=(glyph_t *)element;	gdCacheDelete(a->bitmapCache);	TT_Done_Glyph( a->glyph );	pefree ((char *)element, 1);}/********************************************************************//* bitmap cache functions                                            */static intbitmapTest ( void *element, void *key ){	bitmap_t *a=(bitmap_t *)element;	bitmapkey_t *b=(bitmapkey_t *)key;	if (a->xoffset == b->xoffset && a->yoffset == b->yoffset) {		b->glyph->Bit.bitmap = a->bitmap;		return TRUE;	}	return FALSE;}static void *bitmapFetch ( char **error, void *key ){	bitmap_t			*a;	bitmapkey_t			*b=(bitmapkey_t *)key;	a = (bitmap_t *)pemalloc(sizeof(bitmap_t), 1);	a->xoffset = b->xoffset;	a->yoffset = b->yoffset;	b->glyph->Bit.bitmap = a->bitmap = (char *)pemalloc(b->glyph->Bit.size, 1);	memset(a->bitmap, 0, b->glyph->Bit.size);	/* render glyph */	if (b->glyph->gray_render) {		TT_Get_Glyph_Pixmap(b->glyph->glyph, &b->glyph->Bit,			a->xoffset, a->yoffset);	}	else {		TT_Get_Glyph_Bitmap(b->glyph->glyph, &b->glyph->Bit,			a->xoffset, a->yoffset);	}	return (void *)a;}static voidbitmapRelease( void *element ){	bitmap_t *a=(bitmap_t *)element;	pefree (a->bitmap, 1);	pefree ((char *)element, 1);}/********************************************************************//* tweencolor cache functions                                            */static inttweenColorTest (void *element, void *key){     tweencolor_t *a=(tweencolor_t *)element;    tweencolorkey_t *b=(tweencolorkey_t *)key;        return (a->pixel == b->pixel             && a->bgcolor == b->bgcolor         && a->fgcolor == b->fgcolor         && a->im == b->im);} static void *tweenColorFetch (char **error, void *key){    tweencolor_t *a;    tweencolorkey_t *b=(tweencolorkey_t *)key;	int pixel, npixel, bg, fg;	gdImagePtr im;       a = (tweencolor_t *)pemalloc(sizeof(tweencolor_t), 1);	pixel = a->pixel = b->pixel;	bg = a->bgcolor = b->bgcolor;	fg = a->fgcolor = b->fgcolor;	im = b->im;	/* if fg is specified by a negative color idx, then don't antialias */	if (fg <0) {		a->tweencolor = -fg;	} else {		npixel = NUMCOLORS - pixel;		a->tweencolor = gdImageColorResolve(im,			(pixel * im->red  [fg] + npixel * im->red  [bg]) / NUMCOLORS,			(pixel * im->green[fg] + npixel * im->green[bg]) / NUMCOLORS,			(pixel * im->blue [fg] + npixel * im->blue [bg]) / NUMCOLORS);	}    *error = NULL;    return (void *)a;}           static voidtweenColorRelease(void *element){       pefree((char *)element, 1);}   /********************************************************************//* gdttfchar -  render one character onto a gd image                */static int OneTime=0;static gdCache_head_t   *tweenColorCache;char *gdttfchar(gdImage *im, int fg, font_t *font,	int x, int y,					/* string start pos in pixels */	TT_F26Dot6 x1,	TT_F26Dot6 y1,	/* char start offset (*64) from x,y */	TT_F26Dot6 *advance,	TT_BBox **bbox, 	char **next){    int pc, ch, len;	int row, col;	int x2, y2;     /* char start pos in pixels */ 	int x3, y3;     /* current pixel pos */	unsigned char *pixel;    glyph_t *glyph;    glyphkey_t glyphkey;    bitmapkey_t bitmapkey;	tweencolor_t *tweencolor;	tweencolorkey_t tweencolorkey;	/****** set up tweenColorCache on first call ************/	if (! OneTime) {		tweenColorCache = gdCacheCreate(TWEENCOLORCACHESIZE,			tweenColorTest, tweenColorFetch, tweenColorRelease);		OneTime++;	}	/**************/	if (font->have_char_map_Unicode) { /* use UTF-8 mapping from ASCII */        len = gdTcl_UtfToUniChar(*next, &ch);        *next += len;	} else {	/*	 * Big 5 mapping:	 * use "JIS-8 half-width katakana" coding from 8-bit characters.  Ref:	 * ftp://ftp.ora.com/pub/examples/nutshell/ujip/doc/japan.inf-032092.sjs	 */		ch = (**next) & 255;         /* don't extend sign */		(*next)++;		if (ch >= 161                /* first code of JIS-8 pair */			&& **next) {                /* don't advance past '\0' */			ch = (ch * 256) + **next;			(*next)++;		}	}	glyphkey.character = ch;	glyphkey.hinting = 1;	/* if fg is specified by a negative color idx, then don't antialias */	glyphkey.gray_render = ((font->ptsize < MINANTIALIASPTSIZE) || (fg <0))?FALSE:TRUE;    glyphkey.font = font;    glyph = (glyph_t *)gdCacheGet(font->glyphCache, &glyphkey);    if (! glyph)		return font->glyphCache->error;	*bbox = &glyph->metrics.bbox;	*advance = glyph->metrics.advance;	/* if null *im, or invalid color,  then assume user just wants brect */	if (!im || fg > 255 || fg < -255)		return (char *)NULL;	/* render (via cache) a bitmap for the current fractional offset */	bitmapkey.xoffset = ((x1+32) & 63) - 32 - ((glyph->xmin+32) & -64);	bitmapkey.yoffset = ((y1+32) & 63) - 32 - ((glyph->ymin+32) & -64);	bitmapkey.glyph = glyph;	gdCacheGet(glyph->bitmapCache, &bitmapkey);	/* copy to gif, mapping colors */      x2 = x + (((glyph->xmin+32) & -64) + ((x1+32) & -64)) / 64;      y2 = y - (((glyph->ymin+32) & -64) + ((y1+32) & -64)) / 64;	tweencolorkey.fgcolor = fg;	tweencolorkey.im = im;	for (row = 0; row < glyph->Bit.rows; row++) {		if (glyph->gray_render)			pc = row * glyph->Bit.cols;		else			pc = row * glyph->Bit.cols * 8;		y3 = y2 - row;		if (y3 >= im->sy || y3 < 0) continue;		for (col = 0; col < glyph->Bit.width; col++, pc++) {			if (glyph->gray_render) {				tweencolorkey.pixel = 					*((unsigned char *)(glyph->Bit.bitmap) + pc);			} else {				tweencolorkey.pixel = 					(((*((unsigned char *)(glyph->Bit.bitmap) + pc/8))						<<(pc%8))&128)?4:0;			}			/* if not background */			if (tweencolorkey.pixel > 0) {				x3 = x2 + col;				if (x3 >= im->sx || x3 < 0) continue;#if HAVE_LIBGD20				if (im->trueColor) {					pixel = &im->tpixels[y3][x3];				} else#endif				{#if HAVE_LIBGD13					pixel = &im->pixels[y3][x3];#else					pixel = &im->pixels[x3][y3];#endif				}				tweencolorkey.bgcolor = *pixel;				tweencolor = (tweencolor_t *)gdCacheGet(					tweenColorCache, &tweencolorkey);				*pixel = tweencolor->tweencolor;			}		}	}	return (char *)NULL;}/********************************************************************//* gdttf -  render a utf8 string onto a gd image					*/char *gdttf(gdImage *im, int *brect, int fg, char *fontname,	double ptsize, double angle, int x, int y, char *str){	TT_F26Dot6 ur_x=0, ur_y=0, ll_x=0, ll_y=0;	TT_F26Dot6 advance_x, advance_y, advance, x1, y1;	TT_BBox *bbox;	double sin_a, cos_a;    int i=0, ch;	font_t *font;	fontkey_t fontkey;	char *error, *next;	/****** initialize font engine on first call ************/    static gdCache_head_t	*fontCache;	static TT_Engine 	engine;	if (! fontCache) {		if (TT_Init_FreeType(&engine)) {			return "Failure to initialize font engine";		}		fontCache = gdCacheCreate( FONTCACHESIZE,			fontTest, fontFetch, fontRelease);	}	/**************/	/* get the font (via font cache) */	fontkey.fontname = fontname;	fontkey.ptsize = ptsize;	fontkey.angle = angle;	fontkey.engine = &engine;	font = (font_t *)gdCacheGet(fontCache, &fontkey);	if (! font) {		return fontCache->error;	}	sin_a = font->sin_a;	cos_a = font->cos_a;	advance_x = advance_y = 0;	next=str;	while (*next) {	  		ch = *next;		/* carriage returns */		if (ch == '\r') {			advance_x = 0;			next++;			continue;		}		/* newlines */		if (ch == '\n') {                      advance_y -= (TT_F26Dot6)(font->imetrics.y_ppem * LINESPACE * 64);                      advance_y = (advance_y-32) & -64; /* round to next pixel row */			next++;			continue;		}		x1 = (TT_F26Dot6)(advance_x * cos_a - advance_y * sin_a);		y1 = (TT_F26Dot6)(advance_x * sin_a + advance_y * cos_a);		if ((error=gdttfchar(im, fg, font, x, y, x1, y1, &advance, &bbox, &next)))			return error;		if (! i++) { /* if first character, init BB corner values */			ll_x = bbox->xMin;			ll_y = bbox->yMin;			ur_x = bbox->xMax;			ur_y = bbox->yMax;		}		else {			if (! advance_x) ll_x = MIN(bbox->xMin, ll_x);			ll_y = MIN(advance_y + bbox->yMin, ll_y);			ur_x = MAX(advance_x + bbox->xMax, ur_x);			if (! advance_y) ur_y = MAX(bbox->yMax, ur_y);		}		advance_x += advance;	}	/* rotate bounding rectangle */	brect[0] = (int)(ll_x * cos_a - ll_y * sin_a);	brect[1] = (int)(ll_x * sin_a + ll_y * cos_a);	brect[2] = (int)(ur_x * cos_a - ll_y * sin_a);	brect[3] = (int)(ur_x * sin_a + ll_y * cos_a);	brect[4] = (int)(ur_x * cos_a - ur_y * sin_a);	brect[5] = (int)(ur_x * sin_a + ur_y * cos_a);	brect[6] = (int)(ll_x * cos_a - ur_y * sin_a);	brect[7] = (int)(ll_x * sin_a + ur_y * cos_a);	/* scale, round and offset brect */	i = 0;	while (i<8) {		brect[i] = x + (brect[i] + 32) / 64;		i++;		brect[i] = y - (brect[i] + 32) / 64;		i++;	}    return (char *)NULL;}   #endif /* HAVE_LIBTTF *//* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: */

⌨️ 快捷键说明

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