static void gd_bezier(point* A, int n, int arrow_at_start, int arrow_at_end) { pointf p0, p1, V[4]; int i, j, step; int style[20]; int pen, width; gdImagePtr brush = NULL; if (cstk[SP].pen != P_NONE) { if (cstk[SP].pen == P_DASHED) { for (i = 0; i < 10; i++) style[i] = cstk[SP].pencolor; for (; i < 20; i++) style[i] = gdTransparent; gdImageSetStyle(im, style, 20); pen = gdStyled; } else if (cstk[SP].pen == P_DOTTED) { for (i = 0; i < 2; i++) style[i] = cstk[SP].pencolor; for (; i < 12; i++) style[i] = gdTransparent; gdImageSetStyle(im, style, 12); pen = gdStyled; } else { pen = cstk[SP].pencolor; } #if 0 if (cstk[SP].penwidth != WIDTH_NORMAL) { width=cstk[SP].penwidth; brush = gdImageCreate(width,width); gdImagePaletteCopy(brush, im); gdImageFilledRectangle(brush, 0,0,width-1, width-1, cstk[SP].pencolor); gdImageSetBrush(im, brush); if (pen == gdStyled) pen = gdStyledBrushed; else pen = gdBrushed; } #else width = cstk[SP].penwidth; gdImageSetThickness(im, width); #endif V[3].x = A[0].x; V[3].y = A[0].y; for (i = 0; i+3 < n; i += 3) { V[0] = V[3]; for (j = 1; j <= 3; j++) { V[j].x = A[i+j].x; V[j].y = A[i+j].y; } p0 = gdpt(V[0]); for (step = 1; step <= BEZIERSUBDIVISION; step++) { p1 = gdpt(Bezier(V, 3, (double)step/BEZIERSUBDIVISION, NULL, NULL)); gdImageLine(im, ROUND(p0.x), ROUND(p0.y), ROUND(p1.x), ROUND(p1.y), pen); p0 = p1; } } if (brush) gdImageDestroy(brush); } }
static void gd_polyline(point* A, int n) { pointf p, p1; int i; int style[20]; int pen, width; gdImagePtr brush = NULL; if (cstk[SP].pen != P_NONE) { if (cstk[SP].pen == P_DASHED) { for (i = 0; i < 10; i++) style[i] = cstk[SP].pencolor; for (; i < 20; i++) style[i] = gdTransparent; gdImageSetStyle(im, style, 20); pen = gdStyled; } else if (cstk[SP].pen == P_DOTTED) { for (i = 0; i < 2; i++) style[i] = cstk[SP].pencolor; for (; i < 12; i++) style[i] = gdTransparent; gdImageSetStyle(im, style, 12); pen = gdStyled; } else { pen = cstk[SP].pencolor; } #if 0 if (cstk[SP].penwidth != WIDTH_NORMAL) { width = cstk[SP].penwidth; brush = gdImageCreate(width,width); gdImagePaletteCopy(brush, im); gdImageFilledRectangle(brush, 0,0,width-1,width-1,cstk[SP].pencolor); gdImageSetBrush(im, brush); if (pen == gdStyled) pen = gdStyledBrushed; else pen = gdBrushed; } #else width = cstk[SP].penwidth; gdImageSetThickness(im, width); #endif p.x = A[0].x; p.y = A[0].y; p = gdpt(p); for (i = 1; i < n; i++) { p1.x = A[i].x; p1.y = A[i].y; p1 = gdpt(p1); gdImageLine(im, ROUND(p.x), ROUND(p.y), ROUND(p1.x), ROUND(p1.y), pen); p.x = p1.x; p.y = p1.y; } if (brush) gdImageDestroy(brush); } }
static void gd_ellipse(point p, int rx, int ry, int filled) { pointf mp; int i; int style[40]; /* need 2* size for arcs, I don't know why */ int pen, width; gdImagePtr brush = NULL; if (cstk[SP].pen != P_NONE) { if (cstk[SP].pen == P_DASHED) { for (i = 0; i < 20; i++) style[i] = cstk[SP].pencolor; for (; i < 40; i++) style[i] = gdTransparent; gdImageSetStyle(im, style, 40); pen = gdStyled; } else if (cstk[SP].pen == P_DOTTED) { for (i = 0; i < 2; i++) style[i] = cstk[SP].pencolor; for (; i < 24; i++) style[i] = gdTransparent; gdImageSetStyle(im, style, 24); pen = gdStyled; } else { pen = cstk[SP].pencolor; } #if 1 /* use brush instead of Thickness to improve outline appearance */ gdImageSetThickness(im, WIDTH_NORMAL); if (cstk[SP].penwidth != WIDTH_NORMAL) { width = cstk[SP].penwidth; brush = gdImageCreate(width,width); gdImagePaletteCopy(brush, im); gdImageFilledRectangle(brush, 0,0,width-1, width-1, cstk[SP].pencolor); gdImageSetBrush(im, brush); if (pen == gdStyled) pen = gdStyledBrushed; else pen = gdBrushed; } #else width = cstk[SP].penwidth; gdImageSetThickness(im, width); #endif if (Rot) {int t; t = rx; rx = ry; ry = t;} mp.x = p.x; mp.y = p.y; mp = gdpt(mp); if (filled) { gdImageFilledEllipse(im, ROUND(mp.x), ROUND(mp.y), ROUND(Zoom*(rx + rx)), ROUND(Zoom*(ry + ry)), cstk[SP].fillcolor); } gdImageArc(im, ROUND(mp.x), ROUND(mp.y), ROUND(Zoom*(rx + rx)), ROUND(Zoom*(ry + ry)), 0, 360, pen); if (brush) gdImageDestroy(brush); } }
static void gd_polygon(point *A, int n, int filled) { pointf p; int i; gdPoint *points; int style[20]; int pen, width; gdImagePtr brush = NULL; if (cstk[SP].pen != P_NONE) { if (cstk[SP].pen == P_DASHED) { for (i = 0; i < 10; i++) style[i] = cstk[SP].pencolor; for (; i < 20; i++) style[i] = gdTransparent; gdImageSetStyle(im, style, 20); pen = gdStyled; } else if (cstk[SP].pen == P_DOTTED) { for (i = 0; i < 2; i++) style[i] = cstk[SP].pencolor; for (; i < 12; i++) style[i] = gdTransparent; gdImageSetStyle(im, style, 12); pen = gdStyled; } else { pen = cstk[SP].pencolor; } #if 1 /* use brush instead of Thickness to improve end butts */ gdImageSetThickness(im, WIDTH_NORMAL); if (cstk[SP].penwidth != WIDTH_NORMAL) { width=cstk[SP].penwidth * Zoom; brush = gdImageCreate(width,width); gdImagePaletteCopy(brush, im); gdImageFilledRectangle(brush, 0,0,width-1, width-1, cstk[SP].pencolor); gdImageSetBrush(im, brush); if (pen == gdStyled) pen = gdStyledBrushed; else pen = gdBrushed; } #else width = cstk[SP].penwidth; gdImageSetThickness(im, width); #endif points = N_GNEW(n,gdPoint); for (i = 0; i < n; i++) { p.x = A[i].x; p.y = A[i].y; p = gdpt(p); points[i].x = ROUND(p.x); points[i].y = ROUND(p.y); } if (filled) gdImageFilledPolygon(im, points, n, cstk[SP].fillcolor); gdImagePolygon(im, points, n, pen); free(points); if (brush) gdImageDestroy(brush); } }
static int set_penstyle(GVJ_t * job, gdImagePtr im, gdImagePtr brush) { obj_state_t *obj = job->obj; int i, pen, pencolor, transparent, width, dashstyle[40]; pen = pencolor = color_index(im, obj->pencolor); transparent = gdImageGetTransparent(im); if (obj->pen == PEN_DASHED) { for (i = 0; i < 20; i++) dashstyle[i] = pencolor; for (; i < 40; i++) dashstyle[i] = transparent; gdImageSetStyle(im, dashstyle, 20); pen = gdStyled; } else if (obj->pen == PEN_DOTTED) { for (i = 0; i < 2; i++) dashstyle[i] = pencolor; for (; i < 24; i++) dashstyle[i] = transparent; gdImageSetStyle(im, dashstyle, 24); pen = gdStyled; } width = obj->penwidth * job->scale.x; if (width < PENWIDTH_NORMAL) width = PENWIDTH_NORMAL; /* gd can't do thin lines */ gdImageSetThickness(im, width); /* use brush instead of Thickness to improve end butts */ if (width != PENWIDTH_NORMAL) { brush = gdImageCreate(width, width); gdImagePaletteCopy(brush, im); gdImageFilledRectangle(brush, 0, 0, width - 1, width - 1, pencolor); gdImageSetBrush(im, brush); if (pen == gdStyled) pen = gdStyledBrushed; else pen = gdBrushed; } return pen; }
int renderLineGD(imageObj *img, shapeObj *p, strokeStyleObj *stroke) { gdImagePtr ip; int c; gdImagePtr brush=NULL; if(!img || !p || !stroke) return MS_FAILURE; if(!(ip = MS_IMAGE_GET_GDIMAGEPTR(img))) return MS_FAILURE; SETPEN(ip, stroke->color); c = stroke->color->pen; if(stroke->patternlength > 0) { int *style; int i, j, k=0; int sc; for(i=0; i<stroke->patternlength; i++) k += MS_NINT(stroke->pattern[i]); style = (int *) malloc (k * sizeof(int)); MS_CHECK_ALLOC(style, k * sizeof(int), MS_FAILURE); sc = c; /* start with the color */ k=0; for(i=0; i<stroke->patternlength; i++) { for(j=0; j<MS_NINT(stroke->pattern[i]); j++, k++) { style[k] = sc; } sc = ((sc==c)?gdTransparent:c); } gdImageSetStyle(ip, style, k); free(style); c = gdStyled; } if(stroke->width > 1) { int brush_fc; brush = gdImageCreate(ceil(stroke->width), ceil(stroke->width)); gdImageColorAllocate(brush, gdImageRed(ip,0), gdImageGreen(ip, 0), gdImageBlue(ip, 0)); gdImageColorTransparent(brush,0); brush_fc = gdImageColorAllocate(brush, gdImageRed(ip,stroke->color->pen), gdImageGreen(ip,stroke->color->pen), gdImageBlue(ip,stroke->color->pen)); gdImageFilledEllipse(brush,MS_NINT(brush->sx/2),MS_NINT(brush->sy/2), MS_NINT(stroke->width),MS_NINT(stroke->width), brush_fc); gdImageSetBrush(ip, brush); if(stroke->patternlength > 0) { c = gdStyledBrushed; } else { c = gdBrushed; } } /* finally draw something */ imagePolyline(ip, p, c); /* clean up */ if(stroke->width>1) { gdImageDestroy(brush); } return MS_SUCCESS; }
int main (void) { #ifdef HAVE_LIBPNG /* Input and output files */ FILE *in; FILE *out; /* Input and output images */ gdImagePtr im_in = 0, im_out = 0; /* Brush image */ gdImagePtr brush; /* Color indexes */ int white; int blue; int red; int green; /* Points for polygon */ gdPoint points[3]; int i; /* Create output image, in true color. */ im_out = gdImageCreateTrueColor (256 + 384, 384); /* 2.0.2: first color allocated would automatically be background in a palette based image. Since this is a truecolor image, with an automatic background of black, we must fill it explicitly. */ white = gdImageColorAllocate (im_out, 255, 255, 255); gdImageFilledRectangle (im_out, 0, 0, gdImageSX (im_out), gdImageSY (im_out), white); /* Set transparent color. */ gdImageColorTransparent (im_out, white); /* Try to load demoin.png and paste part of it into the output image. */ in = fopen ("demoin.png", "rb"); if (!in) { fprintf (stderr, "Can't load source image; this demo\n"); fprintf (stderr, "is much more impressive if demoin.png\n"); fprintf (stderr, "is available.\n"); im_in = 0; } else { int a; im_in = gdImageCreateFromPng (in); fclose (in); /* Now copy, and magnify as we do so */ gdImageCopyResampled (im_out, im_in, 32, 32, 0, 0, 192, 192, 255, 255); /* Now display variously rotated space shuttles in a circle of our own */ for (a = 0; (a < 360); a += 45) { int cx = cos (a * .0174532925) * 128; int cy = -sin (a * .0174532925) * 128; gdImageCopyRotated (im_out, im_in, 256 + 192 + cx, 192 + cy, 0, 0, gdImageSX (im_in), gdImageSY (im_in), a); } } red = gdImageColorAllocate (im_out, 255, 0, 0); green = gdImageColorAllocate (im_out, 0, 255, 0); blue = gdImageColorAllocate (im_out, 0, 0, 255); /* Fat Rectangle */ gdImageSetThickness (im_out, 4); gdImageLine (im_out, 16, 16, 240, 16, green); gdImageLine (im_out, 240, 16, 240, 240, green); gdImageLine (im_out, 240, 240, 16, 240, green); gdImageLine (im_out, 16, 240, 16, 16, green); gdImageSetThickness (im_out, 1); /* Circle */ gdImageArc (im_out, 128, 128, 60, 20, 0, 720, blue); /* Arc */ gdImageArc (im_out, 128, 128, 40, 40, 90, 270, blue); /* Flood fill: doesn't do much on a continuously variable tone jpeg original. */ gdImageFill (im_out, 8, 8, blue); /* Polygon */ points[0].x = 64; points[0].y = 0; points[1].x = 0; points[1].y = 128; points[2].x = 128; points[2].y = 128; gdImageFilledPolygon (im_out, points, 3, green); /* 2.0.12: Antialiased Polygon */ gdImageSetAntiAliased (im_out, green); for (i = 0; (i < 3); i++) { points[i].x += 128; } gdImageFilledPolygon (im_out, points, 3, gdAntiAliased); /* Brush. A fairly wild example also involving a line style! */ if (im_in) { int style[8]; brush = gdImageCreateTrueColor (16, 16); gdImageCopyResized (brush, im_in, 0, 0, 0, 0, gdImageSX (brush), gdImageSY (brush), gdImageSX (im_in), gdImageSY (im_in)); gdImageSetBrush (im_out, brush); /* With a style, so they won't overprint each other. Normally, they would, yielding a fat-brush effect. */ style[0] = 0; style[1] = 0; style[2] = 0; style[3] = 0; style[4] = 0; style[5] = 0; style[6] = 0; style[7] = 1; gdImageSetStyle (im_out, style, 8); /* Draw the styled, brushed line */ gdImageLine (im_out, 0, 255, 255, 0, gdStyledBrushed); } /* Text (non-truetype; see gdtestft for a freetype demo) */ gdImageString (im_out, gdFontGiant, 32, 32, (unsigned char *) "hi", red); gdImageStringUp (im_out, gdFontSmall, 64, 64, (unsigned char *) "hi", red); /* Random antialiased lines; coordinates all over the image, but the output will respect a small clipping rectangle */ gdImageSetClip(im_out, 0, gdImageSY(im_out) - 100, 100, gdImageSY(im_out)); /* Fixed seed for reproducibility of results */ srand(100); for (i = 0; (i < 100); i++) { int x1 = rand() % gdImageSX(im_out); int y1 = rand() % gdImageSY(im_out); int x2 = rand() % gdImageSX(im_out); int y2 = rand() % gdImageSY(im_out); gdImageSetAntiAliased(im_out, white); gdImageLine (im_out, x1, y1, x2, y2, gdAntiAliased); } /* Make output image interlaced (progressive, in the case of JPEG) */ gdImageInterlace (im_out, 1); out = fopen ("demoout.png", "wb"); /* Write PNG */ gdImagePng (im_out, out); fclose (out); /* 2.0.12: also write a paletteized version */ out = fopen ("demooutp.png", "wb"); gdImageTrueColorToPalette (im_out, 0, 256); gdImagePng (im_out, out); fclose (out); gdImageDestroy (im_out); if (im_in) { gdImageDestroy (im_in); } #else fprintf (stderr, "No PNG library support.\n"); #endif /* HAVE_LIBPNG */ return 0; }
int main(void) { /* Input and output files */ FILE *in; FILE *out; /* Input and output images */ gdImagePtr im_in, im_out; /* Brush image */ gdImagePtr brush; /* Color indexes */ int white; int blue; int red; int green; /* Points for polygon */ gdPoint points[3]; /* Create output image, 128 by 128 pixels. */ im_out = gdImageCreate(128, 128); /* First color allocated is background. */ white = gdImageColorAllocate(im_out, 255, 255, 255); /* Set transparent color. */ gdImageColorTransparent(im_out, white); /* Try to load demoin.png and paste part of it into the output image. */ in = fopen("demoin.png", "rb"); if (!in) { fprintf(stderr, "Can't load source image; this demo\n"); fprintf(stderr, "is much more impressive if demoin.png\n"); fprintf(stderr, "is available.\n"); im_in = 0; } else { im_in = gdImageCreateFromPng(in); fclose(in); /* Now copy, and magnify as we do so */ gdImageCopyResized(im_out, im_in, 16, 16, 0, 0, 96, 96, 127, 127); } red = gdImageColorAllocate(im_out, 255, 0, 0); green = gdImageColorAllocate(im_out, 0, 255, 0); blue = gdImageColorAllocate(im_out, 0, 0, 255); /* Rectangle */ gdImageLine(im_out, 8, 8, 120, 8, green); gdImageLine(im_out, 120, 8, 120, 120, green); gdImageLine(im_out, 120, 120, 8, 120, green); gdImageLine(im_out, 8, 120, 8, 8, green); /* Circle */ gdImageArc(im_out, 64, 64, 30, 10, 0, 360, blue); /* Arc */ gdImageArc(im_out, 64, 64, 20, 20, 45, 135, blue); /* Flood fill */ gdImageFill(im_out, 4, 4, blue); /* Polygon */ points[0].x = 32; points[0].y = 0; points[1].x = 0; points[1].y = 64; points[2].x = 64; points[2].y = 64; gdImageFilledPolygon(im_out, points, 3, green); /* Brush. A fairly wild example also involving a line style! */ if (im_in) { int style[8]; brush = gdImageCreate(8, 8); gdImageCopyResized(brush, im_in, 0, 0, 0, 0, gdImageSX(brush), gdImageSY(brush), gdImageSX(im_in), gdImageSY(im_in)); gdImageSetBrush(im_out, brush); /* With a style, so they won't overprint each other. Normally, they would, yielding a fat-brush effect. */ style[0] = 0; style[1] = 0; style[2] = 0; style[3] = 0; style[4] = 0; style[5] = 0; style[6] = 0; style[7] = 1; gdImageSetStyle(im_out, style, 8); /* Draw the styled, brushed line */ gdImageLine(im_out, 0, 127, 127, 0, gdStyledBrushed); } /* Text */ gdImageString(im_out, gdFontGiant, 16, 16, (unsigned char *) "hi", red); gdImageStringUp(im_out, gdFontSmall, 32, 32, (unsigned char *) "hi", red); /* Make output image interlaced (allows "fade in" in some viewers, and in the latest web browsers) */ gdImageInterlace(im_out, 1); out = fopen("demoout.png", "wb"); /* Write PNG */ gdImagePng(im_out, out); fclose(out); gdImageDestroy(im_out); if (im_in) { gdImageDestroy(im_in); } return 0; }
static int setlinestyle (wmfAPI* API,wmfDC* dc) { wmf_gd_t* ddata = WMF_GD_GetData (API); gd_t* gd = (gd_t*) ddata->gd_data; wmfPen* pen = 0; wmfRGB* rgb = 0; int pen_width; int pen_height; int fg; int bg; int linestyle; int i; int style[14]; pen = WMF_DC_PEN (dc); /* Color */ rgb = WMF_PEN_COLOR (pen); fg = gdImageColorResolve (gd->image,rgb->r,rgb->g,rgb->b); rgb = WMF_DC_BACKGROUND (dc); bg = gdImageColorResolve (gd->image,rgb->r,rgb->g,rgb->b); linestyle = fg; /* Size */ pen_width = (int) ceil ((double) gd_width (API,WMF_PEN_WIDTH (pen))); pen_height = (int) ceil ((double) gd_height (API,WMF_PEN_HEIGHT (pen))); if (pen_width < 1) pen_width = 1; if (pen_height < 1) pen_height = 1; if ((pen_width == 1) && (pen_height == 1)) { /* Ordinary line */ } else { if (gd->pen.image == 0) { /* Need to create a brush */ gd->pen.image = gdImageCreateTrueColor (pen_width,pen_height); } else if ((pen_width == gd->pen.width) && (pen_height == gd->pen.height)) { /* Already have brush of correct size */ } else { /* Need to free current brush & create new one */ gdImageDestroy (gd->pen.image); gd->pen.image = gdImageCreateTrueColor (pen_width,pen_height); } if (gd->pen.image) { gd->pen.width = pen_width; gd->pen.height = pen_height; rgb = WMF_PEN_COLOR (pen); fg = gdImageColorResolve (gd->pen.image,rgb->r,rgb->g,rgb->b); rgb = WMF_DC_BACKGROUND (dc); bg = gdImageColorResolve (gd->image,rgb->r,rgb->g,rgb->b); if (bg != fg) gdImageColorTransparent (gd->pen.image,bg); gdImageFilledRectangle (gd->pen.image,0,0,gd->pen.width,gd->pen.height,bg); /* `Square' nib */ gdImageFilledRectangle (gd->pen.image,0,0,gd->pen.width,gd->pen.height,fg); gdImageSetBrush (gd->image,gd->pen.image); linestyle = gdBrushed; } } switch (WMF_PEN_STYLE (pen)) { case PS_DASH: for (i = 0; i < 5; i++) style[i] = fg; for (i = 5; i < 8; i++) style[i] = bg; gdImageSetStyle (gd->image,style, 8); if (linestyle == gdBrushed) { linestyle = gdStyledBrushed; } else { linestyle = gdStyled; } break; case PS_DOT: for (i = 0; i < 2; i++) style[i] = fg; for (i = 2; i < 4; i++) style[i] = bg; gdImageSetStyle (gd->image,style, 4); if (linestyle == gdBrushed) { linestyle = gdStyledBrushed; } else { linestyle = gdStyled; } break; case PS_DASHDOT: for (i = 0; i < 4; i++) style[i] = fg; for (i = 4; i < 7; i++) style[i] = bg; for (i = 7; i < 9; i++) style[i] = fg; for (i = 9; i < 12; i++) style[i] = bg; gdImageSetStyle (gd->image,style,12); if (linestyle == gdBrushed) { linestyle = gdStyledBrushed; } else { linestyle = gdStyled; } break; case PS_DASHDOTDOT: for (i = 0; i < 4; i++) style[i] = fg; for (i = 4; i < 6; i++) style[i] = bg; for (i = 6; i < 8; i++) style[i] = fg; for (i = 8; i < 10; i++) style[i] = bg; for (i = 10; i < 12; i++) style[i] = fg; for (i = 12; i < 14; i++) style[i] = bg; gdImageSetStyle (gd->image,style,14); if (linestyle == gdBrushed) { linestyle = gdStyledBrushed; } else { linestyle = gdStyled; } break; case PS_INSIDEFRAME: /* There is nothing to do in this case... */ case PS_SOLID: default: break; } return (linestyle); }
static void gd_bezier(point * A, int n, int arrow_at_start, int arrow_at_end, int filled) { pointf p, p0, p1, V[4]; int i, j, step; int style[20]; int pen, width; gdImagePtr brush = NULL; gdPoint F[4]; if (!im) return; if (cstk[SP].pen != P_NONE) { if (cstk[SP].pen == P_DASHED) { for (i = 0; i < 10; i++) style[i] = cstk[SP].pencolor; for (; i < 20; i++) style[i] = transparent; gdImageSetStyle(im, style, 20); pen = gdStyled; } else if (cstk[SP].pen == P_DOTTED) { for (i = 0; i < 2; i++) style[i] = cstk[SP].pencolor; for (; i < 12; i++) style[i] = transparent; gdImageSetStyle(im, style, 12); pen = gdStyled; } else { pen = cstk[SP].pencolor; } width = cstk[SP].penwidth * CompScale; if (width < WIDTH_NORMAL) width = WIDTH_NORMAL; /* gd can't do thin lines */ gdImageSetThickness(im, width); if (width > WIDTH_NORMAL) { brush = gdImageCreate(width, width); gdImagePaletteCopy(brush, im); gdImageFilledRectangle(brush, 0, 0, width - 1, width - 1, cstk[SP].pencolor); gdImageSetBrush(im, brush); if (pen == gdStyled) pen = gdStyledBrushed; else pen = gdBrushed; } p.x = A[0].x; p.y = A[0].y; p = gdpt(p); F[0].x = ROUND(p.x); F[0].y = ROUND(p.y); p.x = A[n-1].x; p.y = A[n-1].y; p = gdpt(p); F[3].x = ROUND(p.x); F[3].y = ROUND(p.y); V[3].x = A[0].x; V[3].y = A[0].y; for (i = 0; i + 3 < n; i += 3) { V[0] = V[3]; for (j = 1; j <= 3; j++) { V[j].x = A[i + j].x; V[j].y = A[i + j].y; } p0 = gdpt(V[0]); for (step = 1; step <= BEZIERSUBDIVISION; step++) { p1 = gdpt(Bezier (V, 3, (double) step / BEZIERSUBDIVISION, NULL, NULL)); gdImageLine(im, ROUND(p0.x), ROUND(p0.y), ROUND(p1.x), ROUND(p1.y), pen); if (filled) { F[1].x = ROUND(p0.x); F[1].y = ROUND(p0.y); F[2].x = ROUND(p1.x); F[2].y = ROUND(p1.y); gdImageFilledPolygon(im, F, 4, cstk[SP].fillcolor); } p0 = p1; } } if (brush) gdImageDestroy(brush); } }