Exemplo n.º 1
0
/**
 * Draw a polygon in the foreground color, applying clipping if necessary.
 * The polygon is only closed if the first point is repeated at the end.
 * Some care is taken to plot the endpoints correctly if the current
 * drawing mode is XOR.  However, internal crossings are not handled
 * correctly.
 *
 * @param psd Drawing surface.
 * @param count Number of points in polygon.
 * @param points The array of points.
 */
void
GdPoly(PSD psd, int count, MWPOINT *points)
{
  MWCOORD firstx;
  MWCOORD firsty;
  MWBOOL didline;

  if (count < 2)
	  return;
  firstx = points->x;
  firsty = points->y;
  didline = FALSE;

  while (count-- > 1) {
	if (didline && (gr_mode == MWMODE_XOR))
		drawpoint(psd, points->x, points->y);
	/* note: change to drawline*/
	GdLine(psd, points[0].x, points[0].y, points[1].x, points[1].y, TRUE);
	points++;
	didline = TRUE;
  }
  if (gr_mode == MWMODE_XOR) {
	  points--;
	  if (points->x == firstx && points->y == firsty)
		drawpoint(psd, points->x, points->y);
  }
  GdFixCursor(psd);
}
Exemplo n.º 2
0
void
GdFillPoly(PSD psd, int count, MWPOINT *points)
{
  MWPOINT *pp;		/* current point */
  MWCOORD miny;		/* minimum row */
  MWCOORD maxy;		/* maximum row */
  MWCOORD minx;		/* minimum column */
  MWCOORD maxx;		/* maximum column */
  int i;		/* counter */

  if (count <= 0)
	  return;

  /* First determine the minimum and maximum rows for the polygon. */
  pp = points;
  miny = pp->y;
  maxy = pp->y;
  for (i = count; i-- > 0; pp++) {
	if (miny > pp->y) miny = pp->y;
	if (maxy < pp->y) maxy = pp->y;
  }
  if (miny < 0)
	  miny = 0;
  if (maxy >= psd->yvirtres)
	  maxy = psd->yvirtres - 1;
  if (miny > maxy)
	  return;

  /* Now for each row, scan the list of points and determine the
   * minimum and maximum x coordinate for each line, and plot the row.
   * The last point connects with the first point automatically.
   */
  for (; miny <= maxy; miny++) {
	minx = MAX_MWCOORD;
	maxx = MIN_MWCOORD;
	pp = points;
	for (i = count; --i > 0; pp++)
		extendrow(miny, pp[0].x, pp[0].y, pp[1].x, pp[1].y,
			&minx, &maxx);
	extendrow(miny, pp[0].x, pp[0].y, points[0].x, points[0].y,
		&minx, &maxx);

	if (minx <= maxx)
		drawrow(psd, minx, maxx, miny);
  }
  GdFixCursor(psd);
}
Exemplo n.º 3
0
static void
debug_putchar_graphics (void *arg, short ch)
{
	PSD		psd = (PSD) arg;
	MWCOORD		width;			/* width of text area */
	MWCOORD 	height;			/* height of text area */
	MWCOORD		base;			/* baseline of text */
	const MWIMAGEBITS *bitmap;		/* bitmap for characters */
	MWPIXELVAL	saved_foreground;
	MWPIXELVAL	saved_background;
	MWBOOL		saved_usebg;
	int		saved_mode;
	extern MWPIXELVAL gr_foreground;
	extern MWBOOL	gr_usebg;

	/* Use default system FIXED font. */
	gen_gettextbits ((PMWFONT) &gen_fonts[1], ch,
		&bitmap, &width, &height, &base);

	/* Put character, move cursor. */
	switch (ch) {
	case '\n':
		debug_x = 0;
		debug_y += height;
		break;
	case '\r':
		debug_x = 0;
		break;
	case '\t':
		/* Tab stops at every 4 char heights. */
		debug_x = ((debug_x / height) + 4) / 4 * 4 * height;
		break;
	case '\b':
		if (debug_x >= width)
			debug_x -= width;
		break;
	default:
		/* Draw in COPY mode with black background. */
		saved_foreground = gr_foreground;
		saved_background = gr_background;
		saved_usebg = gr_usebg;
		saved_mode = gr_mode;
		gr_foreground = ~0L;
		gr_background = 0;
		gr_usebg = TRUE;
		gr_mode = MWMODE_COPY;
		drawbitmap (psd, debug_x, debug_y, width, height, bitmap);
		gr_foreground = saved_foreground;
		gr_background = saved_background;
		gr_usebg = saved_usebg;
		gr_mode = saved_mode;

		GdFixCursor (psd);

		debug_x += width;
		break;
	}

	if (debug_x + width > psd->xvirtres) {
		/* Roll over right margin. */
		debug_x = 0;
		debug_y += height;
	}

	if (debug_y + height > psd->yvirtres) {
		/* Roll over the screen. */
		debug_y = 0;
	}
}
Exemplo n.º 4
0
/**
 * Draw a filled polygon.
 *
 * @param psd Drawing surface.
 * @param count Number of points in polygon.
 * @param pointtable The array of points.
 */
void
GdFillPoly(PSD psd, int count, MWPOINT * pointtable)
{
	edge_t *get;		/* global edge table */
	int     nge = 0;	/* num global edges */
	int     cge = 0;	/* cur global edge */

	edge_t *aet;		/* active edge table */
	int     nae = 0;	/* num active edges */

	int     i, y;

	if (count < 3) {
		/* error, polygons require at least three edges (a triangle) */
		return;
	}
	get = (edge_t *) calloc(count, sizeof(edge_t));
	aet = (edge_t *) calloc(count, sizeof(edge_t));

	if ((get == 0) || (aet == 0)) {
		/* error, couldn't allocate one or both of the needed tables */
		if (get)
			free(get);
		if (aet)
			free(aet);
		return;
	}
	/* setup the global edge table */
	for (i = 0; i < count; ++i) {
		get[nge].x1 = pointtable[i].x;
		get[nge].y1 = pointtable[i].y;
		get[nge].x2 = pointtable[(i + 1) % count].x;
		get[nge].y2 = pointtable[(i + 1) % count].y;
		if (get[nge].y1 != get[nge].y2) {
			if (get[nge].y1 > get[nge].y2) {
				swap(get[nge].x1, get[nge].x2);
				swap(get[nge].y1, get[nge].y2);
			}
#if USE_FLOAT
			get[nge].x = get[nge].x1;
			get[nge].m = get[nge].x2 - get[nge].x1;
			get[nge].m /= get[nge].y2 - get[nge].y1;
#else
			get[nge].cx = get[nge].x1;
			get[nge].mn = get[nge].x2 - get[nge].x1;
			get[nge].d = get[nge].y2 - get[nge].y1;
			get[nge].fn = get[nge].mn / 2;
#endif
			++nge;
		}
	}

	qsort(get, nge, sizeof(get[0]), edge_cmp);

	/* start with the lowest y in the table */
	y = get[0].y1;

	do {

		/* add edges to the active table from the global table */
		while ((nge > 0) && (get[cge].y1 == y)) {
			aet[nae] = get[cge++];
			--nge;
			aet[nae++].y1 = 0;
		}

		qsort(aet, nae, sizeof(aet[0]), edge_cmp);

		/* using odd parity, render alternating line segments */
		for (i = 1; i < nae; i += 2) {
#if USE_FLOAT
			int     l = (int)aet[i - 1].x;
			int     r = (int)aet[i].x;
#else
			int     l = (int)aet[i - 1].cx;
			int     r = (int)aet[i].cx;
#endif
			if (r > l)
				drawrow(psd, l, r - 1, y);
		}

		/* prepare for the next scan line */
		++y;

		/* remove inactive edges from the active edge table */
		/* or update the current x position of active edges */
		for (i = 0; i < nae; ++i) {
			if (aet[i].y2 == y)
				aet[i--] = aet[--nae];
			else {
#if USE_FLOAT
				aet[i].x += aet[i].m;
#else
				aet[i].fn += aet[i].mn;
				if (aet[i].fn < 0) {
					aet[i].cx += aet[i].fn / aet[i].d - 1;
					aet[i].fn %= aet[i].d;
					aet[i].fn += aet[i].d;
				}
				if (aet[i].fn >= aet[i].d) {
					aet[i].cx += aet[i].fn / aet[i].d;
					aet[i].fn %= aet[i].d;
				}
#endif
			}
		}

		/* keep doing this while there are any edges left */
	} while ((nae > 0) || (nge > 0));

	/* all done, free the edge tables */
	free(get);
	free(aet);

	GdFixCursor(psd);
}
Exemplo n.º 5
0
void
GdFillPoly(PSD psd, int count, MWPOINT *pointtable)
{
    MWCOORD xl = 0, xr = 0;     /* x vals of left and right edges */
    int dl = 0, dr = 0;         /* decision variables             */
    int ml = 0, m1l = 0;        /* left edge slope and slope+1    */
    int mr = 0, m1r = 0;        /* right edge slope and slope+1   */
    int incr1l = 0, incr2l = 0; /* left edge error increments     */
    int incr1r = 0, incr2r = 0; /* right edge error increments    */
    int dy;                     /* delta y                        */
    MWCOORD y;                  /* current scanline               */
    int left, right;            /* indices to first endpoints     */
    int i;                      /* loop counter                   */
    int nextleft, nextright;    /* indices to second endpoints    */
    MWPOINT *ptsOut, *FirstPoint;/* output buffer                 */
    MWCOORD *width, *FirstWidth;/* output buffer                  */
    int imin;                   /* index of smallest vertex (in y)*/
    int ymin;                   /* y-extents of polygon           */
    int ymax;

    /*
     *  find leftx, bottomy, rightx, topy, and the index
     *  of bottomy.
     */

    imin = getPolyYBounds(pointtable, count, &ymin, &ymax);

    if (gr_fillmode != MWFILL_SOLID) {
      int xmin, xmax;
      getPolyXBounds(pointtable, count, &xmin, &xmax);
      set_ts_origin(xmin, ymin);
    }

    dy = ymax - ymin + 1;
    if ((count < 3) || (dy < 0))
	return;
    ptsOut = FirstPoint = (MWPOINT *)ALLOCA(sizeof(MWPOINT) * dy);
    width = FirstWidth = (MWCOORD *)ALLOCA(sizeof(MWCOORD) * dy);
    if(!FirstPoint || !FirstWidth)
    {
	if (FirstWidth) FREEA(FirstWidth);
	if (FirstPoint) FREEA(FirstPoint);
	return;
    }

    nextleft = nextright = imin;
    y = pointtable[nextleft].y;

    /*
     *  loop through all edges of the polygon
     */
    do {
        /*
         *  add a left edge if we need to
         */
        if (pointtable[nextleft].y == y) {
            left = nextleft;

            /*
             *  find the next edge, considering the end
             *  conditions of the array.
             */
            nextleft++;
            if (nextleft >= count)
                nextleft = 0;

            /*
             *  now compute all of the random information
             *  needed to run the iterative algorithm.
             */
            BRESINITPGON(pointtable[nextleft].y-pointtable[left].y,
                         pointtable[left].x,pointtable[nextleft].x,
                         xl, dl, ml, m1l, incr1l, incr2l);
        }

        /*
         *  add a right edge if we need to
         */
        if (pointtable[nextright].y == y) {
            right = nextright;

            /*
             *  find the next edge, considering the end
             *  conditions of the array.
             */
            nextright--;
            if (nextright < 0)
                nextright = count-1;

            /*
             *  now compute all of the random information
             *  needed to run the iterative algorithm.
             */
            BRESINITPGON(pointtable[nextright].y-pointtable[right].y,
                         pointtable[right].x,pointtable[nextright].x,
                         xr, dr, mr, m1r, incr1r, incr2r);
        }

        /*
         *  generate scans to fill while we still have
         *  a right edge as well as a left edge.
         */
        i = MWMIN(pointtable[nextleft].y, pointtable[nextright].y) - y;
	/* in case we're called with non-convex polygon */
	if(i < 0)
        {
	    FREEA(FirstWidth);
	    FREEA(FirstPoint);
	    return;
	}
        while (i-- > 0) 
        {
            ptsOut->y = y;

            /*
             *  reverse the edges if necessary
             */
            if (xl < xr) 
            {
                *(width++) = xr - xl;
                (ptsOut++)->x = xl;
            }
            else 
            {
                *(width++) = xl - xr;
                (ptsOut++)->x = xr;
            }
            y++;

            /* increment down the edges */
            BRESINCRPGON(dl, xl, ml, m1l, incr1l, incr2l);
            BRESINCRPGON(dr, xr, mr, m1r, incr1r, incr2r);
        }
    }  while (y != ymax);

    /*
     * Finally, fill the spans
     */
    i = ptsOut-FirstPoint;
    ptsOut = FirstPoint;
    width = FirstWidth;
    while (--i >= 0) {
	/* calc x extent from width*/
	int e = *width++ - 1;
	if (e >= 0) {
	  if (gr_fillmode != MWFILL_SOLID) 
	    ts_drawrow(psd, ptsOut->x, ptsOut->x + e, ptsOut->y);
	   else
	     drawrow(psd, ptsOut->x, ptsOut->x + e, ptsOut->y);
	}
	++ptsOut;
    }

    FREEA(FirstWidth);
    FREEA(FirstPoint);
    GdFixCursor(psd);
}