2018-05-20 21:27:57 +02:00
|
|
|
/**
|
|
|
|
* @file lv_draw_rect.c
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*********************
|
|
|
|
* INCLUDES
|
|
|
|
*********************/
|
2019-08-21 15:44:35 +02:00
|
|
|
#include <lvgl/src/lv_draw/lv_blend.h>
|
2018-05-20 21:27:57 +02:00
|
|
|
#include "lv_draw_rect.h"
|
|
|
|
#include "../lv_misc/lv_circ.h"
|
|
|
|
#include "../lv_misc/lv_math.h"
|
2019-03-30 06:03:23 +01:00
|
|
|
#include "../lv_core/lv_refr.h"
|
2019-08-13 06:14:38 +02:00
|
|
|
#include "lv_mask.h"
|
2018-05-20 21:27:57 +02:00
|
|
|
|
|
|
|
/*********************
|
|
|
|
* DEFINES
|
|
|
|
*********************/
|
|
|
|
|
|
|
|
/**********************
|
|
|
|
* TYPEDEFS
|
|
|
|
**********************/
|
|
|
|
|
|
|
|
/**********************
|
|
|
|
* STATIC PROTOTYPES
|
|
|
|
**********************/
|
2019-08-13 06:14:38 +02:00
|
|
|
static void draw_bg(const lv_area_t * coords, const lv_area_t * clip, const lv_style_t * style, lv_opa_t opa_scale);
|
2019-08-29 10:07:22 +02:00
|
|
|
static void draw_shadow(const lv_area_t * coords, const lv_area_t * clip, const lv_style_t * style, lv_opa_t opa_scale);
|
2019-09-04 07:35:33 +02:00
|
|
|
static void shadow_draw_corner_buf(const lv_area_t * coords, lv_opa_t * sh_buf, lv_coord_t s, lv_coord_t r);
|
2018-07-30 06:52:29 +02:00
|
|
|
|
2018-05-20 21:27:57 +02:00
|
|
|
/**********************
|
|
|
|
* STATIC VARIABLES
|
|
|
|
**********************/
|
|
|
|
|
|
|
|
/**********************
|
|
|
|
* MACROS
|
|
|
|
**********************/
|
|
|
|
|
|
|
|
/**********************
|
|
|
|
* GLOBAL FUNCTIONS
|
|
|
|
**********************/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Draw a rectangle
|
|
|
|
* @param coords the coordinates of the rectangle
|
|
|
|
* @param mask the rectangle will be drawn only in this mask
|
|
|
|
* @param style pointer to a style
|
2018-06-14 13:08:19 +02:00
|
|
|
* @param opa_scale scale down all opacities by the factor
|
2018-05-20 21:27:57 +02:00
|
|
|
*/
|
2019-08-13 06:14:38 +02:00
|
|
|
void lv_draw_rect(const lv_area_t * coords, const lv_area_t * clip, const lv_style_t * style, lv_opa_t opa_scale)
|
2018-05-20 21:27:57 +02:00
|
|
|
{
|
|
|
|
if(lv_area_get_height(coords) < 1 || lv_area_get_width(coords) < 1) return;
|
|
|
|
|
2019-08-29 10:07:22 +02:00
|
|
|
draw_shadow(coords, clip, style, opa_scale);
|
|
|
|
|
2019-09-04 07:35:33 +02:00
|
|
|
draw_bg(coords, clip, style, opa_scale);
|
2018-05-20 21:27:57 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/**********************
|
|
|
|
* STATIC FUNCTIONS
|
|
|
|
**********************/
|
|
|
|
|
2019-08-13 06:14:38 +02:00
|
|
|
static void draw_bg(const lv_area_t * coords, const lv_area_t * clip, const lv_style_t * style, lv_opa_t opa_scale)
|
2018-05-20 21:27:57 +02:00
|
|
|
{
|
2019-08-13 06:14:38 +02:00
|
|
|
lv_opa_t opa = style->body.opa;
|
2018-05-20 21:27:57 +02:00
|
|
|
|
2019-08-13 06:14:38 +02:00
|
|
|
if(opa > LV_OPA_MAX) opa = LV_OPA_COVER;
|
2018-05-20 21:27:57 +02:00
|
|
|
|
2019-08-23 10:53:38 +02:00
|
|
|
lv_disp_t * disp = lv_refr_get_disp_refreshing();
|
|
|
|
lv_disp_buf_t * vdb = lv_disp_get_buf(disp);
|
2018-05-20 21:27:57 +02:00
|
|
|
|
2019-08-23 10:53:38 +02:00
|
|
|
/* Get clipped fill area which is the real draw area.
|
|
|
|
* It is always the same or inside `fill_area` */
|
|
|
|
lv_area_t draw_area;
|
|
|
|
bool is_common;
|
|
|
|
is_common = lv_area_intersect(&draw_area, coords, clip);
|
|
|
|
if(is_common == false) return;
|
2019-04-04 07:15:40 +02:00
|
|
|
|
2019-08-23 10:53:38 +02:00
|
|
|
const lv_area_t * disp_area = &vdb->area;
|
|
|
|
lv_color_t * disp_buf = vdb->buf_act;
|
|
|
|
|
|
|
|
/* Now `draw_area` has absolute coordinates.
|
|
|
|
* Make it relative to `disp_area` to simplify draw to `disp_buf`*/
|
|
|
|
draw_area.x1 -= disp_area->x1;
|
|
|
|
draw_area.y1 -= disp_area->y1;
|
|
|
|
draw_area.x2 -= disp_area->x1;
|
|
|
|
draw_area.y2 -= disp_area->y1;
|
2019-04-04 07:15:40 +02:00
|
|
|
|
2019-08-23 10:53:38 +02:00
|
|
|
lv_coord_t draw_area_w = lv_area_get_width(&draw_area);
|
2019-04-04 07:15:40 +02:00
|
|
|
|
2019-08-23 10:53:38 +02:00
|
|
|
/*Create a mask if there is a radius*/
|
2019-08-13 06:14:38 +02:00
|
|
|
lv_opa_t mask_buf[LV_HOR_RES_MAX];
|
2019-08-21 15:44:35 +02:00
|
|
|
|
2019-08-23 10:53:38 +02:00
|
|
|
uint8_t other_mask_cnt = lv_mask_get_cnt();
|
2019-08-22 15:23:53 +02:00
|
|
|
int16_t mask_rout_id = LV_MASK_ID_INV;
|
|
|
|
|
2019-08-23 10:53:38 +02:00
|
|
|
/*Get the real radius*/
|
|
|
|
lv_coord_t rout = style->body.radius;
|
2019-08-26 05:06:49 +02:00
|
|
|
lv_coord_t short_side = LV_MATH_MIN(lv_area_get_width(coords), lv_area_get_height(coords));
|
|
|
|
if(rout > short_side >> 1) rout = short_side >> 1;
|
2019-08-22 15:23:53 +02:00
|
|
|
|
2019-08-23 10:53:38 +02:00
|
|
|
/*Most simple case: just a plain rectangle*/
|
|
|
|
if(other_mask_cnt == 0 && rout == 0 && style->body.main_color.full == style->body.grad_color.full) {
|
2019-08-29 10:07:22 +02:00
|
|
|
lv_blend_fill(clip, coords,
|
|
|
|
style->body.main_color, NULL, LV_MASK_RES_FULL_COVER, style->body.opa,
|
|
|
|
LV_BLIT_MODE_NORMAL);
|
2019-08-22 15:23:53 +02:00
|
|
|
}
|
2019-08-23 10:53:38 +02:00
|
|
|
/*More complex case: there is a radius, gradient or mask.*/
|
|
|
|
else {
|
2019-08-21 15:44:35 +02:00
|
|
|
|
2019-08-23 10:53:38 +02:00
|
|
|
lv_mask_param_t mask_rout_param;
|
|
|
|
if(rout > 0) {
|
|
|
|
lv_mask_radius_init(&mask_rout_param, coords, rout, false);
|
|
|
|
mask_rout_id = lv_mask_add(lv_mask_radius, &mask_rout_param, NULL);
|
|
|
|
}
|
2019-08-16 07:54:32 +02:00
|
|
|
|
2019-08-23 10:53:38 +02:00
|
|
|
/*Draw the background line by line*/
|
|
|
|
lv_coord_t h;
|
|
|
|
lv_mask_res_t mask_res = LV_MASK_RES_FULL_COVER;
|
|
|
|
lv_color_t grad_color = style->body.main_color;
|
|
|
|
|
|
|
|
/*Fill the first row with 'color'*/
|
|
|
|
if(opa >= LV_OPA_MIN) {
|
2019-08-24 15:59:19 +02:00
|
|
|
|
|
|
|
lv_area_t fill_area;
|
|
|
|
fill_area.x1 = coords->x1;
|
|
|
|
fill_area.x2 = coords->x2;
|
|
|
|
fill_area.y1 = disp_area->y1 + draw_area.y1;
|
|
|
|
fill_area.y2 = fill_area.y1;
|
2019-08-23 10:53:38 +02:00
|
|
|
for(h = draw_area.y1; h <= draw_area.y2; h++) {
|
|
|
|
lv_coord_t y = h + vdb->area.y1;
|
|
|
|
|
|
|
|
/*In not corner areas apply the mask only if required*/
|
|
|
|
if(y > coords->y1 + rout + 1 &&
|
2019-08-29 10:07:22 +02:00
|
|
|
y < coords->y2 - rout - 1) {
|
2019-08-23 10:53:38 +02:00
|
|
|
mask_res = LV_MASK_RES_FULL_COVER;
|
|
|
|
if(other_mask_cnt != 0) {
|
|
|
|
memset(mask_buf, LV_OPA_COVER, draw_area_w);
|
|
|
|
mask_res = lv_mask_apply(mask_buf, vdb->area.x1 + draw_area.x1, vdb->area.y1 + h, draw_area_w);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/*In corner areas apply the mask anyway*/
|
|
|
|
else {
|
|
|
|
memset(mask_buf, LV_OPA_COVER, draw_area_w);
|
|
|
|
mask_res = lv_mask_apply(mask_buf, vdb->area.x1 + draw_area.x1, vdb->area.y1 + h, draw_area_w);
|
2019-08-22 15:23:53 +02:00
|
|
|
}
|
2019-08-21 15:44:35 +02:00
|
|
|
|
2019-08-23 10:53:38 +02:00
|
|
|
/*Get the current line color*/
|
|
|
|
if(style->body.main_color.full != style->body.grad_color.full) {
|
|
|
|
lv_opa_t mix = (uint32_t)((uint32_t) (y - coords->y1) * 255) / lv_area_get_height(coords);
|
|
|
|
grad_color = lv_color_mix(style->body.grad_color, style->body.main_color, mix);
|
|
|
|
}
|
2019-08-21 15:44:35 +02:00
|
|
|
|
2019-09-04 07:35:33 +02:00
|
|
|
/* If there is not other mask and drawing the corner area split the drawing to corner and middle areas
|
2019-08-27 15:16:05 +02:00
|
|
|
* because it the middle mask shuldn't be taken into account (therefore its faster)*/
|
|
|
|
if(other_mask_cnt == 0 &&
|
2019-08-29 10:07:22 +02:00
|
|
|
(y < coords->y1 + rout + 1 ||
|
|
|
|
y > coords->y2 - rout - 1)) {
|
2019-08-27 15:16:05 +02:00
|
|
|
|
|
|
|
lv_area_t fill_area2;
|
|
|
|
fill_area2.x1 = coords->x1;
|
|
|
|
fill_area2.x2 = coords->x1 + rout;
|
|
|
|
fill_area2.y1 = fill_area.y1;
|
|
|
|
fill_area2.y2 = fill_area.y2;
|
|
|
|
|
2019-08-29 10:07:22 +02:00
|
|
|
lv_blend_fill(clip, &fill_area2,
|
|
|
|
grad_color, mask_buf, mask_res, style->body.opa, LV_BLIT_MODE_NORMAL);
|
2019-08-27 15:16:05 +02:00
|
|
|
|
|
|
|
|
|
|
|
fill_area2.x1 = coords->x1 + rout + 1;
|
|
|
|
fill_area2.x2 = coords->x2 - rout - 1;
|
|
|
|
|
2019-08-29 10:07:22 +02:00
|
|
|
lv_blend_fill(clip, &fill_area2,
|
|
|
|
grad_color, NULL, LV_MASK_RES_FULL_COVER, style->body.opa, LV_BLIT_MODE_NORMAL);
|
2019-08-27 15:16:05 +02:00
|
|
|
|
|
|
|
fill_area2.x1 = coords->x2 - rout;
|
|
|
|
fill_area2.x2 = coords->x2;
|
|
|
|
|
|
|
|
lv_coord_t mask_ofs = (coords->x2 - rout) - (vdb->area.x1 + draw_area.x1);
|
|
|
|
if(mask_ofs < 0) mask_ofs = 0;
|
2019-08-29 10:07:22 +02:00
|
|
|
lv_blend_fill(clip, &fill_area2,
|
|
|
|
grad_color, mask_buf + mask_ofs, mask_res, style->body.opa, LV_BLIT_MODE_NORMAL);
|
2019-08-27 15:16:05 +02:00
|
|
|
} else {
|
2019-08-29 10:07:22 +02:00
|
|
|
lv_blend_fill(clip, &fill_area,
|
|
|
|
grad_color,mask_buf, mask_res, style->body.opa, LV_BLIT_MODE_NORMAL);
|
2019-08-27 15:16:05 +02:00
|
|
|
}
|
2019-08-24 15:59:19 +02:00
|
|
|
fill_area.y1++;
|
|
|
|
fill_area.y2++;
|
2019-08-23 10:53:38 +02:00
|
|
|
}
|
2019-08-21 15:44:35 +02:00
|
|
|
}
|
|
|
|
}
|
2019-03-30 06:03:23 +01:00
|
|
|
|
2019-08-21 15:44:35 +02:00
|
|
|
/*Draw the border if any*/
|
|
|
|
lv_coord_t border_width = style->body.border.width;
|
|
|
|
if(border_width) {
|
|
|
|
/*Move the vdb_buf_tmp to the first row*/
|
|
|
|
lv_mask_param_t mask_rsmall_param;
|
2019-08-24 15:59:19 +02:00
|
|
|
|
|
|
|
/*Get the inner radius*/
|
2019-08-21 15:44:35 +02:00
|
|
|
lv_coord_t rin = rout - border_width;
|
|
|
|
if(rin < 0) rin = 0;
|
2019-08-24 15:59:19 +02:00
|
|
|
|
|
|
|
/*Get the inner area*/
|
2019-08-21 15:44:35 +02:00
|
|
|
lv_area_t area_small;
|
|
|
|
lv_area_copy(&area_small, coords);
|
|
|
|
area_small.x1 += border_width;
|
|
|
|
area_small.x2 -= border_width;
|
|
|
|
area_small.y1 += border_width;
|
|
|
|
area_small.y2 -= border_width;
|
2019-08-24 15:59:19 +02:00
|
|
|
|
|
|
|
/*Create the mask*/
|
2019-08-26 05:06:49 +02:00
|
|
|
lv_mask_radius_init(&mask_rsmall_param, &area_small, rout - border_width, true);
|
2019-08-21 15:44:35 +02:00
|
|
|
int16_t mask_rsmall_id = lv_mask_add(lv_mask_radius, &mask_rsmall_param, NULL);
|
|
|
|
|
2019-08-28 16:33:05 +02:00
|
|
|
lv_coord_t corner_size = LV_MATH_MAX(rout, border_width - 1);
|
2019-08-22 15:23:53 +02:00
|
|
|
|
2019-08-23 10:53:38 +02:00
|
|
|
lv_coord_t h;
|
|
|
|
lv_mask_res_t mask_res;
|
2019-08-24 15:59:19 +02:00
|
|
|
lv_area_t fill_area;
|
|
|
|
|
|
|
|
/*Apply some optimization if there is no other mask*/
|
|
|
|
if(other_mask_cnt == 0) {
|
|
|
|
/*Draw the upper corner area*/
|
|
|
|
lv_coord_t upper_corner_end = coords->y1 - disp_area->y1 + corner_size;
|
|
|
|
fill_area.x1 = coords->x1;
|
|
|
|
fill_area.x2 = coords->x2;
|
|
|
|
fill_area.y1 = disp_area->y1 + draw_area.y1;
|
|
|
|
fill_area.y2 = fill_area.y1;
|
|
|
|
for(h = draw_area.y1; h <= upper_corner_end; h++) {
|
|
|
|
memset(mask_buf, LV_OPA_COVER, draw_area_w);
|
|
|
|
mask_res = lv_mask_apply(mask_buf, vdb->area.x1 + draw_area.x1, vdb->area.y1 + h, draw_area_w);
|
|
|
|
|
2019-08-28 16:33:05 +02:00
|
|
|
lv_area_t fill_area2;
|
|
|
|
fill_area2.x1 = coords->x1;
|
|
|
|
fill_area2.x2 = coords->x1 + rout;
|
|
|
|
fill_area2.y1 = fill_area.y1;
|
|
|
|
fill_area2.y2 = fill_area.y2;
|
|
|
|
|
2019-08-29 10:07:22 +02:00
|
|
|
lv_blend_fill(clip, &fill_area2,
|
|
|
|
style->body.border.color, mask_buf, mask_res, style->body.border.opa, LV_BLIT_MODE_NORMAL);
|
2019-08-24 15:59:19 +02:00
|
|
|
|
2019-08-28 16:33:05 +02:00
|
|
|
|
|
|
|
if(fill_area2.y2 < coords->y1 + style->body.border.width) {
|
|
|
|
fill_area2.x1 = coords->x1 + rout + 1;
|
|
|
|
fill_area2.x2 = coords->x2 - rout - 1;
|
|
|
|
|
2019-08-29 10:07:22 +02:00
|
|
|
lv_blend_fill(clip, &fill_area2,
|
|
|
|
style->body.border.color, NULL, LV_MASK_RES_FULL_COVER, style->body.border.opa, LV_BLIT_MODE_NORMAL);
|
2019-08-28 16:33:05 +02:00
|
|
|
}
|
|
|
|
fill_area2.x1 = coords->x2 - rout;
|
|
|
|
fill_area2.x2 = coords->x2;
|
|
|
|
|
|
|
|
lv_coord_t mask_ofs = (coords->x2 - rout) - (vdb->area.x1 + draw_area.x1);
|
|
|
|
if(mask_ofs < 0) mask_ofs = 0;
|
2019-08-29 10:07:22 +02:00
|
|
|
lv_blend_fill(clip, &fill_area2,
|
|
|
|
style->body.border.color, mask_buf + mask_ofs, mask_res, style->body.border.opa, LV_BLIT_MODE_NORMAL);
|
2019-08-28 16:33:05 +02:00
|
|
|
|
2019-08-24 15:59:19 +02:00
|
|
|
fill_area.y1++;
|
|
|
|
fill_area.y2++;
|
2019-08-22 15:23:53 +02:00
|
|
|
}
|
2019-08-24 15:59:19 +02:00
|
|
|
|
2019-08-26 07:18:08 +02:00
|
|
|
/*Draw the lower corner area corner area*/
|
2019-08-24 15:59:19 +02:00
|
|
|
lv_coord_t lower_corner_end = coords->y2 - disp_area->y1 - corner_size;
|
2019-08-27 15:16:05 +02:00
|
|
|
if(lower_corner_end <= upper_corner_end) lower_corner_end = upper_corner_end + 1;
|
2019-08-24 15:59:19 +02:00
|
|
|
fill_area.y1 = disp_area->y1 + lower_corner_end;
|
|
|
|
fill_area.y2 = fill_area.y1;
|
|
|
|
for(h = lower_corner_end; h <= draw_area.y2; h++) {
|
2019-08-29 10:07:22 +02:00
|
|
|
memset(mask_buf, LV_OPA_COVER, draw_area_w);
|
|
|
|
mask_res = lv_mask_apply(mask_buf, vdb->area.x1 + draw_area.x1, vdb->area.y1 + h, draw_area_w);
|
2019-08-24 15:59:19 +02:00
|
|
|
|
2019-08-29 10:07:22 +02:00
|
|
|
lv_area_t fill_area2;
|
2019-08-28 16:33:05 +02:00
|
|
|
fill_area2.x1 = coords->x1;
|
|
|
|
fill_area2.x2 = coords->x1 + rout;
|
|
|
|
fill_area2.y1 = fill_area.y1;
|
|
|
|
fill_area2.y2 = fill_area.y2;
|
|
|
|
|
2019-08-29 10:07:22 +02:00
|
|
|
lv_blend_fill(clip, &fill_area2,
|
|
|
|
style->body.border.color, mask_buf, mask_res, style->body.border.opa, LV_BLIT_MODE_NORMAL);
|
2019-08-28 16:33:05 +02:00
|
|
|
|
|
|
|
|
|
|
|
if(fill_area2.y2 > coords->y2 - style->body.border.width) {
|
|
|
|
fill_area2.x1 = coords->x1 + rout + 1;
|
|
|
|
fill_area2.x2 = coords->x2 - rout - 1;
|
|
|
|
|
2019-08-29 10:07:22 +02:00
|
|
|
lv_blend_fill(clip, &fill_area2,
|
|
|
|
style->body.border.color, NULL, LV_MASK_RES_FULL_COVER, style->body.border.opa, LV_BLIT_MODE_NORMAL);
|
2019-08-28 16:33:05 +02:00
|
|
|
}
|
|
|
|
fill_area2.x1 = coords->x2 - rout;
|
|
|
|
fill_area2.x2 = coords->x2;
|
|
|
|
|
|
|
|
lv_coord_t mask_ofs = (coords->x2 - rout) - (vdb->area.x1 + draw_area.x1);
|
|
|
|
if(mask_ofs < 0) mask_ofs = 0;
|
2019-08-29 10:07:22 +02:00
|
|
|
lv_blend_fill(clip, &fill_area2,
|
|
|
|
style->body.border.color, mask_buf + mask_ofs, mask_res, style->body.border.opa, LV_BLIT_MODE_NORMAL);
|
2019-08-28 16:33:05 +02:00
|
|
|
|
2019-08-24 15:59:19 +02:00
|
|
|
|
2019-08-29 10:07:22 +02:00
|
|
|
fill_area.y1++;
|
|
|
|
fill_area.y2++;
|
|
|
|
}
|
2019-08-24 15:59:19 +02:00
|
|
|
|
2019-08-29 10:07:22 +02:00
|
|
|
/*Draw the left vertical border part*/
|
2019-08-24 15:59:19 +02:00
|
|
|
fill_area.x1 = coords->x1;
|
|
|
|
fill_area.x2 = coords->x1 + border_width - 1;
|
|
|
|
fill_area.y1 = coords->y1 + corner_size + 1;
|
|
|
|
fill_area.y2 = coords->y2 - corner_size - 1;
|
|
|
|
|
2019-08-29 10:07:22 +02:00
|
|
|
lv_blend_fill(clip, &fill_area,
|
|
|
|
style->body.border.color, NULL, LV_MASK_RES_FULL_COVER, style->body.border.opa, LV_BLIT_MODE_NORMAL);
|
2019-08-24 15:59:19 +02:00
|
|
|
|
2019-08-28 16:33:05 +02:00
|
|
|
/*Draw the right vertical border*/
|
2019-08-24 15:59:19 +02:00
|
|
|
fill_area.x1 = coords->x2 - border_width + 1;
|
|
|
|
fill_area.x2 = coords->x2;
|
|
|
|
|
2019-08-29 10:07:22 +02:00
|
|
|
lv_blend_fill(clip, &fill_area,
|
|
|
|
style->body.border.color, NULL, LV_MASK_RES_FULL_COVER, style->body.border.opa, LV_BLIT_MODE_NORMAL);
|
2019-08-24 15:59:19 +02:00
|
|
|
}
|
|
|
|
/*Process line by line if there is other mask too*/
|
|
|
|
else {
|
|
|
|
fill_area.x1 = coords->x1;
|
|
|
|
fill_area.x2 = coords->x2;
|
|
|
|
fill_area.y1 = disp_area->y1 + draw_area.y1;
|
|
|
|
fill_area.y2 = fill_area.y1;
|
|
|
|
for(h = draw_area.y1; h <= draw_area.y2; h++) {
|
2019-08-23 10:53:38 +02:00
|
|
|
memset(mask_buf, LV_OPA_COVER, draw_area_w);
|
|
|
|
mask_res = lv_mask_apply(mask_buf, vdb->area.x1 + draw_area.x1, vdb->area.y1 + h, draw_area_w);
|
2018-05-20 21:27:57 +02:00
|
|
|
|
2019-08-29 10:07:22 +02:00
|
|
|
lv_blend_fill( clip, &fill_area,
|
|
|
|
style->body.border.color, mask_buf, mask_res, style->body.border.opa, LV_BLIT_MODE_NORMAL);
|
2019-08-24 15:59:19 +02:00
|
|
|
|
|
|
|
fill_area.y1++;
|
|
|
|
fill_area.y2++;
|
|
|
|
|
2019-08-22 15:23:53 +02:00
|
|
|
}
|
2018-05-20 21:27:57 +02:00
|
|
|
}
|
2019-08-21 15:44:35 +02:00
|
|
|
lv_mask_remove_id(mask_rsmall_id);
|
2018-05-20 21:27:57 +02:00
|
|
|
}
|
2019-08-21 15:44:35 +02:00
|
|
|
|
|
|
|
lv_mask_remove_id(mask_rout_id);
|
2018-05-20 21:27:57 +02:00
|
|
|
}
|
2019-08-29 10:07:22 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void draw_shadow(const lv_area_t * coords, const lv_area_t * clip, const lv_style_t * style, lv_opa_t opa_scale)
|
|
|
|
{
|
|
|
|
if(style->body.shadow.width == 0) return;
|
2019-09-04 07:35:33 +02:00
|
|
|
|
|
|
|
lv_coord_t sw = style->body.shadow.width;
|
|
|
|
|
|
|
|
lv_coord_t x_ofs = 0;
|
|
|
|
lv_coord_t y_ofs = 0;
|
|
|
|
|
|
|
|
lv_area_t sh_area;
|
|
|
|
sh_area.x1 = coords->x1 - sw / 2 - 1 + x_ofs;
|
|
|
|
sh_area.x2 = coords->x2 + sw / 2 + 1 + x_ofs;
|
|
|
|
sh_area.y1 = coords->y1 - sw / 2 - 1 + y_ofs;
|
|
|
|
sh_area.y2 = coords->y2 + sw / 2 + 1 + y_ofs;
|
|
|
|
|
2019-08-29 10:07:22 +02:00
|
|
|
|
|
|
|
lv_opa_t opa = style->body.opa;
|
|
|
|
|
|
|
|
if(opa > LV_OPA_MAX) opa = LV_OPA_COVER;
|
|
|
|
lv_disp_t * disp = lv_refr_get_disp_refreshing();
|
|
|
|
lv_disp_buf_t * vdb = lv_disp_get_buf(disp);
|
|
|
|
|
|
|
|
/* Get clipped fill area which is the real draw area.
|
|
|
|
* It is always the same or inside `fill_area` */
|
|
|
|
lv_area_t draw_area;
|
|
|
|
bool is_common;
|
2019-09-04 07:35:33 +02:00
|
|
|
is_common = lv_area_intersect(&draw_area, &sh_area, clip);
|
2019-08-29 10:07:22 +02:00
|
|
|
if(is_common == false) return;
|
|
|
|
|
|
|
|
const lv_area_t * disp_area = &vdb->area;
|
|
|
|
lv_color_t * disp_buf = vdb->buf_act;
|
|
|
|
|
|
|
|
/* Now `draw_area` has absolute coordinates.
|
|
|
|
* Make it relative to `disp_area` to simplify draw to `disp_buf`*/
|
|
|
|
draw_area.x1 -= disp_area->x1;
|
|
|
|
draw_area.y1 -= disp_area->y1;
|
|
|
|
draw_area.x2 -= disp_area->x1;
|
|
|
|
draw_area.y2 -= disp_area->y1;
|
|
|
|
|
|
|
|
lv_coord_t draw_area_w = lv_area_get_width(&draw_area);
|
|
|
|
|
|
|
|
/*Get the real radius*/
|
2019-09-04 07:35:33 +02:00
|
|
|
lv_mask_res_t mask_res;
|
2019-08-29 10:07:22 +02:00
|
|
|
lv_coord_t rout = style->body.radius;
|
|
|
|
lv_coord_t short_side = LV_MATH_MIN(lv_area_get_width(coords), lv_area_get_height(coords));
|
|
|
|
if(rout > short_side >> 1) rout = short_side >> 1;
|
|
|
|
|
|
|
|
|
2019-09-04 07:35:33 +02:00
|
|
|
lv_coord_t corner_size = sw + rout;
|
2019-08-29 10:07:22 +02:00
|
|
|
|
|
|
|
|
|
|
|
lv_opa_t sh_buf[corner_size * corner_size];
|
|
|
|
|
2019-09-04 07:35:33 +02:00
|
|
|
shadow_draw_corner_buf(coords, sh_buf, style->body.shadow.width, rout);
|
|
|
|
|
|
|
|
|
|
|
|
uint8_t other_mask_cnt = lv_mask_get_cnt();
|
|
|
|
lv_coord_t y_max;
|
|
|
|
|
|
|
|
/*Create a mask if there is a radius*/
|
|
|
|
lv_opa_t mask_buf[LV_HOR_RES_MAX];
|
|
|
|
|
|
|
|
lv_mask_param_t mask_rout_param;
|
|
|
|
lv_mask_radius_init(&mask_rout_param, coords, rout, true);
|
|
|
|
|
|
|
|
/*Draw a radius into the shadow buffer*/
|
|
|
|
int16_t mask_rout_id = LV_MASK_ID_INV;
|
2019-08-29 10:07:22 +02:00
|
|
|
|
2019-09-04 07:35:33 +02:00
|
|
|
mask_rout_id = lv_mask_add(lv_mask_radius, &mask_rout_param, NULL);
|
2019-08-29 10:07:22 +02:00
|
|
|
|
|
|
|
lv_area_t a;
|
2019-09-04 07:35:33 +02:00
|
|
|
|
|
|
|
/*Draw the top right corner*/
|
|
|
|
a.x2 = sh_area.x2;
|
|
|
|
a.x1 = a.x2 - corner_size + 1;
|
|
|
|
a.y1 = sh_area.y1;
|
2019-08-29 10:07:22 +02:00
|
|
|
a.y2 = a.y1;
|
|
|
|
|
2019-09-04 07:35:33 +02:00
|
|
|
lv_coord_t first_px;
|
|
|
|
first_px = 0;
|
|
|
|
if(disp_area->x1 > a.x1) {
|
|
|
|
first_px = disp_area->x1 - a.x1;
|
|
|
|
a.x1 += first_px;
|
|
|
|
}
|
|
|
|
|
2019-08-29 10:07:22 +02:00
|
|
|
lv_opa_t * sh_buf_tmp = sh_buf;
|
|
|
|
|
|
|
|
lv_coord_t y;
|
|
|
|
for(y = 0; y < corner_size; y++) {
|
2019-09-04 07:35:33 +02:00
|
|
|
memcpy(mask_buf, sh_buf_tmp, corner_size);
|
|
|
|
mask_res = lv_mask_apply(mask_buf + first_px, a.x1, a.y1, lv_area_get_width(&a));
|
|
|
|
if(mask_res == LV_MASK_RES_FULL_COVER) mask_res = LV_MASK_RES_CHANGED;
|
|
|
|
|
2019-08-29 10:07:22 +02:00
|
|
|
lv_blend_fill(clip, &a,
|
2019-09-04 07:35:33 +02:00
|
|
|
style->body.shadow.color, mask_buf + first_px, mask_res, LV_OPA_COVER, LV_BLIT_MODE_NORMAL);
|
2019-08-29 10:07:22 +02:00
|
|
|
a.y1++;
|
|
|
|
a.y2++;
|
|
|
|
sh_buf_tmp += corner_size;
|
|
|
|
}
|
|
|
|
|
2019-09-04 07:35:33 +02:00
|
|
|
/*Draw the bottom right corner*/
|
|
|
|
a.y1 = sh_area.y2;
|
|
|
|
a.y2 = a.y1;
|
|
|
|
|
|
|
|
sh_buf_tmp = sh_buf ;
|
|
|
|
|
|
|
|
for(y = 0; y < corner_size; y++) {
|
|
|
|
memcpy(mask_buf, sh_buf_tmp, corner_size);
|
|
|
|
mask_res = lv_mask_apply(mask_buf + first_px, a.x1, a.y1, lv_area_get_width(&a));
|
|
|
|
if(mask_res == LV_MASK_RES_FULL_COVER) mask_res = LV_MASK_RES_CHANGED;
|
|
|
|
|
|
|
|
lv_blend_fill(clip, &a,
|
|
|
|
style->body.shadow.color, mask_buf + first_px, mask_res, LV_OPA_COVER, LV_BLIT_MODE_NORMAL);
|
|
|
|
a.y1--;
|
|
|
|
a.y2--;
|
|
|
|
sh_buf_tmp += corner_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*Fill the right side*/
|
|
|
|
a.y1 = sh_area.y1 + corner_size;
|
|
|
|
a.y2 = a.y1;
|
|
|
|
|
|
|
|
|
|
|
|
sh_buf_tmp = sh_buf + corner_size * (corner_size - 1);
|
|
|
|
|
|
|
|
for(y = corner_size; y < lv_area_get_height(&sh_area) - corner_size; y++) {
|
|
|
|
memcpy(mask_buf, sh_buf_tmp, corner_size);
|
|
|
|
mask_res = lv_mask_apply(mask_buf + first_px, a.x1, a.y1, lv_area_get_width(&a));
|
|
|
|
if(mask_res == LV_MASK_RES_FULL_COVER) mask_res = LV_MASK_RES_CHANGED;
|
|
|
|
|
|
|
|
lv_blend_fill(clip, &a,
|
|
|
|
style->body.shadow.color, mask_buf+first_px, mask_res, LV_OPA_COVER, LV_BLIT_MODE_NORMAL);
|
|
|
|
a.y1++;
|
|
|
|
a.y2++;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*Invert the shadow corner buffer and draw the corners on the left*/
|
|
|
|
lv_coord_t x;
|
|
|
|
sh_buf_tmp = sh_buf ;
|
|
|
|
for(y = 0; y < corner_size; y++) {
|
|
|
|
for(x = 0; x < corner_size / 2; x++) {
|
|
|
|
lv_opa_t tmp = sh_buf_tmp[x];
|
|
|
|
sh_buf_tmp[x] = sh_buf_tmp[corner_size - x - 1];
|
|
|
|
sh_buf_tmp[corner_size - x - 1] = tmp;
|
|
|
|
}
|
|
|
|
sh_buf_tmp += corner_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*Draw the top left corner*/
|
|
|
|
a.x1 = sh_area.x1;
|
|
|
|
a.x2 = a.x1 + corner_size - 1;
|
|
|
|
a.y1 = sh_area.y1;
|
|
|
|
a.y2 = a.y1;
|
|
|
|
|
|
|
|
first_px = 0;
|
|
|
|
if(disp_area->x1 > a.x1) {
|
|
|
|
first_px = disp_area->x1 - a.x1;
|
|
|
|
a.x1 += first_px;
|
|
|
|
}
|
|
|
|
|
|
|
|
sh_buf_tmp = sh_buf ;
|
|
|
|
|
|
|
|
for(y = 0; y < corner_size; y++) {
|
|
|
|
memcpy(mask_buf, sh_buf_tmp, corner_size);
|
|
|
|
mask_res = lv_mask_apply(mask_buf + first_px, a.x1, a.y1, lv_area_get_width(&a));
|
|
|
|
if(mask_res == LV_MASK_RES_FULL_COVER) mask_res = LV_MASK_RES_CHANGED;
|
|
|
|
|
|
|
|
lv_blend_fill(clip, &a,
|
|
|
|
style->body.shadow.color, mask_buf + first_px, mask_res, LV_OPA_COVER, LV_BLIT_MODE_NORMAL);
|
|
|
|
a.y1++;
|
|
|
|
a.y2++;
|
|
|
|
sh_buf_tmp += corner_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*Draw the bottom left corner*/
|
|
|
|
a.x1 = sh_area.x1;
|
|
|
|
a.x2 = a.x1 + corner_size - 1;
|
|
|
|
a.y1 = sh_area.y2;
|
|
|
|
a.y2 = a.y1;
|
|
|
|
|
|
|
|
sh_buf_tmp = sh_buf ;
|
|
|
|
|
|
|
|
for(y = 0; y < corner_size; y++) {
|
|
|
|
memcpy(mask_buf, sh_buf_tmp, corner_size);
|
|
|
|
mask_res = lv_mask_apply(mask_buf + first_px, a.x1, a.y1, lv_area_get_width(&a));
|
|
|
|
if(mask_res == LV_MASK_RES_FULL_COVER) mask_res = LV_MASK_RES_CHANGED;
|
|
|
|
|
|
|
|
lv_blend_fill(clip, &a,
|
|
|
|
style->body.shadow.color, mask_buf + first_px, mask_res, LV_OPA_COVER, LV_BLIT_MODE_NORMAL);
|
|
|
|
a.y1--;
|
|
|
|
a.y2--;
|
|
|
|
sh_buf_tmp += corner_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*Fill the left side*/
|
|
|
|
a.y1 = sh_area.y1+corner_size;
|
|
|
|
a.y2 = a.y1;
|
|
|
|
|
|
|
|
sh_buf_tmp = sh_buf + corner_size * (corner_size - 1);
|
|
|
|
|
|
|
|
for(y = corner_size; y < lv_area_get_height(&sh_area) - corner_size; y++) {
|
|
|
|
memcpy(mask_buf, sh_buf_tmp, corner_size);
|
|
|
|
mask_res = lv_mask_apply(mask_buf + first_px, a.x1, a.y1, lv_area_get_width(&a));
|
|
|
|
if(mask_res == LV_MASK_RES_FULL_COVER) mask_res = LV_MASK_RES_CHANGED;
|
|
|
|
|
|
|
|
lv_blend_fill(clip, &a,
|
|
|
|
style->body.shadow.color, mask_buf + first_px, mask_res, LV_OPA_COVER, LV_BLIT_MODE_NORMAL);
|
|
|
|
a.y1++;
|
|
|
|
a.y2++;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*Fill the top side*/
|
|
|
|
a.x1 = sh_area.x1 + corner_size;
|
|
|
|
a.x2 = sh_area.x2 - corner_size;
|
|
|
|
a.y1 = sh_area.y1;
|
|
|
|
a.y2 = a.y1;
|
|
|
|
|
|
|
|
sh_buf_tmp = sh_buf + corner_size - 1;
|
|
|
|
|
|
|
|
y_max = corner_size;
|
|
|
|
if(other_mask_cnt == 0) y_max = sw / 2 + 1 - y_ofs;
|
|
|
|
|
|
|
|
for(y = 0; y < y_max; y++) {
|
|
|
|
if(other_mask_cnt != 0) {
|
|
|
|
memset(mask_buf, sh_buf_tmp[0], lv_area_get_width(&a));
|
|
|
|
mask_res = lv_mask_apply(mask_buf, a.x1, a.y1, lv_area_get_width(&a));
|
|
|
|
if(mask_res == LV_MASK_RES_FULL_COVER) mask_res = LV_MASK_RES_CHANGED;
|
|
|
|
|
|
|
|
lv_blend_fill(clip, &a,
|
|
|
|
style->body.shadow.color, mask_buf, mask_res, LV_OPA_COVER, LV_BLIT_MODE_NORMAL);
|
|
|
|
} else {
|
|
|
|
lv_blend_fill(clip, &a,
|
|
|
|
style->body.shadow.color, NULL, LV_MASK_RES_FULL_COVER, sh_buf_tmp[0], LV_BLIT_MODE_NORMAL);
|
|
|
|
}
|
|
|
|
|
|
|
|
a.y1++;
|
|
|
|
a.y2++;
|
|
|
|
sh_buf_tmp += corner_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*Fill the bottom side*/
|
|
|
|
a.y1 = sh_area.y2 - corner_size + 1 + y_max;
|
|
|
|
a.y2 = a.y1;
|
|
|
|
|
|
|
|
sh_buf_tmp = sh_buf + corner_size * (corner_size - 1 - y_max) + corner_size - 1;
|
|
|
|
|
|
|
|
y_max = 0;
|
|
|
|
if(other_mask_cnt == 0) y_max = sw / 2 + 1 - y_ofs;
|
|
|
|
|
|
|
|
for(y = y_max; y < corner_size; y++) {
|
|
|
|
if(other_mask_cnt != 0) {
|
|
|
|
memset(mask_buf, sh_buf_tmp[0], lv_area_get_width(&a));
|
|
|
|
mask_res = lv_mask_apply(mask_buf, a.x1, a.y1, lv_area_get_width(&a));
|
|
|
|
if(mask_res == LV_MASK_RES_FULL_COVER) mask_res = LV_MASK_RES_CHANGED;
|
|
|
|
lv_blend_fill(clip, &a,
|
|
|
|
style->body.shadow.color, mask_buf, mask_res, LV_OPA_COVER, LV_BLIT_MODE_NORMAL);
|
|
|
|
} else {
|
|
|
|
lv_blend_fill(clip, &a,
|
|
|
|
style->body.shadow.color, NULL, LV_MASK_RES_FULL_COVER, sh_buf_tmp[0], LV_BLIT_MODE_NORMAL);
|
|
|
|
}
|
|
|
|
|
|
|
|
a.y1++;
|
|
|
|
a.y2++;
|
|
|
|
sh_buf_tmp -= corner_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
lv_mask_remove_id(mask_rout_id);
|
2019-08-29 10:07:22 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2019-09-04 07:35:33 +02:00
|
|
|
#define SHADOW_UPSACALE_SHIFT 6
|
2019-08-29 10:07:22 +02:00
|
|
|
|
2019-09-04 07:35:33 +02:00
|
|
|
static void shadow_draw_corner_buf(const lv_area_t * coords, lv_opa_t * sh_buf, lv_coord_t sw, lv_coord_t r)
|
2019-08-29 10:07:22 +02:00
|
|
|
{
|
2019-08-29 19:01:38 +02:00
|
|
|
lv_coord_t size = sw + r;
|
2019-08-29 10:07:22 +02:00
|
|
|
|
|
|
|
lv_area_t sh_area;
|
2019-09-04 07:35:33 +02:00
|
|
|
lv_area_copy(&sh_area, coords);
|
|
|
|
sh_area.x2 = sw / 2 + r - 1; /*make the end far to not draw the other radius*/
|
2019-08-29 19:01:38 +02:00
|
|
|
sh_area.y1 = sw / 2 + 1;
|
2019-09-04 07:35:33 +02:00
|
|
|
|
|
|
|
sh_area.x1 = sh_area.x2 - lv_area_get_width(coords);
|
|
|
|
sh_area.y2 = sh_area.y1 + lv_area_get_height(coords);
|
2019-08-29 10:07:22 +02:00
|
|
|
|
|
|
|
lv_mask_param_t mask_param;
|
|
|
|
lv_mask_radius_init(&mask_param, &sh_area, r, false);
|
|
|
|
int16_t mask_id = lv_mask_add(lv_mask_radius, &mask_param, NULL);
|
|
|
|
|
|
|
|
lv_mask_res_t mask_res;
|
|
|
|
lv_coord_t y;
|
|
|
|
lv_opa_t mask_line[size];
|
2019-08-29 19:01:38 +02:00
|
|
|
uint32_t sh_ups_buf[size*size];
|
|
|
|
uint32_t * sh_ups_tmp_buf = sh_ups_buf;
|
2019-08-29 10:07:22 +02:00
|
|
|
lv_coord_t s_left = sw >> 1;
|
|
|
|
lv_coord_t s_right = (sw >> 1);
|
|
|
|
if((sw & 1) == 0) s_left--;
|
|
|
|
for(y = 0; y < size; y++) {
|
|
|
|
memset(mask_line, 0xFF, size);
|
|
|
|
mask_res = lv_mask_apply(mask_line, 0, y, size);
|
|
|
|
if(mask_res == LV_MASK_RES_FULL_TRANSP) {
|
2019-08-29 19:01:38 +02:00
|
|
|
memset(sh_ups_tmp_buf, 0x00, size * sizeof(sh_ups_buf[0]));
|
|
|
|
} else {
|
|
|
|
uint32_t i;
|
|
|
|
sh_ups_tmp_buf[0] = (mask_line[0] << SHADOW_UPSACALE_SHIFT) / sw;
|
|
|
|
for(i = 1; i < size; i++) {
|
|
|
|
if(mask_line[i] == mask_line[i-1]) sh_ups_tmp_buf[i] = sh_ups_tmp_buf[i-1];
|
|
|
|
else sh_ups_tmp_buf[i] = (mask_line[i] << SHADOW_UPSACALE_SHIFT) / sw;
|
2019-08-29 10:07:22 +02:00
|
|
|
}
|
|
|
|
}
|
2019-08-29 19:01:38 +02:00
|
|
|
|
|
|
|
sh_ups_tmp_buf += size;
|
2019-08-29 10:07:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
lv_mask_remove_id(mask_id);
|
|
|
|
|
2019-09-04 07:35:33 +02:00
|
|
|
|
|
|
|
|
|
|
|
// uint32_t k;
|
|
|
|
// for(k = 0; k < size * size; k++) {
|
|
|
|
// sh_buf[k] = (sh_ups_buf[k] * sw) >> SHADOW_UPSACALE_SHIFT ;
|
|
|
|
// }
|
|
|
|
// return;
|
|
|
|
|
|
|
|
|
2019-08-29 19:01:38 +02:00
|
|
|
/*Horizontal blur*/
|
|
|
|
uint32_t sh_ups_hor_buf[size*size];
|
|
|
|
sh_ups_tmp_buf = sh_ups_buf + (size*0);
|
|
|
|
uint32_t * sh_ups_hor_buf_tmp = sh_ups_hor_buf + (size*0);
|
|
|
|
|
2019-09-04 07:35:33 +02:00
|
|
|
memset(sh_ups_hor_buf, 0x00, sizeof(sh_ups_hor_buf[0]) * 0 * size);
|
|
|
|
|
2019-08-29 19:01:38 +02:00
|
|
|
lv_coord_t x;
|
|
|
|
for(y = 0; y < size; y++) {
|
2019-09-04 07:35:33 +02:00
|
|
|
int32_t v = sh_ups_tmp_buf[size-1] * sw;
|
|
|
|
for(x = size; x >=0; x--) {
|
2019-08-29 19:01:38 +02:00
|
|
|
sh_ups_hor_buf_tmp[x] = v;
|
|
|
|
|
2019-09-04 07:35:33 +02:00
|
|
|
/*Forget the right pixel*/
|
|
|
|
uint32_t right_val = 0;
|
|
|
|
if(x + s_right < size) right_val = sh_ups_tmp_buf[x + s_right];
|
|
|
|
v -= right_val;
|
|
|
|
|
|
|
|
/*Add the left pixel*/
|
2019-08-29 19:01:38 +02:00
|
|
|
uint32_t left_val;
|
2019-09-04 07:35:33 +02:00
|
|
|
if(x - s_left - 1 < 0) left_val = sh_ups_tmp_buf[0];
|
|
|
|
else left_val = sh_ups_tmp_buf[x - s_left - 1];
|
|
|
|
v += left_val;
|
2019-08-29 19:01:38 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
sh_ups_tmp_buf += size;
|
|
|
|
sh_ups_hor_buf_tmp += size;
|
|
|
|
}
|
2019-09-04 07:35:33 +02:00
|
|
|
|
|
|
|
|
|
|
|
// uint32_t z;
|
|
|
|
// for(z = 0; z < size * size; z++) {
|
|
|
|
// sh_buf[z] = (sh_ups_hor_buf[z] >> SHADOW_UPSACALE_SHIFT) ;
|
2019-08-29 19:01:38 +02:00
|
|
|
// }
|
|
|
|
//
|
|
|
|
// return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*Vertical blur*/
|
|
|
|
uint32_t i;
|
|
|
|
sh_ups_hor_buf[0] = sh_ups_hor_buf[0] / sw;
|
|
|
|
for(i = 1; i < size * size; i++) {
|
|
|
|
if(sh_ups_hor_buf[i] == sh_ups_hor_buf[i-1]) sh_ups_hor_buf[i] = sh_ups_hor_buf[i-1];
|
|
|
|
else sh_ups_hor_buf[i] = sh_ups_hor_buf[i] / sw;
|
|
|
|
}
|
|
|
|
|
|
|
|
for(x = 0; x < size; x++) {
|
|
|
|
sh_ups_hor_buf_tmp = &sh_ups_hor_buf[x];
|
|
|
|
lv_opa_t * sh_buf_tmp = &sh_buf[x];
|
|
|
|
int32_t v = sh_ups_hor_buf_tmp[0] * sw;
|
|
|
|
for(y = 0; y < size; y++, sh_ups_hor_buf_tmp += size, sh_buf_tmp += size) {
|
2019-09-04 07:35:33 +02:00
|
|
|
sh_buf_tmp[0] = v < 0 ? 0 : (v >> SHADOW_UPSACALE_SHIFT);
|
2019-08-29 19:01:38 +02:00
|
|
|
|
|
|
|
/*Forget the top pixel*/
|
|
|
|
uint32_t top_val;
|
|
|
|
if(y - s_left <= 0) top_val = sh_ups_hor_buf_tmp[0];//25<< SHADOW_UPSACALE_SHIFT;
|
|
|
|
else top_val = sh_ups_hor_buf[(y - s_left) * size + x];
|
|
|
|
v -= top_val;
|
|
|
|
|
|
|
|
/*Add the bottom pixel*/
|
|
|
|
uint32_t bottom_val;
|
|
|
|
if(y + s_right + 1 < size) bottom_val = sh_ups_hor_buf[(y + s_right + 1) * size + x];
|
|
|
|
else bottom_val = sh_ups_hor_buf[(size - 1) * size + x];
|
|
|
|
v += bottom_val;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-29 10:07:22 +02:00
|
|
|
}
|
|
|
|
|