Esempio n. 1
0
fixed_t FV_Distance(const vector_t *p1, const vector_t *p2)
{
	INT32 xs = FixedMul(p2->x-p1->x,p2->x-p1->x);
	INT32 ys = FixedMul(p2->y-p1->y,p2->y-p1->y);
	INT32 zs = FixedMul(p2->z-p1->z,p2->z-p1->z);
	return FixedSqrt(xs+ys+zs);
}
Esempio n. 2
0
fixed_t FV_Magnitude(const vector_t *a_normal)
{
	INT32 xs = FixedMul(a_normal->x,a_normal->x);
	INT32 ys = FixedMul(a_normal->y,a_normal->y);
	INT32 zs = FixedMul(a_normal->z,a_normal->z);
	return FixedSqrt(xs+ys+zs);
}
Esempio n. 3
0
fixed_t FixedHypot(fixed_t x, fixed_t y)
{
#ifdef HAVE_HYPOT
	const float fx = FIXED_TO_FLOAT(x);
	const float fy = FIXED_TO_FLOAT(y);
	float fz;
#ifdef HAVE_HYPOTF
	fz = hypotf(fx, fy);
#else
	fz = (float)hypot(fx, fy);
#endif
	return FLOAT_TO_FIXED(fz);
#else // !HAVE_HYPOT
	fixed_t ax, yx, yx2, yx1;
	if (abs(y) > abs(x)) // |y|>|x|
	{
		ax = abs(y); // |y| => ax
		yx = FixedDiv(x, y); // (x/y)
	}
	else // |x|>|y|
	{
		ax = abs(x); // |x| => ax
		yx = FixedDiv(y, x); // (x/y)
	}
	yx2 = FixedMul(yx, yx); // (x/y)^2
	yx1 = FixedSqrt(1+FRACUNIT + yx2); // (1 + (x/y)^2)^1/2
	return FixedMul(ax, yx1); // |x|*((1 + (x/y)^2)^1/2)
#endif
}
Esempio n. 4
0
//
// IntersectRaySphere
// Input : rO - origin of ray in world space
//         rV - vector describing direction of ray in world space
//         sO - Origin of sphere
//         sR - radius of sphere
// Notes : Normalized directional vectors expected
// Return: distance to sphere in world units, -1 if no intersection.
//
fixed_t FV_IntersectRaySphere(const vector_t *rO, const vector_t *rV, const vector_t *sO, fixed_t sR)
{
	vector_t Q;
	fixed_t c, v, d;
	FV_SubEx(sO, rO, &Q);

	c = FV_Magnitude(&Q);
	v = FV_Dot(&Q, rV);
	d = FixedMul(sR, sR) - (FixedMul(c,c) - FixedMul(v,v));

	// If there was no intersection, return -1
	if (d < 0*FRACUNIT)
		return (-1*FRACUNIT);

	// Return the distance to the [first] intersecting point
	return (v - FixedSqrt(d));
}
Esempio n. 5
0
/* Read Type 13 charstring. Initial seek to offset performed if offset != -1 */
static void t13Read(cffCtx h, Offset offset, int init, int csLen)
	{
	unsigned length;

	switch (init)
		{
	case cstr_GLYPH:
		/* Initialize glyph charstring */
		h->stack.cnt = 0;
		h->path.nStems = 0;
		h->path.flags = GET_WIDTH|FIRST_MOVE|FIRST_MASK;
		break;
	case cstr_DICT:
		/* Initialize DICT charstring */
		h->path.flags = DICT_CSTR;
		break;
	case cstr_METRIC:
		/* Initialize metric charstring */
		h->stack.cnt = 0;
		h->path.flags = 0;
		break;
		}

	if (offset != -1)
		/* Seek to position of charstring if not already positioned */
		seekbyte(h, offset);

	for (;;)
		{
		int j;
		Fixed a;
		Fixed b;
		int byte0 = GETBYTE(h);
		switch (byte0)
			{
		case t13_endchar:
			if (!(h->path.flags & DICT_CSTR))
				{
				if (h->path.flags & FIRST_MOVE)
					{
					/* Non-marking glyph; set bounds */
					h->path.left = h->path.right = 0;
					h->path.bottom = h->path.top = 0;
					}
				if ((h->path.flags & GET_WIDTH) && setAdvance(h))
					return;	/* Stop after getting width */
				if (h->stack.cnt > 1)
					{
					/* Process seac components */
					int base;
					int accent;
					j = (h->stack.cnt == 4)? 0: 1;
					a = indexFix(h, j++);
					b = indexFix(h, j++);
					base = indexInt(h, j++);
					accent = indexInt(h, j);
					setComponentBounds(h, 0, base, 0, 0);
					setComponentBounds(h, 1, accent, a, b);
					}
				}
			PATH_FUNC_CALL(endchar,(h->cb.ctx));
			h->path.flags |= SEEN_END;
			return;
		case t13_reserved0:
		case t13_reserved236:
		case t13_reserved237:
		case t13_reserved244:
		case t13_reserved255:
			fatal(h, "reserved charstring op");
		case t13_rlineto:
			for (j = 0; j < h->stack.cnt; j += 2)
				addLine(h, indexFix(h, j + 0), indexFix(h, j + 1));
			h->stack.cnt = 0;
			break;
		case t13_hlineto:
		case t13_vlineto:
			{
			int horz = byte0 == t13_hlineto;
			for (j = 0; j < h->stack.cnt; j++)
				if (horz++ & 1)
					addLine(h, indexFix(h, j), 0);
				else
					addLine(h, 0, indexFix(h, j));
			}
			h->stack.cnt = 0;
			break;
		case t13_rrcurveto:
			for (j = 0; j < h->stack.cnt; j += 6)
				addCurve(h, 0,
						 indexFix(h, j + 0), indexFix(h, j + 1), 
						 indexFix(h, j + 2), indexFix(h, j + 3), 
						 indexFix(h, j + 4), indexFix(h, j + 5));
			h->stack.cnt = 0;
			break;
		case t13_callsubr:
			{
			Offset save = TELL(h);
			Offset localOffset = INDEXGet(h, &h->index.Subrs, popInt(h) + 
										  h->index.Subrs.bias, &length);
			t13Read(h, localOffset, cstr_NONE, length);
			if (h->path.flags & SEEN_END)
				return;		/* endchar operator terminated subr */
			seekbyte(h, save);
			}
			break;
		case t13_return:
			return;
		case t13_rcurveline:
			for (j = 0; j < h->stack.cnt - 2; j += 6)
				addCurve(h, 0,
						 indexFix(h, j + 0), indexFix(h, j + 1), 
						 indexFix(h, j + 2), indexFix(h, j + 3), 
						 indexFix(h, j + 4), indexFix(h, j + 5));
			addLine(h, indexFix(h, j + 0), indexFix(h, j + 1));
			h->stack.cnt = 0;
			break;
		case t13_rlinecurve:
			for (j = 0; j < h->stack.cnt - 6; j += 2)
				addLine(h, indexFix(h, j + 0), indexFix(h, j + 1));
			addCurve(h, 0,
					 indexFix(h, j + 0), indexFix(h, j + 1), 
					 indexFix(h, j + 2), indexFix(h, j + 3), 
					 indexFix(h, j + 4), indexFix(h, j + 5));
			h->stack.cnt = 0;
			break;
		case t13_vvcurveto:
			if (h->stack.cnt & 1)
				{
				/* Add initial curve */
				addCurve(h, 0,
						 indexFix(h, 0), indexFix(h, 1), 
						 indexFix(h, 2), indexFix(h, 3), 
						 0,				 indexFix(h, 4));
				j = 5;
				}
			else
				j = 0;

			/* Add remaining curve(s) */
			for (; j < h->stack.cnt; j += 4)
				addCurve(h, 0,
						 0, 				 indexFix(h, j + 0), 
						 indexFix(h, j + 1), indexFix(h, j + 2), 
						 0, 				 indexFix(h, j + 3));
			h->stack.cnt = 0;
			break;
		case t13_hhcurveto:
			if (h->stack.cnt & 1)
				{
				/* Add initial curve */
				addCurve(h, 0,
						 indexFix(h, 1), indexFix(h, 0), 
						 indexFix(h, 2), indexFix(h, 3), 
						 indexFix(h, 4), 0);
				j = 5;
				}
			else
				j = 0;

			/* Add remaining curve(s) */
			for (; j < h->stack.cnt; j += 4)
				addCurve(h, 0,
						 indexFix(h, j + 0), 0,
						 indexFix(h, j + 1), indexFix(h, j + 2), 
						 indexFix(h, j + 3), 0);
			h->stack.cnt = 0;
			break;
		case t13_callgsubr:
			{
			Offset save = TELL(h);
			Offset localOffset = INDEXGet(h, &h->index.global, popInt(h) + 
											  h->index.global.bias, &length);
			t13Read(h, localOffset, cstr_NONE, length);
			if (h->path.flags & SEEN_END)
				return;		/* endchar operator terminated subr */
			seekbyte(h, save);
			}
			break;
		case t13_vhcurveto:
		case t13_hvcurveto:
			{
			int adjust = (h->stack.cnt & 1)? 5: 0;
			int horz = byte0 == t13_hvcurveto;

			/* Add initial curve(s) */
			for (j = 0; j < h->stack.cnt - adjust; j += 4)
				if (horz++ & 1)
					addCurve(h, 0,
							 indexFix(h, j + 0), 0,
							 indexFix(h, j + 1), indexFix(h, j + 2), 
							 0,				     indexFix(h, j + 3));
				else
					addCurve(h, 0,
							 0,				     indexFix(h, j + 0),
							 indexFix(h, j + 1), indexFix(h, j + 2), 
							 indexFix(h, j + 3), 0);

			if (j < h->stack.cnt)
				{
				/* Add last curve */
				if (horz & 1)
					addCurve(h, 0,
							 indexFix(h, j + 0), 0,
							 indexFix(h, j + 1), indexFix(h, j + 2), 
							 indexFix(h, j + 4), indexFix(h, j + 3));
				else
					addCurve(h, 0,
							 0,				     indexFix(h, j + 0),
							 indexFix(h, j + 1), indexFix(h, j + 2), 
							 indexFix(h, j + 3), indexFix(h, j + 4));
				}
			h->stack.cnt = 0;
			}
			break;
		case t13_rmoveto:
			b = popFix(h);
			a = popFix(h);
			if (addMove(h, a, b))
				return;	/* Stop after getting width */
			h->stack.cnt = 0;
			break;
		case t13_hmoveto:
			if (addMove(h, popFix(h), 0))
				return;	/* Stop after getting width */
			h->stack.cnt = 0;
			break;
		case t13_vmoveto:
			if (addMove(h, 0, popFix(h)))
				return;	/* Stop after getting width */
			h->stack.cnt = 0;
			break;
		case t13_hstem:
		case t13_vstem:
		case t13_hstemhm:
		case t13_vstemhm:
			if ((h->path.flags & GET_WIDTH) && setAdvance(h))
				return;	/* Stop after getting width */
			h->path.nStems += h->stack.cnt / 2;
			if (PATH_FUNC_DEFINED(hintstem))
				{
				int vert = byte0 == tx_vstem || byte0 == t2_vstemhm;
				b = vert? h->path.vstem: h->path.hstem;
				for (j = h->stack.cnt & 1; j < h->stack.cnt; j += 2)
					{
					a = b + indexFix(h, j);
					b = a + indexFix(h, j + 1);
					h->path.cb->hintstem(h->cb.ctx, vert, a, b);
					}
				if (vert)
					h->path.vstem = b;
				else
					h->path.hstem = b;
				}
			h->stack.cnt = 0;
			break;
		case t13_hintmask:
		case t13_cntrmask:
			{
			int cnt;
			if (h->path.flags & FIRST_MASK)
				{
				/* The vstem(hm) op may be omitted if stem list is followed by
				   a mask op. In this case count the additional stems */
				if (PATH_FUNC_DEFINED(hintstem))
					{
					b = h->path.vstem;
					for (j = h->stack.cnt & 1; j < h->stack.cnt; j += 2)
						{
						a = b + indexFix(h, j);
						b = a + indexFix(h, j + 1);
						h->path.cb->hintstem(h->cb.ctx, 1, a, b);
						}
					}
				h->path.nStems += h->stack.cnt / 2;
				h->stack.cnt = 0;
				h->path.flags &= ~FIRST_MASK;
				}
			cnt = (h->path.nStems + 7) / 8;
			if (PATH_FUNC_DEFINED(hintmask))
				{
				char mask[CFF_MAX_MASK_BYTES];
				for (j = 0; j < cnt; j++)
					mask[j] = GETBYTE(h);
				h->path.cb->hintmask(h->cb.ctx, 
									 byte0 == t2_cntrmask, cnt, mask);
				}
			else
				while (cnt--)
					(void)GETBYTE(h);	/* Discard mask bytes */
			}
			break;
		case t13_escape:
			{
			double x;
			double y;
			switch (t13_ESC(GETBYTE(h)))
				{
			case t13_dotsection:
				break;
			default:
			case t13_reservedESC255:
			case t13_cntron:
				fatal(h, "reserved charstring op");
			case t13_and:
				b = popFix(h);
				a = popFix(h);
				pushInt(h, a && b);
				break;
			case t13_or:
				b = popFix(h);
				a = popFix(h);
				pushInt(h, a || b);
				break;
			case t13_not:
				a = popFix(h);
				pushInt(h, !a);
				break;
			case t13_store:
				{
				int count = popInt(h);
				int i = popInt(h);
				int j = popInt(h);
				int iReg = popInt(h);
				int regSize;
				Fixed *reg = selRegItem(h, iReg, &regSize);
				if (i < 0 || i + count - 1 >= h->BCA.size ||
					j < 0 || j + count - 1 >= regSize)
					fatal(h, "bounds check (store)\n");
				memcpy(&reg[j], &h->BCA.array[i], sizeof(Fixed) * count);
				}
				break;
			case t13_abs:
				a = popFix(h);
				pushFix(h, (a < 0)? -a: a);
				break;
			case t13_add:
				b = popFix(h);
				a = popFix(h);
				pushFix(h, a + b);
				break;
			case t13_sub:
				b = popFix(h);
				a = popFix(h);
				pushFix(h, a - b);
				break;
			case t13_div:
				y = popDbl(h);
				x = popDbl(h);
				if (y == 0.0)
					fatal(h, "divide by zero (div)");
				pushFix(h, DBL2FIX(x / y));
				break;
			case t13_load:
				{
				int regSize;
				int count = popInt(h);
				int i = popInt(h);
				int iReg = popInt(h);
				Fixed *reg = selRegItem(h, iReg, &regSize);
				if (i < 0 || i + count - 1 >= h->BCA.size || count > regSize)
					fatal(h, "bounds check (load)\n");
				memcpy(&h->BCA.array[i], reg, sizeof(Fixed) * count);
				}
				break;
			case t13_neg:
				a = popFix(h);
				pushFix(h, -a);
				break;
			case t13_eq:
				b = popFix(h);
				a = popFix(h);
				pushInt(h, a == b);
				break;
			case t13_drop:
				(void)popFix(h);
				break;
			case t13_put:
				{
				int i = popInt(h);
				if (i < 0 || i >= h->BCA.size)
					fatal(h, "bounds check (put)\n");
				h->BCA.array[i] = popFix(h);
				}
				break;
			case t13_get:
				{
				int i = popInt(h);
				if (i < 0 || i >= h->BCA.size)
					fatal(h, "bounds check (get)\n");
				pushFix(h, h->BCA.array[i]);
				}
				break;
			case t13_ifelse:
				{
				Fixed v2 = popFix(h);
				Fixed v1 = popFix(h);
				Fixed s2 = popFix(h);
				Fixed s1 = popFix(h);
				pushFix(h, (v1 > v2)? s2: s1);
				}
				break;
			case t13_random:	
				pushFix(h, PMRand());
				break;
			case t13_mul:
				y = popDbl(h);
				x = popDbl(h);
				pushFix(h, DBL2FIX(x * y));
				break;
			case t13_sqrt:
				pushFix(h, FixedSqrt(popFix(h)));
				break;
			case t13_dup:
				pushFix(h, h->stack.array[h->stack.cnt - 1].f);
				break;
			case t13_exch:
				b = popFix(h);
				a = popFix(h);
				pushFix(h, b);
				pushFix(h, a);
				break;
			case t13_index:
				{
				int i = popInt(h);
				if (i < 0)
					i = 0;	/* Duplicate top element */
				if (i >= h->stack.cnt)
					fatal(h, "limit check (index)");
				pushFix(h, h->stack.array[h->stack.cnt - 1 - i].f);
				}
				break;
			case t13_roll:
				{
				int j = popInt(h);
				int n = popInt(h);
				int iTop = h->stack.cnt - 1;
				int iBottom = h->stack.cnt - n;

				if (n < 0 || iBottom < 0)
					fatal(h, "limit check (roll)");

				/* Constrain j to [0,n) */
				if (j < 0)
					j = n - (-j % n);
				j %= n;

				reverse(h, iTop - j + 1, iTop);
				reverse(h, iBottom, iTop - j);
				reverse(h, iBottom, iTop);
				}
				break;
			case t13_hflex:
				addCurve(h, 1,
						 indexFix(h, 0),  0,
						 indexFix(h, 1),  indexFix(h, 2),
						 indexFix(h, 3),  0);
				addCurve(h, 1,
						 indexFix(h, 4),  0,
						 indexFix(h, 5),  0,
						 indexFix(h, 6), -indexFix(h, 2));
				h->stack.cnt = 0;
				break;
			case t13_flex:
				addCurve(h, 1,
						 indexFix(h, 0),  indexFix(h, 1),
						 indexFix(h, 2),  indexFix(h, 3),
						 indexFix(h, 4),  indexFix(h, 5));
				addCurve(h, 1,
						 indexFix(h, 6),  indexFix(h, 7),
						 indexFix(h, 8),  indexFix(h, 9),
						 indexFix(h, 10), indexFix(h, 11));
				h->stack.cnt = 0;
				break;
			case t13_hflex1:
				{
				Fixed dy1 = indexFix(h, 1);
				Fixed dy2 = indexFix(h, 3);
				Fixed dy5 = indexFix(h, 7);
				addCurve(h, 1,
						 indexFix(h, 0),  dy1,
						 indexFix(h, 2),  dy2,
						 indexFix(h, 4),  0);		  
				addCurve(h, 1,
						 indexFix(h, 5),  0,		  
						 indexFix(h, 6),  dy5,
						 indexFix(h, 8),  -(dy1 + dy2 + dy5));
				}
				h->stack.cnt = 0;
				break;
			case t13_flex1:
				{
				Fixed dx1 = indexFix(h, 0);
				Fixed dy1 = indexFix(h, 1);
				Fixed dx2 = indexFix(h, 2);
				Fixed dy2 = indexFix(h, 3);
				Fixed dx3 = indexFix(h, 4);
				Fixed dy3 = indexFix(h, 5);
				Fixed dx4 = indexFix(h, 6);
				Fixed dy4 = indexFix(h, 7);
				Fixed dx5 = indexFix(h, 8);
				Fixed dy5 = indexFix(h, 9);
				Fixed dx = dx1 + dx2 + dx3 + dx4 + dx5;
				Fixed dy = dy1 + dy2 + dy3 + dy4 + dy5;
				if (ABS(dx) > ABS(dy))
					{
					dx = indexFix(h, 10);
					dy = -dy;
					}
				else
					{
					dx = -dx;
					dy = indexFix(h, 10);
					}
				addCurve(h, 1, dx1, dy1, dx2, dy2, dx3, dy3);
				addCurve(h, 1, dx4, dy4, dx5, dy5,  dx,  dy);
				}
				h->stack.cnt = 0;
				break;
				}
			}
			break;
		case t13_blend:
			blendValues(h);
			break;
		default:
			/* Matches 1..215, result -107..107 */
			pushInt(h, 108 - byte0);
			break;
		case 241:
			/* 108..363 */
			pushInt(h, 363 - GETBYTE(h));
			break;
		case 239:
			/* 364..619 */
			pushInt(h, 619 - GETBYTE(h));
			break;
		case 246:
			/* 620..875 */
			pushInt(h, GETBYTE(h) + 620);
			break;
		case 235:
			/* 876..1131 */
			pushInt(h, 1131 - GETBYTE(h));
			break;
		case 232:
			/* -108..-363 */
			pushInt(h, GETBYTE(h) - 363);
			break;
		case 228:
			/* -364..-619 */
			pushInt(h, GETBYTE(h) - 619);
			break;
		case 224:
			/* -620..-875 */
			pushInt(h, GETBYTE(h) - 875);
			break;
		case 220:
			/* -876..-1131 */
			pushInt(h, GETBYTE(h) - 1131);
			break;
		case t13_shortint:
			{
			/* 2 byte number */
			long byte1 = GETBYTE(h);
			pushInt(h, byte1<<8 | GETBYTE(h));
			}
			break;
		case t13_shftshort:
			{
			long byte1 = GETBYTE(h);
			pushFix(h, byte1<<23 | GETBYTE(h)<<15);
			}
			break;
		case 254:
			{
			/* 5 byte number */
			long byte1 = GETBYTE(h);
			long byte2 = GETBYTE(h);
			long byte3 = GETBYTE(h);
			pushFix(h, byte1<<24 | byte2<<16 | byte3<<8 | GETBYTE(h));
			}
			break;
			}
		}
	}