Пример #1
0
static void
writeSWFTextToMethod(SWFBlock block, SWFByteOutputMethod method, void *data)
{
	SWFText text = (SWFText)block;
	int length = 0;
	SWFOutput out;

	if ( text->matrix == NULL )
		text->matrix = newSWFMatrix(1.0, 0, 0, 1.0, 0, 0);

	length += (SWFMatrix_numBits(text->matrix)+7)/8;
	length += (SWFRect_numBits(CHARACTER(text)->bounds)+7)/8;
	length += 4;

	out = newSizedSWFOutput(length);

	SWFOutput_writeUInt16(out, CHARACTERID(text));
	SWFOutput_writeRect(out, CHARACTER(text)->bounds);
	SWFOutput_writeMatrix(out, text->matrix);
	SWFOutput_writeUInt8(out, text->nGlyphBits);
	SWFOutput_writeUInt8(out, text->nAdvanceBits);

	SWFOutput_writeToMethod(out, method, data);
	SWFOutput_writeToMethod(text->out, method, data);

	destroySWFOutput(out);
}
Пример #2
0
SWFBlock
SWFSoundStream_getStreamHead(SWFSoundStream stream, float frameRate, float skip)
{
	int flags = 0;

	SWFOutput out = newSizedSWFOutput(4);
	SWFOutputBlock block = newSWFOutputBlock(out, SWF_SOUNDSTREAMHEAD2);
	
	if(stream->streamSource == STREAM_MP3)
		flags = getStreamFlag_mp3File(stream, frameRate, skip);
	else if(stream->streamSource == STREAM_FLV)
		flags = getStreamFlag_flv(stream, frameRate, skip);
	
	stream->flags = flags;	
	stream->frameRate = frameRate;	
	if(flags < 0)
	{
		destroySWFOutputBlock(block);
		return NULL;
	}

	SWFOutput_writeUInt8(out, flags & 0x0f); 
	SWFOutput_writeUInt8(out, flags);
	SWFOutput_writeUInt16(out, stream->samplesPerFrame);
	if(((flags & 0xf0) >> 4) == 2)	/* MP3 only */
	{
		SWFOutput_writeUInt16(out, stream->initialDelay);
		stream->delay = stream->initialDelay;
	}
	
	return (SWFBlock)block;
}
Пример #3
0
void
outputTrailer (struct Movie *m)
{
SWFOutput out;

out=newSizedSWFOutput(30);
SWFOutput_writeUInt8(out,'F');
SWFOutput_writeUInt8(out,'W');
SWFOutput_writeUInt8(out,'S');
SWFOutput_writeUInt8(out,4);
SWFOutput_writeUInt32(out,SWFOutput_getLength(swfout)+23 /*size of header*/);
SWFOutput_writeBits(out,15,5);
SWFOutput_writeSBits(out,m->frame.xMin,15);
SWFOutput_writeSBits(out,m->frame.xMax,15);
SWFOutput_writeSBits(out,m->frame.yMin,15);
SWFOutput_writeSBits(out,m->frame.yMax,15);
SWFOutput_byteAlign(out);
SWFOutput_writeUInt16(out,m->rate);
SWFOutput_writeUInt16(out,m->nFrames);

/* Add the SWF_END tag */
SWFOutput_writeUInt16(swfout,0);

SWFOutput_writeToMethod(out,fileOutputMethod,stdout);
SWFOutput_writeToMethod(swfout,fileOutputMethod,stdout);
destroySWFOutput(swfout);
destroySWFOutput(out);
}
Пример #4
0
static void
finishBrowserFont(SWFBrowserFont font)
{
	unsigned int i;
	SWFOutput out;
	SWF_assert(BLOCK(font)->swfVersion);

	out = newSWFOutput();
	font->out = out;

	SWFOutput_writeUInt16(out, CHARACTERID(font));
	if(BLOCK(font)->swfVersion > 5)	/* maybe italic or bold flag? */
		SWFOutput_writeUInt8(out, SWF_FONT_WIDECODES);
	else
	 	SWFOutput_writeUInt8(out, 0);

	SWFOutput_writeUInt8(out, 0); /* reserved flags */
	SWFOutput_writeUInt8(out, strlen(font->name));

	for ( i=0; i<strlen(font->name); ++i )
		SWFOutput_writeUInt8(out, font->name[i]);

	SWFOutput_writeUInt16(out, 0); /* number of glyphs */
	SWFOutput_writeSInt16(out, 2); /* offset */

	SWFOutput_byteAlign(out);
}
Пример #5
0
int
completeSWFTextField(SWFBlock block)
{
	SWFTextField field = (SWFTextField)block;

	/* we're guessing how big the block's going to be.. */
	SWFOutput out =
		newSizedSWFOutput(42 
			+ ((field->varName)?strlen(field->varName):0) 
			+ ((field->string)?strlen(field->string):0));

	field->out = out;

	resetBounds(field);

	SWFOutput_writeUInt16(out, CHARACTERID(field));
	SWFOutput_writeRect(out, CHARACTER(field)->bounds);
	SWFOutput_writeUInt16(out, field->flags);

	if(field->flags & SWFTEXTFIELD_HASFONT)
	{
		SWFOutput_writeUInt16(out, CHARACTERID(field->font.fontchar));
		SWFOutput_writeUInt16(out, field->fontHeight);
	}

	if(field->flags & SWFTEXTFIELD_HASCOLOR)
	{
		SWFOutput_writeUInt8(out, field->r);
		SWFOutput_writeUInt8(out, field->g);
		SWFOutput_writeUInt8(out, field->b);
		SWFOutput_writeUInt8(out, field->a);
	}

	if ( field->flags & SWFTEXTFIELD_HASLENGTH )
		SWFOutput_writeUInt16(out, field->length);

	if(field->flags & SWFTEXTFIELD_HASLAYOUT)
	{
		SWFOutput_writeUInt8(out, field->alignment);
		SWFOutput_writeUInt16(out, field->leftMargin);
		SWFOutput_writeUInt16(out, field->rightMargin);
		SWFOutput_writeUInt16(out, field->indentation);
		SWFOutput_writeUInt16(out, field->lineSpacing);
	}

	SWFOutput_writeString(out, (byte*) field->varName);
	if ( field->flags & SWFTEXTFIELD_HASTEXT )
		SWFOutput_writeString(out, (byte*)field->string);

	/*
		XXX - if font is a real font, do we need to talk to it?
		flash 4 just makes a browser font for (editable) textfields for all fonts
	*/

	SWFOutput_byteAlign(out);
	return SWFOutput_getLength(out);
}
Пример #6
0
int
completeSWFPlaceObject2Block(SWFBlock block)
{
	SWFPlaceObject2Block place = (SWFPlaceObject2Block)block;
	SWFOutput out = newSizedSWFOutput(42);

	int flags =
		((place->name != NULL)			? SWF_PLACE_HAS_NAME : 0) |
		((place->ratio != -1)				? SWF_PLACE_HAS_RATIO : 0) |
		((place->masklevel != -1)		? SWF_PLACE_HAS_MASK : 0) |
		((place->cXform != NULL)		? SWF_PLACE_HAS_CXFORM : 0) |
		((place->matrix != NULL)		? SWF_PLACE_HAS_MATRIX : 0) |
		((place->character != NULL) ? SWF_PLACE_HAS_CHARACTER : 0) |
		((place->move != 0)					? SWF_PLACE_MOVE : 0) |
		((place->nActions != 0)			? SWF_PLACE_HAS_ACTIONS : 0);

	SWFOutput_writeUInt8(out, flags);
	if(place->version == 3)
	{
		flags = 0;
		if(place->hasCacheFlag) flags |= SWF_PLACE_CACHE;
		if(place->hasBlendFlag) flags |= SWF_PLACE_HAS_BLEND;
		if(place->hasFilterFlag) flags |= SWF_PLACE_HAS_FILTER;
		SWFOutput_writeUInt8(out, flags);
	}
	SWFOutput_writeUInt16(out, place->depth);
	
	if ( place->character != NULL )
		SWFOutput_writeUInt16(out, CHARACTERID(place->character));

	if ( place->matrix != NULL )
		SWFOutput_writeMatrix(out, place->matrix);

	if ( place->cXform != NULL )
		SWFOutput_writeCXform(out, place->cXform, SWF_PLACEOBJECT2);

	if ( place->ratio != -1 )
		SWFOutput_writeUInt16(out, place->ratio);

	if ( place->name != NULL )
		SWFOutput_writeString(out, (byte*)place->name);

	if ( place->masklevel != -1 )
		SWFOutput_writeUInt16(out, place->masklevel);

	if( place->version == 3 && place->hasFilterFlag)
		SWFOutput_writeFilterList(out, place->filterList);		

	if( place->version == 3 && place->hasBlendFlag)
		SWFOutput_writeUInt8(out, place->blendMode);

	place->out = out;
	writeActions(place);

	return SWFOutput_getLength(out);
}
Пример #7
0
void
SWFOutput_writeGlyphShape(SWFOutput out, SWFShape shape)
{
    unsigned char c;
    int styleDone = 0;
    int i;

    c = 1<<4;
    SWFOutput_writeUInt8(out, c);
    shape->nFills = 1;
    shape->nLines = 0;
    for ( i=0; i<shape->nRecords; ++i )
    {
        if(!styleDone && shape->records[i].type == SHAPERECORD_STATECHANGE)
        {
            shape->records[i].record.stateChange->flags |= SWF_SHAPE_FILLSTYLE0FLAG;
            shape->records[i].record.stateChange->leftFill = 1;
            styleDone = 1;
        }

        if ( i < shape->nRecords-1 ||
                shape->records[i].type != SHAPERECORD_STATECHANGE )
        {
            SWFShape_writeShapeRecord(shape, shape->records[i], out);
        }
    }

    SWFOutput_writeBits(out, 0, 6); /* end tag */
    SWFOutput_byteAlign(out);
}
Пример #8
0
void
SWFOutput_writeGradient(SWFOutput out, SWFGradient gradient, SWFBlocktype shapeType)
{
	int i;
	int nGrads = gradient->nGrads;

	if(shapeType == SWF_DEFINESHAPE4)
	{
		byte flags ;
		nGrads = min(nGrads, 15);
		flags = nGrads;
		flags |= (0x3 & gradient->interpolationMode) << 4;
		flags |= (0x3 & gradient->spreadMode) << 6;
		SWFOutput_writeUInt8(out, flags); /* only 1-15 allowed */
	}
	else 
	{
		nGrads = min(nGrads, 8);
		SWFOutput_writeUInt8(out, nGrads); /* only 1-8 allowed */
	}

	for ( i=0; i<nGrads; ++i )
	{
		SWFOutput_writeUInt8(out, gradient->entries[i].ratio);
		SWFOutput_writeUInt8(out, gradient->entries[i].r);
		SWFOutput_writeUInt8(out, gradient->entries[i].g);
		SWFOutput_writeUInt8(out, gradient->entries[i].b);

		if ( shapeType >= SWF_DEFINESHAPE3 )
			SWFOutput_writeUInt8(out, gradient->entries[i].a);
	}

	if(shapeType == SWF_DEFINESHAPE4 && gradient->isFocalGradient)
		SWFOutput_writeFixed8(out, gradient->focalPoint);
}
Пример #9
0
int completeSWFButton(SWFBlock block)
{
	SWFButton button = (SWFButton)block;
	SWFButtonRecord record;
	SWFOutput out = newSWFOutput();
	int i, length = 0, layer;
	byte *offset;

	SWFOutput_writeUInt16(out, CHARACTERID(button));
	SWFOutput_writeUInt8(out, button->menuflag);

	/* fill in offset later */
	offset = SWFOutput_getCurPos(out);
	SWFOutput_writeUInt16(out, 0);

	for(i=0; i<button->nRecords; ++i)
	{
		record = button->records[i];
		SWFOutput_writeUInt8(out, record->flags);
		SWFOutput_writeUInt16(out, CHARACTERID(record->character));
		layer = record->layer;
		if(layer == 0 && block->swfVersion >= 5) layer = i+1;
		SWFOutput_writeUInt16(out, layer);
		SWFOutput_writeMatrix(out, SWFPosition_getMatrix(record->position));
		SWFOutput_writeUInt8(out, 0); /* blank CXForm */
		if(record->flags & RECORD_HASFILTER)
			SWFOutput_writeFilterList(out, record->filterList);
		if(record->flags & RECORD_HASBLEND)
			SWFOutput_writeUInt8(out, record->blendMode);
	}

	SWFOutput_writeUInt8(out, 0); /* end buttons */

	length = SWFOutput_getLength(out) - 3;

	if(button->nActions > 0)
	{
		*offset = length&0xff;
		*(offset+1) = (length>>8)&0xff;
	}
Пример #10
0
void SWFOutput_writeLineStyles(SWFOutput out,
						 SWFLineStyle *lines, int nLines,
						 SWFBlocktype shapeType)
{
	SWFLineStyle line;
	int i;

	if(nLines<255)
		SWFOutput_writeUInt8(out, nLines);
	else
	{
		SWFOutput_writeUInt8(out, 255);
		SWFOutput_writeUInt16(out, nLines);
	}

	for(i=0; i<nLines; ++i)
	{
		line = lines[i];

		SWFOutput_writeUInt16(out, line->width);
		SWFOutput_writeUInt8(out, line->r);
		SWFOutput_writeUInt8(out, line->g);
		SWFOutput_writeUInt8(out, line->b);

		if(shapeType==SWF_DEFINESHAPE3)
			SWFOutput_writeUInt8(out, line->a);

		++line;
	}
}
Пример #11
0
void 
SWFOutput_writeGradientAsFilter(SWFOutput out, SWFGradient gradient)
{
	int i;
	int nGrads = gradient->nGrads;
	
	if(nGrads > 8)
	{
		SWF_warn("Can't write more than 8 control points for filter gradients\n");
		nGrads = 8;
	}	
	
	SWFOutput_writeUInt8(out, nGrads); /* only 1-8 allowed */

	for ( i=0; i<nGrads; ++i )
	{
		SWFOutput_writeUInt8(out, gradient->entries[i].r);
		SWFOutput_writeUInt8(out, gradient->entries[i].g);
		SWFOutput_writeUInt8(out, gradient->entries[i].b);
		SWFOutput_writeUInt8(out, gradient->entries[i].a);
	}

	for ( i=0; i<nGrads; ++i )
		SWFOutput_writeUInt8(out, gradient->entries[i].ratio);

}
Пример #12
0
void SWFOutput_writeMorphLineStyles(SWFOutput out,
						SWFLineStyle *lines1, int nLines1,
						SWFLineStyle *lines2, int nLines2)
{
	SWFLineStyle line1, line2;
	int i;

	SWF_assert(nLines1 == nLines2);

	if(nLines1<255)
		SWFOutput_writeUInt8(out, nLines1);
	else
	{
		SWFOutput_writeUInt8(out, 255);
		SWFOutput_writeUInt16(out, nLines1);
	}

	for(i=0; i<nLines1; ++i)
	{
		line1 = lines1[i];
		line2 = lines2[i];

		SWFOutput_writeUInt16(out, line1->width);
		SWFOutput_writeUInt16(out, line2->width);
		SWFOutput_writeUInt8(out, line1->r);
		SWFOutput_writeUInt8(out, line1->g);
		SWFOutput_writeUInt8(out, line1->b);
		SWFOutput_writeUInt8(out, line1->a);
		SWFOutput_writeUInt8(out, line2->r);
		SWFOutput_writeUInt8(out, line2->g);
		SWFOutput_writeUInt8(out, line2->b);
		SWFOutput_writeUInt8(out, line2->a);

		++line1;
		++line2;
	}
}
Пример #13
0
SWFShape
newSWFShape()
{
    SWFShape shape = (SWFShape)malloc(sizeof(struct SWFShape_s));

    /* If malloc failed, return NULL to signify this */
    if (NULL == shape)
        return NULL;

    SWFCharacterInit((SWFCharacter)shape);

    BLOCK(shape)->writeBlock = writeSWFShapeBlockToMethod;
    BLOCK(shape)->complete = completeSWFShapeBlock;
    BLOCK(shape)->dtor = (destroySWFBlockMethod) destroySWFShape;
    BLOCK(shape)->type = SWF_DEFINESHAPE3;

    CHARACTERID(shape) = ++SWF_gNumCharacters;

    shape->out = newSWFOutput();
    CHARACTER(shape)->bounds = newSWFRect(0,0,0,0);
    shape->edgeBounds = newSWFRect(0,0,0,0);

    shape->records = NULL;
    shape->lines = NULL;
    shape->fills = NULL;

    shape->nRecords = 0;
    shape->xpos = 0;
    shape->ypos = 0;
    shape->nLines = 0;
    shape->nFills = 0;
    shape->lineWidth = 0;
    shape->isMorph = FALSE;
    shape->isEnded = FALSE;
    shape->flags = 0;
    shape->useVersion = SWF_SHAPE3;

    SWFOutput_writeUInt8(shape->out, 0); /* space for nFillBits, nLineBits */

#if TRACK_ALLOCS
    shape->gcnode = ming_gc_add_node(shape, (dtorfunctype) destroySWFShape);
#endif

    return shape;
}
Пример #14
0
void
SWFShape_addStyleHeader(SWFShape shape)
{
    SWFOutput out = newSWFOutput();
    SWFOutput_writeUInt16(out, CHARACTERID(shape));
    SWFOutput_writeRect(out, SWFCharacter_getBounds(CHARACTER(shape)));
    if(shape->useVersion == SWF_SHAPE4)
    {
        SWFOutput_writeRect(out, shape->edgeBounds);
        SWFOutput_writeUInt8(out, shape->flags);
    }

    SWFOutput_writeFillStyles(out, shape->fills, shape->nFills,
                              BLOCK(shape)->type, shape->edgeBounds);
    SWFOutput_writeLineStyles(out, shape->lines, shape->nLines, BLOCK(shape)->type);

    /* prepend shape->out w/ shape header */
    SWFOutput_setNext(out, shape->out);
    shape->out = out;
}
Пример #15
0
static void writeActions(SWFPlaceObject2Block place)
{
	int i;
	SWFBlock block = BLOCK(place);
	
	if ( place->nActions > 0 )
	{
		SWFOutput_writeUInt16(place->out, 0); 
		
		if(block->swfVersion >= 6)
			SWFOutput_writeUInt32(place->out, place->actionORFlags);
		else
			SWFOutput_writeUInt16(place->out, place->actionORFlags);

		for ( i=0; i<place->nActions; ++i )
		{
			int length;
			SWFAction_compile(place->actions[i], block->swfVersion, &length);
			if(block->swfVersion >= 6)
				SWFOutput_writeUInt32(place->out, place->actionFlags[i]);
			else
				SWFOutput_writeUInt16(place->out, place->actionFlags[i]);
			
			/* SWF6: extra char if(place->actionFlags[i] & 0x20000) */
			if((block->swfVersion >= 6) && (place->actionFlags[i] & 0x20000)) {
				SWFOutput_writeUInt32(place->out, length + 1);
				SWFOutput_writeUInt8(place->out, 0);
			} 
			else 
				SWFOutput_writeUInt32(place->out, length);
			
			SWFOutput_writeAction(place->out, place->actions[i]);
		}
		
		/* trailing 0 for end of actions */
		if(block->swfVersion >= 6)
			SWFOutput_writeUInt32(place->out, 0); 
		else
			SWFOutput_writeUInt16(place->out, 0); 
	}
}
Пример #16
0
void SWFOutputMethod(byte i, void *data)
{
	SWFOutput_writeUInt8( (SWFOutput) data, i);
}
Пример #17
0
void
SWFOutput_writeMorphGradient(SWFOutput out,
                             SWFGradient gradient1, SWFGradient gradient2)
{
	int i;
	int nGrads = min(min(gradient1->nGrads, gradient2->nGrads), 8);

	SWFOutput_writeUInt8(out, nGrads); /* only 1-8 allowed */

	for ( i=0; i<nGrads; ++i )
	{
		SWFOutput_writeUInt8(out, gradient1->entries[i].ratio);
		SWFOutput_writeUInt8(out, gradient1->entries[i].r);
		SWFOutput_writeUInt8(out, gradient1->entries[i].g);
		SWFOutput_writeUInt8(out, gradient1->entries[i].b);
		SWFOutput_writeUInt8(out, gradient1->entries[i].a);
		SWFOutput_writeUInt8(out, gradient2->entries[i].ratio);
		SWFOutput_writeUInt8(out, gradient2->entries[i].r);
		SWFOutput_writeUInt8(out, gradient2->entries[i].g);
		SWFOutput_writeUInt8(out, gradient2->entries[i].b);
		SWFOutput_writeUInt8(out, gradient2->entries[i].a);
	}
}
Пример #18
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;
}
Пример #19
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;
}
Пример #20
0
SWFOutput
outputSWF_DEFINEFONT2 (SWF_Parserstruct * pblock)
{
  SWFOutput hdr0,hdr1,offsettbl,*glyphdata;
  int i,size, glyphbase;
  OUT_BEGIN (SWF_DEFINEFONT2);


  glyphdata = calloc(sblock->NumGlyphs,sizeof(SWFOutput *));
  size=0;
  for (i = 0; i < sblock->NumGlyphs; i++) {
	glyphdata[i] = outputswfSWF_SHAPE (&(sblock->GlyphShapeTable[i]));
	size+= SWFOutput_getLength(glyphdata[i]);
    }

  if( size > 0xffff ) 
    sblock->FontFlagsWideOffsets=1;

  if (sblock->FontFlagsWideOffsets) {
    glyphbase=(sblock->NumGlyphs*4)+4;
    sblock->CodeTableOffset.UI32=glyphbase;
    sblock->OffsetTable.UI32[0]=glyphbase;
  } else {
    glyphbase=(sblock->NumGlyphs*2)+2;
    sblock->CodeTableOffset.UI16=glyphbase;
    sblock->OffsetTable.UI16[0]=glyphbase;
    }

  for (i = 0; i < sblock->NumGlyphs; i++) {
        if (sblock->FontFlagsWideOffsets) {
          sblock->OffsetTable.UI32[i]=sblock->CodeTableOffset.UI32;
	  sblock->CodeTableOffset.UI32=sblock->OffsetTable.UI32[i]+SWFOutput_getLength(glyphdata[i]);
	} else {
          sblock->OffsetTable.UI16[i]=sblock->CodeTableOffset.UI16;
	  sblock->CodeTableOffset.UI16=sblock->OffsetTable.UI16[i]+SWFOutput_getLength(glyphdata[i]);
	}
    }

  offsettbl=newSWFOutput();
  for (i = 0; i < sblock->NumGlyphs; i++) {
      if (sblock->FontFlagsWideOffsets) {
	SWFOutput_writeUInt32(offsettbl,sblock->OffsetTable.UI32[i]);
      } else {
	SWFOutput_writeUInt16(offsettbl,sblock->OffsetTable.UI16[i]);
	}
    }

  /* Now that we have the glyph data, and it's offset, we can start assembling
     this block */

  size=	5		/* Initial header through FontNameLen */
	+(sblock->FontNameLen)	/* FontName */
	+2;		/* NumGlyphs */

  hdr1=newSizedSWFOutput(size);
  SWFOutput_writeUInt16(hdr1,sblock->FontID);
  SWFOutput_writeBits(hdr1,sblock->FontFlagsHasLayout,1);
  SWFOutput_writeBits(hdr1,sblock->FontFlagsShiftJis,1);
  SWFOutput_writeBits(hdr1,sblock->FontFlagsSmallText,1);
  SWFOutput_writeBits(hdr1,sblock->FontFlagsFlagANSI,1);
  SWFOutput_writeBits(hdr1,sblock->FontFlagsWideOffsets,1);
  SWFOutput_writeBits(hdr1,sblock->FontFlagsWideCodes,1);
  SWFOutput_writeBits(hdr1,sblock->FontFlagsFlagsItalics,1);
  SWFOutput_writeBits(hdr1,sblock->FontFlagsFlagsBold,1);
  SWFOutput_writeUInt8(hdr1,sblock->LanguageCode);
  SWFOutput_writeUInt8(hdr1,sblock->FontNameLen);
  SWFOutput_writeBuffer(hdr1,(unsigned char *)sblock->FontName,sblock->FontNameLen);
  SWFOutput_writeUInt16(hdr1,sblock->NumGlyphs);

  /* Now, copy these parts into the hdr buffer */
  SWFOutput_writeToMethod(offsettbl,SWFOutputMethod,hdr1);
  destroySWFOutput(offsettbl);
  if (sblock->FontFlagsWideOffsets)
    {
	SWFOutput_writeUInt32(hdr1,sblock->CodeTableOffset.UI32);
    }
  else
    {
	SWFOutput_writeUInt16(hdr1,sblock->CodeTableOffset.UI16);
    }
  for (i = 0; i < sblock->NumGlyphs; i++) {
    SWFOutput_writeToMethod(glyphdata[i],SWFOutputMethod,hdr1);
    destroySWFOutput(glyphdata[i]);
  }
  free(glyphdata);

  /* Now, resume the normal linear processing this tag */

  for (i = 0; i < sblock->NumGlyphs; i++)
    {
	if( sblock->FontFlagsWideCodes ) {
	  SWFOutput_writeUInt16(hdr1,sblock->CodeTable[i]);
	} else {
	  SWFOutput_writeUInt8(hdr1,sblock->CodeTable[i]);
	}
    }

  if( sblock->FontFlagsHasLayout ) {
    SWFOutput_writeSInt16(hdr1,sblock->FontAscent);
    SWFOutput_writeSInt16(hdr1,sblock->FontDecent);
    SWFOutput_writeSInt16(hdr1,sblock->FontLeading);
    for (i = 0; i < sblock->NumGlyphs; i++) {
      SWFOutput_writeSInt16(hdr1,sblock->FontAdvanceTable[i]);
      }
    for (i = 0; i < sblock->NumGlyphs; i++) {
	outputswfSWF_RECT (hdr1,&(sblock->FontBoundsTable[i]));
        SWFOutput_byteAlign(hdr1);
      }
    SWFOutput_writeUInt16(hdr1,sblock->KerningCount);
    for (i = 0; i < sblock->KerningCount; i++) {
      if( sblock->FontFlagsWideCodes ) {
      	SWFOutput_writeUInt16(hdr1,sblock->FontKerningTable[i].FontKerningCode1);
      	SWFOutput_writeUInt16(hdr1,sblock->FontKerningTable[i].FontKerningCode2);
      	SWFOutput_writeSInt16(hdr1,sblock->FontKerningTable[i].FontKerningAdjustment);
      } else {
      	SWFOutput_writeUInt8(hdr1,sblock->FontKerningTable[i].FontKerningCode1);
      	SWFOutput_writeUInt8(hdr1,sblock->FontKerningTable[i].FontKerningCode2);
      	SWFOutput_writeSInt16(hdr1,sblock->FontKerningTable[i].FontKerningAdjustment);
      }
    }
  }

/* This code really belongs in outputTAGHeader() */
hdr0=newSizedSWFOutput(6);

if(SWFOutput_getLength(hdr1) <= 62 ) {
	fprintf(stderr,"TAG %x\n",(SWF_DEFINEFONT2<<6)|SWFOutput_getLength(hdr1));
	SWFOutput_writeUInt16(hdr0,(SWF_DEFINEFONT2<<6)|SWFOutput_getLength(hdr1));
} else {
	SWFOutput_writeUInt16(hdr0,(SWF_DEFINEFONT2<<6)|0x3f);
	SWFOutput_writeUInt32(hdr0,SWFOutput_getLength(hdr1));
}

SWFOutput_writeToMethod(hdr1,SWFOutputMethod,hdr0);
destroySWFOutput(hdr1);

return hdr0;
}
Пример #21
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;
}