int main(void) { gdImagePtr im; int white, black, r; gdPointPtr points; im = gdImageCreate(100, 100); if (!im) exit(EXIT_FAILURE); white = gdImageColorAllocate(im, 0xff, 0xff, 0xff); black = gdImageColorAllocate(im, 0, 0, 0); gdImageFilledRectangle(im, 0, 0, 99, 99, white); points = (gdPointPtr)gdCalloc(3, sizeof(gdPoint)); if (!points) { gdImageDestroy(im); exit(EXIT_FAILURE); } points[0].x = 10; points[0].y = 10; points[1].x = 50; points[1].y = 70; points[2].x = 90; points[2].y = 30; gdImagePolygon(im, points, 3, black); r = gdAssertImageEqualsToFile(GDTEST_TOP_DIR "/gdimagepolygon/gdimagepolygon3.png", im); gdFree(points); gdImageDestroy(im); if (!r) exit(EXIT_FAILURE); return EXIT_SUCCESS; }
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); } }
int main(void) { gdImagePtr im; int white, black, r; im = gdImageCreate(100, 100); if (!im) exit(EXIT_FAILURE); white = gdImageColorAllocate(im, 0xff, 0xff, 0xff); black = gdImageColorAllocate(im, 0, 0, 0); gdImageFilledRectangle(im, 0, 0, 99, 99, white); gdImagePolygon(im, NULL, 0, black); /* no effect */ gdImagePolygon(im, NULL, -1, black); /* no effect */ r = gdAssertImageEqualsToFile(GDTEST_TOP_DIR "/gdimagepolygon/gdimagepolygon0.png", im); gdImageDestroy(im); if (!r) exit(EXIT_FAILURE); return EXIT_SUCCESS; }
void doPolygon(FILE *stream) { gdPoint points[10]; int n, i, c; n = getNumber(stream); for (i = 0; i < n; i++) { points[i].x = viewx(getNumber(stream)); points[i].y = viewy(getNumber(stream)); } c = getColor(getNumber(stream)); gdImagePolygon(image, points, n, c); }
result_t Image::polygon(v8::Local<v8::Array> points, int32_t color) { if (!m_image) return CHECK_ERROR(CALL_E_INVALID_CALL); std::vector < gdPoint > pts; result_t hr = getPoints(points, pts); if (hr < 0) return hr; gdImagePolygon(m_image, pts.data(), (int32_t) pts.size(), color); return 0; }
void dowheel (gdImagePtr im, int color, char *fontfile, int fontsize, double angle, int x, int y, int offset, char *string) { int brect[8]; FILE *err; double curangrads, curang, x0, y0; char *cp; err = fopen ("err.out", "a"); doerr (err, "------------- New fontwheel --------------"); doerr (err, fontfile); doerr (err, string); doerr (err, "------------------------------------------"); for (curang = 0.0; curang < 360.0; curang += angle) { curangrads = DEGTORAD(curang); x0 = x + cos (curangrads) * offset; y0 = y - sin (curangrads) * offset; /* The case of newlines is taken care of in the gdImageStringTTF call */ #if defined(OLDER_GD) cp = gdImageStringTTF (im, brect, color, fontfile, fontsize, curangrads, x0, y0, string); #else cp = gdImageStringFT (im, brect, color, fontfile, fontsize, curangrads, x0, y0, string); #endif if (cp) doerr (err, cp); gdImagePolygon (im, (gdPointPtr)brect, 4, color); } fclose (err); }
int renderVectorSymbolGD(imageObj *img, double x, double y, symbolObj *symbol, symbolStyleObj *style) { int bRotated = MS_FALSE; int j,k; gdImagePtr ip; gdPoint mPoints[MS_MAXVECTORPOINTS]; gdPoint oldpnt,newpnt; int fc,oc; if(!(ip = MS_IMAGE_GET_GDIMAGEPTR(img))) return MS_FAILURE; SETPEN(ip, style->color); SETPEN(ip, style->outlinecolor); fc = style->color ? style->color->pen : -1; oc = style->outlinecolor ? style->outlinecolor->pen : -1; if(oc==-1 && fc ==-1) { return MS_SUCCESS; } if (style->rotation != 0.0) { bRotated = MS_TRUE; symbol = rotateVectorSymbolPoints(symbol, style->rotation); if(!symbol) { return MS_FAILURE; } } /* We avoid MS_NINT in this context because the potentially variable handling of 0.5 rounding is often a problem for symbols which are often an odd size (ie. 7pixels) and so if "p" is integral the value is always on a 0.5 boundary - bug 1716 */ x -= style->scale*.5*symbol->sizex; y -= style->scale*.5*symbol->sizey; if(symbol->filled) { /* if filled */ k = 0; /* point counter */ for(j=0; j < symbol->numpoints; j++) { if((symbol->points[j].x == -99) && (symbol->points[j].y == -99)) { /* new polygon (PENUP) */ if(k>2) { if(fc >= 0) gdImageFilledPolygon(ip, mPoints, k, fc); if(oc >= 0) gdImagePolygon(ip, mPoints, k, oc); } k = 0; /* reset point counter */ } else { mPoints[k].x = MS_NINT(style->scale*symbol->points[j].x + x); mPoints[k].y = MS_NINT(style->scale*symbol->points[j].y + y); k++; } } if(fc >= 0) gdImageFilledPolygon(ip, mPoints, k, fc); if(oc >= 0) gdImagePolygon(ip, mPoints, k, oc); } else { /* NOT filled */ if(oc >= 0) fc = oc; /* try the outline color (reference maps sometimes do this when combining a box and a custom vector marker */ oldpnt.x = MS_NINT(style->scale*symbol->points[0].x + x); /* convert first point in marker */ oldpnt.y = MS_NINT(style->scale*symbol->points[0].y + y); gdImageSetThickness(ip, style->outlinewidth); for(j=1; j < symbol->numpoints; j++) { /* step through the marker */ if((symbol->points[j].x != -99) || (symbol->points[j].y != -99)) { if((symbol->points[j-1].x == -99) && (symbol->points[j-1].y == -99)) { /* Last point was PENUP, now a new beginning */ oldpnt.x = MS_NINT(style->scale*symbol->points[j].x + x); oldpnt.y = MS_NINT(style->scale*symbol->points[j].y + y); } else { newpnt.x = MS_NINT(style->scale*symbol->points[j].x + x); newpnt.y = MS_NINT(style->scale*symbol->points[j].y + y); gdImageLine(ip, oldpnt.x, oldpnt.y, newpnt.x, newpnt.y, fc); oldpnt = newpnt; } } } /* end for loop */ gdImageSetThickness(ip, 1); /* restore thinkness */ } /* end if-then-else */ if(bRotated) { msFreeSymbol(symbol); /* clean up */ msFree(symbol); } return MS_SUCCESS; }
int GIFoutputGraphic(Metafile *mf, int num, Gint code, Gint num_pt, Gpoint *pos) { int imf; mf_cgmo **cgmo = &mf->cgmo; for (imf = 0; imf < num; ++imf) { Gint i; GIFmetafile *meta = find_meta(cgmo[imf]); assert(meta); assert(num_pt > 0); meta->resize = 0; /* Not OK to resize */ /* Trivial accept and reject clipping of points. */ { int xlo = 1, xhi = 1, yhi = 1, ylo = 1; Gfloat lolimit = -1, hilimit = 2; int i; for (i=1; i < num_pt; ++i){ float x = pos[i].x; float y = pos[i].y; xlo &= (x < lolimit); xhi &= (x > hilimit); ylo &= (y < lolimit); yhi &= (y > hilimit); } if (xlo || xhi || ylo || yhi) return OK; /* If any points are extreme, toss the polygon. Someday, there will be a real clipping algorithm */ for (i=1; i < num_pt; ++i){ float x = pos[i].x; float y = pos[i].y; if (x < -10. || x > 10. || y < -10 || y > 10){ msgWarn("GIFoutputGraphic: Bad NDC point %f %f\n", x, y); return OK; } } } switch(code){ case GKSM_FILL_AREA: { gdPointPtr tpts = (gdPointPtr)umalloc(sizeof(gdPoint) * num_pt); assert(tpts); xform(meta, pos->x, pos->y, &tpts[0].x, &tpts[0].y); #ifdef DEBUG printf("--------------------------------------\n"); printf("Transform: (%f, %f) -> (%d,%d)\n", pos->x, pos->y, tpts[0].x, tpts[0].y); #endif ++pos; for (i=1; i < num_pt; ++i, ++pos){ xform(meta, pos->x, pos->y, &tpts[i].x, &tpts[i].y); #ifdef DEBUG printf("Transform: (%f, %f) -> (%d,%d)\n", pos->x, pos->y, tpts[i].x, tpts[i].y); #endif } if (meta->fillStyleIndex == 0){ gdImagePolygon(meta->image, tpts, num_pt, meta->fillIndex); } else { /* Eliminate colinear points (bug in gd.c) */ stripColinear(tpts, &num_pt); gdImageFilledPolygon(meta->image, tpts, num_pt, meta->fillIndex); } free(tpts); } break; case GKSM_POLYLINE: { int lineIndex = meta->styleIndex == 1 ? meta->lineIndex : gdStyled; gdPointPtr tpts = (gdPointPtr)umalloc(sizeof(gdPoint) * num_pt); assert(tpts); for (i=0; i < num_pt; ++i, ++pos){ xform(meta, pos->x, pos->y, &tpts[i].x, &tpts[i].y); } gdImageWideLines(meta->image, tpts, num_pt, lineIndex, meta->lineWidth); free(tpts); } break; case GKSM_POLYMARKER: msgWarn("GIFoutputGraphics: polymarker unsupported\n"); break; default: msgWarn("GIFoutputGraphics: Unknown code %d\n", code); } } return OK; }
static void vrml_polygon(GVJ_t *job, pointf * A, int np, int filled) { FILE *out = job->output_file; obj_state_t *obj = job->obj; node_t *n; edge_t *e; double z = obj->z; pointf p, mp; gdPoint *points; int i, pen; gdImagePtr brush = NULL; double theta; switch (obj->type) { case ROOTGRAPH_OBJTYPE: fprintf(out, " Background { skyColor %.3f %.3f %.3f }\n", obj->fillcolor.u.rgba[0] / 255., obj->fillcolor.u.rgba[1] / 255., obj->fillcolor.u.rgba[2] / 255.); Saw_skycolor = TRUE; break; case CLUSTER_OBJTYPE: break; case NODE_OBJTYPE: n = obj->u.n; pen = set_penstyle(job, im, brush); points = N_GNEW(np, gdPoint); for (i = 0; i < np; i++) { mp = vrml_node_point(job, n, A[i]); points[i].x = ROUND(mp.x); points[i].y = ROUND(mp.y); } if (filled) gdImageFilledPolygon(im, points, np, color_index(im, obj->fillcolor)); gdImagePolygon(im, points, np, pen); free(points); if (brush) gdImageDestroy(brush); fprintf(out, "Shape {\n"); fprintf(out, " appearance Appearance {\n"); fprintf(out, " material Material {\n"); fprintf(out, " ambientIntensity 0.33\n"); fprintf(out, " diffuseColor 1 1 1\n"); fprintf(out, " }\n"); fprintf(out, " texture ImageTexture { url \"node%d.png\" }\n", n->id); fprintf(out, " }\n"); fprintf(out, " geometry Extrusion {\n"); fprintf(out, " crossSection ["); for (i = 0; i < np; i++) { p.x = A[i].x - ND_coord_i(n).x; p.y = A[i].y - ND_coord_i(n).y; fprintf(out, " %.3f %.3f,", p.x, p.y); } p.x = A[0].x - ND_coord_i(n).x; p.y = A[0].y - ND_coord_i(n).y; fprintf(out, " %.3f %.3f ]\n", p.x, p.y); fprintf(out, " spine [ %d %d %.3f, %d %d %.3f ]\n", ND_coord_i(n).x, ND_coord_i(n).y, z - .01, ND_coord_i(n).x, ND_coord_i(n).y, z + .01); fprintf(out, " }\n"); fprintf(out, "}\n"); break; case EDGE_OBJTYPE: e = obj->u.e; if (np != 3) { static int flag; if (!flag) { flag++; agerr(AGWARN, "vrml_polygon: non-triangle arrowheads not supported - ignoring\n"); } } if (IsSegment) { doArrowhead (job, A); return; } p.x = p.y = 0.0; for (i = 0; i < np; i++) { p.x += A[i].x; p.y += A[i].y; } p.x = p.x / np; p.y = p.y / np; /* it is bad to know that A[1] is the aiming point, but we do */ theta = atan2((A[0].y + A[2].y) / 2.0 - A[1].y, (A[0].x + A[2].x) / 2.0 - A[1].x) + M_PI / 2.0; /* this is gruesome, but how else can we get z coord */ if (DIST2(p, ND_coord_i(e->tail)) < DIST2(p, ND_coord_i(e->head))) z = obj->tail_z; else z = obj->head_z; /* FIXME: arrow vector ought to follow z coord of bezier */ fprintf(out, "Transform {\n"); fprintf(out, " translation %.3f %.3f %.3f\n", p.x, p.y, z); fprintf(out, " children [\n"); fprintf(out, " Transform {\n"); fprintf(out, " rotation 0 0 1 %.3f\n", theta); fprintf(out, " children [\n"); fprintf(out, " Shape {\n"); fprintf(out, " geometry Cone {bottomRadius %.3f height %.3f }\n", obj->penwidth * 2.5, obj->penwidth * 10.0); fprintf(out, " appearance USE E%d\n", e->id); fprintf(out, " }\n"); fprintf(out, " ]\n"); fprintf(out, " }\n"); fprintf(out, " ]\n"); fprintf(out, "}\n"); break; } }
void gdImageFilledArc (gdImagePtr im, int cx, int cy, int width, int height, int s, int e, int color, int style) { gdPoint pt[7]; gdPoint axis_pt[4]; int angle; int have_s = 0; int have_e = 0; int flip_x = 0; int flip_y = 0; int conquer = 0; int i; int a; int b; int x; int y; long s_sin = 0; long s_cos = 0; long e_sin = 0; long e_cos = 0; long w; /* a * 2 */ long h; /* b * 2 */ long x2; /* x * 2 */ long y2; /* y * 2 */ long lx2; /* x * 2 (line) */ long ly2; /* y * 2 (line) */ long ws; /* (a * 2)^2 */ long hs; /* (b * 2)^2 */ long whs; /* (a * 2)^2 * (b * 2)^2 */ long g; /* decision variable */ long lg; /* decision variable (line) */ width = (width & 1) ? (width + 1) : (width); height = (height & 1) ? (height + 1) : (height); a = width / 2; b = height / 2; axis_pt[0].x = a; axis_pt[0].y = 0; axis_pt[1].x = 0; axis_pt[1].y = b; axis_pt[2].x = -a; axis_pt[2].y = 0; axis_pt[3].x = 0; axis_pt[3].y = -b; if (s == e) return; if ((e - s) >= 360) { s = 0; e = 0; } while (s < 0) s += 360; while (s >= 360) s -= 360; while (e < 0) e += 360; while (e >= 360) e -= 360; if (e <= s) e += 360; /* I'm assuming a chord-rule at the moment. Need to add origin to get a * pie-rule, but will need to set chord-rule before recursion... */ for (i = 0; i < 4; i++) { if ((s < (i + 1) * 90) && (e > (i + 1) * 90)) { gdImageFilledArc (im, cx, cy, width, height, s, (i + 1) * 90, color, gdChord); pt[0] = gdArcClosest (width, height, s); pt[0].x += cx; pt[0].y += cy; pt[1].x = cx + axis_pt[(i + 1) & 3].x; pt[1].y = cy + axis_pt[(i + 1) & 3].y; if (e <= (i + 2) * 90) { gdImageFilledArc (im, cx, cy, width, height, (i + 1) * 90, e, color, gdChord); pt[2] = gdArcClosest (width, height, e); pt[2].x += cx; pt[2].y += cy; if (style == gdChord) { gdImageFilledPolygon (im, pt, 3, color); gdImagePolygon (im, pt, 3, color); } else if (style == gdPie) { pt[3].x = cx; pt[3].y = cy; gdImageFilledPolygon (im, pt, 4, color); gdImagePolygon (im, pt, 4, color); } } else { gdImageFilledArc (im, cx, cy, width, height, (i + 1) * 90, (i + 2) * 90, color, gdChord); pt[2].x = cx + axis_pt[(i + 2) & 3].x; pt[2].y = cy + axis_pt[(i + 2) & 3].y; if (e <= (i + 3) * 90) { gdImageFilledArc (im, cx, cy, width, height, (i + 2) * 90, e, color, gdChord); pt[3] = gdArcClosest (width, height, e); pt[3].x += cx; pt[3].y += cy; if (style == gdChord) { gdImageFilledPolygon (im, pt, 4, color); gdImagePolygon (im, pt, 4, color); } else if (style == gdPie) { pt[4].x = cx; pt[4].y = cy; gdImageFilledPolygon (im, pt, 5, color); gdImagePolygon (im, pt, 5, color); } } else { gdImageFilledArc (im, cx, cy, width, height, (i + 2) * 90, (i + 3) * 90, color, gdChord); pt[3].x = cx + axis_pt[(i + 3) & 3].x; pt[3].y = cy + axis_pt[(i + 3) & 3].y; if (e <= (i + 4) * 90) { gdImageFilledArc (im, cx, cy, width, height, (i + 3) * 90, e, color, gdChord); pt[4] = gdArcClosest (width, height, e); pt[4].x += cx; pt[4].y += cy; if (style == gdChord) { gdImageFilledPolygon (im, pt, 5, color); gdImagePolygon (im, pt, 5, color); } else if (style == gdPie) { pt[5].x = cx; pt[5].y = cy; gdImageFilledPolygon (im, pt, 6, color); gdImagePolygon (im, pt, 6, color); } } else { gdImageFilledArc (im, cx, cy, width, height, (i + 3) * 90, (i + 4) * 90, color, gdChord); pt[4].x = cx + axis_pt[(i + 4) & 3].x; pt[4].y = cy + axis_pt[(i + 4) & 3].y; gdImageFilledArc (im, cx, cy, width, height, (i + 4) * 90, e, color, gdChord); pt[5] = gdArcClosest (width, height, e); pt[5].x += cx; pt[5].y += cy; if (style == gdChord) { gdImageFilledPolygon (im, pt, 6, color); gdImagePolygon (im, pt, 6, color); } else if (style == gdPie) { pt[6].x = cx; pt[6].y = cy; gdImageFilledPolygon (im, pt, 7, color); gdImagePolygon (im, pt, 7, color); } } } } return; } } /* At this point we have only arcs that lies within a quadrant - * map this to first quadrant... */ if ((s >= 90) && (e <= 180)) { angle = s; s = 180 - e; e = 180 - angle; flip_x = 1; } if ((s >= 180) && (e <= 270)) { s = s - 180; e = e - 180; flip_x = 1; flip_y = 1; } if ((s >= 270) && (e <= 360)) { angle = s; s = 360 - e; e = 360 - angle; flip_y = 1; } if (s == 0) { s_sin = 0; s_cos = (long) ((double) 32768); } else { s_sin = (long) ((double) 32768 * sin ((double) s * M_PI / (double) 180)); s_cos = (long) ((double) 32768 * cos ((double) s * M_PI / (double) 180)); } if (e == 0) { e_sin = (long) ((double) 32768); e_cos = 0; } else { e_sin = (long) ((double) 32768 * sin ((double) e * M_PI / (double) 180)); e_cos = (long) ((double) 32768 * cos ((double) e * M_PI / (double) 180)); } w = (long) width; h = (long) height; ws = w * w; hs = h * h; whs = 1; while ((ws > 32768) || (hs > 32768)) { ws = (ws + 1) / 2; /* Unfortunate limitations on integers makes */ hs = (hs + 1) / 2; /* drawing large ellipses problematic... */ whs *= 2; } while ((ws * hs) > (0x04000000L / whs)) { ws = (ws + 1) / 2; hs = (hs + 1) / 2; whs *= 2; } whs *= ws * hs; pt[0].x = w / 2; pt[0].y = 0; pt[2].x = 0; pt[2].y = h / 2; have_s = 0; have_e = 0; if (s == 0) have_s = 1; if (e == 90) have_e = 1; x2 = w; y2 = 0; /* Starting point is exactly on ellipse */ g = x2 - 1; g = g * g * hs + 4 * ws - whs; while ((x2 * hs) > (y2 * ws)) /* Keep |tangent| > 1 */ { y2 += 2; g += ws * 4 * (y2 + 1); if (g > 0) /* Need to drop */ { x2 -= 2; g -= hs * 4 * x2; } if ((have_s == 0) && ((s_sin * x2) <= (y2 * s_cos))) { pt[0].x = (int) (x2 / 2); pt[0].y = (int) (y2 / 2); have_s = 1; } if ((have_e == 0) && ((e_sin * x2) <= (y2 * e_cos))) { pt[2].x = (int) (x2 / 2); pt[2].y = (int) (y2 / 2); have_e = 1; } } pt[1].x = (int) (x2 / 2); pt[1].y = (int) (y2 / 2); x2 = 0; y2 = h; /* Starting point is exactly on ellipse */ g = y2 - 1; g = g * g * ws + 4 * hs - whs; while ((x2 * hs) < (y2 * ws)) { x2 += 2; g += hs * 4 * (x2 + 1); if (g > 0) /* Need to drop */ { y2 -= 2; g -= ws * 4 * y2; } if ((have_s == 0) && ((s_sin * x2) >= (y2 * s_cos))) { pt[0].x = (int) (x2 / 2); pt[0].y = (int) (y2 / 2); have_s = 1; } if ((have_e == 0) && ((e_sin * x2) >= (y2 * e_cos))) { pt[2].x = (int) (x2 / 2); pt[2].y = (int) (y2 / 2); have_e = 1; } } if ((have_s == 0) || (have_e == 0)) return; /* Bizarre case */ if (style == gdPie) { pt[3] = pt[0]; pt[4] = pt[1]; pt[5] = pt[2]; pt[0].x = cx + (flip_x ? (-pt[0].x) : pt[0].x); pt[0].y = cy + (flip_y ? (-pt[0].y) : pt[0].y); pt[1].x = cx; pt[1].y = cy; pt[2].x = cx + (flip_x ? (-pt[2].x) : pt[2].x); pt[2].y = cy + (flip_y ? (-pt[2].y) : pt[2].y); gdImageFilledPolygon (im, pt, 3, color); gdImagePolygon (im, pt, 3, color); pt[0] = pt[3]; pt[1] = pt[4]; pt[2] = pt[5]; } if (((s_cos * hs) > (s_sin * ws)) && ((e_cos * hs) < (e_sin * ws))) { /* the points are on different parts of the curve... * this is too tricky to try to handle, so divide and conquer: */ pt[3] = pt[0]; pt[4] = pt[1]; pt[5] = pt[2]; pt[0].x = cx + (flip_x ? (-pt[0].x) : pt[0].x); pt[0].y = cy + (flip_y ? (-pt[0].y) : pt[0].y); pt[1].x = cx + (flip_x ? (-pt[1].x) : pt[1].x); pt[1].y = cy + (flip_y ? (-pt[1].y) : pt[1].y); pt[2].x = cx + (flip_x ? (-pt[2].x) : pt[2].x); pt[2].y = cy + (flip_y ? (-pt[2].y) : pt[2].y); gdImageFilledPolygon (im, pt, 3, color); gdImagePolygon (im, pt, 3, color); pt[0] = pt[3]; pt[2] = pt[4]; conquer = 1; } if (conquer || (((s_cos * hs) > (s_sin * ws)) && ((e_cos * hs) > (e_sin * ws)))) { /* This is the best bit... */ /* steep line + ellipse */ /* go up & left from pt[0] to pt[2] */ x2 = w; y2 = 0; /* Starting point is exactly on ellipse */ g = x2 - 1; g = g * g * hs + 4 * ws - whs; while ((x2 * hs) > (y2 * ws)) /* Keep |tangent| > 1 */ { if ((s_sin * x2) <= (y2 * s_cos)) break; y2 += 2; g += ws * 4 * (y2 + 1); if (g > 0) /* Need to drop */ { x2 -= 2; g -= hs * 4 * x2; } } lx2 = x2; ly2 = y2; lg = lx2 * (pt[0].y - pt[2].y) - ly2 * (pt[0].x - pt[2].x); lg = (lx2 - 1) * (pt[0].y - pt[2].y) - (ly2 + 2) * (pt[0].x - pt[2].x) - lg; while (y2 < (2 * pt[2].y)) { y2 += 2; g += ws * 4 * (y2 + 1); if (g > 0) /* Need to drop */ { x2 -= 2; g -= hs * 4 * x2; } ly2 += 2; lg -= 2 * (pt[0].x - pt[2].x); if (lg < 0) /* Need to drop */ { lx2 -= 2; lg -= 2 * (pt[0].y - pt[2].y); } y = (int) (y2 / 2); for (x = (int) (lx2 / 2); x <= (int) (x2 / 2); x++) { gdImageSetPixel (im, ((flip_x) ? (cx - x) : (cx + x)), ((flip_y) ? (cy - y) : (cy + y)), color); } } } if (conquer) { pt[0] = pt[4]; pt[2] = pt[5]; } if (conquer || (((s_cos * hs) < (s_sin * ws)) && ((e_cos * hs) < (e_sin * ws)))) { /* This is the best bit... */ /* gradual line + ellipse */ /* go down & right from pt[2] to pt[0] */ x2 = 0; y2 = h; /* Starting point is exactly on ellipse */ g = y2 - 1; g = g * g * ws + 4 * hs - whs; while ((x2 * hs) < (y2 * ws)) { x2 += 2; g += hs * 4 * (x2 + 1); if (g > 0) /* Need to drop */ { y2 -= 2; g -= ws * 4 * y2; } if ((e_sin * x2) >= (y2 * e_cos)) break; } lx2 = x2; ly2 = y2; lg = lx2 * (pt[0].y - pt[2].y) - ly2 * (pt[0].x - pt[2].x); lg = (lx2 + 2) * (pt[0].y - pt[2].y) - (ly2 - 1) * (pt[0].x - pt[2].x) - lg; while (x2 < (2 * pt[0].x)) { x2 += 2; g += hs * 4 * (x2 + 1); if (g > 0) /* Need to drop */ { y2 -= 2; g -= ws * 4 * y2; } lx2 += 2; lg += 2 * (pt[0].y - pt[2].y); if (lg < 0) /* Need to drop */ { ly2 -= 2; lg += 2 * (pt[0].x - pt[2].x); } x = (int) (x2 / 2); for (y = (int) (ly2 / 2); y <= (int) (y2 / 2); y++) { gdImageSetPixel (im, ((flip_x) ? (cx - x) : (cx + x)), ((flip_y) ? (cy - y) : (cy + y)), color); } } } }
void CarApp::draw_buttons(int selection) { logger->log(DEBUG, "CarApp::draw_buttons", "start"); int i, top, col, blue; gdPoint points[3]; int brect[8]; int white = gdTrueColor(255,255,255); char *font = conf->get_value("font"); col = gdTrueColor(64,64,198); blue = gdTrueColor(64,64,198); for(i=0; i<6; i++) { top = i * button_height; if (i == selection) col = gdTrueColor(100, 110, 216); else col = gdTrueColor(57, 76, 116); /* special colors for the mute button) */ if (sound->is_mute() && (i == MUTE) && (i != selection)) col = gdTrueColor(200, 94, 94); else if (sound->is_mute() && (i == MUTE) && (i == selection)) col = gdTrueColor(255, 120, 120); gdImageFilledRectangle(fb->img, 1, top+1, button_width - 2, top + button_height - 2, col); if (i == MUTE) { gdImageStringFT(fb->img, &brect[0], white, font, 14, 0.0, 20, 45, "Mute"); } else if (i == UP) { col = gdTrueColor(180, 60, 60); points[0].x = MARGIN + (button_width / 2); points[0].y = top + 20; points[1].x = MARGIN + 20; points[1].y = top + button_height - 20; points[2].x = MARGIN + button_width - 20; points[2].y = top + button_height - 20; gdImageFilledPolygon(fb->img, points, 3, col); gdImagePolygon(fb->img, points, 3, 0); } else if (i ==DOWN) { col = gdTrueColor(180, 60, 60); points[0].x = MARGIN + 20; points[0].y = top + 20; points[1].x = MARGIN + button_width - 20; points[1].y = top + 20; points[2].x = MARGIN + (button_width / 2); points[2].y = top + button_height - 20; gdImageFilledPolygon(fb->img, points, 3, col); gdImagePolygon(fb->img, points, 3, 0); } else if (i == RIGHT) { col = gdTrueColor(100, 160, 100); points[0].x = MARGIN + 20; points[0].y = top + 20; points[1].x = MARGIN + button_width - 20; points[1].y = top + (button_height) / 2; points[2].x = MARGIN + 20; points[2].y = top + button_height - 20; gdImageFilledPolygon(fb->img, points, 3, col); gdImagePolygon(fb->img, points, 3, 0); } else if (i == LEFT) { col = gdTrueColor(100, 160, 100); points[0].x = MARGIN + button_width - 20; points[0].y = top + 20; points[1].x = MARGIN + 20; points[1].y = top + (button_height) / 2; points[2].x = MARGIN + button_width - 20; points[2].y = top + button_height - 20; gdImageFilledPolygon(fb->img, points, 3, col); gdImagePolygon(fb->img, points, 3, 0); } else if (i == MENU) { gdImageStringFT(fb->img, &brect[0], white, font, 14, 0.0, 17, 445, "Menu"); } } fb->update(0, 0, button_width, fb->height-1); logger->log(DEBUG, "CarApp::draw_buttons", "end"); }
static void gd_textline(point p, textline_t * line) { char *str, *fontlist, *err; pointf mp, ep; int brect[8]; double fontsz; gdFTStringExtra strex; int pencolor; if (!im) return; strex.flags = gdFTEX_RESOLUTION; strex.hdpi = strex.vdpi = Dpi * Zoom; if (cstk[SP].pen == P_NONE) return; pencolor = cstk[SP].pencolor; if (!im->trueColor && cstk[SP].fillcolor == transparent) pencolor = -pencolor; /* disable antialiasing */ if (strstr(cstk[SP].fontfam, "/")) strex.flags |= gdFTEX_FONTPATHNAME; else strex.flags |= gdFTEX_FONTCONFIG; str = line->str; fontlist = gd_alternate_fontlist(cstk[SP].fontfam); fontsz = cstk[SP].fontsz; switch (line->just) { case 'l': mp.x = p.x; break; case 'r': mp.x = p.x - line->width; break; default: case 'n': mp.x = p.x - line->width / 2; break; } ep.y = mp.y = p.y; ep.x = mp.x + line->width; mp = gdpt(mp); if (fontsz <= FONTSIZE_MUCH_TOO_SMALL) { /* ignore entirely */ } else if (fontsz <= FONTSIZE_TOO_SMALL) { /* draw line in place of text */ ep = gdpt(ep); gdImageLine(im, ROUND(mp.x), ROUND(mp.y), ROUND(ep.x), ROUND(ep.y), cstk[SP].pencolor); } else { #ifdef HAVE_GD_FREETYPE err = gdImageStringFTEx(im, brect, pencolor, fontlist, fontsz, Rot ? (PI / 2) : 0, ROUND(mp.x), ROUND(mp.y), str, &strex); #if 0 gdImagePolygon(im, (gdPointPtr) brect, 4, cstk[SP].pencolor); #endif #if 0 fprintf(stderr, "textline: font=%s size=%g pos=%g,%g width=%g dpi=%d width/dpi=%g\n", fontlist, fontsz, mp.x, mp.y, (double) (brect[4] - brect[0]), strex.hdpi, (((double) (brect[4] - brect[0])) / strex.hdpi)); #endif if (err) { /* revert to builtin fonts */ gd_missingfont(err, cstk[SP].fontfam); #endif mp.y += 2; if (fontsz <= 8.5) { gdImageString(im, gdFontTiny, ROUND(mp.x), ROUND(mp.y - 9.), (unsigned char *) str, cstk[SP].pencolor); } else if (fontsz <= 9.5) { gdImageString(im, gdFontSmall, ROUND(mp.x), ROUND(mp.y - 12.), (unsigned char *) str, cstk[SP].pencolor); } else if (fontsz <= 10.5) { gdImageString(im, gdFontMediumBold, ROUND(mp.x), ROUND(mp.y - 13.), (unsigned char *) str, cstk[SP].pencolor); } else if (fontsz <= 11.5) { gdImageString(im, gdFontLarge, ROUND(mp.x), ROUND(mp.y - 14.), (unsigned char *) str, cstk[SP].pencolor); } else { gdImageString(im, gdFontGiant, ROUND(mp.x), ROUND(mp.y - 15.), (unsigned char *) str, cstk[SP].pencolor); } #ifdef HAVE_GD_FREETYPE } #endif } }