diff options
author | Jonathan Gordon <rockbox@jdgordon.info> | 2012-02-29 23:43:50 +1100 |
---|---|---|
committer | Jonathan Gordon <rockbox@jdgordon.info> | 2012-03-01 00:10:17 +1100 |
commit | 8efb8f97c4882e3142f62bf35c822cae6fb120c3 (patch) | |
tree | cfb805f4d6e105eb574f82f8836d707e7c2bc029 | |
parent | f0ecce9ee540591493b6d104d62f26fe73af0a73 (diff) |
lcd drivers: split lcd_gradient_rect so it is actually useful
lcd_gradient_rect() was only usable to draw list lines, so split
it up and make a generic gradient draw function available to apps/
Change-Id: I665911a90fef239b5e06592ea2763cbeeb74c83f
-rw-r--r-- | firmware/drivers/lcd-bitmap-common.c | 60 | ||||
-rw-r--r-- | firmware/export/lcd.h | 2 |
2 files changed, 48 insertions, 14 deletions
diff --git a/firmware/drivers/lcd-bitmap-common.c b/firmware/drivers/lcd-bitmap-common.c index b0be687ed2..80796b392b 100644 --- a/firmware/drivers/lcd-bitmap-common.c +++ b/firmware/drivers/lcd-bitmap-common.c @@ -41,11 +41,45 @@ #endif #if defined(MAIN_LCD) && defined(HAVE_LCD_COLOR) -/* Fill a rectangle with a gradient */ -static void lcd_gradient_rect(int x1, int x2, int y, unsigned h, - int num_lines, int cur_line) +void lcd_gradient_fillrect(int x1, int x2, int y1, int y2, + unsigned start_rgb, unsigned end_rgb) { int old_pattern = current_vp->fg_pattern; + int step_mul, i; + if (y2 - y1 == 0) return; + + step_mul = (1 << 16) / (y2 - y1); + int h_r = RGB_UNPACK_RED(start_rgb); + int h_g = RGB_UNPACK_GREEN(start_rgb); + int h_b = RGB_UNPACK_BLUE(start_rgb); + int rstep = (h_r - RGB_UNPACK_RED(end_rgb)) * step_mul; + int gstep = (h_g - RGB_UNPACK_GREEN(end_rgb)) * step_mul; + int bstep = (h_b - RGB_UNPACK_BLUE(end_rgb)) * step_mul; + h_r = (h_r << 16) + (1 << 15); + h_g = (h_g << 16) + (1 << 15); + h_b = (h_b << 16) + (1 << 15); + + for(i = y1; i < y2; i++) { + current_vp->fg_pattern = LCD_RGBPACK(h_r >> 16, h_g >> 16, h_b >> 16); + lcd_hline(x1, x2, i); + h_r -= rstep; + h_g -= gstep; + h_b -= bstep; + } + + current_vp->fg_pattern = old_pattern; +} + +/* Fill a text line with a gradient: + * x1, x2 - x pixel coordinates to start/stop + * y - y pixel to start from + * h - line height + * num_lines - number of lines to span the gradient over + * cur_line - current line being draw + */ +static void lcd_do_gradient_line(int x1, int x2, int y, unsigned h, + int num_lines, int cur_line) +{ int step_mul; if (h == 0) return; @@ -58,6 +92,7 @@ static void lcd_gradient_rect(int x1, int x2, int y, unsigned h, int rstep = (h_r - RGB_UNPACK_RED(current_vp->lse_pattern)) * step_mul; int gstep = (h_g - RGB_UNPACK_GREEN(current_vp->lse_pattern)) * step_mul; int bstep = (h_b - RGB_UNPACK_BLUE(current_vp->lse_pattern)) * step_mul; + unsigned start_rgb, end_rgb; h_r = (h_r << 16) + (1 << 15); h_g = (h_g << 16) + (1 << 15); h_b = (h_b << 16) + (1 << 15); @@ -67,18 +102,15 @@ static void lcd_gradient_rect(int x1, int x2, int y, unsigned h, h_g -= cur_line * gstep; h_b -= cur_line * bstep; } - unsigned count; - - for(count = 0; count < h; count++) { - current_vp->fg_pattern = LCD_RGBPACK(h_r >> 16, h_g >> 16, h_b >> 16); - lcd_hline(x1, x2, y + count); - h_r -= rstep; - h_g -= gstep; - h_b -= bstep; - } + start_rgb = LCD_RGBPACK(h_r >> 16, h_g >> 16, h_b >> 16); - current_vp->fg_pattern = old_pattern; + h_r -= h * rstep; + h_g -= h * gstep; + h_b -= h * bstep; + end_rgb = LCD_RGBPACK(h_r >> 16, h_g >> 16, h_b >> 16); + lcd_gradient_fillrect(x1, x2, y, y + h, start_rgb, end_rgb); } + #endif void LCDFN(set_framebuffer)(FBFN(data) *fb) @@ -284,7 +316,7 @@ static void LCDFN(putsxyofs_style)(int xpos, int ypos, current_vp->drawmode ^= DRMODE_INVERSEVID; if (style & STYLE_GRADIENT) { current_vp->drawmode = DRMODE_FG; - lcd_gradient_rect(xpos, current_vp->width, ypos, h, + lcd_do_gradient_line(xpos, current_vp->width, ypos, h, NUMLN_UNPACK(style), CURLN_UNPACK(style)); current_vp->fg_pattern = current_vp->lst_pattern; } diff --git a/firmware/export/lcd.h b/firmware/export/lcd.h index 7e0e979821..dbb3a781b8 100644 --- a/firmware/export/lcd.h +++ b/firmware/export/lcd.h @@ -523,6 +523,8 @@ extern void lcd_hline(int x1, int x2, int y); extern void lcd_vline(int x, int y1, int y2); 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_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, |