diff options
author | Jonathan Gordon <rockbox@jdgordon.info> | 2012-12-03 20:43:58 +1100 |
---|---|---|
committer | Jonathan Gordon <rockbox@jdgordon.info> | 2012-12-09 17:11:19 +1100 |
commit | 685cf5900825b10c952f36301abbbd9968567435 (patch) | |
tree | 41cdfed9e5a2943c80ac0d4ffe09c45519a3ecf3 | |
parent | 1fbdc280d7e4b4ffb7ec8dccbfd1c1fc67f1c123 (diff) | |
download | rockbox-685cf5900825b10c952f36301abbbd9968567435.tar.gz rockbox-685cf5900825b10c952f36301abbbd9968567435.zip |
9 segment bitmap drawing:
Use %x9(id) to draw an image in the whole current viewport using the
9 segment drawer (which draws the corners as normal and *tiles*
the middle segments to the needed width/height).
Future work is to make it scale instead of tile
Change-Id: Ic3ed1cad93f96091694801eb442e0da5a2401203
-rw-r--r-- | apps/gui/skin_engine/skin_display.c | 13 | ||||
-rw-r--r-- | apps/gui/skin_engine/skin_display.h | 1 | ||||
-rw-r--r-- | apps/gui/skin_engine/skin_parser.c | 5 | ||||
-rw-r--r-- | apps/gui/skin_engine/skin_render.c | 1 | ||||
-rw-r--r-- | apps/gui/skin_engine/wps_internals.h | 1 | ||||
-rw-r--r-- | apps/screen_access.c | 1 | ||||
-rw-r--r-- | apps/screen_access.h | 4 | ||||
-rw-r--r-- | firmware/drivers/lcd-bitmap-common.c | 45 | ||||
-rw-r--r-- | firmware/export/lcd.h | 2 | ||||
-rw-r--r-- | lib/skin_parser/tag_table.c | 1 | ||||
-rw-r--r-- | lib/skin_parser/tag_table.h | 1 | ||||
-rw-r--r-- | manual/appendix/wps_tags.tex | 7 |
12 files changed, 76 insertions, 6 deletions
diff --git a/apps/gui/skin_engine/skin_display.c b/apps/gui/skin_engine/skin_display.c index 4f491dea24..24958a46f2 100644 --- a/apps/gui/skin_engine/skin_display.c +++ b/apps/gui/skin_engine/skin_display.c | |||
@@ -302,17 +302,20 @@ void clear_image_pos(struct gui_wps *gwps, struct gui_img *img) | |||
302 | gwps->display->set_drawmode(DRMODE_SOLID); | 302 | gwps->display->set_drawmode(DRMODE_SOLID); |
303 | } | 303 | } |
304 | 304 | ||
305 | void wps_draw_image(struct gui_wps *gwps, struct gui_img *img, int subimage) | 305 | void wps_draw_image(struct gui_wps *gwps, struct gui_img *img, |
306 | int subimage, struct viewport* vp) | ||
306 | { | 307 | { |
307 | struct screen *display = gwps->display; | 308 | struct screen *display = gwps->display; |
308 | img->bm.data = core_get_data(img->buflib_handle); | 309 | img->bm.data = core_get_data(img->buflib_handle); |
309 | display->set_drawmode(DRMODE_SOLID); | 310 | display->set_drawmode(DRMODE_SOLID); |
310 | 311 | ||
311 | display->bmp_part(&img->bm, 0, img->subimage_height * subimage, | 312 | if (img->is_9_segment) |
312 | img->x, img->y, img->bm.width, img->subimage_height); | 313 | display->nine_segment_bmp(&img->bm, 0, 0, vp->width, vp->height); |
314 | else | ||
315 | display->bmp_part(&img->bm, 0, img->subimage_height * subimage, | ||
316 | img->x, img->y, img->bm.width, img->subimage_height); | ||
313 | } | 317 | } |
314 | 318 | ||
315 | |||
316 | void wps_display_images(struct gui_wps *gwps, struct viewport* vp) | 319 | void wps_display_images(struct gui_wps *gwps, struct viewport* vp) |
317 | { | 320 | { |
318 | if(!gwps || !gwps->data || !gwps->display) | 321 | if(!gwps || !gwps->data || !gwps->display) |
@@ -334,7 +337,7 @@ void wps_display_images(struct gui_wps *gwps, struct viewport* vp) | |||
334 | { | 337 | { |
335 | if (img->display >= 0) | 338 | if (img->display >= 0) |
336 | { | 339 | { |
337 | wps_draw_image(gwps, img, img->display); | 340 | wps_draw_image(gwps, img, img->display, vp); |
338 | } | 341 | } |
339 | } | 342 | } |
340 | list = SKINOFFSETTOPTR(get_skin_buffer(data), list->next); | 343 | list = SKINOFFSETTOPTR(get_skin_buffer(data), list->next); |
diff --git a/apps/gui/skin_engine/skin_display.h b/apps/gui/skin_engine/skin_display.h index 81d04e5a60..b3422b0360 100644 --- a/apps/gui/skin_engine/skin_display.h +++ b/apps/gui/skin_engine/skin_display.h | |||
@@ -34,7 +34,6 @@ void draw_progressbar(struct gui_wps *gwps, int line, struct progressbar *pb); | |||
34 | void draw_playlist_viewer_list(struct gui_wps *gwps, struct playlistviewer *viewer); | 34 | void draw_playlist_viewer_list(struct gui_wps *gwps, struct playlistviewer *viewer); |
35 | /* clears the area where the image was shown */ | 35 | /* clears the area where the image was shown */ |
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); | ||
38 | void wps_display_images(struct gui_wps *gwps, struct viewport* vp); | 37 | void wps_display_images(struct gui_wps *gwps, struct viewport* vp); |
39 | 38 | ||
40 | 39 | ||
diff --git a/apps/gui/skin_engine/skin_parser.c b/apps/gui/skin_engine/skin_parser.c index 93f310df56..94adaf3116 100644 --- a/apps/gui/skin_engine/skin_parser.c +++ b/apps/gui/skin_engine/skin_parser.c | |||
@@ -344,6 +344,9 @@ static int parse_image_display(struct skin_element *element, | |||
344 | token->type = SKIN_TOKEN_IMAGE_DISPLAY_LISTICON; | 344 | token->type = SKIN_TOKEN_IMAGE_DISPLAY_LISTICON; |
345 | } | 345 | } |
346 | 346 | ||
347 | if (token->type == SKIN_TOKEN_IMAGE_DISPLAY_9SEGMENT) | ||
348 | img->is_9_segment = true; | ||
349 | |||
347 | if (element->params_count > 1) | 350 | if (element->params_count > 1) |
348 | { | 351 | { |
349 | if (get_param(element, 1)->type == CODE) | 352 | if (get_param(element, 1)->type == CODE) |
@@ -417,6 +420,7 @@ static int parse_image_load(struct skin_element *element, | |||
417 | img->display = -1; | 420 | img->display = -1; |
418 | img->using_preloaded_icons = false; | 421 | img->using_preloaded_icons = false; |
419 | img->buflib_handle = -1; | 422 | img->buflib_handle = -1; |
423 | img->is_9_segment = false; | ||
420 | 424 | ||
421 | /* save current viewport */ | 425 | /* save current viewport */ |
422 | img->vp = PTRTOSKINOFFSET(skin_buffer, &curr_vp->vp); | 426 | img->vp = PTRTOSKINOFFSET(skin_buffer, &curr_vp->vp); |
@@ -2181,6 +2185,7 @@ static int skin_element_callback(struct skin_element* element, void* data) | |||
2181 | token->value.data = get_param(element, 0)->data.text; | 2185 | token->value.data = get_param(element, 0)->data.text; |
2182 | break; | 2186 | break; |
2183 | case SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY: | 2187 | case SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY: |
2188 | case SKIN_TOKEN_IMAGE_DISPLAY_9SEGMENT: | ||
2184 | function = parse_image_display; | 2189 | function = parse_image_display; |
2185 | break; | 2190 | break; |
2186 | case SKIN_TOKEN_IMAGE_PRELOAD: | 2191 | case SKIN_TOKEN_IMAGE_PRELOAD: |
diff --git a/apps/gui/skin_engine/skin_render.c b/apps/gui/skin_engine/skin_render.c index 0fdf6b019f..e01972fc3b 100644 --- a/apps/gui/skin_engine/skin_render.c +++ b/apps/gui/skin_engine/skin_render.c | |||
@@ -231,6 +231,7 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info, | |||
231 | break; | 231 | break; |
232 | case SKIN_TOKEN_IMAGE_DISPLAY_LISTICON: | 232 | case SKIN_TOKEN_IMAGE_DISPLAY_LISTICON: |
233 | case SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY: | 233 | case SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY: |
234 | case SKIN_TOKEN_IMAGE_DISPLAY_9SEGMENT: | ||
234 | { | 235 | { |
235 | struct image_display *id = SKINOFFSETTOPTR(skin_buffer, token->value.data); | 236 | struct image_display *id = SKINOFFSETTOPTR(skin_buffer, token->value.data); |
236 | const char* label = SKINOFFSETTOPTR(skin_buffer, id->label); | 237 | const char* label = SKINOFFSETTOPTR(skin_buffer, id->label); |
diff --git a/apps/gui/skin_engine/wps_internals.h b/apps/gui/skin_engine/wps_internals.h index 8cd5d9cb60..72bab9b668 100644 --- a/apps/gui/skin_engine/wps_internals.h +++ b/apps/gui/skin_engine/wps_internals.h | |||
@@ -82,6 +82,7 @@ struct gui_img { | |||
82 | bool loaded; /* load state */ | 82 | bool loaded; /* load state */ |
83 | int display; | 83 | int display; |
84 | bool using_preloaded_icons; /* using the icon system instead of a bmp */ | 84 | bool using_preloaded_icons; /* using the icon system instead of a bmp */ |
85 | bool is_9_segment; | ||
85 | }; | 86 | }; |
86 | 87 | ||
87 | struct image_display { | 88 | struct image_display { |
diff --git a/apps/screen_access.c b/apps/screen_access.c index fc92210981..79ab459475 100644 --- a/apps/screen_access.c +++ b/apps/screen_access.c | |||
@@ -195,6 +195,7 @@ struct screen screens[NB_SCREENS] = | |||
195 | #endif | 195 | #endif |
196 | .bmp = &lcd_bmp, | 196 | .bmp = &lcd_bmp, |
197 | .bmp_part = &lcd_bmp_part, | 197 | .bmp_part = &lcd_bmp_part, |
198 | .nine_segment_bmp = &lcd_nine_segment_bmp, | ||
198 | #if LCD_DEPTH > 1 | 199 | #if LCD_DEPTH > 1 |
199 | #if defined(HAVE_LCD_COLOR) && defined(LCD_REMOTE_DEPTH) && LCD_REMOTE_DEPTH > 1 | 200 | #if defined(HAVE_LCD_COLOR) && defined(LCD_REMOTE_DEPTH) && LCD_REMOTE_DEPTH > 1 |
200 | .color_to_native=&lcd_color_to_native, | 201 | .color_to_native=&lcd_color_to_native, |
diff --git a/apps/screen_access.h b/apps/screen_access.h index ab2ef4f14d..ea05a2294d 100644 --- a/apps/screen_access.h +++ b/apps/screen_access.h | |||
@@ -167,6 +167,10 @@ struct screen | |||
167 | unsigned start, unsigned end); | 167 | unsigned start, unsigned end); |
168 | #endif | 168 | #endif |
169 | #endif | 169 | #endif |
170 | #if defined(HAVE_LCD_BITMAP) | ||
171 | void (*nine_segment_bmp)(const struct bitmap* bm, int x, int y, | ||
172 | int width, int height); | ||
173 | #endif | ||
170 | }; | 174 | }; |
171 | 175 | ||
172 | #if defined(HAVE_LCD_BITMAP) || defined(HAVE_REMOTE_LCD) | 176 | #if defined(HAVE_LCD_BITMAP) || defined(HAVE_REMOTE_LCD) |
diff --git a/firmware/drivers/lcd-bitmap-common.c b/firmware/drivers/lcd-bitmap-common.c index 0bae790e58..a149e8aaa9 100644 --- a/firmware/drivers/lcd-bitmap-common.c +++ b/firmware/drivers/lcd-bitmap-common.c | |||
@@ -615,3 +615,48 @@ void LCDFN(bmp)(const struct bitmap* bm, int x, int y) | |||
615 | } | 615 | } |
616 | 616 | ||
617 | #endif | 617 | #endif |
618 | |||
619 | void LCDFN(nine_segment_bmp)(const struct bitmap* bm, int x, int y, | ||
620 | int width, int height) | ||
621 | { | ||
622 | int seg_w = bm->width / 3; | ||
623 | int seg_h = bm->height / 3; | ||
624 | int src_x, src_y, dst_x, dst_y; | ||
625 | |||
626 | /* top */ | ||
627 | src_x = seg_w; src_y = 0; | ||
628 | dst_x = seg_w; dst_y = 0; | ||
629 | for (; dst_x < width - seg_w; dst_x += seg_w) | ||
630 | LCDFN(bmp_part)(bm, src_x, src_y, dst_x, dst_y, seg_w, seg_h); | ||
631 | /* bottom */ | ||
632 | src_x = seg_w; src_y = bm->height - seg_h; | ||
633 | dst_x = seg_w; dst_y = height - seg_h; | ||
634 | for (; dst_x < width - seg_w; dst_x += seg_w) | ||
635 | LCDFN(bmp_part)(bm, src_x, src_y, dst_x, dst_y, seg_w, seg_h); | ||
636 | |||
637 | /* left */ | ||
638 | src_x = 0; src_y = seg_h; | ||
639 | dst_x = 0; dst_y = seg_h; | ||
640 | for (; dst_y < height - seg_h; dst_y += seg_h) | ||
641 | LCDFN(bmp_part)(bm, src_x, src_y, dst_x, dst_y, seg_w, seg_h); | ||
642 | /* right */ | ||
643 | src_x = bm->width - seg_w; src_y = seg_h; | ||
644 | dst_x = width - seg_w; dst_y = seg_h; | ||
645 | for (; dst_y < height - seg_h; dst_y += seg_h) | ||
646 | LCDFN(bmp_part)(bm, src_x, src_y, dst_x, dst_y, seg_w, seg_h); | ||
647 | /* center */ | ||
648 | dst_y = seg_h; src_y = seg_h; src_x = seg_w; | ||
649 | for (; dst_y < height - seg_h; dst_y += seg_h) | ||
650 | { | ||
651 | dst_x = seg_w; | ||
652 | for (; dst_x < width - seg_w; dst_x += seg_w) | ||
653 | LCDFN(bmp_part)(bm, src_x, src_y, dst_x, dst_y, seg_w, seg_h); | ||
654 | } | ||
655 | |||
656 | /* 4 corners */ | ||
657 | LCDFN(bmp_part)(bm, 0, 0, x, y, seg_w, seg_h); | ||
658 | LCDFN(bmp_part)(bm, bm->width - seg_w, 0, width - seg_w, 0, seg_w, seg_h); | ||
659 | LCDFN(bmp_part)(bm, 0, bm->width - seg_h, 0, height - seg_h, seg_w, seg_h); | ||
660 | LCDFN(bmp_part)(bm, bm->width - seg_w, bm->width - seg_h, | ||
661 | width - seg_w, height - seg_h, seg_w, seg_h); | ||
662 | } | ||
diff --git a/firmware/export/lcd.h b/firmware/export/lcd.h index dbb3a781b8..a82c00534d 100644 --- a/firmware/export/lcd.h +++ b/firmware/export/lcd.h | |||
@@ -568,6 +568,8 @@ extern void lcd_bitmap_transparent(const fb_data *src, int x, int y, | |||
568 | extern void lcd_bmp_part(const struct bitmap* bm, int src_x, int src_y, | 568 | extern void lcd_bmp_part(const struct bitmap* bm, int src_x, int src_y, |
569 | int x, int y, int width, int height); | 569 | int x, int y, int width, int height); |
570 | extern void lcd_bmp(const struct bitmap* bm, int x, int y); | 570 | extern void lcd_bmp(const struct bitmap* bm, int x, int y); |
571 | extern void lcd_nine_segment_bmp(const struct bitmap* bm, int x, int y, | ||
572 | int width, int height); | ||
571 | #endif /* HAVE_LCD_BITMAP */ | 573 | #endif /* HAVE_LCD_BITMAP */ |
572 | 574 | ||
573 | 575 | ||
diff --git a/lib/skin_parser/tag_table.c b/lib/skin_parser/tag_table.c index ec1476fb80..24dcf181d4 100644 --- a/lib/skin_parser/tag_table.c +++ b/lib/skin_parser/tag_table.c | |||
@@ -179,6 +179,7 @@ static const struct tag_info legal_tags[] = | |||
179 | { SKIN_TOKEN_IMAGE_PRELOAD, "xl", "SF|III", 0|NOBREAK }, | 179 | { SKIN_TOKEN_IMAGE_PRELOAD, "xl", "SF|III", 0|NOBREAK }, |
180 | { SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY, "xd", "S|[IT]I", 0 }, | 180 | { SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY, "xd", "S|[IT]I", 0 }, |
181 | { SKIN_TOKEN_IMAGE_DISPLAY, "x", "SF|II", SKIN_REFRESH_STATIC|NOBREAK }, | 181 | { SKIN_TOKEN_IMAGE_DISPLAY, "x", "SF|II", SKIN_REFRESH_STATIC|NOBREAK }, |
182 | { SKIN_TOKEN_IMAGE_DISPLAY_9SEGMENT, "x9", "S", 0 }, | ||
182 | 183 | ||
183 | { SKIN_TOKEN_LOAD_FONT, "Fl" , "IF|I", 0|NOBREAK }, | 184 | { SKIN_TOKEN_LOAD_FONT, "Fl" , "IF|I", 0|NOBREAK }, |
184 | { SKIN_TOKEN_ALBUMART_LOAD, "Cl" , "IIII|ss", 0|NOBREAK }, | 185 | { SKIN_TOKEN_ALBUMART_LOAD, "Cl" , "IIII|ss", 0|NOBREAK }, |
diff --git a/lib/skin_parser/tag_table.h b/lib/skin_parser/tag_table.h index 41f7d7dd86..94f82fd759 100644 --- a/lib/skin_parser/tag_table.h +++ b/lib/skin_parser/tag_table.h | |||
@@ -163,6 +163,7 @@ enum skin_token_type { | |||
163 | SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY, | 163 | SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY, |
164 | SKIN_TOKEN_IMAGE_DISPLAY, | 164 | SKIN_TOKEN_IMAGE_DISPLAY, |
165 | SKIN_TOKEN_IMAGE_DISPLAY_LISTICON, | 165 | SKIN_TOKEN_IMAGE_DISPLAY_LISTICON, |
166 | SKIN_TOKEN_IMAGE_DISPLAY_9SEGMENT, | ||
166 | 167 | ||
167 | /* Albumart */ | 168 | /* Albumart */ |
168 | SKIN_TOKEN_ALBUMART_LOAD, | 169 | SKIN_TOKEN_ALBUMART_LOAD, |
diff --git a/manual/appendix/wps_tags.tex b/manual/appendix/wps_tags.tex index 9fea2bade3..7551276bdf 100644 --- a/manual/appendix/wps_tags.tex +++ b/manual/appendix/wps_tags.tex | |||
@@ -403,6 +403,13 @@ Examples: | |||
403 | use the first subimage when \config{\%mh} is on and the second when it is off\newline | 403 | use the first subimage when \config{\%mh} is on and the second when it is off\newline |
404 | \config{offset}: (optional) Add this number to the value from the \config{tag} when | 404 | \config{offset}: (optional) Add this number to the value from the \config{tag} when |
405 | chosing the subimage (may be negative)\\ | 405 | chosing the subimage (may be negative)\\ |
406 | \config{\%x9(n)} | ||
407 | & Display an image as a 9-patch bitmap covering the entire viewport.\newline | ||
408 | 9-patch images are bitmaps split into 9 segments where the four corners | ||
409 | are unscaled, the four middle sections are scaled along one axis and the middle | ||
410 | section is scaled on both axis.\newline | ||
411 | \config{n}: image ID\\ | ||
412 | |||
406 | \end{tagmap} | 413 | \end{tagmap} |
407 | 414 | ||
408 | Examples: | 415 | Examples: |