Mercurial > MadButterfly
comparison src/redraw_man.c @ 1067:7b4e80ab671a openvg
merge from default branch
author | Thinker K.F. Li <thinker@codemud.net> |
---|---|
date | Wed, 01 Dec 2010 12:25:56 +0800 |
parents | b42d69ab8857 a8d20bc8ce40 |
children | d09f603438d8 |
comparison
equal
deleted
inserted
replaced
630:bd18951b51d5 | 1067:7b4e80ab671a |
---|---|
1 // -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 4; -*- | |
2 // vim: sw=4:ts=8:sts=4 | |
1 #include <stdio.h> | 3 #include <stdio.h> |
2 #include <stdlib.h> | 4 #include <stdlib.h> |
3 #include <string.h> | 5 #include <string.h> |
4 #include <math.h> | 6 #include <math.h> |
5 #include "mb_graph_engine.h" | 7 #include "mb_graph_engine.h" |
156 * \section cache_area Area of cached coord | 158 * \section cache_area Area of cached coord |
157 * - *_transform of shapes works as normal | 159 * - *_transform of shapes works as normal |
158 * - areas of descendants of cached coord are in space defined | 160 * - areas of descendants of cached coord are in space defined |
159 * by aggr_matrix of cached coord. | 161 * by aggr_matrix of cached coord. |
160 * - descendants are marked with \ref COF_ANCESTOR_CACHE | 162 * - descendants are marked with \ref COF_ANCESTOR_CACHE |
161 * | 163 * |
162 * Since *_transform of shapes compute area with aggr_matrix that is | 164 * Since *_transform of shapes compute area with aggr_matrix that is |
163 * derived from aggr_matrix of a cached ancestor, area of | 165 * derived from aggr_matrix of a cached ancestor, area of |
164 * \ref COF_ANCESTOR_CACHE ones should be transformed to device space in | 166 * \ref COF_ANCESTOR_CACHE ones should be transformed to device space in |
165 * find_shape_at_pos() with following statement. | 167 * find_shape_at_pos() with following statement. |
166 * \code | 168 * \code |
235 * left-top of bounding box just at origin (0, 0) of canvas. It saves | 237 * left-top of bounding box just at origin (0, 0) of canvas. It saves |
236 * space to give a canvas just enough for rending descadants. The | 238 * space to give a canvas just enough for rending descadants. The |
237 * process of adjusting left-top of bounding box is zeroing. | 239 * process of adjusting left-top of bounding box is zeroing. |
238 * | 240 * |
239 * Following is rules. | 241 * Following is rules. |
240 * - zeroing on a cached coord is performed by adjust coord_t::aggr_matrix | 242 * - zeroing on a cached coord is performed by adjust coord_t::aggr_matrix |
241 * of the cached coord and descendnats. | 243 * of the cached coord and descendnats. |
242 * - Clean coords works just like before without change. | 244 * - Clean coords works just like before without change. |
243 * - in preorder | 245 * - in preorder |
244 * - never perform zeroing on root_coord. | 246 * - never perform zeroing on root_coord. |
245 * - do zeroing on cached coords marked with \ref COF_MUST_ZEROING. | 247 * - do zeroing on cached coords marked with \ref COF_MUST_ZEROING. |
300 | 302 |
301 #ifndef ASSERT | 303 #ifndef ASSERT |
302 #define ASSERT(x) | 304 #define ASSERT(x) |
303 #endif | 305 #endif |
304 | 306 |
307 /* | |
308 * Conitions for coords. | |
309 */ | |
310 #define coord_is_cached(co) ((co)->flags & COF_OWN_CANVAS) | |
311 #define coord_is_always_cached(co) ((co)->flags & COF_ALWAYS_CACHE) | |
312 #define coord_is_fast_cached(co) ((co)->flags & COF_FAST_MASK) | |
313 #define coord_is_precise_cached(co) ((co)->flags & COF_PRECISE_MASK) | |
314 #define coord_is_zeroing(co) ((co)->flags & COF_MUST_ZEROING) | |
315 #define coord_set_zeroing(co) \ | |
316 do { (co)->flags |= COF_MUST_ZEROING; } while(0) | |
317 #define coord_clear_zeroing(co) \ | |
318 do { (co)->flags &= ~COF_MUST_ZEROING; } while(0) | |
319 #define coord_set_flags(co, _flags) \ | |
320 do { (co)->flags |= (_flags); } while(0) | |
321 #define coord_get_parent(co) ((co)->parent) | |
322 #define coord_get_flags(co, _flags) ((co)->flags & (_flags)) | |
323 #define coord_clear_flags(co, _flags) \ | |
324 do { (co)->flags &= ~(_flags); } while(0) | |
325 | |
326 #define coord_get_pcache_area(coord) ((coord)->canvas_info->pcache_cur_area) | |
327 #define coord_get_pcache_last_area(coord) \ | |
328 ((coord)->canvas_info->pcache_last_area) | |
329 #define coord_get_cached(coord) ((coord)->canvas_info->owner) | |
330 #define _coord_get_dirty_areas(coord) (&(coord)->canvas_info->dirty_areas) | |
331 #define _coord_get_aggr_dirty_areas(coord) \ | |
332 ((coord)->canvas_info->aggr_dirty_areas) | |
333 #define coord_get_2pdev(coord) ((coord)->canvas_info->cache_2_pdev) | |
334 #define coord_get_2pdev_rev(coord) ((coord)->canvas_info->cache_2_pdev_rev) | |
335 #define coord_get_aggr2pdev(coord) ((coord)->canvas_info->aggr_2_pdev) | |
336 #define coord_get_aggr2pdev_rev(coord) ((coord)->canvas_info->aggr_2_pdev_rev) | |
337 | |
338 | |
305 /* NOTE: bounding box should also consider width of stroke. | 339 /* NOTE: bounding box should also consider width of stroke. |
306 */ | 340 */ |
307 | 341 |
308 #define sh_attach_geo(sh, g) \ | 342 #define sh_attach_geo(sh, g) \ |
309 do { \ | 343 do { \ |
334 | 368 |
335 extern void sh_dummy_transform(shape_t *shape); | 369 extern void sh_dummy_transform(shape_t *shape); |
336 extern void sh_dummy_fill(shape_t *, mbe_t *); | 370 extern void sh_dummy_fill(shape_t *, mbe_t *); |
337 #endif /* UNITTEST */ | 371 #endif /* UNITTEST */ |
338 | 372 |
339 static subject_t *ob_subject_alloc(ob_factory_t *factory); | 373 static subject_t *observer_subject_alloc(observer_factory_t *factory); |
340 static void ob_subject_free(ob_factory_t *factory, subject_t *subject); | 374 static void observer_subject_free(observer_factory_t *factory, |
341 static observer_t *ob_observer_alloc(ob_factory_t *factory); | 375 subject_t *subject); |
342 static void ob_observer_free(ob_factory_t *factory, observer_t *observer); | 376 static observer_t *observer_observer_alloc(observer_factory_t *factory); |
343 static subject_t *ob_get_parent_subject(ob_factory_t *factory, | 377 static void observer_observer_free(observer_factory_t *factory, |
344 subject_t *cur_subject); | 378 observer_t *observer); |
379 static subject_t *observer_get_parent_subject(observer_factory_t *factory, | |
380 subject_t *cur_subject); | |
345 /* Functions for children. */ | 381 /* Functions for children. */ |
346 #define FORCHILDREN(coord, child) \ | 382 #define FORCHILDREN(coord, child) \ |
347 for((child) = STAILQ_HEAD((coord)->children); \ | 383 for((child) = STAILQ_HEAD((coord)->children); \ |
348 (child) != NULL; \ | 384 (child) != NULL; \ |
349 (child) = STAILQ_NEXT(coord_t, sibling, (child))) | 385 (child) = STAILQ_NEXT(coord_t, sibling, (child))) |
454 return OK; | 490 return OK; |
455 } | 491 } |
456 | 492 |
457 static int add_dirty_area(redraw_man_t *rdman, coord_t *coord, area_t *area) { | 493 static int add_dirty_area(redraw_man_t *rdman, coord_t *coord, area_t *area) { |
458 int r; | 494 int r; |
459 | 495 |
460 if(area->w < 0.01 || area->h < 0.01) | 496 if(area->w < 0.01 || area->h < 0.01) |
461 return OK; | 497 return OK; |
462 | 498 |
463 rdman->n_dirty_areas++; | 499 rdman->n_dirty_areas++; |
464 r = areas_add(_coord_get_dirty_areas(coord), area); | 500 r = areas_add(_coord_get_dirty_areas(coord), area); |
465 return r == 0? OK: ERR; | 501 return r == 0? OK: ERR; |
466 } | 502 } |
467 | 503 |
470 ADD_DATA(coords, zeroing_coords, coord); | 506 ADD_DATA(coords, zeroing_coords, coord); |
471 return OK; | 507 return OK; |
472 } | 508 } |
473 | 509 |
474 static int add_dirty_pcache_area_coord(redraw_man_t *rdman, coord_t *coord) { | 510 static int add_dirty_pcache_area_coord(redraw_man_t *rdman, coord_t *coord) { |
475 coord_set_flags(coord, COF_DIRTY_PCACHE_AREA); | 511 if(!coord_get_flags(coord, COF_DIRTY_PCACHE_AREA)) { |
476 ADD_DATA(coords, dirty_pcache_area_coords, coord); | 512 coord_set_flags(coord, COF_DIRTY_PCACHE_AREA); |
513 ADD_DATA(coords, zeroing_coords, coord); | |
514 } | |
477 return OK; | 515 return OK; |
478 } | 516 } |
479 | 517 |
480 static int add_free_obj(redraw_man_t *rdman, void *obj, | 518 static int add_free_obj(redraw_man_t *rdman, void *obj, |
481 free_func_t free_func) { | 519 free_func_t free_func) { |
513 static void free_objs_destroy(redraw_man_t *rdman) { | 551 static void free_objs_destroy(redraw_man_t *rdman) { |
514 if(rdman->free_objs.objs != NULL) | 552 if(rdman->free_objs.objs != NULL) |
515 free(rdman->free_objs.objs); | 553 free(rdman->free_objs.objs); |
516 } | 554 } |
517 | 555 |
518 | 556 #ifdef UNITTEST |
557 /*! \brief This is only used for unittest. | |
558 */ | |
559 typedef struct { | |
560 co_aix parent_2_cache[6]; | |
561 int w, h; | |
562 } mock_mbe_t; | |
563 #endif | |
519 | 564 |
520 static mbe_t *canvas_new(int w, int h) { | 565 static mbe_t *canvas_new(int w, int h) { |
521 #ifndef UNITTEST | 566 #ifndef UNITTEST |
522 mbe_surface_t *surface; | 567 mbe_surface_t *surface; |
523 mbe_t *cr; | 568 mbe_t *cr; |
524 | 569 |
525 surface = mbe_image_surface_create(MB_IFMT_ARGB32, | 570 surface = mbe_image_surface_create(MB_IFMT_ARGB32, |
526 w, h); | 571 w, h); |
527 cr = mbe_create(surface); | 572 cr = mbe_create(surface); |
528 | 573 |
529 return cr; | 574 return cr; |
530 #else | 575 #else |
531 return NULL; | 576 mock_mbe_t *mbe; |
577 | |
578 mbe = malloc(sizeof(mock_mbe_t)); | |
579 mbe->w = w; | |
580 mbe->h = h; | |
581 | |
582 return (mbe_t *)mbe; | |
532 #endif | 583 #endif |
533 } | 584 } |
534 | 585 |
535 static void canvas_free(mbe_t *canvas) { | 586 static void canvas_free(mbe_t *canvas) { |
536 #ifndef UNITTEST | 587 #ifndef UNITTEST |
537 mbe_destroy(canvas); | 588 mbe_destroy(canvas); |
589 #else | |
590 free(canvas); | |
538 #endif | 591 #endif |
539 } | 592 } |
540 | 593 |
541 static void canvas_get_size(mbe_t *canvas, int *w, int *h) { | 594 static void canvas_get_size(mbe_t *canvas, int *w, int *h) { |
542 #ifndef UNITTEST | 595 #ifndef UNITTEST |
544 | 597 |
545 surface = mbe_get_target(canvas); | 598 surface = mbe_get_target(canvas); |
546 *w = mbe_image_surface_get_width(surface); | 599 *w = mbe_image_surface_get_width(surface); |
547 *h = mbe_image_surface_get_height(surface); | 600 *h = mbe_image_surface_get_height(surface); |
548 #else | 601 #else |
549 *w = 0; | 602 mock_mbe_t *mbe; |
550 *h = 0; | 603 |
604 mbe = (mock_mbe_t *)canvas; | |
605 *w = mbe->w; | |
606 *h = mbe->h; | |
551 #endif | 607 #endif |
552 } | 608 } |
553 | 609 |
554 static int geo_off_in_coord(geo_t *geo, coord_t *coord) { | 610 static int geo_off_in_coord(geo_t *geo, coord_t *coord) { |
555 int off = 0; | 611 int off = 0; |
582 | 638 |
583 RM_MEMBER(coord, geo); | 639 RM_MEMBER(coord, geo); |
584 coord->num_members--; | 640 coord->num_members--; |
585 } | 641 } |
586 | 642 |
587 static coord_canvas_info_t *coord_canvas_info_new(redraw_man_t *rdman, | 643 /*! \brief Create a new canvas and respective info struct for a coord. |
588 coord_t *coord, | 644 */ |
589 mbe_t *canvas) { | 645 static coord_canvas_info_t * |
646 coord_canvas_info_new(redraw_man_t *rdman, coord_t *coord, | |
647 mbe_t *canvas) { | |
590 coord_canvas_info_t *info; | 648 coord_canvas_info_t *info; |
649 static co_aix id[6] = {1, 0, 0, 0, 1, 0}; | |
591 | 650 |
592 info = (coord_canvas_info_t *)elmpool_elm_alloc(rdman->coord_canvas_pool); | 651 info = (coord_canvas_info_t *)elmpool_elm_alloc(rdman->coord_canvas_pool); |
593 if(info == NULL) | 652 if(info == NULL) |
594 return info; | 653 return info; |
595 | 654 |
596 info->owner = coord; | 655 info->owner = coord; |
597 info->canvas = canvas; | 656 info->canvas = canvas; |
598 DARRAY_INIT(&info->dirty_areas); | 657 DARRAY_INIT(&info->dirty_areas); |
599 | 658 |
600 bzero(info->pcache_areas, sizeof(area_t) * 2); | 659 bzero(info->pcache_areas, sizeof(area_t) * 2); |
601 info->pcache_cur_area = &info->pcache_areas[0]; | 660 info->pcache_cur_area = &info->pcache_areas[0]; |
602 info->pcache_last_area = &info->pcache_areas[1]; | 661 info->pcache_last_area = &info->pcache_areas[1]; |
662 memcpy(info->cache_2_pdev, id, sizeof(co_aix) * 6); | |
663 memcpy(info->cache_2_pdev_rev, id, sizeof(co_aix) * 6); | |
664 memcpy(info->aggr_2_pdev, id, sizeof(co_aix) * 6); | |
665 memcpy(info->aggr_2_pdev_rev, id, sizeof(co_aix) * 6); | |
603 | 666 |
604 return info; | 667 return info; |
605 } | 668 } |
606 | 669 |
607 static void coord_canvas_info_free(redraw_man_t *rdman, | 670 static void coord_canvas_info_free(redraw_man_t *rdman, |
613 static void mouse_event_root_dummy(event_t *evt, void *arg) { | 676 static void mouse_event_root_dummy(event_t *evt, void *arg) { |
614 } | 677 } |
615 | 678 |
616 int redraw_man_init(redraw_man_t *rdman, mbe_t *cr, mbe_t *backend) { | 679 int redraw_man_init(redraw_man_t *rdman, mbe_t *cr, mbe_t *backend) { |
617 extern void redraw_man_destroy(redraw_man_t *rdman); | 680 extern void redraw_man_destroy(redraw_man_t *rdman); |
681 extern int _sh_path_size; | |
682 extern int _sh_rect_size; | |
618 extern int _paint_color_size; | 683 extern int _paint_color_size; |
684 extern int _paint_linear_size; | |
685 extern int _paint_radial_size; | |
686 extern int _paint_image_size; | |
619 observer_t *addrm_ob; | 687 observer_t *addrm_ob; |
620 extern void addrm_monitor_hdlr(event_t *evt, void *arg); | 688 extern void addrm_monitor_hdlr(event_t *evt, void *arg); |
621 | 689 |
622 memset(rdman, 0, sizeof(redraw_man_t)); | 690 memset(rdman, 0, sizeof(redraw_man_t)); |
623 | 691 |
624 DARRAY_INIT(&rdman->dirty_coords); | 692 DARRAY_INIT(&rdman->dirty_coords); |
625 DARRAY_INIT(&rdman->dirty_pcache_area_coords); | |
626 DARRAY_INIT(&rdman->dirty_geos); | 693 DARRAY_INIT(&rdman->dirty_geos); |
627 DARRAY_INIT(&rdman->gen_geos); | 694 DARRAY_INIT(&rdman->gen_geos); |
628 DARRAY_INIT(&rdman->zeroing_coords); | 695 DARRAY_INIT(&rdman->zeroing_coords); |
629 | 696 |
630 rdman->geo_pool = elmpool_new(sizeof(geo_t), 128); | 697 rdman->geo_pool = elmpool_new(sizeof(geo_t), 128); |
631 rdman->coord_pool = elmpool_new(sizeof(coord_t), 16); | 698 rdman->coord_pool = elmpool_new(sizeof(coord_t), 16); |
632 rdman->shnode_pool = elmpool_new(sizeof(shnode_t), 16); | 699 rdman->shnode_pool = elmpool_new(sizeof(shnode_t), 16); |
700 rdman->sh_path_pool = elmpool_new(_sh_path_size, 16); | |
701 rdman->sh_rect_pool = elmpool_new(_sh_rect_size, 16); | |
633 rdman->observer_pool = elmpool_new(sizeof(observer_t), 32); | 702 rdman->observer_pool = elmpool_new(sizeof(observer_t), 32); |
634 rdman->subject_pool = elmpool_new(sizeof(subject_t), 32); | 703 rdman->subject_pool = elmpool_new(sizeof(subject_t), 32); |
635 rdman->paint_color_pool = elmpool_new(_paint_color_size, 64); | 704 rdman->paint_color_pool = elmpool_new(_paint_color_size, 64); |
705 rdman->paint_linear_pool = elmpool_new(_paint_linear_size, 64); | |
706 rdman->paint_radial_pool = elmpool_new(_paint_radial_size, 64); | |
707 rdman->paint_image_pool = elmpool_new(_paint_image_size, 64); | |
636 rdman->pent_pool = elmpool_new(sizeof(mb_prop_entry_t), 128); | 708 rdman->pent_pool = elmpool_new(sizeof(mb_prop_entry_t), 128); |
637 rdman->coord_canvas_pool = elmpool_new(sizeof(coord_canvas_info_t), 16); | 709 rdman->coord_canvas_pool = elmpool_new(sizeof(coord_canvas_info_t), 16); |
638 if(!(rdman->geo_pool && rdman->coord_pool && rdman->shnode_pool && | 710 if(!(rdman->geo_pool && rdman->coord_pool && rdman->shnode_pool && |
639 rdman->observer_pool && rdman->subject_pool && | 711 rdman->observer_pool && rdman->subject_pool && |
640 rdman->paint_color_pool && rdman->coord_canvas_pool)) | 712 rdman->paint_color_pool && rdman->coord_canvas_pool)) |
641 goto err; | 713 goto err; |
642 | 714 |
643 rdman->ob_factory.subject_alloc = ob_subject_alloc; | 715 rdman->observer_factory.subject_alloc = observer_subject_alloc; |
644 rdman->ob_factory.subject_free = ob_subject_free; | 716 rdman->observer_factory.subject_free = observer_subject_free; |
645 rdman->ob_factory.observer_alloc = ob_observer_alloc; | 717 rdman->observer_factory.observer_alloc = observer_observer_alloc; |
646 rdman->ob_factory.observer_free = ob_observer_free; | 718 rdman->observer_factory.observer_free = observer_observer_free; |
647 rdman->ob_factory.get_parent_subject = ob_get_parent_subject; | 719 rdman->observer_factory.get_parent_subject = observer_get_parent_subject; |
648 | 720 |
649 rdman->redraw = | 721 rdman->redraw = |
650 subject_new(&rdman->ob_factory, rdman, OBJT_RDMAN); | 722 subject_new(&rdman->observer_factory, rdman, OBJT_RDMAN); |
651 rdman->addrm_monitor = | 723 rdman->addrm_monitor = |
652 subject_new(&rdman->ob_factory, rdman, OBJT_RDMAN); | 724 subject_new(&rdman->observer_factory, rdman, OBJT_RDMAN); |
653 if(!(rdman->redraw && rdman->addrm_monitor)) | 725 if(!(rdman->redraw && rdman->addrm_monitor)) |
654 goto err; | 726 goto err; |
655 | 727 |
656 addrm_ob = subject_add_observer(rdman->addrm_monitor, | 728 addrm_ob = subject_add_observer(rdman->addrm_monitor, |
657 addrm_monitor_hdlr, rdman); | 729 addrm_monitor_hdlr, rdman); |
664 if(rdman->root_coord == NULL) | 736 if(rdman->root_coord == NULL) |
665 redraw_man_destroy(rdman); | 737 redraw_man_destroy(rdman); |
666 rdman->n_coords = 1; | 738 rdman->n_coords = 1; |
667 coord_init(rdman->root_coord, NULL); | 739 coord_init(rdman->root_coord, NULL); |
668 mb_prop_store_init(&rdman->root_coord->obj.props, rdman->pent_pool); | 740 mb_prop_store_init(&rdman->root_coord->obj.props, rdman->pent_pool); |
669 rdman->root_coord->mouse_event = subject_new(&rdman->ob_factory, | 741 rdman->root_coord->mouse_event = subject_new(&rdman->observer_factory, |
670 rdman->root_coord, | 742 rdman->root_coord, |
671 OBJT_COORD); | 743 OBJT_COORD); |
672 coord_set_flags(rdman->root_coord, COF_OWN_CANVAS); | 744 coord_set_flags(rdman->root_coord, COF_OWN_CANVAS); |
673 rdman->root_coord->canvas_info = | 745 rdman->root_coord->canvas_info = |
674 coord_canvas_info_new(rdman, rdman->root_coord, cr); | 746 coord_canvas_info_new(rdman, rdman->root_coord, cr); |
676 | 748 |
677 rdman->cr = cr; | 749 rdman->cr = cr; |
678 rdman->backend = backend; | 750 rdman->backend = backend; |
679 | 751 |
680 STAILQ_INIT(rdman->shapes); | 752 STAILQ_INIT(rdman->shapes); |
681 | 753 |
682 /* \note To make root coord always have at leat one observer. | 754 /* \note To make root coord always have at leat one observer. |
683 * It triggers mouse interpreter to be installed on root. | 755 * It triggers mouse interpreter to be installed on root. |
684 */ | 756 */ |
685 subject_set_monitor(rdman->root_coord->mouse_event, | 757 subject_set_monitor(rdman->root_coord->mouse_event, |
686 rdman->addrm_monitor); | 758 rdman->addrm_monitor); |
695 elmpool_free(rdman->geo_pool); | 767 elmpool_free(rdman->geo_pool); |
696 if(rdman->coord_pool) | 768 if(rdman->coord_pool) |
697 elmpool_free(rdman->coord_pool); | 769 elmpool_free(rdman->coord_pool); |
698 if(rdman->shnode_pool) | 770 if(rdman->shnode_pool) |
699 elmpool_free(rdman->shnode_pool); | 771 elmpool_free(rdman->shnode_pool); |
772 if(rdman->sh_path_pool) | |
773 elmpool_free(rdman->sh_path_pool); | |
774 if(rdman->sh_rect_pool) | |
775 elmpool_free(rdman->sh_rect_pool); | |
700 if(rdman->observer_pool) | 776 if(rdman->observer_pool) |
701 elmpool_free(rdman->observer_pool); | 777 elmpool_free(rdman->observer_pool); |
702 if(rdman->subject_pool) | 778 if(rdman->subject_pool) |
703 elmpool_free(rdman->subject_pool); | 779 elmpool_free(rdman->subject_pool); |
704 if(rdman->paint_color_pool) | 780 if(rdman->paint_color_pool) |
705 elmpool_free(rdman->paint_color_pool); | 781 elmpool_free(rdman->paint_color_pool); |
782 if(rdman->paint_linear_pool) | |
783 elmpool_free(rdman->paint_linear_pool); | |
784 if(rdman->paint_radial_pool) | |
785 elmpool_free(rdman->paint_radial_pool); | |
786 if(rdman->paint_image_pool) | |
787 elmpool_free(rdman->paint_image_pool); | |
706 if(rdman->pent_pool) | 788 if(rdman->pent_pool) |
707 elmpool_free(rdman->pent_pool); | 789 elmpool_free(rdman->pent_pool); |
708 if(rdman->coord_canvas_pool) | 790 if(rdman->coord_canvas_pool) |
709 elmpool_free(rdman->coord_canvas_pool); | 791 elmpool_free(rdman->coord_canvas_pool); |
710 DARRAY_DESTROY(&rdman->dirty_coords); | 792 DARRAY_DESTROY(&rdman->dirty_coords); |
711 DARRAY_DESTROY(&rdman->dirty_pcache_area_coords); | |
712 DARRAY_DESTROY(&rdman->dirty_geos); | 793 DARRAY_DESTROY(&rdman->dirty_geos); |
713 DARRAY_DESTROY(&rdman->gen_geos); | 794 DARRAY_DESTROY(&rdman->gen_geos); |
714 DARRAY_DESTROY(&rdman->zeroing_coords); | 795 DARRAY_DESTROY(&rdman->zeroing_coords); |
715 return ERR; | 796 return ERR; |
716 } | 797 } |
717 | 798 |
718 void redraw_man_destroy(redraw_man_t *rdman) { | 799 void redraw_man_destroy(redraw_man_t *rdman) { |
719 coord_t *coord, *saved_coord; | 800 coord_t *coord, *saved_coord; |
720 shape_t *shape, *saved_shape; | 801 shape_t *shape; |
721 geo_t *member; | 802 geo_t *member; |
722 | 803 |
723 mb_prop_store_destroy(&rdman->props); | 804 mb_prop_store_destroy(&rdman->props); |
724 | 805 |
725 free_free_objs(rdman); | 806 free_free_objs(rdman); |
727 | 808 |
728 /* Mark rdman clean that shapes and coords can be freed | 809 /* Mark rdman clean that shapes and coords can be freed |
729 * successfully. | 810 * successfully. |
730 */ | 811 */ |
731 DARRAY_CLEAN(&rdman->dirty_coords); | 812 DARRAY_CLEAN(&rdman->dirty_coords); |
732 DARRAY_CLEAN(&rdman->dirty_pcache_area_coords); | |
733 DARRAY_CLEAN(&rdman->dirty_geos); | 813 DARRAY_CLEAN(&rdman->dirty_geos); |
734 | 814 |
735 coord = postorder_coord_subtree(rdman->root_coord, NULL); | 815 coord = postorder_coord_subtree(rdman->root_coord, NULL); |
736 while(coord) { | 816 while(coord) { |
737 saved_coord = coord; | 817 saved_coord = coord; |
746 */ | 826 */ |
747 | 827 |
748 while((shape = STAILQ_HEAD(rdman->shapes)) != NULL) { | 828 while((shape = STAILQ_HEAD(rdman->shapes)) != NULL) { |
749 rdman_shape_free(rdman, shape); | 829 rdman_shape_free(rdman, shape); |
750 } | 830 } |
751 | 831 |
752 coord_canvas_info_free(rdman, rdman->root_coord->canvas_info); | 832 coord_canvas_info_free(rdman, rdman->root_coord->canvas_info); |
753 | 833 |
754 /* XXX: paints are not freed, here. All resources of paints would | 834 /* XXX: paints are not freed, here. All resources of paints would |
755 * be reclaimed by freeing elmpools. | 835 * be reclaimed by freeing elmpools. |
756 */ | 836 */ |
757 | 837 |
758 elmpool_free(rdman->coord_pool); | 838 elmpool_free(rdman->coord_pool); |
759 elmpool_free(rdman->geo_pool); | 839 elmpool_free(rdman->geo_pool); |
760 elmpool_free(rdman->shnode_pool); | 840 elmpool_free(rdman->shnode_pool); |
841 elmpool_free(rdman->sh_path_pool); | |
842 elmpool_free(rdman->sh_rect_pool); | |
761 elmpool_free(rdman->observer_pool); | 843 elmpool_free(rdman->observer_pool); |
762 elmpool_free(rdman->subject_pool); | 844 elmpool_free(rdman->subject_pool); |
763 elmpool_free(rdman->paint_color_pool); | 845 elmpool_free(rdman->paint_color_pool); |
846 elmpool_free(rdman->paint_linear_pool); | |
847 elmpool_free(rdman->paint_radial_pool); | |
848 elmpool_free(rdman->paint_image_pool); | |
764 elmpool_free(rdman->pent_pool); | 849 elmpool_free(rdman->pent_pool); |
765 elmpool_free(rdman->coord_canvas_pool); | 850 elmpool_free(rdman->coord_canvas_pool); |
766 | 851 |
767 DARRAY_DESTROY(&rdman->dirty_coords); | 852 DARRAY_DESTROY(&rdman->dirty_coords); |
768 DARRAY_DESTROY(&rdman->dirty_pcache_area_coords); | |
769 DARRAY_DESTROY(&rdman->dirty_geos); | 853 DARRAY_DESTROY(&rdman->dirty_geos); |
770 DARRAY_DESTROY(&rdman->gen_geos); | 854 DARRAY_DESTROY(&rdman->gen_geos); |
771 DARRAY_DESTROY(&rdman->zeroing_coords); | 855 DARRAY_DESTROY(&rdman->zeroing_coords); |
772 } | 856 } |
773 | 857 |
800 int r; | 884 int r; |
801 | 885 |
802 geo = elmpool_elm_alloc(rdman->geo_pool); | 886 geo = elmpool_elm_alloc(rdman->geo_pool); |
803 if(geo == NULL) | 887 if(geo == NULL) |
804 return ERR; | 888 return ERR; |
805 | 889 |
806 geo_init(geo); | 890 geo_init(geo); |
807 geo->mouse_event = subject_new(&rdman->ob_factory, geo, OBJT_GEO); | 891 geo->mouse_event = subject_new(&rdman->observer_factory, geo, OBJT_GEO); |
808 subject_set_monitor(geo->mouse_event, rdman->addrm_monitor); | 892 subject_set_monitor(geo->mouse_event, rdman->addrm_monitor); |
809 | 893 |
810 geo_attach_coord(geo, coord); | 894 geo_attach_coord(geo, coord); |
811 | 895 |
812 /* New one should be dirty to recompute it when drawing. */ | 896 /* New one should be dirty to recompute it when drawing. */ |
852 | 936 |
853 if(shape->stroke != NULL) | 937 if(shape->stroke != NULL) |
854 rdman_paint_stroke(rdman, (paint_t *)NULL, shape); | 938 rdman_paint_stroke(rdman, (paint_t *)NULL, shape); |
855 if(shape->fill != NULL) | 939 if(shape->fill != NULL) |
856 rdman_paint_fill(rdman, (paint_t *)NULL, shape); | 940 rdman_paint_fill(rdman, (paint_t *)NULL, shape); |
857 | 941 |
858 if(geo != NULL) { | 942 if(geo != NULL) { |
859 subject_free(geo->mouse_event); | 943 subject_free(geo->mouse_event); |
860 geo_detach_coord(geo, shape->coord); | 944 geo_detach_coord(geo, shape->coord); |
861 sh_detach_coord(shape); | 945 sh_detach_coord(shape); |
862 sh_detach_geo(shape); | 946 sh_detach_geo(shape); |
867 shape->free(shape); | 951 shape->free(shape); |
868 | 952 |
869 if(rdman->last_mouse_over == (mb_obj_t *)shape) | 953 if(rdman->last_mouse_over == (mb_obj_t *)shape) |
870 rdman->last_mouse_over = NULL; | 954 rdman->last_mouse_over = NULL; |
871 | 955 |
872 | 956 |
873 return OK; | 957 return OK; |
874 } | 958 } |
875 | 959 |
876 shnode_t *shnode_new(redraw_man_t *rdman, shape_t *shape) { | 960 shnode_t *shnode_new(redraw_man_t *rdman, shape_t *shape) { |
877 shnode_t *node; | 961 shnode_t *node; |
887 int rdman_paint_free(redraw_man_t *rdman, paint_t *paint) { | 971 int rdman_paint_free(redraw_man_t *rdman, paint_t *paint) { |
888 shnode_t *shnode, *saved_shnode; | 972 shnode_t *shnode, *saved_shnode; |
889 shape_t *shape; | 973 shape_t *shape; |
890 | 974 |
891 if(rdman_is_dirty(rdman)) { | 975 if(rdman_is_dirty(rdman)) { |
892 if(!(paint->flags & PNTF_FREE)) | 976 if(paint->flags & PNTF_FREE) |
893 return ERR; | 977 return ERR; |
894 add_free_obj(rdman, paint, (free_func_t)rdman_paint_free); | 978 add_free_obj(rdman, paint, (free_func_t)rdman_paint_free); |
895 paint->flags |= PNTF_FREE; | 979 paint->flags |= PNTF_FREE; |
896 return OK; | 980 return OK; |
897 } | 981 } |
899 /* Free member shapes that using this paint. */ | 983 /* Free member shapes that using this paint. */ |
900 saved_shnode = NULL; | 984 saved_shnode = NULL; |
901 FORPAINTMEMBERS(paint, shnode) { | 985 FORPAINTMEMBERS(paint, shnode) { |
902 if(saved_shnode) { | 986 if(saved_shnode) { |
903 RM_PAINTMEMBER(paint, saved_shnode); | 987 RM_PAINTMEMBER(paint, saved_shnode); |
904 | 988 |
905 shape = saved_shnode->shape; | 989 shape = saved_shnode->shape; |
906 if(shape->stroke == paint) | 990 if(shape->stroke == paint) |
907 rdman_paint_stroke(rdman, (paint_t *)NULL, shape); | 991 rdman_paint_stroke(rdman, (paint_t *)NULL, shape); |
908 if(shape->fill == paint) | 992 if(shape->fill == paint) |
909 rdman_paint_fill(rdman, (paint_t *)NULL, shape); | 993 rdman_paint_fill(rdman, (paint_t *)NULL, shape); |
910 | 994 |
911 shnode_free(rdman, saved_shnode); | 995 shnode_free(rdman, saved_shnode); |
912 } | 996 } |
913 saved_shnode = shnode; | 997 saved_shnode = shnode; |
914 } | 998 } |
915 if(saved_shnode) { | 999 if(saved_shnode) { |
916 RM_PAINTMEMBER(paint, saved_shnode); | 1000 RM_PAINTMEMBER(paint, saved_shnode); |
917 | 1001 |
918 shape = saved_shnode->shape; | 1002 shape = saved_shnode->shape; |
919 if(shape->stroke == paint) | 1003 if(shape->stroke == paint) |
920 rdman_paint_stroke(rdman, (paint_t *)NULL, shape); | 1004 rdman_paint_stroke(rdman, (paint_t *)NULL, shape); |
921 if(shape->fill == paint) | 1005 if(shape->fill == paint) |
922 rdman_paint_fill(rdman, (paint_t *)NULL, shape); | 1006 rdman_paint_fill(rdman, (paint_t *)NULL, shape); |
923 | 1007 |
924 shnode_free(rdman, saved_shnode); | 1008 shnode_free(rdman, saved_shnode); |
925 } | 1009 } |
926 | 1010 |
927 paint->free(rdman, paint); | 1011 paint->free(rdman, paint); |
928 return OK; | 1012 return OK; |
950 if(coord == NULL) | 1034 if(coord == NULL) |
951 return NULL; | 1035 return NULL; |
952 | 1036 |
953 coord_init(coord, parent); | 1037 coord_init(coord, parent); |
954 mb_prop_store_init(&coord->obj.props, rdman->pent_pool); | 1038 mb_prop_store_init(&coord->obj.props, rdman->pent_pool); |
955 coord->mouse_event = subject_new(&rdman->ob_factory, | 1039 coord->mouse_event = subject_new(&rdman->observer_factory, |
956 coord, | 1040 coord, |
957 OBJT_COORD); | 1041 OBJT_COORD); |
958 subject_set_monitor(coord->mouse_event, rdman->addrm_monitor); | 1042 subject_set_monitor(coord->mouse_event, rdman->addrm_monitor); |
959 /*! \note default opacity == 1 */ | 1043 /*! \note default opacity == 1 */ |
960 coord->opacity = 1; | 1044 coord->opacity = 1; |
986 static int rdman_coord_free_postponse(redraw_man_t *rdman, coord_t *coord) { | 1070 static int rdman_coord_free_postponse(redraw_man_t *rdman, coord_t *coord) { |
987 int r; | 1071 int r; |
988 | 1072 |
989 if(coord->flags & COF_FREE) | 1073 if(coord->flags & COF_FREE) |
990 return ERR; | 1074 return ERR; |
991 | 1075 |
992 coord->flags |= COF_FREE; | 1076 coord->flags |= COF_FREE; |
993 coord_hide(coord); | 1077 coord_hide(coord); |
994 if(!(coord->flags & COF_DIRTY)) { | 1078 if(!(coord->flags & COF_DIRTY)) { |
995 r = add_dirty_coord(rdman, coord); | 1079 r = add_dirty_coord(rdman, coord); |
996 if(r != OK) | 1080 if(r != OK) |
1031 FORMEMBERS(coord, member) { | 1115 FORMEMBERS(coord, member) { |
1032 cm_cnt++; | 1116 cm_cnt++; |
1033 if(!(member->flags & GEF_FREE)) | 1117 if(!(member->flags & GEF_FREE)) |
1034 return ERR; | 1118 return ERR; |
1035 } | 1119 } |
1036 | 1120 |
1037 if(cm_cnt || rdman_is_dirty(rdman)) | 1121 if(cm_cnt || rdman_is_dirty(rdman)) |
1038 return rdman_coord_free_postponse(rdman, coord); | 1122 return rdman_coord_free_postponse(rdman, coord); |
1039 | 1123 |
1040 /* Free canvas and canvas_info (\ref redraw) */ | 1124 /* Free canvas and canvas_info (\ref redraw) */ |
1041 if(coord_is_cached(coord)) { | 1125 if(coord_is_cached(coord)) { |
1224 break; | 1308 break; |
1225 #endif /* UNITTEST */ | 1309 #endif /* UNITTEST */ |
1226 } | 1310 } |
1227 shape->geo->flags &= ~GEF_DIRTY; | 1311 shape->geo->flags &= ~GEF_DIRTY; |
1228 | 1312 |
1229 if(is_coord_subtree_hidden(shape->coord)) | 1313 if(sh_get_flags(shape, GEF_HIDDEN) || |
1230 sh_hide(shape); | 1314 is_coord_subtree_hidden(shape->coord)) |
1315 sh_set_flags(shape, GEF_NOT_SHOWED); | |
1231 else | 1316 else |
1232 sh_show(shape); | 1317 sh_clear_flags(shape, GEF_NOT_SHOWED); |
1233 } | 1318 } |
1234 | 1319 |
1235 /*! \brief Setup canvas_info for the coord. | 1320 /*! \brief Setup canvas_info for the coord. |
1236 * | 1321 * |
1237 * Own a canvas or inherit it from parent. | 1322 * Own a canvas or inherit it from parent. |
1240 */ | 1325 */ |
1241 static void setup_canvas_info(redraw_man_t *rdman, coord_t *coord) { | 1326 static void setup_canvas_info(redraw_man_t *rdman, coord_t *coord) { |
1242 if(coord->parent == NULL) | 1327 if(coord->parent == NULL) |
1243 return; | 1328 return; |
1244 | 1329 |
1245 if(coord->opacity != 1 || coord_is_cached(coord)) { | 1330 if(coord->opacity != 1 || coord_is_always_cached(coord)) { |
1246 if(!coord_is_cached(coord)) { | 1331 if(!coord_is_cached(coord)) { |
1247 /* canvas is assigned latter, in zeroing_coord() */ | 1332 /* canvas is assigned latter, in zeroing_coord() */ |
1248 coord->canvas_info = coord_canvas_info_new(rdman, coord, NULL); | 1333 coord->canvas_info = coord_canvas_info_new(rdman, coord, NULL); |
1249 coord_set_flags(coord, COF_OWN_CANVAS); | 1334 coord_set_flags(coord, COF_OWN_CANVAS); |
1250 } | 1335 } |
1262 } | 1347 } |
1263 } | 1348 } |
1264 | 1349 |
1265 /* \brief Compute matrix from cached canvas to parent device space. | 1350 /* \brief Compute matrix from cached canvas to parent device space. |
1266 */ | 1351 */ |
1267 static void compute_cached_2_pdev_matrix(coord_t *coord, | 1352 static void compute_cached_2_pdev_matrix(coord_t *coord) { |
1268 co_aix canvas2pdev_matrix[6]) { | 1353 co_aix *canvas2pdev_matrix = coord_get_2pdev(coord); |
1269 coord_t *parent; | 1354 coord_t *parent; |
1270 co_aix *aggr; | 1355 co_aix *aggr; |
1271 co_aix *matrix, *paggr; | 1356 co_aix *matrix, *paggr; |
1272 co_aix scale_x, scale_y; | 1357 co_aix scale_x, scale_y; |
1273 co_aix shift_x, shift_y; | 1358 co_aix shift_x, shift_y; |
1275 | 1360 |
1276 aggr = coord_get_aggr_matrix(coord); | 1361 aggr = coord_get_aggr_matrix(coord); |
1277 matrix = coord->matrix; | 1362 matrix = coord->matrix; |
1278 parent = coord->parent; | 1363 parent = coord->parent; |
1279 paggr = coord_get_aggr_matrix(parent); | 1364 paggr = coord_get_aggr_matrix(parent); |
1280 | 1365 |
1281 scale_x = matrix[0] / aggr[0]; | 1366 scale_x = matrix[0] / aggr[0]; |
1282 scale_y = matrix[3] / aggr[3]; | 1367 scale_y = matrix[4] / aggr[4]; |
1283 shift_x = matrix[2] - scale_x * aggr[2]; | 1368 shift_x = matrix[2] - scale_x * aggr[2]; |
1284 shift_y = matrix[5] - scale_y * aggr[5]; | 1369 shift_y = matrix[5] - scale_y * aggr[5]; |
1285 | 1370 |
1286 canvas2p[0] = scale_x; | 1371 canvas2p[0] = scale_x; |
1287 canvas2p[1] = 0; | 1372 canvas2p[1] = 0; |
1289 canvas2p[3] = 0; | 1374 canvas2p[3] = 0; |
1290 canvas2p[4] = scale_y; | 1375 canvas2p[4] = scale_y; |
1291 canvas2p[5] = shift_y; | 1376 canvas2p[5] = shift_y; |
1292 | 1377 |
1293 matrix_mul(paggr, canvas2p, canvas2pdev_matrix); | 1378 matrix_mul(paggr, canvas2p, canvas2pdev_matrix); |
1379 | |
1380 compute_reverse(canvas2pdev_matrix, coord_get_2pdev_rev(coord)); | |
1294 } | 1381 } |
1295 | 1382 |
1296 /*! \brief Compute area in parent cached coord for a cached coord. | 1383 /*! \brief Compute area in parent cached coord for a cached coord. |
1297 * | 1384 * |
1298 * The coordination system of cached coord and descendants is resized, | 1385 * The coordination system of cached coord and descendants is resized, |
1301 * | 1388 * |
1302 * The bounding box where the canvas would be draw on the canvas on | 1389 * The bounding box where the canvas would be draw on the canvas on |
1303 * ancestral cached coord can be retreived by shifting and resizing | 1390 * ancestral cached coord can be retreived by shifting and resizing |
1304 * canvas box in reverse and transform to coordination system of | 1391 * canvas box in reverse and transform to coordination system of |
1305 * ancestral cached coord. | 1392 * ancestral cached coord. |
1306 */ | 1393 */ |
1307 static void compute_pcache_area(coord_t *coord) { | 1394 static void compute_pcache_area(coord_t *coord) { |
1308 co_aix cached2pdev[6]; | 1395 co_aix *cached2pdev = coord_get_2pdev(coord); |
1309 int c_w, c_h; | 1396 int c_w, c_h; |
1310 canvas_t *canvas; | 1397 canvas_t *canvas; |
1311 coord_canvas_info_t *canvas_info; | 1398 coord_canvas_info_t *canvas_info; |
1312 co_aix poses[4][2]; | 1399 co_aix poses[4][2]; |
1313 | 1400 |
1314 canvas_info = coord->canvas_info; | 1401 canvas_info = coord->canvas_info; |
1315 SWAP(canvas_info->pcache_cur_area, canvas_info->pcache_last_area, | 1402 SWAP(canvas_info->pcache_cur_area, canvas_info->pcache_last_area, |
1316 area_t *); | 1403 area_t *); |
1317 compute_cached_2_pdev_matrix(coord, cached2pdev); | 1404 |
1318 | |
1319 canvas = _coord_get_canvas(coord); | 1405 canvas = _coord_get_canvas(coord); |
1320 canvas_get_size(canvas, &c_w, &c_h); | 1406 canvas_get_size(canvas, &c_w, &c_h); |
1321 | 1407 |
1322 poses[0][0] = 0; | 1408 poses[0][0] = 0; |
1323 poses[0][1] = 0; | 1409 poses[0][1] = 0; |
1324 poses[1][0] = c_w; | 1410 poses[1][0] = c_w; |
1325 poses[1][1] = c_h; | 1411 poses[1][1] = c_h; |
1326 poses[2][0] = 0; | 1412 poses[2][0] = 0; |
1329 poses[3][1] = 0; | 1415 poses[3][1] = 0; |
1330 matrix_trans_pos(cached2pdev, &poses[0][0], &poses[0][1]); | 1416 matrix_trans_pos(cached2pdev, &poses[0][0], &poses[0][1]); |
1331 matrix_trans_pos(cached2pdev, &poses[1][0], &poses[1][1]); | 1417 matrix_trans_pos(cached2pdev, &poses[1][0], &poses[1][1]); |
1332 matrix_trans_pos(cached2pdev, &poses[2][0], &poses[2][1]); | 1418 matrix_trans_pos(cached2pdev, &poses[2][0], &poses[2][1]); |
1333 matrix_trans_pos(cached2pdev, &poses[3][0], &poses[3][1]); | 1419 matrix_trans_pos(cached2pdev, &poses[3][0], &poses[3][1]); |
1334 | 1420 |
1335 area_init(coord_get_pcache_area(coord), 4, poses); | 1421 area_init(coord_get_pcache_area(coord), 4, poses); |
1336 | 1422 |
1337 coord_set_flags(coord, COF_DIRTY_PCACHE_AREA); | 1423 coord_clear_flags(coord, COF_DIRTY_PCACHE_AREA); |
1338 } | 1424 } |
1339 | 1425 |
1340 /*! \brief Compute area of a coord. | 1426 /*! \brief Compute area of a coord. |
1341 */ | 1427 */ |
1342 static int | 1428 static int |
1343 compute_area(coord_t *coord) { | 1429 compute_area(coord_t *coord) { |
1344 static co_aix (*poses)[2]; | 1430 static co_aix (*poses)[2] = NULL; |
1345 static int max_poses = 0; | 1431 static int max_poses = 0; |
1346 geo_t *geo; | 1432 geo_t *geo; |
1347 int cnt, pos_cnt; | 1433 int cnt, pos_cnt; |
1348 | 1434 |
1349 cnt = 0; | 1435 cnt = 0; |
1350 FORMEMBERS(coord, geo) { | 1436 FORMEMBERS(coord, geo) { |
1351 cnt++; | 1437 cnt++; |
1352 } | 1438 } |
1353 | 1439 |
1354 if(max_poses < (cnt * 2)) { | 1440 if(max_poses < (cnt * 2)) { |
1355 free(poses); | 1441 if(poses) |
1442 free(poses); | |
1356 max_poses = cnt * 2; | 1443 max_poses = cnt * 2; |
1357 poses = (co_aix (*)[2])malloc(sizeof(co_aix [2]) * max_poses); | 1444 poses = (co_aix (*)[2])malloc(sizeof(co_aix [2]) * max_poses); |
1358 if(poses == NULL) | 1445 if(poses == NULL) |
1359 return ERR; | 1446 return ERR; |
1360 } | 1447 } |
1372 | 1459 |
1373 static int coord_clean_members_n_compute_area(coord_t *coord) { | 1460 static int coord_clean_members_n_compute_area(coord_t *coord) { |
1374 geo_t *geo; | 1461 geo_t *geo; |
1375 int r; | 1462 int r; |
1376 /*! \note poses is shared by invokings, it is not support reentrying. */ | 1463 /*! \note poses is shared by invokings, it is not support reentrying. */ |
1377 | 1464 |
1378 /* Clean member shapes. */ | 1465 /* Clean member shapes. */ |
1379 FORMEMBERS(coord, geo) { | 1466 FORMEMBERS(coord, geo) { |
1380 clean_shape(geo->shape); | 1467 clean_shape(geo->shape); |
1381 } | 1468 } |
1382 | 1469 |
1394 * normal one. (see compute_aggr_of_cached_coord()). | 1481 * normal one. (see compute_aggr_of_cached_coord()). |
1395 * | 1482 * |
1396 * \note coords their opacity != 1 are also traded as cached ones. | 1483 * \note coords their opacity != 1 are also traded as cached ones. |
1397 */ | 1484 */ |
1398 static int clean_coord(redraw_man_t *rdman, coord_t *coord) { | 1485 static int clean_coord(redraw_man_t *rdman, coord_t *coord) { |
1399 coord_t *child; | |
1400 int r; | 1486 int r; |
1401 | 1487 |
1402 setup_canvas_info(rdman, coord); | 1488 setup_canvas_info(rdman, coord); |
1403 | 1489 |
1404 compute_aggr(coord); | 1490 compute_aggr(coord); |
1405 | 1491 |
1406 /* Areas of cached coords are computed in two phase. | 1492 /* Areas of cached coords are computed in two phase. |
1410 */ | 1496 */ |
1411 r = coord_clean_members_n_compute_area(coord); | 1497 r = coord_clean_members_n_compute_area(coord); |
1412 if(r != OK) | 1498 if(r != OK) |
1413 return ERR; | 1499 return ERR; |
1414 | 1500 |
1501 /* Dirty areas of cached one is added after update pcache_areas. | |
1502 */ | |
1415 add_dirty_area(rdman, coord, coord->cur_area); | 1503 add_dirty_area(rdman, coord, coord->cur_area); |
1416 add_dirty_area(rdman, coord, coord->last_area); | 1504 add_dirty_area(rdman, coord, coord->last_area); |
1417 | 1505 |
1418 coord_clear_flags(coord, COF_DIRTY); | 1506 coord_clear_flags(coord, COF_DIRTY); |
1419 coord_set_flags(coord, COF_JUST_CLEAN); | 1507 coord_set_flags(coord, COF_JUST_CLEAN); |
1420 | 1508 |
1421 FORCHILDREN(coord, child) { | |
1422 if(coord_is_cached(child)) | |
1423 add_dirty_pcache_area_coord(rdman, child); | |
1424 } | |
1425 | |
1426 return OK; | 1509 return OK; |
1427 } | 1510 } |
1428 | 1511 |
1429 /*! \brief Clean coord_t objects. | 1512 /*! \brief Clean coord_t objects. |
1430 * | 1513 * |
1432 * | 1515 * |
1433 * This function also responsible for computing area of parent cached | 1516 * This function also responsible for computing area of parent cached |
1434 * coord, coord_canvas_info_t::pcache_cur_area, for its cached children. | 1517 * coord, coord_canvas_info_t::pcache_cur_area, for its cached children. |
1435 */ | 1518 */ |
1436 static int clean_rdman_coords(redraw_man_t *rdman) { | 1519 static int clean_rdman_coords(redraw_man_t *rdman) { |
1437 coord_t *coord, *child; | 1520 coord_t *coord; |
1438 coord_t **dirty_coords; | 1521 coord_t **dirty_coords; |
1439 int n_dirty_coords; | 1522 int n_dirty_coords; |
1440 int i, r; | 1523 int i, r; |
1441 | 1524 |
1442 n_dirty_coords = rdman->dirty_coords.num; | 1525 n_dirty_coords = rdman->dirty_coords.num; |
1474 clean_shape(visit_geo->shape); | 1557 clean_shape(visit_geo->shape); |
1475 coord = geo_get_coord(visit_geo); | 1558 coord = geo_get_coord(visit_geo); |
1476 add_dirty_area(rdman, coord, visit_geo->cur_area); | 1559 add_dirty_area(rdman, coord, visit_geo->cur_area); |
1477 add_dirty_area(rdman, coord, visit_geo->last_area); | 1560 add_dirty_area(rdman, coord, visit_geo->last_area); |
1478 } | 1561 } |
1479 } | 1562 } |
1480 | 1563 |
1481 return OK; | 1564 return OK; |
1482 } | 1565 } |
1483 | 1566 |
1484 /*! \brief Shift space of coord to align left-top of minimum covering. | 1567 /*! \brief Shift space of coord to align left-top of minimum covering. |
1487 * sub-graphic to origin of the space. | 1570 * sub-graphic to origin of the space. |
1488 */ | 1571 */ |
1489 static | 1572 static |
1490 void zeroing_coord(redraw_man_t *rdman, coord_t *coord) { | 1573 void zeroing_coord(redraw_man_t *rdman, coord_t *coord) { |
1491 coord_t *cur; | 1574 coord_t *cur; |
1492 area_t *area, *saved_area; | 1575 area_t *area; |
1493 geo_t *geo; | 1576 geo_t *geo; |
1494 co_aix min_x, min_y; | 1577 co_aix min_x, min_y; |
1495 co_aix max_x, max_y; | 1578 co_aix max_x, max_y; |
1496 co_aix x, y; | 1579 co_aix x, y; |
1497 int w, h; | 1580 int w, h; |
1498 int c_w, c_h; | 1581 int c_w, c_h; |
1499 mbe_t *canvas; | 1582 mbe_t *canvas; |
1500 co_aix *aggr; | 1583 co_aix *aggr; |
1501 co_aix poses[4][2]; | |
1502 | 1584 |
1503 if(coord->parent == NULL) /*! \note Should not zeroing root coord */ | 1585 if(coord->parent == NULL) /*! \note Should not zeroing root coord */ |
1504 abort(); | 1586 abort(); |
1505 if(!(coord_is_zeroing(coord))) | 1587 if(!(coord_is_zeroing(coord))) |
1506 abort(); | 1588 abort(); |
1517 max_y = min_y + area->h; | 1599 max_y = min_y + area->h; |
1518 | 1600 |
1519 for(cur = preorder_coord_subtree(coord, coord); | 1601 for(cur = preorder_coord_subtree(coord, coord); |
1520 cur != NULL; | 1602 cur != NULL; |
1521 cur = preorder_coord_subtree(coord, cur)) { | 1603 cur = preorder_coord_subtree(coord, cur)) { |
1522 area = coord_get_area(cur); | 1604 if(coord_is_cached(cur)) { |
1605 preorder_coord_skip_subtree(cur); | |
1606 /* This means pcache_area of descendants must be computed | |
1607 * before zeroing ancestor cached one. | |
1608 * (See add_rdman_zeroing_n_pcache_coords()) | |
1609 */ | |
1610 area = coord_get_pcache_area(cur); | |
1611 } else | |
1612 area = coord_get_area(cur); | |
1613 | |
1614 if(area->w == 0 && area->h == 0) | |
1615 continue; | |
1616 | |
1617 if(min_x == max_x && min_y == max_y) { | |
1618 min_x = area->x; | |
1619 max_x = area->x + area->w; | |
1620 min_y = area->y; | |
1621 max_y = area->y + area->h; | |
1622 continue; | |
1623 } | |
1624 | |
1523 if(area->x < min_x) | 1625 if(area->x < min_x) |
1524 min_x = area->x; | 1626 min_x = area->x; |
1525 if(area->y < min_y) | 1627 if(area->y < min_y) |
1526 min_y = area->y; | 1628 min_y = area->y; |
1527 | 1629 |
1528 x = area->x + area->w; | 1630 x = area->x + area->w; |
1529 y = area->y + area->h; | 1631 y = area->y + area->h; |
1530 | 1632 |
1531 if(x > max_x) | 1633 if(x > max_x) |
1532 max_x = x; | 1634 max_x = x; |
1533 if(y > max_y) | 1635 if(y > max_y) |
1534 max_y = y; | 1636 max_y = y; |
1535 if(coord_is_cached(cur)) | |
1536 preorder_coord_skip_subtree(cur); | |
1537 } | 1637 } |
1538 | 1638 |
1539 w = max_x - min_x; | 1639 w = max_x - min_x; |
1540 h = max_y - min_y; | 1640 h = max_y - min_y; |
1541 | 1641 |
1542 canvas = _coord_get_canvas(coord); | 1642 canvas = _coord_get_canvas(coord); |
1543 if(canvas) | 1643 if(canvas) |
1544 canvas_get_size(canvas, &c_w, &c_h); | 1644 canvas_get_size(canvas, &c_w, &c_h); |
1545 else | 1645 else |
1546 c_w = c_h = 0; | 1646 c_w = c_h = 0; |
1558 h >= (c_h >> 2) && w >= (c_w >> 2)) { | 1658 h >= (c_h >> 2) && w >= (c_w >> 2)) { |
1559 /* Canvas fully cover sub-graphic. */ | 1659 /* Canvas fully cover sub-graphic. */ |
1560 coord_set_flags(coord, COF_SKIP_ZERO); | 1660 coord_set_flags(coord, COF_SKIP_ZERO); |
1561 return; | 1661 return; |
1562 } | 1662 } |
1563 | 1663 |
1564 /* | 1664 /* |
1565 * Adjust matrics of descendants to align left-top corner of | 1665 * Adjust matrics of descendants to align left-top corner of |
1566 * minimum covering area with origin of space defined by | 1666 * minimum covering area with origin of space defined by |
1567 * zeroing coord. | 1667 * zeroing coord. |
1568 */ | 1668 */ |
1575 */ | 1675 */ |
1576 preorder_coord_skip_subtree(cur); | 1676 preorder_coord_skip_subtree(cur); |
1577 } | 1677 } |
1578 /* Shift space */ | 1678 /* Shift space */ |
1579 aggr = coord_get_aggr_matrix(cur); | 1679 aggr = coord_get_aggr_matrix(cur); |
1580 aggr[3] -= min_x; | 1680 aggr[2] -= min_x; |
1581 aggr[5] -= min_y; | 1681 aggr[5] -= min_y; |
1582 | 1682 |
1583 FOR_COORD_MEMBERS(coord, geo) { | 1683 FOR_COORD_MEMBERS(coord, geo) { |
1584 /* \see GEO_SWAP() */ | 1684 /* \see GEO_SWAP() */ |
1585 if(!geo_get_flags(geo, GEF_SWAP)) | 1685 if(!geo_get_flags(geo, GEF_SWAP)) |
1586 SWAP(geo->cur_area, geo->last_area, area_t *); | 1686 SWAP(geo->cur_area, geo->last_area, area_t *); |
1587 } | 1687 } |
1588 coord_clean_members_n_compute_area(cur); | 1688 coord_clean_members_n_compute_area(cur); |
1589 } | 1689 } |
1590 | 1690 |
1591 /* | 1691 /* |
1592 * Setup canvas | 1692 * Setup canvas |
1593 * | 1693 * |
1594 * Canvas of a cached coord is not setted in | 1694 * Canvas of a cached coord is not setted in |
1595 * coord_canvas_info_new(). It should be setted, here. | 1695 * coord_canvas_info_new(). It should be setted, here. |
1602 } | 1702 } |
1603 | 1703 |
1604 coord_set_flags(coord, COF_JUST_ZERO); | 1704 coord_set_flags(coord, COF_JUST_ZERO); |
1605 } | 1705 } |
1606 | 1706 |
1607 /*! \brief Add canvas owner of dirty geos to redraw_man_t::zeroing_coords. | 1707 /*! \brief Add coords that need to perform zeroing or re-compute pcache_area. |
1608 * | 1708 * |
1609 * All possible coords that need a zeroing have at least one dirty geo. | 1709 * A coord that need to perform zeroing has one or more dirty members |
1610 */ | 1710 * in its descendants. |
1611 static int add_rdman_zeroing_coords(redraw_man_t *rdman) { | 1711 * |
1712 * To zeroing a coord, pcache_area of first level cached descendants | |
1713 * must be updated. To update the pcache_area of a cached coord, the | |
1714 * cached coord also need to perform zeroing. So, zeroing and | |
1715 * re-computing pcache_area are interleaved. | |
1716 * | |
1717 * The pcache_area of a cached coord must be re-computed if its | |
1718 * parent/ancestors is dirty/just cleaned, or it must be zeroed. It | |
1719 * means cached coord with jsut cleaned parent should also re-compute | |
1720 * pcache_area. So, this function also check and add coords for this | |
1721 * situation. | |
1722 */ | |
1723 static int add_rdman_zeroing_n_pcache_coords(redraw_man_t *rdman) { | |
1612 int i; | 1724 int i; |
1613 int n_dirty_geos; | 1725 int n_dirty_geos; |
1614 geo_t **dirty_geos, *geo; | 1726 geo_t **dirty_geos, *geo; |
1615 int n_dirty_coords; | 1727 int n_dirty_coords; |
1616 coord_t **dirty_coords, *coord; | 1728 coord_t **dirty_coords, *coord; |
1729 coord_t *parent_coord; | |
1617 | 1730 |
1618 /* Mark all cached ancestral coords of dirty geos */ | 1731 /* Mark all cached ancestral coords of dirty geos */ |
1619 n_dirty_geos = rdman->dirty_geos.num; | 1732 n_dirty_geos = rdman->dirty_geos.num; |
1620 dirty_geos = rdman->dirty_geos.ds; | 1733 dirty_geos = rdman->dirty_geos.ds; |
1621 for(i = 0; i < n_dirty_geos; i++) { | 1734 for(i = 0; i < n_dirty_geos; i++) { |
1626 break; | 1739 break; |
1627 coord_set_flags(coord, COF_TEMP_MARK); | 1740 coord_set_flags(coord, COF_TEMP_MARK); |
1628 coord = coord_get_cached(coord_get_parent(coord)); | 1741 coord = coord_get_cached(coord_get_parent(coord)); |
1629 } | 1742 } |
1630 } | 1743 } |
1631 | 1744 |
1632 /* Mark all cached ancestral coords of dirty coords */ | 1745 /* Mark all cached ancestral coords of dirty coords */ |
1633 n_dirty_coords = rdman->dirty_coords.num; | 1746 n_dirty_coords = rdman->dirty_coords.num; |
1634 dirty_coords = rdman->dirty_coords.ds; | 1747 dirty_coords = rdman->dirty_coords.ds; |
1635 for(i = 0; i < n_dirty_coords; i++) { | 1748 for(i = 0; i < n_dirty_coords; i++) { |
1636 coord = coord_get_cached(dirty_coords[i]); | 1749 coord = coord_get_cached(dirty_coords[i]); |
1639 break; | 1752 break; |
1640 coord_set_flags(coord, COF_TEMP_MARK); | 1753 coord_set_flags(coord, COF_TEMP_MARK); |
1641 coord = coord_get_cached(coord_get_parent(coord)); | 1754 coord = coord_get_cached(coord_get_parent(coord)); |
1642 } | 1755 } |
1643 } | 1756 } |
1644 | 1757 |
1645 /* Add all marked coords into redraw_man_t::zeroing_coords list */ | 1758 /* Add all marked coords into redraw_man_t::zeroing_coords list */ |
1646 FOR_COORDS_PREORDER(rdman->root_coord, coord) { | 1759 FOR_COORDS_PREORDER(rdman->root_coord, coord) { |
1647 if(!coord_is_cached(coord)) | 1760 if(!coord_is_cached(coord) || coord_is_root(coord)) |
1648 continue; /* skip coords that is not cached */ | 1761 continue; /* skip coords that is not cached */ |
1649 | 1762 |
1650 if(!coord_get_flags(coord, COF_TEMP_MARK)) { | 1763 if(!coord_get_flags(coord, COF_TEMP_MARK)) { |
1651 if(coord_get_flags(coord, COF_DIRTY_PCACHE_AREA)) | 1764 parent_coord = coord_get_parent(coord); |
1765 /* The pcache_area of a cached coord that is a child of a | |
1766 * just cleaned one must be recomputed. | |
1767 */ | |
1768 if(coord_get_flags(parent_coord, COF_JUST_CLEAN)) | |
1652 add_dirty_pcache_area_coord(rdman, coord); | 1769 add_dirty_pcache_area_coord(rdman, coord); |
1770 | |
1653 preorder_coord_skip_subtree(coord); | 1771 preorder_coord_skip_subtree(coord); |
1654 continue; | 1772 continue; |
1655 } | 1773 } |
1656 add_zeroing_coord(rdman, coord); | 1774 add_zeroing_coord(rdman, coord); |
1657 | 1775 |
1658 coord_clear_flags(coord, COF_TEMP_MARK); | 1776 coord_clear_flags(coord, COF_TEMP_MARK); |
1659 } | 1777 } |
1660 | 1778 |
1661 return OK; | 1779 return OK; |
1662 } | 1780 } |
1663 | 1781 |
1664 /*! \brief Zeroing coords in redraw_man_t::zeroing_coords. | 1782 /*! \brief Zeroing coords in redraw_man_t::zeroing_coords. |
1665 * | 1783 * |
1669 */ | 1787 */ |
1670 static int zeroing_rdman_coords(redraw_man_t *rdman) { | 1788 static int zeroing_rdman_coords(redraw_man_t *rdman) { |
1671 int i; | 1789 int i; |
1672 coords_t *all_zeroing; | 1790 coords_t *all_zeroing; |
1673 coord_t *coord; | 1791 coord_t *coord; |
1674 | 1792 |
1675 all_zeroing = &rdman->zeroing_coords; | 1793 all_zeroing = &rdman->zeroing_coords; |
1676 /*! Zeroing is performed from leaves to root. | 1794 /*! Zeroing is performed from leaves to root. |
1677 * | 1795 * |
1678 * REASON: The size of canvas is also effected by cached | 1796 * REASON: The size of canvas is also effected by cached |
1679 * descedants. A cached coord is only effected by parent | 1797 * descedants. A cached coord is only effected by parent |
1684 * performed before zeroing. It means ancestors of a | 1802 * performed before zeroing. It means ancestors of a |
1685 * cached coord would not effect it when zeroing. | 1803 * cached coord would not effect it when zeroing. |
1686 */ | 1804 */ |
1687 for(i = all_zeroing->num - 1; i >= 0; i--) { | 1805 for(i = all_zeroing->num - 1; i >= 0; i--) { |
1688 coord = all_zeroing->ds[i]; | 1806 coord = all_zeroing->ds[i]; |
1689 zeroing_coord(rdman, coord); | 1807 if(coord_is_zeroing(coord)) |
1808 zeroing_coord(rdman, coord); | |
1809 compute_cached_2_pdev_matrix(coord); | |
1810 /* This is required by ancester cached ones to perform | |
1811 * zeroing. | |
1812 */ | |
1690 compute_pcache_area(coord); | 1813 compute_pcache_area(coord); |
1691 } | 1814 } |
1692 | 1815 |
1693 return OK; | 1816 return OK; |
1694 } | 1817 } |
1695 | 1818 |
1696 /*! \brief Compute pcache_area for coords whoes pcache_area is dirty. | 1819 /*! \brief Update aggregated cache_2_pdev matrix for cached coords. |
1697 * | 1820 * |
1698 * coord_t::dirty_pcache_area_coords also includes part of coords in | 1821 * This is perfromed from root to leaves. Aggregated cache_2_pdev is |
1699 * coord_t::zeroing_coords. The pcache_area of coords that is in | 1822 * named as aggr_2_pdev field of canvas_info_t. It is the matrix to |
1700 * coord_t::dirty_pcache_area_coords, but is not in | 1823 * transform a point from space of a cached coord to the space of root |
1701 * coord_t::zeroing_coords should be computed here. | 1824 * coord. |
1702 * zeroing_rdman_coords() is responsible for computing pcache_area for | |
1703 * zeroing ones. | |
1704 */ | 1825 */ |
1705 static int | 1826 static int |
1706 compute_rdman_coords_pcache_area(redraw_man_t *rdman) { | 1827 update_aggr_pdev(redraw_man_t *rdman) { |
1707 coords_t *all_coords; | |
1708 coord_t *coord; | |
1709 int i; | 1828 int i; |
1710 | 1829 coords_t *all_zeroing; |
1711 all_coords = &rdman->dirty_pcache_area_coords; | 1830 coord_t *coord, *parent_cached; |
1712 for(i = 0; i < all_coords->num; i++) { | 1831 |
1713 coord = all_coords->ds[i]; | 1832 all_zeroing = &rdman->zeroing_coords; |
1714 if(coord_get_flags(coord, COF_DIRTY_PCACHE_AREA)) | 1833 for(i = 0; i < all_zeroing->num; i++) { |
1715 compute_pcache_area(coord); | 1834 coord = all_zeroing->ds[i]; |
1716 } | 1835 parent_cached = coord_get_cached(coord_get_parent(coord)); |
1836 matrix_mul(coord_get_2pdev(parent_cached), | |
1837 coord_get_2pdev(coord), | |
1838 coord_get_aggr2pdev(coord)); | |
1839 matrix_mul(coord_get_2pdev_rev(coord), | |
1840 coord_get_2pdev_rev(parent_cached), | |
1841 coord_get_aggr2pdev_rev(coord)); | |
1842 } | |
1843 | |
1717 return OK; | 1844 return OK; |
1718 } | 1845 } |
1719 | 1846 |
1720 /*! \brief Add aggregated dirty areas to ancestor. | 1847 /*! \brief Add aggregated dirty areas to ancestor. |
1721 * | 1848 * |
1725 */ | 1852 */ |
1726 static void add_aggr_dirty_areas_to_ancestor(redraw_man_t *rdman, | 1853 static void add_aggr_dirty_areas_to_ancestor(redraw_man_t *rdman, |
1727 coord_t *coord) { | 1854 coord_t *coord) { |
1728 int i; | 1855 int i; |
1729 int n_areas; | 1856 int n_areas; |
1730 int enable_poses1 = 0; | |
1731 co_aix poses0[2][2], poses1[2][2]; | 1857 co_aix poses0[2][2], poses1[2][2]; |
1732 co_aix reverse[6]; | 1858 co_aix *canvas2pdev_matrix; |
1733 co_aix canvas2pdev_matrix[6]; | |
1734 area_t **areas, *area; | 1859 area_t **areas, *area; |
1735 area_t *area0, *area1; | 1860 area_t *area0, *area1; |
1736 coord_t *parent, *pcached_coord; | 1861 coord_t *parent, *pcached_coord; |
1737 | 1862 |
1738 n_areas = _coord_get_dirty_areas(coord)->num; | 1863 n_areas = _coord_get_dirty_areas(coord)->num; |
1739 areas = _coord_get_dirty_areas(coord)->ds; | 1864 areas = _coord_get_dirty_areas(coord)->ds; |
1740 if(n_areas == 0) | 1865 if(n_areas == 0) { |
1741 abort(); /* should not happen! */ | 1866 /* Go here for cached one that is descendant of another zeroed |
1742 | 1867 * one, but itself is not zeroed. It is here for recomputing |
1868 * pcache areas. | |
1869 */ | |
1870 if(coord_get_flags(coord, COF_JUST_CLEAN | COF_JUST_ZERO)) | |
1871 abort(); /* should not happen! */ | |
1872 | |
1873 parent = coord_get_parent(coord); | |
1874 pcached_coord = coord_get_cached(parent); | |
1875 area = coord_get_pcache_area(coord); | |
1876 add_dirty_area(rdman, pcached_coord, area); | |
1877 area = coord_get_pcache_last_area(coord); | |
1878 add_dirty_area(rdman, pcached_coord, area); | |
1879 return; | |
1880 } | |
1881 | |
1743 area0 = _coord_get_aggr_dirty_areas(coord); | 1882 area0 = _coord_get_aggr_dirty_areas(coord); |
1744 area1 = area0 + 1; | 1883 area1 = area0 + 1; |
1745 | 1884 |
1746 /* TODO: Since both cur & last area of coords are added into dirty | 1885 /* TODO: Since both cur & last area of coords are added into dirty |
1747 * area list, position of both areas shoud be adjusted for | 1886 * area list, position of both areas shoud be adjusted for |
1753 break; | 1892 break; |
1754 } | 1893 } |
1755 | 1894 |
1756 if(i >= n_areas) | 1895 if(i >= n_areas) |
1757 return; | 1896 return; |
1758 | 1897 |
1759 area = areas[i++]; | 1898 area = areas[i++]; |
1760 poses0[0][0] = area->x; | 1899 poses0[0][0] = area->x; |
1761 poses0[0][1] = area->y; | 1900 poses0[0][1] = area->y; |
1762 poses0[1][0] = area->x + area->w; | 1901 poses0[1][0] = area->x + area->w; |
1763 poses0[1][1] = area->y + area->h; | 1902 poses0[1][1] = area->y + area->h; |
1764 | 1903 |
1765 if(i < n_areas) { | 1904 if(i < n_areas) { |
1766 area = areas[i++]; | 1905 area = areas[i++]; |
1767 poses1[0][0] = area->x; | 1906 poses1[0][0] = area->x; |
1768 poses1[0][1] = area->y; | 1907 poses1[0][1] = area->y; |
1769 poses1[1][0] = area->x + area->w; | 1908 poses1[1][0] = area->x + area->w; |
1772 poses1[0][0] = 0; | 1911 poses1[0][0] = 0; |
1773 poses1[0][1] = 0; | 1912 poses1[0][1] = 0; |
1774 poses1[1][0] = 0; | 1913 poses1[1][0] = 0; |
1775 poses1[1][1] = 0; | 1914 poses1[1][1] = 0; |
1776 } | 1915 } |
1777 | 1916 |
1778 for(; i < n_areas - 1;) { | 1917 for(; i < n_areas - 1;) { |
1779 /* Even areas */ | 1918 /* Even areas */ |
1780 area = areas[i++]; | 1919 area = areas[i++]; |
1781 if(area->w != 0 || area->h != 0) { | 1920 if(area->w != 0 || area->h != 0) { |
1782 poses0[0][0] = MB_MIN(poses0[0][0], area->x); | 1921 poses0[0][0] = MB_MIN(poses0[0][0], area->x); |
1791 poses1[0][1] = MB_MIN(poses1[0][1], area->y); | 1930 poses1[0][1] = MB_MIN(poses1[0][1], area->y); |
1792 poses1[1][0] = MB_MAX(poses1[1][0], area->x + area->w); | 1931 poses1[1][0] = MB_MAX(poses1[1][0], area->x + area->w); |
1793 poses1[1][1] = MB_MAX(poses1[1][1], area->y + area->h); | 1932 poses1[1][1] = MB_MAX(poses1[1][1], area->y + area->h); |
1794 } | 1933 } |
1795 } | 1934 } |
1796 | 1935 |
1797 if(i < n_areas) { | 1936 if(i < n_areas) { |
1798 area = areas[i]; | 1937 area = areas[i]; |
1799 if(area->w != 0 || area->h != 0) { | 1938 if(area->w != 0 || area->h != 0) { |
1800 poses0[0][0] = MB_MIN(poses0[0][0], area->x); | 1939 poses0[0][0] = MB_MIN(poses0[0][0], area->x); |
1801 poses0[0][1] = MB_MIN(poses0[0][1], area->y); | 1940 poses0[0][1] = MB_MIN(poses0[0][1], area->y); |
1802 poses0[1][0] = MB_MAX(poses0[1][0], area->x + area->w); | 1941 poses0[1][0] = MB_MAX(poses0[1][0], area->x + area->w); |
1803 poses0[1][1] = MB_MAX(poses0[1][1], area->y + area->h); | 1942 poses0[1][1] = MB_MAX(poses0[1][1], area->y + area->h); |
1804 } | 1943 } |
1805 } | 1944 } |
1806 | 1945 |
1807 parent = coord_get_parent(coord); | 1946 parent = coord_get_parent(coord); |
1808 pcached_coord = coord_get_cached(parent); | 1947 pcached_coord = coord_get_cached(parent); |
1809 | 1948 |
1810 compute_cached_2_pdev_matrix(coord, canvas2pdev_matrix); | 1949 canvas2pdev_matrix = coord_get_2pdev(coord); |
1811 | 1950 |
1812 /* Add dirty areas to parent cached coord. */ | 1951 /* Add dirty areas to parent cached coord. */ |
1813 matrix_trans_pos(canvas2pdev_matrix, poses0[0], poses0[0] + 1); | 1952 matrix_trans_pos(canvas2pdev_matrix, poses0[0], poses0[0] + 1); |
1814 matrix_trans_pos(canvas2pdev_matrix, poses0[1], poses0[1] + 1); | 1953 matrix_trans_pos(canvas2pdev_matrix, poses0[1], poses0[1] + 1); |
1815 area_init(area0, 2, poses0); | 1954 area_init(area0, 2, poses0); |
1816 add_dirty_area(rdman, pcached_coord, area0); | 1955 add_dirty_area(rdman, pcached_coord, area0); |
1817 | 1956 |
1818 matrix_trans_pos(canvas2pdev_matrix, poses1[0], poses1[0] + 1); | 1957 matrix_trans_pos(canvas2pdev_matrix, poses1[0], poses1[0] + 1); |
1819 matrix_trans_pos(canvas2pdev_matrix, poses1[1], poses1[1] + 1); | 1958 matrix_trans_pos(canvas2pdev_matrix, poses1[1], poses1[1] + 1); |
1820 area_init(area1, 2, poses1); | 1959 area_init(area1, 2, poses1); |
1821 add_dirty_area(rdman, pcached_coord, area1); | 1960 add_dirty_area(rdman, pcached_coord, area1); |
1822 | 1961 |
1838 * areas and one or new areas. Both aggregation areas are add into | 1977 * areas and one or new areas. Both aggregation areas are add into |
1839 * dirty_areas list of closet ancestral cached coord. | 1978 * dirty_areas list of closet ancestral cached coord. |
1840 */ | 1979 */ |
1841 static int add_rdman_aggr_dirty_areas(redraw_man_t *rdman) { | 1980 static int add_rdman_aggr_dirty_areas(redraw_man_t *rdman) { |
1842 int i; | 1981 int i; |
1843 int n_zeroing; | 1982 coord_t *coord, *parent_coord, *pcached_coord; |
1844 coord_t **zeroings; | 1983 int n_zeroing_coords; /* number of dirty pcache area coords */ |
1845 coord_t *coord, *pcached_coord; | 1984 coord_t **zeroing_coords; /* dirty pcache area coords */ |
1846 int n_dpca_coords; /* number of dirty pcache area coords */ | 1985 |
1847 coord_t **dpca_coords; /* dirty pcache area coords */ | 1986 n_zeroing_coords = rdman->zeroing_coords.num; |
1848 | 1987 zeroing_coords = rdman->zeroing_coords.ds; |
1849 /* Add aggregated areas to parent cached one for coords in zeroing | 1988 for(i = n_zeroing_coords - 1; i >= 0; i--) { |
1850 * list | 1989 coord = zeroing_coords[i]; |
1851 */ | |
1852 n_zeroing = rdman->zeroing_coords.num; | |
1853 zeroings = rdman->zeroing_coords.ds; | |
1854 for(i = 0; i < n_zeroing; i++) { | |
1855 if(coord_get_flags(coord, COF_TEMP_MARK)) | |
1856 continue; | |
1857 coord_set_flags(coord, COF_TEMP_MARK); | |
1858 | |
1859 coord = zeroings[i]; | |
1860 pcached_coord = coord_get_cached(coord_get_parent(coord)); | |
1861 | |
1862 if(coord_is_root(coord) || IS_CACHE_REDRAW_ALL(pcached_coord)) | |
1863 continue; | |
1864 | |
1865 if(IS_CACHE_REDRAW_ALL(coord)) { | 1990 if(IS_CACHE_REDRAW_ALL(coord)) { |
1991 parent_coord = coord_get_parent(coord); | |
1992 pcached_coord = coord_get_cached(parent_coord); | |
1993 | |
1866 add_dirty_area(rdman, pcached_coord, | 1994 add_dirty_area(rdman, pcached_coord, |
1867 coord_get_pcache_area(coord)); | 1995 coord_get_pcache_area(coord)); |
1868 add_dirty_area(rdman, pcached_coord, | 1996 add_dirty_area(rdman, pcached_coord, |
1869 coord_get_pcache_last_area(coord)); | 1997 coord_get_pcache_last_area(coord)); |
1870 } else { | 1998 } else { |
1871 add_aggr_dirty_areas_to_ancestor(rdman, coord); | 1999 add_aggr_dirty_areas_to_ancestor(rdman, coord); |
1872 } | 2000 } |
1873 } | |
1874 | |
1875 /* Add pcache_areas to parent cached one for coord that is | |
1876 * non-zeroing and its parent is changed. | |
1877 */ | |
1878 n_dpca_coords = rdman->dirty_pcache_area_coords.num; | |
1879 dpca_coords = rdman->dirty_pcache_area_coords.ds; | |
1880 for(i = 0; i < n_dpca_coords; i++) { | |
1881 if(coord_get_flags(coord, COF_TEMP_MARK)) | |
1882 continue; | |
1883 coord_set_flags(coord, COF_TEMP_MARK); | |
1884 | |
1885 coord = dpca_coords[i]; | |
1886 pcached_coord = coord_get_cached(coord_get_parent(coord)); | |
1887 | |
1888 if(coord_is_root(coord) || IS_CACHE_REDRAW_ALL(pcached_coord)) | |
1889 continue; | |
1890 | |
1891 add_dirty_area(rdman, pcached_coord, | |
1892 coord_get_pcache_area(coord)); | |
1893 add_dirty_area(rdman, pcached_coord, | |
1894 coord_get_pcache_last_area(coord)); | |
1895 } | |
1896 | |
1897 /* Remove temporary mark */ | |
1898 for(i = 0; i < n_zeroing; i++) { | |
1899 coord_clear_flags(zeroings[i], COF_TEMP_MARK); | |
1900 } | |
1901 for(i = 0; i < n_dpca_coords; i++) { | |
1902 coord_clear_flags(dpca_coords[i], COF_TEMP_MARK); | |
1903 } | 2001 } |
1904 | 2002 |
1905 return OK; | 2003 return OK; |
1906 } | 2004 } |
1907 | 2005 |
1979 SWAP(coord->cur_area, coord->last_area, area_t *); | 2077 SWAP(coord->cur_area, coord->last_area, area_t *); |
1980 FOR_COORD_MEMBERS(coord, geo) { | 2078 FOR_COORD_MEMBERS(coord, geo) { |
1981 GEO_SWAP(geo); | 2079 GEO_SWAP(geo); |
1982 } | 2080 } |
1983 } | 2081 } |
1984 | 2082 |
2083 /* XXX: some geo may swap two times. Should avoid it. | |
2084 */ | |
1985 geos = rdman->dirty_geos.ds; | 2085 geos = rdman->dirty_geos.ds; |
1986 for(i = 0; i < rdman->dirty_geos.num; i++) { | 2086 for(i = 0; i < rdman->dirty_geos.num; i++) { |
1987 geo = geos[i]; | 2087 geo = geos[i]; |
1988 GEO_SWAP(geo); | 2088 GEO_SWAP(geo); |
1989 } | 2089 } |
1990 | 2090 |
1991 r = clean_rdman_coords(rdman); | 2091 r = clean_rdman_coords(rdman); |
1992 if(r != OK) | 2092 if(r != OK) |
1993 return ERR; | 2093 return ERR; |
1994 | 2094 |
1995 /* TODO: save area of cached coord and descendants in | 2095 /* TODO: save area of cached coord and descendants in |
2001 return ERR; | 2101 return ERR; |
2002 | 2102 |
2003 /* Zeroing must be performed after clearing to get latest position | 2103 /* Zeroing must be performed after clearing to get latest position |
2004 * of shapes for computing new bounding box | 2104 * of shapes for computing new bounding box |
2005 */ | 2105 */ |
2006 r = add_rdman_zeroing_coords(rdman); | 2106 r = add_rdman_zeroing_n_pcache_coords(rdman); |
2007 if(r != OK) | 2107 if(r != OK) |
2008 return ERR; | 2108 return ERR; |
2009 | 2109 |
2010 r = zeroing_rdman_coords(rdman); | 2110 r = zeroing_rdman_coords(rdman); |
2011 if(r != OK) | 2111 if(r != OK) |
2012 return ERR; | 2112 return ERR; |
2013 | 2113 |
2014 r = compute_rdman_coords_pcache_area(rdman); | 2114 r = add_rdman_aggr_dirty_areas(rdman); |
2015 if(r != OK) | 2115 if(r != OK) |
2016 return ERR; | 2116 return ERR; |
2017 | 2117 |
2018 r = add_rdman_aggr_dirty_areas(rdman); | 2118 r = update_aggr_pdev(rdman); |
2019 if(r != OK) | 2119 if(r != OK) |
2020 return ERR; | 2120 return ERR; |
2021 | 2121 |
2022 /* | 2122 /* |
2023 * Clear all flags setted by zeroing. | 2123 * Clear all flags setted by zeroing. |
2033 } | 2133 } |
2034 coords = rdman->zeroing_coords.ds; | 2134 coords = rdman->zeroing_coords.ds; |
2035 for(i = 0; i < rdman->zeroing_coords.num; i++) | 2135 for(i = 0; i < rdman->zeroing_coords.num; i++) |
2036 coord_clear_flags(coords[i], | 2136 coord_clear_flags(coords[i], |
2037 COF_JUST_CLEAN | COF_JUST_ZERO | COF_SKIP_ZERO); | 2137 COF_JUST_CLEAN | COF_JUST_ZERO | COF_SKIP_ZERO); |
2038 coords = rdman->dirty_pcache_area_coords.ds; | |
2039 for(i = 0; i < rdman->dirty_pcache_area_coords.num; i++) | |
2040 coord_clear_flags(coords[i], | |
2041 COF_JUST_CLEAN | COF_JUST_ZERO | COF_SKIP_ZERO); | |
2042 | 2138 |
2043 /* \see GEO_SWAP() */ | 2139 /* \see GEO_SWAP() */ |
2044 for(i = 0; i < rdman->dirty_geos.num; i++) { | 2140 for(i = 0; i < rdman->dirty_geos.num; i++) { |
2045 geo = geos[i]; | 2141 geo = geos[i]; |
2046 geo_clear_flags(geo, GEF_SWAP); | 2142 geo_clear_flags(geo, GEF_SWAP); |
2047 } | 2143 } |
2048 | 2144 |
2049 return OK; | 2145 return OK; |
2050 } | 2146 } |
2051 | 2147 |
2052 | 2148 |
2053 /* Drawing and Redrawing | 2149 /* Drawing and Redrawing |
2057 #ifndef UNITTEST | 2153 #ifndef UNITTEST |
2058 static void set_shape_stroke_param(shape_t *shape, mbe_t *cr) { | 2154 static void set_shape_stroke_param(shape_t *shape, mbe_t *cr) { |
2059 mbe_set_line_width(cr, shape->stroke_width); | 2155 mbe_set_line_width(cr, shape->stroke_width); |
2060 } | 2156 } |
2061 | 2157 |
2062 static void fill_path_preserve(redraw_man_t *rdman) { | 2158 static void fill_path_preserve(redraw_man_t *rdman, mbe_t *cr) { |
2063 mbe_fill_preserve(rdman->cr); | 2159 mbe_fill_preserve(cr); |
2064 } | 2160 } |
2065 | 2161 |
2066 static void fill_path(redraw_man_t *rdman) { | 2162 static void fill_path(redraw_man_t *rdman, mbe_t *cr) { |
2067 mbe_fill(rdman->cr); | 2163 mbe_fill(cr); |
2068 } | 2164 } |
2069 | 2165 |
2070 static void stroke_path(redraw_man_t *rdman) { | 2166 static void stroke_path(redraw_man_t *rdman, mbe_t *cr) { |
2071 mbe_stroke(rdman->cr); | 2167 mbe_stroke(cr); |
2072 } | 2168 } |
2073 #else | 2169 #else |
2074 static void set_shape_stroke_param(shape_t *shape, mbe_t *cr) { | 2170 static void set_shape_stroke_param(shape_t *shape, mbe_t *cr) { |
2075 } | 2171 } |
2076 | 2172 |
2077 static void fill_path_preserve(redraw_man_t *rdman) { | 2173 static void fill_path_preserve(redraw_man_t *rdman, mbe_t *cr) { |
2078 } | 2174 } |
2079 | 2175 |
2080 static void fill_path(redraw_man_t *rdman) { | 2176 static void fill_path(redraw_man_t *rdman, mbe_t *cr) { |
2081 } | 2177 } |
2082 | 2178 |
2083 static void stroke_path(redraw_man_t *rdman) { | 2179 static void stroke_path(redraw_man_t *rdman, mbe_t *cr) { |
2084 } | 2180 } |
2085 #endif | 2181 #endif |
2086 | 2182 |
2087 static void draw_shape(redraw_man_t *rdman, mbe_t *cr, shape_t *shape) { | 2183 static void draw_shape(redraw_man_t *rdman, mbe_t *cr, shape_t *shape) { |
2088 paint_t *fill, *stroke; | 2184 paint_t *fill, *stroke; |
2118 #endif /* UNITTEST */ | 2214 #endif /* UNITTEST */ |
2119 } | 2215 } |
2120 | 2216 |
2121 fill = shape->fill; | 2217 fill = shape->fill; |
2122 if(shape->fill) { | 2218 if(shape->fill) { |
2123 fill->prepare(fill, cr); | 2219 fill->prepare(fill, cr, shape); |
2124 if(shape->stroke) | 2220 if(shape->stroke) |
2125 fill_path_preserve(rdman); | 2221 fill_path_preserve(rdman, cr); |
2126 else | 2222 else |
2127 fill_path(rdman); | 2223 fill_path(rdman, cr); |
2128 } | 2224 } |
2129 | 2225 |
2130 stroke = shape->stroke; | 2226 stroke = shape->stroke; |
2131 if(stroke) { | 2227 if(stroke) { |
2132 stroke->prepare(stroke, cr); | 2228 stroke->prepare(stroke, cr, shape); |
2133 set_shape_stroke_param(shape, cr); | 2229 set_shape_stroke_param(shape, cr); |
2134 stroke_path(rdman); | 2230 stroke_path(rdman, cr); |
2135 } | 2231 } |
2136 } | 2232 } |
2137 } | 2233 } |
2138 | 2234 |
2139 #ifndef UNITTEST | 2235 #ifndef UNITTEST |
2140 static void clear_canvas(canvas_t *canvas) { | 2236 static void clear_canvas(canvas_t *canvas) { |
2141 mbe_clear(canvas); | 2237 mbe_clear(canvas); |
2142 } | 2238 } |
2143 | 2239 |
2144 #define make_clip(canvas, n_dirty_areas, dirty_areas) \ | 2240 static void make_clip(mbe_t *cr, int n_dirty_areas, |
2145 mbe_scissoring(canvas, n_dirty_areas, dirty_areas) | 2241 area_t **dirty_areas) { |
2242 int i; | |
2243 area_t *area; | |
2244 | |
2245 mbe_new_path(cr); | |
2246 for(i = 0; i < n_dirty_areas; i++) { | |
2247 area = dirty_areas[i]; | |
2248 if(area->w < 0.1 || area->h < 0.1) | |
2249 continue; | |
2250 mbe_rectangle(cr, area->x, area->y, area->w, area->h); | |
2251 } | |
2252 mbe_clip(cr); | |
2253 } | |
2146 | 2254 |
2147 static void reset_clip(canvas_t *cr) { | 2255 static void reset_clip(canvas_t *cr) { |
2148 mbe_reset_scissoring(cr); | 2256 mbe_reset_clip(cr); |
2149 } | 2257 } |
2150 | 2258 |
2151 static void copy_cr_2_backend(redraw_man_t *rdman, int n_dirty_areas, | 2259 static void copy_cr_2_backend(redraw_man_t *rdman, int n_dirty_areas, |
2152 area_t **dirty_areas) { | 2260 area_t **dirty_areas) { |
2153 if(n_dirty_areas) | 2261 if(n_dirty_areas) |
2154 make_clip(rdman->backend, n_dirty_areas, dirty_areas); | 2262 make_clip(rdman->backend, n_dirty_areas, dirty_areas); |
2155 | 2263 |
2156 mbe_copy_source(rdman->cr, rdman->backend); | 2264 mbe_copy_source(rdman->cr, rdman->backend); |
2157 } | 2265 } |
2158 #else /* UNITTEST */ | 2266 #else /* UNITTEST */ |
2159 #define make_clip(canvas, n_dirty_areas, dirty_areas) | 2267 static void make_clip(mbe_t *cr, int n_dirty_areas, |
2268 area_t **dirty_areas) { | |
2269 } | |
2160 | 2270 |
2161 static void clear_canvas(canvas_t *canvas) { | 2271 static void clear_canvas(canvas_t *canvas) { |
2162 } | 2272 } |
2163 | 2273 |
2164 static void reset_clip(canvas_t *cr) { | 2274 static void reset_clip(canvas_t *cr) { |
2167 static void copy_cr_2_backend(redraw_man_t *rdman, int n_dirty_areas, | 2277 static void copy_cr_2_backend(redraw_man_t *rdman, int n_dirty_areas, |
2168 area_t **dirty_areas) { | 2278 area_t **dirty_areas) { |
2169 } | 2279 } |
2170 #endif /* UNITTEST */ | 2280 #endif /* UNITTEST */ |
2171 | 2281 |
2172 static void update_cached_canvas_2_parent(redraw_man_t *rdman, | 2282 static void |
2173 coord_t *coord) { | 2283 _update_cached_canvas_2_parent(redraw_man_t *rdman, co_aix reverse[6], |
2174 mbe_t *pcanvas, *canvas; | 2284 mbe_t *canvas, mbe_t *pcanvas, |
2285 co_aix opacity) { | |
2175 mbe_surface_t *surface; | 2286 mbe_surface_t *surface; |
2176 mbe_pattern_t *pattern; | 2287 mbe_pattern_t *pattern; |
2177 co_aix reverse[6]; | |
2178 co_aix canvas2pdev_matrix[6]; | |
2179 | |
2180 if(coord_is_root(coord)) | |
2181 return; | |
2182 | |
2183 compute_cached_2_pdev_matrix(coord, canvas2pdev_matrix); | |
2184 compute_reverse(canvas2pdev_matrix, reverse); | |
2185 | 2288 |
2186 canvas = _coord_get_canvas(coord); | |
2187 pcanvas = _coord_get_canvas(coord->parent); | |
2188 surface = mbe_get_target(canvas); | 2289 surface = mbe_get_target(canvas); |
2189 pattern = mbe_pattern_create_for_surface(surface); | 2290 pattern = mbe_pattern_create_for_surface(surface); |
2190 mbe_pattern_set_matrix(pattern, reverse); | 2291 mbe_pattern_set_matrix(pattern, reverse); |
2191 mbe_set_source(pcanvas, pattern); | 2292 mbe_set_source(pcanvas, pattern); |
2192 mbe_paint_with_alpha(pcanvas, coord->opacity); | 2293 mbe_paint_with_alpha(pcanvas, opacity); |
2294 } | |
2295 | |
2296 static void update_cached_canvas_2_parent(redraw_man_t *rdman, | |
2297 coord_t *coord) { | |
2298 mbe_t *pcanvas, *canvas; | |
2299 co_aix *c2pdev_reverse; | |
2300 | |
2301 if(coord_is_root(coord)) | |
2302 return; | |
2303 | |
2304 c2pdev_reverse = coord_get_2pdev_rev(coord); | |
2305 | |
2306 canvas = _coord_get_canvas(coord); | |
2307 pcanvas = _coord_get_canvas(coord->parent); | |
2308 #ifndef UNITTEST | |
2309 _update_cached_canvas_2_parent(rdman, c2pdev_reverse, canvas, pcanvas, | |
2310 coord->opacity); | |
2311 #else | |
2312 memcpy(((mock_mbe_t *)canvas)->parent_2_cache, c2pdev_reverse, | |
2313 sizeof(co_aix) * 6); | |
2314 #endif | |
2193 } | 2315 } |
2194 | 2316 |
2195 static int draw_coord_shapes_in_dirty_areas(redraw_man_t *rdman, | 2317 static int draw_coord_shapes_in_dirty_areas(redraw_man_t *rdman, |
2196 coord_t *coord) { | 2318 coord_t *coord) { |
2197 int dirty = 0; | 2319 int dirty = 0; |
2203 coord_t *child; | 2325 coord_t *child; |
2204 int mem_idx; | 2326 int mem_idx; |
2205 | 2327 |
2206 if(coord->flags & COF_HIDDEN) | 2328 if(coord->flags & COF_HIDDEN) |
2207 return OK; | 2329 return OK; |
2208 | 2330 |
2209 areas = _coord_get_dirty_areas(coord)->ds; | 2331 areas = _coord_get_dirty_areas(coord)->ds; |
2210 n_areas = _coord_get_dirty_areas(coord)->num; | 2332 n_areas = _coord_get_dirty_areas(coord)->num; |
2211 canvas = _coord_get_canvas(coord); | 2333 canvas = _coord_get_canvas(coord); |
2212 | 2334 |
2213 member = FIRST_MEMBER(coord); | 2335 member = FIRST_MEMBER(coord); |
2214 mem_idx = 0; | 2336 mem_idx = 0; |
2215 child = FIRST_CHILD(coord); | 2337 child = FIRST_CHILD(coord); |
2216 while(child != NULL || member != NULL) { | 2338 while(child != NULL || member != NULL) { |
2217 if(child && child->before_pmem == mem_idx) { | 2339 if(child && child->before_pmem == mem_idx) { |
2218 if(coord_is_cached(child)) { | 2340 if(coord_is_cached(child)) { |
2219 if(!(child->flags & COF_HIDDEN) && | 2341 if(!(child->flags & COF_HIDDEN) && |
2220 is_area_in_areas(coord_get_area(child), n_areas, areas)) { | 2342 is_area_in_areas(coord_get_pcache_area(child), |
2343 n_areas, areas)) { | |
2221 update_cached_canvas_2_parent(rdman, child); | 2344 update_cached_canvas_2_parent(rdman, child); |
2222 dirty = 1; | 2345 dirty = 1; |
2223 } | 2346 } |
2224 } else { | 2347 } else { |
2225 r = draw_coord_shapes_in_dirty_areas(rdman, child); | 2348 r = draw_coord_shapes_in_dirty_areas(rdman, child); |
2226 dirty |= r; | 2349 dirty |= r; |
2227 } | 2350 } |
2228 child = NEXT_CHILD(child); | 2351 child = NEXT_CHILD(child); |
2229 } else { | 2352 } else { |
2230 ASSERT(member != NULL); | 2353 ASSERT(member != NULL); |
2231 if((!(member->flags & GEF_HIDDEN)) && | 2354 if((!(member->flags & GEF_NOT_SHOWED)) && |
2232 is_geo_in_areas(member, n_areas, areas)) { | 2355 is_geo_in_areas(member, n_areas, areas)) { |
2233 draw_shape(rdman, canvas, member->shape); | 2356 draw_shape(rdman, canvas, member->shape); |
2234 dirty = 1; | 2357 dirty = 1; |
2235 } | 2358 } |
2236 | 2359 |
2249 int n_areas; | 2372 int n_areas; |
2250 mbe_t *canvas; | 2373 mbe_t *canvas; |
2251 mbe_surface_t *surface; | 2374 mbe_surface_t *surface; |
2252 int i; | 2375 int i; |
2253 int r; | 2376 int r; |
2254 | 2377 |
2255 canvas = _coord_get_canvas(coord); | 2378 canvas = _coord_get_canvas(coord); |
2256 | 2379 |
2257 if(IS_CACHE_REDRAW_ALL(coord)) { | 2380 if(IS_CACHE_REDRAW_ALL(coord)) { |
2258 /* | 2381 /* |
2259 * full_area covers all dirty areas of the cached coord. | 2382 * full_area covers all dirty areas of the cached coord. |
2260 */ | 2383 */ |
2261 DARRAY_CLEAN(_coord_get_dirty_areas(coord)); | 2384 DARRAY_CLEAN(_coord_get_dirty_areas(coord)); |
2267 add_dirty_area(rdman, coord, &full_area); | 2390 add_dirty_area(rdman, coord, &full_area); |
2268 } | 2391 } |
2269 | 2392 |
2270 areas = _coord_get_dirty_areas(coord)->ds; | 2393 areas = _coord_get_dirty_areas(coord)->ds; |
2271 n_areas = _coord_get_dirty_areas(coord)->num; | 2394 n_areas = _coord_get_dirty_areas(coord)->num; |
2272 | 2395 |
2273 for(i = 0; i < n_areas; i++) { | 2396 for(i = 0; i < n_areas; i++) { |
2274 area = areas[i]; | 2397 area = areas[i]; |
2275 area->x = floorf(area->x); | 2398 area->x = floorf(area->x); |
2276 area->y = floorf(area->y); | 2399 area->y = floorf(area->y); |
2277 area->w = ceilf(area->w); | 2400 area->w = ceilf(area->w); |
2280 | 2403 |
2281 make_clip(canvas, n_areas, areas); | 2404 make_clip(canvas, n_areas, areas); |
2282 clear_canvas(canvas); | 2405 clear_canvas(canvas); |
2283 | 2406 |
2284 r = draw_coord_shapes_in_dirty_areas(rdman, coord); | 2407 r = draw_coord_shapes_in_dirty_areas(rdman, coord); |
2285 | 2408 |
2286 reset_clip(canvas); | 2409 reset_clip(canvas); |
2287 | 2410 |
2288 return OK; | 2411 return OK; |
2289 } | 2412 } |
2290 | 2413 |
2304 if(coord_get_flags(coord, COF_TEMP_MARK)) | 2427 if(coord_get_flags(coord, COF_TEMP_MARK)) |
2305 continue; | 2428 continue; |
2306 draw_dirty_cached_coord(rdman, coord); | 2429 draw_dirty_cached_coord(rdman, coord); |
2307 coord_set_flags(coord, COF_TEMP_MARK); | 2430 coord_set_flags(coord, COF_TEMP_MARK); |
2308 } | 2431 } |
2309 for(i = 0; i < num; i++) | 2432 for(i = 0; i < num; i++) { |
2433 coord = zeroings[i]; | |
2310 coord_clear_flags(coord, COF_TEMP_MARK); | 2434 coord_clear_flags(coord, COF_TEMP_MARK); |
2435 } | |
2311 | 2436 |
2312 draw_dirty_cached_coord(rdman, rdman->root_coord); | 2437 draw_dirty_cached_coord(rdman, rdman->root_coord); |
2313 } | 2438 } |
2314 | 2439 |
2315 | 2440 |
2348 int rdman_redraw_changed(redraw_man_t *rdman) { | 2473 int rdman_redraw_changed(redraw_man_t *rdman) { |
2349 int r; | 2474 int r; |
2350 event_t event; | 2475 event_t event; |
2351 subject_t *redraw; | 2476 subject_t *redraw; |
2352 int i; | 2477 int i; |
2353 coord_t *coord, **coords; | 2478 coord_t *coord; |
2354 int n_areas; | 2479 int n_areas; |
2355 area_t **areas; | 2480 area_t **areas; |
2356 | 2481 |
2357 r = rdman_clean_dirties(rdman); | 2482 r = rdman_clean_dirties(rdman); |
2358 if(r != OK) | 2483 if(r != OK) |
2359 return ERR; | 2484 return ERR; |
2360 | 2485 |
2361 if(rdman->n_dirty_areas > 0) { | 2486 if(rdman->n_dirty_areas > 0) { |
2376 } | 2501 } |
2377 | 2502 |
2378 DARRAY_CLEAN(&rdman->dirty_coords); | 2503 DARRAY_CLEAN(&rdman->dirty_coords); |
2379 DARRAY_CLEAN(&rdman->dirty_geos); | 2504 DARRAY_CLEAN(&rdman->dirty_geos); |
2380 DARRAY_CLEAN(&rdman->zeroing_coords); | 2505 DARRAY_CLEAN(&rdman->zeroing_coords); |
2381 DARRAY_CLEAN(&rdman->dirty_pcache_area_coords); | 2506 |
2382 | |
2383 /* Free postponsed removing */ | 2507 /* Free postponsed removing */ |
2384 free_free_objs(rdman); | 2508 free_free_objs(rdman); |
2385 | 2509 |
2386 redraw = rdman_get_redraw_subject(rdman); | 2510 redraw = rdman_get_redraw_subject(rdman); |
2387 event.type = EVT_RDMAN_REDRAW; | 2511 event.type = EVT_RDMAN_REDRAW; |
2439 /*! \brief Helping function to travel descendant shapes of a coord. | 2563 /*! \brief Helping function to travel descendant shapes of a coord. |
2440 */ | 2564 */ |
2441 geo_t *rdman_geos(redraw_man_t *rdman, geo_t *last) { | 2565 geo_t *rdman_geos(redraw_man_t *rdman, geo_t *last) { |
2442 geo_t *next; | 2566 geo_t *next; |
2443 coord_t *coord; | 2567 coord_t *coord; |
2444 | 2568 |
2445 if(last == NULL) { | 2569 if(last == NULL) { |
2446 coord = rdman->root_coord; | 2570 coord = rdman->root_coord; |
2447 while(coord != NULL && FIRST_MEMBER(coord) == NULL) | 2571 while(coord != NULL && FIRST_MEMBER(coord) == NULL) |
2448 coord = preorder_coord_subtree(rdman->root_coord, coord); | 2572 coord = preorder_coord_subtree(rdman->root_coord, coord); |
2449 if(coord == NULL) | 2573 if(coord == NULL) |
2495 /* \defgroup rdman_observer Observer memory management | 2619 /* \defgroup rdman_observer Observer memory management |
2496 * | 2620 * |
2497 * Implment factory and strategy functions for observers and subjects. | 2621 * Implment factory and strategy functions for observers and subjects. |
2498 * @{ | 2622 * @{ |
2499 */ | 2623 */ |
2500 static subject_t *ob_subject_alloc(ob_factory_t *factory) { | 2624 static subject_t *observer_subject_alloc(observer_factory_t *factory) { |
2501 redraw_man_t *rdman; | 2625 redraw_man_t *rdman; |
2502 subject_t *subject; | 2626 subject_t *subject; |
2503 | 2627 |
2504 rdman = MEM2OBJ(factory, redraw_man_t, ob_factory); | 2628 rdman = MEM2OBJ(factory, redraw_man_t, observer_factory); |
2505 subject = elmpool_elm_alloc(rdman->subject_pool); | 2629 subject = elmpool_elm_alloc(rdman->subject_pool); |
2506 | 2630 |
2507 return subject; | 2631 return subject; |
2508 } | 2632 } |
2509 | 2633 |
2510 static void ob_subject_free(ob_factory_t *factory, subject_t *subject) { | 2634 static void |
2635 observer_subject_free(observer_factory_t *factory, subject_t *subject) { | |
2511 redraw_man_t *rdman; | 2636 redraw_man_t *rdman; |
2512 | 2637 |
2513 rdman = MEM2OBJ(factory, redraw_man_t, ob_factory); | 2638 rdman = MEM2OBJ(factory, redraw_man_t, observer_factory); |
2514 elmpool_elm_free(rdman->subject_pool, subject); | 2639 elmpool_elm_free(rdman->subject_pool, subject); |
2515 } | 2640 } |
2516 | 2641 |
2517 static observer_t *ob_observer_alloc(ob_factory_t *factory) { | 2642 static observer_t *observer_observer_alloc(observer_factory_t *factory) { |
2518 redraw_man_t *rdman; | 2643 redraw_man_t *rdman; |
2519 observer_t *observer; | 2644 observer_t *observer; |
2520 | 2645 |
2521 rdman = MEM2OBJ(factory, redraw_man_t, ob_factory); | 2646 rdman = MEM2OBJ(factory, redraw_man_t, observer_factory); |
2522 observer = elmpool_elm_alloc(rdman->observer_pool); | 2647 observer = elmpool_elm_alloc(rdman->observer_pool); |
2523 | 2648 |
2524 return observer; | 2649 return observer; |
2525 } | 2650 } |
2526 | 2651 |
2527 static void ob_observer_free(ob_factory_t *factory, observer_t *observer) { | 2652 static void |
2653 observer_observer_free(observer_factory_t *factory, observer_t *observer) { | |
2528 redraw_man_t *rdman; | 2654 redraw_man_t *rdman; |
2529 | 2655 |
2530 rdman = MEM2OBJ(factory, redraw_man_t, ob_factory); | 2656 rdman = MEM2OBJ(factory, redraw_man_t, observer_factory); |
2531 elmpool_elm_free(rdman->observer_pool, observer); | 2657 elmpool_elm_free(rdman->observer_pool, observer); |
2532 } | 2658 } |
2533 | 2659 |
2534 static subject_t *ob_get_parent_subject(ob_factory_t *factory, | 2660 static subject_t * |
2535 subject_t *cur_subject) { | 2661 observer_get_parent_subject(observer_factory_t *factory, |
2662 subject_t *cur_subject) { | |
2536 redraw_man_t *rdman; | 2663 redraw_man_t *rdman; |
2537 coord_t *coord, *parent_coord; | 2664 coord_t *coord, *parent_coord; |
2538 geo_t *geo; | 2665 geo_t *geo; |
2539 subject_t *parent; | 2666 subject_t *parent; |
2540 | 2667 |
2541 rdman = MEM2OBJ(factory, redraw_man_t, ob_factory); | 2668 rdman = MEM2OBJ(factory, redraw_man_t, observer_factory); |
2542 switch(cur_subject->obj_type) { | 2669 switch(cur_subject->obj_type) { |
2543 case OBJT_GEO: | 2670 case OBJT_GEO: |
2544 geo = (geo_t *)cur_subject->obj; | 2671 geo = (geo_t *)cur_subject->obj; |
2545 parent_coord = geo->shape->coord; | 2672 parent_coord = geo->shape->coord; |
2546 parent = parent_coord->mouse_event; | 2673 parent = parent_coord->mouse_event; |
2568 */ | 2695 */ |
2569 paint_t *rdman_img_ldr_load_paint(redraw_man_t *rdman, const char *img_id) { | 2696 paint_t *rdman_img_ldr_load_paint(redraw_man_t *rdman, const char *img_id) { |
2570 mb_img_data_t *img_data; | 2697 mb_img_data_t *img_data; |
2571 paint_t *paint; | 2698 paint_t *paint; |
2572 mb_img_ldr_t *ldr = rdman_img_ldr(rdman); | 2699 mb_img_ldr_t *ldr = rdman_img_ldr(rdman); |
2573 | 2700 |
2574 img_data = MB_IMG_LDR_LOAD(ldr, img_id); | 2701 img_data = MB_IMG_LDR_LOAD(ldr, img_id); |
2575 if(img_data == NULL) | 2702 if(img_data == NULL) |
2576 return NULL; | 2703 return NULL; |
2577 | 2704 |
2578 paint = rdman_paint_image_new(rdman, img_data); | 2705 paint = rdman_paint_image_new(rdman, img_data); |
2579 if(paint == NULL) | 2706 if(paint == NULL) |
2580 MB_IMG_DATA_FREE(img_data); | 2707 MB_IMG_DATA_FREE(img_data); |
2581 | 2708 |
2582 return paint; | 2709 return paint; |
2583 } | 2710 } |
2584 | 2711 |
2585 #ifdef UNITTEST | 2712 #ifdef UNITTEST |
2586 /* Test cases */ | 2713 /* Test cases */ |
2591 shape_t shape; | 2718 shape_t shape; |
2592 co_aix x, y; | 2719 co_aix x, y; |
2593 co_aix w, h; | 2720 co_aix w, h; |
2594 int trans_cnt; | 2721 int trans_cnt; |
2595 int draw_cnt; | 2722 int draw_cnt; |
2723 mbe_t *last_draw; | |
2596 }; | 2724 }; |
2597 | 2725 |
2598 void sh_dummy_free(shape_t *sh) { | 2726 void sh_dummy_free(shape_t *sh) { |
2599 free(sh); | 2727 free(sh); |
2600 } | 2728 } |
2614 dummy->w = w; | 2742 dummy->w = w; |
2615 dummy->h = h; | 2743 dummy->h = h; |
2616 dummy->trans_cnt = 0; | 2744 dummy->trans_cnt = 0; |
2617 dummy->draw_cnt = 0; | 2745 dummy->draw_cnt = 0; |
2618 dummy->shape.free = sh_dummy_free; | 2746 dummy->shape.free = sh_dummy_free; |
2619 | 2747 |
2620 rdman_shape_man(rdman, (shape_t *)dummy); | 2748 rdman_man_shape(rdman, (shape_t *)dummy); |
2621 | 2749 |
2622 return (shape_t *)dummy; | 2750 return (shape_t *)dummy; |
2623 } | 2751 } |
2624 | 2752 |
2625 void sh_dummy_transform(shape_t *shape) { | 2753 void sh_dummy_transform(shape_t *shape) { |
2626 sh_dummy_t *dummy = (sh_dummy_t *)shape; | 2754 sh_dummy_t *dummy = (sh_dummy_t *)shape; |
2627 co_aix poses[2][2]; | 2755 co_aix poses[2][2]; |
2628 co_aix x1, y1, x2, y2; | 2756 co_aix x1, y1, x2, y2; |
2629 | 2757 |
2630 if(shape->geo && shape->coord) { | 2758 if(shape->geo && shape->coord) { |
2631 x1 = dummy->x; | 2759 x1 = dummy->x; |
2632 y1 = dummy->y; | 2760 y1 = dummy->y; |
2633 x2 = x1 + dummy->w; | 2761 x2 = x1 + dummy->w; |
2634 y2 = y1 + dummy->h; | 2762 y2 = y1 + dummy->h; |
2637 coord_trans_pos(shape->coord, &x2, &y2); | 2765 coord_trans_pos(shape->coord, &x2, &y2); |
2638 poses[0][0] = x1; | 2766 poses[0][0] = x1; |
2639 poses[0][1] = y1; | 2767 poses[0][1] = y1; |
2640 poses[1][0] = x2; | 2768 poses[1][0] = x2; |
2641 poses[1][1] = y2; | 2769 poses[1][1] = y2; |
2642 | 2770 |
2643 if(shape->geo) | 2771 if(shape->geo) |
2644 geo_from_positions(shape->geo, 2, poses); | 2772 geo_from_positions(shape->geo, 2, poses); |
2645 } | 2773 } |
2646 dummy->trans_cnt++; | 2774 dummy->trans_cnt++; |
2647 } | 2775 } |
2649 void sh_dummy_fill(shape_t *shape, mbe_t *cr) { | 2777 void sh_dummy_fill(shape_t *shape, mbe_t *cr) { |
2650 sh_dummy_t *dummy; | 2778 sh_dummy_t *dummy; |
2651 | 2779 |
2652 dummy = (sh_dummy_t *)shape; | 2780 dummy = (sh_dummy_t *)shape; |
2653 dummy->draw_cnt++; | 2781 dummy->draw_cnt++; |
2782 dummy->last_draw = cr; | |
2654 } | 2783 } |
2655 | 2784 |
2656 static void dummy_paint_prepare(paint_t *paint, mbe_t *cr) { | 2785 static void dummy_paint_prepare(paint_t *paint, mbe_t *cr) { |
2657 } | 2786 } |
2658 | 2787 |
2701 CU_ASSERT(dummys[1]->trans_cnt == 1); | 2830 CU_ASSERT(dummys[1]->trans_cnt == 1); |
2702 CU_ASSERT(dummys[2]->trans_cnt == 1); | 2831 CU_ASSERT(dummys[2]->trans_cnt == 1); |
2703 CU_ASSERT(dummys[0]->draw_cnt == 1); | 2832 CU_ASSERT(dummys[0]->draw_cnt == 1); |
2704 CU_ASSERT(dummys[1]->draw_cnt == 1); | 2833 CU_ASSERT(dummys[1]->draw_cnt == 1); |
2705 CU_ASSERT(dummys[2]->draw_cnt == 1); | 2834 CU_ASSERT(dummys[2]->draw_cnt == 1); |
2706 | 2835 |
2707 coords[2]->matrix[2] = 100; | 2836 coords[2]->matrix[2] = 100; |
2708 coords[2]->matrix[5] = 100; | 2837 coords[2]->matrix[5] = 100; |
2709 rdman_coord_changed(rdman, coords[0]); | 2838 rdman_coord_changed(rdman, coords[0]); |
2710 rdman_coord_changed(rdman, coords[2]); | 2839 rdman_coord_changed(rdman, coords[2]); |
2711 rdman_redraw_changed(rdman); | 2840 rdman_redraw_changed(rdman); |
2739 | 2868 |
2740 redraw_man_destroy(rdman); | 2869 redraw_man_destroy(rdman); |
2741 CU_ASSERT(test_free_pass == 4); | 2870 CU_ASSERT(test_free_pass == 4); |
2742 } | 2871 } |
2743 | 2872 |
2873 static void | |
2874 test_setup_canvas_info(void) { | |
2875 redraw_man_t *rdman; | |
2876 redraw_man_t _rdman; | |
2877 coord_t *coord; | |
2878 | |
2879 redraw_man_init(&_rdman, NULL, NULL); | |
2880 rdman = &_rdman; | |
2881 | |
2882 coord = rdman_coord_new(rdman, rdman->root_coord); | |
2883 CU_ASSERT(coord->parent == rdman->root_coord); | |
2884 | |
2885 coord_set_opacity(coord, 0.9); | |
2886 setup_canvas_info(rdman, coord); | |
2887 | |
2888 CU_ASSERT(coord->canvas_info != rdman->root_coord->canvas_info); | |
2889 | |
2890 coord_set_opacity(coord, 1); | |
2891 setup_canvas_info(rdman, coord); | |
2892 | |
2893 CU_ASSERT(coord->canvas_info == rdman->root_coord->canvas_info); | |
2894 } | |
2895 | |
2896 static void | |
2897 test_own_canvas_area(void) { | |
2898 redraw_man_t *rdman; | |
2899 redraw_man_t _rdman; | |
2900 coord_t *coord1, *coord2; | |
2901 sh_dummy_t *sh; | |
2902 | |
2903 redraw_man_init(&_rdman, NULL, NULL); | |
2904 rdman = &_rdman; | |
2905 | |
2906 coord1 = rdman_coord_new(rdman, rdman->root_coord); | |
2907 CU_ASSERT(coord1->parent == rdman->root_coord); | |
2908 | |
2909 coord2 = rdman_coord_new(rdman, coord1); | |
2910 CU_ASSERT(coord2->parent == coord1); | |
2911 | |
2912 coord_set_opacity(coord2, 0.9); | |
2913 rdman_coord_changed(rdman, coord2); | |
2914 | |
2915 sh = (sh_dummy_t *)sh_dummy_new(rdman, 100, 100, 20, 20); | |
2916 rdman_add_shape(rdman, (shape_t *)sh, coord2); | |
2917 rdman_shape_changed(rdman, (shape_t *)sh); | |
2918 | |
2919 clean_coord(rdman, coord2); | |
2920 | |
2921 /* Parent cached coord must be updated */ | |
2922 CU_ASSERT(geo_get_area(coord2)->x == 100); | |
2923 CU_ASSERT(geo_get_area(coord2)->y == 100); | |
2924 CU_ASSERT(geo_get_area(coord2)->w <= 22 && geo_get_area(coord2)->w >= 19); | |
2925 CU_ASSERT(geo_get_area(coord2)->h <= 22 && geo_get_area(coord2)->h >= 19); | |
2926 | |
2927 redraw_man_destroy(rdman); | |
2928 } | |
2929 | |
2930 static void | |
2931 test_own_canvas(void) { | |
2932 redraw_man_t *rdman; | |
2933 redraw_man_t _rdman; | |
2934 coord_t *coord1, *coord2; | |
2935 sh_dummy_t *sh; | |
2936 | |
2937 redraw_man_init(&_rdman, NULL, NULL); | |
2938 rdman = &_rdman; | |
2939 | |
2940 coord1 = rdman_coord_new(rdman, rdman->root_coord); | |
2941 CU_ASSERT(coord1->parent == rdman->root_coord); | |
2942 | |
2943 coord2 = rdman_coord_new(rdman, coord1); | |
2944 CU_ASSERT(coord2->parent == coord1); | |
2945 | |
2946 coord_set_opacity(coord2, 0.9); | |
2947 rdman_coord_changed(rdman, coord2); | |
2948 | |
2949 sh = (sh_dummy_t *)sh_dummy_new(rdman, 100, 100, 20, 20); | |
2950 rdman_add_shape(rdman, (shape_t *)sh, coord2); | |
2951 rdman_shape_changed(rdman, (shape_t *)sh); | |
2952 | |
2953 rdman_clean_dirties(rdman); | |
2954 | |
2955 /* Parent cached coord must be updated */ | |
2956 CU_ASSERT(_coord_get_dirty_areas(rdman->root_coord)->num == 1); | |
2957 | |
2958 CU_ASSERT(geo_get_area(coord2)->x == 0); | |
2959 CU_ASSERT(geo_get_area(coord2)->y == 0); | |
2960 CU_ASSERT(geo_get_area(coord2)->w <= 22 && geo_get_area(coord2)->w >= 19); | |
2961 CU_ASSERT(geo_get_area(coord2)->h <= 22 && geo_get_area(coord2)->h >= 19); | |
2962 | |
2963 redraw_man_destroy(rdman); | |
2964 } | |
2965 | |
2966 static void | |
2967 test_own_canvas_redraw(void) { | |
2968 redraw_man_t *rdman; | |
2969 redraw_man_t _rdman; | |
2970 coord_t *coord1, *coord2; | |
2971 sh_dummy_t *sh; | |
2972 paint_t *paint; | |
2973 co_aix *parent_2_cache; | |
2974 | |
2975 redraw_man_init(&_rdman, NULL, NULL); | |
2976 rdman = &_rdman; | |
2977 | |
2978 coord1 = rdman_coord_new(rdman, rdman->root_coord); | |
2979 CU_ASSERT(coord1->parent == rdman->root_coord); | |
2980 | |
2981 coord2 = rdman_coord_new(rdman, coord1); | |
2982 CU_ASSERT(coord2->parent == coord1); | |
2983 | |
2984 coord_set_opacity(coord2, 0.9); | |
2985 rdman_coord_changed(rdman, coord2); | |
2986 | |
2987 sh = (sh_dummy_t *)sh_dummy_new(rdman, 100, 100, 20, 20); | |
2988 rdman_add_shape(rdman, (shape_t *)sh, coord2); | |
2989 rdman_shape_changed(rdman, (shape_t *)sh); | |
2990 | |
2991 paint = dummy_paint_new(rdman); | |
2992 rdman_paint_fill(rdman, paint, (shape_t *)sh); | |
2993 | |
2994 rdman_redraw_all(rdman); | |
2995 | |
2996 CU_ASSERT(sh->draw_cnt == 1); | |
2997 CU_ASSERT(sh->last_draw == _coord_get_canvas(coord2)); | |
2998 | |
2999 parent_2_cache = ((mock_mbe_t *)_coord_get_canvas(coord2))->parent_2_cache; | |
3000 CU_ASSERT(parent_2_cache[0] == 1); | |
3001 CU_ASSERT(parent_2_cache[1] == 0); | |
3002 CU_ASSERT(parent_2_cache[2] == -100); | |
3003 CU_ASSERT(parent_2_cache[3] == 0); | |
3004 CU_ASSERT(parent_2_cache[4] == 1); | |
3005 CU_ASSERT(parent_2_cache[5] == -100); | |
3006 | |
3007 coord2->matrix[2] = 20; | |
3008 coord2->matrix[5] = 30; | |
3009 rdman_coord_changed(rdman, coord2); | |
3010 rdman_redraw_changed(rdman); | |
3011 | |
3012 /* To test if transform matrix of cached coord working */ | |
3013 parent_2_cache = ((mock_mbe_t *)_coord_get_canvas(coord2))->parent_2_cache; | |
3014 CU_ASSERT(parent_2_cache[0] == 1); | |
3015 CU_ASSERT(parent_2_cache[1] == 0); | |
3016 CU_ASSERT(parent_2_cache[2] == -120); | |
3017 CU_ASSERT(parent_2_cache[3] == 0); | |
3018 CU_ASSERT(parent_2_cache[4] == 1); | |
3019 CU_ASSERT(parent_2_cache[5] == -130); | |
3020 | |
3021 rdman_paint_free(rdman, paint); | |
3022 redraw_man_destroy(rdman); | |
3023 } | |
3024 | |
2744 CU_pSuite get_redraw_man_suite(void) { | 3025 CU_pSuite get_redraw_man_suite(void) { |
2745 CU_pSuite suite; | 3026 CU_pSuite suite; |
2746 | 3027 |
2747 suite = CU_add_suite("Suite_redraw_man", NULL, NULL); | 3028 suite = CU_add_suite("Suite_redraw_man", NULL, NULL); |
2748 CU_ADD_TEST(suite, test_rdman_redraw_changed); | 3029 CU_ADD_TEST(suite, test_rdman_redraw_changed); |
2749 CU_ADD_TEST(suite, test_rdman_free_objs); | 3030 CU_ADD_TEST(suite, test_rdman_free_objs); |
3031 CU_ADD_TEST(suite, test_setup_canvas_info); | |
3032 CU_ADD_TEST(suite, test_own_canvas_area); | |
3033 CU_ADD_TEST(suite, test_own_canvas); | |
3034 CU_ADD_TEST(suite, test_own_canvas_redraw); | |
2750 | 3035 |
2751 return suite; | 3036 return suite; |
2752 } | 3037 } |
2753 | 3038 |
2754 #endif /* UNITTEST */ | 3039 #endif /* UNITTEST */ |