int BoxShadow_GetX( LCUI_BoxShadow *shadow ) { if( shadow->x <= SHADOW_WIDTH(shadow) ) { return 0; } return shadow->x - SHADOW_WIDTH(shadow); }
int BoxShadow_GetBoxY( LCUI_BoxShadow *shadow ) { if( shadow->y >= SHADOW_WIDTH(shadow) ) { return 0; } return SHADOW_WIDTH(shadow) - shadow->y; }
/** 计算Box在添加阴影后的宽度 */ int BoxShadow_GetWidth( LCUI_BoxShadow *shadow, int box_w ) { if( shadow->x >= SHADOW_WIDTH(shadow) ) { return box_w + SHADOW_WIDTH(shadow) + shadow->x; } else if( shadow->x <= -SHADOW_WIDTH(shadow) ) { return box_w + SHADOW_WIDTH(shadow) - shadow->x; } return box_w + SHADOW_WIDTH(shadow)*2; }
/** 计算Box在添加阴影后的高度 */ int BoxShadow_GetHeight( LCUI_BoxShadow *shadow, int box_h ) { if( shadow->y >= SHADOW_WIDTH(shadow) ) { return box_h + SHADOW_WIDTH(shadow) + shadow->y; } else if( shadow->y <= -SHADOW_WIDTH(shadow) ) { return box_h + SHADOW_WIDTH(shadow) - shadow->y; } return box_h + SHADOW_WIDTH(shadow)*2; }
int BoxShadow_GetBoxHeight( LCUI_BoxShadow *shadow, int h ) { h -= SHADOW_WIDTH(shadow)*2; if( shadow->y >= SHADOW_WIDTH(shadow) ) { return h - shadow->y + SHADOW_WIDTH(shadow); } else if( shadow->y <= -SHADOW_WIDTH(shadow) ) { return h + shadow->y + SHADOW_WIDTH(shadow); } return h; }
int BoxShadow_GetBoxWidth( LCUI_BoxShadow *shadow, int w ) { w -= SHADOW_WIDTH(shadow)*2; /* 如果水平向右的偏移距离大于阴影宽度,说明内容区左上角与容器一致 */ if( shadow->x >= SHADOW_WIDTH(shadow) ) { return w - (shadow->x - SHADOW_WIDTH(shadow)); } /* 如果水平向左的偏移距离大于阴影宽度,说明阴影区左上角与容器一致 */ else if( shadow->x <= -SHADOW_WIDTH(shadow) ) { return w + shadow->x + SHADOW_WIDTH(shadow); } /* 水平偏移距离没有超出阴影宽度,容器大小会是固定的,所以直接减 * 去两边的阴影宽度即可得到内容区宽度 */ return w; }
static void Graph_DrawRightShadow( LCUI_PaintContext paint, LCUI_Rect *box, LCUI_BoxShadow *shadow ) { float v, a; int s, t, x, y, bound_x, bound_y; LCUI_Color color; LCUI_Graph *graph; LCUI_Rect shadow_area, box_area, area; box_area.x = BoxShadow_GetBoxX( shadow ); box_area.y = BoxShadow_GetBoxY( shadow ); box_area.w = BoxShadow_GetBoxWidth( shadow, box->w ); box_area.h = BoxShadow_GetBoxHeight( shadow, box->h ); shadow_area.x = BoxShadow_GetX( shadow ) + SHADOW_WIDTH(shadow); shadow_area.x += box_area.w + INNER_SHADOW_WIDTH(shadow); shadow_area.y = BoxShadow_GetY( shadow ) + BLUR_WIDTH(shadow); shadow_area.w = BLUR_WIDTH(shadow); shadow_area.h = box_area.h + INNER_SHADOW_WIDTH(shadow)*2; color = shadow->color; bound_x = shadow_area.x + shadow_area.w; bound_y = shadow_area.y + shadow_area.h; graph = Graph_GetQuote( &paint->canvas ); Graph_GetValidRect( &paint->canvas, &area ); if( !LCUIRect_GetOverlayRect( &area, &paint->rect, &area ) ) { return; } s = 255; t = BLUR_WIDTH(shadow); v = 512.0/t; a = 2*(v*t-s)/(t*t); for( t=0,x=shadow_area.x; x<bound_x; ++x,++t ) { if( x < area.x || x >= area.x + area.w ) { continue; } color.alpha = (uchar_t)(s-(v*t-(a*t*t)/2)); color.alpha *= shadow->color.a/255.0; for( y=shadow_area.y; y<bound_y; ++y ) { if( y < area.y || y >= area.y + area.h ) { continue; } if( y >= box_area.y && y < box_area.y + box_area.h && x >= box_area.x && x < box_area.x + box_area.w ) { continue; } Graph_SetPixel( graph, x, y, color ); } } }