Drawing to a temporary canvas for rotation

Description

I’m trying to draw a rotated pill shape to a layer by rendering to a temporary canvas, then rendering that out to an image and finally drawing it on my screen canvas with a rotation. Similar to this example: lvgl/examples/widgets/canvas/lv_example_canvas_1.c at c903c1dc0fdfae20bce69d0a48894bdebae278ff · lvgl/lvgl · GitHub

I cannot get this to display anything. Even the temporary canvas background color doesn’t display. My LVGL is configured correctly. I can draw pills normally to the canvas just fine.

What am I doing wrong here?

What MCU/Processor/Board and compiler are you using?

esp32

What LVGL version are you using?

9.2.2

Code to reproduce

// This does not work
void lv_draw_pill_rotate(lv_layer_t * layer, float center_x, float center_y, float width, float height, float angle = 30) {
    // Create a buffer for the temporary canvas
    LV_DRAW_BUF_DEFINE_STATIC(eye_buff, EYE_DRAW_BUF_WIDTH, EYE_DRAW_BUF_HEIGHT, LV_COLOR_FORMAT_RGB565);
    LV_DRAW_BUF_INIT_STATIC(eye_buff);
    
    // Create and set up temporary canvas
    lv_obj_t * temp_canvas = lv_canvas_create(NULL);
    lv_canvas_set_draw_buf(temp_canvas, &eye_buff);
    lv_obj_center(temp_canvas);
    lv_canvas_fill_bg(temp_canvas, lv_color_hex(0xFF0000), LV_OPA_100);

    // Draw pill on temporary canvas
    lv_layer_t temp_layer;
    lv_canvas_init_layer(temp_canvas, &temp_layer);

    lv_draw_rect_dsc_t rect_dsc;
    lv_draw_rect_dsc_init(&rect_dsc);
    rect_dsc.radius = min(height/2, width/2);
    rect_dsc.bg_opa = LV_OPA_COVER;
    rect_dsc.bg_color = lv_color_white();
    rect_dsc.border_width = 0;

    // Center the pill in the temporary canvas
    lv_area_t coords = {
        (EYE_DRAW_BUF_WIDTH - width)/2,
        (EYE_DRAW_BUF_HEIGHT - height)/2,
        (EYE_DRAW_BUF_WIDTH + width)/2,
        (EYE_DRAW_BUF_HEIGHT + height)/2
    };

    lv_draw_rect(&temp_layer, &rect_dsc, &coords);
    lv_canvas_finish_layer(temp_canvas, &temp_layer);

    // Convert canvas buffer to image
    lv_image_dsc_t img;
    lv_draw_buf_to_image(&eye_buff, &img);
    
    lv_draw_image_dsc_t img_dsc;
    lv_draw_image_dsc_init(&img_dsc);
    img_dsc.rotation = angle * 10;  // LVGL uses 0.1 degrees
    img_dsc.src = &img;
    img_dsc.pivot.x = EYE_DRAW_BUF_WIDTH / 2;
    img_dsc.pivot.y = EYE_DRAW_BUF_HEIGHT / 2;

    // Draw rotated image at the desired position
    lv_area_t coords_img = {
        center_x - EYE_DRAW_BUF_WIDTH/2,
        center_y - EYE_DRAW_BUF_HEIGHT/2,
        center_x + EYE_DRAW_BUF_WIDTH/2 - 1,
        center_y + EYE_DRAW_BUF_HEIGHT/2 - 1
    };
    
    lv_draw_image(layer, &img_dsc, &coords_img);

    // Clean up
    lv_obj_del(temp_canvas);
}

// This works
void lv_draw_pill(lv_layer_t * layer, float center_x, float center_y, float width, float height) {
    lv_draw_rect_dsc_t rect_dsc;
    lv_draw_rect_dsc_init(&rect_dsc);
    rect_dsc.radius = min(height/2, width/2);
    rect_dsc.bg_opa = LV_OPA_COVER;
    rect_dsc.bg_color = lv_color_white();
    rect_dsc.border_width = 0;

    lv_area_t coords = {
        center_x - width/2,
        center_y - height/2,
        center_x + width/2,
        center_y + height/2
    };

    lv_draw_rect(layer, &rect_dsc, &coords);
}