1
0
Fork 0
forked from len0rd/rockbox

Improved code for the splash function: spare some calculation, fix a bug for screens wider then 255 (ipod 5g), fix FS#5775 by displaying complete lines instead of word by word.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11113 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Shachar Liberman 2006-10-02 23:54:28 +00:00
parent c9d7f76ae5
commit f5452c0bde

View file

@ -25,13 +25,11 @@
#ifdef HAVE_LCD_BITMAP #ifdef HAVE_LCD_BITMAP
#define SPACE 3 /* pixels between words */
#define MAXLETTERS 128 /* 16*8 */ #define MAXLETTERS 128 /* 16*8 */
#define MAXLINES 10 #define MAXLINES 10
#else #else
#define SPACE 1 /* one letter space */
#define MAXLETTERS 22 /* 11 * 2 */ #define MAXLETTERS 22 /* 11 * 2 */
#define MAXLINES 2 #define MAXLINES 2
@ -42,93 +40,80 @@ static void splash(struct screen * screen,
{ {
char *next; char *next;
char *store=NULL; char *store=NULL;
int x=0; int x = 0;
int y=0;
int w, h; int w, h;
unsigned char splash_buf[MAXLETTERS]; unsigned char splash_buf[MAXLETTERS];
unsigned char widths[MAXLINES]; unsigned short widths[MAXLINES];
int line=0; unsigned char *text = splash_buf;
int line = 0, i_line = 0;
bool first=true; bool first=true;
#ifdef HAVE_LCD_BITMAP #ifdef HAVE_LCD_BITMAP
int maxw=0; int maxw=0;
int space;
int y;
screen->getstringsize(" ", &space, &y);
#if LCD_DEPTH > 1 #if LCD_DEPTH > 1
unsigned prevbg = LCD_DEFAULT_BG; unsigned prevbg = LCD_DEFAULT_BG;
unsigned prevfg = LCD_DEFAULT_FG; unsigned prevfg = LCD_DEFAULT_FG;
#endif #endif
#endif #else
screen->double_height (false); /* HAVE_LCD_CHARCELLS */
#ifdef HAVE_LCD_CHARCELLS int space = 1;
screen->double_height (false); int y = 0;
#endif #endif
screen->stop_scroll(); screen->stop_scroll();
vsnprintf( splash_buf, sizeof(splash_buf), fmt, ap ); vsnprintf( splash_buf, sizeof(splash_buf), fmt, ap );
va_end( ap );
if(center) {
/* first a pass to measure sizes */ /* measure sizes & concatenates tokenise words into lines. */
next = strtok_r(splash_buf, " ", &store); next = strtok_r(splash_buf, " ", &store);
while (next) { while (next) {
#ifdef HAVE_LCD_BITMAP #ifdef HAVE_LCD_BITMAP
screen->getstringsize(next, &w, &h); screen->getstringsize(next, &w, &h);
#else #else
w = strlen(next); w = strlen(next);
h = 1; /* store height in characters */ h = 1; /* store height in characters */
#endif #endif
if(!first) { if(!first) {
if(x+w> screen->width) { if(x + w > screen->width) { /* Too wide, wrap */
/* Too wide, wrap */ y += h;
y+=h; line++;
line++; x = 0;
if((y > (screen->height-h)) || (line > screen->nb_lines)) if((y > (screen->height-h)) || (line > screen->nb_lines))
/* STOP */ /* STOP */
break; break;
x=0;
first=true;
}
} }
else else
first = false; next[-1] = ' '; /* re-concatenate string */
/* think of it as if the text was written here at position x,y
being w pixels/chars wide and h high */
x += w+SPACE;
widths[line]=x-SPACE; /* don't count the trailing space */
#ifdef HAVE_LCD_BITMAP
/* store the widest line */
if(widths[line]>maxw)
maxw = widths[line];
#endif
next = strtok_r(NULL, " ", &store);
} }
else
first = false;
x += w + space;
widths[line] = x - space; /* don't count the trailing space */
#ifdef HAVE_LCD_BITMAP #ifdef HAVE_LCD_BITMAP
/* Start displaying the message at position y. The reason for the /* store the widest line */
added h here is that it isn't added until the end of lines in the if(widths[line]>maxw)
loop above and we always break the loop in the middle of a line. */ maxw = widths[line];
y = (screen->height - (y+h) )/2; #endif
next = strtok_r(NULL, " ", &store);
}
if(center) {
#ifdef HAVE_LCD_BITMAP
/* Start displaying the message at position y. */
y = (screen->height - y)/2;
#else #else
y = 0; /* vertical center on 2 lines would be silly */ y = 0; /* vertical center on 2 lines would be silly */
#endif #endif
first=true; } else
y = 0;
/* Now recreate the string again since the strtok_r() above has ruined
the one we already have! Here's room for improvements! */
vsnprintf( splash_buf, sizeof(splash_buf), fmt, ap );
}
va_end( ap );
if(center)
{
x = (screen->width-widths[0])/2;
if(x < 0)
x = 0;
}
#ifdef HAVE_LCD_BITMAP
/* If we center the display, then just clear the box we need and put /* If we center the display, then just clear the box we need and put
a nice little frame and put the text in there! */ a nice little frame and put the text in there! */
#ifdef HAVE_LCD_BITMAP
if(center && (y > 2)) { if(center && (y > 2)) {
int xx = (screen->width-maxw)/2 - 2; int xx = (screen->width - maxw)/2 - 2;
/* The new graphics routines handle clipping, so no need to check */ /* The new graphics routines handle clipping, so no need to check */
#if LCD_DEPTH > 1 #if LCD_DEPTH > 1
if(screen->depth>1) { if(screen->depth>1) {
@ -146,43 +131,23 @@ static void splash(struct screen * screen,
else else
#endif #endif
screen->clear_display(); screen->clear_display();
line=0;
next = strtok_r(splash_buf, " ", &store); /* print the message to screen */
while (next) { while(line-- >= 0) {
if (center) {
x = (screen->width-widths[i_line++])/2;
if(x < 0)
x = 0;
} else
x = 0;
#ifdef HAVE_LCD_BITMAP #ifdef HAVE_LCD_BITMAP
screen->getstringsize(next, &w, &h); screen->putsxy(x, y, text);
#else #else
w = strlen(next); screen->puts(x, y, text);
h = 1;
#endif #endif
if(!first) { text += strlen(text) + 1;
if(x+w> screen->width) { y +=h;
/* too wide */
y+=h;
line++; /* goto next line */
first=true;
if(y > (screen->height-h))
/* STOP */
break;
if(center) {
x = (screen->width-widths[line])/2;
if(x < 0)
x = 0;
}
else
x=0;
}
} }
else
first=false;
#ifdef HAVE_LCD_BITMAP
screen->putsxy(x, y, next);
#else
screen->puts(x, y, next);
#endif
x += w+SPACE; /* pixels space! */
next = strtok_r(NULL, " ", &store);
}
#if defined(HAVE_LCD_BITMAP) && (LCD_DEPTH > 1) #if defined(HAVE_LCD_BITMAP) && (LCD_DEPTH > 1)
if(screen->depth > 1) { if(screen->depth > 1) {