summaryrefslogtreecommitdiff
path: root/apps/gui
diff options
context:
space:
mode:
Diffstat (limited to 'apps/gui')
-rw-r--r--apps/gui/splash.c187
1 files changed, 106 insertions, 81 deletions
diff --git a/apps/gui/splash.c b/apps/gui/splash.c
index f41d174881..0995968415 100644
--- a/apps/gui/splash.c
+++ b/apps/gui/splash.c
@@ -18,105 +18,123 @@
18 ****************************************************************************/ 18 ****************************************************************************/
19#include "stdarg.h" 19#include "stdarg.h"
20#include "string.h" 20#include "string.h"
21#include "rbunicode.h"
21#include "stdio.h" 22#include "stdio.h"
22#include "kernel.h" 23#include "kernel.h"
23#include "screen_access.h" 24#include "screen_access.h"
24 25
26#ifndef MAX
27#define MAX(a, b) (((a)>(b))?(a):(b))
28#endif
25 29
26#ifdef HAVE_LCD_BITMAP 30#ifdef HAVE_LCD_BITMAP
27 31
28#define MAXLETTERS 128 /* 16*8 */ 32#define MAXLINES (LCD_HEIGHT/6)
29#define MAXLINES 10 33#define MAXBUFFER 512
30 34
31#else 35#else /* HAVE_LCD_CHARCELLS */
32 36
33#define MAXLETTERS 22 /* 11 * 2 */ 37#define MAXLINES 2
34#define MAXLINES 2 38#define MAXBUFFER 64
35 39
36#endif 40#endif
37 41
38static void splash(struct screen * screen, 42static void splash(struct screen * screen, bool center,
39 bool center, const char *fmt, va_list ap) 43 const char *fmt, va_list ap)
40{ 44{
45 char splash_buf[MAXBUFFER];
46 short widths[MAXLINES];
47 char *lines[MAXLINES];
48
41 char *next; 49 char *next;
42 char *store=NULL; 50 char *lastbreak = NULL;
51 char *store = NULL;
52 int line = 0;
43 int x = 0; 53 int x = 0;
44 int w, h = 1; 54 int y, i;
45 unsigned char splash_buf[MAXLETTERS]; 55 int space_w, w, h;
46 unsigned short widths[MAXLINES];
47 unsigned char *text = splash_buf;
48 int line = 0, i_line = 0;
49 bool first=true;
50#ifdef HAVE_LCD_BITMAP 56#ifdef HAVE_LCD_BITMAP
51 int maxw=0; 57 int maxw = 0;
52 int space;
53 int y;
54 screen->getstringsize(" ", &space, &y);
55#if LCD_DEPTH > 1 58#if LCD_DEPTH > 1
56 unsigned prevbg = LCD_DEFAULT_BG; 59 unsigned prevbg = 0;
57 unsigned prevfg = LCD_DEFAULT_FG; 60 unsigned prevfg = 0;
58#endif 61#endif
59#else 62
60 screen->double_height (false); /* HAVE_LCD_CHARCELLS */ 63 screen->getstringsize(" ", &space_w, &h);
61 int space = 1; 64#else /* HAVE_LCD_CHARCELLS */
62 int y = 0; 65
66 space_w = h = 1;
67 screen->double_height (false);
63#endif 68#endif
64 screen->stop_scroll(); 69 y = h;
65 vsnprintf( splash_buf, sizeof(splash_buf), fmt, ap ); 70
66 va_end( ap ); 71 vsnprintf(splash_buf, sizeof(splash_buf), fmt, ap);
67 72 va_end(ap);
68 /* measure sizes & concatenates tokenise words into lines. */ 73
74 /* break splash string into display lines, doing proper word wrap */
75
69 next = strtok_r(splash_buf, " ", &store); 76 next = strtok_r(splash_buf, " ", &store);
70 while (next) { 77 if (!next)
78 return; /* nothing to display */
79
80 lines[0] = next;
81 while (true)
82 {
71#ifdef HAVE_LCD_BITMAP 83#ifdef HAVE_LCD_BITMAP
72 screen->getstringsize(next, &w, &h); 84 screen->getstringsize(next, &w, NULL);
73#else 85#else
74 w = strlen(next); 86 w = utf8length(next);
75 h = 1; /* store height in characters */
76#endif 87#endif
77 if(!first) { 88 if (lastbreak)
78 if(x + w > screen->width) { /* Too wide, wrap */ 89 {
79 y += h; 90 if (x + (next - lastbreak) * space_w + w > screen->width)
80 line++; 91 { /* too wide, wrap */
92 widths[line] = x;
93#ifdef HAVE_LCD_BITMAP
94 if (x > maxw)
95 maxw = x;
96#endif
97 if ((y + h > screen->height) || (line >= (MAXLINES-1)))
98 break; /* screen full or out of lines */
81 x = 0; 99 x = 0;
82 if((y > (screen->height-h)) || (line > screen->nb_lines)) 100 y += h;
83 /* STOP */ 101 lines[++line] = next;
84 break;
85 } 102 }
86 else 103 else
87 next[-1] = ' '; /* re-concatenate string */ 104 {
105 /* restore & calculate spacing */
106 *lastbreak = ' ';
107 x += (next - lastbreak) * space_w;
108 }
88 } 109 }
89 else 110 x += w;
90 first = false; 111 lastbreak = next + strlen(next);
91 112 next = strtok_r(NULL, " ", &store);
92 x += w + space; 113 if (!next)
93 widths[line] = x - space; /* don't count the trailing space */ 114 { /* no more words */
115 widths[line] = x;
94#ifdef HAVE_LCD_BITMAP 116#ifdef HAVE_LCD_BITMAP
95 /* store the widest line */ 117 if (x > maxw)
96 if(widths[line]>maxw) 118 maxw = x;
97 maxw = widths[line];
98#endif 119#endif
99 next = strtok_r(NULL, " ", &store); 120 break;
121 }
100 } 122 }
101 123
102 if(center) { 124 /* prepare screen */
103#ifdef HAVE_LCD_BITMAP
104 /* Start displaying the message at position y. */
105 y = (screen->height - y)/2;
106#else
107 y = 0; /* vertical center on 2 lines would be silly */
108#endif
109 } else
110 y = 0;
111 125
126 screen->stop_scroll();
127
128#ifdef HAVE_LCD_BITMAP
112 /* If we center the display, then just clear the box we need and put 129 /* If we center the display, then just clear the box we need and put
113 a nice little frame and put the text in there! */ 130 a nice little frame and put the text in there! */
114#ifdef HAVE_LCD_BITMAP 131 if (center)
115 if(center && (y > 2)) { 132 {
116 int xx = (screen->width - maxw)/2 - 2; 133 y = (screen->height - y) / 2; /* height => y start position */
117 /* The new graphics routines handle clipping, so no need to check */ 134 x = (screen->width - maxw) / 2 - 2;
118#if LCD_DEPTH > 1 135#if LCD_DEPTH > 1
119 if(screen->depth>1) { 136 if (screen->depth > 1)
137 {
120 prevbg = screen->get_background(); 138 prevbg = screen->get_background();
121 prevfg = screen->get_foreground(); 139 prevfg = screen->get_foreground();
122 screen->set_background(LCD_LIGHTGRAY); 140 screen->set_background(LCD_LIGHTGRAY);
@@ -124,33 +142,40 @@ static void splash(struct screen * screen,
124 } 142 }
125#endif 143#endif
126 screen->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); 144 screen->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
127 screen->fillrect(xx, y-2, maxw+4, screen->height-y*2+4); 145 screen->fillrect(x, y-2, maxw+4, screen->height-y*2+4);
128 screen->set_drawmode(DRMODE_SOLID); 146 screen->set_drawmode(DRMODE_SOLID);
129 screen->drawrect(xx, y-2, maxw+4, screen->height-y*2+4); 147 screen->drawrect(x, y-2, maxw+4, screen->height-y*2+4);
130 } 148 }
131 else 149 else
132#endif 150 {
151 y = 0;
152 x = 0;
133 screen->clear_display(); 153 screen->clear_display();
154 }
155#else /* HAVE_LCD_CHARCELLS */
156 y = 0; /* vertical center on 2 lines would be silly */
157 x = 0;
158 screen->clear_display();
159#endif
160
161 /* print the message to screen */
162
163 for (i = 0; i <= line; i++)
164 {
165 if (center)
166 x = MAX((screen->width - widths[i]) / 2, 0);
134 167
135 /* print the message to screen */
136 while(line-- >= 0) {
137 if (center) {
138 x = (screen->width-widths[i_line++])/2;
139 if(x < 0)
140 x = 0;
141 } else
142 x = 0;
143#ifdef HAVE_LCD_BITMAP 168#ifdef HAVE_LCD_BITMAP
144 screen->putsxy(x, y, text); 169 screen->putsxy(x, y, lines[i]);
145#else 170#else
146 screen->puts(x, y, text); 171 screen->puts(x, y, lines[i]);
147#endif 172#endif
148 text += strlen(text) + 1; 173 y += h;
149 y +=h; 174 }
150 }
151 175
152#if defined(HAVE_LCD_BITMAP) && (LCD_DEPTH > 1) 176#if defined(HAVE_LCD_BITMAP) && (LCD_DEPTH > 1)
153 if(screen->depth > 1) { 177 if (center && (screen->depth > 1))
178 {
154 screen->set_background(prevbg); 179 screen->set_background(prevbg);
155 screen->set_foreground(prevfg); 180 screen->set_foreground(prevfg);
156 } 181 }