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)calloc(3, sizeof(gdPoint));
	if (!points) {
		gdImageDestroy(im);
		exit(EXIT_FAILURE);
	}
	points[0].x = 10;
	points[0].y = 10;
	gdImageFilledPolygon(im, points, 1, black);
	r = gdAssertImageEqualsToFile(GDTEST_TOP_DIR "/gdimagefilledpolygon/gdimagefilledpolygon1.png", im);
	free(points);
	gdImageDestroy(im);
	if (!r) exit(EXIT_FAILURE);
	return EXIT_SUCCESS;
}
Example #2
0
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);
	gdImageFilledPolygon(im, NULL, 0, black);  /* no effect */
	gdImageFilledPolygon(im, NULL, -1, black); /* no effect */
	r = gdAssertImageEqualsToFile(GDTEST_TOP_DIR "/gdimagefilledpolygon/gdimagefilledpolygon0.png", im);
	gdImageDestroy(im);
	if (!r) exit(EXIT_FAILURE);
	return EXIT_SUCCESS;
}
/* prints the arrow into the image poined to by the pointer with given
   color*/
void ocin_vis_arrow::print(gdImagePtr im, float scale_val) {

  int thick = ((int)((float)thickness *scale_val)) + 1;

  int scaled_a_size = (int) ((float)(a_size - 4) *scale_val) + 4;

  // create points for arrow head based on scale factor
  if (dir == S) {
    points[1].x = x2 - scaled_a_size;
    points[1].y = y2 - scaled_a_size;
    points[2].x = x2 + scaled_a_size;
    points[2].y = y2 - scaled_a_size;
  } else if (dir == E) {
    points[1].x = x2 - scaled_a_size;
    points[1].y = y2 + scaled_a_size;
    points[2].x = x2 - scaled_a_size;
    points[2].y = y2 - scaled_a_size;
  } else if (dir == N) {
    points[1].x = x2 - scaled_a_size;
    points[1].y = y2 + scaled_a_size;
    points[2].x = x2 + scaled_a_size;
    points[2].y = y2 + scaled_a_size;
  } else if (dir == W) {
    points[1].x = x2 + scaled_a_size;
    points[1].y = y2 + scaled_a_size;
    points[2].x = x2 + scaled_a_size;
    points[2].y = y2 - scaled_a_size;
  }
  // setup the arrow head points
  points[0].x = x2;             // first point is end of the line
  points[0].y = y2;

  // select the color for the arrow head
  int cnt = 255 - ((int)(250.0*scale_val));
  cnt = cnt &0xfffffffe;	// make sure we have an even number
				// (?)
  int color;
  color = gdImageColorResolve(im, cnt, cnt, cnt);

  // if (cnt < 0) {
  //   color = gdImageColorResolve(im, 0, 255+cnt, (cnt*-1));
  // } else {
  //   color = gdImageColorResolve(im, cnt, 255-cnt, 0);
  // }


  
  // draw the arrowhead first (why not)
  gdImageFilledPolygon(im, points, 3, color);

  // then the line
  gdImageSetThickness(im, thick);
  gdImageLine(im, x1, y1, x2, y2, color);
  
 
  
}
Example #5
0
void doFilledPolygon(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));
  gdImageFilledPolygon(image, points, n, c);
}
Example #6
0
result_t Image::filledPolygon(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;

    gdImageFilledPolygon(m_image, pts.data(), (int32_t) pts.size(), color);
    return 0;
}
Example #7
0
static void
fill_polygon(PLStream *pls)
{
png_Dev *dev=(png_Dev *)pls->dev;

    int i;
    gdPoint *points=NULL;

    if (pls->dev_npts < 1)
	return;

     points = malloc((size_t)pls->dev_npts * sizeof(gdPoint));

     for (i = 0; i < pls->dev_npts; i++)
         {
	   points[i].x = pls->dev_x[i]/dev->scale;
	   points[i].y = dev->pngy - (pls->dev_y[i]/dev->scale);
         }

    #if GD2_VERS >= 2
      if (dev->smooth==1)
        {
          gdImageSetAntiAliased(dev->im_out,dev->colour);
          gdImageFilledPolygon(dev->im_out, points, pls->dev_npts, gdAntiAliased);
        }
      else
        {
          gdImageFilledPolygon(dev->im_out, points, pls->dev_npts, dev->colour);
        }
    #else
      gdImageFilledPolygon(dev->im_out, points, pls->dev_npts, dev->colour);
    #endif

   free(points);

}
Example #8
0
void draw_block(gdImagePtr g, int x, int y, int size, int color)
{
    gdPoint block[4];

    block[0].x = x;
    block[0].y = y;
    block[1].x = x + size;
    block[1].y = y;
    block[2].x = x + size;
    block[2].y = y + size;
    block[3].x = x;
    block[3].y = y + size;

    gdImageFilledPolygon(g, block, 4, color);
}
Example #9
0
void gdoFilledTriangle(struct ADrawTag *ctx,
                       unsigned int x1,
                       unsigned int y1,
                       unsigned int x2,
                       unsigned int y2,
                       unsigned int x3,
                       unsigned int y3)
{
    gdPoint p[3];

    p[0].x = x1; p[0].y = y1;
    p[1].x = x2; p[1].y = y2;
    p[2].x = x3; p[2].y = y3;

    gdImageFilledPolygon(getGdoImg(ctx), p, 3, getGdoPen(ctx));
}
Example #10
0
void doArrow(FILE *stream) {
  float x1, y1, x2, y2;
  int vx, vy, size, c;
  gdPoint triangle[3];

  x1 = getFloat(stream);
  y1 = getFloat(stream);
  x2 = getFloat(stream);
  y2 = getFloat(stream);
  size = getNumber(stream);
  c = getColor(getNumber(stream));
  vx = viewx(x2);
  vy = viewy(y2);
  triangle[0].x = vx;
  triangle[0].y = vy;
  gdImageLine(image, viewx(x1), viewy(y1), vx, vy, c);
  if (y1 == y2) {
    if (x2 > x1) {		/* horizontal, pointing right */
      triangle[1].x = vx - size;
      triangle[1].y = vy - size;
      triangle[2].x = vx - size;
      triangle[2].y = vy + size;
    } else {		/* horizontal, pointing left */
      triangle[1].x = vx + size;
      triangle[1].y = vy - size;
      triangle[2].x = vx + size;
      triangle[2].y = vy + size;
    }
  } else {
    if (y2 > y1) {		/* vertical, pointing up */
      triangle[1].x = vx - size;
      triangle[1].y = vy - size;
      triangle[2].x = vx + size;
      triangle[2].y = vy - size;
    } else {		/* horizontal, pointing left */
      triangle[1].x = vx - size;
      triangle[1].y = vy + size;
      triangle[2].x = vx + size;
      triangle[2].y = vy + size;
    }
  }
  gdImageFilledPolygon(image, triangle, 3, c);
}
Example #11
0
gdImagePtr renderDrawing(ei::DnaDrawing *d)
{
    // make new image, true color, with alpha support
    gdImagePtr img = 0;
    img = gdImageCreateTrueColor(ei::Tools::maxWidth, ei::Tools::maxHeight);
    if (0 == img)
    {
        std::cout << "Could not create image" << std::endl;
        return 0;
    }
    gdImageAlphaBlending(img, 1);
    int black = gdTrueColor(0,0,0);         // also acts as background

    // render image:
    // * for each polygon:
    ei::DnaPolygonList *polys = d->polygons();
    ei::DnaPolygonList::iterator iter;
    for (iter = polys->begin(); iter != polys->end(); iter++)
    {
        ei::DnaPolygon *poly = *iter;
        // ** allocate its color & alpha
        ei::DnaBrush *brush = poly->brush();
        int color = gdTrueColorAlpha(brush->r, brush->g, brush->b, brush->a);
        // ** render a closed polygon:
        // *** make array of gdPoints
        ei::DnaPointList *points = poly->points();
        gdPoint gdPts[points->size()];
        // *** translate points
        ei::DnaPointList::iterator eachPt;
        for (int i=0; i < points->size(); i++)
        {
            gdPts[i].x = (*points)[i]->x;
            gdPts[i].y = (*points)[i]->y;
        }
        // *** render via gdImageFilledPolygon().
        gdImageFilledPolygon(img, gdPts, points->size(), color);
    }

    return img;
}
Example #12
0
    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;
}
Example #13
0
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);
	    }
	}
    }
}
Example #15
0
/* ======================================================= *\ 
 * PIE
 * 
 * Notes:
 *  always drawn from 12:00 position clockwise
 *  'missing' slices don't get labels
 *  sum(val[0], ... val[num_points-1]) is assumed to be 100%
\* ======================================================= */
void
GDC_out_pie( short			IMGWIDTH,
			 short			IMGHEIGHT,
			 FILE			*img_fptr,			/* open file pointer */
			 GDCPIE_TYPE	type,
			 int			num_points,
			 char			*lbl[],				/* data labels */
			 float			val[] )				/* data */
{
	int			i;

	gdImagePtr	im;
	int			BGColor,
				LineColor,
				PlotColor,
				EdgeColor,
				EdgeColorShd;
	CREATE_ARRAY1( SliceColor, int, num_points );		/* int SliceColor[num_points] */
	CREATE_ARRAY1( SliceColorShd, int, num_points );	/* int SliceColorShd[num_points] */

	float		rad = 0.0;					/* radius */
	float		ellipsex = 1.0;
	float		ellipsey = 1.0 - (float)GDCPIE_perspective/100.0;
	float		tot_val = 0.0;
	float		pscl;
	int			cx,							/* affects PX() */
				cy;							/* affects PY() */
								/* ~ 1% for a size of 100 pixs */
								/* label sizes will more dictate this */
	float		min_grphable = ( GDCPIE_other_threshold < 0?
								  100.0/(float)MIN(IMGWIDTH,IMGHEIGHT):
								  (float)GDCPIE_other_threshold )/100.0;
	short		num_slices1 = 0,
				num_slices2 = 0;
	char		any_too_small = FALSE;
	CREATE_ARRAY1( others, char, num_points );			/* char others[num_points] */
	CREATE_ARRAY2( slice_angle, float, 3, num_points );	/* float slice_angle[3][num_points] */
														/* must be used with others[] */
	char		threeD = ( type == GDC_3DPIE );

	int			xdepth_3D      = 0,			/* affects PX() */
				ydepth_3D      = 0;			/* affects PY() */
	int			do3Dx = 0,					/* reserved for macro use */
				do3Dy = 0;

	CREATE_ARRAY2( pct_lbl, char, num_points, 16 );			/* sizeof or strlen (GDCPIE_percent_fmt)? */
	CREATE_ARRAY1( pct_ftsz, struct fnt_sz_t, num_points );	/* struct fnt_sz_t lbl_ftsz[num_points] */
	CREATE_ARRAY1( lbl_ftsz, struct fnt_sz_t, num_points );	/* struct fnt_sz_t lbl_ftsz[num_points] */


#ifdef HAVE_LIBFREETYPE
	char			*gdcpie_title_font  = GDCPIE_title_font;
	char			*gdcpie_label_font  = GDCPIE_label_font;
	double			gdcpie_title_ptsize = GDCPIE_title_ptsize;
	double			gdcpie_label_ptsize = GDCPIE_label_ptsize;
#else
	char			*gdcpie_title_font  = NULL;
	char			*gdcpie_label_font  = NULL;
	double			gdcpie_title_ptsize = 0.0;
	double			gdcpie_label_ptsize = 0.0;
#endif

/*	GDCPIE_3d_angle = MOD_360(90-GDCPIE_3d_angle+360); */
	pie_3D_rad = TO_RAD( GDCPIE_3d_angle );

	xdepth_3D      = threeD? (int)( cos((double)MOD_2PI(M_PI_2-pie_3D_rad+2.0*M_PI)) * GDCPIE_3d_depth ): 0;
	ydepth_3D      = threeD? (int)( sin((double)MOD_2PI(M_PI_2-pie_3D_rad+2.0*M_PI)) * GDCPIE_3d_depth ): 0;
/*	xdepth_3D      = threeD? (int)( cos(pie_3D_rad) * GDCPIE_3d_depth ): 0; */
/*	ydepth_3D      = threeD? (int)( sin(pie_3D_rad) * GDCPIE_3d_depth ): 0; */

	load_font_conversions();

	/* ----- get total value ----- */
	for( i=0; i<num_points; ++i )
		tot_val += val[i];

	/* ----- pie sizing ----- */
	/* ----- make width room for labels, depth, etc.: ----- */
	/* ----- determine pie's radius ----- */
	{
	int		title_hgt  = GDCPIE_title? 1			/*  title? horizontal text line */
									   + GDCfnt_sz( GDCPIE_title,
													GDCPIE_title_size,
													gdcpie_title_font, gdcpie_title_ptsize, 0.0, NULL ).h

									   + 2:
									   0;
	float	last = 0.0;
	float	label_explode_limit = 0.0;
	int		cheight,
			cwidth;

	/* maximum: no labels, explosions */
	/* gotta start somewhere */
	rad = (float)MIN( (IMGWIDTH/2)/ellipsex-(1+ABS(xdepth_3D)), (IMGHEIGHT/2)/ellipsey-(1+ABS(ydepth_3D))-title_hgt );

	/* ok fix center, i.e., no floating re labels, explosion, etc. */
	cx = IMGWIDTH/2 /* - xdepth_3D */ ;
	cy = (IMGHEIGHT-title_hgt)/2 + title_hgt /* + ydepth_3D */ ;

	cheight = (IMGHEIGHT- title_hgt)/2 /* - ydepth_3D */ ;
	cwidth  = cx;

	/* walk around pie. determine spacing to edge */
	for( i=0; i<num_points; ++i )
		{
		float	this_pct = val[i]/tot_val;						/* should never be > 100% */
		float	this = this_pct*(2.0*M_PI);						/* pie-portion */
		if( (this_pct > min_grphable) ||						/* too small */
			(!GDCPIE_missing || !GDCPIE_missing[i]) )			/* still want angles */
			{
			int this_explode = GDCPIE_explode? GDCPIE_explode[i]: 0;
			double	this_sin;
			double	this_cos;
			slice_angle[0][i] = this/2.0+last;				/* mid-point on full pie */
			slice_angle[1][i] = last;						/* 1st on full pie */
			slice_angle[2][i] = this+last;					/* 2nd on full pie */
			this_sin        = ellipsex*sin( (double)slice_angle[0][i] );
			this_cos        = ellipsey*cos( (double)slice_angle[0][i] );

			if( !GDCPIE_missing || !(GDCPIE_missing[i]) )
				{
				short	lbl_wdth = 0,
						lbl_hgt  = 0;
				float	this_y_explode_limit,
						this_x_explode_limit;

				/* start slice label height, width     */
				/*  accounting for PCT placement, font */
				pct_ftsz[i].h = 0;
				pct_ftsz[i].w = 0;
				if( GDCPIE_percent_fmt &&
					GDCPIE_percent_labels != GDCPIE_PCT_NONE )
					{
					sprintf( pct_lbl[i], GDCPIE_percent_fmt, this_pct * 100.0 );
					pct_ftsz[i] = GDCfnt_sz( pct_lbl[i],
											 GDCPIE_label_size,
											 gdcpie_label_font, gdcpie_label_ptsize, 0.0, NULL );
					lbl_wdth = pct_ftsz[i].w;
					lbl_hgt  = pct_ftsz[i].h;
					}

				if( lbl && lbl[i] )
					{
					lbl_ftsz[i] = GDCfnt_sz( lbl[i],
											 GDCPIE_label_size,
											 gdcpie_label_font, gdcpie_label_ptsize, 0.0, NULL );

					if( GDCPIE_percent_labels == GDCPIE_PCT_ABOVE ||
						GDCPIE_percent_labels == GDCPIE_PCT_BELOW )
						{
						lbl_wdth = MAX( pct_ftsz[i].w, lbl_ftsz[i].w );
						lbl_hgt  = pct_ftsz[i].h + lbl_ftsz[i].h + 1;
						}
					else
					if( GDCPIE_percent_labels == GDCPIE_PCT_RIGHT ||
						GDCPIE_percent_labels == GDCPIE_PCT_LEFT )
						{
						lbl_wdth = pct_ftsz[i].w + lbl_ftsz[i].w + 1;
						lbl_hgt  = MAX( pct_ftsz[i].h, lbl_ftsz[i].h );
						}
					else /* GDCPIE_PCT_NONE */
						{
						lbl_wdth = lbl_ftsz[i].w;
						lbl_hgt  = lbl_ftsz[i].h;
						}
					}
				else
					lbl_wdth = lbl_hgt = 0;
				/* end label height, width */
				
				/* diamiter limited by this point's: explosion, label                 */
				/* (radius to box @ slice_angle) - (explode) - (projected label size) */
				/* radius constraint due to labels */
				this_y_explode_limit = (float)this_cos==0.0? FLT_MAX:
										(	(float)( (double)cheight/ABS(this_cos) ) - 
											(float)( this_explode + (lbl&&lbl[i]? GDCPIE_label_dist: 0) ) -
											(float)( lbl_hgt/2 ) / (float)ABS(this_cos)	);
				this_x_explode_limit = (float)this_sin==0.0? FLT_MAX:
										(	(float)( (double)cwidth/ABS(this_sin) ) - 
											(float)( this_explode + (lbl&&lbl[i]? GDCPIE_label_dist: 0) ) -
											(float)( lbl_wdth ) / (float)ABS(this_sin)	);

				rad = MIN( rad, this_y_explode_limit );
				rad = MIN( rad, this_x_explode_limit );

				/* ok at this radius (which is most likely larger than final) */
				/* adjust for inter-label spacing */
/*				if( lbl[i] && *lbl[i] ) */
/*					{ */
/*					char which_edge = slice_angle[0][i] > M_PI? +1: -1;		// which semi */
/*					last_label_yedge = cheight - (int)( (rad +				// top or bottom of label */
/*														(float)(this_explode + */
/*														(float)GDCPIE_label_dist)) * (float)this_cos ) + */
/*											     ( (GDC_fontc[GDCPIE_label_size].h+1)/2 + */
/*													GDC_label_spacing )*which_edge; */
/*					} */

				/* radius constriant due to exploded depth */
				/* at each edge of the slice, and the middle */
				/* this is really stupid */
				/*  this section uses a different algorithm then above, but does the same thing */
				/*  could be combined, but each is ugly enough! */
/* PROTECT /0 */
				if( threeD )
					{
					short	j;
					int		this_y_explode_pos;
					int		this_x_explode_pos;

					/* first N E S W (actually no need for N) */
					if( (slice_angle[1][i] < M_PI_2 && M_PI_2 < slice_angle[2][i]) &&				/* E */
						(this_x_explode_pos=OX(i,M_PI_2,1)) > cx+cwidth )
						rad -= (float)ABS( (double)(1+this_x_explode_pos-(cx+cwidth))/sin(M_PI_2) );
					if( (slice_angle[1][i] < 3.0*M_PI_2 && 3.0*M_PI_2 < slice_angle[2][i]) &&		/* W */
						(this_x_explode_pos=OX(i,3.0*M_PI_2,1)) < cx-cwidth )
						rad -= (float)ABS( (double)(this_x_explode_pos-(cx+cwidth))/sin(3.0*M_PI_2) );
					if( (slice_angle[1][i] < M_PI && M_PI < slice_angle[2][i]) &&					/* S */
						(this_y_explode_pos=OY(i,M_PI,1)) > cy+cheight )
						rad -= (float)ABS( (double)(1+this_y_explode_pos-(cy+cheight))/cos(M_PI) );

					for( j=0; j<3; ++j )
						{
						this_y_explode_pos = IY(i,j,1);
						if( this_y_explode_pos < cy-cheight )
							rad -= (float)ABS( (double)((cy-cheight)-this_y_explode_pos)/cos((double)slice_angle[j][i]) );
						if( this_y_explode_pos > cy+cheight )
							rad -= (float)ABS( (double)(1+this_y_explode_pos-(cy+cheight))/cos((double)slice_angle[j][i]) );

						this_x_explode_pos = IX(i,j,1);
						if( this_x_explode_pos < cx-cwidth )
							rad -= (float)ABS( (double)((cx-cwidth)-this_x_explode_pos)/sin((double)slice_angle[j][i]) );
						if( this_x_explode_pos > cx+cwidth )
							rad -= (float)ABS( (double)(1+this_x_explode_pos-(cx+cwidth))/sin((double)slice_angle[j][i]) );
						}
					}
				}
			others[i] = FALSE;
			}
		else
			{
			others[i] = TRUE;
			slice_angle[0][i] = -FLT_MAX;
			}
		last += this;
		}
	}

	/* ----- go ahead and start the image ----- */
	im = gdImageCreate( IMGWIDTH, IMGHEIGHT );

	/* --- allocate the requested colors --- */
	BGColor   = clrallocate( im, GDCPIE_BGColor );
	LineColor = clrallocate( im, GDCPIE_LineColor );
	PlotColor = clrallocate( im, GDCPIE_PlotColor );
	if( GDCPIE_EdgeColor != GDC_NOCOLOR )
	 {
	 EdgeColor = clrallocate( im, GDCPIE_EdgeColor );
	 if( threeD )
	  EdgeColorShd = clrshdallocate( im, GDCPIE_EdgeColor );
	 }

	/* --- set color for each slice --- */
	for( i=0; i<num_points; ++i )
		if( GDCPIE_Color )
			{
			unsigned long	slc_clr = GDCPIE_Color[i];

			SliceColor[i]     = clrallocate( im, slc_clr );
			if( threeD )
			 SliceColorShd[i] = clrshdallocate( im, slc_clr );
			}
		else
			{
			SliceColor[i]     = PlotColor;
			if( threeD )
			 SliceColorShd[i] = clrshdallocate( im, GDCPIE_PlotColor );
			}

	pscl = (2.0*M_PI)/tot_val;
	
	/* ----- calc: smallest a slice can be ----- */
	/* 1/2 circum / num slices per side. */
	/*              determined by number of labels that'll fit (height) */
	/* scale to user values */
	/* ( M_PI / (IMGHEIGHT / (SFONTHGT+1)) ) */
/*	min_grphable = tot_val / */
/*				   ( 2.0 * (float)IMGHEIGHT / (float)(SFONTHGT+1+TFONTHGT+2) ); */


	if( threeD )
		{
		/* draw background shaded pie */
		{
		float	rad1 = rad * 3.0/4.0;
		for( i=0; i<num_points; ++i )
			if( !(others[i]) &&
				(!GDCPIE_missing || !GDCPIE_missing[i]) )
				{
				int		edge_color = GDCPIE_EdgeColor == GDC_NOCOLOR? SliceColorShd[i]:
				                                                      EdgeColorShd;

				gdImageLine( im, CX(i,1), CY(i,1), IX(i,1,1), IY(i,1,1), edge_color );
				gdImageLine( im, CX(i,1), CY(i,1), IX(i,2,1), IY(i,2,1), edge_color );
				gdImageArc( im, CX(i,1), CY(i,1),
								(int)(rad*ellipsex*2.0), (int)(rad*ellipsey*2.0),
								TO_INT_DEG_FLOOR(slice_angle[1][i])+270,
								TO_INT_DEG_CEIL(slice_angle[2][i])+270,
								edge_color );
					
/*				gdImageFilledArc( im, CX(i,1), CY(i,1), */
/*									  rad*ellipsex*2, rad*ellipsey*2, */
/*									  TO_INT_DEG_FLOOR(slice_angle[1][i])+270, */
/*									  TO_INT_DEG_CEIL(slice_angle[2][i])+270, */
/*									  SliceColorShd[i], */
/*									  gdPie ); */
				/* attempt to fill, if slice is wide enough */
				if( (ABS(IX(i,1,1)-IX(i,2,1)) + ABS(IY(i,1,1)-IY(i,2,1))) > 2 )
					{
					float	rad = rad1;										/* local override */
					gdImageFillToBorder( im, IX(i,0,1), IY(i,0,1), edge_color, SliceColorShd[i] );
					}
				}
		}
		/* fill in connection to foreground pie */
		/* this is where we earn our keep */
		{
		int					t,
							num_slice_angles = 0;
		CREATE_ARRAY1( tmp_slice, struct tmp_slice_t, 4*num_points+4 );		/* should only need 2*num_points+2 */

		for( i=0; i<num_points; ++i )
			if( !GDCPIE_missing || !GDCPIE_missing[i] )
				{
				if( RAD_DIST1(slice_angle[1][i]) < RAD_DIST2(slice_angle[0][i]) )
					tmp_slice[num_slice_angles].hidden = FALSE;
				else
					tmp_slice[num_slice_angles].hidden = TRUE;
				tmp_slice[num_slice_angles].i       = i;
				tmp_slice[num_slice_angles].slice   = slice_angle[0][i];
				tmp_slice[num_slice_angles++].angle = slice_angle[1][i];
				if( RAD_DIST1(slice_angle[2][i]) < RAD_DIST2(slice_angle[0][i]) )
					tmp_slice[num_slice_angles].hidden = FALSE;
				else
					tmp_slice[num_slice_angles].hidden = TRUE;
				tmp_slice[num_slice_angles].i       = i;
				tmp_slice[num_slice_angles].slice   = slice_angle[0][i];
				tmp_slice[num_slice_angles++].angle = slice_angle[2][i];
				/* identify which 2 slices (i) have a tangent parallel to depth angle  */
				if( slice_angle[1][i]<MOD_2PI(pie_3D_rad+M_PI_2) && slice_angle[2][i]>MOD_2PI(pie_3D_rad+M_PI_2) )
					{
					tmp_slice[num_slice_angles].i       = i;
					tmp_slice[num_slice_angles].hidden  = FALSE;
					tmp_slice[num_slice_angles].slice   = slice_angle[0][i];
					tmp_slice[num_slice_angles++].angle = MOD_2PI( pie_3D_rad+M_PI_2 );
					}
				if( slice_angle[1][i]<MOD_2PI(pie_3D_rad+3.0*M_PI_2) && slice_angle[2][i]>MOD_2PI(pie_3D_rad+3.0*M_PI_2) )
					{
					tmp_slice[num_slice_angles].i       = i;
					tmp_slice[num_slice_angles].hidden  = FALSE;
					tmp_slice[num_slice_angles].slice   = slice_angle[0][i];
					tmp_slice[num_slice_angles++].angle = MOD_2PI( pie_3D_rad+3.0*M_PI_2 );
					}
				}

		qsort( tmp_slice, num_slice_angles, sizeof(struct tmp_slice_t), ocmpr );
		for( t=0; t<num_slice_angles; ++t )
			{
			gdPoint	gdp[4];

			i = tmp_slice[t].i;

			gdp[0].x  = CX(i,0);					gdp[0].y = CY(i,0);
			gdp[1].x  = CX(i,1);					gdp[1].y = CY(i,1);
			gdp[2].x  = OX(i,tmp_slice[t].angle,1);	gdp[2].y = OY(i,tmp_slice[t].angle,1);
			gdp[3].x  = OX(i,tmp_slice[t].angle,0);	gdp[3].y = OY(i,tmp_slice[t].angle,0);

			if( !(tmp_slice[t].hidden) )
				gdImageFilledPolygon( im, gdp, 4, SliceColorShd[i] );
			else
				{
				rad -= 2.0;										/* no peeking */
				gdp[0].x  = OX(i,slice_angle[0][i],0);	gdp[0].y = OY(i,slice_angle[0][i],0);
				gdp[1].x  = OX(i,slice_angle[0][i],1);	gdp[1].y = OY(i,slice_angle[0][i],1);
				rad += 2.0;
				gdp[2].x  = OX(i,slice_angle[1][i],1);	gdp[2].y = OY(i,slice_angle[1][i],1);
				gdp[3].x  = OX(i,slice_angle[1][i],0);	gdp[3].y = OY(i,slice_angle[1][i],0);
				gdImageFilledPolygon( im, gdp, 4, SliceColorShd[i] );
				gdp[2].x  = OX(i,slice_angle[2][i],1);	gdp[2].y = OY(i,slice_angle[2][i],1);
				gdp[3].x  = OX(i,slice_angle[2][i],0);	gdp[3].y = OY(i,slice_angle[2][i],0);
				gdImageFilledPolygon( im, gdp, 4, SliceColorShd[i] );
				}
				

			if( GDCPIE_EdgeColor != GDC_NOCOLOR )
				{
				gdImageLine( im, CX(i,0), CY(i,0), CX(i,1), CY(i,1), EdgeColorShd );
				gdImageLine( im, OX(i,tmp_slice[t].angle,0), OY(i,tmp_slice[t].angle,0),
								 OX(i,tmp_slice[t].angle,1), OY(i,tmp_slice[t].angle,1),
								 EdgeColorShd );
				}
			}
		FREE_ARRAY1( tmp_slice );
		}
		}


	/* ----- pie face ----- */
	{
	/* float	last = 0.0; */
	float	rad1 = rad * 3.0/4.0;
	for( i=0; i<num_points; ++i )
		if( !others[i] &&
			(!GDCPIE_missing || !GDCPIE_missing[i]) )
			{
			int		edge_color = GDCPIE_EdgeColor == GDC_NOCOLOR? SliceColor[i]:
																  EdgeColorShd;
			/* last += val[i]; */
			/* EXPLODE_CX_CY( slice_angle[0][i], i ); */
			gdImageLine( im, CX(i,0), CY(i,0), IX(i,1,0), IY(i,1,0), edge_color );
			gdImageLine( im, CX(i,0), CY(i,0), IX(i,2,0), IY(i,2,0), edge_color );
			gdImageArc( im, CX(i,0), CY(i,0), 
							(int)(rad*ellipsex*2.0), (int)(rad*ellipsey*2.0),
							(TO_INT_DEG_FLOOR(slice_angle[1][i])+270)%360,
							(TO_INT_DEG_CEIL(slice_angle[2][i])+270)%360,
							edge_color );
			/* antialiasing here */
			/* likely only on the face? */
/* bugs in gd2.0.0 */
/*	arc doesn't honor deg>360 */
/*	arcs from gdImageFilledArc() don't match with gdImageArc() */
/*	angles are off */
/*	doesn't always fill completely */
/*			gdImageFilledArc( im, CX(i,0), CY(i,0),  */
/*								  (int)(rad*ellipsex*2.0), (int)(rad*ellipsey*2.0), */
/*								  (TO_INT_DEG_FLOOR(slice_angle[1][i])+270)%360, */
/*								  (TO_INT_DEG_CEIL(slice_angle[2][i])+270)%360, */
/*								  SliceColor[i], */
/*								  gdPie ); */
			/* attempt to fill, if slice is wide enough */
			{
			float	rad = rad1;										/* local override */
			if( (ABS(IX(i,1,1)-IX(i,2,1)) + ABS(IY(i,1,1)-IY(i,2,1))) > 2 )
				{
				gdImageFillToBorder( im, IX(i,0,0), IY(i,0,0), edge_color, SliceColor[i] );
				}
			/* catch missed pixels on narrow slices */
			gdImageLine( im, CX(i,0), CY(i,0), IX(i,0,0), IY(i,0,0), SliceColor[i] );
			}
			}
	}

	if( GDCPIE_title )
		{
		struct fnt_sz_t	tftsz      = GDCfnt_sz( GDCPIE_title,
												GDCPIE_title_size,
												gdcpie_title_font, gdcpie_title_ptsize, 0.0, NULL );
		GDCImageStringNL( im,
						  &GDC_fontc[GDCPIE_title_size],
						  gdcpie_title_font, gdcpie_title_ptsize,
						  0.0,
						  IMGWIDTH/2 - tftsz.w/2,
						  1,
						  GDCPIE_title,
						  LineColor,
						  GDC_JUSTIFY_CENTER,
						  NULL );
		}

	/* labels */
	if( lbl )
		{
		float	liner = rad;

		rad += GDCPIE_label_dist;
		for( i=0; i<num_points; ++i )
			{
			if( !others[i] &&
				(!GDCPIE_missing || !GDCPIE_missing[i]) )
				{
				int		lblx,  pctx,
						lbly,  pcty,
						linex, liney;

				lbly = (liney = IY(i,0,0))-lbl_ftsz[i].h / 2;
				lblx = pctx = linex = IX(i,0,0);

				if( slice_angle[0][i] > M_PI )								/* which semicircle */
					{
					lblx -= lbl_ftsz[i].w;
					pctx = lblx;
					++linex;
					}
				else
					--linex;

				switch( GDCPIE_percent_labels )
					{
					case GDCPIE_PCT_LEFT:	if( slice_angle[0][i] > M_PI )
												pctx -= lbl_ftsz[i].w-1;
											else
												lblx += pct_ftsz[i].w+1;
											pcty = IY(i,0,0) - ( 1+pct_ftsz[i].h ) / 2;
											break;
					case GDCPIE_PCT_RIGHT:	if( slice_angle[0][i] > M_PI )
												lblx -= pct_ftsz[i].w-1;
											else
												pctx += lbl_ftsz[i].w+1;
											pcty = IY(i,0,0) - ( 1+pct_ftsz[i].h ) / 2;
											break;
					case GDCPIE_PCT_ABOVE:	lbly += (1+pct_ftsz[i].h) / 2;
											pcty = lbly - pct_ftsz[i].h;
											break;
					case GDCPIE_PCT_BELOW:	lbly -= (1+pct_ftsz[i].h) / 2;
											pcty = lbly + lbl_ftsz[i].h;
											break;
					case GDCPIE_PCT_NONE:
					default:;
					}

				if( GDCPIE_percent_labels != GDCPIE_PCT_NONE )
					GDCImageStringNL( im,
									  &GDC_fontc[GDCPIE_label_size],
									  gdcpie_label_font, gdcpie_label_ptsize,
									  0.0,
									  slice_angle[0][i] <= M_PI? pctx:
																 pctx+lbl_ftsz[i].w-pct_ftsz[i].w,
									  pcty,
									  pct_lbl[i],
									  LineColor,
									  GDC_JUSTIFY_CENTER,
									  NULL );
				if( lbl[i] )
					GDCImageStringNL( im,
									  &GDC_fontc[GDCPIE_label_size],
									  gdcpie_label_font, gdcpie_label_ptsize,
									  0.0,
									  lblx,
									  lbly,
									  lbl[i],
									  LineColor,
									  slice_angle[0][i] <= M_PI? GDC_JUSTIFY_LEFT:
																 GDC_JUSTIFY_RIGHT,
									  NULL );
				if( GDCPIE_label_line )
					{
					float	rad = liner;
					gdImageLine( im, linex, liney, IX(i,0,0), IY(i,0,0), LineColor );
					}
				}
			}
		rad -= GDCPIE_label_dist;
		}

		fflush( img_fptr );
		switch( GDC_image_type )
			{
#ifdef HAVE_JPEG
			case GDC_JPEG:	gdImageJpeg( im, img_fptr, GDC_jpeg_quality );	break;
#endif
			case GDC_WBMP:	gdImageWBMP( im, PlotColor, img_fptr );			break;
			case GDC_GIF:	gdImageGif( im, img_fptr);						break;
			case GDC_PNG:
			default:		gdImagePng( im, img_fptr );
			}

	FREE_ARRAY1( lbl_ftsz );
	FREE_ARRAY1( pct_ftsz );
	FREE_ARRAY2( pct_lbl );

	FREE_ARRAY2( slice_angle );
	FREE_ARRAY1( others );

	FREE_ARRAY1( SliceColorShd );
	FREE_ARRAY1( SliceColor );
	gdImageDestroy(im);
	return;
}
Example #16
0
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");
}
Example #17
0
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;
}
Example #18
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;
}
Example #19
0
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;
}
Example #20
0
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);
    }
}