Example #1
0
static void
fz_drawtriangle(fz_pixmap *pix, float *av, float *bv, float *cv, int n)
{
	float poly[MAXV][MAXN];
	float temp[MAXV][MAXN];
	float cx0 = pix->x;
	float cy0 = pix->y;
	float cx1 = pix->x + pix->w;
	float cy1 = pix->y + pix->h;

	int gel[MAXV][MAXN];
	int ael[2][MAXN];
	int del[2][MAXN];
	int y, s0, s1, e0, e1;
	int top, bot, len;

	int i, k;

	copyvert(poly[0], av, n);
	copyvert(poly[1], bv, n);
	copyvert(poly[2], cv, n);

	len = clippoly(poly, temp,   3, n, cx0, 0, 0);
	len = clippoly(temp, poly, len, n, cx1, 0, 1);
	len = clippoly(poly, temp, len, n, cy0, 1, 0);
	len = clippoly(temp, poly, len, n, cy1, 1, 1);

	if (len < 3)
		return;

	for (i = 0; i < len; i++)
	{
		gel[i][0] = fz_floor(poly[i][0] + 0.5) * 65536; /* trunc and fix */
		gel[i][1] = fz_floor(poly[i][1] + 0.5);	/* y is not fixpoint */
		for (k = 2; k < n; k++)
			gel[i][k] = poly[i][k] * 65536;	/* fix with precision */
	}

	top = bot = 0;
	for (i = 0; i < len; i++)
	{
		if (gel[i][1] < gel[top][1])
			top = i;
		if (gel[i][1] > gel[bot][1])
			bot = i;
	}

	if (gel[bot][1] - gel[top][1] == 0)
		return;

	y = gel[top][1];

	if (findnext(gel, len, top, &s0, &e0,  1))
		return;
	if (findnext(gel, len, top, &s1, &e1, -1))
		return;

	loadedge(gel, s0, e0, ael[0], del[0], n);
	loadedge(gel, s1, e1, ael[1], del[1], n);

	while (1)
	{
		int x0 = ael[0][0] >> 16;
		int x1 = ael[1][0] >> 16;

		if (ael[0][0] < ael[1][0])
			drawscan(pix, y, x0, x1, ael[0]+2, ael[1]+2, n-2);
		else
			drawscan(pix, y, x1, x0, ael[1]+2, ael[0]+2, n-2);

		stepedge(ael[0], del[0], n);
		stepedge(ael[1], del[1], n);
		y ++;

		if (y >= gel[e0][1])
		{
			if (findnext(gel, len, e0, &s0, &e0, 1))
				return;
			loadedge(gel, s0, e0, ael[0], del[0], n);
		}

		if (y >= gel[e1][1])
		{
			if (findnext(gel, len, e1, &s1, &e1, -1))
				return;
			loadedge(gel, s1, e1, ael[1], del[1], n);
		}
	}
}
Example #2
0
LOCAL void fbp_drawtriangle(struct rfb_Display *mod, struct rfb_Window *v,
	TINT x0, TINT y0, TINT x1, TINT y1, TINT x2, TINT y2, struct rfb_Pen *pen)
{
	struct Coord res[MAX_VERT];
	TINT outlen;

	struct Region R;

	if (!rfb_getlayermask(mod, &R, v->rfbw_ClipRect.r, v, 0, 0))
		return;

	TUINT p = pixconv_rgbfmt(v->rfbw_PixBuf.tpb_Format, pen->rgb);

	struct TNode *next, *node = R.rg_Rects.rl_List.tlh_Head.tln_Succ;

	for (; (next = node->tln_Succ); node = next)
	{
		struct RectNode *rn = (struct RectNode *) node;
		TINT *r = rn->rn_Rect;

		if (!clippoly(res, &outlen, x0, y0, x1, y1, x2, y2,
				r[0], r[1], r[2], r[3]))
			continue;

		TINT d[4];

		if (outlen == 1)
		{
			d[0] = res[0].x;
			d[1] = res[0].y;
			d[2] = res[0].x;
			d[3] = res[0].y;
			rfb_markdirty(mod, v, d);
			pixconv_setpixelbuf(&v->rfbw_PixBuf, res[0].x, res[0].y, p);
		}
		else if (outlen == 2)
		{
			TINT rect[4] = { res[0].x, res[0].y, res[1].x, res[1].y };
			rfb_markdirty(mod, v, rect);
			fbp_drawline(mod, v, rect, pen);
		}
		else
		{
			TINT i;

			d[0] = TMIN(TMIN(res[0].x, res[1].x), res[2].x);
			d[1] = TMIN(TMIN(res[0].y, res[1].y), res[2].y);
			d[2] = TMAX(TMAX(res[0].x, res[1].x), res[2].x);
			d[3] = TMAX(TMAX(res[0].y, res[1].y), res[2].y);
			rfb_markdirty(mod, v, d);

			rendertriangle(v, res[0], res[1], res[2], p);
			for (i = 2; i < outlen; i++)
			{
				if ((i + 1) < outlen)
					rendertriangle(v, res[0], res[i], res[i + 1], p);
			}
		}
	}
	region_free(&mod->rfb_RectPool, &R);
}