📄 displaylist.cpp
字号:
////////////////////////////////////////////////////////////// Flash Plugin and Player// Copyright (C) 1998,1999 Olivier Debon// // This program is free software; you can redistribute it and/or// modify it under the terms of the GNU General Public License// as published by the Free Software Foundation; either version 2// of the License, or (at your option) any later version.// // This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.// // You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.// ///////////////////////////////////////////////////////////////// Author : Olivier Debon <odebon@club-internet.fr>// #include "swf.h"#ifdef RCSIDstatic char *rcsid = "$Id: displaylist.cc,v 1.2 2004/12/22 18:36:41 tgc Exp $";#endif#define PRINT 0void deleteButton(FlashMovie *movie, DisplayListEntry *e){ /* save the focus */ if (movie->mouse_active == 0 && e->renderState == stateOver) { movie->lost_over = (Button *)e->character; movie->cur_focus = NULL; } if (e == movie->cur_focus) { movie->cur_focus = NULL; }}void addButton(FlashMovie *movie, DisplayListEntry *e){ if (movie->mouse_active == 0 && movie->cur_focus == NULL && movie->lost_over == (Button *)e->character) { /* restore the lost focus */ e->renderState = stateOver; e->oldState = stateOver; ((Button *)e->character)->updateButtonState(e); movie->lost_over = NULL; movie->cur_focus = e; }}DisplayList::DisplayList(FlashMovie *movie){ list = NULL; this->movie = movie; bbox.reset(); isSprite = 0;}DisplayList::~DisplayList(){ clearList();}voidDisplayList::clearList(){ DisplayListEntry *del, *e; for(e = list; e;) { updateBoundingBox(e); if (e->character->isButton()) { deleteButton(movie,e); } del = e; e = e->next; delete del; } list = 0;}DisplayListEntry *DisplayList::getList(){ return list;}static void bbox(Rect *rect, Matrix *m, long x1, long y1){ long x,y; x = m->getX(x1,y1); y = m->getY(x1,y1); if (x < rect->xmin) rect->xmin = x; if (x > rect->xmax) rect->xmax = x; if (y < rect->ymin) rect->ymin = y; if (y > rect->ymax) rect->ymax = y;}// Update bb to include boundary, optional reset of bbvoid transformBoundingBox(Rect *bb, Matrix *matrix, Rect *boundary, int reset){ if (reset) { bb->reset(); } if (boundary->xmin != LONG_MAX && matrix != NULL) { bbox(bb, matrix, boundary->xmin, boundary->ymin); bbox(bb, matrix, boundary->xmax, boundary->ymin); bbox(bb, matrix, boundary->xmin, boundary->ymax); bbox(bb, matrix, boundary->xmax, boundary->ymax); }}voidDisplayList::placeObject(GraphicDevice *gd,Character *character, long depth, Matrix *matrix, Cxform *cxform, char *name){ DisplayListEntry *n,*e,*prev; n = new DisplayListEntry; if (n == NULL) return; n->depth = depth; n->matrix = matrix; n->cxform = cxform; n->character = character; n->instanceName = name; n->owner = this;#if 0 printf("Dl %lx: placeObject: depth=%d character=%d cxform=%p\n", this, n->depth,n->character ? n->character->getTagId() : 0, cxform);#endif if (character == 0 || matrix == 0 || cxform == 0) {//found character with the same TagID with n from list for (e = list; e; prev = e, e = e->next) { if (e->depth == n->depth) { if (character == 0) { n->character = e->character; } if (matrix == 0) { n->matrix = e->matrix; } if (cxform == 0) { n->cxform = e->cxform; } break; } } } if (n->character == 0) { // Not found !!! Should not happen // printf("PlaceObject cannot find character at depth %ld\n", n->depth); delete n; return; } prev = 0; for (e = list; e; prev = e, e = e->next) { if (e->depth == n->depth) { if (e->character->isButton()) { deleteButton(movie, e); } // Do update, object has moved or been resized updateBoundingBox(e); // Replace object e->depth = n->depth; e->matrix = n->matrix; e->cxform = n->cxform; e->character = n->character; /* if it is a button, we must update its state */ if (e->character->isButton()) { movie->buttons_updated = 1; addButton(movie, e); } updateBoundingBox(e); delete n; return; } if (e->depth > n->depth) break; } /* new object */ /* button instantiation */ if (n->character->isButton()) { n->renderState = stateUp; n->oldState = stateUp; ((Button *)n->character)->updateButtonState(n); addButton(movie,n); } updateBoundingBox(n); if (prev == 0) { // Object comes at first place n->next = list; list = n; } else { // Insert object n->next = prev->next; prev->next = n; }}Character *DisplayList::removeObject(GraphicDevice *gd,Character *character, long depth){ DisplayListEntry *e,*prev; // List should not be empty if (list == 0) return 0; #if 0 printf("removeObject: depth=%d character=%d\n", depth,character ? character->getTagId() : 0);#endif prev = 0; for (e = list; e; prev = e, e = e->next) { if (e->depth == depth) { if (prev) { prev->next = e->next; } else { list = e->next; } if (character == 0) { character = e->character; } if (e->character->isButton()) { deleteButton(movie, e); } if (e->character->isSprite()) { ((Sprite*)e->character)->reset(); } updateBoundingBox(e); delete e; return character; } } return 0; // Should not happen}voidDisplayList::updateBoundingBox(DisplayListEntry *e){ Rect rect; //rect.reset(); e->character->getBoundingBox(&rect,e); transformBoundingBox(&this->bbox, e->matrix, &rect, 0);}intDisplayList::updateSprites(){ Sprite *sprite; DisplayListEntry *e; int refresh = 0; for (e = this->list; e != NULL; e = e->next) { if (e->character->isButton() && e->buttonCharacter) { if (e->buttonCharacter->isSprite()) { Matrix mat; sprite = (Sprite *)e->buttonCharacter; refresh |= sprite->program->dl->updateSprites(); refresh |= sprite->program->nestedMovie(this->movie->gd,this->movie->sm, e->matrix, e->cxform); mat = (*e->matrix) * e->buttonMatrix; transformBoundingBox(&this->bbox, &mat, &(sprite->program->dl->bbox), 0); } } if (e->character->isSprite()) { sprite = (Sprite *)e->character; refresh |= sprite->program->dl->updateSprites(); refresh |= sprite->program->nestedMovie(this->movie->gd,this->movie->sm, e->matrix, e->cxform); transformBoundingBox(&this->bbox, e->matrix, &(sprite->program->dl->bbox), 0); } } return refresh;}/* Function can return either 0,1 or 2 0: Nothing match, continue 1: Something matches, but continue searching 2: Something matches, but stop searching*/static int exploreButtons1(Program *prg, void *opaque, ExploreButtonFunc func){ DisplayListEntry *e; int ret, ret2 = 0; for(e=prg->dl->list; e != NULL; e = e->next) { if (e->character == NULL) continue; if (e->character->isButton()) { ret = func(opaque,prg,e); if (ret == 2) return ret; // Func asks to return at once !!! if (ret) ret2 = 1; } if (e->character->isSprite()) { ret = exploreButtons1(((Sprite *)e->character)->program, opaque,func); if (ret == 2) return ret; // Func asks to return at once !!! if (ret) ret2 = 1; } } return ret2;}int exploreButtons(FlashMovie *movie, void *opaque, ExploreButtonFunc func){ CInputScript *script; int ret; script = movie->main; while (script != NULL) { if (script->program) { ret = exploreButtons1(script->program, opaque, func); if (ret) return ret; } script = script->next; } return 0;}typedef struct { long x,y; int hit; DisplayListEntry *bhit;} HitTable;static void button_hit_func(void *id, long y, long start, long end){ HitTable *h = (HitTable *) id;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -