void SWFShape_drawCurveTo(SWFShape shape, float controlx, float controly,
				float anchorx, float anchory)
{
	SWFShape_drawScaledCurveTo(shape,
					 (int)rint(controlx*Ming_scale),
					 (int)rint(controly*Ming_scale),
					 (int)rint(anchorx*Ming_scale),
					 (int)rint(anchory*Ming_scale));
}
Exemple #2
0
void SWFShape_drawCurveTo(SWFShape shape, double controlx, double controly,
				double anchorx, double anchory)
{
	SWFShape_drawScaledCurveTo(shape,
					 (int)rint(controlx*Ming_scale),
					 (int)rint(controly*Ming_scale),
					 (int)rint(anchorx*Ming_scale),
					 (int)rint(anchory*Ming_scale));
}
Exemple #3
0
void
SWFShape_drawScaledGlyph(SWFShape shape,
												 SWFFont font, unsigned short c, int size)
{
	byte *p = SWFFont_findGlyph(font, c);
	byte **f = &p;

	int moveBits, x=0, y=0;
	int straight, numBits;
	int numFillBits, numLineBits;

	/* moveTos in the record are absolute, but we want to draw from the current
		 location. grr. */

	int startX = shape->xpos;
	int startY = shape->ypos;
	int style;

	byteAlign();

	if ( (numFillBits = readBitsP(f, 4)) != 1 ) /* fill bits */
		SWF_error("SWFShape_drawGlyph: bad file format (was expecting fill bits = 1)");

	if ( (numLineBits = readBitsP(f, 4)) > 1 ) /* line bits */
		SWF_error("SWFShape_drawGlyph: bad file format (was expecting line bits = 0)");

	/* now we get to parse the shape commands.	Oh boy.
		 the first one will be a non-edge block- grab the moveto loc */

	readBitsP(f, 2); /* type 0, newstyles */
	style = readBitsP(f, 3);

	if(readBitsP(f, 1))
	{	moveBits = readBitsP(f, 5);
		x = startX + readSBitsP(f, moveBits);
		y = startY + readSBitsP(f, moveBits);
	}
	else if(style == 0)	/* no style, no move => space character */
		return;

	SWFShape_moveScaledPenTo(shape, x*size/1024, y*size/1024);

	if ( style & 1 )
		if ( readBitsP(f, numFillBits) != 0 ) /* fill0 = 0 */
			SWF_error("SWFFont_getShape: bad file format (was expecting fill0 = 0)");
	if ( style & 2 )
		if ( readBitsP(f, numFillBits) != 1 ) /* fill1 = 1 */
			SWF_error("SWFFont_getShape: bad file format (was expecting fill1 = 1)");
	if ( style & 4 )
		if ( readBitsP(f, numLineBits) != 0 ) /* line = 1 */
			SWF_error("SWFFont_getShape: bad file format (was expecting line = 0)");

	/* translate the glyph's shape records into drawing commands */

	for ( ;; )
	{
		if ( readBitsP(f, 1) == 0 )
		{
			/* it's a moveTo or a shape end */

			if ( readBitsP(f, 5) == 0 )
				break;

			moveBits = readBitsP(f, 5);
			x = startX + readSBitsP(f, moveBits);
			y = startY + readSBitsP(f, moveBits);

			SWFShape_moveScaledPenTo(shape, x*size/1024, y*size/1024);

			continue;
		}

		straight = readBitsP(f, 1);
		numBits = readBitsP(f, 4)+2;

		if ( straight==1 )
		{
			if ( readBitsP(f, 1) ) /* general line */
			{
				x += readSBitsP(f, numBits);
				y += readSBitsP(f, numBits);
			}
			else
			{
				if ( readBitsP(f, 1) ) /* vert = 1 */
					y += readSBitsP(f, numBits);
				else
					x += readSBitsP(f, numBits);
			}

			SWFShape_drawScaledLineTo(shape, x*size/1024, y*size/1024);
		}
		else
		{
			int controlX = readSBitsP(f, numBits);
			int controlY = readSBitsP(f, numBits);
			int anchorX = readSBitsP(f, numBits);
			int anchorY = readSBitsP(f, numBits);

			SWFShape_drawScaledCurveTo(shape,
				 (x+controlX)*size/1024,
				 (y+controlY)*size/1024,
				 (x+controlX+anchorX)*size/1024,
				 (y+controlY+anchorY)*size/1024);

			x += controlX + anchorX;
			y += controlY + anchorY;
		}
	}

	/* no idea where the pen was left */
	SWFShape_moveScaledPenTo(shape, startX, startY);
}
static int SWFShape_approxCubic(SWFShape shape, cubic *c)
{
	quadratic q;

	float cx, cy, qx, qy;

	if(c->b.x == c->a.x && c->b.y == c->a.y)
	{
		q.a = c->a;
		q.b = c->c;
		q.c = c->d;
	}
	else if(c->d.x == c->c.x && c->d.y == c->c.y)
	{
		q.a = c->a;
		q.b = c->b;
		q.c = c->d;
	}
	else
		if((c->a.x-c->b.x)*(c->c.x-c->b.x)+(c->a.y-c->b.y)*(c->c.y-c->b.y) >= 0 ||
			 (c->b.x-c->c.x)*(c->d.x-c->c.x)+(c->b.y-c->c.y)*(c->d.y-c->c.y) >= 0)
	{
		/* make sure that angles B and C are obtuse, so that outside
			 edges meet on the right side */

			return subdivideCubic(shape, c);
	}
	else
	{
		float bcrossa = c->b.x*c->a.y - c->a.x*c->b.y;
		float ccrossd = c->c.x*c->d.y - c->d.x*c->c.y;

		float denom = (c->a.y-c->b.y)*(c->d.x-c->c.x) -
			(c->a.x-c->b.x)*(c->d.y-c->c.y);

		if(denom == 0)
		{
			/* XXX - they're collinear?? */
			SWFShape_drawScaledLineTo(shape, (int)rint(c->d.x), (int)rint(c->d.y));
			return 1;
		}

		q.a = c->a;
		q.b.x = ((c->d.x-c->c.x)*bcrossa + (c->b.x-c->a.x)*ccrossd) / denom;
		q.b.y = ((c->d.y-c->c.y)*bcrossa + (c->b.y-c->a.y)*ccrossd) / denom;
		q.c = c->d;
	}

	halfpointCubic(c, &cx, &cy);
	halfpointQuadratic(&q, &qx, &qy);

	if(errorPoints(cx, cy, qx, qy) > Ming_cubicThreshold)
	{
		return subdivideCubic(shape, c);
	}
	else
	{
		/* draw quadratic w/ control point at intersection of outside edges */

		SWFShape_drawScaledCurveTo(shape, (int)rint(q.b.x), (int)rint(q.b.y),
						 (int)rint(q.c.x), (int)rint(q.c.y));
		return 1;
	}
}