示例#1
0
void DisplayList::UpdateButton(SObject* obj, int newState)
// Add or remove child characters so that the button matches newState
{
	SCharacter* ch = obj->character;
	if ( ch->type != buttonChar )
		return;
	
	int oldState = obj->state;
	if ( oldState == newState ) return;

	U8 * cxData = ch->button.cxformData;

	ScriptPlayer* player = ch->player;
	for ( int pass = 0; pass < 2; pass++ ) {
		SParser parser;
		parser.Attach(ch->data, 0);

		if ( ch->tagCode == stagDefineButton2 ) 
			parser.GetWord();	// skip the action offset

		SParser cxParser;
		if ( cxData )
			cxParser.Attach(cxData, 0);

		for (;;) {
			U8 stateFlags = parser.GetByte();
			if ( !stateFlags ) break;

			PlaceInfo info;
			info.flags = splaceCharacter|splaceMatrix|splaceColorTransform;
			U16 tag = parser.GetWord();
			info.depth = obj->depth + parser.GetWord();
			parser.GetMatrix(&info.mat);
			if ( ch->tagCode == stagDefineButton2 ) 
				parser.GetColorTransform(&info.cxform, true);	// new style button
			else if ( cxData )
				cxParser.GetColorTransform(&info.cxform, false);// separate cxfrom data
			else
				info.cxform.Clear();							// no cxform data

			// Remove the objects first and then add in case we have conflicting layer/id combos
			BOOL newVis = stateFlags & btnStateMap[newState];
			BOOL oldVis = stateFlags & btnStateMap[oldState];
			if ( pass == 0 && !newVis && oldVis ) {
				// Remove the child
				RemoveObject(obj, info.depth);
			}
			if ( pass == 1 && newVis && !oldVis ) {
				// Add the child
				info.character = player->FindCharacter(tag);
				info.name = 0;
				if ( info.character )
					PlaceObject(obj, &info);
			}
		}
	}
	obj->state = newState;
}
示例#2
0
文件: edittext.cpp 项目: F5000/spree
void EditText::GetFontDesc(FontDesc& fontDesc)
{
	SParser parser;
	parser.Attach(m_character->data, 0);

	U16 flags = parser.GetWord();

	U16 fontTag = 0;

	if ( flags & seditTextFlagsHasFont )
	{
		fontTag = parser.GetWord();
		fontDesc.height = parser.GetWord();
	}

	ScriptPlayer* player = m_character->player;

	// On Unix, if no font was specified, fall back on built-in Times Roman.
	if ( !fontTag )
	{
		fontTag = kUnixSerifFont;
		player = &player->splayer->builtInFontsPlayer;
	}

	if ( fontTag )
	{
		// Find the font character
		SCharacter* font = player->FindCharacter(fontTag);
		char fontName[256];

		if ( font )
		{
			// Get the font name
			if ( font->tagCode == stagDefineFont2 )
			{
				parser.Attach(font->data - font->font.nDataOffset, 0);
				int len = parser.GetByte();
				parser.GetData(fontName, len);
				fontName[len] = 0;

				fontDesc.boldFlag = (font->font.flags & sfontFlagsBold) != 0;
				fontDesc.italicFlag = (font->font.flags & sfontFlagsItalic) != 0;
				fontDesc.japaneseFlag = (font->font.flags & sfontFlagsShiftJIS) != 0;

			}
			else if ( font->font.infoData )
			{
				parser.Attach(font->font.infoData, 0);
				int len = parser.GetByte();
				parser.GetData(fontName, len);
				fontName[len] = 0;

				// Get the font flags
				U8 flags = parser.GetByte();

				fontDesc.boldFlag = (flags & tfontBold) != 0;
				fontDesc.italicFlag = (flags & tfontItalic) != 0;
				fontDesc.japaneseFlag = (flags & 0xf) == tfontShiftJIS;
			}

			BOOL useGlyphFont = IsFontIncluded();

			// If outlines aren't included, we need to fall back
			// on a built-in font
			if ( !useGlyphFont )
			{
				if ( !strcmp(fontName, SANS_NAME) )
				{
					fontTag = kUnixSansFont;
				}
				else if ( !strcmp(fontName, TYPEWRITER_NAME) )
				{
					fontTag = kUnixTypewriterFont;
				}
				else
				{
					fontTag = kUnixSerifFont;
				}
				if ( fontDesc.boldFlag )
				{
					fontTag += kUnixBoldOffset;
				}
				if ( fontDesc.italicFlag )
				{
					fontTag += kUnixItalicOffset;
				}
				font = m_character->player->splayer->builtInFontsPlayer.FindCharacter(fontTag);
				useGlyphFont = TRUE;
			}

			// Figure out the code table offset, if applicable
			if ( useGlyphFont )
			{
				U16 g = font->font.nGlyphs;
				U8* s;
				if ( font->font.flags & sfontFlagsWideOffsets )
				{
					s = font->data + 4*g;
					fontDesc.codeOffset = (U32)s[0] | ((U32)s[1]<<8) | ((U32)s[2]<<16) | ((U32)s[3]<<24);
				}
				else
				{
					s = font->data + 2*g;
					fontDesc.codeOffset = (U16)s[0] | ((U16)s[1]<<8);
				}
			}
			else
			{
				// Not using the outlines so ignore the code table
				fontDesc.codeOffset = -1;

				// We must determine if this font actually exists.
				// If it doesn't, fall back on a predetermined font.
				if ( !PlayerIsFontAvailable(fontDesc.fontName) )
				{
					if ( fontDesc.japaneseFlag )
					{
						// MS UI Gothic is preferred, but fallback on MS Gothic if not present
						if ( PlayerIsFontAvailable(DEFAULT_EDITTEXT_J_FONT_1) )
						{
							strcpy(fontDesc.fontName, DEFAULT_EDITTEXT_J_FONT_1);
						}
						else
						{
							strcpy(fontDesc.fontName, DEFAULT_EDITTEXT_J_FONT_2);
						}
					}
					else
					{
						strcpy(fontDesc.fontName, DEFAULT_EDITTEXT_FONT);
					}
				}
			}

			// Success!  Return this font information.
			fontDesc.font = font;
			return;
		}
	}

	// No font info in the text field tag, so we'll have to use defaults.
	strcpy(fontDesc.fontName, DEFAULT_EDITTEXT_FONT);
	fontDesc.boldFlag = FALSE;
	fontDesc.italicFlag = FALSE;
	fontDesc.japaneseFlag = FALSE;
	fontDesc.height = DEFAULT_EDITTEXT_HEIGHT;
	fontDesc.font = NULL;
	fontDesc.codeOffset = -1;
}
示例#3
0
SObject* DisplayList::PlaceObject(SObject* parent, PlaceInfo* info)
{
	// Find the insertion point
	SObject** link = &parent->bottomChild;
	for (;;) {
		SObject* obj = *link;
		if ( !obj ) break;
	 	if ( obj->depth >= info->depth ) {
			FLASHASSERT(obj->depth != info->depth);
			break;
		}
		link = &obj->above;
	}

	// Create a new object
	SObject* obj = CreateObject();
	if ( !obj ) return 0;

	// Add to list
	obj->parent = parent;
	obj->above = *link;
	*link = obj;

	// Set up object
	obj->character = info->character;
	obj->xform = *info;
	obj->depth = info->depth;
	obj->ratio = info->ratio;
    obj->puppet = info->puppet;
	obj->drawn = false;
    obj->visible = true;
	obj->dragCenter = false;
	RectSetEmpty(&obj->dragConstraint);
	obj->dropTarget = NULL;
	obj->display = this;
	obj->bottomChild = 0;
	obj->edges = 0;
	obj->colors = 0;
	obj->state = 0;
#ifdef EDITTEXT
	obj->editText = 0;
#endif

	// If this is a movie clip and it has no name,
	// generate a default name
	if (obj->character->type == spriteChar && !info->name) {
		URLBuilder ub;
		ub.AppendString("instance");
		ub.AppendInt(++instanceNameCount);
		obj->name = CreateStr(ub.buf);
	} else {
		// Regular processing: copy name if present
		obj->name = CreateStr(info->name);
	}
	obj->thread = parent ? parent->thread : 0;
	obj->clipDepth = info->flags & splaceDefineClip ? info->clipDepth : 0;//(info->flags & splaceDefineClip) != 0;
	obj->Modify();

	switch ( obj->character->type ) {
		case buttonChar: {
			// Set up the button state
			int state = bsIdle;
			if ( obj->depth == buttonDepth && obj->parent == buttonParent && 
				 buttonCharacter == obj->character && obj->ratio == buttonRatio ) {
				// The button is currently being tracked
				FLASHASSERT(obj->character->type == buttonChar);
				button = obj;
				state = buttonState;
			}
			UpdateButton(obj, state);
		} break;

#ifdef EDITTEXT
		case editTextChar:
			{
				obj->editText = new EditText(obj);
				if (holdParent != obj->parent) {
					// Not doing a hold... update value immediately
					obj->editText->UpdateFromVariable();
				}
				// If there is a holdParent, the edit text's value will
				// be updated later.
			}
			break;
#endif

		case spriteExternalChar:
        {
			ScriptThread    *thread = 0;
            ScriptPlayer    *player = obj->character->player;
            int             startPos = 0;
            int             len = 0;
            int             numFrames = 0;

            if (info->flags & splaceCloneExternalSprite)
            {
                // means we are cloning an existing
                // external sprite
                if (player->len >= player->scriptLen)
                {
                    // we only clone the external
                    // sprite if it has been completely loaded
                    // allocate full player instead of thread
                    // it is easier to delete the external
                    // sprite if it has its own player
                    thread = new ScriptPlayer;
                    startPos = player->startPos;
                    len = player->len;
                    numFrames = player->numFrames;
                    thread->script = player->script;
                    ((ScriptPlayer *) thread)->numFramesComplete = player->numFramesComplete;
                    player = (ScriptPlayer *) thread;
                    player->gotHeader = true;
                    
                    // add a ref count to the script
                    // we don't want to duplicate it
                    // so we want to make sure it's
                    // protected from deletion for
                    // cloned external sprites
                    player->scriptRefCount = obj->character->player->scriptRefCount;
                    player->ScriptAddRefCount();
                }
            }
            else
            {
                // note that it's ok to have some of the
                // initial values of the len, etc. set
                // to zero. they will be set during pushdata
                thread = player;

                // add a ref count to the script
                // we don't want to duplicate it
                // so we want to make sure it's
                // protected from deletion for
                // cloned external sprites
                player->ScriptAddRefCount();
            }
			
            if ( thread ) 
            {
				thread->ClearState();
				obj->thread = thread;
				thread->player = player;
				thread->layerDepth = obj->depth;
				thread->rootObject = obj;
				thread->SetDisplay(obj->display);
				thread->Attach(obj->character->player->script, startPos);
				thread->len = len;
				thread->startPos = startPos;
				thread->numFrames = numFrames;
                
                // for non cloned sprite this won't draw the frame
                // untill we push data into the script (this is ok)
				thread->DrawFrame(0, false);
			}
		} break;

  		case spriteChar: {
			// Create a sprite thread
			ScriptThread* thread = new ScriptThread();
			if ( thread ) {
				thread->ClearState();
				obj->thread = thread;
				thread->player = obj->character->player;
				thread->layerDepth = obj->depth;
				thread->rootObject = obj;
				thread->SetDisplay(obj->display);
				thread->Attach(obj->character->data, 0);
				thread->len = obj->character->sprite.length;
				thread->startPos = 0;
				thread->numFrames = obj->character->sprite.numFrames;
				thread->DrawFrame(0, false);
			}
		} break;
	}

	return obj;
}