Description
What MCU/Processor/Board and compiler are you using?
PC Simulator
What LVGL version are you using?
V9.0
What do you want to achieve?
- Using a separated thread to draw a custom image using lvgl canvas.
- Rotate the custom image and draw it on the screen when LV_EVENT_DRAW_MAIN event is received.
What have you tried so far?
I found the image rotation can work if I use lv_obj_invalidate() without specify the area (which means the whole object will be redraw). However, I use lv_obj_invalidate(lv_area_t*) to specify the updated area, the updated area will not be rotated.
Code to reproduce
The following is the code of main function.
/* lvgl initialization code /
…
/ lvgl initialization code */
lv_delay_set_cb(SDL_Delay);
BaseWindow * baseWindow = new BaseWindow();
lv_thread_t thread;
lv_thread_init(&thread, LV_THREAD_PRIO_MID, mainThread, 0, baseWindow);
baseWindow->load();
/*Handle LVGL tasks*/
while (1) {
baseWindow->lock();
int timeTillNext = lv_timer_handler();
baseWindow->unlock();
lv_delay_ms(timeTillNext);
}
The following is the code of mainThread
static void mainThread(void* args) {
BaseWindow* win = (BaseWindow*) args;
lv_obj_t *canvas = lv_canvas_create(lv_obj_create(nullptr));
lv_canvas_set_draw_buf(canvas, win->getBuffer());
lv_canvas_fill_bg(canvas, lv_color_white(), LV_OPA_COVER);
int counter = 0;
while(true) {
win->lock();
lv_layer_t layer;
lv_canvas_init_layer(canvas, &layer);
lv_draw_rect_dsc_t rect_dsc;
lv_area_t rect_area = {700, 300, 900, 500};
lv_draw_rect_dsc_init(&rect_dsc);
rect_dsc.bg_color = lv_color_white();
lv_draw_rect(&layer, &rect_dsc, &rect_area);
lv_draw_arc_dsc_t arc_dsc;
lv_draw_arc_dsc_init(&arc_dsc);
arc_dsc.center.x = 800;
arc_dsc.center.y = 400;
arc_dsc.color = lv_color_make(0, 255, 255);
arc_dsc.width = 10;
arc_dsc.start_angle = 0 + counter;
arc_dsc.end_angle = 280;
arc_dsc.radius = 100;
arc_dsc.rounded = 1;
lv_draw_arc(&layer, &arc_dsc);
lv_draw_label_dsc_t label_dsc;
lv_draw_label_dsc_init(&label_dsc);
char textBuf[255] = {0};
lv_snprintf(textBuf, 255, "Hello world %d \n", counter);
label_dsc.color = lv_color_make(255, 0, 0);
label_dsc.text = textBuf;
lv_area_t area;
area.x1 = 100;
area.x2 = 400;
area.y1 = 100;
area.y2 = 400;
lv_draw_rect(&layer, &rect_dsc, &area);
lv_draw_label(&layer, &label_dsc, &area);
lv_canvas_finish_layer(canvas, &layer);
win->invalidate(&area);
win->invalidate(&rect_area);
win->unlock();
counter++;
if(counter > 50)
counter = 0;
lv_delay_ms(100);
}
}
The following is the code of event handler LV_EVENT_DRAW_MAIN
void onDraw(lv_layer_t* layer) {
lv_draw_image_dsc_t drawImageDsc;
lv_area_t area = {0, 0, getWidth(), getHeight()};
lv_draw_image_dsc_init(&drawImageDsc);
lv_draw_buf_to_image(m_drawbuffer, &m_content);
drawImageDsc.src = &m_content;
drawImageDsc.pivot.x = LV_HOR_RES / 2;
drawImageDsc.pivot.y = LV_VER_RES / 2;
drawImageDsc.rotation = 45;
lv_draw_image(layer, &drawImageDsc, &area);
}
Screenshot and/or video
The incorrect result.
The expected result.