📄 gd.c
字号:
void gdImageFilledArc (gdImagePtr im, int cx, int cy, int w, int h, int s, int e, int color, int style){ gdPoint pts[3]; int i; int lx = 0, ly = 0; int fx = 0, fy = 0; while (s<0) { s += 360; } while (e < s) { e += 360; } for (i = s; i <= e; i++) { int x, y; x = ((long) gdCosT[i % 360] * (long) w / (2 * 1024)) + cx; y = ((long) gdSinT[i % 360] * (long) h / (2 * 1024)) + cy; if (i != s) { if (!(style & gdChord)) { if (style & gdNoFill) { gdImageLine(im, lx, ly, x, y, color); } else { /* This is expensive! */ pts[0].x = lx; pts[0].y = ly; pts[1].x = x; pts[1].y = y; pts[2].x = cx; pts[2].y = cy; gdImageFilledPolygon(im, pts, 3, color); } } } else { fx = x; fy = y; } lx = x; ly = y; } if (style & gdChord) { if (style & gdNoFill) { if (style & gdEdged) { gdImageLine(im, cx, cy, lx, ly, color); gdImageLine(im, cx, cy, fx, fy, color); } gdImageLine(im, fx, fy, lx, ly, color); } else { pts[0].x = fx; pts[0].y = fy; pts[1].x = lx; pts[1].y = ly; pts[2].x = cx; pts[2].y = cy; gdImageFilledPolygon(im, pts, 3, color); } } else { if (style & gdNoFill) { if (style & gdEdged) { gdImageLine(im, cx, cy, lx, ly, color); gdImageLine(im, cx, cy, fx, fy, color); } } }}/** * Integer Ellipse functions (gdImageEllipse and gdImageFilledEllipse) * Function added by Pierre-Alain Joye 02/08/2003 (paj@pearfr.org) * See the ellipse function simplification for the equation * as well as the midpoint algorithm. */void gdImageEllipse(gdImagePtr im, int mx, int my, int w, int h, int c){ int x=0,mx1=0,mx2=0,my1=0,my2=0; long aq,bq,dx,dy,r,rx,ry,a,b; a=w>>1; b=h>>1; gdImageSetPixel(im,mx+a, my, c); gdImageSetPixel(im,mx-a, my, c); mx1 = mx-a;my1 = my; mx2 = mx+a;my2 = my; aq = a * a; bq = b * b; dx = aq << 1; dy = bq << 1; r = a * bq; rx = r << 1; ry = 0; x = a; while (x > 0){ if (r > 0) { my1++;my2--; ry +=dx; r -=ry; } if (r <= 0){ x--; mx1++;mx2--; rx -=dy; r +=rx; } gdImageSetPixel(im,mx1, my1, c); gdImageSetPixel(im,mx1, my2, c); gdImageSetPixel(im,mx2, my1, c); gdImageSetPixel(im,mx2, my2, c); }}void gdImageFilledEllipse (gdImagePtr im, int mx, int my, int w, int h, int c){ int x=0,mx1=0,mx2=0,my1=0,my2=0; long aq,bq,dx,dy,r,rx,ry,a,b; int i; int old_y1,old_y2; a=w>>1; b=h>>1; gdImageLine(im, mx-a, my, mx+a, my, c); mx1 = mx-a;my1 = my; mx2 = mx+a;my2 = my; aq = a * a; bq = b * b; dx = aq << 1; dy = bq << 1; r = a * bq; rx = r << 1; ry = 0; x = a; old_y2=-2; old_y1=-2; while (x > 0){ if (r > 0) { my1++;my2--; ry +=dx; r -=ry; } if (r <= 0){ x--; mx1++;mx2--; rx -=dy; r +=rx; } if(old_y2!=my2){ for(i=mx1;i<=mx2;i++){ gdImageSetPixel(im,i,my1,c); } } if(old_y2!=my2){ for(i=mx1;i<=mx2;i++){ gdImageSetPixel(im,i,my2,c); } } old_y2 = my2; old_y1 = my1; }}void gdImageFillToBorder (gdImagePtr im, int x, int y, int border, int color){ int lastBorder; /* Seek left */ int leftLimit = -1, rightLimit; int i, restoreAlphaBleding=0; if (border < 0) { /* Refuse to fill to a non-solid border */ return; } if (im->alphaBlendingFlag) { restoreAlphaBleding = 1; im->alphaBlendingFlag = 0; } if (x >= im->sx) { x = im->sx - 1; } if (y >= im->sy) { y = im->sy - 1; } for (i = x; i >= 0; i--) { if (gdImageGetPixel(im, i, y) == border) { break; } gdImageSetPixel(im, i, y, color); leftLimit = i; } if (leftLimit == -1) { if (restoreAlphaBleding) { im->alphaBlendingFlag = 1; } return; } /* Seek right */ rightLimit = x; for (i = (x + 1); i < im->sx; i++) { if (gdImageGetPixel(im, i, y) == border) { break; } gdImageSetPixel(im, i, y, color); rightLimit = i; } /* Look at lines above and below and start paints */ /* Above */ if (y > 0) { lastBorder = 1; for (i = leftLimit; i <= rightLimit; i++) { int c = gdImageGetPixel(im, i, y - 1); if (lastBorder) { if ((c != border) && (c != color)) { gdImageFillToBorder(im, i, y - 1, border, color); lastBorder = 0; } } else if ((c == border) || (c == color)) { lastBorder = 1; } } } /* Below */ if (y < ((im->sy) - 1)) { lastBorder = 1; for (i = leftLimit; i <= rightLimit; i++) { int c = gdImageGetPixel(im, i, y + 1); if (lastBorder) { if ((c != border) && (c != color)) { gdImageFillToBorder(im, i, y + 1, border, color); lastBorder = 0; } } else if ((c == border) || (c == color)) { lastBorder = 1; } } } if (restoreAlphaBleding) { im->alphaBlendingFlag = 1; }}/* * set the pixel at (x,y) and its 4-connected neighbors * with the same pixel value to the new pixel value nc (new color). * A 4-connected neighbor: pixel above, below, left, or right of a pixel. * ideas from comp.graphics discussions. * For tiled fill, the use of a flag buffer is mandatory. As the tile image can * contain the same color as the color to fill. To do not bloat normal filling * code I added a 2nd private function. *//* horizontal segment of scan line y */struct seg {int y, xl, xr, dy;};/* max depth of stack */#define FILL_MAX 1200000#define FILL_PUSH(Y, XL, XR, DY) \ if (sp<stack+FILL_MAX*10 && Y+(DY)>=0 && Y+(DY)<wy2) \ {sp->y = Y; sp->xl = XL; sp->xr = XR; sp->dy = DY; sp++;}#define FILL_POP(Y, XL, XR, DY) \ {sp--; Y = sp->y+(DY = sp->dy); XL = sp->xl; XR = sp->xr;}void _gdImageFillTiled(gdImagePtr im, int x, int y, int nc);void gdImageFill(gdImagePtr im, int x, int y, int nc){ int l, x1, x2, dy; int oc; /* old pixel value */ int wx2,wy2; int alphablending_bak; /* stack of filled segments */ /* struct seg stack[FILL_MAX],*sp = stack;; */ struct seg *stack; struct seg *sp; alphablending_bak = im->alphaBlendingFlag; im->alphaBlendingFlag = 0; if (nc==gdTiled){ _gdImageFillTiled(im,x,y,nc); im->alphaBlendingFlag = alphablending_bak; return; } wx2=im->sx;wy2=im->sy; oc = gdImageGetPixel(im, x, y); if (oc==nc || x<0 || x>wx2 || y<0 || y>wy2) { im->alphaBlendingFlag = alphablending_bak; return; } stack = (struct seg *)safe_emalloc(sizeof(struct seg), ((int)(im->sy*im->sx)/4), 1); sp = stack; /* required! */ FILL_PUSH(y,x,x,1); /* seed segment (popped 1st) */ FILL_PUSH(y+1, x, x, -1); while (sp>stack) { FILL_POP(y, x1, x2, dy); for (x=x1; x>=0 && gdImageGetPixel(im,x, y)==oc; x--) { gdImageSetPixel(im,x, y, nc); } if (x>=x1) { goto skip; } l = x+1; /* leak on left? */ if (l<x1) { FILL_PUSH(y, l, x1-1, -dy); } x = x1+1; do { for (; x<=wx2 && gdImageGetPixel(im,x, y)==oc; x++) { gdImageSetPixel(im, x, y, nc); } FILL_PUSH(y, l, x-1, dy); /* leak on right? */ if (x>x2+1) { FILL_PUSH(y, x2+1, x-1, -dy); }skip: for (x++; x<=x2 && (gdImageGetPixel(im, x, y)!=oc); x++); l = x; } while (x<=x2); } efree(stack); im->alphaBlendingFlag = alphablending_bak; }void _gdImageFillTiled(gdImagePtr im, int x, int y, int nc){ int i,l, x1, x2, dy; int oc; /* old pixel value */ int tiled; int wx2,wy2; /* stack of filled segments */ struct seg *stack; struct seg *sp; int **pts; if(!im->tile){ return; } wx2=im->sx;wy2=im->sy; tiled = nc==gdTiled; nc = gdImageTileGet(im,x,y); pts = (int **) ecalloc(sizeof(int *) * im->sy, sizeof(int)); for (i=0; i<im->sy;i++) { pts[i] = (int *) ecalloc(im->sx, sizeof(int)); } stack = (struct seg *)safe_emalloc(sizeof(struct seg), ((int)(im->sy*im->sx)/4), 1); sp = stack; oc = gdImageGetPixel(im, x, y); /* required! */ FILL_PUSH(y,x,x,1); /* seed segment (popped 1st) */ FILL_PUSH(y+1, x, x, -1); while (sp>stack) { FILL_POP(y, x1, x2, dy); for (x=x1; x>=0 && (!pts[y][x] && gdImageGetPixel(im,x,y)==oc); x--) { if (pts[y][x]){ /* we should never be here */ break; } nc = gdImageTileGet(im,x,y); pts[y][x]=1; gdImageSetPixel(im,x, y, nc); } if (x>=x1) { goto skip; } l = x+1; /* leak on left? */ if (l<x1) { FILL_PUSH(y, l, x1-1, -dy); } x = x1+1; do { for (; x<=wx2 && (!pts[y][x] && gdImageGetPixel(im,x, y)==oc) ; x++) { if (pts[y][x]){ /* we should never be here */ break; } nc = gdImageTileGet(im,x,y); pts[y][x]=1; gdImageSetPixel(im, x, y, nc); } FILL_PUSH(y, l, x-1, dy); /* leak on right? */ if (x>x2+1) { FILL_PUSH(y, x2+1, x-1, -dy); }skip: for (x++; x<=x2 && (pts[y][x] || gdImageGetPixel(im,x, y)!=oc); x++); l = x; } while (x<=x2); } for (i=0; i<im->sy;i++) { efree(pts[i]); } efree(pts); efree(stack);}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; int half1 = 1; int t; if (y2 < y1) { t=y1; y1 = y2; y2 = t; t = x1; x1 = x2; x2 = t; } x1h = x1; x1v = x1; y1h = y1; y1v = y1; x2h = x2; x2v = x2; y2h = y2; y2v = y2; if (thick > 1) { int cx, cy, x1ul, y1ul, x2lr, y2lr; int half = thick >> 1; half1 = thick - half; x1ul = x1 - half; y1ul = y1 - half; x2lr = x2 + half; y2lr = y2 + half; cy = y1ul + thick; while (cy-- > y1ul) { cx = x1ul - 1; while (cx++ < x2lr) { gdImageSetPixel(im, cx, cy, color); } } cy = y2lr - thick; while (cy++ < y2lr) { cx = x1ul - 1; while (cx++ < x2lr) { gdImageSetPixel(im, cx, cy, color); } } cy = y1ul + thick - 1; while (cy++ < y2lr -thick) { cx = x1ul - 1; while (cx++ < x1ul + thick) { gdImageSetPixel(im, cx, cy, color); } } cy = y1ul + thick - 1; while (cy++ < y2lr -thick) { cx = x2lr - thick - 1; while (cx++ < x2lr) { gdImageSetPixel(im, cx, cy, color); } } return; } else { y1v = y1h + 1; y2v = y2h - 1; 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); }}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); } if (x1 > x2) { x = x1; x1 = x2; x2 = x; } if (y1 > y2) { y = y1; y1 = y2; y2 = y; } for (y = y1; (y <= y2); y++) { for (x = x1; (x <= x2); x++) { gdImageSetPixel (im, x, y, color); } }}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];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -