Diffstat (limited to 'core/multimedia/opieplayer/libflash/displaylist.cc') (more/less context) (show whitespace changes)
-rw-r--r-- | core/multimedia/opieplayer/libflash/displaylist.cc | 708 |
1 files changed, 708 insertions, 0 deletions
diff --git a/core/multimedia/opieplayer/libflash/displaylist.cc b/core/multimedia/opieplayer/libflash/displaylist.cc new file mode 100644 index 0000000..d71cfb7 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/displaylist.cc | |||
@@ -0,0 +1,708 @@ | |||
1 | //////////////////////////////////////////////////////////// | ||
2 | // Flash Plugin and Player | ||
3 | // Copyright (C) 1998,1999 Olivier Debon | ||
4 | // | ||
5 | // This program is free software; you can redistribute it and/or | ||
6 | // modify it under the terms of the GNU General Public License | ||
7 | // as published by the Free Software Foundation; either version 2 | ||
8 | // of the License, or (at your option) any later version. | ||
9 | // | ||
10 | // This program is distributed in the hope that it will be useful, | ||
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | // GNU General Public License for more details. | ||
14 | // | ||
15 | // You should have received a copy of the GNU General Public License | ||
16 | // along with this program; if not, write to the Free Software | ||
17 | // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
18 | // | ||
19 | /////////////////////////////////////////////////////////////// | ||
20 | // Author : Olivier Debon <odebon@club-internet.fr> | ||
21 | // | ||
22 | |||
23 | #include "swf.h" | ||
24 | |||
25 | #ifdef RCSID | ||
26 | static char *rcsid = "$Id$"; | ||
27 | #endif | ||
28 | |||
29 | #define PRINT 0 | ||
30 | |||
31 | void deleteButton(FlashMovie *movie, DisplayListEntry *e) | ||
32 | { | ||
33 | /* save the focus */ | ||
34 | if (movie->mouse_active == 0 && e->renderState == stateOver) { | ||
35 | movie->lost_over = (Button *)e->character; | ||
36 | movie->cur_focus = NULL; | ||
37 | } | ||
38 | |||
39 | if (e == movie->cur_focus) { | ||
40 | movie->cur_focus = NULL; | ||
41 | } | ||
42 | } | ||
43 | |||
44 | void addButton(FlashMovie *movie, DisplayListEntry *e) | ||
45 | { | ||
46 | if (movie->mouse_active == 0 && | ||
47 | movie->cur_focus == NULL && | ||
48 | movie->lost_over == (Button *)e->character) { | ||
49 | /* restore the lost focus */ | ||
50 | e->renderState = stateOver; | ||
51 | e->oldState = stateOver; | ||
52 | ((Button *)e->character)->updateButtonState(e); | ||
53 | movie->lost_over = NULL; | ||
54 | movie->cur_focus = e; | ||
55 | } | ||
56 | } | ||
57 | |||
58 | DisplayList::DisplayList(FlashMovie *movie) | ||
59 | { | ||
60 | list = NULL; | ||
61 | this->movie = movie; | ||
62 | bbox.reset(); | ||
63 | isSprite = 0; | ||
64 | } | ||
65 | |||
66 | DisplayList::~DisplayList() | ||
67 | { | ||
68 | clearList(); | ||
69 | } | ||
70 | |||
71 | void | ||
72 | DisplayList::clearList() | ||
73 | { | ||
74 | DisplayListEntry *del, *e; | ||
75 | |||
76 | for(e = list; e;) | ||
77 | { | ||
78 | updateBoundingBox(e); | ||
79 | if (e->character->isButton()) { | ||
80 | deleteButton(movie,e); | ||
81 | } | ||
82 | del = e; | ||
83 | e = e->next; | ||
84 | delete del; | ||
85 | } | ||
86 | list = 0; | ||
87 | } | ||
88 | |||
89 | DisplayListEntry * | ||
90 | DisplayList::getList() | ||
91 | { | ||
92 | return list; | ||
93 | } | ||
94 | |||
95 | static void bbox(Rect *rect, Matrix *m, long x1, long y1) | ||
96 | { | ||
97 | long x,y; | ||
98 | |||
99 | x = m->getX(x1,y1); | ||
100 | y = m->getY(x1,y1); | ||
101 | if (x < rect->xmin) rect->xmin = x; | ||
102 | if (x > rect->xmax) rect->xmax = x; | ||
103 | if (y < rect->ymin) rect->ymin = y; | ||
104 | if (y > rect->ymax) rect->ymax = y; | ||
105 | } | ||
106 | |||
107 | // Update bb to include boundary, optional reset of bb | ||
108 | void transformBoundingBox(Rect *bb, Matrix *matrix, Rect *boundary, int reset) | ||
109 | { | ||
110 | if (reset) { | ||
111 | bb->reset(); | ||
112 | } | ||
113 | |||
114 | if (boundary->xmin != LONG_MAX) { | ||
115 | bbox(bb, matrix, boundary->xmin, boundary->ymin); | ||
116 | bbox(bb, matrix, boundary->xmax, boundary->ymin); | ||
117 | bbox(bb, matrix, boundary->xmin, boundary->ymax); | ||
118 | bbox(bb, matrix, boundary->xmax, boundary->ymax); | ||
119 | } | ||
120 | } | ||
121 | |||
122 | void | ||
123 | DisplayList::placeObject(GraphicDevice *gd,Character *character, long depth, Matrix *matrix, Cxform *cxform, char *name) | ||
124 | { | ||
125 | DisplayListEntry *n,*e,*prev; | ||
126 | |||
127 | n = new DisplayListEntry; | ||
128 | if (n == NULL) return; | ||
129 | |||
130 | n->depth = depth; | ||
131 | n->matrix = matrix; | ||
132 | n->cxform = cxform; | ||
133 | n->character = character; | ||
134 | n->instanceName = name; | ||
135 | n->owner = this; | ||
136 | |||
137 | #if 0 | ||
138 | printf("Dl %lx: placeObject: depth=%d character=%d cxform=%p\n", | ||
139 | this, n->depth,n->character ? n->character->getTagId() : 0, cxform); | ||
140 | #endif | ||
141 | |||
142 | if (character == 0 || matrix == 0 || cxform == 0) { | ||
143 | for (e = list; e; prev = e, e = e->next) { | ||
144 | if (e->depth == n->depth) { | ||
145 | if (character == 0) { | ||
146 | n->character = e->character; | ||
147 | } | ||
148 | if (matrix == 0) { | ||
149 | n->matrix = e->matrix; | ||
150 | } | ||
151 | if (cxform == 0) { | ||
152 | n->cxform = e->cxform; | ||
153 | } | ||
154 | break; | ||
155 | } | ||
156 | } | ||
157 | } | ||
158 | |||
159 | if (n->character == 0) { | ||
160 | // Not found !!! Should not happen | ||
161 | // printf("PlaceObject cannot find character at depth %ld\n", n->depth); | ||
162 | delete n; | ||
163 | return; | ||
164 | } | ||
165 | |||
166 | prev = 0; | ||
167 | for (e = list; e; prev = e, e = e->next) | ||
168 | { | ||
169 | if (e->depth == n->depth) { | ||
170 | if (e->character->isButton()) { | ||
171 | deleteButton(movie, e); | ||
172 | } | ||
173 | |||
174 | // Do update, object has moved or been resized | ||
175 | updateBoundingBox(e); | ||
176 | |||
177 | // Replace object | ||
178 | e->depth = n->depth; | ||
179 | e->matrix = n->matrix; | ||
180 | e->cxform = n->cxform; | ||
181 | e->character = n->character; | ||
182 | /* if it is a button, we must update its state */ | ||
183 | if (e->character->isButton()) { | ||
184 | movie->buttons_updated = 1; | ||
185 | addButton(movie, e); | ||
186 | } | ||
187 | |||
188 | updateBoundingBox(e); | ||
189 | |||
190 | delete n; | ||
191 | return; | ||
192 | } | ||
193 | if (e->depth > n->depth) break; | ||
194 | } | ||
195 | /* new object */ | ||
196 | |||
197 | /* button instantiation */ | ||
198 | if (n->character->isButton()) { | ||
199 | n->renderState = stateUp; | ||
200 | n->oldState = stateUp; | ||
201 | ((Button *)n->character)->updateButtonState(n); | ||
202 | addButton(movie,n); | ||
203 | } | ||
204 | |||
205 | updateBoundingBox(n); | ||
206 | |||
207 | if (prev == 0) { | ||
208 | // Object comes at first place | ||
209 | n->next = list; | ||
210 | list = n; | ||
211 | } else { | ||
212 | // Insert object | ||
213 | n->next = prev->next; | ||
214 | prev->next = n; | ||
215 | } | ||
216 | } | ||
217 | |||
218 | |||
219 | Character * | ||
220 | DisplayList::removeObject(GraphicDevice *gd,Character *character, long depth) | ||
221 | { | ||
222 | DisplayListEntry *e,*prev; | ||
223 | |||
224 | // List should not be empty | ||
225 | if (list == 0) return 0; | ||
226 | |||
227 | #if 0 | ||
228 | printf("removeObject: depth=%d character=%d\n", | ||
229 | depth,character ? character->getTagId() : 0); | ||
230 | #endif | ||
231 | |||
232 | prev = 0; | ||
233 | for (e = list; e; prev = e, e = e->next) { | ||
234 | if (e->depth == depth) { | ||
235 | if (prev) { | ||
236 | prev->next = e->next; | ||
237 | } else { | ||
238 | list = e->next; | ||
239 | } | ||
240 | if (character == 0) { | ||
241 | character = e->character; | ||
242 | } | ||
243 | if (e->character->isButton()) { | ||
244 | deleteButton(movie, e); | ||
245 | } | ||
246 | if (e->character->isSprite()) { | ||
247 | ((Sprite*)e->character)->reset(); | ||
248 | } | ||
249 | |||
250 | updateBoundingBox(e); | ||
251 | |||
252 | delete e; | ||
253 | return character; | ||
254 | } | ||
255 | } | ||
256 | return 0;// Should not happen | ||
257 | } | ||
258 | |||
259 | void | ||
260 | DisplayList::updateBoundingBox(DisplayListEntry *e) | ||
261 | { | ||
262 | Rect rect; | ||
263 | |||
264 | //rect.reset(); | ||
265 | e->character->getBoundingBox(&rect,e); | ||
266 | transformBoundingBox(&this->bbox, e->matrix, &rect, 0); | ||
267 | } | ||
268 | |||
269 | int | ||
270 | DisplayList::updateSprites() | ||
271 | { | ||
272 | Sprite *sprite; | ||
273 | DisplayListEntry *e; | ||
274 | int refresh = 0; | ||
275 | |||
276 | for (e = this->list; e != NULL; e = e->next) { | ||
277 | if (e->character->isButton() && e->buttonCharacter) { | ||
278 | if (e->buttonCharacter->isSprite()) { | ||
279 | Matrix mat; | ||
280 | |||
281 | sprite = (Sprite *)e->buttonCharacter; | ||
282 | refresh |= sprite->program->dl->updateSprites(); | ||
283 | refresh |= sprite->program->nestedMovie(this->movie->gd,this->movie->sm, e->matrix, e->cxform); | ||
284 | mat = (*e->matrix) * e->buttonMatrix; | ||
285 | transformBoundingBox(&this->bbox, &mat, | ||
286 | &(sprite->program->dl->bbox), | ||
287 | 0); | ||
288 | } | ||
289 | } | ||
290 | if (e->character->isSprite()) { | ||
291 | sprite = (Sprite *)e->character; | ||
292 | refresh |= sprite->program->dl->updateSprites(); | ||
293 | refresh |= sprite->program->nestedMovie(this->movie->gd,this->movie->sm, e->matrix, e->cxform); | ||
294 | transformBoundingBox(&this->bbox, e->matrix, | ||
295 | &(sprite->program->dl->bbox), | ||
296 | 0); | ||
297 | } | ||
298 | } | ||
299 | return refresh; | ||
300 | } | ||
301 | |||
302 | /* Function can return either 0,1 or 2 | ||
303 | 0: Nothing match, continue | ||
304 | 1: Something matches, but continue searching | ||
305 | 2: Something matches, but stop searching | ||
306 | */ | ||
307 | |||
308 | static int exploreButtons1(Program *prg, void *opaque, | ||
309 | ExploreButtonFunc func) | ||
310 | { | ||
311 | DisplayListEntry *e; | ||
312 | int ret, ret2 = 0; | ||
313 | |||
314 | for(e=prg->dl->list; e != NULL; e = e->next) { | ||
315 | if (e->character == NULL) continue; | ||
316 | if (e->character->isButton()) { | ||
317 | ret = func(opaque,prg,e); | ||
318 | if (ret == 2) return ret;// Func asks to return at once !!! | ||
319 | if (ret) ret2 = 1; | ||
320 | } | ||
321 | if (e->character->isSprite()) { | ||
322 | ret = exploreButtons1(((Sprite *)e->character)->program, | ||
323 | opaque,func); | ||
324 | if (ret == 2) return ret;// Func asks to return at once !!! | ||
325 | if (ret) ret2 = 1; | ||
326 | } | ||
327 | } | ||
328 | return ret2; | ||
329 | } | ||
330 | |||
331 | int exploreButtons(FlashMovie *movie, void *opaque, ExploreButtonFunc func) | ||
332 | { | ||
333 | CInputScript *script; | ||
334 | int ret; | ||
335 | |||
336 | script = movie->main; | ||
337 | while (script != NULL) { | ||
338 | if (script->program) { | ||
339 | ret = exploreButtons1(script->program, opaque, func); | ||
340 | if (ret) return ret; | ||
341 | } | ||
342 | script = script->next; | ||
343 | } | ||
344 | return 0; | ||
345 | } | ||
346 | |||
347 | typedef struct { | ||
348 | long x,y; | ||
349 | int hit; | ||
350 | DisplayListEntry *bhit; | ||
351 | } HitTable; | ||
352 | |||
353 | static void button_hit_func(void *id, long y, long start, long end) | ||
354 | { | ||
355 | HitTable *h = (HitTable *) id; | ||
356 | if ( y == h->y && (h->x >= start && h->x < end) ) | ||
357 | h->hit = 1; | ||
358 | } | ||
359 | |||
360 | typedef struct { | ||
361 | FlashMovie *movie; | ||
362 | DisplayListEntry *bhit; | ||
363 | } ButtonHit; | ||
364 | |||
365 | static int button_hit(void *opaque, Program *prg, DisplayListEntry *e) | ||
366 | { | ||
367 | ButtonHit *h = (ButtonHit *) opaque; | ||
368 | HitTable hit_table; | ||
369 | FlashMovie *movie = h->movie; | ||
370 | Rect bb,boundary; | ||
371 | Matrix mat; | ||
372 | ButtonState save; | ||
373 | |||
374 | hit_table.x = movie->mouse_x; | ||
375 | hit_table.y = movie->mouse_y / FRAC; | ||
376 | hit_table.hit = 0; | ||
377 | |||
378 | // Compute the bounding box in screen coordinates | ||
379 | save = e->renderState; | ||
380 | e->renderState = stateHitTest; | ||
381 | e->character->getBoundingBox(&boundary,e); | ||
382 | e->renderState = save; | ||
383 | mat = (*movie->gd->adjust) * e->renderMatrix; | ||
384 | transformBoundingBox(&bb, &mat, &boundary, 1); | ||
385 | // Check if mouse is within bb | ||
386 | if (movie->mouse_x < bb.xmin) return 0; | ||
387 | if (movie->mouse_x > bb.xmax) return 0; | ||
388 | if (movie->mouse_y < bb.ymin) return 0; | ||
389 | if (movie->mouse_y > bb.ymax) return 0; | ||
390 | |||
391 | e->character->getRegion(movie->gd, &e->renderMatrix, | ||
392 | &hit_table, button_hit_func); | ||
393 | |||
394 | if (hit_table.hit) { | ||
395 | h->bhit = e; | ||
396 | return 1; | ||
397 | } else { | ||
398 | return 0; | ||
399 | } | ||
400 | } | ||
401 | |||
402 | static int button_reset(void *opaque, Program *prg, DisplayListEntry *e) | ||
403 | { | ||
404 | if (e->renderState != stateUp) { | ||
405 | e->owner->updateBoundingBox(e); | ||
406 | e->oldState = e->renderState; | ||
407 | e->renderState = stateUp; | ||
408 | ((Button *)e->character)->updateButtonState(e); | ||
409 | e->owner->updateBoundingBox(e); | ||
410 | } | ||
411 | return 0; | ||
412 | } | ||
413 | |||
414 | /* update the button states according to the current mouse state & return the list of actions */ | ||
415 | void | ||
416 | DisplayList::updateButtons(FlashMovie *movie) | ||
417 | { | ||
418 | DisplayListEntry *bhit; | ||
419 | ButtonHit h; | ||
420 | |||
421 | if (movie->mouse_active) { | ||
422 | |||
423 | h.bhit = NULL; | ||
424 | h.movie = movie; | ||
425 | |||
426 | exploreButtons(movie, &h, button_hit); | ||
427 | |||
428 | bhit = h.bhit; | ||
429 | |||
430 | /* set every button to not hit */ | ||
431 | exploreButtons(movie, NULL, button_reset); | ||
432 | |||
433 | if (bhit) { | ||
434 | ButtonState state; | ||
435 | |||
436 | if (movie->button_pressed) { | ||
437 | state = stateDown; | ||
438 | } else { | ||
439 | state = stateOver; | ||
440 | } | ||
441 | if (state != bhit->renderState) { | ||
442 | bhit->owner->updateBoundingBox(bhit); | ||
443 | bhit->renderState = state; | ||
444 | ((Button *)bhit->character)->updateButtonState(bhit); | ||
445 | bhit->owner->updateBoundingBox(bhit); | ||
446 | movie->cur_focus = bhit; | ||
447 | if (movie->cursorOnOff) | ||
448 | movie->cursorOnOff(1,movie->cursorOnOffClientData); | ||
449 | } | ||
450 | } else { | ||
451 | if (movie->cursorOnOff) | ||
452 | movie->cursorOnOff(0,movie->cursorOnOffClientData); | ||
453 | } | ||
454 | } | ||
455 | } | ||
456 | |||
457 | typedef struct { | ||
458 | ActionRecord *action;// Action to do | ||
459 | Program *prg; // Context program | ||
460 | } ButtonAction; | ||
461 | |||
462 | static int button_action(void *opaque, Program *prg, DisplayListEntry *e) | ||
463 | { | ||
464 | ButtonAction *h = (ButtonAction *)opaque; | ||
465 | static ActionRecord actionRefresh; | ||
466 | static ActionRecord soundFx; | ||
467 | Button *b; | ||
468 | ActionRecord **paction; | ||
469 | int n; | ||
470 | |||
471 | actionRefresh.action = ActionRefresh; | ||
472 | actionRefresh.next = 0; | ||
473 | |||
474 | soundFx.action = ActionPlaySound; | ||
475 | soundFx.next = &actionRefresh; | ||
476 | |||
477 | b = (Button *)e->character; | ||
478 | |||
479 | if (e->oldState != e->renderState) { | ||
480 | |||
481 | paction = &actionRefresh.next; | ||
482 | |||
483 | if (b->conditionList) { | ||
484 | *paction = b->getActionFromTransition(e->renderState, e->oldState); | ||
485 | } else if (e->renderState == stateDown) { | ||
486 | /* if the button is pressed and | ||
487 | no condition list is defined*/ | ||
488 | *paction = b->actionRecords; | ||
489 | } | ||
490 | |||
491 | switch(e->renderState) { | ||
492 | case stateUp: | ||
493 | n = 0; | ||
494 | break; | ||
495 | case stateOver: | ||
496 | n = 1; | ||
497 | break; | ||
498 | default: | ||
499 | /* case stateDown: */ | ||
500 | n = 2; | ||
501 | break; | ||
502 | } | ||
503 | |||
504 | if (b->sound[n]) { | ||
505 | soundFx.sound = b->sound[n]; | ||
506 | h->action = &soundFx; | ||
507 | } else { | ||
508 | h->action = &actionRefresh; | ||
509 | } | ||
510 | |||
511 | e->oldState = e->renderState; | ||
512 | |||
513 | h->prg = prg; | ||
514 | return 2; | ||
515 | } | ||
516 | h->action = 0;// Nothing to do about this | ||
517 | return 0; | ||
518 | } | ||
519 | |||
520 | int computeActions(FlashMovie *movie, Program **prg, ActionRecord **ar) | ||
521 | { | ||
522 | ButtonAction h; | ||
523 | |||
524 | h.action = NULL; | ||
525 | exploreButtons(movie, &h, button_action); | ||
526 | if (h.action) { | ||
527 | *prg = h.prg; | ||
528 | *ar = h.action; | ||
529 | return 1; | ||
530 | } | ||
531 | return 0; | ||
532 | } | ||
533 | |||
534 | #define FOCUS_ZOOM 1.5 | ||
535 | /* in pixels */ | ||
536 | #define FOCUS_SIZE_MIN 50 | ||
537 | #define FOCUS_TRANSLATE 15 | ||
538 | |||
539 | int | ||
540 | DisplayList::render(GraphicDevice *gd, Matrix *render_matrix, Cxform *cxform) | ||
541 | { | ||
542 | DisplayListEntry *e,*cur_focus; | ||
543 | int sprite = 0; | ||
544 | long n = 0; | ||
545 | Cxform cxf,*cxf1; | ||
546 | Rect bb,boundary; | ||
547 | |||
548 | cur_focus = NULL; | ||
549 | |||
550 | /* | ||
551 | if (isSprite == 0) { | ||
552 | if (this->bbox.xmin == LONG_MAX) return 0; | ||
553 | gd->updateClippingRegion(&this->bbox, render_matrix); | ||
554 | gd->clearCanvas(); | ||
555 | } | ||
556 | */ | ||
557 | |||
558 | for (e = list; e; e = e->next) | ||
559 | { | ||
560 | #if PRINT | ||
561 | printf("Character %3d @ %3d\n", e->character ? e->character->getTagId() : 0, e->depth); | ||
562 | #endif | ||
563 | if (e->character) { | ||
564 | Matrix mat; | ||
565 | |||
566 | if (render_matrix) { | ||
567 | mat = *render_matrix; | ||
568 | } | ||
569 | |||
570 | if (e->matrix) { | ||
571 | mat = mat * (*e->matrix); | ||
572 | } | ||
573 | |||
574 | /* fast clipping */ | ||
575 | // If object boundaries are outside current clip region give up with rendering | ||
576 | e->character->getBoundingBox(&boundary,e); | ||
577 | if (boundary.xmin != LONG_MAX) { | ||
578 | Matrix tmat; | ||
579 | |||
580 | tmat = (*gd->adjust) * mat; | ||
581 | transformBoundingBox(&bb, &tmat, &boundary, 1); | ||
582 | |||
583 | bb.xmin = bb.xmin >> FRAC_BITS; | ||
584 | bb.ymin = bb.ymin >> FRAC_BITS; | ||
585 | bb.xmax = (bb.xmax + FRAC - 1) >> FRAC_BITS; | ||
586 | bb.ymax = (bb.ymax + FRAC - 1) >> FRAC_BITS; | ||
587 | |||
588 | if (bb.xmin >= gd->clip_rect.xmax || | ||
589 | bb.xmax <= gd->clip_rect.xmin || | ||
590 | bb.ymin >= gd->clip_rect.ymax || | ||
591 | bb.ymax <= gd->clip_rect.ymin) { | ||
592 | continue; | ||
593 | } | ||
594 | } | ||
595 | |||
596 | if (cxform == NULL) { | ||
597 | cxf1 = e->cxform; | ||
598 | } | ||
599 | else if (e->cxform == NULL) { | ||
600 | cxf1 = cxform; | ||
601 | } | ||
602 | else { | ||
603 | cxf1 = &cxf; | ||
604 | cxf.ra = cxform->ra * e->cxform->ra; | ||
605 | cxf.ga = cxform->ga * e->cxform->ga; | ||
606 | cxf.ba = cxform->ba * e->cxform->ba; | ||
607 | cxf.aa = cxform->aa * e->cxform->aa; | ||
608 | |||
609 | cxf.rb = (long)(cxform->ra * e->cxform->rb + cxform->rb); | ||
610 | cxf.gb = (long)(cxform->ga * e->cxform->gb + cxform->gb); | ||
611 | cxf.bb = (long)(cxform->ba * e->cxform->bb + cxform->bb); | ||
612 | cxf.ab = (long)(cxform->aa * e->cxform->ab + cxform->ab); | ||
613 | } | ||
614 | |||
615 | if (e->character->isButton()) { | ||
616 | Button *b = (Button *) e->character; | ||
617 | |||
618 | e->renderMatrix = mat; | ||
619 | |||
620 | if (e->renderState != stateUp && movie->mouse_active == 0) { | ||
621 | cur_focus = e; | ||
622 | ((Button *)e->character)->updateButtonState(e); | ||
623 | } | ||
624 | |||
625 | if (b->execute(gd, &mat, cxf1, e->renderState)) { | ||
626 | sprite = 1; | ||
627 | } | ||
628 | } else { | ||
629 | if (e->character->execute(gd, &mat, cxf1)) { | ||
630 | sprite = 1; | ||
631 | } | ||
632 | } | ||
633 | |||
634 | n++; | ||
635 | } | ||
636 | } | ||
637 | |||
638 | #if 0 | ||
639 | { | ||
640 | /* display the bounding box (debug) */ | ||
641 | Matrix tmat; | ||
642 | long x1,x2,y1,y2; | ||
643 | Color white; | ||
644 | |||
645 | white.red = 255; | ||
646 | white.green = white.blue = 0; | ||
647 | gd->setForegroundColor(white); | ||
648 | |||
649 | if (render_matrix) { | ||
650 | tmat = (*gd->adjust) * (*render_matrix); | ||
651 | } else { | ||
652 | tmat = *gd->adjust; | ||
653 | } | ||
654 | x1 = bbox.xmin; | ||
655 | y1 = bbox.ymin; | ||
656 | x2 = bbox.xmax; | ||
657 | y2 = bbox.ymax; | ||
658 | gd->drawLine(tmat.getX(x1,y1),tmat.getY(x1,y1),tmat.getX(x2,y1),tmat.getY(x2,y1),10*FRAC); | ||
659 | gd->drawLine(tmat.getX(x2,y1),tmat.getY(x2,y1),tmat.getX(x2,y2),tmat.getY(x2,y2),10*FRAC); | ||
660 | gd->drawLine(tmat.getX(x2,y2),tmat.getY(x2,y2),tmat.getX(x1,y2),tmat.getY(x1,y2),10*FRAC); | ||
661 | gd->drawLine(tmat.getX(x1,y2),tmat.getY(x1,y2),tmat.getX(x1,y1),tmat.getY(x1,y1),10*FRAC); | ||
662 | bbox.print(); | ||
663 | } | ||
664 | #endif | ||
665 | |||
666 | // Reset clipping zone | ||
667 | bbox.reset(); | ||
668 | |||
669 | return sprite; | ||
670 | } | ||
671 | |||
672 | void | ||
673 | DisplayList::getBoundary(Rect *bb) | ||
674 | { | ||
675 | DisplayListEntry *e; | ||
676 | Rect boundary; | ||
677 | |||
678 | bb->reset(); | ||
679 | for (e = list; e; e = e->next) | ||
680 | { | ||
681 | if (e->character) { | ||
682 | e->character->getBoundingBox(&boundary,e); | ||
683 | transformBoundingBox(bb, e->matrix, &boundary, 0); | ||
684 | } | ||
685 | } | ||
686 | } | ||
687 | |||
688 | extern "C" { | ||
689 | |||
690 | void dump_buttons(FlashHandle flashHandle) | ||
691 | { | ||
692 | #if 0 | ||
693 | Rect rect; | ||
694 | DisplayListEntry *e; | ||
695 | FlashMovie *movie; | ||
696 | |||
697 | movie = (FlashMovie *)flashHandle; | ||
698 | |||
699 | for (e = movie->first_button; e; e = e->next_button) { | ||
700 | computeBBox(movie,&rect,e); | ||
701 | printf("button: id=%d pos=%d %d %d %d\n", | ||
702 | e->character->getTagId(), | ||
703 | rect.xmin, rect.ymin, rect.xmax, rect.ymax); | ||
704 | } | ||
705 | #endif | ||
706 | } | ||
707 | |||
708 | } | ||