diff --git a/hal.c b/hal.c index 5f93ac60..4587639d 100644 --- a/hal.c +++ b/hal.c @@ -328,3 +328,20 @@ void lvgui_focus_ring_disable() lv_group_set_style_mod_cb(lvgui_focus_group, lvgui_style_mod_noop); lv_group_set_style_mod_edit_cb(lvgui_focus_group, lvgui_style_mod_noop); } + +hal_panel_orientation_t hal_get_panel_orientation() +{ +#if USE_DRM + switch (drm_display_orientation) { + case DRM_ORIENTATION_NORMAL: + return HAL_PANEL_ORIENTATION_NORMAL; + case DRM_ORIENTATION_UPSIDE_DOWN: + return HAL_PANEL_ORIENTATION_BOTTOM_UP; + case DRM_ORIENTATION_CLOCKWISE: + return HAL_PANEL_ORIENTATION_LEFT_UP; + case DRM_ORIENTATION_COUNTER_CLOCKWISE: + return HAL_PANEL_ORIENTATION_RIGHT_UP; + } +#endif + return 0; +} diff --git a/hal.h b/hal.h index 835e8cd0..978696b7 100644 --- a/hal.h +++ b/hal.h @@ -1,10 +1,22 @@ #ifndef HAL_H #define HAL_H +/* + * Same semantics as drm_orientation_t. + */ +enum { + HAL_PANEL_ORIENTATION_NORMAL = 0, + HAL_PANEL_ORIENTATION_BOTTOM_UP = 1, + HAL_PANEL_ORIENTATION_RIGHT_UP = 2, + HAL_PANEL_ORIENTATION_LEFT_UP = 3, +}; +typedef uint8_t hal_panel_orientation_t; + void hal_init(const char* asset_path); lv_group_t * lvgui_get_focus_group(); void lvgui_focus_ring_disable(); char * hal_asset_path(const char* asset_path); +hal_panel_orientation_t hal_get_panel_orientation() ; extern lv_disp_drv_t disp_drv; extern int mn_hal_default_dpi; diff --git a/lvgl/src/lv_objx/lv_canvas.c b/lvgl/src/lv_objx/lv_canvas.c index 68f37601..f58eceee 100644 --- a/lvgl/src/lv_objx/lv_canvas.c +++ b/lvgl/src/lv_objx/lv_canvas.c @@ -100,18 +100,13 @@ lv_obj_t * lv_canvas_create(lv_obj_t * par, const lv_obj_t * copy) /** * Set a buffer for the canvas. * @param buf a buffer where the content of the canvas will be. - * The required size is (lv_img_color_format_get_px_size(cf) * w * h) / 8) - * It can be allocated with `lv_mem_alloc()` or - * it can be statically allocated array (e.g. static lv_color_t buf[100*50]) or - * it can be an address in RAM or external SRAM * @param canvas pointer to a canvas object + * @param buf buffer for the canvas * @param w width of the canvas * @param h height of the canvas - * @param cf color format. The following formats are supported: - * LV_IMG_CF_TRUE_COLOR, LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED, LV_IMG_CF_INDEXES_1/2/4/8BIT - * + * @param cf color format. `LV_IMG_CF_...` */ -void lv_canvas_set_buffer(lv_obj_t * canvas, void * buf, lv_coord_t w, lv_coord_t h, lv_img_cf_t cf) +void lv_canvas_set_buffer(lv_obj_t * canvas, lv_img_dsc_t * buf, lv_coord_t w, lv_coord_t h, lv_img_cf_t cf) { LV_ASSERT_OBJ(canvas, LV_OBJX_NAME); LV_ASSERT_NULL(buf); @@ -121,7 +116,7 @@ void lv_canvas_set_buffer(lv_obj_t * canvas, void * buf, lv_coord_t w, lv_coord_ ext->dsc.header.cf = cf; ext->dsc.header.w = w; ext->dsc.header.h = h; - ext->dsc.data = buf; + ext->dsc.data = buf->data; ext->dsc.data_size = (lv_img_color_format_get_px_size(cf) * w * h) / 8; lv_img_set_src(canvas, &ext->dsc); @@ -274,6 +269,9 @@ void lv_canvas_copy_buf(lv_obj_t * canvas, const void * to_copy, lv_coord_t x, l /** * Rotate and image and store the result on a canvas. + * + * NOTE: When doing 90, 180 or 270 degree rotations, using pivot point 0,0 will do a perfect rotation. + * * @param canvas pointer to a canvas object * @param img pointer to an image descriptor. * Can be the image descriptor of an other canvas too (`lv_canvas_get_img()`). @@ -305,6 +303,40 @@ void lv_canvas_rotate(lv_obj_t * canvas, lv_img_dsc_t * img, int16_t angle, lv_c int32_t y; for(x = -offset_x; x < dest_width - offset_x; x++) { for(y = -offset_y; y < dest_height - offset_y; y++) { + // Right angle rotations are "perfect" pixel-for-pixel rotations. + // Since we always operate on the same scale (1 pixel to 1 pixel) + // we can rely on simpler lookups. + // Usage (rb): + // # The offset has to be -1/-1 to get the full picture in. + // canvas.rotate(other.get_img(), 180, width-1, height-1, 0, 0) + if (angle == 180 && pivot_x == 0 && pivot_y == 0) { + int32_t source_x = img_width - 1 - (x + offset_x); + int32_t source_y = img_height - 1 - (y + offset_y); + + lv_color_t color_res = lv_img_buf_get_px_color(img, source_x, source_y, style); + lv_img_buf_set_px_color(&ext_dst->dsc, x + offset_x, y + offset_y, color_res); + continue; + } + if ((angle == 270 || angle == 90) && pivot_x == 0 && pivot_y == 0) { + int32_t source_x = x + offset_x; + int32_t source_y = y + offset_y; + int32_t dest_x = x + offset_x; + int32_t dest_y = y + offset_y; + + if (angle == 90) { + source_x = img_height - 1 - (x + offset_x); + } + else { + source_y = img_width - 1 - (y + offset_y); + } + + lv_color_t color_res = lv_img_buf_get_px_color(img, source_y, source_x, style); + + lv_img_buf_set_px_color(&ext_dst->dsc, dest_x, dest_y, color_res); + + continue; + } + /*Get the target point relative coordinates to the pivot*/ int32_t xt = x - pivot_x; int32_t yt = y - pivot_y; diff --git a/lvgl/src/lv_objx/lv_canvas.h b/lvgl/src/lv_objx/lv_canvas.h index dab9a152..c1e255bd 100644 --- a/lvgl/src/lv_objx/lv_canvas.h +++ b/lvgl/src/lv_objx/lv_canvas.h @@ -65,16 +65,13 @@ lv_obj_t * lv_canvas_create(lv_obj_t * par, const lv_obj_t * copy); /** * Set a buffer for the canvas. * @param buf a buffer where the content of the canvas will be. - * The required size is (lv_img_color_format_get_px_size(cf) * w * h) / 8) - * It can be allocated with `lv_mem_alloc()` or - * it can be statically allocated array (e.g. static lv_color_t buf[100*50]) or - * it can be an address in RAM or external SRAM * @param canvas pointer to a canvas object + * @param buf buffer for the canvas * @param w width of the canvas * @param h height of the canvas * @param cf color format. `LV_IMG_CF_...` */ -void lv_canvas_set_buffer(lv_obj_t * canvas, void * buf, lv_coord_t w, lv_coord_t h, lv_img_cf_t cf); +void lv_canvas_set_buffer(lv_obj_t * canvas, lv_img_dsc_t * buf, lv_coord_t w, lv_coord_t h, lv_img_cf_t cf); /** * Set the color of a pixel on the canvas