Esempio n. 1
0
/*
========================
idSWFShapeParser::ParseMorph
========================
*/
void idSWFShapeParser::ParseMorph( idSWFBitStream& bitstream, idSWFShape& shape )
{
	extendedCount = true;
	lineStyle2 = false;
	rgba = true;
	morph = true;
	
	bitstream.ReadRect( shape.startBounds );
	bitstream.ReadRect( shape.endBounds );
	
	uint32 offset = bitstream.ReadU32();
	
	// offset is the byte offset from the current read position to the 'endShape' record
	// we read the entire block into 'bitstream1' which moves the read pointer of 'bitstream'
	// to the start of the 'endShape' record
	
	idSWFBitStream bitstream1;
	bitstream1.Load( ( byte* )bitstream.ReadData( offset ), offset, false );
	
	ReadFillStyle( bitstream1 );
	ParseShapes( bitstream1, &bitstream, true );
	TriangulateSoup( shape );
}
Esempio n. 2
0
/*
========================
idSWF::DefineTextX
========================
*/
void idSWF::DefineTextX( idSWFBitStream & bitstream, bool rgba ) {
	uint16 characterID = bitstream.ReadU16();
	idSWFDictionaryEntry * entry = AddDictionaryEntry( characterID, SWF_DICT_TEXT );
	if ( entry == NULL ) {
		return;
	}
	idSWFText * text = entry->text;

	bitstream.ReadRect( text->bounds );
	bitstream.ReadMatrix( text->matrix );

	uint8 glyphBits = bitstream.ReadU8();
	uint8 advanceBits = bitstream.ReadU8();

	while ( true ) {
		uint8 flags = bitstream.ReadU8();
		if ( flags == 0 ) {
			break;
		}
		idSWFTextRecord & textRecord = text->textRecords.Alloc();

		if ( flags & BIT( 3 ) ) {
			textRecord.fontID = bitstream.ReadU16();
		}
		if ( flags & BIT( 2 ) ) {
			if ( rgba ) {
				bitstream.ReadColorRGBA( textRecord.color );
			} else {
				bitstream.ReadColorRGB( textRecord.color );
			}
		}
		if ( flags & BIT( 0 ) ) {
			textRecord.xOffset = bitstream.ReadS16();
		}
		if ( flags & BIT( 1 ) ) {
			textRecord.yOffset = bitstream.ReadS16();
		}
		if ( flags & BIT( 3 ) ) {
			textRecord.textHeight = bitstream.ReadU16();
		}
		textRecord.firstGlyph = text->glyphs.Num();
		textRecord.numGlyphs = bitstream.ReadU8();
		for ( int i = 0; i < textRecord.numGlyphs; i++ ) {
			swfGlyphEntry_t & glyph = text->glyphs.Alloc();
			glyph.index = bitstream.ReadU( glyphBits );
			glyph.advance = bitstream.ReadS( advanceBits );
		}
	};
}
Esempio n. 3
0
/*
========================
idSWF::DefineFont2
========================
*/
void idSWF::DefineFont2( idSWFBitStream & bitstream ) {
	uint16 characterID = bitstream.ReadU16();
	idSWFDictionaryEntry * entry = AddDictionaryEntry( characterID, SWF_DICT_FONT );
	if ( entry == NULL ) {
		return;
	}
	uint8 flags = bitstream.ReadU8();
	uint8 language = bitstream.ReadU8();

	char fontName[257];
	uint8 fontNameLength = bitstream.ReadU8();
	memcpy( fontName, bitstream.ReadData( fontNameLength ), fontNameLength );
	fontName[ fontNameLength ] = 0;

	entry->font->fontID = renderSystem->RegisterFont( fontName );

	uint16 numGlyphs = bitstream.ReadU16();
	entry->font->glyphs.SetNum( numGlyphs );

	if ( flags & BIT( 3 ) ) {
		// 32 bit offsets
		uint32 offsetTableSize = ( numGlyphs + 1 ) * 4;
		idSWFBitStream offsetStream( bitstream.ReadData( offsetTableSize ), offsetTableSize, false );
		if ( offsetStream.ReadU32() != offsetTableSize ) {
			idLib::Warning( "idSWF::DefineFont2: first glyph offset != offsetTableSize" );
			return;
		}
		uint32 previousOffset = offsetTableSize;
		for ( int i = 0; i < numGlyphs; i++ ) {
			uint32 nextOffset = offsetStream.ReadU32();
			uint32 shapeSize = nextOffset - previousOffset;
			previousOffset = nextOffset;
			idSWFBitStream shapeStream( bitstream.ReadData( shapeSize ), shapeSize, false );
			idSWFShapeParser swfShapeParser;
			swfShapeParser.ParseFont( shapeStream, entry->font->glyphs[i] );
		}
	} else {
		// 16 bit offsets
		uint16 offsetTableSize = ( numGlyphs + 1 ) * 2;
		idSWFBitStream offsetStream( bitstream.ReadData( offsetTableSize ), offsetTableSize, false );
		if ( offsetStream.ReadU16() != offsetTableSize ) {
			idLib::Warning( "idSWF::DefineFont2: first glyph offset != offsetTableSize" );
			return;
		}
		uint16 previousOffset = offsetTableSize;
		for ( int i = 0; i < numGlyphs; i++ ) {
			uint16 nextOffset = offsetStream.ReadU16();
			uint16 shapeSize = nextOffset - previousOffset;
			previousOffset = nextOffset;
			idSWFBitStream shapeStream( bitstream.ReadData( shapeSize ), shapeSize, false );
			idSWFShapeParser swfShapeParser;
			swfShapeParser.ParseFont( shapeStream, entry->font->glyphs[i] );
		}
	}
	if ( flags & BIT( 2 ) ) {
		// 16 bit codes
		for ( int i = 0; i < numGlyphs; i++ ) {
			entry->font->glyphs[i].code = bitstream.ReadU16();
		}
	} else {
		// 8 bit codes
		for ( int i = 0; i < numGlyphs; i++ ) {
			entry->font->glyphs[i].code = bitstream.ReadU8();
		}
	}
	if ( flags & BIT( 7 ) ) {
		entry->font->ascent = bitstream.ReadS16();
		entry->font->descent = bitstream.ReadS16();
		entry->font->leading = bitstream.ReadS16();
		for ( int i = 0; i < numGlyphs; i++ ) {
			entry->font->glyphs[i].advance = bitstream.ReadS16();
		}
		for ( int i = 0; i < numGlyphs; i++ ) {
			swfRect_t ignored;
			bitstream.ReadRect( ignored );
		}
		uint16 kearningCount = bitstream.ReadU16();
		if ( flags & BIT( 2 ) ) {
			for ( int i = 0; i < kearningCount; i++ ) {
				uint16 code1 = bitstream.ReadU16();
				uint16 code2 = bitstream.ReadU16();
				int16 adjustment = bitstream.ReadS16();
			}
		} else {
			for ( int i = 0; i < kearningCount; i++ ) {
				uint16 code1 = bitstream.ReadU8();
				uint16 code2 = bitstream.ReadU8();
				int16 adjustment = bitstream.ReadS16();
			}
		}
	}
}
Esempio n. 4
0
/*
========================
idSWF::DefineEditText
========================
*/
void idSWF::DefineEditText( idSWFBitStream & bitstream ) {
	uint16 characterID = bitstream.ReadU16();
	idSWFDictionaryEntry * entry = AddDictionaryEntry( characterID, SWF_DICT_EDITTEXT );
	if ( entry == NULL ) {
		return;
	}
	idSWFEditText * edittext = entry->edittext;
	bitstream.ReadRect( edittext->bounds );
	bitstream.ResetBits();
	bool hasText = bitstream.ReadBool();
	bool wordWrap = bitstream.ReadBool();
	bool multiline = bitstream.ReadBool();
	bool password = bitstream.ReadBool();
	bool readonly = bitstream.ReadBool();
	bool hasTextColor = bitstream.ReadBool();
	bool hasMaxLength = bitstream.ReadBool();
	bool hasFont = bitstream.ReadBool();
	bool hasFontClass = bitstream.ReadBool();
	bool autoSize = bitstream.ReadBool();
	bool hasLayout = bitstream.ReadBool();
	bool noSelect = bitstream.ReadBool();
	bool border = bitstream.ReadBool();
	bool wasStatic = bitstream.ReadBool();
	bool html = bitstream.ReadBool();
	bool useOutlines = bitstream.ReadBool();
	if ( hasFont ) {
		edittext->fontID = bitstream.ReadU16();
		edittext->fontHeight = bitstream.ReadU16();
	}
	if ( hasFontClass ) {
		idStr fontClass = bitstream.ReadString();
	}
	if ( hasTextColor ) {
		bitstream.ReadColorRGBA( edittext->color );
	}
	if ( hasMaxLength ) {
		edittext->maxLength = bitstream.ReadU16();
	}
	if ( hasLayout ) {
		edittext->align = (swfEditTextAlign_t)bitstream.ReadU8();
		edittext->leftMargin = bitstream.ReadU16();
		edittext->rightMargin = bitstream.ReadU16();
		edittext->indent = bitstream.ReadU16();
		edittext->leading = bitstream.ReadS16();
	}
	edittext->variable = bitstream.ReadString();
	if ( hasText ) {
		const char * text = bitstream.ReadString();
		idStr initialText;

		// convert html tags if necessary
		for ( int i = 0; text[i] != 0; i++ ) {
			if ( text[i] == '<' ) {
				if ( i != 0 && text[i+1] == 'p' ) {
					initialText.Append( '\n' );
				}
				for ( ; text[i] != 0 && text[i] != '>'; i++ ) {
				}
				continue;
			}
			byte tc = (byte)text[i];
			if ( tc == '&' ) {
				idStr special;
				for ( i++; text[i] != 0 && text[i] != ';'; i++ ) {
					special.Append( text[i] );
				}
				if ( special.Icmp( "amp" ) == 0 ) {
					tc = '&';
				} else if ( special.Icmp( "apos" ) == 0 ) {
					tc = '\'';
				} else if ( special.Icmp( "lt" ) == 0 ) {
					tc = '<';
				} else if ( special.Icmp( "gt" ) == 0 ) {
					tc = '>';
				} else if ( special.Icmp( "quot" ) == 0 ) {
					tc = '\"';
				}
			}
			initialText.Append( tc );
		}
		edittext->initialText = initialText;
	}
	edittext->flags |= wordWrap ? SWF_ET_WORDWRAP : 0;
	edittext->flags |= multiline ? SWF_ET_MULTILINE : 0;
	edittext->flags |= password ? SWF_ET_PASSWORD : 0;
	edittext->flags |= readonly ? SWF_ET_READONLY : 0;
	edittext->flags |= autoSize ? SWF_ET_AUTOSIZE : 0;
	edittext->flags |= border ? SWF_ET_BORDER : 0;
}
Esempio n. 5
0
/*
========================
idSWFShapeParser::ParseShape
========================
*/
void idSWFShapeParser::Parse( idSWFBitStream& bitstream, idSWFShape& shape, int recordType )
{
	extendedCount = ( recordType > 1 );
	lineStyle2 = ( recordType == 4 );
	rgba = ( recordType >= 3 );
	morph = false;
	
	bitstream.ReadRect( shape.startBounds );
	shape.endBounds = shape.startBounds;
	
	if( recordType == 4 )
	{
		swfRect_t edgeBounds;
		bitstream.ReadRect( edgeBounds );
		bitstream.ReadU8();	// flags (that we ignore)
	}
	
	ReadFillStyle( bitstream );
	ParseShapes( bitstream, NULL, false );
	TriangulateSoup( shape );
	
	shape.lineDraws.SetNum( lineDraws.Num() );
	for( int i = 0; i < lineDraws.Num(); i++ )
	{
		idSWFShapeDrawLine& ld = shape.lineDraws[i];
		swfSPDrawLine_t& spld = lineDraws[i];
		ld.style = spld.style;
		ld.indices.SetNum( spld.edges.Num() * 3 );
		ld.indices.SetNum( 0 );
		for( int e = 0; e < spld.edges.Num(); e++ )
		{
			int v0 = ld.startVerts.AddUnique( verts[ spld.edges[e].start.v0 ] );
			ld.indices.Append( v0 );
			ld.indices.Append( v0 );
			
			// Rather then tesselating curves at run time, we do them once here by inserting a vert every 10 units
			// It may not wind up being 10 actual pixels when rendered because the shape may have scaling applied to it
			if( spld.edges[e].start.cp != 0xFFFF )
			{
				assert( spld.edges[e].end.cp != 0xFFFF );
				float length1 = ( verts[ spld.edges[e].start.v0 ] - verts[ spld.edges[e].start.v1 ] ).Length();
				float length2 = ( verts[ spld.edges[e].end.v0 ] - verts[ spld.edges[e].end.v1 ] ).Length();
				int numPoints = 1 + idMath::Ftoi( Max( length1, length2 ) / 10.0f );
				for( int ti = 0; ti < numPoints; ti++ )
				{
					float t0 = ( ti + 1 ) / ( ( float ) numPoints + 1.0f );
					float t1 = ( 1.0f - t0 );
					float c1 = t1 * t1;
					float c2 = t0 * t1 * 2.0f;
					float c3 = t0 * t0;
					
					idVec2	p1  = c1 * verts[ spld.edges[e].start.v0 ];
					p1 += c2 * verts[ spld.edges[e].start.cp ];
					p1 += c3 * verts[ spld.edges[e].start.v1 ];
					
					int v1 = ld.startVerts.AddUnique( p1 );
					ld.indices.Append( v1 );
					ld.indices.Append( v1 );
					ld.indices.Append( v1 );
				}
			}
			ld.indices.Append( ld.startVerts.AddUnique( verts[ spld.edges[e].start.v1 ] ) );
		}
	}
}