18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Copyright (C) 2007-2008 The Android Open Source Project 28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** 38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** This software is licensed under the terms of the GNU General Public 48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** License version 2, as published by the Free Software Foundation, and 58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** may be copied, distributed, and modified under those terms. 68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** 78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** This program is distributed in the hope that it will be useful, 88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** but WITHOUT ANY WARRANTY; without even the implied warranty of 98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** GNU General Public License for more details. 118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/ 128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/skin/composer.h" 138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stddef.h> 148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/utils/system.h" 158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* forwards */ 178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void skin_plate_get_region ( SkinPlate* p, SkinRegion *pregion ); 188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void skin_plate_get_opaque_region( SkinPlate* p, SkinRegion *pregion ); 198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* recompute region if needed */ 218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void 228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_plate_ensure_region( SkinPlate* p ) 238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (p->any.type == SKIN_PLATE_SURFACE || p->group.hasRegion) 258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else { 278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int n, count = areflist_count( p->group.children ); 288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_region_reset(p->any.region); 308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (n = 0; n < count; n++) { 328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SkinRegion r[1]; 338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SkinPlate* child = areflist_get( p->group.children, n ); 348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_plate_get_region( child, r ); 368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_region_translate( r, child->any.pos.x, child->any.pos.y ); 378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_region_union( p->any.region, r ); 388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p->group.hasRegion = 1; 418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* return region in 'region' */ 458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void 468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_plate_get_region( SkinPlate* p, SkinRegion* region ) 478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ( p->any.type != SKIN_PLATE_SURFACE && !p->group.hasRegion ) { 498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_plate_ensure_region(p); 508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_region_init_copy( region, p->any.region ); 528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* recompute opaque region is needed */ 568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void 578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_plate_ensure_opaque_region( SkinPlate* p ) 588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (p->any.type != SKIN_PLATE_SURFACE && !p->group.hasOpaqueRegion) { 608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int n, count = areflist_count( p->group.children ); 618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_region_reset(p->group.opaqueRegion); 638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (n = 0; n < count; n++) { 658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SkinRegion r[1]; 668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SkinPlate* child = areflist_get( p->group.children, n ); 678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_plate_get_opaque_region(child, r); 698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_region_translate(r, child->any.pos.x, child->any.pos.y); 708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_region_union( p->group.opaqueRegion, r); 718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p->group.hasOpaqueRegion = 1; 748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* return opaque pixels region */ 798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void 808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_plate_get_opaque_region( SkinPlate* p, SkinRegion *pregion ) 818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ( p->any.type == SKIN_PLATE_SURFACE ) { 838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (p->any.isOpaque) 848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_region_init_copy(pregion, p->any.region); 858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_region_reset(pregion); 878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_plate_ensure_opaque_region(p); 898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_region_init_copy(pregion, p->group.opaqueRegion); 908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* invalidate region in parent groups */ 958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void 968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_plate_invalidate_parent( SkinPlate* p ) 978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!p->any.isVisible) 998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (p) { 1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (p->any.type != SKIN_PLATE_SURFACE) { 1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p->group.hasRegion = 0; 1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p->group.hasOpaqueRegion = 0; 1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p = p->any.parent; 1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void 1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_plate_invalidate_( SkinPlate* p, SkinRegion* r, SkinPlate* child ) 1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (p->any.type != SKIN_PLATE_SURFACE) { 1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int n = areflist_count( p->group.children ); 1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (child != NULL) { 1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n = areflist_indexOf( p->group.children, child ); 1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (n > 0) { 1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n -= 1; 1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project child = areflist_get( p->group.children, n ); 1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_region_translate( r, child->any.pos.x, child->any.pos.y ); 1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_plate_invalidate_( p, r, NULL ); 1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_region_translate( r, -child->any.pos.x, -child->any.pos.y ); 1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (skin_region_is_empty(r)) 1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (p->any.type != SKIN_PLATE_SPACE) { 1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SkinPlate* parent = p->any.parent; 1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_region_translate(r, parent->any.pos.x, parent->any.pos.y ); 1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_plate_invalidate_(parent, r, p); 1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* send to viewports */ 1348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int n, count = areflist_count( p->space.viewports ); 1358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (n = 0; n < count; n++) { 1368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SkinViewport* v = areflist_get( p->space.viewports, n ); 1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_viewport_invalidate(v, r); 1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void 1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_plate_invalidate_region( SkinPlate* p ) 1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SkinRegion r[1]; 1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_plate_get_region( p, r ); 1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_plate_invalidate_(p->any.parent, r, p); 1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_region_reset(r); 1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* change visibility */ 1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid 1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_plate_set_visible( SkinPlate* p, int isVisible ) 1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project isVisible = !!isVisible; 1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (isVisible == p->any.isVisible) 1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_plate_invalidate_parent(p); 1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_plate_invalidate_region(p); 1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p->any.isVisible = isVisible; 1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid 1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_plate_set_opaque( SkinPlate* p, int isOpaque ) 1688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project isOpaque = !!isOpaque; 1708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (isOpaque == p->any.isOpaque) 1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 1728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_plate_invalidate_parent(p); 1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_plate_invalidate_region(p); 1758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p->any.isOpaque = isOpaque; 1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern SkinPlate* 1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_plate_surface( SkinPlate* parent, 1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SkinPos* pos, 1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SkinRegion* region, 1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project void* surface, 1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SkinPlateDrawFunc draw, 1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SkinPlateDoneFunc done ) 1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SkinPlate* p; 1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ANEW0(p); 1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p->any.type = SKIN_PLATE_SURFACE; 1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p->any.parent = parent; 1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p->any.pos.x = pos->x; 1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p->any.pos.y = pos->y; 1958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p->any.isVisible = 1; 1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p->any.isOpaque = 1; 1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_region_init_copy( p->any.region, region ); 1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return p; 2008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectSkinPlate* 2048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_plate_group( SkinPlate* parent, SkinPos* pos ) 2058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SkinRegion r[1]; 2078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SkinPlate* p; 2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_region_reset(r); 2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p = skin_plate_surface( parent, pos, r, NULL, NULL, NULL ); 2118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p->any.type = SKIN_PLATE_GROUP; 2128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p->group.hasOpaqueRegion = 0; 2138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_region_init_empty( p->group.opaqueRegion ); 2148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project areflist_init( p->group.children ); 2168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return p; 2178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectSkinPlate* 2218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_plate_space( void ) 2228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SkinPos pos; 2248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SkinPlate* p; 2258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pos.x = pos.y = 0; 2278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p = skin_plate_group( NULL, &pos ); 2288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p->any.type = SKIN_PLATE_SPACE; 2298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project areflist_init( p->space.viewports ); 2308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return p; 2318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern void 2358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_plate_free( SkinPlate* p ) 2368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (p->any.type >= SKIN_PLATE_SPACE) { 2388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while ( areflist_count( p->space.viewports ) ) 2398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_viewport_free( areflist_get( p->space.viewports, 0 ) ); 2408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (p->any.type >= SKIN_PLATE_GROUP) { 2428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_region_reset( p->group.opaqueRegion ); 2438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p->group.hasOpaqueRegion = 0; 2448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p->group.hasRegion = 0; 2458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while ( areflist_count( p->group.children ) ) 2478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_plate_free( areflist_get( p->group.children, 0 ) ); 2488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (p->any.type == SKIN_PLATE_SURFACE) { 2508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (p->surface.done) 2518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p->surface.done( p->surface.user ); 2528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_region_reset( p->any.region ); 2558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (p->any.parent) { 2574c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner areflist_delFirst( p->any.parent->group.children, p ); 2588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid 2628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_plate_invalidate( SkinPlate* plate, SkinRegion* region ) 2638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SkinRegion r[1]; 2658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_region_init_copy( r, region ); 2668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* we use two regions to manage the front-to-back composition here 2708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 2718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 'updated' initially contains the update region, in parent coordinates 2728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 2738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 'drawn' is initially empty, and will be filled with the region of translucent 2748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * pixels that have been 2758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 2768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * for a given surface plate, we translate the regions to plate coordinates, 2778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * then we do an opaque blit of 'intersection(updated,region)', then removing it from 'updated' 2788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 2798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * after that, we make a DSTOVER blit of 'intersection(drawn,region)' 2808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * if the plate is not opaque, we add this intersection to 'drawn' 2818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 2828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 2838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void 2848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_plate_redraw( SkinPlate* plate, SkinRegion* updated, SkinRegion* drawn, SkinPos* apos, SkinViewport* viewport ) 2858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SkinPos pos = plate->any.pos; 2878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!plate->any.isVisible) 2898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 2908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (skin_region_is_empty(updated) && skin_region_is_empty(drawn)) 2928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 2938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* translate regions to plate coordinates */ 2958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_region_translate( updated, pos.x, pos.y ); 2968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_region_translate( drawn, pos.y, pos.y ); 2978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project apos->x += pos.x; 2988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project apos->y += pos.y; 2998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (plate->any.type == SKIN_PLATE_SURFACE) { 3018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SkinRegion r[1]; 3028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* inter(updated,region) => opaque blit + remove 'region' from 'updated'*/ 3048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_plate_get_region(plate, r); 3058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_region_intersect(r, updated); 3068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!skin_region_is_empty(r)) { 3078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project plate->surface.draw( plate->surface.user, r, apos, viewport, 1 ); 3088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_region_substract(updated, r); 3098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_region_reset(r); 3108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* inter(drawn,region) => DSTOVER blit + if non-opaque add it to 'drawn' */ 3138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_plate_get_region(plate, r); 3148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_region_intersect(r, drawn); 3158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!skin_region_is_empty(r)) { 3168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project plate->surface.draw( plate->surface.user, r, apos, viewport, 0); 3178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!plate->any.isOpaque) 3188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_region_union(drawn, r); 3198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_region_reset(r); 3208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 3238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int n, count = areflist_count(plate->group.children); 3248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (n = 0; n < count; n++) { 3258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SkinPos pos; 3268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pos.x = apos->x + plate->any.pos.x; 3288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pos.y = apos->y + plate->any.pos.y; 3298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_plate_redraw( areflist_get(plate->group.children, n ), updated, drawn, &pos, viewport ); 3318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (skin_region_is_empty(updated) && skin_region_is_empty(drawn)) 3328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 3338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* convert back to parent coordinates */ 3378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project apos->x -= pos.x; 3388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project apos->y -= pos.y; 3398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_region_translate( updated, -pos.x, -pos.y ); 3408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_region_translate( drawn, -pos.x, -pos.y ); 3418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern SkinViewport* 3458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_viewport( SkinPlate* space, SkinRect* rect, void* surface, int sx, int sy ) 3468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SkinViewport* v; 3488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ANEW0(v); 3508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project v->space = space; 3518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project v->rect = rect[0]; 3528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project v->spos.x = sx; 3538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project v->spos.y = sy; 3548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project v->surface = surface; 3558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_region_init_empty( v->update ); 3578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return v; 3588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern void 3618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_viewport_free( SkinViewport* v ) 3628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SkinPlate* space = v->space; 3648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (space != NULL) { 3654c0f745dc80d392fddea23eb8d4d7d86425ce0c6David 'Digit' Turner areflist_delFirst( space->space.viewports, v ); 3668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project v->space = NULL; 3678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_region_reset( v->update ); 3698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project AFREE(v); 3708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern void 3738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_viewport_invalidate( SkinViewport* v, SkinRegion* region ) 3748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SkinRegion r[1]; 3768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_region_init_copy(r,region); 3778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_region_translate(r, -v->spos.x, -v->spos.y); 3788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_region_intersect_rect(r,&v->rect); 3798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_region_union( v->update, r ); 3808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_region_reset(r); 3818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern void 3848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectskin_viewport_redraw( SkinViewport* v ) 3858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (v->space && !skin_region_is_empty(v->update)) { 3878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SkinRegion update[1]; 3888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SkinRegion drawn[1]; 3898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SkinPos apos; 3908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_region_copy(update, v->update); 3928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_region_reset(drawn); 3938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_region_reset( v->update ); 3948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project apos.x = apos.y = 0; 3968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_plate_redraw( v->space, update, drawn, &apos, v ); 3978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_region_reset(update); 3998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project skin_region_reset(drawn); 4008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 402