diff --git a/apps/screen_access.c b/apps/screen_access.c index 23625ae89c..dd8b16e3fd 100644 --- a/apps/screen_access.c +++ b/apps/screen_access.c @@ -268,6 +268,7 @@ struct screen screens[NB_SCREENS] = .set_framebuffer = (void*)lcd_set_framebuffer, #if defined(HAVE_LCD_COLOR) .gradient_fillrect = lcd_gradient_fillrect, + .gradient_fillrect_part = lcd_gradient_fillrect_part, #endif #endif }, diff --git a/apps/screen_access.h b/apps/screen_access.h index 210ad2e990..d5bcd7e095 100644 --- a/apps/screen_access.h +++ b/apps/screen_access.h @@ -169,6 +169,8 @@ struct screen #if defined(HAVE_LCD_COLOR) void (*gradient_fillrect)(int x, int y, int width, int height, unsigned start, unsigned end); + void (*gradient_fillrect_part)(int x, int y, int width, int height, + unsigned start, unsigned end, int src_height, int row_skip); #endif #endif #if defined(HAVE_LCD_BITMAP) diff --git a/firmware/drivers/lcd-bitmap-common.c b/firmware/drivers/lcd-bitmap-common.c index 5961bba7a5..2b309ba75a 100644 --- a/firmware/drivers/lcd-bitmap-common.c +++ b/firmware/drivers/lcd-bitmap-common.c @@ -41,8 +41,21 @@ #endif #if defined(MAIN_LCD) && defined(HAVE_LCD_COLOR) -void lcd_gradient_fillrect(int x, int y, int width, int height, - unsigned start_rgb, unsigned end_rgb) +/* Fill a rectangle with a gradient. This function draws only the partial + * gradient. It assumes the original gradient is src_height high and skips + * the first few rows. This is useful for drawing only the bottom half of + * a full gradient. + * + * height == src_height and row_skip == 0 will draw the full gradient + * + * x, y, width, height - dimensions describing the rectangle + * start_rgb - beginning color of the gradient + * end_rgb - end color of the gradient + * src_height - assumed original height (only height rows will be drawn) + * row_skip - how many rows of the original gradient to skip + */ +void lcd_gradient_fillrect_part(int x, int y, int width, int height, + unsigned start_rgb, unsigned end_rgb, int src_height, int row_skip) { int old_pattern = current_vp->fg_pattern; int step_mul, i; @@ -52,7 +65,7 @@ void lcd_gradient_fillrect(int x, int y, int width, int height, if (height == 0) return; - step_mul = (1 << 16) / height; + step_mul = (1 << 16) / src_height; int h_r = RGB_UNPACK_RED(start_rgb); int h_g = RGB_UNPACK_GREEN(start_rgb); int h_b = RGB_UNPACK_BLUE(start_rgb); @@ -63,6 +76,13 @@ void lcd_gradient_fillrect(int x, int y, int width, int height, h_g = (h_g << 16) + (1 << 15); h_b = (h_b << 16) + (1 << 15); + if (row_skip > 0) + { + h_r -= rstep * row_skip; + h_g -= gstep * row_skip; + h_b -= bstep * row_skip; + } + for(i = y; i < y + height; i++) { current_vp->fg_pattern = LCD_RGBPACK(h_r >> 16, h_g >> 16, h_b >> 16); lcd_hline(x1, x2, i); @@ -74,6 +94,19 @@ void lcd_gradient_fillrect(int x, int y, int width, int height, current_vp->fg_pattern = old_pattern; } +/* Fill a rectangle with a gradient. The gradient's color will fade from + * start_rgb to end_rgb over the height of the rectangle + * + * x, y, width, height - dimensions describing the rectangle + * start_rgb - beginning color of the gradient + * end_rgb - end color of the gradient + */ +void lcd_gradient_fillrect(int x, int y, int width, int height, + unsigned start_rgb, unsigned end_rgb) +{ + lcd_gradient_fillrect_part(x, y, width, height, start_rgb, end_rgb, height, 0); +} + /* Fill a text line with a gradient: * x1, x2 - x pixel coordinates to start/stop * y - y pixel to start from diff --git a/firmware/export/lcd.h b/firmware/export/lcd.h index 745c445dda..af32b796be 100644 --- a/firmware/export/lcd.h +++ b/firmware/export/lcd.h @@ -530,6 +530,8 @@ extern void lcd_drawrect(int x, int y, int width, int height); extern void lcd_fillrect(int x, int y, int width, int height); extern void lcd_gradient_fillrect(int x, int y, int width, int height, unsigned start_rgb, unsigned end_rgb); +extern void lcd_gradient_fillrect_part(int x, int y, int width, int height, + unsigned start_rgb, unsigned end_rgb, int src_height, int row_skip); extern void lcd_draw_border_viewport(void); extern void lcd_fill_viewport(void); extern void lcd_bitmap_part(const fb_data *src, int src_x, int src_y,