Beispiel #1
0
/* 
 * Assigns a name to a SWFBlock object.
 * Creates an exportlibrary with named symbols to be imported by other 
 * SWF movies.
 * Call SWFMovie_writeExports() when you're done with the exports
 * to actually write the tag. If you don't the tag will be added
 * at the END of the SWF.
 * see also SWFMovie_importCharacter, SWFMovie_importFont
 */
void
SWFMovie_addExport(SWFMovie movie, SWFBlock block, const char *name)
{
	switch( SWFBlock_getType(block))
	{
		case SWF_DEFINESHAPE:
		case SWF_DEFINESHAPE2:
		case SWF_DEFINESHAPE3:
		case SWF_DEFINESHAPE4:
		case SWF_DEFINEBUTTON:
		case SWF_DEFINEBUTTON2:
		case SWF_DEFINESPRITE:
		case SWF_DEFINEFONT2:
		case SWF_DEFINESOUND:
		case SWF_DEFINELOSSLESS:
		case SWF_DEFINELOSSLESS2:
		case SWF_DEFINEBITS:
		case SWF_DEFINEBITSJPEG2:
		case SWF_DEFINEBITSJPEG3:
			movie->exports = (struct SWFExport_s*)realloc(movie->exports,
					(movie->nExports+1) * sizeof(struct SWFExport_s));
			movie->exports[movie->nExports].block = block;
			movie->exports[movie->nExports].name = strdup(name);
			++movie->nExports;
			break;
		default:
			SWF_error("Exporting a character of type %d is not supported", SWFBlock_getType(block));
			break;
	}
}
Beispiel #2
0
void
SWFText_addUTF8String(SWFText text, const char* string, int* advance)
{
	unsigned short* widestring;
	int len = UTF8ExpandString(string, &widestring);

	SWFTextRecord textRecord = text->currentRecord;

	/* marginally sloppy to tack on a new record,
		 but I don't want to deal with concats */

	if ( textRecord == NULL || textRecord->string != NULL )
		textRecord = SWFText_addTextRecord(text);

	/* If SWFText_addTextRecord() failed, return early */
	if (NULL == textRecord)
		return;

	if ( textRecord->font.font == NULL )
		SWF_error("font must be set before calling addString");

	textRecord->advance = advance;
	textRecord->strlen = len;
	textRecord->string = widestring;
}
Beispiel #3
0
/*
 * Creates a shape filled with bitmap
 */
SWFShape
newSWFShapeFromBitmap(SWFBitmap bitmap, int flag)
{
    SWFShape shape = newSWFShape();
    SWFFillStyle fill;
    int width, height;

    if ( flag != SWFFILL_TILED_BITMAP && flag != SWFFILL_CLIPPED_BITMAP)
    {
        SWF_error("Invalid bitmap fill flag");
    }

    fill = SWFShape_addBitmapFillStyle(shape, bitmap, flag);

    width = SWFBitmap_getWidth(bitmap);
    height = SWFBitmap_getHeight(bitmap);

    SWFShape_setRightFillStyle(shape, fill);

    // XXX - scale shouldn't be hardcoded! (here, or in newSWFBitmapFillStyle)
    SWFShape_drawScaledLine(shape, width * 20, 0);
    SWFShape_drawScaledLine(shape, 0, height * 20);
    SWFShape_drawScaledLine(shape, -width * 20, 0);
    SWFShape_drawScaledLine(shape, 0, -height * 20);

    return shape;
}
Beispiel #4
0
void
SWFText_addWideString(SWFText text, const unsigned short* widestring,
											int len, int* advance)
{
	SWFTextRecord textRecord = text->currentRecord;

	/* marginally sloppy to tack on a new record,
		 but I don't want to deal with concats */

	if ( textRecord == NULL || textRecord->string != NULL )
		textRecord = SWFText_addTextRecord(text);

	/* If SWFText_addTextRecord() failed, return early */
	if (NULL == textRecord)
		return;

	if ( textRecord->font.font == NULL )
		SWF_error("font must be set before calling addString");

	textRecord->advance = advance;
	textRecord->strlen = len;
	textRecord->string = (unsigned short*)malloc(sizeof(unsigned short) * len);

	/* If malloc failed, return early */
	if (NULL == textRecord->string)
	{
		destroySWFTextRecord(textRecord);
		return;
	}

	memcpy(textRecord->string, widestring, sizeof(unsigned short) * len);
}
Beispiel #5
0
/* note: replaces action, doesn't append.. */
void SWFButton_addAction(SWFButton button, SWFAction action, int flags)
{
	if ( SWFCharacter_isFinished((SWFCharacter)button) )
		SWF_error("Can't alter a button after it's been added to another character");

	if ( button->nActions % BUTTONRECORD_INCREMENT == 0 )
	{
		button->actions = (struct actionRecord*) realloc(button->actions,
						(button->nActions + BUTTONRECORD_INCREMENT) *
						sizeof(struct actionRecord));
	}

	button->actions[button->nActions].action = action;
	button->actions[button->nActions].flags = flags;
	++button->nActions;
}
Beispiel #6
0
void
SWFOutput_writeRect(SWFOutput out, SWFRect rect)
{
    int nBits = max(max(SWFOutput_numSBits(rect->minX),
                        SWFOutput_numSBits(rect->maxX)),
                    max(SWFOutput_numSBits(rect->minY),
                        SWFOutput_numSBits(rect->maxY)));

    if(nBits>=32)
        SWF_error("SWFRect too large for file format");

    SWFOutput_writeBits(out, nBits, 5);
    SWFOutput_writeSBits(out, rect->minX, nBits);
    SWFOutput_writeSBits(out, rect->maxX, nBits);
    SWFOutput_writeSBits(out, rect->minY, nBits);
    SWFOutput_writeSBits(out, rect->maxY, nBits);
}
Beispiel #7
0
static void
setPlaceObjectVersion(SWFPlaceObject2Block block, int version)
{
	switch(version)
	{
		case 2: 
			block->version = version;
			BLOCK(block)->type = SWF_PLACEOBJECT2;
			break;
		case 3:
			block->version = version;
			BLOCK(block)->type = SWF_PLACEOBJECT3;
			break;
		default:
			SWF_error("setPlaceObjectVersion: invalid version %i\n",
                                  version);
	}
}
Beispiel #8
0
/* adds a shape character 
 * Add a shape character to a button for given states
 * possible states:
 * SWFBUTTON_HIT  
 * SWFBUTTON_DOWN  
 * SWFBUTTON_OVER
 * SWFBUTTON_UP
 * states can be combined using the binary or operator    
 * deprecated! use SWFButton_addCharacter instead
 */
void SWFButton_addShape(SWFButton button, SWFCharacter character, byte flags)
{
	SWFMatrix m;
	SWF_warnOnce("SWFButton_addShape is deprecated\nUse SWFButton_addCharacter instead\n");
	if ( SWFCharacter_isFinished((SWFCharacter)button) )
		SWF_error("Can't alter a button after it's been added to another character");

	m = newSWFMatrix(1.0, 0, 0, 1.0, 0, 0);

	SWFCharacter_getDependencies((SWFCharacter)character,
									 &CHARACTER(button)->dependencies,
									 &CHARACTER(button)->nDependencies);

	SWFCharacter_addDependency((SWFCharacter)button, (SWFCharacter)character);

	SWFCharacter_setFinished(character);
	SWFButton_addRecord(button, newSWFButtonRecord(flags, character, 0, m));
}
Beispiel #9
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);
}
Beispiel #10
0
void 
SWFText_setFont(SWFText text, void* font)
{
	SWFTextRecord textRecord = text->currentRecord;

	if ( textRecord == NULL || textRecord->string != NULL )
		textRecord = SWFText_addTextRecord(text);

	textRecord->flags |= SWF_TEXT_HAS_FONT;

	/* XXX */
	textRecord->isBrowserFont = (BLOCK(font)->type == SWF_DEFINEEDITTEXT);

	if ( textRecord->isBrowserFont )
		SWF_error("cannot use browser font for SWFText");
//		textRecord->font.browserFont = (SWFBrowserFont)font;
	else
		textRecord->font.font = (SWFFont)font;
}
Beispiel #11
0
void
SWFShape_setRightFillStyle(SWFShape shape, SWFFillStyle fill)
{
	ShapeRecord record;

	if ( shape->isEnded || shape->isMorph )
		return;

	record = addStyleRecord(shape);

	if ( fill != NOFILL )
	{
		if ( SWFFill_getIdx(fill) > *shape->nFills )
			SWF_error("Invalid fill idx");

		record.record.stateChange->rightFill = SWFFill_getIdx(fill);
	}
	else
		record.record.stateChange->rightFill = 0;

	record.record.stateChange->flags |= SWF_SHAPE_FILLSTYLE1FLAG;
}
Beispiel #12
0
/* 
 * Assigns a name to a SWFBlock object.
 * Creates an exportlibrary with named symbols to be imported by other 
 * SWF movies.
 * Call SWFMovie_writeExports() when you're done with the exports
 * to actually write the tag. If you don't the tag will be added
 * at the END of the SWF.
 * see also SWFMovie_importCharacter, SWFMovie_importFont
 */
void
SWFMovie_addExport(SWFMovie movie, SWFBlock block, const char *name)
{
	switch( SWFBlock_getType(block))
	{
		case SWF_DEFINESHAPE:
		case SWF_DEFINESHAPE2:
		case SWF_DEFINESHAPE3:
			/*SWF_warn("Exporting a shape character is not ensured to work");*/
		case SWF_DEFINESPRITE:
		case SWF_DEFINEFONT2:
			movie->exports = (struct SWFExport_s*)realloc(movie->exports,
					(movie->nExports+1) * sizeof(struct SWFExport_s));
			movie->exports[movie->nExports].block = block;
			movie->exports[movie->nExports].name = strdup(name);
			++movie->nExports;
			break;
		default:
			SWF_error("Exporting a character of type %d is not supported", SWFBlock_getType(block));
			break;
	}
}
Beispiel #13
0
SWFDBLBitmapData newSWFDBLBitmapData_fromGifInput(SWFInput input)
{
    SWF_error("newSWFDBLBitmapData_fromGifInput can't be used (no gif compiled into this build of Ming).\n");
    return NULL;
}
Beispiel #14
0
SWFDBLBitmap
newSWFDBLBitmap_fromInput(SWFInput input)
{
	SWFDBLBitmap dbl;
	int version;
	int width, height;

	dbl = (SWFDBLBitmap)malloc(sizeof(struct SWFDBLBitmap_s));

	SWFCharacterInit((SWFCharacter)dbl);

	CHARACTERID(dbl) = ++SWF_gNumCharacters;

	BLOCK(dbl)->writeBlock = writeSWFDBLBitmapToMethod;
	BLOCK(dbl)->complete = completeSWFDBLBitmap;
	BLOCK(dbl)->dtor = (destroySWFBlockMethod) destroySWFCharacter;

	dbl->input = input;

	if ( SWFInput_getChar(input) != 'D' ||
			 SWFInput_getChar(input) != 'B' )
	{
		SWF_error("File is not a DBL file!");
	}

	version = SWFInput_getChar(input);

	if ( version != 'L' && version != 'l' )
		SWF_error("File is not a DBL file!");

	switch ( SWFInput_getChar(input) )
	{
		case 1:
			BLOCK(dbl)->type = SWF_DEFINELOSSLESS;
			break;
		case 2:
			BLOCK(dbl)->type = SWF_DEFINELOSSLESS2;
			break;
		default:
			SWF_error("Unexpected DBL type byte!");
	}

	if ( version == 'l' )
	{
		BLOCK(dbl)->length = SWFInput_getUInt32_BE(input);
		BLOCK(dbl)->length += 2; /* character id */
	}
	else
	{
		/* first version used a 2-byte file length..	brilliant, eh? */

		BLOCK(dbl)->length = SWFInput_getUInt16_BE(input);
		BLOCK(dbl)->length += 2; /* character id */
	}

	SWFInput_getChar(input); /* format */

	width = SWFInput_getUInt16(input);
	height = SWFInput_getUInt16(input);

	/* roll back to beginning of dbl data */
	SWFInput_seek(input, -5, SEEK_CUR);

	CHARACTER(dbl)->bounds = newSWFRect(0, width, 0, height);

	return dbl;
}
Beispiel #15
0
void
SWFShape_writeShapeRecord(SWFShape shape, ShapeRecord record, SWFOutput out)
{
    switch(record.type)
    {
    case SHAPERECORD_STATECHANGE:
    {
        int flags = record.record.stateChange->flags;

        if(flags == 0)
            return;

        SWFOutput_writeBits(out, flags, 6);

        if(flags & SWF_SHAPE_MOVETOFLAG)
        {
            int x = record.record.stateChange->moveToX;
            int y = record.record.stateChange->moveToY;
            int nBits = max(SWFOutput_numSBits(x), SWFOutput_numSBits(y));

            SWF_assert(nBits<32);
            SWFOutput_writeBits(out, nBits, 5);
            SWFOutput_writeSBits(out, x, nBits);
            SWFOutput_writeSBits(out, y, nBits);
        }

        if(flags & SWF_SHAPE_FILLSTYLE0FLAG)
        {
            SWFOutput_writeBits(out, record.record.stateChange->leftFill,
                                SWFOutput_numBits(shape->nFills));
        }

        if(flags & SWF_SHAPE_FILLSTYLE1FLAG)
        {
            SWFOutput_writeBits(out, record.record.stateChange->rightFill,
                                SWFOutput_numBits(shape->nFills));
        }

        if(flags & SWF_SHAPE_LINESTYLEFLAG)
        {
            SWFOutput_writeBits(out, record.record.stateChange->line,
                                SWFOutput_numBits(shape->nLines));
        }

        /* newstyle's never used.	 But this is what it looks like:

        if ( flags & SWF_SHAPE_NEWSTYLEFLAG )
        {
        	SWFOutput_writeFillStyles(shape->out, shape->fills, shape->nFills,
        	BLOCK(shape)->type);

        	SWFOutput_writeLineStyles(shape->out, shape->lines, shape->nLines,
        		BLOCK(shape)->type);

        	SWFOutput_writeBits(shape->out, SWFOutput_numBits(shape->nFills), 4);
        	SWFOutput_writeBits(shape->out, SWFOutput_numBits(shape->nLines), 4);
        }

        */

        break;
    }

    case SHAPERECORD_LINETO:
    {
        int nBits;
        int dx = record.record.lineTo->dx;
        int dy = record.record.lineTo->dy;

        SWFOutput_writeBits(out, 3, 2); /* straight edge */

        if(dx==0)
        {
            nBits = SWFOutput_numSBits(dy);
            SWF_assert(nBits<18);
            SWFOutput_writeBits(out, nBits-2, 4);
            SWFOutput_writeBits(out, 1, 2); /* vertical line */
            SWFOutput_writeSBits(out, dy, nBits);
        }
        else if(dy==0)
        {
            nBits = SWFOutput_numSBits(dx);
            SWF_assert(nBits<18);
            SWFOutput_writeBits(out, nBits-2, 4);
            SWFOutput_writeBits(out, 0, 2); /* horizontal line */
            SWFOutput_writeSBits(out, dx, nBits);
        }
        else
        {
            nBits = max(SWFOutput_numSBits(dx), SWFOutput_numSBits(dy));
            SWF_assert(nBits<18);
            SWFOutput_writeBits(out, nBits-2, 4);
            SWFOutput_writeBits(out, 1, 1); /* general line */
            SWFOutput_writeSBits(out, dx, nBits);
            SWFOutput_writeSBits(out, dy, nBits);
        }

        break;
    }

    case SHAPERECORD_CURVETO:
    {
        int controlx = record.record.curveTo->controlx;
        int controly = record.record.curveTo->controly;
        int anchorx = record.record.curveTo->anchorx;
        int anchory = record.record.curveTo->anchory;

        int nBits = max(max(SWFOutput_numSBits(controlx),
                            SWFOutput_numSBits(controly)),
                        max(SWFOutput_numSBits(anchorx),
                            SWFOutput_numSBits(anchory)));

        if ( nBits < 2 )
            nBits = 2;

        SWF_assert(nBits < 18);

        SWFOutput_writeBits(out, 2, 2); /* curved edge */
        SWFOutput_writeBits(out, nBits-2, 4);
        SWFOutput_writeSBits(out, controlx, nBits);
        SWFOutput_writeSBits(out, controly, nBits);
        SWFOutput_writeSBits(out, anchorx, nBits);
        SWFOutput_writeSBits(out, anchory, nBits);

        break;
    }

    default:
        SWF_error("Unknown shapeRecordType");
    }
}
Beispiel #16
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;
}
Beispiel #17
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);
}
Beispiel #18
0
void
SWFShape_writeShapeRecord(SWFShape shape, ShapeRecord record)
{
	SWFOutput out = shape->out;

	switch(record.type)
	{
		case SHAPERECORD_STATECHANGE:
		{
			int flags = record.record.stateChange->flags;

			if(flags == 0)
				return;

			SWFOutput_writeBits(out, flags, 6);

			if(flags & SWF_SHAPE_MOVETOFLAG)
			{
				int x = record.record.stateChange->moveToX;
				int y = record.record.stateChange->moveToY;
				int nBits = max(SWFOutput_numSBits(x), SWFOutput_numSBits(y));

				SWF_assert(nBits<32);
				SWFOutput_writeBits(out, nBits, 5);
				SWFOutput_writeSBits(out, x, nBits);
				SWFOutput_writeSBits(out, y, nBits);
			}

			if(flags & SWF_SHAPE_FILLSTYLE0FLAG)
			{
				SWFOutput_writeBits(out, record.record.stateChange->leftFill,
														SWFOutput_numBits(shape->nFills2));
			}

			if(flags & SWF_SHAPE_FILLSTYLE1FLAG)
			{
				SWFOutput_writeBits(out, record.record.stateChange->rightFill,
														SWFOutput_numBits(shape->nFills2));
			}

			if(flags & SWF_SHAPE_LINESTYLEFLAG)
			{
				SWFOutput_writeBits(out, record.record.stateChange->line,
														SWFOutput_numBits(shape->nLines2));
			}

			/* newstyle's never used.	 But this is what it looks like: */

			if ( flags & SWF_SHAPE_NEWSTYLEFLAG )
			{
				int i;

				shape->lines = &record.record.stateChange->lines;
				shape->fills = &record.record.stateChange->fills;
				shape->nLines = &record.record.stateChange->nLines;
				shape->nFills = &record.record.stateChange->nFills;
				shape->nFills2 = *shape->nFills;
				shape->nLines2 = *shape->nLines;

				SWFOutput_writeFillStyles(shape->out, *shape->fills, *shape->nFills,
				BLOCK(shape)->type);

				SWFOutput_writeLineStyles(shape->out, *shape->lines, *shape->nLines,
					BLOCK(shape)->type);

				SWFOutput_writeBits(shape->out, SWFOutput_numBits(*shape->nFills), 4);
				SWFOutput_writeBits(shape->out, SWFOutput_numBits(*shape->nLines), 4);

				for ( i=0; i<*shape->nFills; ++i )
				{
					SWFMatrix matrix = SWFFillStyle_getMatrix((*shape->fills)[i]);

					if ( matrix != NULL )
						destroySWFMatrix(matrix);

					/* gradients and bitmaps are destroyed separately */

					free((*shape->fills)[i]);
				}

				if ( *shape->fills != NULL )
					free(*shape->fills);

				for ( i=0; i<*shape->nLines; ++i )
					free((*shape->lines)[i]);

				if ( *shape->lines != NULL )
					free(*shape->lines);
			}

			break;
		}

		case SHAPERECORD_LINETO:
		{
			int nBits;
			int dx = record.record.lineTo->dx;
			int dy = record.record.lineTo->dy;

			SWFOutput_writeBits(out, 3, 2); /* straight edge */

			if(dx==0 && dy!=0)
			{
				nBits = SWFOutput_numSBits(dy);
				SWF_assert(nBits<18);
				SWFOutput_writeBits(out, nBits-2, 4);
				SWFOutput_writeBits(out, 1, 2); /* vertical line */
				SWFOutput_writeSBits(out, dy, nBits);
			}
			else if(dy==0 && dx!=0)
			{
				nBits = SWFOutput_numSBits(dx);
				SWF_assert(nBits<18);
				SWFOutput_writeBits(out, nBits-2, 4);
				SWFOutput_writeBits(out, 0, 2); /* horizontal line */
				SWFOutput_writeSBits(out, dx, nBits);
			}
			else
			{
				nBits = max(SWFOutput_numSBits(dx), SWFOutput_numSBits(dy));
				nBits = max(nBits, 2);
				SWF_assert(nBits<18);
				SWFOutput_writeBits(out, nBits-2, 4);
				SWFOutput_writeBits(out, 1, 1); /* general line */
				SWFOutput_writeSBits(out, dx, nBits);
				SWFOutput_writeSBits(out, dy, nBits);
			}

			break;
		}

		case SHAPERECORD_CURVETO:
		{
			int controlx = record.record.curveTo->controlx;
			int controly = record.record.curveTo->controly;
			int anchorx = record.record.curveTo->anchorx;
			int anchory = record.record.curveTo->anchory;

			int nBits = max(max(SWFOutput_numSBits(controlx),
													SWFOutput_numSBits(controly)),
											max(SWFOutput_numSBits(anchorx),
													SWFOutput_numSBits(anchory)));

			if ( nBits < 2 )
				nBits = 2;

			SWF_assert(nBits < 18);

			SWFOutput_writeBits(out, 2, 2); /* curved edge */
			SWFOutput_writeBits(out, nBits-2, 4);
			SWFOutput_writeSBits(out, controlx, nBits);
			SWFOutput_writeSBits(out, controly, nBits);
			SWFOutput_writeSBits(out, anchorx, nBits);
			SWFOutput_writeSBits(out, anchory, nBits);

			break;
		}

		default:
			SWF_error("Unknown shapeRecordType");
	}
}
Beispiel #19
0
SWFDBLBitmapData newSWFDBLBitmapData_fromGifFile(const char * fileName)
{
    SWF_error("newSWFDBLBitmapData_fromGifFile can't be used (no gif compiled into this build of Ming).\n");
    return NULL;
}
Beispiel #20
0
SWFOutput
SWFMovie_toOutput(SWFMovie movie, int level)
{
	int swflength;
#if USE_ZLIB
	int status;
#endif
	SWFOutput header, tempbuffer=0, buffer, swfbuffer;
	SWFBlock lastBlock;
	unsigned long compresslength;

	if ( movie->nExports > 0 )
		SWFMovie_writeExports(movie);

	if ( movie->metadata != NULL)
	{
		SWFMovie_addBlock(movie, (SWFBlock)movie->metadata);
		movie->metadata = NULL; // do not destroy with movie if added as block
	}

	/* Add a terminating SHOWFRAME tag if not already there */
	lastBlock = SWFBlockList_getLastBlock(movie->blockList);
	if ( ! lastBlock || SWFBlock_getType(lastBlock) != SWF_SHOWFRAME )
	{
		SWFMovie_nextFrame(movie);
	}

	while ( movie->nFrames < movie->totalFrames )
		SWFMovie_nextFrame(movie);

	if(movie->symbolClass)
		SWFMovie_addBlock(movie, (SWFBlock)movie->symbolClass);

	if(movie->sceneData)
		SWFMovie_addBlock(movie, (SWFBlock)movie->sceneData);

	SWFMovie_addBlock(movie, newSWFEndBlock());

	// add five for the setbackground block..
	swflength = SWFBlockList_completeBlocks(movie->blockList, movie->version);

	/* XXX - hack */
	SWFDisplayList_rewindSoundStream(movie->displayList);

	header = newSizedSWFOutput(23);

	SWFOutput_writeRect(header, movie->bounds);
	SWFOutput_writeUInt16(header, (int)floor(movie->rate*256));
	SWFOutput_writeUInt16(header, movie->nFrames);

	/* SWF >= 8: first block _must_ be SWF_FILEATTRIBUTES */ 
	if(movie->fattrs)
		writeSWFBlockToMethod((SWFBlock)movie->fattrs, SWFOutputMethod, header);

	if(movie->backgroundBlock)
		writeSWFBlockToMethod(movie->backgroundBlock, SWFOutputMethod, header);
	
	if(movie->limits)
		writeSWFBlockToMethod((SWFBlock)movie->limits, SWFOutputMethod, header);	
	SWFOutput_byteAlign(header);
	swflength += 8 + SWFOutput_getLength(header);

	// compression level check
#if USE_ZLIB
	if (level < -1) level = -1;
	if (level >  9) level = 9;
#else
	if ( level != -1 )
	{
		SWF_warn("No zlib support compiled in, "
			"cannot generate compressed output");
		level = -1; 
	}
#endif

	// reserve output buffer
	if(level >= 0)
	{	// a little bit more than the uncompressed data
		compresslength = swflength + (swflength/1000) + 15 + 1;
		swfbuffer    = newSizedSWFOutput( compresslength + 8 );
	}
	else
		swfbuffer    = newSizedSWFOutput( swflength );

	if (level >= 0) SWFOutput_writeUInt8 (swfbuffer, 'C');
	else SWFOutput_writeUInt8 (swfbuffer, 'F');
	SWFOutput_writeUInt8 (swfbuffer, 'W');
	SWFOutput_writeUInt8 (swfbuffer, 'S');

	SWFOutput_writeUInt8 (swfbuffer, movie->version);

	// Movie length
	SWFOutput_writeUInt32(swfbuffer, swflength);

	if(level >= 0)
		buffer = tempbuffer = newSizedSWFOutput( swflength - 8);
	else
		buffer = swfbuffer;

	SWFOutput_writeToMethod(header, SWFOutputMethod, buffer);

	destroySWFOutput(header);

	// fill swfbuffer with blocklist
	SWFBlockList_writeBlocksToMethod(movie->blockList, SWFOutputMethod, buffer);

#if USE_ZLIB
	if (level >= 0)
	{
		status = compress2 ( (Bytef*) SWFOutput_getBuffer(swfbuffer)+8, &compresslength, SWFOutput_getBuffer(tempbuffer), SWFOutput_getLength(tempbuffer), level);
		if (status == Z_OK) {
			SWFOutput_truncate(swfbuffer, compresslength+8);
			destroySWFOutput(tempbuffer);
		} else SWF_error("compression failed");
	}
#endif // ndef USE_ZLIB
	return swfbuffer;
}
Beispiel #21
0
void
SWFOutput_writeCXform(SWFOutput out, SWFCXform cXform, SWFBlocktype type)
{
	int nBits = 0;
	int hasAdd, hasMult;

	SWFOutput_byteAlign(out);

	hasAdd = ( cXform->rAdd != 0 || cXform->gAdd != 0 ||
						 cXform->bAdd != 0 || cXform->aAdd != 0 );

	hasMult = ( cXform->rMult != 256 || cXform->gMult != 256 ||
							cXform->bMult != 256 || cXform->aMult != 256 );

	SWFOutput_writeBits(out, hasAdd ? 1 : 0, 1);
	SWFOutput_writeBits(out, hasMult ? 1 : 0, 1);

	if ( hasAdd )
	{
		nBits = max(nBits, SWFOutput_numSBits(cXform->rAdd));
		nBits = max(nBits, SWFOutput_numSBits(cXform->gAdd));
		nBits = max(nBits, SWFOutput_numSBits(cXform->bAdd));

		if ( type == SWF_PLACEOBJECT2 )
			nBits = max(nBits, SWFOutput_numSBits(cXform->aAdd));
	}

	if ( hasMult )
	{
		nBits = max(nBits, SWFOutput_numSBits(cXform->rMult));
		nBits = max(nBits, SWFOutput_numSBits(cXform->gMult));
		nBits = max(nBits, SWFOutput_numSBits(cXform->bMult));

		if ( type == SWF_PLACEOBJECT2 )
			nBits = max(nBits, SWFOutput_numSBits(cXform->aMult));
	}

	if ( nBits>=16 )
		SWF_error("color transform data out of scale");

	SWFOutput_writeBits(out, nBits, 4);

	if ( hasMult )
	{
		SWFOutput_writeSBits(out, cXform->rMult, nBits);
		SWFOutput_writeSBits(out, cXform->gMult, nBits);
		SWFOutput_writeSBits(out, cXform->bMult, nBits);

		if ( type == SWF_PLACEOBJECT2 )
			SWFOutput_writeSBits(out, cXform->aMult, nBits);
	}

	if ( hasAdd )
	{
		SWFOutput_writeSBits(out, cXform->rAdd, nBits);
		SWFOutput_writeSBits(out, cXform->gAdd, nBits);
		SWFOutput_writeSBits(out, cXform->bAdd, nBits);

		if ( type == SWF_PLACEOBJECT2 )
			SWFOutput_writeSBits(out, cXform->aAdd, nBits);
	}
}
Beispiel #22
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;
}
Beispiel #23
0
void
SWFOutput_writeMatrix(SWFOutput out, SWFMatrix matrix)
{
	int nBits;

	SWFOutput_byteAlign(out);

	if ( (matrix->scaleX == 0 && matrix->scaleY == 0) ||
			 (matrix->scaleX == 1.0 && matrix->scaleY == 1.0) )
	{
		SWFOutput_writeBits(out, 0, 1);	 
	}
	else
	{
		int xScale = (int)floor(matrix->scaleX * (1<<FIXEDBITS));
		int yScale = (int)floor(matrix->scaleY * (1<<FIXEDBITS));

		SWFOutput_writeBits(out, 1, 1);
		nBits = max(SWFOutput_numSBits(xScale), SWFOutput_numSBits(yScale));
		if(nBits >= 32)
			SWF_error("SWFMatrix_scale: number is to big. "
				  " Requested %i bits\n", nBits);
		
		SWFOutput_writeBits(out, nBits, 5);
		SWFOutput_writeSBits(out, xScale, nBits);
		SWFOutput_writeSBits(out, yScale, nBits);
	}

	if ( matrix->rotate0 == 0 && matrix->rotate1 == 0 )
	{
		SWFOutput_writeBits(out, 0, 1);
	}
	else
	{
		int rot0 = (int)floor(matrix->rotate0 * (1<<FIXEDBITS));
		int rot1 = (int)floor(matrix->rotate1 * (1<<FIXEDBITS));

		SWFOutput_writeBits(out, 1, 1);
		nBits = max(SWFOutput_numSBits(rot0), SWFOutput_numSBits(rot1));
		if(nBits >= 32)
			SWF_error("SWFMatrix_rotate: number is to big. "
				  " Requested %i bits\n", nBits);

		SWFOutput_writeBits(out, nBits, 5);
		SWFOutput_writeSBits(out, rot0, nBits);
		SWFOutput_writeSBits(out, rot1, nBits);
	}

	if ( matrix->translateX != 0 || matrix->translateY != 0 )
	{
		nBits = max(SWFOutput_numSBits(matrix->translateX),
		SWFOutput_numSBits(matrix->translateY));

		if(nBits >= 32)
			SWF_error("SWFMatrix_translate: number is to big. "
				  " Requested %i bits\n", nBits);
	}
	else
		nBits = 0;

	SWFOutput_writeBits(out, nBits, 5);
	SWFOutput_writeSBits(out, matrix->translateX, nBits);
	SWFOutput_writeSBits(out, matrix->translateY, nBits);
}