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

📄 gd.c

📁 PHP v6.0 For Linux 运行环境:Win9X/ WinME/ WinNT/ Win2K/ WinXP
💻 C
📖 第 1 页 / 共 5 页
字号:
	{			/* No room for more colors */	  return ct;		/* Return closest available color */	}      im->colorsTotal++;    }  im->red[op] = r;  im->green[op] = g;  im->blue[op] = b;  im->alpha[op] = a;  im->open[op] = 0;  return op;			/* Return newly allocated color */}void gdImageColorDeallocate (gdImagePtr im, int color){	if (im->trueColor) {		return;	}	/* Mark it open. */	im->open[color] = 1;}void gdImageColorTransparent (gdImagePtr im, int color){	if (!im->trueColor) {		if (im->transparent != -1) {			im->alpha[im->transparent] = gdAlphaOpaque;		}		if (color > -1 && color<im->colorsTotal && color<=gdMaxColors) {			im->alpha[color] = gdAlphaTransparent;		} else {			return;		}	}	im->transparent = color;}void gdImagePaletteCopy (gdImagePtr to, gdImagePtr from){	int i;	int x, y, p;	int xlate[256];	if (to->trueColor || from->trueColor) {		return;	}	for (i = 0; i < 256; i++) {		xlate[i] = -1;	}	for (x = 0; x < to->sx; x++) {		for (y = 0; y < to->sy; y++) {			p = gdImageGetPixel(to, x, y);			if (xlate[p] == -1) {				/* This ought to use HWB, but we don't have an alpha-aware version of that yet. */				xlate[p] = gdImageColorClosestAlpha (from, to->red[p], to->green[p], to->blue[p], to->alpha[p]);			}			gdImageSetPixel(to, x, y, xlate[p]);		}	}	for (i = 0; i < from->colorsTotal; i++) {		to->red[i] = from->red[i];		to->blue[i] = from->blue[i];		to->green[i] = from->green[i];		to->alpha[i] = from->alpha[i];		to->open[i] = 0;	}	for (i = from->colorsTotal; i < to->colorsTotal; i++) {		to->open[i] = 1;	}	to->colorsTotal = from->colorsTotal;}/* 2.0.10: before the drawing routines, some code to clip points that are * outside the drawing window.  Nick Atty (nick@canalplan.org.uk) * * This is the Sutherland Hodgman Algorithm, as implemented by * Duvanenko, Robbins and Gyurcsik - SH(DRG) for short.  See Dr Dobb's * Journal, January 1996, pp107-110 and 116-117 * * Given the end points of a line, and a bounding rectangle (which we * know to be from (0,0) to (SX,SY)), adjust the endpoints to be on * the edges of the rectangle if the line should be drawn at all, * otherwise return a failure code *//* this does "one-dimensional" clipping: note that the second time it *  is called, all the x parameters refer to height and the y to width *  - the comments ignore this (if you can understand it when it's *  looking at the X parameters, it should become clear what happens on *  the second call!)  The code is simplified from that in the article, *  as we know that gd images always start at (0,0) */static int clip_1d(int *x0, int *y0, int *x1, int *y1, int maxdim) {	double m;      /* gradient of line */	if (*x0 < 0) {  /* start of line is left of window */		if(*x1 < 0) { /* as is the end, so the line never cuts the window */			return 0;		}		m = (*y1 - *y0)/(double)(*x1 - *x0); /* calculate the slope of the line */		/* adjust x0 to be on the left boundary (ie to be zero), and y0 to match */		*y0 -= (int)(m * *x0);		*x0 = 0;		/* now, perhaps, adjust the far end of the line as well */		if (*x1 > maxdim) {			*y1 += (int)(m * (maxdim - *x1));			*x1 = maxdim;		}		return 1;	}	if (*x0 > maxdim) { /* start of line is right of window - complement of above */		if (*x1 > maxdim) { /* as is the end, so the line misses the window */			return 0;		}		m = (*y1 - *y0)/(double)(*x1 - *x0);  /* calculate the slope of the line */		*y0 += (int)(m * (maxdim - *x0)); /* adjust so point is on the right boundary */		*x0 = maxdim;		/* now, perhaps, adjust the end of the line */		if (*x1 < 0) {			*y1 -= (int)(m * *x1);			*x1 = 0;		}		return 1;	}	/* the final case - the start of the line is inside the window */	if (*x1 > maxdim) { /* other end is outside to the right */		m = (*y1 - *y0)/(double)(*x1 - *x0);  /* calculate the slope of the line */		*y1 += (int)(m * (maxdim - *x1));		*x1 = maxdim;		return 1;	}	if (*x1 < 0) { /* other end is outside to the left */		m = (*y1 - *y0)/(double)(*x1 - *x0);  /* calculate the slope of the line */		*y1 -= (int)(m * *x1);		*x1 = 0;		return 1;	}	/* only get here if both points are inside the window */	return 1;}void gdImageSetPixel (gdImagePtr im, int x, int y, int color){	int p;	switch (color) {		case gdStyled:			if (!im->style) {				/* Refuse to draw if no style is set. */				return;			} else {				p = im->style[im->stylePos++];			}			if (p != gdTransparent) {				gdImageSetPixel(im, x, y, p);			}			im->stylePos = im->stylePos % im->styleLength;			break;		case gdStyledBrushed:			if (!im->style) {				/* Refuse to draw if no style is set. */				return;			}			p = im->style[im->stylePos++];			if (p != gdTransparent && p != 0) {				gdImageSetPixel(im, x, y, gdBrushed);			}			im->stylePos = im->stylePos % im->styleLength;			break;		case gdBrushed:			gdImageBrushApply(im, x, y);			break;		case gdTiled:			gdImageTileApply(im, x, y);			break;		case gdAntiAliased:			gdImageAntiAliasedApply(im, x, y);			break;		default:			if (gdImageBoundsSafe(im, x, y)) {				if (im->trueColor) {					switch (im->alphaBlendingFlag) {						default:						case gdEffectReplace:							im->tpixels[y][x] = color;							break;						case gdEffectAlphaBlend:							im->tpixels[y][x] = gdAlphaBlend(im->tpixels[y][x], color);							break;						case gdEffectNormal:							im->tpixels[y][x] = gdAlphaBlend(im->tpixels[y][x], color);							break;						case gdEffectOverlay :							im->tpixels[y][x] = gdLayerOverlay(im->tpixels[y][x], color);							break;					}				} else {					im->pixels[y][x] = color;				}			}			break;	}}int gdImageGetTrueColorPixel (gdImagePtr im, int x, int y){	int p = gdImageGetPixel(im, x, y);	if (!im->trueColor)  {		return gdTrueColorAlpha(im->red[p], im->green[p], im->blue[p], (im->transparent == p) ? gdAlphaTransparent : gdAlphaOpaque);	} else {		return p;	}}static void gdImageBrushApply (gdImagePtr im, int x, int y){	int lx, ly;	int hy, hx;	int x1, y1, x2, y2;	int srcx, srcy;	if (!im->brush) {		return;	}	hy = gdImageSY(im->brush) / 2;	y1 = y - hy;	y2 = y1 + gdImageSY(im->brush);	hx = gdImageSX(im->brush) / 2;	x1 = x - hx;	x2 = x1 + gdImageSX(im->brush);	srcy = 0;	if (im->trueColor) {		if (im->brush->trueColor) {			for (ly = y1; ly < y2; ly++) {				srcx = 0;				for (lx = x1; (lx < x2); lx++) {					int p;					p = gdImageGetTrueColorPixel(im->brush, srcx, srcy);					/* 2.0.9, Thomas Winzig: apply simple full transparency */					if (p != gdImageGetTransparent(im->brush)) {						gdImageSetPixel(im, lx, ly, p);					}					srcx++;				}				srcy++;			}		} else {			/* 2.0.12: Brush palette, image truecolor (thanks to Thorben Kundinger for pointing out the issue) */			for (ly = y1; ly < y2; ly++) {				srcx = 0;				for (lx = x1; lx < x2; lx++) {					int p, tc;					p = gdImageGetPixel(im->brush, srcx, srcy);					tc = gdImageGetTrueColorPixel(im->brush, srcx, srcy);					/* 2.0.9, Thomas Winzig: apply simple full transparency */					if (p != gdImageGetTransparent(im->brush)) {						gdImageSetPixel(im, lx, ly, tc);					}					srcx++;				}				srcy++;			}		}	} else {		for (ly = y1; ly < y2; ly++) {			srcx = 0;			for (lx = x1; lx < x2; lx++) {				int p;				p = gdImageGetPixel(im->brush, srcx, srcy);				/* Allow for non-square brushes! */				if (p != gdImageGetTransparent(im->brush)) {					/* Truecolor brush. Very slow on a palette destination. */					if (im->brush->trueColor) {						gdImageSetPixel(im, lx, ly, gdImageColorResolveAlpha(im, gdTrueColorGetRed(p),													 gdTrueColorGetGreen(p),													 gdTrueColorGetBlue(p),													 gdTrueColorGetAlpha(p)));					} else {						gdImageSetPixel(im, lx, ly, im->brushColorMap[p]);					}				}				srcx++;			}			srcy++;		}	}}static void gdImageTileApply (gdImagePtr im, int x, int y){	int srcx, srcy;	int p;	if (!im->tile) {		return;	}	srcx = x % gdImageSX(im->tile);	srcy = y % gdImageSY(im->tile);	if (im->trueColor) {		p = gdImageGetTrueColorPixel(im->tile, srcx, srcy);		gdImageSetPixel(im, x, y, p);	} else {		p = gdImageGetPixel(im->tile, srcx, srcy);		/* Allow for transparency */		if (p != gdImageGetTransparent(im->tile)) {			if (im->tile->trueColor) {				/* Truecolor tile. Very slow on a palette destination. */				gdImageSetPixel(im, x, y, gdImageColorResolveAlpha(im,											gdTrueColorGetRed(p),											gdTrueColorGetGreen(p),											gdTrueColorGetBlue(p),											gdTrueColorGetAlpha(p)));			} else {				gdImageSetPixel(im, x, y, im->tileColorMap[p]);			}		}	}}static int gdImageTileGet (gdImagePtr im, int x, int y){	int srcx, srcy;	int tileColor,p;	if (!im->tile) {		return -1;	}	srcx = x % gdImageSX(im->tile);	srcy = y % gdImageSY(im->tile);	p = gdImageGetPixel(im->tile, srcx, srcy);	if (im->trueColor) {		if (im->tile->trueColor) {			tileColor = p;		} else {			tileColor = gdTrueColorAlpha( gdImageRed(im->tile,p), gdImageGreen(im->tile,p), gdImageBlue (im->tile,p), gdImageAlpha (im->tile,p));		}	} else {		if (im->tile->trueColor) {			tileColor = gdImageColorResolveAlpha(im, gdTrueColorGetRed (p), gdTrueColorGetGreen (p), gdTrueColorGetBlue (p), gdTrueColorGetAlpha (p));		} else {			tileColor = p;			tileColor = gdImageColorResolveAlpha(im, gdImageRed (im->tile,p), gdImageGreen (im->tile,p), gdImageBlue (im->tile,p), gdImageAlpha (im->tile,p));		}	}	return tileColor;}static void gdImageAntiAliasedApply (gdImagePtr im, int px, int py){	float p_dist, p_alpha;	unsigned char opacity;	/*	 * Find the perpendicular distance from point C (px, py) to the line	 * segment AB that is being drawn.  (Adapted from an algorithm from the	 * comp.graphics.algorithms FAQ.)	 */	int LAC_2, LBC_2;	int Ax_Cx = im->AAL_x1 - px;	int Ay_Cy = im->AAL_y1 - py;	int Bx_Cx = im->AAL_x2 - px;	int By_Cy = im->AAL_y2 - py;	/* 2.0.13: bounds check! AA_opacity is just as capable of	 * overflowing as the main pixel array. Arne Jorgensen.	 * 2.0.14: typo fixed. 2.0.15: moved down below declarations	 * to satisfy non-C++ compilers.	 */	if (!gdImageBoundsSafe(im, px, py)) {		return;	}	/* Get the squares of the lengths of the segemnts AC and BC. */	LAC_2 = (Ax_Cx * Ax_Cx) + (Ay_Cy * Ay_Cy);	LBC_2 = (Bx_Cx * Bx_Cx) + (By_Cy * By_Cy);	if (((im->AAL_LAB_2 + LAC_2) >= LBC_2) && ((im->AAL_LAB_2 + LBC_2) >= LAC_2)) {		/* The two angles are acute.  The point lies inside the portion of the		 * plane spanned by the line segment.		 */		p_dist = fabs ((float) ((Ay_Cy * im->AAL_Bx_Ax) - (Ax_Cx * im->AAL_By_Ay)) / im->AAL_LAB);	} else {		/* The point is past an end of the line segment.  It's length from the		 * segment is the shorter of the lengths from the endpoints, but call		 * the distance -1, so as not to compute the alpha nor draw the pixel.		 */		p_dist = -1;	}	if ((p_dist >= 0) && (p_dist <= (float) (im->thick))) {		p_alpha = pow (1.0 - (p_dist / 1.5), 2);		if (p_alpha > 0) {			if (p_alpha >= 1) {				opacity = 255;			} else {				opacity = (unsigned char) (p_alpha * 255.0);			}			if (!im->AA_polygon || (im->AA_opacity[py][px] < opacity)) {				im->AA_opacity[py][px] = opacity;			}		}	}}int gdImageGetPixel (gdImagePtr im, int x, int y){	if (gdImageBoundsSafe(im, x, y)) {		if (im->trueColor) {			return im->tpixels[y][x];		} else {			return im->pixels[y][x];		}	} else {		return 0;	}}void gdImageAABlend (gdImagePtr im){	float p_alpha, old_alpha;	int color = im->AA_color, color_red, color_green, color_blue;	int old_color, old_red, old_green, old_blue;	int p_color, p_red, p_green, p_blue;	int px, py;	color_red = gdImageRed(im, color);	color_green = gdImageGreen(im, color);	color_blue = gdImageBlue(im, color);	/* Impose the anti-aliased drawing on the image. */	for (py = 0; py < im->sy; py++) {		for (px = 0; px < im->sx; px++) {			if (im->AA_opacity[py][px] != 0) {				old_color = gdImageGetPixel(im, px, py);				if ((old_color != color) && ((old_color != im->AA_dont_blend) || (im->AA_opacity[py][px] == 255))) {					/* Only blend with different colors that aren't the dont_blend color. */					p_alpha = (float) (im->AA_opacity[py][px]) / 255.0;					old_alpha = 1.0 - p_alpha;					if (p_alpha >= 1.0) {						p_color = color;					} else {						old_red = gdImageRed(im, old_color);						old_green = gdImageGreen(im, old_color);						old_blue = gdImageBlue(im, old_color);						p_red = (int) (((float) color_red * p_alpha) + ((float) old_red * old_alpha));						p_green = (int) (((float) color_green * p_alpha) + ((float) old_green * old_alpha));						p_blue = (int) (((float) color_blue * p_alpha) + ((float) old_blue * old_alpha));						p_color = gdImageColorResolve(im, p_red, p_green, p_blue);					}					gdImageSetPixel(im, px, py, p_color);				}			}		}		/* Clear the AA_opacity array behind us. */		memset(im->AA_opacity[py], 0, im->sx);	}}/* Bresenham as presented in Foley & Van Dam */void gdImageLine (gdImagePtr im, int x1, int y1, int x2, int y2, int color){	int t;	int dx, dy, incr1, incr2, d, x, y, xend, yend, xdirflag, ydirflag;	int wid;	int w, wstart;	int thick = im->thick;	/* 2.0.10: Nick Atty: clip to edges of drawing rectangle, return if no points need to be drawn */	if (!clip_1d(&x1,&y1,&x2,&y2,gdImageSX(im)) || !clip_1d(&y1,&x1,&y2,&x2,gdImageSY(im))) {		return;	}	/* Vertical */	if (x1==x2) {		if (y2 < y1) {			t = y2;			y2 = y1;			y1 = t;		}		for (;y1 <= y2; y1++) {			gdImageSetPixel(im, x1,y1, color);		}		return;	}	/* Horizontal */	if (y1==y2) {		if (x2 < x1) {			t = x2;			x2 = x1;			x1 = t;		}		for (;x1 <= x2; x1++) {			gdImageSetPixel(im, x1,y1, color);		}		return;	}	/* gdAntiAliased passed as color: set anti-aliased line (AAL) global vars. */	if (color == gdAntiAliased) {		im->AAL_x1 = x1;		im->AAL_y1 = y1;		im->AAL_x2 = x2;		im->AAL_y2 = y2;		/* Compute what we can for point-to-line distance calculation later. */		im->AAL_Bx_Ax = x2 - x1;		im->AAL_By_Ay = y2 - y1;		im->AAL_LAB_2 = (im->AAL_Bx_Ax * im->AAL_Bx_Ax) + (im->AAL_By_Ay * im->AAL_By_Ay);		im->AAL_LAB = sqrt (im->AAL_LAB_2);		/* For AA, we must draw pixels outside the width of the line.  Keep in		 * mind that this will be curtailed by cos/sin of theta later.		 */		thick += 4;	}	dx = abs(x2 - x1);	dy = abs(y2 - y1);	if (dy <= dx) {		/* More-or-less horizontal. use wid for vertical stroke */		/* Doug Claar: watch out for NaN in atan2 (2.0.5) */		if ((dx == 0) && (dy == 0)) {			wid = 1;

⌨️ 快捷键说明

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