Mercurial > MadButterfly
comparison src/redraw_man.c @ 840:048cc704bef7
Merge dirty_pcache_area_coords and zeroing_coords.
Also interleave zeroing and updating pcache_area tasks. To zeroing a
cached coord, pcache_area of descendants cached coords must be updated
before zeroing. But, updating pcache_area of a cached coord must be
performed after zeroing the coord. So, they are interleaved.
dirty_pcache_area_coords are removed from redraw_man_t. It is merged
to zeroing_coords.
author | Thinker K.F. Li <thinker@codemud.net> |
---|---|
date | Fri, 17 Sep 2010 12:21:36 +0800 |
parents | a3be0162bf44 |
children | ce6cd06adccf |
comparison
equal
deleted
inserted
replaced
839:a3be0162bf44 | 840:048cc704bef7 |
---|---|
474 } | 474 } |
475 | 475 |
476 static int add_dirty_pcache_area_coord(redraw_man_t *rdman, coord_t *coord) { | 476 static int add_dirty_pcache_area_coord(redraw_man_t *rdman, coord_t *coord) { |
477 if(!coord_get_flags(coord, COF_DIRTY_PCACHE_AREA)) { | 477 if(!coord_get_flags(coord, COF_DIRTY_PCACHE_AREA)) { |
478 coord_set_flags(coord, COF_DIRTY_PCACHE_AREA); | 478 coord_set_flags(coord, COF_DIRTY_PCACHE_AREA); |
479 ADD_DATA(coords, dirty_pcache_area_coords, coord); | 479 ADD_DATA(coords, zeroing_coords, coord); |
480 } | 480 } |
481 return OK; | 481 return OK; |
482 } | 482 } |
483 | 483 |
484 static int add_free_obj(redraw_man_t *rdman, void *obj, | 484 static int add_free_obj(redraw_man_t *rdman, void *obj, |
644 extern void addrm_monitor_hdlr(event_t *evt, void *arg); | 644 extern void addrm_monitor_hdlr(event_t *evt, void *arg); |
645 | 645 |
646 memset(rdman, 0, sizeof(redraw_man_t)); | 646 memset(rdman, 0, sizeof(redraw_man_t)); |
647 | 647 |
648 DARRAY_INIT(&rdman->dirty_coords); | 648 DARRAY_INIT(&rdman->dirty_coords); |
649 DARRAY_INIT(&rdman->dirty_pcache_area_coords); | |
650 DARRAY_INIT(&rdman->dirty_geos); | 649 DARRAY_INIT(&rdman->dirty_geos); |
651 DARRAY_INIT(&rdman->gen_geos); | 650 DARRAY_INIT(&rdman->gen_geos); |
652 DARRAY_INIT(&rdman->zeroing_coords); | 651 DARRAY_INIT(&rdman->zeroing_coords); |
653 | 652 |
654 rdman->geo_pool = elmpool_new(sizeof(geo_t), 128); | 653 rdman->geo_pool = elmpool_new(sizeof(geo_t), 128); |
730 if(rdman->pent_pool) | 729 if(rdman->pent_pool) |
731 elmpool_free(rdman->pent_pool); | 730 elmpool_free(rdman->pent_pool); |
732 if(rdman->coord_canvas_pool) | 731 if(rdman->coord_canvas_pool) |
733 elmpool_free(rdman->coord_canvas_pool); | 732 elmpool_free(rdman->coord_canvas_pool); |
734 DARRAY_DESTROY(&rdman->dirty_coords); | 733 DARRAY_DESTROY(&rdman->dirty_coords); |
735 DARRAY_DESTROY(&rdman->dirty_pcache_area_coords); | |
736 DARRAY_DESTROY(&rdman->dirty_geos); | 734 DARRAY_DESTROY(&rdman->dirty_geos); |
737 DARRAY_DESTROY(&rdman->gen_geos); | 735 DARRAY_DESTROY(&rdman->gen_geos); |
738 DARRAY_DESTROY(&rdman->zeroing_coords); | 736 DARRAY_DESTROY(&rdman->zeroing_coords); |
739 return ERR; | 737 return ERR; |
740 } | 738 } |
751 | 749 |
752 /* Mark rdman clean that shapes and coords can be freed | 750 /* Mark rdman clean that shapes and coords can be freed |
753 * successfully. | 751 * successfully. |
754 */ | 752 */ |
755 DARRAY_CLEAN(&rdman->dirty_coords); | 753 DARRAY_CLEAN(&rdman->dirty_coords); |
756 DARRAY_CLEAN(&rdman->dirty_pcache_area_coords); | |
757 DARRAY_CLEAN(&rdman->dirty_geos); | 754 DARRAY_CLEAN(&rdman->dirty_geos); |
758 | 755 |
759 coord = postorder_coord_subtree(rdman->root_coord, NULL); | 756 coord = postorder_coord_subtree(rdman->root_coord, NULL); |
760 while(coord) { | 757 while(coord) { |
761 saved_coord = coord; | 758 saved_coord = coord; |
787 elmpool_free(rdman->paint_color_pool); | 784 elmpool_free(rdman->paint_color_pool); |
788 elmpool_free(rdman->pent_pool); | 785 elmpool_free(rdman->pent_pool); |
789 elmpool_free(rdman->coord_canvas_pool); | 786 elmpool_free(rdman->coord_canvas_pool); |
790 | 787 |
791 DARRAY_DESTROY(&rdman->dirty_coords); | 788 DARRAY_DESTROY(&rdman->dirty_coords); |
792 DARRAY_DESTROY(&rdman->dirty_pcache_area_coords); | |
793 DARRAY_DESTROY(&rdman->dirty_geos); | 789 DARRAY_DESTROY(&rdman->dirty_geos); |
794 DARRAY_DESTROY(&rdman->gen_geos); | 790 DARRAY_DESTROY(&rdman->gen_geos); |
795 DARRAY_DESTROY(&rdman->zeroing_coords); | 791 DARRAY_DESTROY(&rdman->zeroing_coords); |
796 } | 792 } |
797 | 793 |
1419 * normal one. (see compute_aggr_of_cached_coord()). | 1415 * normal one. (see compute_aggr_of_cached_coord()). |
1420 * | 1416 * |
1421 * \note coords their opacity != 1 are also traded as cached ones. | 1417 * \note coords their opacity != 1 are also traded as cached ones. |
1422 */ | 1418 */ |
1423 static int clean_coord(redraw_man_t *rdman, coord_t *coord) { | 1419 static int clean_coord(redraw_man_t *rdman, coord_t *coord) { |
1424 coord_t *child; | |
1425 int r; | 1420 int r; |
1426 | 1421 |
1427 setup_canvas_info(rdman, coord); | 1422 setup_canvas_info(rdman, coord); |
1428 | 1423 |
1429 compute_aggr(coord); | 1424 compute_aggr(coord); |
1538 max_y = min_y + area->h; | 1533 max_y = min_y + area->h; |
1539 | 1534 |
1540 for(cur = preorder_coord_subtree(coord, coord); | 1535 for(cur = preorder_coord_subtree(coord, coord); |
1541 cur != NULL; | 1536 cur != NULL; |
1542 cur = preorder_coord_subtree(coord, cur)) { | 1537 cur = preorder_coord_subtree(coord, cur)) { |
1543 area = coord_get_area(cur); | 1538 if(coord_is_cached(cur)) { |
1539 preorder_coord_skip_subtree(cur); | |
1540 /* This means pcache_area of descendants must be computed | |
1541 * before zeroing ancestor cached one. | |
1542 * (See add_rdman_zeroing_n_pcache_coords()) | |
1543 */ | |
1544 area = coord_get_pcache_area(cur); | |
1545 } else | |
1546 area = coord_get_area(cur); | |
1547 | |
1544 if(area->x < min_x) | 1548 if(area->x < min_x) |
1545 min_x = area->x; | 1549 min_x = area->x; |
1546 if(area->y < min_y) | 1550 if(area->y < min_y) |
1547 min_y = area->y; | 1551 min_y = area->y; |
1548 | 1552 |
1551 | 1555 |
1552 if(x > max_x) | 1556 if(x > max_x) |
1553 max_x = x; | 1557 max_x = x; |
1554 if(y > max_y) | 1558 if(y > max_y) |
1555 max_y = y; | 1559 max_y = y; |
1556 if(coord_is_cached(cur)) | |
1557 preorder_coord_skip_subtree(cur); | |
1558 } | 1560 } |
1559 | 1561 |
1560 w = max_x - min_x; | 1562 w = max_x - min_x; |
1561 h = max_y - min_y; | 1563 h = max_y - min_y; |
1562 | 1564 |
1623 } | 1625 } |
1624 | 1626 |
1625 coord_set_flags(coord, COF_JUST_ZERO); | 1627 coord_set_flags(coord, COF_JUST_ZERO); |
1626 } | 1628 } |
1627 | 1629 |
1628 /*! \brief Add canvas owner of dirty geos to redraw_man_t::zeroing_coords. | 1630 /*! \brief Add coords that need to perform zeroing or re-compute pcache_area. |
1629 * | 1631 * |
1630 * All possible coords that need a zeroing have at least one dirty geo. | 1632 * A coord that need to perform zeroing has one or more dirty members |
1631 */ | 1633 * in its descendants. |
1632 static int add_rdman_zeroing_coords(redraw_man_t *rdman) { | 1634 * |
1635 * To zeroing a coord, pcache_area of first level cached descendants | |
1636 * must be updated. To update the pcache_area of a cached coord, the | |
1637 * cached coord also need to perform zeroing. So, zeroing and | |
1638 * re-computing pcache_area are interleaved. | |
1639 * | |
1640 * The pcache_area of a cached coord must be re-computed if its | |
1641 * parent/ancestors is dirty/just cleaned, or it must be zeroed. It | |
1642 * means cached coord with jsut cleaned parent should also re-compute | |
1643 * pcache_area. So, this function also check and add coords for this | |
1644 * situation. | |
1645 */ | |
1646 static int add_rdman_zeroing_n_pcache_coords(redraw_man_t *rdman) { | |
1633 int i; | 1647 int i; |
1634 int n_dirty_geos; | 1648 int n_dirty_geos; |
1635 geo_t **dirty_geos, *geo; | 1649 geo_t **dirty_geos, *geo; |
1636 int n_dirty_coords; | 1650 int n_dirty_coords; |
1637 coord_t **dirty_coords, *coord; | 1651 coord_t **dirty_coords, *coord; |
1652 coord_t *parent_coord; | |
1638 | 1653 |
1639 /* Mark all cached ancestral coords of dirty geos */ | 1654 /* Mark all cached ancestral coords of dirty geos */ |
1640 n_dirty_geos = rdman->dirty_geos.num; | 1655 n_dirty_geos = rdman->dirty_geos.num; |
1641 dirty_geos = rdman->dirty_geos.ds; | 1656 dirty_geos = rdman->dirty_geos.ds; |
1642 for(i = 0; i < n_dirty_geos; i++) { | 1657 for(i = 0; i < n_dirty_geos; i++) { |
1667 FOR_COORDS_PREORDER(rdman->root_coord, coord) { | 1682 FOR_COORDS_PREORDER(rdman->root_coord, coord) { |
1668 if(!coord_is_cached(coord) || coord_is_root(coord)) | 1683 if(!coord_is_cached(coord) || coord_is_root(coord)) |
1669 continue; /* skip coords that is not cached */ | 1684 continue; /* skip coords that is not cached */ |
1670 | 1685 |
1671 if(!coord_get_flags(coord, COF_TEMP_MARK)) { | 1686 if(!coord_get_flags(coord, COF_TEMP_MARK)) { |
1687 parent_coord = coord_get_parent(coord); | |
1688 /* The pcache_area of a cached coord that is a child of a | |
1689 * just cleaned one must be recomputed. | |
1690 */ | |
1691 if(coord_get_flags(parent_coord, COF_JUST_CLEAN)) | |
1692 add_dirty_pcache_area_coord(rdman, coord); | |
1693 | |
1672 preorder_coord_skip_subtree(coord); | 1694 preorder_coord_skip_subtree(coord); |
1673 continue; | 1695 continue; |
1674 } | 1696 } |
1675 add_zeroing_coord(rdman, coord); | 1697 add_zeroing_coord(rdman, coord); |
1676 | 1698 |
1703 * performed before zeroing. It means ancestors of a | 1725 * performed before zeroing. It means ancestors of a |
1704 * cached coord would not effect it when zeroing. | 1726 * cached coord would not effect it when zeroing. |
1705 */ | 1727 */ |
1706 for(i = all_zeroing->num - 1; i >= 0; i--) { | 1728 for(i = all_zeroing->num - 1; i >= 0; i--) { |
1707 coord = all_zeroing->ds[i]; | 1729 coord = all_zeroing->ds[i]; |
1708 zeroing_coord(rdman, coord); | 1730 if(coord_is_zeroing(coord)) |
1709 } | 1731 zeroing_coord(rdman, coord); |
1710 | 1732 /* This is required by ancester cached ones to perform |
1711 return OK; | 1733 * zeroing. |
1712 } | 1734 */ |
1713 | 1735 compute_pcache_area(coord); |
1714 /*! \brief Compute pcache_area for coords whoes pcache_area is dirty. | 1736 } |
1715 * | 1737 |
1716 * coord_t::dirty_pcache_area_coords also includes part of coords in | |
1717 * coord_t::zeroing_coords. The pcache_area of coords that is in | |
1718 * coord_t::dirty_pcache_area_coords, but is not in | |
1719 * coord_t::zeroing_coords should be computed here. | |
1720 * zeroing_rdman_coords() is responsible for computing pcache_area for | |
1721 * zeroing ones. | |
1722 */ | |
1723 static int | |
1724 compute_rdman_coords_pcache_area(redraw_man_t *rdman) { | |
1725 coords_t *all_coords; | |
1726 coord_t *coord; | |
1727 int i; | |
1728 | |
1729 all_coords = &rdman->dirty_pcache_area_coords; | |
1730 for(i = 0; i < all_coords->num; i++) { | |
1731 coord = all_coords->ds[i]; | |
1732 if(coord_get_flags(coord, COF_DIRTY_PCACHE_AREA)) | |
1733 compute_pcache_area(coord); | |
1734 } | |
1735 return OK; | 1738 return OK; |
1736 } | 1739 } |
1737 | 1740 |
1738 /*! \brief Add aggregated dirty areas to ancestor. | 1741 /*! \brief Add aggregated dirty areas to ancestor. |
1739 * | 1742 * |
1854 * areas and one or new areas. Both aggregation areas are add into | 1857 * areas and one or new areas. Both aggregation areas are add into |
1855 * dirty_areas list of closet ancestral cached coord. | 1858 * dirty_areas list of closet ancestral cached coord. |
1856 */ | 1859 */ |
1857 static int add_rdman_aggr_dirty_areas(redraw_man_t *rdman) { | 1860 static int add_rdman_aggr_dirty_areas(redraw_man_t *rdman) { |
1858 int i; | 1861 int i; |
1859 int n_zeroing; | 1862 coord_t *coord, *parent_coord, *pcached_coord; |
1860 coord_t **zeroings; | 1863 int n_zeroing_coords; /* number of dirty pcache area coords */ |
1861 coord_t *coord, *pcached_coord; | 1864 coord_t **zeroing_coords; /* dirty pcache area coords */ |
1862 int n_dpca_coords; /* number of dirty pcache area coords */ | 1865 |
1863 coord_t **dpca_coords; /* dirty pcache area coords */ | 1866 n_zeroing_coords = rdman->zeroing_coords.num; |
1864 | 1867 zeroing_coords = rdman->zeroing_coords.ds; |
1865 /* Add aggregated areas to parent cached one for coords in zeroing | 1868 for(i = n_zeroing_coords - 1; i >= 0; i--) { |
1866 * list | 1869 coord = zeroing_coords[i]; |
1867 */ | |
1868 n_zeroing = rdman->zeroing_coords.num; | |
1869 zeroings = rdman->zeroing_coords.ds; | |
1870 for(i = 0; i < n_zeroing; i++) { | |
1871 coord = zeroings[i]; | |
1872 | |
1873 if(coord_get_flags(coord, COF_TEMP_MARK)) | |
1874 continue; | |
1875 coord_set_flags(coord, COF_TEMP_MARK); | |
1876 | |
1877 pcached_coord = coord_get_cached(coord_get_parent(coord)); | |
1878 | |
1879 if(coord_is_root(coord) || IS_CACHE_REDRAW_ALL(pcached_coord)) | |
1880 continue; | |
1881 | |
1882 if(IS_CACHE_REDRAW_ALL(coord)) { | 1870 if(IS_CACHE_REDRAW_ALL(coord)) { |
1871 parent_coord = coord_get_parent(coord); | |
1872 pcached_coord = coord_get_cached(parent_coord); | |
1873 | |
1883 add_dirty_area(rdman, pcached_coord, | 1874 add_dirty_area(rdman, pcached_coord, |
1884 coord_get_pcache_area(coord)); | 1875 coord_get_pcache_area(coord)); |
1885 add_dirty_area(rdman, pcached_coord, | 1876 add_dirty_area(rdman, pcached_coord, |
1886 coord_get_pcache_last_area(coord)); | 1877 coord_get_pcache_last_area(coord)); |
1887 } else { | 1878 } else { |
1888 add_aggr_dirty_areas_to_ancestor(rdman, coord); | 1879 add_aggr_dirty_areas_to_ancestor(rdman, coord); |
1889 } | 1880 } |
1890 } | 1881 } |
1891 | 1882 |
1892 /* Add pcache_areas to parent cached one for coord that is | |
1893 * non-zeroing and its parent is changed. | |
1894 */ | |
1895 n_dpca_coords = rdman->dirty_pcache_area_coords.num; | |
1896 dpca_coords = rdman->dirty_pcache_area_coords.ds; | |
1897 for(i = 0; i < n_dpca_coords; i++) { | |
1898 coord = dpca_coords[i]; | |
1899 | |
1900 if(coord_get_flags(coord, COF_TEMP_MARK)) | |
1901 continue; | |
1902 coord_set_flags(coord, COF_TEMP_MARK); | |
1903 | |
1904 pcached_coord = coord_get_cached(coord_get_parent(coord)); | |
1905 | |
1906 if(coord_is_root(coord) || IS_CACHE_REDRAW_ALL(pcached_coord)) | |
1907 continue; | |
1908 | |
1909 add_dirty_area(rdman, pcached_coord, | |
1910 coord_get_pcache_area(coord)); | |
1911 add_dirty_area(rdman, pcached_coord, | |
1912 coord_get_pcache_last_area(coord)); | |
1913 } | |
1914 | |
1915 /* Remove temporary mark */ | |
1916 for(i = 0; i < n_zeroing; i++) { | |
1917 coord_clear_flags(zeroings[i], COF_TEMP_MARK); | |
1918 } | |
1919 for(i = 0; i < n_dpca_coords; i++) { | |
1920 coord_clear_flags(dpca_coords[i], COF_TEMP_MARK); | |
1921 } | |
1922 | |
1923 return OK; | 1883 return OK; |
1924 } | |
1925 | |
1926 static int | |
1927 add_rdman_coords_pcache_area(redraw_man_t *rdman) { | |
1928 coord_t *root, *cur; | |
1929 coord_t *parent; | |
1930 | |
1931 root = rdman->root_coord; | |
1932 FOR_COORDS_POSTORDER(root, cur) { | |
1933 if(coord_is_root(cur)) | |
1934 continue; | |
1935 if(!coord_is_cached(cur)) | |
1936 continue; | |
1937 if(!coord_get_flags(cur, COF_JUST_ZERO | COF_JUST_CLEAN)) { | |
1938 parent = coord_get_parent(cur); | |
1939 if(!coord_get_flags(parent, COF_JUST_CLEAN)) | |
1940 continue; | |
1941 } | |
1942 add_dirty_pcache_area_coord(rdman, cur); | |
1943 } | |
1944 } | 1884 } |
1945 | 1885 |
1946 /*! \brief Swap geo_t::cur_area and geo_t::last_area for a geo_t. | 1886 /*! \brief Swap geo_t::cur_area and geo_t::last_area for a geo_t. |
1947 * | 1887 * |
1948 * It is call by rdman_clean_dirties() to swap areas for members of | 1888 * It is call by rdman_clean_dirties() to swap areas for members of |
2041 return ERR; | 1981 return ERR; |
2042 | 1982 |
2043 /* Zeroing must be performed after clearing to get latest position | 1983 /* Zeroing must be performed after clearing to get latest position |
2044 * of shapes for computing new bounding box | 1984 * of shapes for computing new bounding box |
2045 */ | 1985 */ |
2046 r = add_rdman_zeroing_coords(rdman); | 1986 r = add_rdman_zeroing_n_pcache_coords(rdman); |
2047 if(r != OK) | 1987 if(r != OK) |
2048 return ERR; | 1988 return ERR; |
2049 | 1989 |
2050 r = zeroing_rdman_coords(rdman); | 1990 r = zeroing_rdman_coords(rdman); |
2051 if(r != OK) | |
2052 return ERR; | |
2053 | |
2054 r = add_rdman_coords_pcache_area(rdman); | |
2055 if(r != OK) | |
2056 return ERR; | |
2057 | |
2058 r = compute_rdman_coords_pcache_area(rdman); | |
2059 if(r != OK) | 1991 if(r != OK) |
2060 return ERR; | 1992 return ERR; |
2061 | 1993 |
2062 r = add_rdman_aggr_dirty_areas(rdman); | 1994 r = add_rdman_aggr_dirty_areas(rdman); |
2063 if(r != OK) | 1995 if(r != OK) |
2077 } | 2009 } |
2078 coords = rdman->zeroing_coords.ds; | 2010 coords = rdman->zeroing_coords.ds; |
2079 for(i = 0; i < rdman->zeroing_coords.num; i++) | 2011 for(i = 0; i < rdman->zeroing_coords.num; i++) |
2080 coord_clear_flags(coords[i], | 2012 coord_clear_flags(coords[i], |
2081 COF_JUST_CLEAN | COF_JUST_ZERO | COF_SKIP_ZERO); | 2013 COF_JUST_CLEAN | COF_JUST_ZERO | COF_SKIP_ZERO); |
2082 coords = rdman->dirty_pcache_area_coords.ds; | 2014 |
2083 for(i = 0; i < rdman->dirty_pcache_area_coords.num; i++) | |
2084 coord_clear_flags(coords[i], | |
2085 COF_JUST_CLEAN | COF_JUST_ZERO | COF_SKIP_ZERO); | |
2086 | |
2087 /* \see GEO_SWAP() */ | 2015 /* \see GEO_SWAP() */ |
2088 for(i = 0; i < rdman->dirty_geos.num; i++) { | 2016 for(i = 0; i < rdman->dirty_geos.num; i++) { |
2089 geo = geos[i]; | 2017 geo = geos[i]; |
2090 geo_clear_flags(geo, GEF_SWAP); | 2018 geo_clear_flags(geo, GEF_SWAP); |
2091 } | 2019 } |
2287 child = FIRST_CHILD(coord); | 2215 child = FIRST_CHILD(coord); |
2288 while(child != NULL || member != NULL) { | 2216 while(child != NULL || member != NULL) { |
2289 if(child && child->before_pmem == mem_idx) { | 2217 if(child && child->before_pmem == mem_idx) { |
2290 if(coord_is_cached(child)) { | 2218 if(coord_is_cached(child)) { |
2291 if(!(child->flags & COF_HIDDEN) && | 2219 if(!(child->flags & COF_HIDDEN) && |
2292 is_area_in_areas(coord_get_area(child), n_areas, areas)) { | 2220 is_area_in_areas(coord_get_pcache_area(child), |
2221 n_areas, areas)) { | |
2293 update_cached_canvas_2_parent(rdman, child); | 2222 update_cached_canvas_2_parent(rdman, child); |
2294 dirty = 1; | 2223 dirty = 1; |
2295 } | 2224 } |
2296 } else { | 2225 } else { |
2297 r = draw_coord_shapes_in_dirty_areas(rdman, child); | 2226 r = draw_coord_shapes_in_dirty_areas(rdman, child); |
2448 } | 2377 } |
2449 | 2378 |
2450 DARRAY_CLEAN(&rdman->dirty_coords); | 2379 DARRAY_CLEAN(&rdman->dirty_coords); |
2451 DARRAY_CLEAN(&rdman->dirty_geos); | 2380 DARRAY_CLEAN(&rdman->dirty_geos); |
2452 DARRAY_CLEAN(&rdman->zeroing_coords); | 2381 DARRAY_CLEAN(&rdman->zeroing_coords); |
2453 DARRAY_CLEAN(&rdman->dirty_pcache_area_coords); | |
2454 | 2382 |
2455 /* Free postponsed removing */ | 2383 /* Free postponsed removing */ |
2456 free_free_objs(rdman); | 2384 free_free_objs(rdman); |
2457 | 2385 |
2458 redraw = rdman_get_redraw_subject(rdman); | 2386 redraw = rdman_get_redraw_subject(rdman); |