summaryrefslogtreecommitdiff
path: root/firmware/drivers/lcd-bitmap-common.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers/lcd-bitmap-common.c')
-rw-r--r--firmware/drivers/lcd-bitmap-common.c146
1 files changed, 17 insertions, 129 deletions
diff --git a/firmware/drivers/lcd-bitmap-common.c b/firmware/drivers/lcd-bitmap-common.c
index 7c5df5a3a8..e37da51a1b 100644
--- a/firmware/drivers/lcd-bitmap-common.c
+++ b/firmware/drivers/lcd-bitmap-common.c
@@ -41,6 +41,7 @@
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
44/* Fill a rectangle with a gradient. This function draws only the partial 45/* Fill a rectangle with a gradient. This function draws only the partial
45 * gradient. It assumes the original gradient is src_height high and skips 46 * gradient. It assumes the original gradient is src_height high and skips
46 * the first few rows. This is useful for drawing only the bottom half of 47 * the first few rows. This is useful for drawing only the bottom half of
@@ -107,47 +108,6 @@ void lcd_gradient_fillrect(int x, int y, int width, int height,
107 lcd_gradient_fillrect_part(x, y, width, height, start_rgb, end_rgb, height, 0); 108 lcd_gradient_fillrect_part(x, y, width, height, start_rgb, end_rgb, height, 0);
108} 109}
109 110
110/* Fill a text line with a gradient:
111 * x1, x2 - x pixel coordinates to start/stop
112 * y - y pixel to start from
113 * h - line height
114 * num_lines - number of lines to span the gradient over
115 * cur_line - current line being draw
116 */
117static void lcd_do_gradient_line(int x1, int x2, int y, unsigned h,
118 int num_lines, int cur_line)
119{
120 int step_mul;
121 if (h == 0) return;
122
123 num_lines *= h;
124 cur_line *= h;
125 step_mul = (1 << 16) / (num_lines);
126 int h_r = RGB_UNPACK_RED(current_vp->lss_pattern);
127 int h_g = RGB_UNPACK_GREEN(current_vp->lss_pattern);
128 int h_b = RGB_UNPACK_BLUE(current_vp->lss_pattern);
129 int rstep = (h_r - RGB_UNPACK_RED(current_vp->lse_pattern)) * step_mul;
130 int gstep = (h_g - RGB_UNPACK_GREEN(current_vp->lse_pattern)) * step_mul;
131 int bstep = (h_b - RGB_UNPACK_BLUE(current_vp->lse_pattern)) * step_mul;
132 unsigned start_rgb, end_rgb;
133 h_r = (h_r << 16) + (1 << 15);
134 h_g = (h_g << 16) + (1 << 15);
135 h_b = (h_b << 16) + (1 << 15);
136 if (cur_line)
137 {
138 h_r -= cur_line * rstep;
139 h_g -= cur_line * gstep;
140 h_b -= cur_line * bstep;
141 }
142 start_rgb = LCD_RGBPACK(h_r >> 16, h_g >> 16, h_b >> 16);
143
144 h_r -= h * rstep;
145 h_g -= h * gstep;
146 h_b -= h * bstep;
147 end_rgb = LCD_RGBPACK(h_r >> 16, h_g >> 16, h_b >> 16);
148 lcd_gradient_fillrect(x1, y, x2 - x1, h, start_rgb, end_rgb);
149}
150
151#endif 111#endif
152 112
153void LCDFN(set_framebuffer)(FBFN(data) *fb) 113void LCDFN(set_framebuffer)(FBFN(data) *fb)
@@ -368,6 +328,8 @@ static void LCDFN(putsxyofs)(int x, int y, int ofs, const unsigned char *str)
368 font_lock(current_vp->font, false); 328 font_lock(current_vp->font, false);
369} 329}
370 330
331/*** pixel oriented text output ***/
332
371/* put a string at a given pixel position */ 333/* put a string at a given pixel position */
372void LCDFN(putsxy)(int x, int y, const unsigned char *str) 334void LCDFN(putsxy)(int x, int y, const unsigned char *str)
373{ 335{
@@ -385,90 +347,14 @@ void LCDFN(putsxyf)(int x, int y, const unsigned char *fmt, ...)
385 LCDFN(putsxy)(x, y, buf); 347 LCDFN(putsxy)(x, y, buf);
386} 348}
387 349
388static void LCDFN(putsxyofs_style)(int xpos, int ypos,
389 const unsigned char *str, int style,
390 int offset)
391{
392 int lastmode = current_vp->drawmode;
393 int text_ypos = ypos;
394 int h = font_get(current_vp->font)->height;
395
396 if ((style & STYLE_MODE_MASK) == STYLE_NONE) {
397 if (str[0])
398 LCDFN(putsxyofs)(xpos, text_ypos, offset, str);
399 return;
400 }
401#if defined(MAIN_LCD) && defined(HAVE_LCD_COLOR)
402 int oldfgcolor = current_vp->fg_pattern;
403 int oldbgcolor = current_vp->bg_pattern;
404 current_vp->drawmode = DRMODE_SOLID | ((style & STYLE_INVERT) ?
405 DRMODE_INVERSEVID : 0);
406 if (style & STYLE_COLORED) {
407 if (current_vp->drawmode == DRMODE_SOLID)
408 current_vp->fg_pattern = style & STYLE_COLOR_MASK;
409 else
410 current_vp->bg_pattern = style & STYLE_COLOR_MASK;
411 }
412 current_vp->drawmode ^= DRMODE_INVERSEVID;
413 if (style & STYLE_GRADIENT) {
414 current_vp->drawmode = DRMODE_FG;
415 lcd_do_gradient_line(xpos, current_vp->width, ypos, h,
416 NUMLN_UNPACK(style), CURLN_UNPACK(style));
417 current_vp->fg_pattern = current_vp->lst_pattern;
418 }
419 else if (style & STYLE_COLORBAR) {
420 current_vp->drawmode = DRMODE_FG;
421 current_vp->fg_pattern = current_vp->lss_pattern;
422 lcd_fillrect(xpos, ypos, current_vp->width - xpos, h);
423 current_vp->fg_pattern = current_vp->lst_pattern;
424 }
425 else {
426 lcd_fillrect(xpos, ypos, current_vp->width - xpos, h);
427 current_vp->drawmode = (style & STYLE_INVERT) ?
428 (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID;
429 }
430 if (str[0])
431 lcd_putsxyofs(xpos, text_ypos, offset, str);
432 current_vp->fg_pattern = oldfgcolor;
433 current_vp->bg_pattern = oldbgcolor;
434#else
435 current_vp->drawmode = DRMODE_SOLID | ((style & STYLE_INVERT) ?
436 0 : DRMODE_INVERSEVID);
437 LCDFN(fillrect)(xpos, ypos, current_vp->width - xpos, h);
438 current_vp->drawmode ^= DRMODE_INVERSEVID;
439 if (str[0])
440 LCDFN(putsxyofs)(xpos, text_ypos, offset, str);
441#endif
442 current_vp->drawmode = lastmode;
443}
444
445/*** Line oriented text output ***/ 350/*** Line oriented text output ***/
446 351
447static void LCDFN(putsofs_style)(int x, int y, const unsigned char *str,
448 int style, int x_offset)
449{
450 int xpos, ypos, h;
451 if(!str)
452 return;
453
454 h = font_get(current_vp->font)->height;
455 if ((style&STYLE_XY_PIXELS) == 0)
456 {
457 xpos = x * LCDFN(getstringsize)(" ", NULL, NULL);
458 ypos = y * h;
459 }
460 else
461 {
462 xpos = x;
463 ypos = y;
464 }
465 LCDFN(scroll_stop_viewport_rect)(current_vp, xpos, ypos, current_vp->width - xpos, h);
466 LCDFN(putsxyofs_style)(xpos, ypos, str, style, x_offset);
467}
468
469void LCDFN(puts)(int x, int y, const unsigned char *str) 352void LCDFN(puts)(int x, int y, const unsigned char *str)
470{ 353{
471 LCDFN(putsofs_style)(x, y, str, STYLE_DEFAULT, 0); 354 int h;
355 x *= LCDFN(getstringsize)(" ", NULL, &h);
356 y *= h;
357 LCDFN(putsxyofs)(x, y, 0, str);
472} 358}
473 359
474/* Formatting version of LCDFN(puts) */ 360/* Formatting version of LCDFN(puts) */
@@ -500,11 +386,16 @@ static struct scrollinfo* find_scrolling_line(int x, int y)
500 386
501void LCDFN(scroll_fn)(struct scrollinfo* s) 387void LCDFN(scroll_fn)(struct scrollinfo* s)
502{ 388{
503 LCDFN(putsxyofs_style)(s->x, s->y, s->line, s->style, s->offset); 389 /* Fill with background/backdrop to clear area.
390 * cannot use clear_viewport_rect() since stops scrolling as well */
391 LCDFN(set_drawmode)(DRMODE_SOLID|DRMODE_INVERSEVID);
392 LCDFN(fillrect)(s->x, s->y, s->width, s->height);
393 LCDFN(set_drawmode)(DRMODE_SOLID);
394 LCDFN(putsxyofs)(s->x, s->y, s->offset, s->line);
504} 395}
505 396
506static void LCDFN(puts_scroll_worker)(int x, int y, const unsigned char *string, 397static void LCDFN(puts_scroll_worker)(int x, int y, const unsigned char *string,
507 int style, int x_offset, 398 int x_offset,
508 bool linebased, 399 bool linebased,
509 void (*scroll_func)(struct scrollinfo *), 400 void (*scroll_func)(struct scrollinfo *),
510 void *data) 401 void *data)
@@ -534,7 +425,7 @@ static void LCDFN(puts_scroll_worker)(int x, int y, const unsigned char *string,
534 if (restart) { 425 if (restart) {
535 /* remove any previously scrolling line at the same location */ 426 /* remove any previously scrolling line at the same location */
536 LCDFN(scroll_stop_viewport_rect)(current_vp, x, y, width, height); 427 LCDFN(scroll_stop_viewport_rect)(current_vp, x, y, width, height);
537 LCDFN(putsxyofs_style)(x, y, string, style, x_offset); 428 LCDFN(putsxyofs)(x, y, x_offset, string);
538 429
539 if (LCDFN(scroll_info).lines >= LCDM(SCROLLABLE_LINES)) 430 if (LCDFN(scroll_info).lines >= LCDM(SCROLLABLE_LINES))
540 return; 431 return;
@@ -570,7 +461,6 @@ static void LCDFN(puts_scroll_worker)(int x, int y, const unsigned char *string,
570 if (restart) { 461 if (restart) {
571 s->offset = x_offset; 462 s->offset = x_offset;
572 s->backward = false; 463 s->backward = false;
573 s->style = style;
574 /* assign the rectangle. not necessary if continuing an earlier line */ 464 /* assign the rectangle. not necessary if continuing an earlier line */
575 s->x = x; 465 s->x = x;
576 s->y = y; 466 s->y = y;
@@ -588,14 +478,12 @@ void LCDFN(putsxy_scroll_func)(int x, int y, const unsigned char *string,
588 if (!scroll_func) 478 if (!scroll_func)
589 LCDFN(putsxyofs)(x, y, x_offset, string); 479 LCDFN(putsxyofs)(x, y, x_offset, string);
590 else 480 else
591 LCDFN(puts_scroll_worker)(x, y, string, STYLE_NONE, x_offset, 481 LCDFN(puts_scroll_worker)(x, y, string, x_offset, false, scroll_func, data);
592 false, scroll_func, data);
593} 482}
594 483
595void LCDFN(puts_scroll)(int x, int y, const unsigned char *string) 484void LCDFN(puts_scroll)(int x, int y, const unsigned char *string)
596{ 485{
597 LCDFN(puts_scroll_worker)(x, y, string, STYLE_DEFAULT, 0, 486 LCDFN(puts_scroll_worker)(x, y, string, 0, true, LCDFN(scroll_fn), NULL);
598 true, LCDFN(scroll_fn), NULL);
599} 487}
600 488
601#if !defined(HAVE_LCD_COLOR) || !defined(MAIN_LCD) 489#if !defined(HAVE_LCD_COLOR) || !defined(MAIN_LCD)