#include "lv_draw_dave2d.h" #if LV_USE_DRAW_DAVE2D #include "../../../misc/lv_area_private.h" void lv_draw_dave2d_fill(lv_draw_dave2d_unit_t * u, const lv_draw_fill_dsc_t * dsc, const lv_area_t * coords) { lv_area_t draw_area; lv_area_t coordinates; bool is_common; int32_t x; int32_t y; d2_u8 current_alpha_mode = 0; d2_s32 result; d2_u32 flags = 0; lv_point_t arc_centre; is_common = lv_area_intersect(&draw_area, coords, u->base_unit.clip_area); if(!is_common) return; #if LV_USE_OS lv_result_t status; status = lv_mutex_lock(u->pd2Mutex); LV_ASSERT(LV_RESULT_OK == status); #endif lv_area_copy(&coordinates, coords); x = 0 - u->base_unit.target_layer->buf_area.x1; y = 0 - u->base_unit.target_layer->buf_area.y1; lv_area_move(&draw_area, x, y); lv_area_move(&coordinates, x, y); // // Generate render operations // #if D2_RENDER_EACH_OPERATION d2_selectrenderbuffer(u->d2_handle, u->renderbuffer); #endif d2_framebuffer_from_layer(u->d2_handle, u->base_unit.target_layer); if(LV_GRAD_DIR_NONE != dsc->grad.dir) { float a1; float a2; float y1; float y2; float y3; float y0; int16_t y0_i ; int16_t y3_i ; if(LV_GRAD_DIR_VER == dsc->grad.dir) { a1 = dsc->grad.stops[0].opa; a2 = dsc->grad.stops[dsc->grad.stops_count - 1].opa; y1 = (float)LV_MIN(coordinates.y1, coordinates.y2); y2 = (float)LV_MAX(coordinates.y1, coordinates.y2); if(a1 < a2) { /* TODO */ LV_ASSERT(0); y0 = 0.0f;//silence the compiler warning y3 = 0.0f; } else { y0 = y2 - ((y2 - y1) / (a2 - a1) * (a2)); //point where alpha is 0 y3 = y1 + ((y2 - y1) / (a2 - a1) * (255 - a1)); //point where alpha is 255 } y0_i = (int16_t)y0; y3_i = (int16_t)y3; d2_setalphagradient(u->d2_handle, 0, (d2_point)D2_FIX4(0), (d2_point)D2_FIX4(y0_i), (d2_point)D2_FIX4(0), (d2_point)D2_FIX4((y3_i - y0_i))); } else if(LV_GRAD_DIR_HOR == dsc->grad.dir) { /* TODO */ LV_ASSERT(0); float x1; float x2; float x3; float x0; int16_t x0_i ; int16_t x3_i ; a1 = dsc->grad.stops[0].opa; a2 = dsc->grad.stops[dsc->grad.stops_count - 1].opa; x1 = (float)LV_MIN(coordinates.x1, coordinates.x2); x2 = (float)LV_MAX(coordinates.x1, coordinates.x2); if(a1 < a2) { /* TODO */ LV_ASSERT(0); x0 = 0.0f;//silence the compiler warning x3 = 0.0f; } else { x0 = x2 - ((x2 - x1) / (a2 - a1) * (a2)); //point where alpha is 0 x3 = x1 + ((x2 - x1) / (a2 - a1) * (255 - a1)); //point where alpha is 255 } x0_i = (int16_t)x0; x3_i = (int16_t)x3; d2_setalphagradient(u->d2_handle, 0, (d2_point)D2_FIX4(x0_i), (d2_point)D2_FIX4(0), (d2_point)D2_FIX4(x3_i - x0_i), (d2_point)D2_FIX4((0))); } current_alpha_mode = d2_getalphamode(u->d2_handle); d2_setfillmode(u->d2_handle, d2_fm_color); d2_setcolor(u->d2_handle, 0, lv_draw_dave2d_lv_colour_to_d2_colour(dsc->grad.stops[0].color)); d2_setalphamode(u->d2_handle, d2_am_gradient1); } else { d2_setfillmode(u->d2_handle, d2_fm_color); //default d2_setcolor(u->d2_handle, 0, lv_draw_dave2d_lv_colour_to_d2_colour(dsc->color)); d2_setalpha(u->d2_handle, dsc->opa); } d2_cliprect(u->d2_handle, (d2_border)draw_area.x1, (d2_border)draw_area.y1, (d2_border)draw_area.x2, (d2_border)draw_area.y2); if(dsc->radius == 0) { d2_renderbox(u->d2_handle, (d2_point)D2_FIX4(coordinates.x1), (d2_point)D2_FIX4(coordinates.y1), (d2_point)D2_FIX4(lv_area_get_width(&coordinates)), (d2_point)D2_FIX4(lv_area_get_height(&coordinates))); } else { /*Get the real radius. Can't be larger than the half of the shortest side */ int32_t coords_bg_w = lv_area_get_width(&coordinates); int32_t coords_bg_h = lv_area_get_height(&coordinates); int32_t short_side = LV_MIN(coords_bg_w, coords_bg_h); int32_t radius = LV_MIN(dsc->radius, short_side >> 1); arc_centre.x = coordinates.x1 + radius; arc_centre.y = coordinates.y1 + radius; if(((2 * radius) == coords_bg_w) && ((2 * radius) == coords_bg_h)) { result = d2_rendercircle(u->d2_handle, (d2_point)D2_FIX4(arc_centre.x), (d2_point) D2_FIX4(arc_centre.y), (d2_width) D2_FIX4(radius), (d2_width) D2_FIX4(0)); LV_ASSERT(D2_OK == result); } else { lv_area_t arc_area; lv_area_t clip_arc; arc_centre.x = coordinates.x1 + radius; arc_centre.y = coordinates.y1 + radius; arc_area.x1 = coordinates.x1; arc_area.y1 = coordinates.y1; arc_area.x2 = coordinates.x1 + radius; arc_area.y2 = coordinates.y1 + radius; if(lv_area_intersect(&clip_arc, &arc_area, &draw_area)) { d2_cliprect(u->d2_handle, (d2_border)clip_arc.x1, (d2_border)clip_arc.y1, (d2_border)clip_arc.x2, (d2_border)clip_arc.y2); // d2_renderwedge internally changes the clip rectangle, only draw it if it is in side the current clip rectangle result = d2_renderwedge(u->d2_handle, (d2_point)D2_FIX4(arc_centre.x), (d2_point) D2_FIX4(arc_centre.y), (d2_width) D2_FIX4(radius), (d2_width) D2_FIX4(0), (d2_s32) D2_FIX16(0), // 180 Degrees (d2_s32) D2_FIX16((int16_t) -1), (d2_s32) D2_FIX16((int16_t) -1),//( 270 Degrees (d2_s32) D2_FIX16(0), flags); LV_ASSERT(D2_OK == result); } arc_centre.x = coordinates.x2 - radius; arc_centre.y = coordinates.y1 + radius; arc_area.x1 = coordinates.x2 - radius; arc_area.y1 = coordinates.y1; arc_area.x2 = coordinates.x2; arc_area.y2 = coordinates.y1 + radius; if(lv_area_intersect(&clip_arc, &arc_area, &draw_area)) { d2_cliprect(u->d2_handle, (d2_border)clip_arc.x1, (d2_border)clip_arc.y1, (d2_border)clip_arc.x2, (d2_border)clip_arc.y2); result = d2_renderwedge(u->d2_handle, (d2_point)D2_FIX4(arc_centre.x), (d2_point) D2_FIX4(arc_centre.y), (d2_width) D2_FIX4(radius), (d2_width) D2_FIX4(0), (d2_s32) D2_FIX16((int16_t)1), // 270 Degrees (d2_s32) D2_FIX16(0), (d2_s32) D2_FIX16(0),// 0 degrees (d2_s32) D2_FIX16(-1), flags); LV_ASSERT(D2_OK == result); } arc_centre.x = coordinates.x2 - radius; arc_centre.y = coordinates.y2 - radius; arc_area.x1 = coordinates.x2 - radius; arc_area.y1 = coordinates.y2 - radius; arc_area.x2 = coordinates.x2; arc_area.y2 = coordinates.y2; if(lv_area_intersect(&clip_arc, &arc_area, &draw_area)) { d2_cliprect(u->d2_handle, (d2_border)clip_arc.x1, (d2_border)clip_arc.y1, (d2_border)clip_arc.x2, (d2_border)clip_arc.y2); result = d2_renderwedge(u->d2_handle, (d2_point)D2_FIX4(arc_centre.x), (d2_point) D2_FIX4(arc_centre.y), (d2_width) D2_FIX4(radius), (d2_width) D2_FIX4(0), (d2_s32) D2_FIX16(0),// 0 degrees (d2_s32) D2_FIX16(1), (d2_s32) D2_FIX16(1),// 90 degrees (d2_s32) D2_FIX16(0), flags); LV_ASSERT(D2_OK == result); } arc_centre.x = coordinates.x1 + radius; arc_centre.y = coordinates.y2 - radius; arc_area.x1 = coordinates.x1; arc_area.y1 = coordinates.y2 - radius; arc_area.x2 = coordinates.x1 + radius; arc_area.y2 = coordinates.y2; if(lv_area_intersect(&clip_arc, &arc_area, &draw_area)) { d2_cliprect(u->d2_handle, (d2_border)clip_arc.x1, (d2_border)clip_arc.y1, (d2_border)clip_arc.x2, (d2_border)clip_arc.y2); result = d2_renderwedge(u->d2_handle, (d2_point)D2_FIX4(arc_centre.x), (d2_point) D2_FIX4(arc_centre.y), (d2_width) D2_FIX4(radius), (d2_width) D2_FIX4(0), (d2_s32) D2_FIX16((int16_t) -1), //90 degrees (d2_s32) D2_FIX16(0), (d2_s32) D2_FIX16(0), //180 degrees (d2_s32) D2_FIX16(1), flags); LV_ASSERT(D2_OK == result); } /* reset the clip rectangle */ d2_cliprect(u->d2_handle, (d2_border)draw_area.x1, (d2_border)draw_area.y1, (d2_border)draw_area.x2, (d2_border)draw_area.y2); result = d2_renderbox(u->d2_handle, (d2_width)D2_FIX4(coordinates.x1 + radius), (d2_width)D2_FIX4(coordinates.y1), (d2_width)D2_FIX4(lv_area_get_width(&coordinates) - (2 * radius)), (d2_width)D2_FIX4(lv_area_get_height(&coordinates))); LV_ASSERT(D2_OK == result); result = d2_renderbox(u->d2_handle, (d2_width)D2_FIX4(coordinates.x1), (d2_width)D2_FIX4(coordinates.y1 + radius), (d2_width)D2_FIX4(radius), (d2_width)D2_FIX4(lv_area_get_height(&coordinates) - (2 * radius))); LV_ASSERT(D2_OK == result); result = d2_renderbox(u->d2_handle, (d2_width)D2_FIX4(coordinates.x2 - radius), (d2_width)D2_FIX4(coordinates.y1 + radius), (d2_width)D2_FIX4(radius), (d2_width)D2_FIX4(lv_area_get_height(&coordinates) - (2 * radius))); LV_ASSERT(D2_OK == result); } } // // Execute render operations // #if D2_RENDER_EACH_OPERATION d2_executerenderbuffer(u->d2_handle, u->renderbuffer, 0); d2_flushframe(u->d2_handle); #endif if(LV_GRAD_DIR_NONE != dsc->grad.dir) { d2_setalphamode(u->d2_handle, current_alpha_mode); d2_setfillmode(u->d2_handle, d2_fm_color); //default } #if LV_USE_OS status = lv_mutex_unlock(u->pd2Mutex); LV_ASSERT(LV_RESULT_OK == status); #endif } #endif /*LV_USE_DRAW_DAVE2D*/