From 15ddd7a7ec2aa92767234e37907904309943a27b Mon Sep 17 00:00:00 2001 From: Dave Chapman Date: Sun, 23 Mar 2008 20:31:00 +0000 Subject: Add the ability to use bitmap strips (a single .bmp file containing many images of the same dimensions, tiled vertically - similar to icon strips) in the WPS. The %xl tag now has an optional "number of subimages" parameter, and the %xd tag has an optional "subimage to display" parameter (a-z,A-Z - allowing up to 52 sub-images). So for example, a bitmap with 10 subimages is loaded with %xl|M|volume.bmp|134|153|10| and then this can be used in a conditional as %?pv<%xdMa|%xdMb|%xdMc|%xdMd|%xdMe|%xdMf|%xdMg|%xdMh|%xdMi|%xdMj>. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16764 a1c6a512-1295-4272-9138-f99709370657 --- apps/gui/gwps-common.c | 43 ++++++++++++++++++++++++++----------------- apps/gui/gwps.h | 4 +++- apps/gui/wps_parser.c | 40 ++++++++++++++++++++++++++++++++++------ 3 files changed, 63 insertions(+), 24 deletions(-) diff --git a/apps/gui/gwps-common.c b/apps/gui/gwps-common.c index 744f86e42a..37b2b7c5d1 100644 --- a/apps/gui/gwps-common.c +++ b/apps/gui/gwps-common.c @@ -516,11 +516,11 @@ static void clear_image_pos(struct gui_wps *gwps, int n) struct wps_data *data = gwps->data; gwps->display->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); gwps->display->fillrect(data->img[n].x, data->img[n].y, - data->img[n].bm.width, data->img[n].bm.height); + data->img[n].bm.width, data->img[n].subimage_height); gwps->display->set_drawmode(DRMODE_SOLID); } -static void wps_draw_image(struct gui_wps *gwps, int n) +static void wps_draw_image(struct gui_wps *gwps, int n, int subimage) { struct screen *display = gwps->display; struct wps_data *data = gwps->data; @@ -532,15 +532,18 @@ static void wps_draw_image(struct gui_wps *gwps, int n) #if LCD_DEPTH > 1 if(data->img[n].bm.format == FORMAT_MONO) { #endif - display->mono_bitmap(data->img[n].bm.data, data->img[n].x, - data->img[n].y, data->img[n].bm.width, - data->img[n].bm.height); + display->mono_bitmap_part(data->img[n].bm.data, + 0, data->img[n].subimage_height * subimage, + data->img[n].bm.width, data->img[n].x, + data->img[n].y, data->img[n].bm.width, + data->img[n].subimage_height); #if LCD_DEPTH > 1 } else { - display->transparent_bitmap((fb_data *)data->img[n].bm.data, - data->img[n].x, - data->img[n].y, data->img[n].bm.width, - data->img[n].bm.height); + display->transparent_bitmap_part((fb_data *)data->img[n].bm.data, + 0, data->img[n].subimage_height * subimage, + data->img[n].bm.width, data->img[n].x, + data->img[n].y, data->img[n].bm.width, + data->img[n].subimage_height); } #endif } @@ -556,11 +559,15 @@ static void wps_display_images(struct gui_wps *gwps, struct viewport* vp) for (n = 0; n < MAX_IMAGES; n++) { - if (data->img[n].loaded && - (data->img[n].display || - (data->img[n].always_display && data->img[n].vp == vp))) + if (data->img[n].loaded) { - wps_draw_image(gwps, n); + if (data->img[n].display >= 0) + { + wps_draw_image(gwps, n, data->img[n].display); + } else if (data->img[n].always_display && data->img[n].vp == vp) + { + wps_draw_image(gwps, n, 0); + } } } display->set_drawmode(DRMODE_SOLID); @@ -1449,7 +1456,7 @@ static bool evaluate_conditional(struct gui_wps *gwps, int *token_index) #ifdef HAVE_LCD_BITMAP /* clear all pictures in the conditional and nested ones */ if (data->tokens[i].type == WPS_TOKEN_IMAGE_PRELOAD_DISPLAY) - clear_image_pos(gwps, data->tokens[i].value.i); + clear_image_pos(gwps, data->tokens[i].value.i & 0xFF); #endif #ifdef HAVE_ALBUMART if (data->tokens[i].type == WPS_TOKEN_ALBUMART_DISPLAY) @@ -1515,9 +1522,11 @@ static bool get_line(struct gui_wps *gwps, case WPS_TOKEN_IMAGE_PRELOAD_DISPLAY: { struct gui_img *img = data->img; - int n = data->tokens[i].value.i; + int n = data->tokens[i].value.i & 0xFF; + int subimage = data->tokens[i].value.i >> 8; + if (n >= 0 && n < MAX_IMAGES && img[n].loaded) - img[n].display = true; + img[n].display = subimage; break; } #endif @@ -1944,7 +1953,7 @@ bool gui_wps_refresh(struct gui_wps *gwps, /* Set images to not to be displayed */ for (i = 0; i < MAX_IMAGES; i++) { - data->img[i].display = false; + data->img[i].display = -1; } #endif diff --git a/apps/gui/gwps.h b/apps/gui/gwps.h index e72b41308b..b24c243cd7 100644 --- a/apps/gui/gwps.h +++ b/apps/gui/gwps.h @@ -64,8 +64,10 @@ struct gui_img{ struct viewport* vp; /* The viewport to display this image in */ int x; /* x-pos */ int y; /* y-pos */ + int num_subimages; /* number of sub-images */ + int subimage_height; /* height of each sub-image */ + int display; /* -1 for no display, 0..n to display a subimage */ bool loaded; /* load state */ - bool display; /* is to be displayed */ bool always_display; /* not using the preload/display mechanism */ }; diff --git a/apps/gui/wps_parser.c b/apps/gui/wps_parser.c index eb4b1087e3..d5e29f3a4f 100644 --- a/apps/gui/wps_parser.c +++ b/apps/gui/wps_parser.c @@ -432,7 +432,8 @@ static int parse_image_display(const char *wps_bufptr, struct wps_data *wps_data) { (void)wps_data; - int n = get_image_id(*wps_bufptr); + int n = get_image_id(wps_bufptr[0]); + int subimage; if (n == -1) { @@ -440,9 +441,15 @@ static int parse_image_display(const char *wps_bufptr, return WPS_ERROR_INVALID_PARAM; } - token->value.i = n; - - return 1; + if ((subimage = get_image_id(wps_bufptr[1])) != -1) + { + /* Store sub-image number to display in high bits */ + token->value.i = n | (subimage << 8); + return 2; /* We have consumed 2 bytes */ + } else { + token->value.i = n; + return 1; /* We have consumed 1 byte */ + } } static int parse_image_load(const char *wps_bufptr, @@ -451,12 +458,16 @@ static int parse_image_load(const char *wps_bufptr, { int n; const char *ptr = wps_bufptr; + const char *pos; const char* filename; const char* id; + const char *newline; int x,y; /* format: %x|n|filename.bmp|x|y| - or %xl|n|filename.bmp|x|y| */ + or %xl|n|filename.bmp|x|y| + or %xl|n|filename.bmp|x|y|num_subimages| + */ if (*ptr != '|') return WPS_ERROR_INVALID_PARAM; @@ -490,7 +501,18 @@ static int parse_image_load(const char *wps_bufptr, wps_data->img[n].vp = &wps_data->viewports[wps_data->num_viewports].vp; if (token->type == WPS_TOKEN_IMAGE_DISPLAY) + { wps_data->img[n].always_display = true; + } + else + { + /* Parse the (optional) number of sub-images */ + ptr++; + newline = strchr(ptr, '\n'); + pos = strchr(ptr, '|'); + if (pos && pos < newline) + wps_data->img[n].num_subimages = atoi(ptr); + } /* Skip the rest of the line */ return skip_end_of_line(wps_bufptr); @@ -1283,8 +1305,9 @@ static void wps_images_clear(struct wps_data *data) for (i = 0; i < MAX_IMAGES; i++) { data->img[i].loaded = false; - data->img[i].display = false; + data->img[i].display = -1; data->img[i].always_display = false; + data->img[i].num_subimages = 1; } data->progressbar.have_bitmap_pb = false; } @@ -1357,6 +1380,11 @@ static void load_wps_bitmaps(struct wps_data *wps_data, char *bmpdir) if (load_bitmap(wps_data, img_path, bitmap)) { *loaded = true; + + /* Calculate and store height if this image has sub-images */ + if (n < MAX_IMAGES) + wps_data->img[n].subimage_height = wps_data->img[n].bm.height / + wps_data->img[n].num_subimages; } } } -- cgit v1.2.3