1
0
Fork 0
forked from len0rd/rockbox

Fix charcell %pb and %pf tags, FS#11592

This also moves draw_player_fullbar() and draw_player_progress() from skin_display.c to skin_tokens.c. Charcell is a bit different from bitmap here because drawing a progress bar is a combination of setting up the LCD controller (custom characters) and providing a format string. The custom character definition might fit in skin_display.c, but the format strings are needed in skin_tokens.c. Putting these functions in skin_tokens.c seemed to fit better.


git-svn-id: svn://svn.rockbox.org/rockbox/trunk@28241 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Frank Gevaerts 2010-10-10 23:46:15 +00:00
parent 5462ef728f
commit 1f0ab7c9e6
4 changed files with 154 additions and 157 deletions

View file

@ -349,149 +349,7 @@ void wps_display_images(struct gui_wps *gwps, struct viewport* vp)
display->set_drawmode(DRMODE_SOLID);
}
#else /* HAVE_LCD_CHARCELL */
bool draw_player_progress(struct gui_wps *gwps)
{
struct wps_state *state = skin_get_global_state();
struct screen *display = gwps->display;
unsigned char progress_pattern[7];
int pos = 0;
int i;
int elapsed, length;
if (LIKELY(state->id3))
{
elapsed = state->id3->elapsed;
length = state->id3->length;
}
else
{
elapsed = 0;
length = 0;
}
if (length)
pos = 36 * (elapsed + state->ff_rewind_count) / length;
for (i = 0; i < 7; i++, pos -= 5)
{
if (pos <= 0)
progress_pattern[i] = 0x1fu;
else if (pos >= 5)
progress_pattern[i] = 0x00u;
else
progress_pattern[i] = 0x1fu >> pos;
}
display->define_pattern(gwps->data->wps_progress_pat[0], progress_pattern);
return true;
}
void draw_player_fullbar(struct gui_wps *gwps, char* buf, int buf_size)
{
static const unsigned char numbers[10][4] = {
{0x0e, 0x0a, 0x0a, 0x0e}, /* 0 */
{0x04, 0x0c, 0x04, 0x04}, /* 1 */
{0x0e, 0x02, 0x04, 0x0e}, /* 2 */
{0x0e, 0x02, 0x06, 0x0e}, /* 3 */
{0x08, 0x0c, 0x0e, 0x04}, /* 4 */
{0x0e, 0x0c, 0x02, 0x0c}, /* 5 */
{0x0e, 0x08, 0x0e, 0x0e}, /* 6 */
{0x0e, 0x02, 0x04, 0x08}, /* 7 */
{0x0e, 0x0e, 0x0a, 0x0e}, /* 8 */
{0x0e, 0x0e, 0x02, 0x0e}, /* 9 */
};
struct wps_state *state = skin_get_global_state();
struct screen *display = gwps->display;
struct wps_data *data = gwps->data;
unsigned char progress_pattern[7];
char timestr[10];
int time;
int time_idx = 0;
int pos = 0;
int pat_idx = 1;
int digit, i, j;
bool softchar;
int elapsed, length;
if (LIKELY(state->id3))
{
elapsed = state->id3->elapsed;
length = state->id3->length;
}
else
{
elapsed = 0;
length = 0;
}
if (buf_size < 34) /* worst case: 11x UTF-8 char + \0 */
return;
time = elapsed + state->ff_rewind_count;
if (length)
pos = 55 * time / length;
memset(timestr, 0, sizeof(timestr));
format_time(timestr, sizeof(timestr)-2, time);
timestr[strlen(timestr)] = ':'; /* always safe */
for (i = 0; i < 11; i++, pos -= 5)
{
softchar = false;
memset(progress_pattern, 0, sizeof(progress_pattern));
if ((digit = timestr[time_idx]))
{
softchar = true;
digit -= '0';
if (timestr[time_idx + 1] == ':') /* ones, left aligned */
{
memcpy(progress_pattern, numbers[digit], 4);
time_idx += 2;
}
else /* tens, shifted right */
{
for (j = 0; j < 4; j++)
progress_pattern[j] = numbers[digit][j] >> 1;
if (time_idx > 0) /* not the first group, add colon in front */
{
progress_pattern[1] |= 0x10u;
progress_pattern[3] |= 0x10u;
}
time_idx++;
}
if (pos >= 5)
progress_pattern[5] = progress_pattern[6] = 0x1fu;
}
if (pos > 0 && pos < 5)
{
softchar = true;
progress_pattern[5] = progress_pattern[6] = (~0x1fu >> pos) & 0x1fu;
}
if (softchar && pat_idx < 8)
{
display->define_pattern(data->wps_progress_pat[pat_idx],
progress_pattern);
buf = utf8encode(data->wps_progress_pat[pat_idx], buf);
pat_idx++;
}
else if (pos <= 0)
buf = utf8encode(' ', buf);
else
buf = utf8encode(0xe115, buf); /* 2/7 _ */
}
*buf = '\0';
}
#endif /* HAVE_LCD_CHARCELL */
#endif /* HAVE_LCD_BITMAP */
/* Evaluate the conditional that is at *token_index and return whether a skip
has ocurred. *token_index is updated with the new position.

View file

@ -36,9 +36,6 @@ void draw_playlist_viewer_list(struct gui_wps *gwps, struct playlistviewer *view
void clear_image_pos(struct gui_wps *gwps, struct gui_img *img);
void wps_draw_image(struct gui_wps *gwps, struct gui_img *img, int subimage);
void wps_display_images(struct gui_wps *gwps, struct viewport* vp);
#else
bool draw_player_progress(struct gui_wps *gwps);
void draw_player_fullbar(struct gui_wps *gwps, char* buf, int buf_size);
#endif
/* Evaluate the conditional that is at *token_index and return whether a skip

View file

@ -83,10 +83,14 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
{
#ifndef HAVE_LCD_BITMAP
(void)vp; /* silence warnings */
(void)info;
#endif
struct wps_token *token = (struct wps_token *)element->data;
#ifdef HAVE_LCD_BITMAP
struct wps_data *data = gwps->data;
bool do_refresh = (element->tag->flags & info->refresh_type) > 0;
#endif
switch (token->type)
{
#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1))
@ -137,22 +141,14 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
#endif
case SKIN_TOKEN_VOLUMEBAR:
case SKIN_TOKEN_BATTERY_PERCENTBAR:
#ifdef HAVE_LCD_BITMAP
case SKIN_TOKEN_PROGRESSBAR:
{
#ifdef HAVE_LCD_BITMAP
struct progressbar *bar = (struct progressbar*)token->value.data;
if (do_refresh)
draw_progressbar(gwps, info->line_number, bar);
#else /* HAVE_LCD_CHARCELL */
if (do_refresh)
{
if (data->full_line_progressbar)
draw_player_fullbar(gwps, info->buf, info->buf_size);
else
draw_player_progress(gwps);
}
#endif
}
break;
#ifdef HAVE_LCD_BITMAP
case SKIN_TOKEN_IMAGE_DISPLAY_LISTICON:

View file

@ -554,6 +554,148 @@ static struct mp3entry* get_mp3entry_from_offset(int offset, char **filename)
return pid3;
}
#ifdef HAVE_LCD_CHARCELLS
void format_player_progress(struct gui_wps *gwps)
{
struct wps_state *state = skin_get_global_state();
struct screen *display = gwps->display;
unsigned char progress_pattern[7];
int pos = 0;
int i;
int elapsed, length;
if (LIKELY(state->id3))
{
elapsed = state->id3->elapsed;
length = state->id3->length;
}
else
{
elapsed = 0;
length = 0;
}
if (length)
pos = 36 * (elapsed + state->ff_rewind_count) / length;
for (i = 0; i < 7; i++, pos -= 5)
{
if (pos <= 0)
progress_pattern[i] = 0x1fu;
else if (pos >= 5)
progress_pattern[i] = 0x00u;
else
progress_pattern[i] = 0x1fu >> pos;
}
display->define_pattern(gwps->data->wps_progress_pat[0], progress_pattern);
}
void format_player_fullbar(struct gui_wps *gwps, char* buf, int buf_size)
{
static const unsigned char numbers[10][4] = {
{0x0e, 0x0a, 0x0a, 0x0e}, /* 0 */
{0x04, 0x0c, 0x04, 0x04}, /* 1 */
{0x0e, 0x02, 0x04, 0x0e}, /* 2 */
{0x0e, 0x02, 0x06, 0x0e}, /* 3 */
{0x08, 0x0c, 0x0e, 0x04}, /* 4 */
{0x0e, 0x0c, 0x02, 0x0c}, /* 5 */
{0x0e, 0x08, 0x0e, 0x0e}, /* 6 */
{0x0e, 0x02, 0x04, 0x08}, /* 7 */
{0x0e, 0x0e, 0x0a, 0x0e}, /* 8 */
{0x0e, 0x0e, 0x02, 0x0e}, /* 9 */
};
struct wps_state *state = skin_get_global_state();
struct screen *display = gwps->display;
struct wps_data *data = gwps->data;
unsigned char progress_pattern[7];
char timestr[10];
int time;
int time_idx = 0;
int pos = 0;
int pat_idx = 1;
int digit, i, j;
bool softchar;
int elapsed, length;
if (LIKELY(state->id3))
{
elapsed = state->id3->elapsed;
length = state->id3->length;
}
else
{
elapsed = 0;
length = 0;
}
if (buf_size < 34) /* worst case: 11x UTF-8 char + \0 */
return;
time = elapsed + state->ff_rewind_count;
if (length)
pos = 55 * time / length;
memset(timestr, 0, sizeof(timestr));
format_time(timestr, sizeof(timestr)-2, time);
timestr[strlen(timestr)] = ':'; /* always safe */
for (i = 0; i < 11; i++, pos -= 5)
{
softchar = false;
memset(progress_pattern, 0, sizeof(progress_pattern));
if ((digit = timestr[time_idx]))
{
softchar = true;
digit -= '0';
if (timestr[time_idx + 1] == ':') /* ones, left aligned */
{
memcpy(progress_pattern, numbers[digit], 4);
time_idx += 2;
}
else /* tens, shifted right */
{
for (j = 0; j < 4; j++)
progress_pattern[j] = numbers[digit][j] >> 1;
if (time_idx > 0) /* not the first group, add colon in front */
{
progress_pattern[1] |= 0x10u;
progress_pattern[3] |= 0x10u;
}
time_idx++;
}
if (pos >= 5)
progress_pattern[5] = progress_pattern[6] = 0x1fu;
}
if (pos > 0 && pos < 5)
{
softchar = true;
progress_pattern[5] = progress_pattern[6] = (~0x1fu >> pos) & 0x1fu;
}
if (softchar && pat_idx < 8)
{
display->define_pattern(data->wps_progress_pat[pat_idx],
progress_pattern);
buf = utf8encode(data->wps_progress_pat[pat_idx], buf);
pat_idx++;
}
else if (pos <= 0)
buf = utf8encode(' ', buf);
else
buf = utf8encode(0xe115, buf); /* 2/7 _ */
}
*buf = '\0';
}
#endif /* HAVE_LCD_CHARCELLS */
/* Don't inline this; it was broken out of get_token_value to reduce stack
* usage.
*/
@ -1075,7 +1217,9 @@ const char *get_token_value(struct gui_wps *gwps,
#ifdef HAVE_LCD_CHARCELLS
case SKIN_TOKEN_PROGRESSBAR:
{
char *end = utf8encode(data->wps_progress_pat[0], buf);
char *end;
format_player_progress(gwps);
end = utf8encode(data->wps_progress_pat[0], buf);
*end = '\0';
return buf;
}
@ -1086,6 +1230,8 @@ const char *get_token_value(struct gui_wps *gwps,
/* we need 11 characters (full line) for
progress-bar */
strlcpy(buf, " ", buf_size);
format_player_fullbar(gwps,buf,buf_size);
DEBUGF("bar='%s'\n",buf);
}
else
{