diff options
Diffstat (limited to 'apps/gui/splash.c')
-rw-r--r-- | apps/gui/splash.c | 57 |
1 files changed, 33 insertions, 24 deletions
diff --git a/apps/gui/splash.c b/apps/gui/splash.c index efb4b1cda2..3f361f5a04 100644 --- a/apps/gui/splash.c +++ b/apps/gui/splash.c | |||
@@ -29,8 +29,9 @@ | |||
29 | #include "talk.h" | 29 | #include "talk.h" |
30 | #include "splash.h" | 30 | #include "splash.h" |
31 | #include "viewport.h" | 31 | #include "viewport.h" |
32 | #include "strtok_r.h" | 32 | #include "strptokspn_r.h" |
33 | #include "scrollbar.h" | 33 | #include "scrollbar.h" |
34 | #include "font.h" | ||
34 | 35 | ||
35 | static long progress_next_tick = 0; | 36 | static long progress_next_tick = 0; |
36 | 37 | ||
@@ -43,57 +44,68 @@ static bool splash_internal(struct screen * screen, const char *fmt, va_list ap, | |||
43 | struct viewport *vp, int addl_lines) | 44 | struct viewport *vp, int addl_lines) |
44 | { | 45 | { |
45 | char splash_buf[MAXBUFFER]; | 46 | char splash_buf[MAXBUFFER]; |
46 | char *lines[MAXLINES]; | 47 | struct splash_lines { |
48 | const char *str; | ||
49 | size_t len; | ||
50 | } lines[MAXLINES]; | ||
47 | char *next; | 51 | char *next; |
48 | char *lastbreak = NULL; | 52 | char *lastbreak = NULL; |
49 | char *store = NULL; | 53 | char *store = NULL; |
50 | int line = 0; | 54 | int line = 0; |
51 | int x = 0; | 55 | int x = 0; |
52 | int y, i; | 56 | int y, i; |
53 | int space_w, w, h; | 57 | int space_w, w, chr_h; |
54 | int width, height; | 58 | int width, height; |
55 | int maxw = 0; | 59 | int maxw = 0; |
60 | int fontnum = vp->font; | ||
56 | 61 | ||
57 | screen->getstringsize(" ", &space_w, &h); | 62 | char lastbrkchr; |
58 | y = h + (addl_lines * h); | 63 | size_t len, next_len; |
64 | const char matchstr[] = "\r\n\f\v\t "; | ||
65 | font_getstringsize(" ", &space_w, &chr_h, fontnum); | ||
66 | y = chr_h + (addl_lines * chr_h); | ||
59 | 67 | ||
60 | vsnprintf(splash_buf, sizeof(splash_buf), fmt, ap); | 68 | vsnprintf(splash_buf, sizeof(splash_buf), fmt, ap); |
61 | va_end(ap); | 69 | va_end(ap); |
62 | 70 | ||
63 | /* break splash string into display lines, doing proper word wrap */ | 71 | /* break splash string into display lines, doing proper word wrap */ |
64 | 72 | next = strptokspn_r(splash_buf, matchstr, &next_len, &store); | |
65 | next = strtok_r(splash_buf, " ", &store); | ||
66 | if (!next) | 73 | if (!next) |
67 | return false; /* nothing to display */ | 74 | return false; /* nothing to display */ |
68 | 75 | ||
69 | lines[0] = next; | 76 | lines[line].len = next_len + 1; |
77 | lines[line].str = next; | ||
70 | while (true) | 78 | while (true) |
71 | { | 79 | { |
72 | screen->getstringsize(next, &w, NULL); | 80 | w = font_getstringnsize(next, next_len + 1, NULL, NULL, fontnum); |
73 | if (lastbreak) | 81 | if (lastbreak) |
74 | { | 82 | { |
75 | int next_w = (next - lastbreak) * space_w; | 83 | len = next - lastbreak; |
76 | 84 | int next_w = len * space_w; | |
77 | if (x + next_w + w > vp->width - RECT_SPACING*2) | 85 | if (x + next_w + w > vp->width - RECT_SPACING*2 || lastbrkchr != ' ') |
78 | { /* too wide, wrap */ | 86 | { /* too wide, or control character wrap */ |
79 | if (x > maxw) | 87 | if (x > maxw) |
80 | maxw = x; | 88 | maxw = x; |
81 | if ((y + h > vp->height) || (line >= (MAXLINES-1))) | 89 | if ((y + chr_h * 2 > vp->height) || (line >= (MAXLINES-1))) |
82 | break; /* screen full or out of lines */ | 90 | break; /* screen full or out of lines */ |
83 | x = 0; | 91 | x = 0; |
84 | y += h; | 92 | y += chr_h; |
85 | lines[++line] = next; | 93 | lines[++line].len = next_len + len; |
94 | lines[line].str = next; | ||
86 | } | 95 | } |
87 | else | 96 | else |
88 | { | 97 | { |
89 | /* restore & calculate spacing */ | 98 | /* restore & calculate spacing */ |
90 | *lastbreak = ' '; | 99 | lines[line].len += next_len + len + 1; |
91 | x += next_w; | 100 | x += next_w; |
92 | } | 101 | } |
93 | } | 102 | } |
94 | x += w; | 103 | x += w; |
95 | lastbreak = next + strlen(next); | 104 | lastbreak = next + next_len + 1; |
96 | next = strtok_r(NULL, " ", &store); | 105 | lastbrkchr = *lastbreak; |
106 | |||
107 | next = strptokspn_r(NULL, matchstr, &next_len, &store); | ||
108 | |||
97 | if (!next) | 109 | if (!next) |
98 | { /* no more words */ | 110 | { /* no more words */ |
99 | if (x > maxw) | 111 | if (x > maxw) |
@@ -147,13 +159,10 @@ static bool splash_internal(struct screen * screen, const char *fmt, va_list ap, | |||
147 | 159 | ||
148 | screen->draw_border_viewport(); | 160 | screen->draw_border_viewport(); |
149 | 161 | ||
150 | /* prepare putting the text */ | ||
151 | y = RECT_SPACING; | ||
152 | |||
153 | /* print the message to screen */ | 162 | /* print the message to screen */ |
154 | for (i = 0; i <= line; i++, y+=h) | 163 | for(i = 0, y = RECT_SPACING; i <= line; i++, y+= chr_h) |
155 | { | 164 | { |
156 | screen->putsxy(0, y, lines[i]); | 165 | screen->putsxyf(0, y, "%.*s", lines[i].len, lines[i].str); |
157 | } | 166 | } |
158 | return true; /* needs update */ | 167 | return true; /* needs update */ |
159 | } | 168 | } |