Esempio n. 1
0
void
SWFShape_drawScaledLine(SWFShape shape, int dx, int dy)
{
    ShapeRecord record;

    if ( shape->isEnded )
        return;

    if ( dx == 0 && dy == 0 )
        return;

    record = newShapeRecord(shape, SHAPERECORD_LINETO);

    SWF_assert(SWFOutput_numSBits(dx) < 18);
    SWF_assert(SWFOutput_numSBits(dy) < 18);

    record.record.lineTo->dx = dx;
    record.record.lineTo->dy = dy;

    shape->xpos += dx;
    shape->ypos += dy;

    SWFRect_includePoint(SWFCharacter_getBounds(CHARACTER(shape)),
                         shape->xpos, shape->ypos, shape->lineWidth);
    SWFRect_includePoint(shape->edgeBounds, shape->xpos, shape->ypos, 0);
}
Esempio n. 2
0
void
SWFShape_drawScaledCurve(SWFShape shape,
                         int controldx, int controldy,
                         int anchordx, int anchordy)
{
    ShapeRecord record;

    if ( shape->isEnded )
        return;

    if ( controldx == 0 && controldy == 0 && anchordx == 0 && anchordy == 0 )
        return;

    // printf("curve %i,%i, %i, %i\n", controldx, controldy, anchordx,  anchordy);

    record = newShapeRecord(shape, SHAPERECORD_CURVETO);

    record.record.curveTo->controlx = controldx;
    record.record.curveTo->controly = controldy;
    record.record.curveTo->anchorx = anchordx;
    record.record.curveTo->anchory = anchordy;

    if ( SWFOutput_numSBits(controldx) >= 18 ||
            SWFOutput_numSBits(controldy) >= 18 ||
            SWFOutput_numSBits(anchordx) >= 18 ||
            SWFOutput_numSBits(anchordy) >= 18 )
        SWF_error("Curve parameters too large");

    /* including the control point is sloppy, but safe.. */

    shape->xpos += controldx;
    shape->ypos += controldy;

    SWFRect_includePoint(SWFCharacter_getBounds(CHARACTER(shape)),
                         shape->xpos, shape->ypos, shape->lineWidth);
    SWFRect_includePoint(shape->edgeBounds, shape->xpos, shape->ypos, 0);
    shape->xpos += anchordx;
    shape->ypos += anchordy;

    SWFRect_includePoint(SWFCharacter_getBounds(CHARACTER(shape)),
                         shape->xpos, shape->ypos, shape->lineWidth);
    SWFRect_includePoint(shape->edgeBounds, shape->xpos, shape->ypos, 0);
}
Esempio n. 3
0
void
SWFText_resolveCodes(SWFText text)
{
	SWFTextRecord textRecord, oldRecord;
	SWFOutput out = text->out;
	int nGlyphBits = 0;
	int len, i;
	int curX = 0, curY = 0, curH = 0;

	textRecord = text->initialRecord;

	while ( textRecord != NULL )
	{
		SWFTextRecord_computeAdvances(textRecord);

		text->nAdvanceBits = max(text->nAdvanceBits, textRecord->nAdvanceBits);

		if ( textRecord->flags & SWF_TEXT_HAS_FONT )
		{	
			int fontGlyphs = SWFFontCharacter_getNGlyphs(textRecord->font.fontchar);
			nGlyphBits = max(nGlyphBits, SWFOutput_numBits(fontGlyphs-1));
		}

		textRecord = textRecord->next;
	}

	textRecord = text->initialRecord;

	while ( textRecord != NULL )
	{
		SWFFontCharacter fontchar = NULL;
		SWFFont font = NULL;
		oldRecord = textRecord;

		if ( textRecord->string == NULL || textRecord->strlen == 0 )
		{
			textRecord = textRecord->next;
			destroySWFTextRecord(oldRecord);
			continue;
		}

		SWFOutput_byteAlign(out);

		/* Raff says the spec lies- there's always a change record, even if
			 it's empty, and the string record length is the full 8 bits. */

		SWFOutput_writeUInt8(out, textRecord->flags | SWF_TEXT_STATE_CHANGE);

		if ( textRecord->flags & SWF_TEXT_HAS_FONT )
			SWFOutput_writeUInt16(out, CHARACTERID(textRecord->font.fontchar));

		if ( textRecord->flags & SWF_TEXT_HAS_COLOR )
		{
			SWFOutput_writeUInt8(out, textRecord->r);
			SWFOutput_writeUInt8(out, textRecord->g);
			SWFOutput_writeUInt8(out, textRecord->b);

			if ( BLOCK(text)->type == SWF_DEFINETEXT2 )
				SWFOutput_writeUInt8(out, textRecord->a);
		}

		if ( textRecord->flags & SWF_TEXT_HAS_X )
		{
			SWFOutput_writeUInt16(out, textRecord->x);
			curX = textRecord->x;
		}

		if ( textRecord->flags & SWF_TEXT_HAS_Y )
		{
			SWFOutput_writeUInt16(out, textRecord->y);
			curY = textRecord->y;
		}

		if ( textRecord->flags & SWF_TEXT_HAS_FONT )
		{
			SWFOutput_writeUInt16(out, textRecord->height);
			curH = textRecord->height;
		}

		/* record type 0: string data */

		len = textRecord->strlen;

		if ( len >= 256 )
			SWF_error("Found text record >= 256 characters!");

		SWFOutput_writeUInt8(out, len);

		fontchar = textRecord->font.fontchar;
		font = SWFFontCharacter_getFont(fontchar);

		if ( font == NULL )
			SWF_error("Couldn't find font");

		for ( i=0; i<len; ++i )
		{
			SWFRect glyphBounds;
			int minX, maxX, minY, maxY;

			unsigned short font_glyphcode =
				SWFFont_findGlyphCode(font, textRecord->string[i]);
			glyphBounds = SWFFont_getGlyphBounds(font,font_glyphcode);
			SWFRect_getBounds(glyphBounds, &minX, &maxX, &minY, &maxY);

			int fontchar_glyphcode =
				SWFFontCharacter_findGlyphCode(fontchar, textRecord->string[i]);
			if (fontchar_glyphcode < 0) {
				SWF_error("SWFText_resolveCodes: no suitable glyph available (in dumped font)");
			}
			SWFOutput_writeBits(out, (unsigned short) fontchar_glyphcode,	nGlyphBits);
			SWFOutput_writeBits(out, textRecord->advance[i], text->nAdvanceBits);

			if ( CHARACTER(text)->bounds )
			{
				SWFRect_includePoint(CHARACTER(text)->bounds, curX + minX * curH / 1024, 
				                     curY + minY * curH / 1024, 0);
				SWFRect_includePoint(CHARACTER(text)->bounds, curX + maxX * curH / 1024, 
				                     curY + maxY * curH / 1024, 0);
			}
			else
			{
				CHARACTER(text)->bounds = newSWFRect(curX + minX * curH /1024, 
					curX + maxX * curH /1024, curY + minY * curH /1024, 
					curY + maxY * curH /1024);
			}

			if ( textRecord->advance != NULL )
				curX += textRecord->advance[i];
		}
		textRecord = textRecord->next;
		destroySWFTextRecord(oldRecord);
	}
	SWFOutput_writeUInt8(out, 0); /* end text records */

	text->nGlyphBits = nGlyphBits;
	text->initialRecord = NULL;
	text->currentRecord = NULL;
}
Esempio n. 4
0
/* copy shaperecord from other shape */
static ShapeRecord addShapeRecord(SWFShape shape, ShapeRecord record,
                                  int *vx, int *vy, float scale)
{
    if ( shape->nRecords % SHAPERECORD_INCREMENT == 0 )
    {
        shape->records = (ShapeRecord*) realloc(shape->records,
                                                sizeof(ShapeRecord) *
                                                (shape->nRecords + SHAPERECORD_INCREMENT));
    }

    switch ( record.type )
    {
    case SHAPERECORD_STATECHANGE:
    {
        StateChangeRecord change = (StateChangeRecord)
                                   calloc(1,sizeof(struct stateChangeRecord));
        *change = *record.record.stateChange;
        shape->records[shape->nRecords].record.stateChange = change;
        change->moveToX += shape->xpos;
        change->moveToY += shape->ypos;
        change->moveToX *= scale;
        change->moveToY *= scale;

        *vx = change->moveToX;
        *vy = change->moveToY;
        break;
    }
    case SHAPERECORD_LINETO:
    {
        LineToRecord lineTo = (LineToRecord)
                              calloc(1,sizeof(struct lineToRecord));
        *lineTo = *record.record.lineTo;
        lineTo->dx *= scale;
        lineTo->dy *= scale;
        shape->records[shape->nRecords].record.lineTo = lineTo;

        *vx += lineTo->dx;
        *vy += lineTo->dy;
        SWFRect_includePoint(SWFCharacter_getBounds(CHARACTER(shape)),
                             *vx, *vy, shape->lineWidth);
        SWFRect_includePoint(shape->edgeBounds, *vx, *vy, 0);
        break;
    }
    case SHAPERECORD_CURVETO:
    {
        CurveToRecord curveTo = (CurveToRecord)
                                calloc(1,sizeof(struct curveToRecord));
        *curveTo = *record.record.curveTo;
        curveTo->controlx *= scale;
        curveTo->controly *= scale;
        curveTo->anchorx *= scale;
        curveTo->anchory *= scale;
        shape->records[shape->nRecords].record.curveTo = curveTo;

        *vx += curveTo->controlx;
        *vy += curveTo->controly;
        SWFRect_includePoint(SWFCharacter_getBounds(CHARACTER(shape)),
                             *vx, *vy, shape->lineWidth);
        SWFRect_includePoint(shape->edgeBounds, *vx, *vy, 0);
        *vx += curveTo->anchorx;
        *vy += curveTo->anchory;
        SWFRect_includePoint(SWFCharacter_getBounds(CHARACTER(shape)),
                             *vx, *vy, shape->lineWidth);
        SWFRect_includePoint(shape->edgeBounds, *vx, *vy, 0);
        break;
    }
    }
    shape->records[shape->nRecords].type = record.type;
    shape->nRecords++;
    return shape->records[shape->nRecords-1];

}
Esempio n. 5
0
void
SWFText_resolveCodes(SWFText text)
{
	SWFTextRecord textRecord, oldRecord;
	SWFOutput out = text->out;
	int nGlyphBits = 0;
	int len, i;
	int curX = 0, curY = 0, curH = 0;

	textRecord = text->initialRecord;

	while ( textRecord != NULL )
	{
		SWFTextRecord_computeAdvances(textRecord);

		text->nAdvanceBits = max(text->nAdvanceBits, textRecord->nAdvanceBits);

		if ( textRecord->flags & SWF_TEXT_HAS_FONT )
		{
			if ( textRecord->isBrowserFont )
			{
				/* XXX - assume browser fonts have 8bit glyph table? */
				nGlyphBits = max(nGlyphBits, 8);
			}
			else
			{
				int fontGlyphs = SWFFontCharacter_getNGlyphs(textRecord->font.fontchar);
				nGlyphBits = max(nGlyphBits, SWFOutput_numBits(fontGlyphs-1));
			}
		}

		textRecord = textRecord->next;
	}

	textRecord = text->initialRecord;

	while ( textRecord != NULL )
	{
		oldRecord = textRecord;

		if ( textRecord->string == NULL || textRecord->strlen == 0 )
		{
			textRecord = textRecord->next;
			destroySWFTextRecord(oldRecord);
			continue;
		}

		SWFOutput_byteAlign(out);

		/* Raff says the spec lies- there's always a change record, even if
			 it's empty, and the string record length is the full 8 bits. */

		SWFOutput_writeUInt8(out, textRecord->flags | SWF_TEXT_STATE_CHANGE);

		if ( textRecord->flags & SWF_TEXT_HAS_FONT )
		{
			if ( textRecord->isBrowserFont )
				SWFOutput_writeUInt16(out, CHARACTERID(textRecord->font.browserFont));
			else
				SWFOutput_writeUInt16(out, CHARACTERID(textRecord->font.fontchar));
		}

		if ( textRecord->flags & SWF_TEXT_HAS_COLOR )
		{
			SWFOutput_writeUInt8(out, textRecord->r);
			SWFOutput_writeUInt8(out, textRecord->g);
			SWFOutput_writeUInt8(out, textRecord->b);

			if ( BLOCK(text)->type == SWF_DEFINETEXT2 )
				SWFOutput_writeUInt8(out, textRecord->a);
		}

		if ( textRecord->flags & SWF_TEXT_HAS_X )
		{
			SWFOutput_writeUInt16(out, textRecord->x);
			curX = textRecord->x;
		}

		if ( textRecord->flags & SWF_TEXT_HAS_Y )
		{
			SWFOutput_writeUInt16(out, textRecord->y);
			curY = textRecord->y;
		}

		if ( textRecord->flags & SWF_TEXT_HAS_FONT )
		{
			SWFOutput_writeUInt16(out, textRecord->height);
			curH = textRecord->height;
		}

		/* record type 0: string data */

		len = textRecord->strlen;

		if ( len >= 256 )
			SWF_error("Found text record >= 256 characters!");

		SWFOutput_writeUInt8(out, len);

		/* XXX - er, browser fonts in text objects crash the player..
			 Maybe because there's no definefontinfo block? */

		if ( textRecord->isBrowserFont )
		{
			for ( i=0; i<len; ++i )
			{
				SWFOutput_writeBits(out, textRecord->string[i], nGlyphBits);
				SWFOutput_writeBits(out, textRecord->advance[i], text->nAdvanceBits);

				/* XXX - fudging the text character bounds since we don't
					 have font metrics */

				if ( CHARACTER(text)->bounds )
				{
					SWFRect_includePoint(CHARACTER(text)->bounds, curX, curY, 0);
					SWFRect_includePoint(CHARACTER(text)->bounds,
															 curX + curH, curY + curH, 0);
				}
				else
				{
					CHARACTER(text)->bounds =
						newSWFRect(curX, curX + curH, curY, curY + curH);
				}

				curX += curH;
			}
		}
		else
		{
			SWFFontCharacter fontchar = textRecord->font.fontchar;
			SWFFont font = SWFFontCharacter_getFont(fontchar);

			if ( font == NULL )
				SWF_error("Couldn't find font");

			for ( i=0; i<len; ++i )
			{
				SWFRect glyphBounds;
				int minX, maxX, minY, maxY;

				unsigned short code =
					SWFFontCharacter_getGlyphCode(fontchar, textRecord->string[i]);

				glyphBounds = SWFFont_getGlyphBounds(font, code);

				SWFRect_getBounds(glyphBounds, &minX, &maxX, &minY, &maxY);

				SWFOutput_writeBits(out, textRecord->string[i],	nGlyphBits);
				SWFOutput_writeBits(out, textRecord->advance[i], text->nAdvanceBits);

				if ( CHARACTER(text)->bounds )
				{
					SWFRect_includePoint(CHARACTER(text)->bounds,
															 curX + minX * curH / 1024,
															 curY + minY * curH / 1024, 0);

					SWFRect_includePoint(CHARACTER(text)->bounds,
															 curX + maxX * curH / 1024,
															 curY + maxY * curH / 1024, 0);
				}
				else
				{
					CHARACTER(text)->bounds =
						newSWFRect(curX + minX * curH /1024, curX + maxX * curH /1024,
											 curY + minY * curH /1024, curY + maxY * curH /1024);
				}

				if ( textRecord->advance != NULL )
					curX += textRecord->advance[i];
			}
		}

		textRecord = textRecord->next;
		destroySWFTextRecord(oldRecord);
	}

	SWFOutput_writeUInt8(out, 0); /* end text records */

	text->nGlyphBits = nGlyphBits;
	text->initialRecord = NULL;
	text->currentRecord = NULL;
}