Hi LVGL team
,
I’m experimenting with lv_draw_mask_rect() and I have a question about how the keep_outside parameter is expected to behave — especially when using a radius mask.
According to the documentation:
- If
keep_outside = 1, the area outside the rectangle should be kept, and the inside should be cleared (transparent).
However, in the following example, when I apply a rectangle mask with keep_outside = 1, the inside of the masked area is still visible, and the outside is cleared — which feels like the behavior of keep_outside = 0.
Full Example Code
static void event_cb_draw_mask(lv_event_t * e)
{
const auto * obj = static_cast<lv_obj_t *>(lv_event_get_target(e));
const lv_draw_task_t * draw_task = lv_event_get_draw_task(e);
const auto * base_dsc = static_cast<lv_draw_dsc_base_t *>(lv_draw_task_get_draw_dsc(draw_task));
lv_area_t obj_coords;
lv_obj_get_coords(obj, &obj_coords);
lv_layer_t * layer = base_dsc->layer;
lv_area_t layer_area = {0,0, 200, 200};
lv_area_align(&obj_coords, &layer_area, LV_ALIGN_CENTER, 0, 0);
if(base_dsc->part == LV_PART_MAIN) {
// Draw red background
lv_draw_rect_dsc_t draw_background_dsc;
lv_draw_rect_dsc_init(&draw_background_dsc);
draw_background_dsc.bg_color = lv_color_hex(0xFF0000);
lv_draw_rect(layer, &draw_background_dsc, &layer_area);
// Draw black rect into a new layer
lv_layer_t * new_layer = lv_draw_layer_create(layer, LV_COLOR_FORMAT_ARGB8888, &layer_area);
lv_draw_rect_dsc_t draw_yellow_rect_dsc;
lv_draw_rect_dsc_init(&draw_yellow_rect_dsc);
draw_yellow_rect_dsc.bg_color = lv_color_hex(0x000000);
lv_draw_rect(new_layer, &draw_yellow_rect_dsc, &layer_area);
// Apply rectangle mask with radius and keep_outside = 1
lv_draw_mask_rect_dsc_t mask_dsc;
lv_draw_mask_rect_dsc_init(&mask_dsc);
mask_dsc.area = layer_area;
mask_dsc.radius = LV_RADIUS_CIRCLE;
mask_dsc.keep_outside = 1;
lv_draw_mask_rect(new_layer, &mask_dsc);
// Composite back
lv_draw_image_dsc_t image_draw_dsc;
lv_draw_image_dsc_init(&image_draw_dsc);
image_draw_dsc.src = new_layer;
lv_draw_layer(layer, &image_draw_dsc, &layer_area);
}
}
void lv_example_event_draw(void)
{
lv_obj_t * cont = lv_obj_create(lv_screen_active());
lv_obj_set_size(cont, 200, 200);
lv_obj_center(cont);
lv_obj_add_event_cb(cont, event_cb_draw_mask, LV_EVENT_DRAW_TASK_ADDED, nullptr);
lv_obj_add_flag(cont, LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS);
}
Observed Behavior
Despite setting keep_outside = 1, the inside of the rectangle is preserved and the outside is cleared, which matches what I’d expect from keep_outside = 0.
Internal Code Observation
In the source code of lv_draw_sw_mask_rect(), this line appears:
lv_draw_sw_mask_radius_init(¶m, &dsc->area, dsc->radius, false);
But shouldn’t the last invert parameter reflect dsc->keep_outside?
Changing it to:
lv_draw_sw_mask_radius_init(¶m, &dsc->area, dsc->radius, dsc->keep_outside);
…produces the expected behavior.
Current result:

Expected result:
