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

📄 gd.c

📁 Linux/Unix下的绘图函数库(Graphic Drawing Library)
💻 C
📖 第 1 页 / 共 5 页
字号:
  /* Below */  if (y < ((im->sy) - 1))    {      lastBorder = 1;      for (i = leftLimit; (i <= rightLimit); i++)	{	  int c;	  c = gdImageGetPixel (im, i, y + 1);	  if (lastBorder)	    {	      if (c == old)		{		  gdImageFill (im, i, y + 1, color);		  lastBorder = 0;		}	    }	  else if (c != old)	    {	      lastBorder = 1;	    }	}    }}BGD_DECLARE(void) gdImageRectangle (gdImagePtr im, int x1, int y1, int x2, int y2, int color){  int x1h = x1, x1v = x1, y1h = y1, y1v = y1, x2h = x2, x2v = x2, y2h = y2,    y2v = y2;  int thick = im->thick;  if (thick > 1)    {      int half = thick / 2;      int half1 = thick - half;      if (y1 < y2)	{	  y1v = y1h - half;	  y2v = y2h + half1 - 1;	}      else	{	  y1v = y1h + half1 - 1;	  y2v = y2h - half;	}    }  gdImageLine (im, x1h, y1h, x2h, y1h, color);  gdImageLine (im, x1h, y2h, x2h, y2h, color);  gdImageLine (im, x1v, y1v, x1v, y2v, color);  gdImageLine (im, x2v, y1v, x2v, y2v, color);}BGD_DECLARE(void) gdImageFilledRectangle (gdImagePtr im, int x1, int y1, int x2, int y2,			int color){  int x, y;  /* Nick Atty: limit the points at the edge.  Note that this also     nicely kills any plotting for rectangles completely outside the     window as it makes the tests in the for loops fail */  if (x1 < 0)    x1 = 0;  if (x1 > gdImageSX (im))    x1 = gdImageSX (im);  if (y1 < 0)    y1 = 0;  if (y1 > gdImageSY (im))    y1 = gdImageSY (im);  for (y = y1; (y <= y2); y++)    {      for (x = x1; (x <= x2); x++)	{	  gdImageSetPixel (im, x, y, color);	}    }}BGD_DECLARE(void) gdImageCopy (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX,	     int srcY, int w, int h){  int c;  int x, y;  int tox, toy;  int i;  int colorMap[gdMaxColors];  if (dst->trueColor)    {      /* 2.0: much easier when the destination is truecolor. */      /* 2.0.10: needs a transparent-index check that is still valid if         the source is not truecolor. Thanks to Frank Warmerdam. */      for (y = 0; (y < h); y++)	{	  for (x = 0; (x < w); x++)	    {	      int p = gdImageGetPixel (src, srcX + x, srcY + y);	      if (p != src->transparent)		{		  int c = gdImageGetTrueColorPixel (src, srcX + x,						    srcY + y);		  gdImageSetPixel (dst, dstX + x, dstY + y, c);		}	    }	}      return;    }  for (i = 0; (i < gdMaxColors); i++)    {      colorMap[i] = (-1);    }  toy = dstY;  for (y = srcY; (y < (srcY + h)); y++)    {      tox = dstX;      for (x = srcX; (x < (srcX + w)); x++)	{	  int nc;	  int mapTo;	  c = gdImageGetPixel (src, x, y);	  /* Added 7/24/95: support transparent copies */	  if (gdImageGetTransparent (src) == c)	    {	      tox++;	      continue;	    }	  /* Have we established a mapping for this color? */	  if (src->trueColor)	    {	      /* 2.05: remap to the palette available in the	         destination image. This is slow and	         works badly, but it beats crashing! Thanks 	         to Padhrig McCarthy. */	      mapTo = gdImageColorResolveAlpha (dst,						gdTrueColorGetRed (c),						gdTrueColorGetGreen (c),						gdTrueColorGetBlue (c),						gdTrueColorGetAlpha (c));	    }	  else if (colorMap[c] == (-1))	    {	      /* If it's the same image, mapping is trivial */	      if (dst == src)		{		  nc = c;		}	      else		{		  /* Get best match possible. This		     function never returns error. */		  nc = gdImageColorResolveAlpha (dst,						 src->red[c], src->green[c],						 src->blue[c], src->alpha[c]);		}	      colorMap[c] = nc;	      mapTo = colorMap[c];	    }	  else	    {	      mapTo = colorMap[c];	    }	  gdImageSetPixel (dst, tox, toy, mapTo);	  tox++;	}      toy++;    }}/* This function is a substitute for real alpha channel operations,   so it doesn't pay attention to the alpha channel. */BGD_DECLARE(void) gdImageCopyMerge (gdImagePtr dst, gdImagePtr src, int dstX, int dstY,		  int srcX, int srcY, int w, int h, int pct){  int c, dc;  int x, y;  int tox, toy;  int ncR, ncG, ncB;  toy = dstY;  for (y = srcY; (y < (srcY + h)); y++)    {      tox = dstX;      for (x = srcX; (x < (srcX + w)); x++)	{	  int nc;	  c = gdImageGetPixel (src, x, y);	  /* Added 7/24/95: support transparent copies */	  if (gdImageGetTransparent (src) == c)	    {	      tox++;	      continue;	    }	  /* If it's the same image, mapping is trivial */	  if (dst == src)	    {	      nc = c;	    }	  else	    {	      dc = gdImageGetPixel (dst, tox, toy);	      ncR = gdImageRed (src, c) * (pct / 100.0)		+ gdImageRed (dst, dc) * ((100 - pct) / 100.0);	      ncG = gdImageGreen (src, c) * (pct / 100.0)		+ gdImageGreen (dst, dc) * ((100 - pct) / 100.0);	      ncB = gdImageBlue (src, c) * (pct / 100.0)		+ gdImageBlue (dst, dc) * ((100 - pct) / 100.0);	      /* Find a reasonable color */	      nc = gdImageColorResolve (dst, ncR, ncG, ncB);	    }	  gdImageSetPixel (dst, tox, toy, nc);	  tox++;	}      toy++;    }}/* This function is a substitute for real alpha channel operations,   so it doesn't pay attention to the alpha channel. */BGD_DECLARE(void) gdImageCopyMergeGray (gdImagePtr dst, gdImagePtr src, int dstX, int dstY,		      int srcX, int srcY, int w, int h, int pct){  int c, dc;  int x, y;  int tox, toy;  int ncR, ncG, ncB;  float g;  toy = dstY;  for (y = srcY; (y < (srcY + h)); y++)    {      tox = dstX;      for (x = srcX; (x < (srcX + w)); x++)	{	  int nc;	  c = gdImageGetPixel (src, x, y);	  /* Added 7/24/95: support transparent copies */	  if (gdImageGetTransparent (src) == c)	    {	      tox++;	      continue;	    }	  /* 	   * If it's the same image, mapping is NOT trivial since we 	   * merge with greyscale target, but if pct is 100, the grey 	   * value is not used, so it becomes trivial. pjw 2.0.12. 	   */	  if (dst == src && pct == 100)	    {	      nc = c;	    }	  else	    {	      dc = gdImageGetPixel (dst, tox, toy);	      g = 0.29900 * dst->red[dc]		+ 0.58700 * dst->green[dc] + 0.11400 * dst->blue[dc];	      ncR = gdImageRed (src, c) * (pct / 100.0)		+ g * ((100 - pct) / 100.0);	      ncG = gdImageGreen (src, c) * (pct / 100.0)		+ g * ((100 - pct) / 100.0);	      ncB = gdImageBlue (src, c) * (pct / 100.0)		+ g * ((100 - pct) / 100.0);	      /* First look for an exact match */	      nc = gdImageColorExact (dst, ncR, ncG, ncB);	      if (nc == (-1))		{		  /* No, so try to allocate it */		  nc = gdImageColorAllocate (dst, ncR, ncG, ncB);		  /* If we're out of colors, go for the		     closest color */		  if (nc == (-1))		    {		      nc = gdImageColorClosest (dst, ncR, ncG, ncB);		    }		}	    }	  gdImageSetPixel (dst, tox, toy, nc);	  tox++;	}      toy++;    }}BGD_DECLARE(void) gdImageCopyResized (gdImagePtr dst, gdImagePtr src, int dstX, int dstY,		    int srcX, int srcY, int dstW, int dstH, int srcW,		    int srcH){  int c;  int x, y;  int tox, toy;  int ydest;  int i;  int colorMap[gdMaxColors];  /* Stretch vectors */  int *stx;  int *sty;  /* We only need to use floating point to determine the correct     stretch vector for one line's worth. */  if (overflow2(sizeof (int), srcW)) {    return;  }  if (overflow2(sizeof (int), srcH)) {    return;  }  stx = (int *) gdMalloc (sizeof (int) * srcW);  sty = (int *) gdMalloc (sizeof (int) * srcH);  /* Fixed by Mao Morimoto 2.0.16 */  for (i = 0; (i < srcW); i++)    {      stx[i] = dstW * (i + 1) / srcW - dstW * i / srcW;    }  for (i = 0; (i < srcH); i++)    {      sty[i] = dstH * (i + 1) / srcH - dstH * i / srcH;    }  for (i = 0; (i < gdMaxColors); i++)    {      colorMap[i] = (-1);    }  toy = dstY;  for (y = srcY; (y < (srcY + srcH)); y++)    {      for (ydest = 0; (ydest < sty[y - srcY]); ydest++)	{	  tox = dstX;	  for (x = srcX; (x < (srcX + srcW)); x++)	    {	      int nc = 0;	      int mapTo;	      if (!stx[x - srcX])		{		  continue;		}	      if (dst->trueColor)		{		  /* 2.0.9: Thorben Kundinger: Maybe the source image is not 		     a truecolor image */		  if (!src->trueColor)		    {		      int tmp = gdImageGetPixel (src, x, y);		      mapTo = gdImageGetTrueColorPixel (src, x, y);		      if (gdImageGetTransparent (src) == tmp)			{			  /* 2.0.21, TK: not tox++ */			  tox += stx[x - srcX];			  continue;			}		    }		  else		    {		      /* TK: old code follows */		      mapTo = gdImageGetTrueColorPixel (src, x, y);		      /* Added 7/24/95: support transparent copies */		      if (gdImageGetTransparent (src) == mapTo)			{			  /* 2.0.21, TK: not tox++ */			  tox += stx[x - srcX];			  continue;			}		    }		}	      else		{		  c = gdImageGetPixel (src, x, y);		  /* Added 7/24/95: support transparent copies */		  if (gdImageGetTransparent (src) == c)		    {		      tox += stx[x - srcX];		      continue;		    }		  if (src->trueColor)		    {		      /* Remap to the palette available in the		         destination image. This is slow and		         works badly. */		      mapTo = gdImageColorResolveAlpha (dst,							gdTrueColorGetRed (c),							gdTrueColorGetGreen							(c),							gdTrueColorGetBlue							(c),							gdTrueColorGetAlpha							(c));		    }		  else		    {		      /* Have we established a mapping for this color? */		      if (colorMap[c] == (-1))			{			  /* If it's the same image, mapping is trivial */			  if (dst == src)			    {			      nc = c;			    }			  else			    {			      /* Find or create the best match */			      /* 2.0.5: can't use gdTrueColorGetRed, etc with palette */			      nc = gdImageColorResolveAlpha (dst,							     gdImageRed (src,									 c),							     gdImageGreen							     (src, c),							     gdImageBlue (src,									  c),							     gdImageAlpha							     (src, c));			    }			  colorMap[c] = nc;			}		      mapTo = colorMap[c];		    }		}	      for (i = 0; (i < stx[x - srcX]); i++)		{		  gdImageSetPixel (dst, tox, toy, mapTo);		  tox++;		}	    }	  toy++;	}    }  gdFree (stx);  gdFree (sty);}/* gd 2.0.8: gdImageCopyRotated is added. Source 	is a rectangle, with its upper left corner at	srcX and srcY. Destination is the *center* of        the rotated copy. Angle is in degrees, same as        gdImageArc. Floating point destination center	coordinates allow accurate rotation of 	objects of odd-numbered width or height. */BGD_DECLARE(void) gdImageCopyRotated (gdImagePtr dst,		    gdImagePtr src,		    double dstX, double dstY,		    int srcX, int srcY,		    int srcWidth, int srcHeight, int angle){  double dx, dy;  double radius = sqrt (srcWidth * srcWidth + srcHeight * srcHeight);  double aCos = cos (angle * .0174532925);  double aSin = sin (angle * .0174532925);  double scX = srcX + ((double) srcWidth) / 2;  double scY = srcY + ((double) srcHeight) / 2;  int cmap[gdMaxColors];  int i;  for (i = 0; (i < gdMaxColors); i++)    {      cmap[i] = (-1);    }  for (dy = dstY - radius; (dy <= dstY + radius); dy++)    {      for (dx = dstX - radius; (dx <= dstX + radius); dx++)	{	  double sxd = (dx - dstX) * aCos - (dy - dstY) * aSin;	  double syd = (dy - dstY) * aCos + (dx - dstX) * aSin;	  int sx = sxd + scX;	  int sy = syd + scY;	  if ((sx >= srcX) && (sx < srcX + srcWidth) &&	      (sy >= srcY) && (sy < srcY + srcHeight))	    {	      int c = gdImageGetPixel (src, sx, sy);	      if (!src->trueColor)		{		  /* Use a table to avoid an expensive		     lookup on every single pixel */		  if (cmap[c] == -1)		    {		      cmap[c] = gdImageColorResolveAlpha (dst,							  gdImageRed (src, c),							  gdImageGreen (src,									c),							  gdImageBlue (src,								       c),							  gdImageAlpha (src,									c));		    }		  gdImageSetPixel (dst, dx, dy, cmap[c]);		}	      else		{		  gdImageSetPixel (dst,				   dx, dy,				   gdImageColorResolveAlpha (dst,							     gdImageRed (src,									 c),							     gdImageGreen							     (src, c),							     gdImageBlue (src,									  c),							     gdImageAlpha							     (src, c)));		}	    }	}    }}/* When gd 1.x was first created, floating point was to be avoided.   These days it is often faster than table lookups or integer   arithmetic. The routine below is shamelessly, gloriously   floating point. TBB *//* 2.0.10: cast instead of floor() yields 35% performance improvement. 	Thanks to John Buckman. */#define floor2(exp) ((long) exp)/*#define floor2(exp) floor(exp)*/BGD_DECLARE(void) gdImageCopyResampled (gdImagePtr dst,		      gdImagePtr src,		      int dstX, int dstY,		      int srcX, int srcY,		      int dstW, int dstH, int srcW, int srcH){  int x, y;  double sy1, sy2, sx1, sx2;  if (!dst->trueColor)    {      gdImageCopyResized (dst, src, dstX, dstY, srcX, srcY, dstW, dstH,			  srcW, srcH);      return;    }  for (y = dstY; (y < dstY + dstH); y++)    {      sy1 = ((double) y - (double) dstY) * (double) srcH / (double) dstH;      sy2 = ((double) (y + 1) - (double) dstY) * (double) srcH /	(double) dstH;      for (x = dstX; (x < dstX + dstW); x++)	{	  double sx, sy;	  double spixels = 0;	  double red = 0.0, green = 0.0, blue = 0.0, alpha = 0.0;	  sx1 = ((double) x - (double) dstX) * (double) srcW / dstW;	  sx2 = ((double) (x + 1) - (double) dstX) * (double) srcW / dstW;	  sy = sy1;	  do	    {	      double yportion;	      if (floor2 (sy) == floor2 (sy1))		{		  yportion = 1.0 - (sy - floor2 (sy));		  if (yportion > sy2 - sy1)		    {		      yportion = sy2 - sy1;		    }		  sy = floor2 (sy);		}	      else if (sy == floor2 (sy2))		{		  yportion = sy2 - floor2 (sy2);		}	      else		{		  yportion = 1.0;		}	      sx = sx1;	      do		{		  double xportion;		  double pcontribution;		  int p;		  if (floor2 (sx) == floor2 (sx1))		    {		      xportion = 1.0 - (sx - floor2 (sx));		      if (xportion > sx2 - sx1)			{			  xportion = sx2 - sx1;			}		      sx = floor2 (sx);		    }		  else if (sx == floor2 (sx2))		    {		      xportion = sx2 - floor2 (sx2);		    }		  else		    {		      xportion = 1.0;		    }		  pcontribution = xportion * yportion;		  /* 2.08: previously srcX and srcY were ignored. 		     Andrew Pattison */		  p = gdImageGetTrueColorPixel (src,						(int) sx + srcX,						(int) sy + srcY);		  red += gdTrueColorGetRed (p) * pcontribution;

⌨️ 快捷键说明

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