📄 gd.c
字号:
green += gdTrueColorGetGreen (p) * pcontribution; blue += gdTrueColorGetBlue (p) * pcontribution; alpha += gdTrueColorGetAlpha (p) * pcontribution; spixels += xportion * yportion; sx += 1.0; } while (sx < sx2); sy += 1.0; } while (sy < sy2); if (spixels != 0.0) { red /= spixels; green /= spixels; blue /= spixels; alpha /= spixels; } /* Clamping to allow for rounding errors above */ if (red > 255.0) { red = 255.0; } if (green > 255.0) { green = 255.0; } if (blue > 255.0) { blue = 255.0; } if (alpha > gdAlphaMax) { alpha = gdAlphaMax; } gdImageSetPixel (dst, x, y, gdTrueColorAlpha ((int) red, (int) green, (int) blue, (int) alpha)); } }}BGD_DECLARE(gdImagePtr) gdImageCreateFromXbm (FILE * fd){ gdImagePtr im; int bit; int w, h; int bytes; int ch; int i, x, y; char *sp; char s[161]; if (!fgets (s, 160, fd)) { return 0; } sp = &s[0]; /* Skip #define */ sp = strchr (sp, ' '); if (!sp) { return 0; } /* Skip width label */ sp++; sp = strchr (sp, ' '); if (!sp) { return 0; } /* Get width */ w = atoi (sp + 1); if (!w) { return 0; } if (!fgets (s, 160, fd)) { return 0; } sp = s; /* Skip #define */ sp = strchr (sp, ' '); if (!sp) { return 0; } /* Skip height label */ sp++; sp = strchr (sp, ' '); if (!sp) { return 0; } /* Get height */ h = atoi (sp + 1); if (!h) { return 0; } /* Skip declaration line */ if (!fgets (s, 160, fd)) { return 0; } bytes = (w * h / 8) + 1; im = gdImageCreate (w, h); gdImageColorAllocate (im, 255, 255, 255); gdImageColorAllocate (im, 0, 0, 0); x = 0; y = 0; for (i = 0; (i < bytes); i++) { char h[3]; unsigned int b; /* Skip spaces, commas, CRs, 0x */ while (1) { ch = getc (fd); if (ch == EOF) { goto fail; } if (ch == 'x') { break; } } /* Get hex value */ ch = getc (fd); if (ch == EOF) { goto fail; } h[0] = ch; ch = getc (fd); if (ch == EOF) { goto fail; } h[1] = ch; h[2] = '\0'; sscanf (h, "%x", &b); for (bit = 1; (bit <= 128); (bit = bit << 1)) { gdImageSetPixel (im, x++, y, (b & bit) ? 1 : 0); if (x == im->sx) { x = 0; y++; if (y == im->sy) { return im; } /* Fix 8/8/95 */ break; } } } /* Shouldn't happen */ fprintf (stderr, "Error: bug in gdImageCreateFromXbm!\n"); return 0;fail: gdImageDestroy (im); return 0;}BGD_DECLARE(void) gdImagePolygon (gdImagePtr im, gdPointPtr p, int n, int c){ if (!n) { return; } gdImageLine (im, p->x, p->y, p[n - 1].x, p[n - 1].y, c); gdImageOpenPolygon (im, p, n, c);}BGD_DECLARE(void) gdImageOpenPolygon (gdImagePtr im, gdPointPtr p, int n, int c){ int i; int lx, ly; if (!n) { return; } lx = p->x; ly = p->y; for (i = 1; (i < n); i++) { p++; gdImageLine (im, lx, ly, p->x, p->y, c); lx = p->x; ly = p->y; }}/* THANKS to Kirsten Schulz for the polygon fixes! *//* The intersection finding technique of this code could be improved *//* by remembering the previous intertersection, and by using the slope. *//* That could help to adjust intersections to produce a nice *//* interior_extrema. */#if 0static void horizontalLine(gdImagePtr im, int minx, int maxx, int y, int fill_color);#endifBGD_DECLARE(void) gdImageFilledPolygon (gdImagePtr im, gdPointPtr p, int n, int c){ int i; int j; int index; int y; int miny, maxy; int x1, y1; int x2, y2; int ind1, ind2; int ints; int fill_color; if (!n) { return; } if (!im->polyAllocated) { if (overflow2(sizeof (int), n)) { return; } im->polyInts = (int *) gdMalloc (sizeof (int) * n); im->polyAllocated = n; } if (im->polyAllocated < n) { while (im->polyAllocated < n) { im->polyAllocated *= 2; } im->polyInts = (int *) gdRealloc (im->polyInts, sizeof (int) * im->polyAllocated); } miny = p[0].y; maxy = p[0].y; for (i = 1; (i < n); i++) { if (p[i].y < miny) { miny = p[i].y; } if (p[i].y > maxy) { maxy = p[i].y; } } /* 2.0.16: Optimization by Ilia Chipitsine -- don't waste time offscreen */ /* 2.0.26: clipping rectangle is even better */ if (miny < im->cy1) { miny = im->cy1; } if (maxy > im->cy2) { maxy = im->cy2; } /* Fix in 1.3: count a vertex only once */ for (y = miny; (y <= maxy); y++) {/*1.4 int interLast = 0; *//* int dirLast = 0; *//* int interFirst = 1; *//* 2.0.26+ int yshift = 0; */ if (c == gdAntiAliased) { fill_color = im->AA_color; } else { fill_color = c; } ints = 0; for (i = 0; (i < n); i++) { if (!i) { ind1 = n - 1; ind2 = 0; } else { ind1 = i - 1; ind2 = i; } y1 = p[ind1].y; y2 = p[ind2].y; if (y1 < y2) { x1 = p[ind1].x; x2 = p[ind2].x; } else if (y1 > y2) { y2 = p[ind1].y; y1 = p[ind2].y; x2 = p[ind1].x; x1 = p[ind2].x; } else { continue; } /* Do the following math as float intermediately, and round to ensure * that Polygon and FilledPolygon for the same set of points have the * same footprint. */ if ((y >= y1) && (y < y2)) { im->polyInts[ints++] = (int) ((float) ((y - y1) * (x2 - x1)) / (float) (y2 - y1) + 0.5 + x1); } else if ((y == maxy) && (y > y1) && (y <= y2)) { im->polyInts[ints++] = (int) ((float) ((y - y1) * (x2 - x1)) / (float) (y2 - y1) + 0.5 + x1); } } /* 2.0.26: polygons pretty much always have less than 100 points, and most of the time they have considerably less. For such trivial cases, insertion sort is a good choice. Also a good choice for future implementations that may wish to indirect through a table. */ for (i = 1; (i < ints); i++) { index = im->polyInts[i]; j = i; while ((j > 0) && (im->polyInts[j - 1] > index)) { im->polyInts[j] = im->polyInts[j - 1]; j--; } im->polyInts[j] = index; } for (i = 0; (i < (ints)); i += 2) {#if 0 int minx = im->polyInts[i]; int maxx = im->polyInts[i + 1];#endif /* 2.0.29: back to gdImageLine to prevent segfaults when performing a pattern fill */ gdImageLine (im, im->polyInts[i], y, im->polyInts[i + 1], y, fill_color); } } /* If we are drawing this AA, then redraw the border with AA lines. */ /* This doesn't work as well as I'd like, but it doesn't clash either. */ if (c == gdAntiAliased) { gdImagePolygon (im, p, n, c); } }#if 0static void horizontalLine(gdImagePtr im, int minx, int maxx, int y, int fill_color){ /* 2.0.27: potential corruption fixed by John Ellson */ if (minx < im->cx1) minx = im->cx1; if (maxx < minx) maxx = minx; if (maxx > im->cx2) maxx = im->cx2; if (minx > maxx) minx = maxx; if (y < im->cy1) y = im->cy1; if (y > im->cy2) y = im->cy2; if (im->trueColor) { while (minx <= maxx) { im->tpixels[y][minx++] = fill_color; } } else { while (minx <= maxx) { im->pixels[y][minx++] = fill_color; } }}#endifstatic void gdImageSetAAPixelColor(gdImagePtr im, int x, int y, int color, int t);BGD_DECLARE(void) gdImageSetStyle (gdImagePtr im, int *style, int noOfPixels){ if (im->style) { gdFree (im->style); } if (overflow2(sizeof (int), noOfPixels)) { return; } im->style = (int *) gdMalloc (sizeof (int) * noOfPixels); memcpy (im->style, style, sizeof (int) * noOfPixels); im->styleLength = noOfPixels; im->stylePos = 0;}BGD_DECLARE(void) gdImageSetThickness (gdImagePtr im, int thickness){ im->thick = thickness;}BGD_DECLARE(void) gdImageSetBrush (gdImagePtr im, gdImagePtr brush){ int i; im->brush = brush; if ((!im->trueColor) && (!im->brush->trueColor)) { for (i = 0; (i < gdImageColorsTotal (brush)); i++) { int index; index = gdImageColorResolveAlpha (im, gdImageRed (brush, i), gdImageGreen (brush, i), gdImageBlue (brush, i), gdImageAlpha (brush, i)); im->brushColorMap[i] = index; } }}BGD_DECLARE(void) gdImageSetTile (gdImagePtr im, gdImagePtr tile){ int i; im->tile = tile; if ((!im->trueColor) && (!im->tile->trueColor)) { for (i = 0; (i < gdImageColorsTotal (tile)); i++) { int index; index = gdImageColorResolveAlpha (im, gdImageRed (tile, i), gdImageGreen (tile, i), gdImageBlue (tile, i), gdImageAlpha (tile, i)); im->tileColorMap[i] = index; } }}BGD_DECLARE(void) gdImageSetAntiAliased (gdImagePtr im, int c){ im->AA = 1; im->AA_color = c; im->AA_dont_blend = -1;}BGD_DECLARE(void) gdImageSetAntiAliasedDontBlend (gdImagePtr im, int c, int dont_blend){ im->AA = 1; im->AA_color = c; im->AA_dont_blend = dont_blend;}BGD_DECLARE(void) gdImageInterlace (gdImagePtr im, int interlaceArg){ im->interlace = interlaceArg;}BGD_DECLARE(int) gdImageCompare (gdImagePtr im1, gdImagePtr im2){ int x, y; int p1, p2; int cmpStatus = 0; int sx, sy; if (im1->interlace != im2->interlace) { cmpStatus |= GD_CMP_INTERLACE; } if (im1->transparent != im2->transparent) { cmpStatus |= GD_CMP_TRANSPARENT; } if (im1->trueColor != im2->trueColor) { cmpStatus |= GD_CMP_TRUECOLOR; } sx = im1->sx; if (im1->sx != im2->sx) { cmpStatus |= GD_CMP_SIZE_X + GD_CMP_IMAGE; if (im2->sx < im1->sx) { sx = im2->sx; } } sy = im1->sy; if (im1->sy != im2->sy) { cmpStatus |= GD_CMP_SIZE_Y + GD_CMP_IMAGE; if (im2->sy < im1->sy) { sy = im2->sy; } } if (im1->colorsTotal != im2->colorsTotal) { cmpStatus |= GD_CMP_NUM_COLORS; } for (y = 0; (y < sy); y++) { for (x = 0; (x < sx); x++) { p1 = im1->trueColor ? gdImageTrueColorPixel (im1, x, y) : gdImagePalettePixel (im1, x, y); p2 = im2->trueColor ? gdImageTrueColorPixel (im2, x, y) : gdImagePalettePixel (im2, x, y); if (gdImageRed (im1, p1) != gdImageRed (im2, p2)) { cmpStatus |= GD_CMP_COLOR + GD_CMP_IMAGE; break; } if (gdImageGreen (im1, p1) != gdImageGreen (im2, p2)) { cmpStatus |= GD_CMP_COLOR + GD_CMP_IMAGE; break; } if (gdImageBlue (im1, p1) != gdImageBlue (im2, p2)) { cmpStatus |= GD_CMP_COLOR + GD_CMP_IMAGE; break; }#if 0 /* Soon we'll add alpha channel to palettes */ if (gdImageAlpha (im1, p1) != gdImageAlpha (im2, p2)) { cmpStatus |= GD_CMP_COLOR + GD_CMP_IMAGE; break; }#endif } if (cmpStatus & GD_CMP_COLOR) { break; }; } return cmpStatus;}/* Thanks to Frank Warmerdam for this superior implementation of gdAlphaBlend(), which merges alpha in the destination color much better. */BGD_DECLARE(int) gdAlphaBlend (int dst, int src){ int src_alpha = gdTrueColorGetAlpha(src); int dst_alpha, alpha, red, green, blue; int src_weight, dst_weight, tot_weight;/* -------------------------------------------------------------------- *//* Simple cases we want to handle fast. *//* -------------------------------------------------------------------- */ if( src_alpha == gdAlphaOpaque ) return src; dst_alpha = gdTrueColorGetAlpha(dst); if( src_alpha == gdAlphaTransparent ) return dst; if( dst_alpha == gdAlphaTransparent ) return src;/* --
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -