comparison src/redraw_man.c @ 822:586e50f82c1f

Unify coding style tag for emacs and vim.
author Shih-Yuan Lee (FourDollars) <fourdollars@gmail.com>
date Tue, 14 Sep 2010 01:08:39 +0800
parents 86f2c59cef09
children 94041f085797
comparison
equal deleted inserted replaced
821:bfdc82bbd6e4 822:586e50f82c1f
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.
454 return OK; 456 return OK;
455 } 457 }
456 458
457 static int add_dirty_area(redraw_man_t *rdman, coord_t *coord, area_t *area) { 459 static int add_dirty_area(redraw_man_t *rdman, coord_t *coord, area_t *area) {
458 int r; 460 int r;
459 461
460 if(area->w < 0.01 || area->h < 0.01) 462 if(area->w < 0.01 || area->h < 0.01)
461 return OK; 463 return OK;
462 464
463 rdman->n_dirty_areas++; 465 rdman->n_dirty_areas++;
464 r = areas_add(_coord_get_dirty_areas(coord), area); 466 r = areas_add(_coord_get_dirty_areas(coord), area);
465 return r == 0? OK: ERR; 467 return r == 0? OK: ERR;
466 } 468 }
467 469
519 521
520 static mbe_t *canvas_new(int w, int h) { 522 static mbe_t *canvas_new(int w, int h) {
521 #ifndef UNITTEST 523 #ifndef UNITTEST
522 mbe_surface_t *surface; 524 mbe_surface_t *surface;
523 mbe_t *cr; 525 mbe_t *cr;
524 526
525 surface = mbe_image_surface_create(MB_IFMT_ARGB32, 527 surface = mbe_image_surface_create(MB_IFMT_ARGB32,
526 w, h); 528 w, h);
527 cr = mbe_create(surface); 529 cr = mbe_create(surface);
528 530
529 return cr; 531 return cr;
592 coord_canvas_info_t *info; 594 coord_canvas_info_t *info;
593 595
594 info = (coord_canvas_info_t *)elmpool_elm_alloc(rdman->coord_canvas_pool); 596 info = (coord_canvas_info_t *)elmpool_elm_alloc(rdman->coord_canvas_pool);
595 if(info == NULL) 597 if(info == NULL)
596 return info; 598 return info;
597 599
598 info->owner = coord; 600 info->owner = coord;
599 info->canvas = canvas; 601 info->canvas = canvas;
600 DARRAY_INIT(&info->dirty_areas); 602 DARRAY_INIT(&info->dirty_areas);
601 603
602 bzero(info->pcache_areas, sizeof(area_t) * 2); 604 bzero(info->pcache_areas, sizeof(area_t) * 2);
603 info->pcache_cur_area = &info->pcache_areas[0]; 605 info->pcache_cur_area = &info->pcache_areas[0];
604 info->pcache_last_area = &info->pcache_areas[1]; 606 info->pcache_last_area = &info->pcache_areas[1];
605 607
606 return info; 608 return info;
626 DARRAY_INIT(&rdman->dirty_coords); 628 DARRAY_INIT(&rdman->dirty_coords);
627 DARRAY_INIT(&rdman->dirty_pcache_area_coords); 629 DARRAY_INIT(&rdman->dirty_pcache_area_coords);
628 DARRAY_INIT(&rdman->dirty_geos); 630 DARRAY_INIT(&rdman->dirty_geos);
629 DARRAY_INIT(&rdman->gen_geos); 631 DARRAY_INIT(&rdman->gen_geos);
630 DARRAY_INIT(&rdman->zeroing_coords); 632 DARRAY_INIT(&rdman->zeroing_coords);
631 633
632 rdman->geo_pool = elmpool_new(sizeof(geo_t), 128); 634 rdman->geo_pool = elmpool_new(sizeof(geo_t), 128);
633 rdman->coord_pool = elmpool_new(sizeof(coord_t), 16); 635 rdman->coord_pool = elmpool_new(sizeof(coord_t), 16);
634 rdman->shnode_pool = elmpool_new(sizeof(shnode_t), 16); 636 rdman->shnode_pool = elmpool_new(sizeof(shnode_t), 16);
635 rdman->observer_pool = elmpool_new(sizeof(observer_t), 32); 637 rdman->observer_pool = elmpool_new(sizeof(observer_t), 32);
636 rdman->subject_pool = elmpool_new(sizeof(subject_t), 32); 638 rdman->subject_pool = elmpool_new(sizeof(subject_t), 32);
678 680
679 rdman->cr = cr; 681 rdman->cr = cr;
680 rdman->backend = backend; 682 rdman->backend = backend;
681 683
682 STAILQ_INIT(rdman->shapes); 684 STAILQ_INIT(rdman->shapes);
683 685
684 /* \note To make root coord always have at leat one observer. 686 /* \note To make root coord always have at leat one observer.
685 * It triggers mouse interpreter to be installed on root. 687 * It triggers mouse interpreter to be installed on root.
686 */ 688 */
687 subject_set_monitor(rdman->root_coord->mouse_event, 689 subject_set_monitor(rdman->root_coord->mouse_event,
688 rdman->addrm_monitor); 690 rdman->addrm_monitor);
748 */ 750 */
749 751
750 while((shape = STAILQ_HEAD(rdman->shapes)) != NULL) { 752 while((shape = STAILQ_HEAD(rdman->shapes)) != NULL) {
751 rdman_shape_free(rdman, shape); 753 rdman_shape_free(rdman, shape);
752 } 754 }
753 755
754 coord_canvas_info_free(rdman, rdman->root_coord->canvas_info); 756 coord_canvas_info_free(rdman, rdman->root_coord->canvas_info);
755 757
756 /* XXX: paints are not freed, here. All resources of paints would 758 /* XXX: paints are not freed, here. All resources of paints would
757 * be reclaimed by freeing elmpools. 759 * be reclaimed by freeing elmpools.
758 */ 760 */
759 761
760 elmpool_free(rdman->coord_pool); 762 elmpool_free(rdman->coord_pool);
761 elmpool_free(rdman->geo_pool); 763 elmpool_free(rdman->geo_pool);
762 elmpool_free(rdman->shnode_pool); 764 elmpool_free(rdman->shnode_pool);
763 elmpool_free(rdman->observer_pool); 765 elmpool_free(rdman->observer_pool);
764 elmpool_free(rdman->subject_pool); 766 elmpool_free(rdman->subject_pool);
802 int r; 804 int r;
803 805
804 geo = elmpool_elm_alloc(rdman->geo_pool); 806 geo = elmpool_elm_alloc(rdman->geo_pool);
805 if(geo == NULL) 807 if(geo == NULL)
806 return ERR; 808 return ERR;
807 809
808 geo_init(geo); 810 geo_init(geo);
809 geo->mouse_event = subject_new(&rdman->ob_factory, geo, OBJT_GEO); 811 geo->mouse_event = subject_new(&rdman->ob_factory, geo, OBJT_GEO);
810 subject_set_monitor(geo->mouse_event, rdman->addrm_monitor); 812 subject_set_monitor(geo->mouse_event, rdman->addrm_monitor);
811 813
812 geo_attach_coord(geo, coord); 814 geo_attach_coord(geo, coord);
854 856
855 if(shape->stroke != NULL) 857 if(shape->stroke != NULL)
856 rdman_paint_stroke(rdman, (paint_t *)NULL, shape); 858 rdman_paint_stroke(rdman, (paint_t *)NULL, shape);
857 if(shape->fill != NULL) 859 if(shape->fill != NULL)
858 rdman_paint_fill(rdman, (paint_t *)NULL, shape); 860 rdman_paint_fill(rdman, (paint_t *)NULL, shape);
859 861
860 if(geo != NULL) { 862 if(geo != NULL) {
861 subject_free(geo->mouse_event); 863 subject_free(geo->mouse_event);
862 geo_detach_coord(geo, shape->coord); 864 geo_detach_coord(geo, shape->coord);
863 sh_detach_coord(shape); 865 sh_detach_coord(shape);
864 sh_detach_geo(shape); 866 sh_detach_geo(shape);
869 shape->free(shape); 871 shape->free(shape);
870 872
871 if(rdman->last_mouse_over == (mb_obj_t *)shape) 873 if(rdman->last_mouse_over == (mb_obj_t *)shape)
872 rdman->last_mouse_over = NULL; 874 rdman->last_mouse_over = NULL;
873 875
874 876
875 return OK; 877 return OK;
876 } 878 }
877 879
878 shnode_t *shnode_new(redraw_man_t *rdman, shape_t *shape) { 880 shnode_t *shnode_new(redraw_man_t *rdman, shape_t *shape) {
879 shnode_t *node; 881 shnode_t *node;
901 /* Free member shapes that using this paint. */ 903 /* Free member shapes that using this paint. */
902 saved_shnode = NULL; 904 saved_shnode = NULL;
903 FORPAINTMEMBERS(paint, shnode) { 905 FORPAINTMEMBERS(paint, shnode) {
904 if(saved_shnode) { 906 if(saved_shnode) {
905 RM_PAINTMEMBER(paint, saved_shnode); 907 RM_PAINTMEMBER(paint, saved_shnode);
906 908
907 shape = saved_shnode->shape; 909 shape = saved_shnode->shape;
908 if(shape->stroke == paint) 910 if(shape->stroke == paint)
909 rdman_paint_stroke(rdman, (paint_t *)NULL, shape); 911 rdman_paint_stroke(rdman, (paint_t *)NULL, shape);
910 if(shape->fill == paint) 912 if(shape->fill == paint)
911 rdman_paint_fill(rdman, (paint_t *)NULL, shape); 913 rdman_paint_fill(rdman, (paint_t *)NULL, shape);
912 914
913 shnode_free(rdman, saved_shnode); 915 shnode_free(rdman, saved_shnode);
914 } 916 }
915 saved_shnode = shnode; 917 saved_shnode = shnode;
916 } 918 }
917 if(saved_shnode) { 919 if(saved_shnode) {
918 RM_PAINTMEMBER(paint, saved_shnode); 920 RM_PAINTMEMBER(paint, saved_shnode);
919 921
920 shape = saved_shnode->shape; 922 shape = saved_shnode->shape;
921 if(shape->stroke == paint) 923 if(shape->stroke == paint)
922 rdman_paint_stroke(rdman, (paint_t *)NULL, shape); 924 rdman_paint_stroke(rdman, (paint_t *)NULL, shape);
923 if(shape->fill == paint) 925 if(shape->fill == paint)
924 rdman_paint_fill(rdman, (paint_t *)NULL, shape); 926 rdman_paint_fill(rdman, (paint_t *)NULL, shape);
925 927
926 shnode_free(rdman, saved_shnode); 928 shnode_free(rdman, saved_shnode);
927 } 929 }
928 930
929 paint->free(rdman, paint); 931 paint->free(rdman, paint);
930 return OK; 932 return OK;
988 static int rdman_coord_free_postponse(redraw_man_t *rdman, coord_t *coord) { 990 static int rdman_coord_free_postponse(redraw_man_t *rdman, coord_t *coord) {
989 int r; 991 int r;
990 992
991 if(coord->flags & COF_FREE) 993 if(coord->flags & COF_FREE)
992 return ERR; 994 return ERR;
993 995
994 coord->flags |= COF_FREE; 996 coord->flags |= COF_FREE;
995 coord_hide(coord); 997 coord_hide(coord);
996 if(!(coord->flags & COF_DIRTY)) { 998 if(!(coord->flags & COF_DIRTY)) {
997 r = add_dirty_coord(rdman, coord); 999 r = add_dirty_coord(rdman, coord);
998 if(r != OK) 1000 if(r != OK)
1033 FORMEMBERS(coord, member) { 1035 FORMEMBERS(coord, member) {
1034 cm_cnt++; 1036 cm_cnt++;
1035 if(!(member->flags & GEF_FREE)) 1037 if(!(member->flags & GEF_FREE))
1036 return ERR; 1038 return ERR;
1037 } 1039 }
1038 1040
1039 if(cm_cnt || rdman_is_dirty(rdman)) 1041 if(cm_cnt || rdman_is_dirty(rdman))
1040 return rdman_coord_free_postponse(rdman, coord); 1042 return rdman_coord_free_postponse(rdman, coord);
1041 1043
1042 /* Free canvas and canvas_info (\ref redraw) */ 1044 /* Free canvas and canvas_info (\ref redraw) */
1043 if(coord_is_cached(coord)) { 1045 if(coord_is_cached(coord)) {
1278 1280
1279 aggr = coord_get_aggr_matrix(coord); 1281 aggr = coord_get_aggr_matrix(coord);
1280 matrix = coord->matrix; 1282 matrix = coord->matrix;
1281 parent = coord->parent; 1283 parent = coord->parent;
1282 paggr = coord_get_aggr_matrix(parent); 1284 paggr = coord_get_aggr_matrix(parent);
1283 1285
1284 scale_x = matrix[0] / aggr[0]; 1286 scale_x = matrix[0] / aggr[0];
1285 scale_y = matrix[4] / aggr[4]; 1287 scale_y = matrix[4] / aggr[4];
1286 shift_x = matrix[2] - scale_x * aggr[2]; 1288 shift_x = matrix[2] - scale_x * aggr[2];
1287 shift_y = matrix[5] - scale_y * aggr[5]; 1289 shift_y = matrix[5] - scale_y * aggr[5];
1288 1290
1304 * 1306 *
1305 * The bounding box where the canvas would be draw on the canvas on 1307 * The bounding box where the canvas would be draw on the canvas on
1306 * ancestral cached coord can be retreived by shifting and resizing 1308 * ancestral cached coord can be retreived by shifting and resizing
1307 * canvas box in reverse and transform to coordination system of 1309 * canvas box in reverse and transform to coordination system of
1308 * ancestral cached coord. 1310 * ancestral cached coord.
1309 */ 1311 */
1310 static void compute_pcache_area(coord_t *coord) { 1312 static void compute_pcache_area(coord_t *coord) {
1311 co_aix cached2pdev[6]; 1313 co_aix cached2pdev[6];
1312 int c_w, c_h; 1314 int c_w, c_h;
1313 canvas_t *canvas; 1315 canvas_t *canvas;
1314 coord_canvas_info_t *canvas_info; 1316 coord_canvas_info_t *canvas_info;
1315 co_aix poses[4][2]; 1317 co_aix poses[4][2];
1316 1318
1317 canvas_info = coord->canvas_info; 1319 canvas_info = coord->canvas_info;
1318 SWAP(canvas_info->pcache_cur_area, canvas_info->pcache_last_area, 1320 SWAP(canvas_info->pcache_cur_area, canvas_info->pcache_last_area,
1319 area_t *); 1321 area_t *);
1320 compute_cached_2_pdev_matrix(coord, cached2pdev); 1322 compute_cached_2_pdev_matrix(coord, cached2pdev);
1321 1323
1322 canvas = _coord_get_canvas(coord); 1324 canvas = _coord_get_canvas(coord);
1323 canvas_get_size(canvas, &c_w, &c_h); 1325 canvas_get_size(canvas, &c_w, &c_h);
1324 1326
1325 poses[0][0] = 0; 1327 poses[0][0] = 0;
1326 poses[0][1] = 0; 1328 poses[0][1] = 0;
1327 poses[1][0] = c_w; 1329 poses[1][0] = c_w;
1328 poses[1][1] = c_h; 1330 poses[1][1] = c_h;
1329 poses[2][0] = 0; 1331 poses[2][0] = 0;
1332 poses[3][1] = 0; 1334 poses[3][1] = 0;
1333 matrix_trans_pos(cached2pdev, &poses[0][0], &poses[0][1]); 1335 matrix_trans_pos(cached2pdev, &poses[0][0], &poses[0][1]);
1334 matrix_trans_pos(cached2pdev, &poses[1][0], &poses[1][1]); 1336 matrix_trans_pos(cached2pdev, &poses[1][0], &poses[1][1]);
1335 matrix_trans_pos(cached2pdev, &poses[2][0], &poses[2][1]); 1337 matrix_trans_pos(cached2pdev, &poses[2][0], &poses[2][1]);
1336 matrix_trans_pos(cached2pdev, &poses[3][0], &poses[3][1]); 1338 matrix_trans_pos(cached2pdev, &poses[3][0], &poses[3][1]);
1337 1339
1338 area_init(coord_get_pcache_area(coord), 4, poses); 1340 area_init(coord_get_pcache_area(coord), 4, poses);
1339 1341
1340 coord_set_flags(coord, COF_DIRTY_PCACHE_AREA); 1342 coord_set_flags(coord, COF_DIRTY_PCACHE_AREA);
1341 } 1343 }
1342 1344
1346 compute_area(coord_t *coord) { 1348 compute_area(coord_t *coord) {
1347 static co_aix (*poses)[2]; 1349 static co_aix (*poses)[2];
1348 static int max_poses = 0; 1350 static int max_poses = 0;
1349 geo_t *geo; 1351 geo_t *geo;
1350 int cnt, pos_cnt; 1352 int cnt, pos_cnt;
1351 1353
1352 cnt = 0; 1354 cnt = 0;
1353 FORMEMBERS(coord, geo) { 1355 FORMEMBERS(coord, geo) {
1354 cnt++; 1356 cnt++;
1355 } 1357 }
1356 1358
1357 if(max_poses < (cnt * 2)) { 1359 if(max_poses < (cnt * 2)) {
1358 free(poses); 1360 free(poses);
1359 max_poses = cnt * 2; 1361 max_poses = cnt * 2;
1360 poses = (co_aix (*)[2])malloc(sizeof(co_aix [2]) * max_poses); 1362 poses = (co_aix (*)[2])malloc(sizeof(co_aix [2]) * max_poses);
1361 if(poses == NULL) 1363 if(poses == NULL)
1375 1377
1376 static int coord_clean_members_n_compute_area(coord_t *coord) { 1378 static int coord_clean_members_n_compute_area(coord_t *coord) {
1377 geo_t *geo; 1379 geo_t *geo;
1378 int r; 1380 int r;
1379 /*! \note poses is shared by invokings, it is not support reentrying. */ 1381 /*! \note poses is shared by invokings, it is not support reentrying. */
1380 1382
1381 /* Clean member shapes. */ 1383 /* Clean member shapes. */
1382 FORMEMBERS(coord, geo) { 1384 FORMEMBERS(coord, geo) {
1383 clean_shape(geo->shape); 1385 clean_shape(geo->shape);
1384 } 1386 }
1385 1387
1399 * \note coords their opacity != 1 are also traded as cached ones. 1401 * \note coords their opacity != 1 are also traded as cached ones.
1400 */ 1402 */
1401 static int clean_coord(redraw_man_t *rdman, coord_t *coord) { 1403 static int clean_coord(redraw_man_t *rdman, coord_t *coord) {
1402 coord_t *child; 1404 coord_t *child;
1403 int r; 1405 int r;
1404 1406
1405 setup_canvas_info(rdman, coord); 1407 setup_canvas_info(rdman, coord);
1406 1408
1407 compute_aggr(coord); 1409 compute_aggr(coord);
1408 1410
1409 /* Areas of cached coords are computed in two phase. 1411 /* Areas of cached coords are computed in two phase.
1418 add_dirty_area(rdman, coord, coord->cur_area); 1420 add_dirty_area(rdman, coord, coord->cur_area);
1419 add_dirty_area(rdman, coord, coord->last_area); 1421 add_dirty_area(rdman, coord, coord->last_area);
1420 1422
1421 coord_clear_flags(coord, COF_DIRTY); 1423 coord_clear_flags(coord, COF_DIRTY);
1422 coord_set_flags(coord, COF_JUST_CLEAN); 1424 coord_set_flags(coord, COF_JUST_CLEAN);
1423 1425
1424 FORCHILDREN(coord, child) { 1426 FORCHILDREN(coord, child) {
1425 if(coord_is_cached(child)) 1427 if(coord_is_cached(child))
1426 add_dirty_pcache_area_coord(rdman, child); 1428 add_dirty_pcache_area_coord(rdman, child);
1427 } 1429 }
1428 1430
1429 return OK; 1431 return OK;
1430 } 1432 }
1431 1433
1432 /*! \brief Clean coord_t objects. 1434 /*! \brief Clean coord_t objects.
1433 * 1435 *
1477 clean_shape(visit_geo->shape); 1479 clean_shape(visit_geo->shape);
1478 coord = geo_get_coord(visit_geo); 1480 coord = geo_get_coord(visit_geo);
1479 add_dirty_area(rdman, coord, visit_geo->cur_area); 1481 add_dirty_area(rdman, coord, visit_geo->cur_area);
1480 add_dirty_area(rdman, coord, visit_geo->last_area); 1482 add_dirty_area(rdman, coord, visit_geo->last_area);
1481 } 1483 }
1482 } 1484 }
1483 1485
1484 return OK; 1486 return OK;
1485 } 1487 }
1486 1488
1487 /*! \brief Shift space of coord to align left-top of minimum covering. 1489 /*! \brief Shift space of coord to align left-top of minimum covering.
1524 area = coord_get_area(cur); 1526 area = coord_get_area(cur);
1525 if(area->x < min_x) 1527 if(area->x < min_x)
1526 min_x = area->x; 1528 min_x = area->x;
1527 if(area->y < min_y) 1529 if(area->y < min_y)
1528 min_y = area->y; 1530 min_y = area->y;
1529 1531
1530 x = area->x + area->w; 1532 x = area->x + area->w;
1531 y = area->y + area->h; 1533 y = area->y + area->h;
1532 1534
1533 if(x > max_x) 1535 if(x > max_x)
1534 max_x = x; 1536 max_x = x;
1535 if(y > max_y) 1537 if(y > max_y)
1536 max_y = y; 1538 max_y = y;
1537 if(coord_is_cached(cur)) 1539 if(coord_is_cached(cur))
1538 preorder_coord_skip_subtree(cur); 1540 preorder_coord_skip_subtree(cur);
1539 } 1541 }
1540 1542
1541 w = max_x - min_x; 1543 w = max_x - min_x;
1542 h = max_y - min_y; 1544 h = max_y - min_y;
1543 1545
1544 canvas = _coord_get_canvas(coord); 1546 canvas = _coord_get_canvas(coord);
1545 if(canvas) 1547 if(canvas)
1546 canvas_get_size(canvas, &c_w, &c_h); 1548 canvas_get_size(canvas, &c_w, &c_h);
1547 else 1549 else
1548 c_w = c_h = 0; 1550 c_w = c_h = 0;
1560 h >= (c_h >> 2) && w >= (c_w >> 2)) { 1562 h >= (c_h >> 2) && w >= (c_w >> 2)) {
1561 /* Canvas fully cover sub-graphic. */ 1563 /* Canvas fully cover sub-graphic. */
1562 coord_set_flags(coord, COF_SKIP_ZERO); 1564 coord_set_flags(coord, COF_SKIP_ZERO);
1563 return; 1565 return;
1564 } 1566 }
1565 1567
1566 /* 1568 /*
1567 * Adjust matrics of descendants to align left-top corner of 1569 * Adjust matrics of descendants to align left-top corner of
1568 * minimum covering area with origin of space defined by 1570 * minimum covering area with origin of space defined by
1569 * zeroing coord. 1571 * zeroing coord.
1570 */ 1572 */
1579 } 1581 }
1580 /* Shift space */ 1582 /* Shift space */
1581 aggr = coord_get_aggr_matrix(cur); 1583 aggr = coord_get_aggr_matrix(cur);
1582 aggr[2] -= min_x; 1584 aggr[2] -= min_x;
1583 aggr[5] -= min_y; 1585 aggr[5] -= min_y;
1584 1586
1585 FOR_COORD_MEMBERS(coord, geo) { 1587 FOR_COORD_MEMBERS(coord, geo) {
1586 /* \see GEO_SWAP() */ 1588 /* \see GEO_SWAP() */
1587 if(!geo_get_flags(geo, GEF_SWAP)) 1589 if(!geo_get_flags(geo, GEF_SWAP))
1588 SWAP(geo->cur_area, geo->last_area, area_t *); 1590 SWAP(geo->cur_area, geo->last_area, area_t *);
1589 } 1591 }
1590 coord_clean_members_n_compute_area(cur); 1592 coord_clean_members_n_compute_area(cur);
1591 } 1593 }
1592 1594
1593 /* 1595 /*
1594 * Setup canvas 1596 * Setup canvas
1595 * 1597 *
1596 * Canvas of a cached coord is not setted in 1598 * Canvas of a cached coord is not setted in
1597 * coord_canvas_info_new(). It should be setted, here. 1599 * coord_canvas_info_new(). It should be setted, here.
1628 break; 1630 break;
1629 coord_set_flags(coord, COF_TEMP_MARK); 1631 coord_set_flags(coord, COF_TEMP_MARK);
1630 coord = coord_get_cached(coord_get_parent(coord)); 1632 coord = coord_get_cached(coord_get_parent(coord));
1631 } 1633 }
1632 } 1634 }
1633 1635
1634 /* Mark all cached ancestral coords of dirty coords */ 1636 /* Mark all cached ancestral coords of dirty coords */
1635 n_dirty_coords = rdman->dirty_coords.num; 1637 n_dirty_coords = rdman->dirty_coords.num;
1636 dirty_coords = rdman->dirty_coords.ds; 1638 dirty_coords = rdman->dirty_coords.ds;
1637 for(i = 0; i < n_dirty_coords; i++) { 1639 for(i = 0; i < n_dirty_coords; i++) {
1638 coord = coord_get_cached(dirty_coords[i]); 1640 coord = coord_get_cached(dirty_coords[i]);
1641 break; 1643 break;
1642 coord_set_flags(coord, COF_TEMP_MARK); 1644 coord_set_flags(coord, COF_TEMP_MARK);
1643 coord = coord_get_cached(coord_get_parent(coord)); 1645 coord = coord_get_cached(coord_get_parent(coord));
1644 } 1646 }
1645 } 1647 }
1646 1648
1647 /* Add all marked coords into redraw_man_t::zeroing_coords list */ 1649 /* Add all marked coords into redraw_man_t::zeroing_coords list */
1648 FOR_COORDS_PREORDER(rdman->root_coord, coord) { 1650 FOR_COORDS_PREORDER(rdman->root_coord, coord) {
1649 if(!coord_is_cached(coord) || coord_is_root(coord)) 1651 if(!coord_is_cached(coord) || coord_is_root(coord))
1650 continue; /* skip coords that is not cached */ 1652 continue; /* skip coords that is not cached */
1651 1653
1652 if(!coord_get_flags(coord, COF_TEMP_MARK)) { 1654 if(!coord_get_flags(coord, COF_TEMP_MARK)) {
1653 if(coord_get_flags(coord, COF_DIRTY_PCACHE_AREA)) 1655 if(coord_get_flags(coord, COF_DIRTY_PCACHE_AREA))
1654 add_dirty_pcache_area_coord(rdman, coord); 1656 add_dirty_pcache_area_coord(rdman, coord);
1655 preorder_coord_skip_subtree(coord); 1657 preorder_coord_skip_subtree(coord);
1656 continue; 1658 continue;
1657 } 1659 }
1658 add_zeroing_coord(rdman, coord); 1660 add_zeroing_coord(rdman, coord);
1659 1661
1660 coord_clear_flags(coord, COF_TEMP_MARK); 1662 coord_clear_flags(coord, COF_TEMP_MARK);
1661 } 1663 }
1662 1664
1663 return OK; 1665 return OK;
1664 } 1666 }
1665 1667
1666 /*! \brief Zeroing coords in redraw_man_t::zeroing_coords. 1668 /*! \brief Zeroing coords in redraw_man_t::zeroing_coords.
1667 * 1669 *
1671 */ 1673 */
1672 static int zeroing_rdman_coords(redraw_man_t *rdman) { 1674 static int zeroing_rdman_coords(redraw_man_t *rdman) {
1673 int i; 1675 int i;
1674 coords_t *all_zeroing; 1676 coords_t *all_zeroing;
1675 coord_t *coord; 1677 coord_t *coord;
1676 1678
1677 all_zeroing = &rdman->zeroing_coords; 1679 all_zeroing = &rdman->zeroing_coords;
1678 /*! Zeroing is performed from leaves to root. 1680 /*! Zeroing is performed from leaves to root.
1679 * 1681 *
1680 * REASON: The size of canvas is also effected by cached 1682 * REASON: The size of canvas is also effected by cached
1681 * descedants. A cached coord is only effected by parent 1683 * descedants. A cached coord is only effected by parent
1689 for(i = all_zeroing->num - 1; i >= 0; i--) { 1691 for(i = all_zeroing->num - 1; i >= 0; i--) {
1690 coord = all_zeroing->ds[i]; 1692 coord = all_zeroing->ds[i];
1691 zeroing_coord(rdman, coord); 1693 zeroing_coord(rdman, coord);
1692 compute_pcache_area(coord); 1694 compute_pcache_area(coord);
1693 } 1695 }
1694 1696
1695 return OK; 1697 return OK;
1696 } 1698 }
1697 1699
1698 /*! \brief Compute pcache_area for coords whoes pcache_area is dirty. 1700 /*! \brief Compute pcache_area for coords whoes pcache_area is dirty.
1699 * 1701 *
1707 static int 1709 static int
1708 compute_rdman_coords_pcache_area(redraw_man_t *rdman) { 1710 compute_rdman_coords_pcache_area(redraw_man_t *rdman) {
1709 coords_t *all_coords; 1711 coords_t *all_coords;
1710 coord_t *coord; 1712 coord_t *coord;
1711 int i; 1713 int i;
1712 1714
1713 all_coords = &rdman->dirty_pcache_area_coords; 1715 all_coords = &rdman->dirty_pcache_area_coords;
1714 for(i = 0; i < all_coords->num; i++) { 1716 for(i = 0; i < all_coords->num; i++) {
1715 coord = all_coords->ds[i]; 1717 coord = all_coords->ds[i];
1716 if(coord_get_flags(coord, COF_DIRTY_PCACHE_AREA)) 1718 if(coord_get_flags(coord, COF_DIRTY_PCACHE_AREA))
1717 compute_pcache_area(coord); 1719 compute_pcache_area(coord);
1737 1739
1738 n_areas = _coord_get_dirty_areas(coord)->num; 1740 n_areas = _coord_get_dirty_areas(coord)->num;
1739 areas = _coord_get_dirty_areas(coord)->ds; 1741 areas = _coord_get_dirty_areas(coord)->ds;
1740 if(n_areas == 0) 1742 if(n_areas == 0)
1741 abort(); /* should not happen! */ 1743 abort(); /* should not happen! */
1742 1744
1743 area0 = _coord_get_aggr_dirty_areas(coord); 1745 area0 = _coord_get_aggr_dirty_areas(coord);
1744 area1 = area0 + 1; 1746 area1 = area0 + 1;
1745 1747
1746 /* TODO: Since both cur & last area of coords are added into dirty 1748 /* TODO: Since both cur & last area of coords are added into dirty
1747 * area list, position of both areas shoud be adjusted for 1749 * area list, position of both areas shoud be adjusted for
1753 break; 1755 break;
1754 } 1756 }
1755 1757
1756 if(i >= n_areas) 1758 if(i >= n_areas)
1757 return; 1759 return;
1758 1760
1759 area = areas[i++]; 1761 area = areas[i++];
1760 poses0[0][0] = area->x; 1762 poses0[0][0] = area->x;
1761 poses0[0][1] = area->y; 1763 poses0[0][1] = area->y;
1762 poses0[1][0] = area->x + area->w; 1764 poses0[1][0] = area->x + area->w;
1763 poses0[1][1] = area->y + area->h; 1765 poses0[1][1] = area->y + area->h;
1764 1766
1765 if(i < n_areas) { 1767 if(i < n_areas) {
1766 area = areas[i++]; 1768 area = areas[i++];
1767 poses1[0][0] = area->x; 1769 poses1[0][0] = area->x;
1768 poses1[0][1] = area->y; 1770 poses1[0][1] = area->y;
1769 poses1[1][0] = area->x + area->w; 1771 poses1[1][0] = area->x + area->w;
1772 poses1[0][0] = 0; 1774 poses1[0][0] = 0;
1773 poses1[0][1] = 0; 1775 poses1[0][1] = 0;
1774 poses1[1][0] = 0; 1776 poses1[1][0] = 0;
1775 poses1[1][1] = 0; 1777 poses1[1][1] = 0;
1776 } 1778 }
1777 1779
1778 for(; i < n_areas - 1;) { 1780 for(; i < n_areas - 1;) {
1779 /* Even areas */ 1781 /* Even areas */
1780 area = areas[i++]; 1782 area = areas[i++];
1781 if(area->w != 0 || area->h != 0) { 1783 if(area->w != 0 || area->h != 0) {
1782 poses0[0][0] = MB_MIN(poses0[0][0], area->x); 1784 poses0[0][0] = MB_MIN(poses0[0][0], area->x);
1791 poses1[0][1] = MB_MIN(poses1[0][1], area->y); 1793 poses1[0][1] = MB_MIN(poses1[0][1], area->y);
1792 poses1[1][0] = MB_MAX(poses1[1][0], area->x + area->w); 1794 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); 1795 poses1[1][1] = MB_MAX(poses1[1][1], area->y + area->h);
1794 } 1796 }
1795 } 1797 }
1796 1798
1797 if(i < n_areas) { 1799 if(i < n_areas) {
1798 area = areas[i]; 1800 area = areas[i];
1799 if(area->w != 0 || area->h != 0) { 1801 if(area->w != 0 || area->h != 0) {
1800 poses0[0][0] = MB_MIN(poses0[0][0], area->x); 1802 poses0[0][0] = MB_MIN(poses0[0][0], area->x);
1801 poses0[0][1] = MB_MIN(poses0[0][1], area->y); 1803 poses0[0][1] = MB_MIN(poses0[0][1], area->y);
1802 poses0[1][0] = MB_MAX(poses0[1][0], area->x + area->w); 1804 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); 1805 poses0[1][1] = MB_MAX(poses0[1][1], area->y + area->h);
1804 } 1806 }
1805 } 1807 }
1806 1808
1807 parent = coord_get_parent(coord); 1809 parent = coord_get_parent(coord);
1808 pcached_coord = coord_get_cached(parent); 1810 pcached_coord = coord_get_cached(parent);
1809 1811
1810 compute_cached_2_pdev_matrix(coord, canvas2pdev_matrix); 1812 compute_cached_2_pdev_matrix(coord, canvas2pdev_matrix);
1811 1813
1812 /* Add dirty areas to parent cached coord. */ 1814 /* Add dirty areas to parent cached coord. */
1813 matrix_trans_pos(canvas2pdev_matrix, poses0[0], poses0[0] + 1); 1815 matrix_trans_pos(canvas2pdev_matrix, poses0[0], poses0[0] + 1);
1814 matrix_trans_pos(canvas2pdev_matrix, poses0[1], poses0[1] + 1); 1816 matrix_trans_pos(canvas2pdev_matrix, poses0[1], poses0[1] + 1);
1815 area_init(area0, 2, poses0); 1817 area_init(area0, 2, poses0);
1816 add_dirty_area(rdman, pcached_coord, area0); 1818 add_dirty_area(rdman, pcached_coord, area0);
1817 1819
1818 matrix_trans_pos(canvas2pdev_matrix, poses1[0], poses1[0] + 1); 1820 matrix_trans_pos(canvas2pdev_matrix, poses1[0], poses1[0] + 1);
1819 matrix_trans_pos(canvas2pdev_matrix, poses1[1], poses1[1] + 1); 1821 matrix_trans_pos(canvas2pdev_matrix, poses1[1], poses1[1] + 1);
1820 area_init(area1, 2, poses1); 1822 area_init(area1, 2, poses1);
1821 add_dirty_area(rdman, pcached_coord, area1); 1823 add_dirty_area(rdman, pcached_coord, area1);
1822 1824
1843 int n_zeroing; 1845 int n_zeroing;
1844 coord_t **zeroings; 1846 coord_t **zeroings;
1845 coord_t *coord, *pcached_coord; 1847 coord_t *coord, *pcached_coord;
1846 int n_dpca_coords; /* number of dirty pcache area coords */ 1848 int n_dpca_coords; /* number of dirty pcache area coords */
1847 coord_t **dpca_coords; /* dirty pcache area coords */ 1849 coord_t **dpca_coords; /* dirty pcache area coords */
1848 1850
1849 /* Add aggregated areas to parent cached one for coords in zeroing 1851 /* Add aggregated areas to parent cached one for coords in zeroing
1850 * list 1852 * list
1851 */ 1853 */
1852 n_zeroing = rdman->zeroing_coords.num; 1854 n_zeroing = rdman->zeroing_coords.num;
1853 zeroings = rdman->zeroing_coords.ds; 1855 zeroings = rdman->zeroing_coords.ds;
1854 for(i = 0; i < n_zeroing; i++) { 1856 for(i = 0; i < n_zeroing; i++) {
1855 coord = zeroings[i]; 1857 coord = zeroings[i];
1856 1858
1857 if(coord_get_flags(coord, COF_TEMP_MARK)) 1859 if(coord_get_flags(coord, COF_TEMP_MARK))
1858 continue; 1860 continue;
1859 coord_set_flags(coord, COF_TEMP_MARK); 1861 coord_set_flags(coord, COF_TEMP_MARK);
1860 1862
1861 pcached_coord = coord_get_cached(coord_get_parent(coord)); 1863 pcached_coord = coord_get_cached(coord_get_parent(coord));
1862 1864
1863 if(coord_is_root(coord) || IS_CACHE_REDRAW_ALL(pcached_coord)) 1865 if(coord_is_root(coord) || IS_CACHE_REDRAW_ALL(pcached_coord))
1864 continue; 1866 continue;
1865 1867
1866 if(IS_CACHE_REDRAW_ALL(coord)) { 1868 if(IS_CACHE_REDRAW_ALL(coord)) {
1867 add_dirty_area(rdman, pcached_coord, 1869 add_dirty_area(rdman, pcached_coord,
1868 coord_get_pcache_area(coord)); 1870 coord_get_pcache_area(coord));
1869 add_dirty_area(rdman, pcached_coord, 1871 add_dirty_area(rdman, pcached_coord,
1870 coord_get_pcache_last_area(coord)); 1872 coord_get_pcache_last_area(coord));
1871 } else { 1873 } else {
1872 add_aggr_dirty_areas_to_ancestor(rdman, coord); 1874 add_aggr_dirty_areas_to_ancestor(rdman, coord);
1873 } 1875 }
1874 } 1876 }
1875 1877
1876 /* Add pcache_areas to parent cached one for coord that is 1878 /* Add pcache_areas to parent cached one for coord that is
1877 * non-zeroing and its parent is changed. 1879 * non-zeroing and its parent is changed.
1878 */ 1880 */
1879 n_dpca_coords = rdman->dirty_pcache_area_coords.num; 1881 n_dpca_coords = rdman->dirty_pcache_area_coords.num;
1880 dpca_coords = rdman->dirty_pcache_area_coords.ds; 1882 dpca_coords = rdman->dirty_pcache_area_coords.ds;
1881 for(i = 0; i < n_dpca_coords; i++) { 1883 for(i = 0; i < n_dpca_coords; i++) {
1882 coord = dpca_coords[i]; 1884 coord = dpca_coords[i];
1883 1885
1884 if(coord_get_flags(coord, COF_TEMP_MARK)) 1886 if(coord_get_flags(coord, COF_TEMP_MARK))
1885 continue; 1887 continue;
1886 coord_set_flags(coord, COF_TEMP_MARK); 1888 coord_set_flags(coord, COF_TEMP_MARK);
1887 1889
1888 pcached_coord = coord_get_cached(coord_get_parent(coord)); 1890 pcached_coord = coord_get_cached(coord_get_parent(coord));
1889 1891
1890 if(coord_is_root(coord) || IS_CACHE_REDRAW_ALL(pcached_coord)) 1892 if(coord_is_root(coord) || IS_CACHE_REDRAW_ALL(pcached_coord))
1891 continue; 1893 continue;
1892 1894
1893 add_dirty_area(rdman, pcached_coord, 1895 add_dirty_area(rdman, pcached_coord,
1894 coord_get_pcache_area(coord)); 1896 coord_get_pcache_area(coord));
1895 add_dirty_area(rdman, pcached_coord, 1897 add_dirty_area(rdman, pcached_coord,
1896 coord_get_pcache_last_area(coord)); 1898 coord_get_pcache_last_area(coord));
1897 } 1899 }
1981 SWAP(coord->cur_area, coord->last_area, area_t *); 1983 SWAP(coord->cur_area, coord->last_area, area_t *);
1982 FOR_COORD_MEMBERS(coord, geo) { 1984 FOR_COORD_MEMBERS(coord, geo) {
1983 GEO_SWAP(geo); 1985 GEO_SWAP(geo);
1984 } 1986 }
1985 } 1987 }
1986 1988
1987 /* XXX: some geo may swap two times. Should avoid it. 1989 /* XXX: some geo may swap two times. Should avoid it.
1988 */ 1990 */
1989 geos = rdman->dirty_geos.ds; 1991 geos = rdman->dirty_geos.ds;
1990 for(i = 0; i < rdman->dirty_geos.num; i++) { 1992 for(i = 0; i < rdman->dirty_geos.num; i++) {
1991 geo = geos[i]; 1993 geo = geos[i];
1992 GEO_SWAP(geo); 1994 GEO_SWAP(geo);
1993 } 1995 }
1994 1996
1995 r = clean_rdman_coords(rdman); 1997 r = clean_rdman_coords(rdman);
1996 if(r != OK) 1998 if(r != OK)
1997 return ERR; 1999 return ERR;
1998 2000
1999 /* TODO: save area of cached coord and descendants in 2001 /* TODO: save area of cached coord and descendants in
2016 return ERR; 2018 return ERR;
2017 2019
2018 r = compute_rdman_coords_pcache_area(rdman); 2020 r = compute_rdman_coords_pcache_area(rdman);
2019 if(r != OK) 2021 if(r != OK)
2020 return ERR; 2022 return ERR;
2021 2023
2022 r = add_rdman_aggr_dirty_areas(rdman); 2024 r = add_rdman_aggr_dirty_areas(rdman);
2023 if(r != OK) 2025 if(r != OK)
2024 return ERR; 2026 return ERR;
2025 2027
2026 /* 2028 /*
2041 COF_JUST_CLEAN | COF_JUST_ZERO | COF_SKIP_ZERO); 2043 COF_JUST_CLEAN | COF_JUST_ZERO | COF_SKIP_ZERO);
2042 coords = rdman->dirty_pcache_area_coords.ds; 2044 coords = rdman->dirty_pcache_area_coords.ds;
2043 for(i = 0; i < rdman->dirty_pcache_area_coords.num; i++) 2045 for(i = 0; i < rdman->dirty_pcache_area_coords.num; i++)
2044 coord_clear_flags(coords[i], 2046 coord_clear_flags(coords[i],
2045 COF_JUST_CLEAN | COF_JUST_ZERO | COF_SKIP_ZERO); 2047 COF_JUST_CLEAN | COF_JUST_ZERO | COF_SKIP_ZERO);
2046 2048
2047 /* \see GEO_SWAP() */ 2049 /* \see GEO_SWAP() */
2048 for(i = 0; i < rdman->dirty_geos.num; i++) { 2050 for(i = 0; i < rdman->dirty_geos.num; i++) {
2049 geo = geos[i]; 2051 geo = geos[i];
2050 geo_clear_flags(geo, GEF_SWAP); 2052 geo_clear_flags(geo, GEF_SWAP);
2051 } 2053 }
2052 2054
2053 return OK; 2055 return OK;
2054 } 2056 }
2055 2057
2056 2058
2057 /* Drawing and Redrawing 2059 /* Drawing and Redrawing
2135 if(stroke) { 2137 if(stroke) {
2136 stroke->prepare(stroke, cr); 2138 stroke->prepare(stroke, cr);
2137 set_shape_stroke_param(shape, cr); 2139 set_shape_stroke_param(shape, cr);
2138 stroke_path(rdman); 2140 stroke_path(rdman);
2139 } 2141 }
2140 } 2142 }
2141 } 2143 }
2142 2144
2143 #ifndef UNITTEST 2145 #ifndef UNITTEST
2144 static void clear_canvas(canvas_t *canvas) { 2146 static void clear_canvas(canvas_t *canvas) {
2145 mbe_clear(canvas); 2147 mbe_clear(canvas);
2166 2168
2167 static void copy_cr_2_backend(redraw_man_t *rdman, int n_dirty_areas, 2169 static void copy_cr_2_backend(redraw_man_t *rdman, int n_dirty_areas,
2168 area_t **dirty_areas) { 2170 area_t **dirty_areas) {
2169 if(n_dirty_areas) 2171 if(n_dirty_areas)
2170 make_clip(rdman->backend, n_dirty_areas, dirty_areas); 2172 make_clip(rdman->backend, n_dirty_areas, dirty_areas);
2171 2173
2172 mbe_copy_source(rdman->cr, rdman->backend); 2174 mbe_copy_source(rdman->cr, rdman->backend);
2173 } 2175 }
2174 #else /* UNITTEST */ 2176 #else /* UNITTEST */
2175 static void make_clip(mbe_t *cr, int n_dirty_areas, 2177 static void make_clip(mbe_t *cr, int n_dirty_areas,
2176 area_t **dirty_areas) { 2178 area_t **dirty_areas) {
2198 if(coord_is_root(coord)) 2200 if(coord_is_root(coord))
2199 return; 2201 return;
2200 2202
2201 compute_cached_2_pdev_matrix(coord, canvas2pdev_matrix); 2203 compute_cached_2_pdev_matrix(coord, canvas2pdev_matrix);
2202 compute_reverse(canvas2pdev_matrix, reverse); 2204 compute_reverse(canvas2pdev_matrix, reverse);
2203 2205
2204 canvas = _coord_get_canvas(coord); 2206 canvas = _coord_get_canvas(coord);
2205 pcanvas = _coord_get_canvas(coord->parent); 2207 pcanvas = _coord_get_canvas(coord->parent);
2206 surface = mbe_get_target(canvas); 2208 surface = mbe_get_target(canvas);
2207 pattern = mbe_pattern_create_for_surface(surface); 2209 pattern = mbe_pattern_create_for_surface(surface);
2208 mbe_pattern_set_matrix(pattern, reverse); 2210 mbe_pattern_set_matrix(pattern, reverse);
2221 coord_t *child; 2223 coord_t *child;
2222 int mem_idx; 2224 int mem_idx;
2223 2225
2224 if(coord->flags & COF_HIDDEN) 2226 if(coord->flags & COF_HIDDEN)
2225 return OK; 2227 return OK;
2226 2228
2227 areas = _coord_get_dirty_areas(coord)->ds; 2229 areas = _coord_get_dirty_areas(coord)->ds;
2228 n_areas = _coord_get_dirty_areas(coord)->num; 2230 n_areas = _coord_get_dirty_areas(coord)->num;
2229 canvas = _coord_get_canvas(coord); 2231 canvas = _coord_get_canvas(coord);
2230 2232
2231 member = FIRST_MEMBER(coord); 2233 member = FIRST_MEMBER(coord);
2232 mem_idx = 0; 2234 mem_idx = 0;
2233 child = FIRST_CHILD(coord); 2235 child = FIRST_CHILD(coord);
2234 while(child != NULL || member != NULL) { 2236 while(child != NULL || member != NULL) {
2235 if(child && child->before_pmem == mem_idx) { 2237 if(child && child->before_pmem == mem_idx) {
2267 int n_areas; 2269 int n_areas;
2268 mbe_t *canvas; 2270 mbe_t *canvas;
2269 mbe_surface_t *surface; 2271 mbe_surface_t *surface;
2270 int i; 2272 int i;
2271 int r; 2273 int r;
2272 2274
2273 canvas = _coord_get_canvas(coord); 2275 canvas = _coord_get_canvas(coord);
2274 2276
2275 if(IS_CACHE_REDRAW_ALL(coord)) { 2277 if(IS_CACHE_REDRAW_ALL(coord)) {
2276 /* 2278 /*
2277 * full_area covers all dirty areas of the cached coord. 2279 * full_area covers all dirty areas of the cached coord.
2278 */ 2280 */
2279 DARRAY_CLEAN(_coord_get_dirty_areas(coord)); 2281 DARRAY_CLEAN(_coord_get_dirty_areas(coord));
2285 add_dirty_area(rdman, coord, &full_area); 2287 add_dirty_area(rdman, coord, &full_area);
2286 } 2288 }
2287 2289
2288 areas = _coord_get_dirty_areas(coord)->ds; 2290 areas = _coord_get_dirty_areas(coord)->ds;
2289 n_areas = _coord_get_dirty_areas(coord)->num; 2291 n_areas = _coord_get_dirty_areas(coord)->num;
2290 2292
2291 for(i = 0; i < n_areas; i++) { 2293 for(i = 0; i < n_areas; i++) {
2292 area = areas[i]; 2294 area = areas[i];
2293 area->x = floorf(area->x); 2295 area->x = floorf(area->x);
2294 area->y = floorf(area->y); 2296 area->y = floorf(area->y);
2295 area->w = ceilf(area->w); 2297 area->w = ceilf(area->w);
2298 2300
2299 make_clip(canvas, n_areas, areas); 2301 make_clip(canvas, n_areas, areas);
2300 clear_canvas(canvas); 2302 clear_canvas(canvas);
2301 2303
2302 r = draw_coord_shapes_in_dirty_areas(rdman, coord); 2304 r = draw_coord_shapes_in_dirty_areas(rdman, coord);
2303 2305
2304 reset_clip(canvas); 2306 reset_clip(canvas);
2305 2307
2306 return OK; 2308 return OK;
2307 } 2309 }
2308 2310
2369 subject_t *redraw; 2371 subject_t *redraw;
2370 int i; 2372 int i;
2371 coord_t *coord; 2373 coord_t *coord;
2372 int n_areas; 2374 int n_areas;
2373 area_t **areas; 2375 area_t **areas;
2374 2376
2375 r = rdman_clean_dirties(rdman); 2377 r = rdman_clean_dirties(rdman);
2376 if(r != OK) 2378 if(r != OK)
2377 return ERR; 2379 return ERR;
2378 2380
2379 if(rdman->n_dirty_areas > 0) { 2381 if(rdman->n_dirty_areas > 0) {
2395 2397
2396 DARRAY_CLEAN(&rdman->dirty_coords); 2398 DARRAY_CLEAN(&rdman->dirty_coords);
2397 DARRAY_CLEAN(&rdman->dirty_geos); 2399 DARRAY_CLEAN(&rdman->dirty_geos);
2398 DARRAY_CLEAN(&rdman->zeroing_coords); 2400 DARRAY_CLEAN(&rdman->zeroing_coords);
2399 DARRAY_CLEAN(&rdman->dirty_pcache_area_coords); 2401 DARRAY_CLEAN(&rdman->dirty_pcache_area_coords);
2400 2402
2401 /* Free postponsed removing */ 2403 /* Free postponsed removing */
2402 free_free_objs(rdman); 2404 free_free_objs(rdman);
2403 2405
2404 redraw = rdman_get_redraw_subject(rdman); 2406 redraw = rdman_get_redraw_subject(rdman);
2405 event.type = EVT_RDMAN_REDRAW; 2407 event.type = EVT_RDMAN_REDRAW;
2457 /*! \brief Helping function to travel descendant shapes of a coord. 2459 /*! \brief Helping function to travel descendant shapes of a coord.
2458 */ 2460 */
2459 geo_t *rdman_geos(redraw_man_t *rdman, geo_t *last) { 2461 geo_t *rdman_geos(redraw_man_t *rdman, geo_t *last) {
2460 geo_t *next; 2462 geo_t *next;
2461 coord_t *coord; 2463 coord_t *coord;
2462 2464
2463 if(last == NULL) { 2465 if(last == NULL) {
2464 coord = rdman->root_coord; 2466 coord = rdman->root_coord;
2465 while(coord != NULL && FIRST_MEMBER(coord) == NULL) 2467 while(coord != NULL && FIRST_MEMBER(coord) == NULL)
2466 coord = preorder_coord_subtree(rdman->root_coord, coord); 2468 coord = preorder_coord_subtree(rdman->root_coord, coord);
2467 if(coord == NULL) 2469 if(coord == NULL)
2586 */ 2588 */
2587 paint_t *rdman_img_ldr_load_paint(redraw_man_t *rdman, const char *img_id) { 2589 paint_t *rdman_img_ldr_load_paint(redraw_man_t *rdman, const char *img_id) {
2588 mb_img_data_t *img_data; 2590 mb_img_data_t *img_data;
2589 paint_t *paint; 2591 paint_t *paint;
2590 mb_img_ldr_t *ldr = rdman_img_ldr(rdman); 2592 mb_img_ldr_t *ldr = rdman_img_ldr(rdman);
2591 2593
2592 img_data = MB_IMG_LDR_LOAD(ldr, img_id); 2594 img_data = MB_IMG_LDR_LOAD(ldr, img_id);
2593 if(img_data == NULL) 2595 if(img_data == NULL)
2594 return NULL; 2596 return NULL;
2595 2597
2596 paint = rdman_paint_image_new(rdman, img_data); 2598 paint = rdman_paint_image_new(rdman, img_data);
2597 if(paint == NULL) 2599 if(paint == NULL)
2598 MB_IMG_DATA_FREE(img_data); 2600 MB_IMG_DATA_FREE(img_data);
2599 2601
2600 return paint; 2602 return paint;
2601 } 2603 }
2602 2604
2603 #ifdef UNITTEST 2605 #ifdef UNITTEST
2604 /* Test cases */ 2606 /* Test cases */
2632 dummy->w = w; 2634 dummy->w = w;
2633 dummy->h = h; 2635 dummy->h = h;
2634 dummy->trans_cnt = 0; 2636 dummy->trans_cnt = 0;
2635 dummy->draw_cnt = 0; 2637 dummy->draw_cnt = 0;
2636 dummy->shape.free = sh_dummy_free; 2638 dummy->shape.free = sh_dummy_free;
2637 2639
2638 rdman_shape_man(rdman, (shape_t *)dummy); 2640 rdman_shape_man(rdman, (shape_t *)dummy);
2639 2641
2640 return (shape_t *)dummy; 2642 return (shape_t *)dummy;
2641 } 2643 }
2642 2644
2643 void sh_dummy_transform(shape_t *shape) { 2645 void sh_dummy_transform(shape_t *shape) {
2644 sh_dummy_t *dummy = (sh_dummy_t *)shape; 2646 sh_dummy_t *dummy = (sh_dummy_t *)shape;
2645 co_aix poses[2][2]; 2647 co_aix poses[2][2];
2646 co_aix x1, y1, x2, y2; 2648 co_aix x1, y1, x2, y2;
2647 2649
2648 if(shape->geo && shape->coord) { 2650 if(shape->geo && shape->coord) {
2649 x1 = dummy->x; 2651 x1 = dummy->x;
2650 y1 = dummy->y; 2652 y1 = dummy->y;
2651 x2 = x1 + dummy->w; 2653 x2 = x1 + dummy->w;
2652 y2 = y1 + dummy->h; 2654 y2 = y1 + dummy->h;
2655 coord_trans_pos(shape->coord, &x2, &y2); 2657 coord_trans_pos(shape->coord, &x2, &y2);
2656 poses[0][0] = x1; 2658 poses[0][0] = x1;
2657 poses[0][1] = y1; 2659 poses[0][1] = y1;
2658 poses[1][0] = x2; 2660 poses[1][0] = x2;
2659 poses[1][1] = y2; 2661 poses[1][1] = y2;
2660 2662
2661 if(shape->geo) 2663 if(shape->geo)
2662 geo_from_positions(shape->geo, 2, poses); 2664 geo_from_positions(shape->geo, 2, poses);
2663 } 2665 }
2664 dummy->trans_cnt++; 2666 dummy->trans_cnt++;
2665 } 2667 }
2719 CU_ASSERT(dummys[1]->trans_cnt == 1); 2721 CU_ASSERT(dummys[1]->trans_cnt == 1);
2720 CU_ASSERT(dummys[2]->trans_cnt == 1); 2722 CU_ASSERT(dummys[2]->trans_cnt == 1);
2721 CU_ASSERT(dummys[0]->draw_cnt == 1); 2723 CU_ASSERT(dummys[0]->draw_cnt == 1);
2722 CU_ASSERT(dummys[1]->draw_cnt == 1); 2724 CU_ASSERT(dummys[1]->draw_cnt == 1);
2723 CU_ASSERT(dummys[2]->draw_cnt == 1); 2725 CU_ASSERT(dummys[2]->draw_cnt == 1);
2724 2726
2725 coords[2]->matrix[2] = 100; 2727 coords[2]->matrix[2] = 100;
2726 coords[2]->matrix[5] = 100; 2728 coords[2]->matrix[5] = 100;
2727 rdman_coord_changed(rdman, coords[0]); 2729 rdman_coord_changed(rdman, coords[0]);
2728 rdman_coord_changed(rdman, coords[2]); 2730 rdman_coord_changed(rdman, coords[2]);
2729 rdman_redraw_changed(rdman); 2731 rdman_redraw_changed(rdman);
2765 redraw_man_t _rdman; 2767 redraw_man_t _rdman;
2766 coord_t *coord; 2768 coord_t *coord;
2767 2769
2768 redraw_man_init(&_rdman, NULL, NULL); 2770 redraw_man_init(&_rdman, NULL, NULL);
2769 rdman = &_rdman; 2771 rdman = &_rdman;
2770 2772
2771 coord = rdman_coord_new(rdman, rdman->root_coord); 2773 coord = rdman_coord_new(rdman, rdman->root_coord);
2772 CU_ASSERT(coord->parent == rdman->root_coord); 2774 CU_ASSERT(coord->parent == rdman->root_coord);
2773 2775
2774 coord_set_opacity(coord, 0.9); 2776 coord_set_opacity(coord, 0.9);
2775 setup_canvas_info(rdman, coord); 2777 setup_canvas_info(rdman, coord);
2789 coord_t *coord1, *coord2; 2791 coord_t *coord1, *coord2;
2790 sh_dummy_t *sh; 2792 sh_dummy_t *sh;
2791 2793
2792 redraw_man_init(&_rdman, NULL, NULL); 2794 redraw_man_init(&_rdman, NULL, NULL);
2793 rdman = &_rdman; 2795 rdman = &_rdman;
2794 2796
2795 coord1 = rdman_coord_new(rdman, rdman->root_coord); 2797 coord1 = rdman_coord_new(rdman, rdman->root_coord);
2796 CU_ASSERT(coord1->parent == rdman->root_coord); 2798 CU_ASSERT(coord1->parent == rdman->root_coord);
2797 2799
2798 coord2 = rdman_coord_new(rdman, coord1); 2800 coord2 = rdman_coord_new(rdman, coord1);
2799 CU_ASSERT(coord2->parent == coord1); 2801 CU_ASSERT(coord2->parent == coord1);
2821 coord_t *coord1, *coord2; 2823 coord_t *coord1, *coord2;
2822 sh_dummy_t *sh; 2824 sh_dummy_t *sh;
2823 2825
2824 redraw_man_init(&_rdman, NULL, NULL); 2826 redraw_man_init(&_rdman, NULL, NULL);
2825 rdman = &_rdman; 2827 rdman = &_rdman;
2826 2828
2827 coord1 = rdman_coord_new(rdman, rdman->root_coord); 2829 coord1 = rdman_coord_new(rdman, rdman->root_coord);
2828 CU_ASSERT(coord1->parent == rdman->root_coord); 2830 CU_ASSERT(coord1->parent == rdman->root_coord);
2829 2831
2830 coord2 = rdman_coord_new(rdman, coord1); 2832 coord2 = rdman_coord_new(rdman, coord1);
2831 CU_ASSERT(coord2->parent == coord1); 2833 CU_ASSERT(coord2->parent == coord1);
2844 2846
2845 CU_ASSERT(geo_get_area(coord2)->x == 0); 2847 CU_ASSERT(geo_get_area(coord2)->x == 0);
2846 CU_ASSERT(geo_get_area(coord2)->y == 0); 2848 CU_ASSERT(geo_get_area(coord2)->y == 0);
2847 CU_ASSERT(geo_get_area(coord2)->w <= 22 && geo_get_area(coord2)->w >= 19); 2849 CU_ASSERT(geo_get_area(coord2)->w <= 22 && geo_get_area(coord2)->w >= 19);
2848 CU_ASSERT(geo_get_area(coord2)->h <= 22 && geo_get_area(coord2)->h >= 19); 2850 CU_ASSERT(geo_get_area(coord2)->h <= 22 && geo_get_area(coord2)->h >= 19);
2849 2851
2850 CU_ASSERT(geo_get_area(coord1)->x == 100); 2852 CU_ASSERT(geo_get_area(coord1)->x == 100);
2851 CU_ASSERT(geo_get_area(coord1)->y == 100); 2853 CU_ASSERT(geo_get_area(coord1)->y == 100);
2852 CU_ASSERT(geo_get_area(coord1)->w <= 22 && geo_get_area(coord1)->w >= 19); 2854 CU_ASSERT(geo_get_area(coord1)->w <= 22 && geo_get_area(coord1)->w >= 19);
2853 CU_ASSERT(geo_get_area(coord1)->h <= 22 && geo_get_area(coord1)->h >= 19); 2855 CU_ASSERT(geo_get_area(coord1)->h <= 22 && geo_get_area(coord1)->h >= 19);
2854 } 2856 }