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

📄 gdft.c

📁 php-4.4.7学习linux时下载的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
}  int gdFontCacheSetup(void){	if (fontCache) {		/* Already set up */		return 0;	}	gdMutexSetup(gdFontCacheMutex);	if (FT_Init_FreeType(&library)) {		gdMutexShutdown(gdFontCacheMutex);		return -1;	}	fontCache = gdCacheCreate (FONTCACHESIZE, fontTest, fontFetch, fontRelease);	return 0;}/********************************************************************//* gdImageStringFT -  render a utf8 string onto a gd image          */char *gdImageStringFT (gdImage * im, int *brect, int fg, char *fontlist,   		 double ptsize, double angle, int x, int y, char *string){	return gdImageStringFTEx(im, brect, fg, fontlist, ptsize, angle, x, y, string, 0);}char *gdImageStringFTEx (gdImage * im, int *brect, int fg, char *fontlist, double ptsize, double angle, int x, int y, char *string, gdFTStringExtraPtr strex){	FT_BBox bbox, glyph_bbox;	FT_Matrix matrix;	FT_Vector pen, delta, penf;	FT_Face face;	FT_Glyph image;	FT_GlyphSlot slot;	FT_Bool use_kerning;	FT_UInt glyph_index, previous;	double sin_a = sin (angle);	double cos_a = cos (angle);	int len, i = 0, ch;	int x1 = 0, y1 = 0;	font_t *font;	fontkey_t fontkey;	char *next;	char *tmpstr = NULL;	int render = (im && (im->trueColor || (fg <= 255 && fg >= -255)));	FT_BitmapGlyph bm;	/* 2.0.13: Bob Ostermann: don't force autohint, that's just for testing freetype and doesn't look as good */	int render_mode = FT_LOAD_DEFAULT;	int m, mfound;	/* Now tuneable thanks to Wez Furlong */	double linespace = LINESPACE;	/* 2.0.6: put this declaration with the other declarations! */	/*	*   make a new tweenColorCache on every call	*   because caching colormappings between calls	*   is not safe. If the im-pointer points to a	*   brand new image, the cache gives out bogus	*   colorindexes.          -- 27.06.2001 <krisku@arrak.fi>	*/	gdCache_head_t  *tc_cache;	/* Tuneable horizontal and vertical resolution in dots per inch */	int hdpi, vdpi;	if (strex && ((strex->flags & gdFTEX_LINESPACE) == gdFTEX_LINESPACE)) {		linespace = strex->linespacing;	}	tc_cache = gdCacheCreate(TWEENCOLORCACHESIZE, tweenColorTest, tweenColorFetch, tweenColorRelease);	/***** initialize font library and font cache on first call ******/	if (!fontCache) {		if (gdFontCacheSetup() != 0) {			gdCacheDelete(tc_cache);			return "Failure to initialize font library";		}	}	/*****/		gdMutexLock(gdFontCacheMutex);	/* get the font (via font cache) */	fontkey.fontlist = fontlist;	fontkey.library = &library;	font = (font_t *) gdCacheGet (fontCache, &fontkey);	if (!font) {		gdCacheDelete(tc_cache);		gdMutexUnlock(gdFontCacheMutex);		return fontCache->error;	}	face = font->face;		/* shortcut */	slot = face->glyph;		/* shortcut */	/*	 * Added hdpi and vdpi to support images at non-screen resolutions, i.e. 300 dpi TIFF,	 * or 100h x 50v dpi FAX format. 2.0.23.	 * 2004/02/27 Mark Shackelford, mark.shackelford@acs-inc.com	 */	hdpi = GD_RESOLUTION;	vdpi = GD_RESOLUTION;	if (strex && (strex->flags & gdFTEX_RESOLUTION)) {		hdpi = strex->hdpi;		vdpi = strex->vdpi;	}	if (FT_Set_Char_Size(face, 0, (FT_F26Dot6) (ptsize * 64), hdpi, vdpi)) {		gdCacheDelete(tc_cache);		gdMutexUnlock(gdFontCacheMutex);		return "Could not set character size";	}	matrix.xx = (FT_Fixed) (cos_a * (1 << 16));	matrix.yx = (FT_Fixed) (sin_a * (1 << 16));	matrix.xy = -matrix.yx;	matrix.yy = matrix.xx;	penf.x = penf.y = 0;		/* running position of non-rotated string */	pen.x = pen.y = 0;		/* running position of rotated string */	bbox.xMin = bbox.xMax = bbox.yMin = bbox.yMax = 0;	use_kerning = FT_HAS_KERNING (face);	previous = 0;	if (fg < 0) {		render_mode |= FT_LOAD_MONOCHROME;	}	/* 2.0.12: allow explicit specification of the preferred map;	 * but we still fall back if it is not available.	 */	m = gdFTEX_Unicode;	if (strex && (strex->flags & gdFTEX_CHARMAP)) {		m = strex->charmap;	}	/* Try all three types of maps, but start with the specified one */	mfound = 0;	for (i = 0; i < 3; i++) {		switch (m) {			case gdFTEX_Unicode:				if (font->have_char_map_unicode) {					mfound = 1;				}				break;			case gdFTEX_Shift_JIS:				if (font->have_char_map_sjis) {					mfound = 1;				}				break;			case gdFTEX_Big5:				/* This was the 'else' case, we can't really 'detect' it */				mfound = 1;				break;		}		if (mfound) {			break;		}		m++;		m %= 3;	}	if (!mfound) {		/* No character set found! */		gdMutexUnlock(gdFontCacheMutex);		return "No character set found";	}#ifndef JISX0208	if (font->have_char_map_sjis) {#endif		tmpstr = (char *) gdMalloc(BUFSIZ);		any2eucjp(tmpstr, string, BUFSIZ);		next = tmpstr;#ifndef JISX0208	} else {		next = string;	}#endif	while (*next) {		ch = *next;		/* carriage returns */		if (ch == '\r') {			penf.x = 0;			x1 = (int)(penf.x * cos_a - penf.y * sin_a + 32) / 64;			y1 = (int)(penf.x * sin_a + penf.y * cos_a + 32) / 64;			pen.x = pen.y = 0;			previous = 0;		/* clear kerning flag */			next++;			continue;		}		/* newlines */		if (ch == '\n') {			/* 2.0.13: reset penf.x. Christopher J. Grayce */			penf.x = 0;			  penf.y -= (long)(face->size->metrics.height * linespace);			  penf.y = (penf.y - 32) & -64;		/* round to next pixel row */			  x1 = (int)(penf.x * cos_a - penf.y * sin_a + 32) / 64;			  y1 = (int)(penf.x * sin_a + penf.y * cos_a + 32) / 64;			  pen.x = pen.y = 0;			  previous = 0;		/* clear kerning flag */			  next++;			  continue;		}/* EAM DEBUG */#if (defined(FREETYPE_MAJOR) && ((FREETYPE_MAJOR == 2 && ((FREETYPE_MINOR == 1 && FREETYPE_PATCH >= 3) || FREETYPE_MINOR > 1) || FREETYPE_MAJOR > 2)))		if (font->face->charmap->encoding == FT_ENCODING_MS_SYMBOL && strcmp(font->face->family_name, "Symbol") == 0) {			/* I do not know the significance of the constant 0xf000.			 * It was determined by inspection of the character codes			 * stored in Microsoft font symbol.			 */			/* Convert to the Symbol glyph range only for a Symbol family member */ 			len = gdTcl_UtfToUniChar (next, &ch);			ch |= 0xf000;			next += len;		} else#endif /* Freetype 2.1 or better *//* EAM DEBUG */		switch (m) {			case gdFTEX_Unicode:				if (font->have_char_map_unicode) {					/* use UTF-8 mapping from ASCII */					len = gdTcl_UtfToUniChar(next, &ch);					next += len;				}				break;			case gdFTEX_Shift_JIS: 				if (font->have_char_map_sjis) {					unsigned char c;					int jiscode;					c = *next;					if (0xA1 <= c && c <= 0xFE) {						next++;						jiscode = 0x100 * (c & 0x7F) + ((*next) & 0x7F);						ch = (jiscode >> 8) & 0xFF;						jiscode &= 0xFF;						if (ch & 1) {							jiscode += 0x40 - 0x21;						} else {							jiscode += 0x9E - 0x21;						}						if (jiscode >= 0x7F) {							jiscode++;						}						ch = (ch - 0x21) / 2 + 0x81;						if (ch >= 0xA0) {							ch += 0x40;						}						ch = (ch << 8) + jiscode;					} else {						ch = c & 0xFF;	/* don't extend sign */					}					if (*next) next++;				}				break;			case gdFTEX_Big5: {				/*				 * 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) & 0xFF;	/* don't extend sign */				next++;				if (ch >= 161	/* first code of JIS-8 pair */					&& *next) { /* don't advance past '\0' */					/* TBB: Fix from Kwok Wah On: & 255 needed */					ch = (ch * 256) + ((*next) & 255);					next++;				}			}			break;		}		/* set rotation transform */		FT_Set_Transform(face, &matrix, NULL);		/* Convert character code to glyph index */		glyph_index = FT_Get_Char_Index(face, ch);				/* retrieve kerning distance and move pen position */		if (use_kerning && previous && glyph_index) {			FT_Get_Kerning(face, previous, glyph_index, ft_kerning_default, &delta);			pen.x += delta.x;			penf.x += delta.x;		}		/* load glyph image into the slot (erase previous one) */		if (FT_Load_Glyph(face, glyph_index, render_mode)) {			if (tmpstr) {				gdFree(tmpstr);			}			gdCacheDelete(tc_cache);			gdMutexUnlock(gdFontCacheMutex);			return "Problem loading glyph";		}		/* transform glyph image */		FT_Get_Glyph(slot, &image);		if (brect) { /* only if need brect */			FT_Glyph_Get_CBox(image, ft_glyph_bbox_gridfit, &glyph_bbox);			glyph_bbox.xMin += penf.x;			glyph_bbox.yMin += penf.y;			glyph_bbox.xMax += penf.x;			glyph_bbox.yMax += penf.y;			if (ch == ' ') { /* special case for trailing space */				glyph_bbox.xMax += slot->metrics.horiAdvance;			}			if (!i) { /* if first character, init BB corner values */				bbox.xMin = glyph_bbox.xMin;				bbox.yMin = glyph_bbox.yMin;				bbox.xMax = glyph_bbox.xMax;				bbox.yMax = glyph_bbox.yMax;			} else {				if (bbox.xMin > glyph_bbox.xMin) {					bbox.xMin = glyph_bbox.xMin;				}				if (bbox.yMin > glyph_bbox.yMin) {					bbox.yMin = glyph_bbox.yMin;				}				if (bbox.xMax < glyph_bbox.xMax) {					bbox.xMax = glyph_bbox.xMax;				}				if (bbox.yMax < glyph_bbox.yMax) {					bbox.yMax = glyph_bbox.yMax;				}			}			i++;		}		if (render) {			if (image->format != ft_glyph_format_bitmap && FT_Glyph_To_Bitmap(&image, ft_render_mode_normal, 0, 1)) {				if (tmpstr) {					gdFree(tmpstr);				}				gdCacheDelete(tc_cache);				gdMutexUnlock(gdFontCacheMutex);				return "Problem rendering glyph";			}			/* now, draw to our target surface */			bm = (FT_BitmapGlyph) image;			gdft_draw_bitmap(tc_cache, im, fg, bm->bitmap, x + x1 + ((pen.x + 31) >> 6) + bm->left, y - y1 + ((pen.y + 31) >> 6) - bm->top);		}		/* record current glyph index for kerning */		previous = glyph_index;		/* increment pen position */		pen.x += image->advance.x >> 10;		pen.y -= image->advance.y >> 10;		penf.x += slot->metrics.horiAdvance;		FT_Done_Glyph(image);	}	if (brect) { /* only if need brect */		/* For perfect rounding, must get sin(a + pi/4) and sin(a - pi/4). */		double d1 = sin (angle + 0.78539816339744830962);		double d2 = sin (angle - 0.78539816339744830962);		/* rotate bounding rectangle */		brect[0] = (int) (bbox.xMin * cos_a - bbox.yMin * sin_a);		brect[1] = (int) (bbox.xMin * sin_a + bbox.yMin * cos_a);		brect[2] = (int) (bbox.xMax * cos_a - bbox.yMin * sin_a);		brect[3] = (int) (bbox.xMax * sin_a + bbox.yMin * cos_a);		brect[4] = (int) (bbox.xMax * cos_a - bbox.yMax * sin_a);		brect[5] = (int) (bbox.xMax * sin_a + bbox.yMax * cos_a);		brect[6] = (int) (bbox.xMin * cos_a - bbox.yMax * sin_a);		brect[7] = (int) (bbox.xMin * sin_a + bbox.yMax * cos_a);		/* scale, round and offset brect */		brect[0] = x + gdroundupdown(brect[0], d2 > 0);		brect[1] = y - gdroundupdown(brect[1], d1 < 0);		brect[2] = x + gdroundupdown(brect[2], d1 > 0);		brect[3] = y - gdroundupdown(brect[3], d2 > 0);		brect[4] = x + gdroundupdown(brect[4], d2 < 0);		brect[5] = y - gdroundupdown(brect[5], d1 > 0);		brect[6] = x + gdroundupdown(brect[6], d1 < 0);		brect[7] = y - gdroundupdown(brect[7], d2 < 0);	}	if (tmpstr) {		gdFree(tmpstr);	}	gdCacheDelete(tc_cache);	gdMutexUnlock(gdFontCacheMutex);	return (char *) NULL;}#endif /* HAVE_LIBFREETYPE */

⌨️ 快捷键说明

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