Пример #1
0
int
SWFText_getScaledStringWidth(SWFText text, const char *string)
{
	SWFFont font;
	int height;
	unsigned short* widestr;
	int len = strlen(string);
	int n, ret;
	
	if(text->currentRecord == NULL)
		return -1;

	height = text->currentRecord->height;
	widestr = (unsigned short *)malloc(2 * len);

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

	for(n = 0 ; n < len ; n++)
		widestr[n] = (unsigned char)string[n];

	if ( text->currentRecord->isResolved )
		font = SWFFontCharacter_getFont(text->currentRecord->font.fontchar);
	else
		font = text->currentRecord->font.font;

	ret = SWFFont_getScaledWideStringWidth(font, widestr, len) * height / 1024;
	free(widestr);
	return ret;
}
Пример #2
0
static inline int checkSWFFontCharacter(SWFFontCharacter fc)
{
	int font_flags;
	int nGlyphs;

	SWFFont font = SWFFontCharacter_getFont(fc);
	font_flags = SWFFont_getFlags(font);
	nGlyphs = SWFFontCharacter_getNGlyphs(fc);
	
	if((font_flags & SWF_FONT_HASLAYOUT) == 0 && nGlyphs == 0)
		return -1;

	return 0;
}
Пример #3
0
static void
SWFTextRecord_computeAdvances(SWFTextRecord textRecord)
{
	int i;
	int len = textRecord->strlen;
	unsigned short* widestring = textRecord->string;
	unsigned short glyph;

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

	if(!len) return;	// do not try to calculate 1st char of null string

	/* compute advances (spacing) from spacing, advance and kern table */

	if ( textRecord->advance == NULL )
	{
		textRecord->advance = (int*)malloc(sizeof(int) * len);
		memset(textRecord->advance, 0, sizeof(int) * len);
	}

	glyph = SWFFontCharacter_getGlyphCode(fontchar, widestring[0]);

	for ( i=0; i<len; ++i )
	{
		int adv;
		unsigned short nextglyph;

		adv = SWFFont_getCharacterAdvance(font, (unsigned short)glyph);
		adv += textRecord->spacing;

		/* get kerning from font's kern table */

		if ( i < len-1 )
		{	nextglyph = SWFFontCharacter_getGlyphCode(fontchar, widestring[i+1]);
			adv += SWFFont_getCharacterKern(font, glyph, nextglyph);
			glyph = nextglyph;
		}

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

		textRecord->advance[i] = adv * textRecord->height / 1024;

		textRecord->nAdvanceBits = max(textRecord->nAdvanceBits,
																	 SWFOutput_numSBits(textRecord->advance[i]));

	}
}
Пример #4
0
/* 
 * Adds a font to a movie.
 * retursn a SWFFontCharacter object
 */
SWFFontCharacter
SWFMovie_addFont(SWFMovie movie, SWFFont font)
{
	SWFFontCharacter fontchar;
	int i;
	
	for( i = 0 ; i < movie->nFonts ; i++ )
	{	fontchar = movie->fonts[i];
		if ( SWFFontCharacter_getFont(fontchar) == font )
			return fontchar;
	}
	movie->fonts = (SWFFontCharacter*)realloc(movie->fonts,
					 sizeof(SWFFontCharacter) * (movie->nFonts + 1));
	fontchar = newSWFFontCharacter(font);
	movie->fonts[movie->nFonts++] = fontchar;
	SWFMovie_addBlock(movie, (SWFBlock)fontchar);
	return fontchar;
}
Пример #5
0
int
SWFText_getScaledWideStringWidth(SWFText text, const unsigned short *string)
{
	SWFFont font;
	int height = text->currentRecord->height;
	int len;

	for(len = 0 ; *string ; len++)
		;
	if ( text->currentRecord->isResolved )
		font = SWFFontCharacter_getFont(text->currentRecord->font.fontchar);
	else
		font = text->currentRecord->font.font;

	if ( text->currentRecord->isBrowserFont )
		return 0;
	else
		return SWFFont_getScaledWideStringWidth(font, string, len) * height / 1024;
}
Пример #6
0
int
SWFText_getScaledUTF8StringWidth(SWFText text, const char *string)
{
	SWFFont font;
	int height = text->currentRecord->height;
	unsigned short* widestr;
	int len, ret;

	len = UTF8ExpandString(string, &widestr);
	if ( text->currentRecord->isResolved )
		font = SWFFontCharacter_getFont(text->currentRecord->font.fontchar);
	else
		font = text->currentRecord->font.font;

	if ( text->currentRecord->isBrowserFont )
		ret = 0;
	else
		ret = SWFFont_getScaledWideStringWidth(font, widestr, len) * height / 1024;
	free(widestr);
	return ret;
}
Пример #7
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;
}
Пример #8
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;
}