summaryrefslogtreecommitdiff
path: root/firmware/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers')
-rw-r--r--firmware/drivers/lcd-bitmap-common.c60
1 files changed, 46 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 @@
41#endif 41#endif
42 42
43#if defined(MAIN_LCD) && defined(HAVE_LCD_COLOR) 43#if defined(MAIN_LCD) && defined(HAVE_LCD_COLOR)
44/* Fill a rectangle with a gradient */ 44void lcd_gradient_fillrect(int x1, int x2, int y1, int y2,
45static void lcd_gradient_rect(int x1, int x2, int y, unsigned h, 45 unsigned start_rgb, unsigned end_rgb)
46 int num_lines, int cur_line)
47{ 46{
48 int old_pattern = current_vp->fg_pattern; 47 int old_pattern = current_vp->fg_pattern;
48 int step_mul, i;
49 if (y2 - y1 == 0) return;
50
51 step_mul = (1 << 16) / (y2 - y1);
52 int h_r = RGB_UNPACK_RED(start_rgb);
53 int h_g = RGB_UNPACK_GREEN(start_rgb);
54 int h_b = RGB_UNPACK_BLUE(start_rgb);
55 int rstep = (h_r - RGB_UNPACK_RED(end_rgb)) * step_mul;
56 int gstep = (h_g - RGB_UNPACK_GREEN(end_rgb)) * step_mul;
57 int bstep = (h_b - RGB_UNPACK_BLUE(end_rgb)) * step_mul;
58 h_r = (h_r << 16) + (1 << 15);
59 h_g = (h_g << 16) + (1 << 15);
60 h_b = (h_b << 16) + (1 << 15);
61
62 for(i = y1; i < y2; i++) {
63 current_vp->fg_pattern = LCD_RGBPACK(h_r >> 16, h_g >> 16, h_b >> 16);
64 lcd_hline(x1, x2, i);
65 h_r -= rstep;
66 h_g -= gstep;
67 h_b -= bstep;
68 }
69
70 current_vp->fg_pattern = old_pattern;
71}
72
73/* Fill a text line with a gradient:
74 * x1, x2 - x pixel coordinates to start/stop
75 * y - y pixel to start from
76 * h - line height
77 * num_lines - number of lines to span the gradient over
78 * cur_line - current line being draw
79 */
80static void lcd_do_gradient_line(int x1, int x2, int y, unsigned h,
81 int num_lines, int cur_line)
82{
49 int step_mul; 83 int step_mul;
50 if (h == 0) return; 84 if (h == 0) return;
51 85
@@ -58,6 +92,7 @@ static void lcd_gradient_rect(int x1, int x2, int y, unsigned h,
58 int rstep = (h_r - RGB_UNPACK_RED(current_vp->lse_pattern)) * step_mul; 92 int rstep = (h_r - RGB_UNPACK_RED(current_vp->lse_pattern)) * step_mul;
59 int gstep = (h_g - RGB_UNPACK_GREEN(current_vp->lse_pattern)) * step_mul; 93 int gstep = (h_g - RGB_UNPACK_GREEN(current_vp->lse_pattern)) * step_mul;
60 int bstep = (h_b - RGB_UNPACK_BLUE(current_vp->lse_pattern)) * step_mul; 94 int bstep = (h_b - RGB_UNPACK_BLUE(current_vp->lse_pattern)) * step_mul;
95 unsigned start_rgb, end_rgb;
61 h_r = (h_r << 16) + (1 << 15); 96 h_r = (h_r << 16) + (1 << 15);
62 h_g = (h_g << 16) + (1 << 15); 97 h_g = (h_g << 16) + (1 << 15);
63 h_b = (h_b << 16) + (1 << 15); 98 h_b = (h_b << 16) + (1 << 15);
@@ -67,18 +102,15 @@ static void lcd_gradient_rect(int x1, int x2, int y, unsigned h,
67 h_g -= cur_line * gstep; 102 h_g -= cur_line * gstep;
68 h_b -= cur_line * bstep; 103 h_b -= cur_line * bstep;
69 } 104 }
70 unsigned count; 105 start_rgb = LCD_RGBPACK(h_r >> 16, h_g >> 16, h_b >> 16);
71
72 for(count = 0; count < h; count++) {
73 current_vp->fg_pattern = LCD_RGBPACK(h_r >> 16, h_g >> 16, h_b >> 16);
74 lcd_hline(x1, x2, y + count);
75 h_r -= rstep;
76 h_g -= gstep;
77 h_b -= bstep;
78 }
79 106
80 current_vp->fg_pattern = old_pattern; 107 h_r -= h * rstep;
108 h_g -= h * gstep;
109 h_b -= h * bstep;
110 end_rgb = LCD_RGBPACK(h_r >> 16, h_g >> 16, h_b >> 16);
111 lcd_gradient_fillrect(x1, x2, y, y + h, start_rgb, end_rgb);
81} 112}
113
82#endif 114#endif
83 115
84void LCDFN(set_framebuffer)(FBFN(data) *fb) 116void LCDFN(set_framebuffer)(FBFN(data) *fb)
@@ -284,7 +316,7 @@ static void LCDFN(putsxyofs_style)(int xpos, int ypos,
284 current_vp->drawmode ^= DRMODE_INVERSEVID; 316 current_vp->drawmode ^= DRMODE_INVERSEVID;
285 if (style & STYLE_GRADIENT) { 317 if (style & STYLE_GRADIENT) {
286 current_vp->drawmode = DRMODE_FG; 318 current_vp->drawmode = DRMODE_FG;
287 lcd_gradient_rect(xpos, current_vp->width, ypos, h, 319 lcd_do_gradient_line(xpos, current_vp->width, ypos, h,
288 NUMLN_UNPACK(style), CURLN_UNPACK(style)); 320 NUMLN_UNPACK(style), CURLN_UNPACK(style));
289 current_vp->fg_pattern = current_vp->lst_pattern; 321 current_vp->fg_pattern = current_vp->lst_pattern;
290 } 322 }