diff options
-rw-r--r-- | apps/gui/line.c | 3 | ||||
-rw-r--r-- | apps/gui/line.h | 24 | ||||
-rw-r--r-- | firmware/drivers/lcd-bitmap-common.c | 146 | ||||
-rw-r--r-- | firmware/export/lcd.h | 21 | ||||
-rw-r--r-- | firmware/export/scroll_engine.h | 3 |
5 files changed, 41 insertions, 156 deletions
diff --git a/apps/gui/line.c b/apps/gui/line.c index 9374279b60..3d563d171c 100644 --- a/apps/gui/line.c +++ b/apps/gui/line.c | |||
@@ -264,7 +264,6 @@ static void style_line(struct screen *display, | |||
264 | int style = line->style; | 264 | int style = line->style; |
265 | int width = display->getwidth(); | 265 | int width = display->getwidth(); |
266 | int height = line->height == -1 ? display->getcharheight() : line->height; | 266 | int height = line->height == -1 ? display->getcharheight() : line->height; |
267 | unsigned mask = STYLE_MODE_MASK & ~STYLE_COLORED; | ||
268 | 267 | ||
269 | /* mask out gradient and colorbar styles for non-color displays */ | 268 | /* mask out gradient and colorbar styles for non-color displays */ |
270 | if (display->depth < 16) | 269 | if (display->depth < 16) |
@@ -277,7 +276,7 @@ static void style_line(struct screen *display, | |||
277 | style &= ~STYLE_COLORED; | 276 | style &= ~STYLE_COLORED; |
278 | } | 277 | } |
279 | 278 | ||
280 | switch (style & mask) | 279 | switch (style & _STYLE_DECO_MASK) |
281 | { | 280 | { |
282 | #if (LCD_DEPTH > 1 || (defined(LCD_REMOTE_DEPTH) && LCD_REMOTE_DEPTH > 1)) | 281 | #if (LCD_DEPTH > 1 || (defined(LCD_REMOTE_DEPTH) && LCD_REMOTE_DEPTH > 1)) |
283 | case STYLE_GRADIENT: | 282 | case STYLE_GRADIENT: |
diff --git a/apps/gui/line.h b/apps/gui/line.h index d5350eb410..fa1522003c 100644 --- a/apps/gui/line.h +++ b/apps/gui/line.h | |||
@@ -29,6 +29,28 @@ | |||
29 | #include "lcd.h" | 29 | #include "lcd.h" |
30 | #include "screens.h" | 30 | #include "screens.h" |
31 | 31 | ||
32 | /* Possible line decoration styles. Specify one of | ||
33 | * STYLE_NONE, _DEFAULT, _INVERT, _COLORBAR or _GRADIENT, and optionally | ||
34 | * or with STYLE_COLORED specifying line_desc.text_color */ | ||
35 | enum line_styles { | ||
36 | /* Just print the text. Do not clear or draw line decorations */ | ||
37 | STYLE_NONE = 0x00, | ||
38 | /* Line background filled with the bg color (or backdrop if present) */ | ||
39 | STYLE_DEFAULT = 0x01, | ||
40 | /* Like STYLE_DFEAULT except that text and background color will be swapped */ | ||
41 | STYLE_INVERT = 0x02, | ||
42 | /* Line background filled with line color line_desc.line_color */ | ||
43 | STYLE_COLORBAR = 0x04, | ||
44 | /* Line background filled with gradient, colors taken from | ||
45 | * line_desc.line_color and line_desc.line_end_color */ | ||
46 | STYLE_GRADIENT = 0x08, | ||
47 | /* Modifier for the text color, which will be taken from line_desc.text_color */ | ||
48 | STYLE_COLORED = 0x10, | ||
49 | /* These are used internally */ | ||
50 | _STYLE_DECO_MASK = 0x0f, | ||
51 | _STYLE_MODE_MASK = 0x7F, | ||
52 | }; | ||
53 | |||
32 | struct line_desc { | 54 | struct line_desc { |
33 | /* height of the line (in pixels). -1 to inherit the height | 55 | /* height of the line (in pixels). -1 to inherit the height |
34 | * from the font. The text will be centered if the height is larger, | 56 | * from the font. The text will be centered if the height is larger, |
@@ -49,7 +71,7 @@ struct line_desc { | |||
49 | * lcd format (convert with LCD_RGBPACK() if necessary) */ | 71 | * lcd format (convert with LCD_RGBPACK() if necessary) */ |
50 | fb_data line_color, line_end_color; | 72 | fb_data line_color, line_end_color; |
51 | /* line decorations, see STYLE_DEFAULT etc. */ | 73 | /* line decorations, see STYLE_DEFAULT etc. */ |
52 | int style; | 74 | enum line_styles style; |
53 | /* whether the line can scroll */ | 75 | /* whether the line can scroll */ |
54 | bool scroll; | 76 | bool scroll; |
55 | }; | 77 | }; |
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) |
diff --git a/firmware/export/lcd.h b/firmware/export/lcd.h index bdeddf0b52..e7a75e893a 100644 --- a/firmware/export/lcd.h +++ b/firmware/export/lcd.h | |||
@@ -120,27 +120,6 @@ struct scrollinfo; | |||
120 | #define STRIDE(screen, w, h) (screen==SCREEN_MAIN?STRIDE_MAIN((w), \ | 120 | #define STRIDE(screen, w, h) (screen==SCREEN_MAIN?STRIDE_MAIN((w), \ |
121 | (h)):STRIDE_REMOTE((w),(h))) | 121 | (h)):STRIDE_REMOTE((w),(h))) |
122 | 122 | ||
123 | #define STYLE_NONE 0x00000000 | ||
124 | #define STYLE_DEFAULT 0x01000000 | ||
125 | #define STYLE_COLORED 0x02000000 | ||
126 | #define STYLE_INVERT 0x04000000 | ||
127 | #define STYLE_COLORBAR 0x08000000 | ||
128 | #define STYLE_GRADIENT 0x10000000 | ||
129 | #define STYLE_MODE_MASK 0xFF000000 | ||
130 | /* HACK: This isnt really a style, We need to be able to tell some of | ||
131 | * the lcd API that we want to draw text to a specific pixel instead | ||
132 | * of a char. Remove this hack when the whole LCD api goes to fully | ||
133 | * pixel based positioning - jdgordon */ | ||
134 | #define STYLE_XY_PIXELS 0x00010000 | ||
135 | #define STYLE_COLOR_MASK 0x0000FFFF | ||
136 | #ifdef HAVE_LCD_COLOR | ||
137 | #define STYLE_CURLN_MASK 0x0000FF00 | ||
138 | #define STYLE_MAXLN_MASK 0x000000FF | ||
139 | #define CURLN_PACK(x) (((x)<<8) & STYLE_CURLN_MASK) | ||
140 | #define CURLN_UNPACK(x) ((unsigned char)(((x)&STYLE_CURLN_MASK) >> 8)) | ||
141 | #define NUMLN_PACK(x) ((x) & STYLE_MAXLN_MASK) | ||
142 | #define NUMLN_UNPACK(x) ((unsigned char)((x) & STYLE_MAXLN_MASK)) | ||
143 | #endif | ||
144 | 123 | ||
145 | #ifdef HAVE_LCD_BITMAP | 124 | #ifdef HAVE_LCD_BITMAP |
146 | #if LCD_DEPTH <=8 | 125 | #if LCD_DEPTH <=8 |
diff --git a/firmware/export/scroll_engine.h b/firmware/export/scroll_engine.h index e3fd720550..19a2bc4cca 100644 --- a/firmware/export/scroll_engine.h +++ b/firmware/export/scroll_engine.h | |||
@@ -69,9 +69,6 @@ struct scrollinfo | |||
69 | int width, height; | 69 | int width, height; |
70 | /* pixel to skip from the beginning of the string, increments as the text scrolls */ | 70 | /* pixel to skip from the beginning of the string, increments as the text scrolls */ |
71 | int offset; | 71 | int offset; |
72 | #ifdef HAVE_LCD_BITMAP | ||
73 | int style; /* line style */ | ||
74 | #endif /* HAVE_LCD_BITMAP */ | ||
75 | /* scroll presently forward or backward? */ | 72 | /* scroll presently forward or backward? */ |
76 | bool backward; | 73 | bool backward; |
77 | bool bidir; | 74 | bool bidir; |