diff options
author | Frank Gevaerts <frank@gevaerts.be> | 2010-10-10 23:46:15 +0000 |
---|---|---|
committer | Frank Gevaerts <frank@gevaerts.be> | 2010-10-10 23:46:15 +0000 |
commit | 1f0ab7c9e636ba3e88700b1b6fb75e876a0f0a44 (patch) | |
tree | 4b030482b9f788e673a4b74cbbb7e83f67118615 | |
parent | 5462ef728fd41a6db4d1d784c478416ceeebf588 (diff) | |
download | rockbox-1f0ab7c9e636ba3e88700b1b6fb75e876a0f0a44.tar.gz rockbox-1f0ab7c9e636ba3e88700b1b6fb75e876a0f0a44.zip |
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
-rw-r--r-- | apps/gui/skin_engine/skin_display.c | 144 | ||||
-rw-r--r-- | apps/gui/skin_engine/skin_display.h | 3 | ||||
-rw-r--r-- | apps/gui/skin_engine/skin_render.c | 16 | ||||
-rw-r--r-- | apps/gui/skin_engine/skin_tokens.c | 148 |
4 files changed, 154 insertions, 157 deletions
diff --git a/apps/gui/skin_engine/skin_display.c b/apps/gui/skin_engine/skin_display.c index 8638d2c902..24e976d393 100644 --- a/apps/gui/skin_engine/skin_display.c +++ b/apps/gui/skin_engine/skin_display.c | |||
@@ -349,149 +349,7 @@ void wps_display_images(struct gui_wps *gwps, struct viewport* vp) | |||
349 | display->set_drawmode(DRMODE_SOLID); | 349 | display->set_drawmode(DRMODE_SOLID); |
350 | } | 350 | } |
351 | 351 | ||
352 | #else /* HAVE_LCD_CHARCELL */ | 352 | #endif /* HAVE_LCD_BITMAP */ |
353 | |||
354 | bool draw_player_progress(struct gui_wps *gwps) | ||
355 | { | ||
356 | struct wps_state *state = skin_get_global_state(); | ||
357 | struct screen *display = gwps->display; | ||
358 | unsigned char progress_pattern[7]; | ||
359 | int pos = 0; | ||
360 | int i; | ||
361 | |||
362 | int elapsed, length; | ||
363 | if (LIKELY(state->id3)) | ||
364 | { | ||
365 | elapsed = state->id3->elapsed; | ||
366 | length = state->id3->length; | ||
367 | } | ||
368 | else | ||
369 | { | ||
370 | elapsed = 0; | ||
371 | length = 0; | ||
372 | } | ||
373 | |||
374 | if (length) | ||
375 | pos = 36 * (elapsed + state->ff_rewind_count) / length; | ||
376 | |||
377 | for (i = 0; i < 7; i++, pos -= 5) | ||
378 | { | ||
379 | if (pos <= 0) | ||
380 | progress_pattern[i] = 0x1fu; | ||
381 | else if (pos >= 5) | ||
382 | progress_pattern[i] = 0x00u; | ||
383 | else | ||
384 | progress_pattern[i] = 0x1fu >> pos; | ||
385 | } | ||
386 | |||
387 | display->define_pattern(gwps->data->wps_progress_pat[0], progress_pattern); | ||
388 | return true; | ||
389 | } | ||
390 | |||
391 | void draw_player_fullbar(struct gui_wps *gwps, char* buf, int buf_size) | ||
392 | { | ||
393 | static const unsigned char numbers[10][4] = { | ||
394 | {0x0e, 0x0a, 0x0a, 0x0e}, /* 0 */ | ||
395 | {0x04, 0x0c, 0x04, 0x04}, /* 1 */ | ||
396 | {0x0e, 0x02, 0x04, 0x0e}, /* 2 */ | ||
397 | {0x0e, 0x02, 0x06, 0x0e}, /* 3 */ | ||
398 | {0x08, 0x0c, 0x0e, 0x04}, /* 4 */ | ||
399 | {0x0e, 0x0c, 0x02, 0x0c}, /* 5 */ | ||
400 | {0x0e, 0x08, 0x0e, 0x0e}, /* 6 */ | ||
401 | {0x0e, 0x02, 0x04, 0x08}, /* 7 */ | ||
402 | {0x0e, 0x0e, 0x0a, 0x0e}, /* 8 */ | ||
403 | {0x0e, 0x0e, 0x02, 0x0e}, /* 9 */ | ||
404 | }; | ||
405 | |||
406 | struct wps_state *state = skin_get_global_state(); | ||
407 | struct screen *display = gwps->display; | ||
408 | struct wps_data *data = gwps->data; | ||
409 | unsigned char progress_pattern[7]; | ||
410 | char timestr[10]; | ||
411 | int time; | ||
412 | int time_idx = 0; | ||
413 | int pos = 0; | ||
414 | int pat_idx = 1; | ||
415 | int digit, i, j; | ||
416 | bool softchar; | ||
417 | |||
418 | int elapsed, length; | ||
419 | if (LIKELY(state->id3)) | ||
420 | { | ||
421 | elapsed = state->id3->elapsed; | ||
422 | length = state->id3->length; | ||
423 | } | ||
424 | else | ||
425 | { | ||
426 | elapsed = 0; | ||
427 | length = 0; | ||
428 | } | ||
429 | |||
430 | if (buf_size < 34) /* worst case: 11x UTF-8 char + \0 */ | ||
431 | return; | ||
432 | |||
433 | time = elapsed + state->ff_rewind_count; | ||
434 | if (length) | ||
435 | pos = 55 * time / length; | ||
436 | |||
437 | memset(timestr, 0, sizeof(timestr)); | ||
438 | format_time(timestr, sizeof(timestr)-2, time); | ||
439 | timestr[strlen(timestr)] = ':'; /* always safe */ | ||
440 | |||
441 | for (i = 0; i < 11; i++, pos -= 5) | ||
442 | { | ||
443 | softchar = false; | ||
444 | memset(progress_pattern, 0, sizeof(progress_pattern)); | ||
445 | |||
446 | if ((digit = timestr[time_idx])) | ||
447 | { | ||
448 | softchar = true; | ||
449 | digit -= '0'; | ||
450 | |||
451 | if (timestr[time_idx + 1] == ':') /* ones, left aligned */ | ||
452 | { | ||
453 | memcpy(progress_pattern, numbers[digit], 4); | ||
454 | time_idx += 2; | ||
455 | } | ||
456 | else /* tens, shifted right */ | ||
457 | { | ||
458 | for (j = 0; j < 4; j++) | ||
459 | progress_pattern[j] = numbers[digit][j] >> 1; | ||
460 | |||
461 | if (time_idx > 0) /* not the first group, add colon in front */ | ||
462 | { | ||
463 | progress_pattern[1] |= 0x10u; | ||
464 | progress_pattern[3] |= 0x10u; | ||
465 | } | ||
466 | time_idx++; | ||
467 | } | ||
468 | |||
469 | if (pos >= 5) | ||
470 | progress_pattern[5] = progress_pattern[6] = 0x1fu; | ||
471 | } | ||
472 | |||
473 | if (pos > 0 && pos < 5) | ||
474 | { | ||
475 | softchar = true; | ||
476 | progress_pattern[5] = progress_pattern[6] = (~0x1fu >> pos) & 0x1fu; | ||
477 | } | ||
478 | |||
479 | if (softchar && pat_idx < 8) | ||
480 | { | ||
481 | display->define_pattern(data->wps_progress_pat[pat_idx], | ||
482 | progress_pattern); | ||
483 | buf = utf8encode(data->wps_progress_pat[pat_idx], buf); | ||
484 | pat_idx++; | ||
485 | } | ||
486 | else if (pos <= 0) | ||
487 | buf = utf8encode(' ', buf); | ||
488 | else | ||
489 | buf = utf8encode(0xe115, buf); /* 2/7 _ */ | ||
490 | } | ||
491 | *buf = '\0'; | ||
492 | } | ||
493 | |||
494 | #endif /* HAVE_LCD_CHARCELL */ | ||
495 | 353 | ||
496 | /* Evaluate the conditional that is at *token_index and return whether a skip | 354 | /* Evaluate the conditional that is at *token_index and return whether a skip |
497 | has ocurred. *token_index is updated with the new position. | 355 | has ocurred. *token_index is updated with the new position. |
diff --git a/apps/gui/skin_engine/skin_display.h b/apps/gui/skin_engine/skin_display.h index 67b7bfdf27..da4bb92aef 100644 --- a/apps/gui/skin_engine/skin_display.h +++ b/apps/gui/skin_engine/skin_display.h | |||
@@ -36,9 +36,6 @@ void draw_playlist_viewer_list(struct gui_wps *gwps, struct playlistviewer *view | |||
36 | void clear_image_pos(struct gui_wps *gwps, struct gui_img *img); | 36 | void clear_image_pos(struct gui_wps *gwps, struct gui_img *img); |
37 | void wps_draw_image(struct gui_wps *gwps, struct gui_img *img, int subimage); | 37 | void wps_draw_image(struct gui_wps *gwps, struct gui_img *img, int subimage); |
38 | void wps_display_images(struct gui_wps *gwps, struct viewport* vp); | 38 | void wps_display_images(struct gui_wps *gwps, struct viewport* vp); |
39 | #else | ||
40 | bool draw_player_progress(struct gui_wps *gwps); | ||
41 | void draw_player_fullbar(struct gui_wps *gwps, char* buf, int buf_size); | ||
42 | #endif | 39 | #endif |
43 | 40 | ||
44 | /* Evaluate the conditional that is at *token_index and return whether a skip | 41 | /* Evaluate the conditional that is at *token_index and return whether a skip |
diff --git a/apps/gui/skin_engine/skin_render.c b/apps/gui/skin_engine/skin_render.c index bd86c0bdf8..9b86380ade 100644 --- a/apps/gui/skin_engine/skin_render.c +++ b/apps/gui/skin_engine/skin_render.c | |||
@@ -83,10 +83,14 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info, | |||
83 | { | 83 | { |
84 | #ifndef HAVE_LCD_BITMAP | 84 | #ifndef HAVE_LCD_BITMAP |
85 | (void)vp; /* silence warnings */ | 85 | (void)vp; /* silence warnings */ |
86 | (void)info; | ||
86 | #endif | 87 | #endif |
87 | struct wps_token *token = (struct wps_token *)element->data; | 88 | struct wps_token *token = (struct wps_token *)element->data; |
89 | |||
90 | #ifdef HAVE_LCD_BITMAP | ||
88 | struct wps_data *data = gwps->data; | 91 | struct wps_data *data = gwps->data; |
89 | bool do_refresh = (element->tag->flags & info->refresh_type) > 0; | 92 | bool do_refresh = (element->tag->flags & info->refresh_type) > 0; |
93 | #endif | ||
90 | switch (token->type) | 94 | switch (token->type) |
91 | { | 95 | { |
92 | #if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)) | 96 | #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, | |||
137 | #endif | 141 | #endif |
138 | case SKIN_TOKEN_VOLUMEBAR: | 142 | case SKIN_TOKEN_VOLUMEBAR: |
139 | case SKIN_TOKEN_BATTERY_PERCENTBAR: | 143 | case SKIN_TOKEN_BATTERY_PERCENTBAR: |
144 | #ifdef HAVE_LCD_BITMAP | ||
140 | case SKIN_TOKEN_PROGRESSBAR: | 145 | case SKIN_TOKEN_PROGRESSBAR: |
141 | { | 146 | { |
142 | #ifdef HAVE_LCD_BITMAP | ||
143 | struct progressbar *bar = (struct progressbar*)token->value.data; | 147 | struct progressbar *bar = (struct progressbar*)token->value.data; |
144 | if (do_refresh) | 148 | if (do_refresh) |
145 | draw_progressbar(gwps, info->line_number, bar); | 149 | draw_progressbar(gwps, info->line_number, bar); |
146 | #else /* HAVE_LCD_CHARCELL */ | ||
147 | if (do_refresh) | ||
148 | { | ||
149 | if (data->full_line_progressbar) | ||
150 | draw_player_fullbar(gwps, info->buf, info->buf_size); | ||
151 | else | ||
152 | draw_player_progress(gwps); | ||
153 | } | ||
154 | #endif | ||
155 | } | 150 | } |
151 | #endif | ||
156 | break; | 152 | break; |
157 | #ifdef HAVE_LCD_BITMAP | 153 | #ifdef HAVE_LCD_BITMAP |
158 | case SKIN_TOKEN_IMAGE_DISPLAY_LISTICON: | 154 | case SKIN_TOKEN_IMAGE_DISPLAY_LISTICON: |
diff --git a/apps/gui/skin_engine/skin_tokens.c b/apps/gui/skin_engine/skin_tokens.c index 11200e448c..78d141e743 100644 --- a/apps/gui/skin_engine/skin_tokens.c +++ b/apps/gui/skin_engine/skin_tokens.c | |||
@@ -554,6 +554,148 @@ static struct mp3entry* get_mp3entry_from_offset(int offset, char **filename) | |||
554 | return pid3; | 554 | return pid3; |
555 | } | 555 | } |
556 | 556 | ||
557 | #ifdef HAVE_LCD_CHARCELLS | ||
558 | void format_player_progress(struct gui_wps *gwps) | ||
559 | { | ||
560 | struct wps_state *state = skin_get_global_state(); | ||
561 | struct screen *display = gwps->display; | ||
562 | unsigned char progress_pattern[7]; | ||
563 | int pos = 0; | ||
564 | int i; | ||
565 | |||
566 | int elapsed, length; | ||
567 | if (LIKELY(state->id3)) | ||
568 | { | ||
569 | elapsed = state->id3->elapsed; | ||
570 | length = state->id3->length; | ||
571 | } | ||
572 | else | ||
573 | { | ||
574 | elapsed = 0; | ||
575 | length = 0; | ||
576 | } | ||
577 | |||
578 | if (length) | ||
579 | pos = 36 * (elapsed + state->ff_rewind_count) / length; | ||
580 | |||
581 | for (i = 0; i < 7; i++, pos -= 5) | ||
582 | { | ||
583 | if (pos <= 0) | ||
584 | progress_pattern[i] = 0x1fu; | ||
585 | else if (pos >= 5) | ||
586 | progress_pattern[i] = 0x00u; | ||
587 | else | ||
588 | progress_pattern[i] = 0x1fu >> pos; | ||
589 | } | ||
590 | |||
591 | display->define_pattern(gwps->data->wps_progress_pat[0], progress_pattern); | ||
592 | } | ||
593 | |||
594 | void format_player_fullbar(struct gui_wps *gwps, char* buf, int buf_size) | ||
595 | { | ||
596 | static const unsigned char numbers[10][4] = { | ||
597 | {0x0e, 0x0a, 0x0a, 0x0e}, /* 0 */ | ||
598 | {0x04, 0x0c, 0x04, 0x04}, /* 1 */ | ||
599 | {0x0e, 0x02, 0x04, 0x0e}, /* 2 */ | ||
600 | {0x0e, 0x02, 0x06, 0x0e}, /* 3 */ | ||
601 | {0x08, 0x0c, 0x0e, 0x04}, /* 4 */ | ||
602 | {0x0e, 0x0c, 0x02, 0x0c}, /* 5 */ | ||
603 | {0x0e, 0x08, 0x0e, 0x0e}, /* 6 */ | ||
604 | {0x0e, 0x02, 0x04, 0x08}, /* 7 */ | ||
605 | {0x0e, 0x0e, 0x0a, 0x0e}, /* 8 */ | ||
606 | {0x0e, 0x0e, 0x02, 0x0e}, /* 9 */ | ||
607 | }; | ||
608 | |||
609 | struct wps_state *state = skin_get_global_state(); | ||
610 | struct screen *display = gwps->display; | ||
611 | struct wps_data *data = gwps->data; | ||
612 | unsigned char progress_pattern[7]; | ||
613 | char timestr[10]; | ||
614 | int time; | ||
615 | int time_idx = 0; | ||
616 | int pos = 0; | ||
617 | int pat_idx = 1; | ||
618 | int digit, i, j; | ||
619 | bool softchar; | ||
620 | |||
621 | int elapsed, length; | ||
622 | if (LIKELY(state->id3)) | ||
623 | { | ||
624 | elapsed = state->id3->elapsed; | ||
625 | length = state->id3->length; | ||
626 | } | ||
627 | else | ||
628 | { | ||
629 | elapsed = 0; | ||
630 | length = 0; | ||
631 | } | ||
632 | |||
633 | if (buf_size < 34) /* worst case: 11x UTF-8 char + \0 */ | ||
634 | return; | ||
635 | |||
636 | time = elapsed + state->ff_rewind_count; | ||
637 | if (length) | ||
638 | pos = 55 * time / length; | ||
639 | |||
640 | memset(timestr, 0, sizeof(timestr)); | ||
641 | format_time(timestr, sizeof(timestr)-2, time); | ||
642 | timestr[strlen(timestr)] = ':'; /* always safe */ | ||
643 | |||
644 | for (i = 0; i < 11; i++, pos -= 5) | ||
645 | { | ||
646 | softchar = false; | ||
647 | memset(progress_pattern, 0, sizeof(progress_pattern)); | ||
648 | |||
649 | if ((digit = timestr[time_idx])) | ||
650 | { | ||
651 | softchar = true; | ||
652 | digit -= '0'; | ||
653 | |||
654 | if (timestr[time_idx + 1] == ':') /* ones, left aligned */ | ||
655 | { | ||
656 | memcpy(progress_pattern, numbers[digit], 4); | ||
657 | time_idx += 2; | ||
658 | } | ||
659 | else /* tens, shifted right */ | ||
660 | { | ||
661 | for (j = 0; j < 4; j++) | ||
662 | progress_pattern[j] = numbers[digit][j] >> 1; | ||
663 | |||
664 | if (time_idx > 0) /* not the first group, add colon in front */ | ||
665 | { | ||
666 | progress_pattern[1] |= 0x10u; | ||
667 | progress_pattern[3] |= 0x10u; | ||
668 | } | ||
669 | time_idx++; | ||
670 | } | ||
671 | |||
672 | if (pos >= 5) | ||
673 | progress_pattern[5] = progress_pattern[6] = 0x1fu; | ||
674 | } | ||
675 | |||
676 | if (pos > 0 && pos < 5) | ||
677 | { | ||
678 | softchar = true; | ||
679 | progress_pattern[5] = progress_pattern[6] = (~0x1fu >> pos) & 0x1fu; | ||
680 | } | ||
681 | |||
682 | if (softchar && pat_idx < 8) | ||
683 | { | ||
684 | display->define_pattern(data->wps_progress_pat[pat_idx], | ||
685 | progress_pattern); | ||
686 | buf = utf8encode(data->wps_progress_pat[pat_idx], buf); | ||
687 | pat_idx++; | ||
688 | } | ||
689 | else if (pos <= 0) | ||
690 | buf = utf8encode(' ', buf); | ||
691 | else | ||
692 | buf = utf8encode(0xe115, buf); /* 2/7 _ */ | ||
693 | } | ||
694 | *buf = '\0'; | ||
695 | } | ||
696 | |||
697 | #endif /* HAVE_LCD_CHARCELLS */ | ||
698 | |||
557 | /* Don't inline this; it was broken out of get_token_value to reduce stack | 699 | /* Don't inline this; it was broken out of get_token_value to reduce stack |
558 | * usage. | 700 | * usage. |
559 | */ | 701 | */ |
@@ -1075,7 +1217,9 @@ const char *get_token_value(struct gui_wps *gwps, | |||
1075 | #ifdef HAVE_LCD_CHARCELLS | 1217 | #ifdef HAVE_LCD_CHARCELLS |
1076 | case SKIN_TOKEN_PROGRESSBAR: | 1218 | case SKIN_TOKEN_PROGRESSBAR: |
1077 | { | 1219 | { |
1078 | char *end = utf8encode(data->wps_progress_pat[0], buf); | 1220 | char *end; |
1221 | format_player_progress(gwps); | ||
1222 | end = utf8encode(data->wps_progress_pat[0], buf); | ||
1079 | *end = '\0'; | 1223 | *end = '\0'; |
1080 | return buf; | 1224 | return buf; |
1081 | } | 1225 | } |
@@ -1086,6 +1230,8 @@ const char *get_token_value(struct gui_wps *gwps, | |||
1086 | /* we need 11 characters (full line) for | 1230 | /* we need 11 characters (full line) for |
1087 | progress-bar */ | 1231 | progress-bar */ |
1088 | strlcpy(buf, " ", buf_size); | 1232 | strlcpy(buf, " ", buf_size); |
1233 | format_player_fullbar(gwps,buf,buf_size); | ||
1234 | DEBUGF("bar='%s'\n",buf); | ||
1089 | } | 1235 | } |
1090 | else | 1236 | else |
1091 | { | 1237 | { |