diff options
Diffstat (limited to 'firmware/drivers/lcd-bitmap-common.c')
-rw-r--r-- | firmware/drivers/lcd-bitmap-common.c | 146 |
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 | */ | ||
117 | static 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 | ||
153 | void LCDFN(set_framebuffer)(FBFN(data) *fb) | 113 | void 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 */ |
372 | void LCDFN(putsxy)(int x, int y, const unsigned char *str) | 334 | void 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 | ||
388 | static 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 | ||
447 | static 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 | |||
469 | void LCDFN(puts)(int x, int y, const unsigned char *str) | 352 | void 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 | ||
501 | void LCDFN(scroll_fn)(struct scrollinfo* s) | 387 | void 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 | ||
506 | static void LCDFN(puts_scroll_worker)(int x, int y, const unsigned char *string, | 397 | static 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 | ||
595 | void LCDFN(puts_scroll)(int x, int y, const unsigned char *string) | 484 | void 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) |