void DisplayList::Update() { CalcUpdate(); // Use multiple dirty rectangles to minimize area if ( nDirty > 0 && bits ) { // Update the frame buffer DecomposeDirtyList(); for ( int i = 0; i < nDirty; i++ ) { SRECT bitsDirtyRgn; CalcBitsDirty(devDirtyRect+i, &bitsDirtyRgn); RectUnion(&bitsDirtyRgn, &screenDirtyRgn, &screenDirtyRgn); UpdateRect(&bitsDirtyRgn); } } RectSetEmpty(&devDirtyRgn); nDirty = 0; }
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); }
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; }
DisplayList::DisplayList() : edgeAlloc(sizeof(REdge), 600, true, 0x22222222), colorAlloc(sizeof(RColor), 64, true, 0x44444444), objectAlloc(sizeof(SObject), 32, true, 0x55555555) { // Set up the root object root.display = this; root.parent = 0; root.above = 0; root.bottomChild = 0; root.character = 0; root.depth = 0; root.ratio = 0; root.name = 0; root.xform.Clear(); RectSetEmpty(&root.devBounds); root.state = 0; root.drawn = false; root.puppet = false; root.edges = 0; root.colors = 0; root.thread = 0; root.visible = true; root.dragCenter = false; RectSetEmpty(&root.dragConstraint); root.dropTarget = 0; #ifdef EDITTEXT root.editText = 0; #endif holdList = 0; holdParent = 0; threads = 0; instanceNameCount = 0; camera.Clear(); antialias = false; faster = false; useDeviceFont = false; bits = 0; dirty = false; RectSetEmpty(&screenDirtyRgn); RectSetEmpty(&devDirtyRgn); nDirty = 0; UpdateDevViewRect(); backgroundColor.all = SRGBWhite; backgroundColorPriority = 0; // Button info buttonState = 0; button = 0; RectSetEmpty(&tabFocusRect); useFocusRect = true; buttonParent = 0; buttonCharacter = 0; buttonDepth = 0; buttonRatio = 0; actionURL[0] = 0; #ifdef EDITTEXT // Text editing iBeam = FALSE; #endif hasDeviceEditText = false; actionCallStackTop = 0; }