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; }
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; }
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; }