summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Gordon <rockbox@jdgordon.info>2012-12-03 20:43:58 +1100
committerJonathan Gordon <rockbox@jdgordon.info>2012-12-09 17:11:19 +1100
commit685cf5900825b10c952f36301abbbd9968567435 (patch)
tree41cdfed9e5a2943c80ac0d4ffe09c45519a3ecf3
parent1fbdc280d7e4b4ffb7ec8dccbfd1c1fc67f1c123 (diff)
downloadrockbox-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.c13
-rw-r--r--apps/gui/skin_engine/skin_display.h1
-rw-r--r--apps/gui/skin_engine/skin_parser.c5
-rw-r--r--apps/gui/skin_engine/skin_render.c1
-rw-r--r--apps/gui/skin_engine/wps_internals.h1
-rw-r--r--apps/screen_access.c1
-rw-r--r--apps/screen_access.h4
-rw-r--r--firmware/drivers/lcd-bitmap-common.c45
-rw-r--r--firmware/export/lcd.h2
-rw-r--r--lib/skin_parser/tag_table.c1
-rw-r--r--lib/skin_parser/tag_table.h1
-rw-r--r--manual/appendix/wps_tags.tex7
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
305void wps_draw_image(struct gui_wps *gwps, struct gui_img *img, int subimage) 305void 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
316void wps_display_images(struct gui_wps *gwps, struct viewport* vp) 319void 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);
34void draw_playlist_viewer_list(struct gui_wps *gwps, struct playlistviewer *viewer); 34void 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 */
36void clear_image_pos(struct gui_wps *gwps, struct gui_img *img); 36void clear_image_pos(struct gui_wps *gwps, struct gui_img *img);
37void wps_draw_image(struct gui_wps *gwps, struct gui_img *img, int subimage);
38void wps_display_images(struct gui_wps *gwps, struct viewport* vp); 37void 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
87struct image_display { 88struct 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
619void 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,
568extern void lcd_bmp_part(const struct bitmap* bm, int src_x, int src_y, 568extern 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);
570extern void lcd_bmp(const struct bitmap* bm, int x, int y); 570extern void lcd_bmp(const struct bitmap* bm, int x, int y);
571extern 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
408Examples: 415Examples: