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; }
EditText::EditText(SObject* obj) { SParser parser; parser.Attach(obj->character->data, 0); m_flags = parser.GetWord(); if ( m_flags & seditTextFlagsHasFont ) { parser.SkipBytes(4); } if ( m_flags & seditTextFlagsHasTextColor ) { parser.GetColor(true); } if ( m_flags & seditTextFlagsHasMaxLength ) { m_maxLength = parser.GetWord(); } else { m_maxLength = 0; } if ( m_flags & seditTextFlagsHasLayout ) { m_align = parser.GetByte(); parser.SkipBytes(8); } else { m_align = stextAlignLeft; } m_variable = parser.GetStringP(); if ( m_flags & seditTextFlagsHasText ) { m_initialText = parser.GetStringP(); } else { m_initialText = NULL; } m_obj = obj; m_character = obj->character; m_clickTime = 0; m_selecting = FALSE; m_buffer = new U16[1]; m_buffer[0] = '\0'; m_length = 0; m_selectionStart = 0; m_selectionEnd = 0; m_hscroll = 0; m_vscroll = 0; m_mouseIsDown = FALSE; m_doFindCursor = FALSE; m_mousePosition.x = 0; m_mousePosition.y = 0; m_lineX = NULL; m_drawn = FALSE; m_lineStarts = NULL; m_numLines = 0; m_atLineEnd = FALSE; m_heldLeadByte = -1; devCharWidths = NULL; devLineSpacing = 0; devAscent = 0; RectSetEmpty(&devBounds); }
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; }
void DisplayList::DoButtonAction(SObject* target, int transition) { SCharacter* ch = target->character; FLASHASSERT(ch->type == buttonChar); if ( ch->tagCode == stagDefineButton2 ) { // Handle the new style button SParser parser; parser.Attach(ch->data, 0); BOOL first = true; for (;;) { S32 link = parser.pos; int offset = parser.GetWord(); if ( !first ) { int code = parser.GetWord(); if ( code & (1<<transition) ) { PushAction(parser.script+parser.pos, target->thread); } } if ( !offset ) break; parser.pos = link + offset; first = false; } } else { // Handle the old style button if ( transition == bsOverDownToOverUp ) { // Do the button action on the mouse up in SParser parser; parser.Attach(ch->data, 0); // Skip over the child data for (;;) { U8 stateFlags = parser.GetByte(); if ( !stateFlags ) break; MATRIX m; parser.SkipBytes(4);//GetWord(); //parser.GetWord(); parser.GetMatrix(&m); } // Handle the action PushAction(parser.script+parser.pos, target->thread); } } #ifdef SOUND {// Play the sound int state = 0; switch ( transition ) { case bsIdleToOverDown: case bsIdleToOverUp: state = sbtnOverState; break; case bsOverUpToOverDown: state = sbtnDownState; break; case bsOverDownToOverUp: state = sbtnHitTestState; break; case bsOverUpToIdle: case bsOutDownToIdle: case bsOverDownToIdle: state = sbtnUpState; break; } if ( state && ch->button.soundData ) { SParser parser; parser.Attach(ch->button.soundData, 0); // Skip the sounds for ( int i = 1; i < state; i <<= 1 ) { U16 tag = parser.GetWord(); if ( tag ) parser.GetSoundInfo(0);// skip the data } // Get the sound we want U16 tag = parser.GetWord(); if ( tag ) { SCharacter* sound = ch->player->FindCharacter(tag); if ( !sound || sound->type != soundChar ) return; CSoundChannel* channel = new CSoundChannel(); if ( channel ) { channel->AddRef(); channel->sound = &sound->sound; channel->tag = (U32)this; parser.GetSoundInfo(channel); // set up envelope, inPoint, loops, etc... theSoundMix->AddSound(channel); channel->Release(); } } } } #endif }