Beispiel #1
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 );
		}
	};
}
Beispiel #2
0
/*
========================
idSWF::DefineShape4
========================
*/
void idSWF::DefineShape4( idSWFBitStream & bitstream ) {
	uint16 characterID = bitstream.ReadU16();
	idSWFDictionaryEntry * entry = AddDictionaryEntry( characterID, SWF_DICT_SHAPE );
	if ( entry == NULL ) {
		return;
	}

	idSWFShapeParser swfShapeParser;
	swfShapeParser.Parse( bitstream, *entry->shape, 4 );
}
/*
========================
idSWFSpriteInstance::PlaceObject2
========================
*/
void idSWFSpriteInstance::PlaceObject2( idSWFBitStream & bitstream ) {
	c_PlaceObject2++;

	uint64 flags = bitstream.ReadU8();
	int depth = bitstream.ReadU16();

	int characterID = -1;
	if ( ( flags & PlaceFlagHasCharacter ) != 0 ) {
		characterID = bitstream.ReadU16();
	}

	swfDisplayEntry_t * display = NULL;

	if ( ( flags & PlaceFlagMove ) != 0 ) {
		// modify an existing entry
		display = FindDisplayEntry( depth );
		if ( display == NULL ) {
			idLib::Warning( "PlaceObject2: trying to modify entry %d, which doesn't exist", depth );
			return;
		}
		if ( characterID >= 0 ) {
			// We are very picky about what kind of objects can change characters
			// Shapes can become other shapes, but sprites can never change
			if ( display->spriteInstance || display->textInstance ) {
				idLib::Warning( "PlaceObject2: Trying to change the character of a sprite after it's been created" );
				return;
			}
			idSWFDictionaryEntry * dictEntry = sprite->swf->FindDictionaryEntry( characterID );
			if ( dictEntry != NULL ) {
				if ( dictEntry->type == SWF_DICT_SPRITE || dictEntry->type == SWF_DICT_EDITTEXT ) {
					idLib::Warning( "PlaceObject2: Trying to change the character of a shape to a sprite" );
					return;
				}
			}
			display->characterID = characterID;
		}
	} else {
		if ( characterID < 0 ) {
			idLib::Warning( "PlaceObject2: Trying to create a new object without a character" );
			return;
		}
		// create a new entry
		display = AddDisplayEntry( depth, characterID );
		if ( display == NULL ) {
			idLib::Warning( "PlaceObject2: trying to create a new entry at %d, but an item already exists there", depth );
			return;
		}
	}
	if ( ( flags & PlaceFlagHasMatrix ) != 0 ) {
		bitstream.ReadMatrix( display->matrix );
	}
	if ( ( flags & PlaceFlagHasColorTransform ) != 0 ) {
		bitstream.ReadColorXFormRGBA( display->cxf );
	}
	if ( ( flags & PlaceFlagHasRatio ) != 0 ) {
		display->ratio = bitstream.ReadU16() * ( 1.0f / 65535.0f );
	}
	if ( ( flags & PlaceFlagHasName ) != 0 ) {
		idStr name = bitstream.ReadString();
		if ( display->spriteInstance ) {
			display->spriteInstance->name = name;
			scriptObject->Set( name, display->spriteInstance->GetScriptObject() );
		} else if ( display->textInstance ) {
			scriptObject->Set( name, display->textInstance->GetScriptObject() );
		}
	}
	if ( ( flags & PlaceFlagHasClipDepth ) != 0 ) {
		display->clipDepth = bitstream.ReadU16();
	}
	if ( ( flags & PlaceFlagHasClipActions ) != 0 ) {
		// FIXME: clip actions
	}
}
/*
========================
idSWFSpriteInstance::RemoveObject2
========================
*/
void idSWFSpriteInstance::RemoveObject2( idSWFBitStream & bitstream ) {
	RemoveDisplayEntry( bitstream.ReadU16() );
}
/*
========================
idSWFSpriteInstance::PlaceObject3
========================
*/
void idSWFSpriteInstance::PlaceObject3( idSWFBitStream & bitstream ) {
	c_PlaceObject3++;

	uint64 flags1 = bitstream.ReadU8();
	uint64 flags2 = bitstream.ReadU8();
	uint16 depth = bitstream.ReadU16();

	if ( ( flags2 & PlaceFlagHasClassName ) != 0 || ( ( ( flags2 & PlaceFlagHasImage ) != 0 ) && ( ( flags1 & PlaceFlagHasCharacter ) != 0 ) ) ) {
		bitstream.ReadString(); // ignored
	}

	int characterID = -1;
	if ( ( flags1 & PlaceFlagHasCharacter ) != 0 ) {
		characterID = bitstream.ReadU16();
	}

	swfDisplayEntry_t * display = NULL;

	if ( ( flags1 & PlaceFlagMove ) != 0 ) {
		// modify an existing entry
		display = FindDisplayEntry( depth );
		if ( display == NULL ) {
			idLib::Warning( "PlaceObject3: trying to modify entry %d, which doesn't exist", depth );
			return;
		}
		if ( characterID >= 0 ) {
			// We are very picky about what kind of objects can change characters
			// Shapes can become other shapes, but sprites can never change
			if ( display->spriteInstance || display->textInstance ) {
				idLib::Warning( "PlaceObject3: Trying to change the character of a sprite after it's been created" );
				return;
			}
			idSWFDictionaryEntry * dictEntry = sprite->swf->FindDictionaryEntry( characterID );
			if ( dictEntry != NULL ) {
				if ( dictEntry->type == SWF_DICT_SPRITE || dictEntry->type == SWF_DICT_EDITTEXT ) {
					idLib::Warning( "PlaceObject3: Trying to change the character of a shape to a sprite" );
					return;
				}
			}
			display->characterID = characterID;
		}
	} else {
		if ( characterID < 0 ) {
			idLib::Warning( "PlaceObject3: Trying to create a new object without a character" );
			return;
		}
		// create a new entry
		display = AddDisplayEntry( depth, characterID );
		if ( display == NULL ) {
			idLib::Warning( "PlaceObject3: trying to create a new entry at %d, but an item already exists there", depth );
			return;
		}
	}
	if ( ( flags1 & PlaceFlagHasMatrix ) != 0 ) {
		bitstream.ReadMatrix( display->matrix );
	}
	if ( ( flags1 & PlaceFlagHasColorTransform ) != 0 ) {
		bitstream.ReadColorXFormRGBA( display->cxf );
	}
	if ( ( flags1 & PlaceFlagHasRatio ) != 0 ) {
		display->ratio = bitstream.ReadU16() * ( 1.0f / 65535.0f );
	}
	if ( ( flags1 & PlaceFlagHasName ) != 0 ) {
		idStr name = bitstream.ReadString();
		if ( display->spriteInstance ) {
			display->spriteInstance->name = name;
			scriptObject->Set( name, display->spriteInstance->GetScriptObject() );
		} else if ( display->textInstance ) {
			scriptObject->Set( name, display->textInstance->GetScriptObject() );
		}
	}
	if ( ( flags1 & PlaceFlagHasClipDepth ) != 0 ) {
		display->clipDepth = bitstream.ReadU16();
	}
	if ( ( flags2 & PlaceFlagHasFilterList ) != 0 ) {
		// we don't support filters and because the filter list is variable length we
		// can't support anything after the filter list either (blend modes and clip actions)
		idLib::Warning( "PlaceObject3: has filters" );
		return;
	}
	if ( ( flags2 & PlaceFlagHasBlendMode ) != 0 ) {
		display->blendMode = bitstream.ReadU8();
	}
	if ( ( flags1 & PlaceFlagHasClipActions ) != 0 ) {
		// FIXME:
	}
}
Beispiel #6
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();
			}
		}
	}
}
Beispiel #7
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;
}