mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-10-14 02:27:39 -04:00
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
This commit is contained in:
parent
1fbdc280d7
commit
685cf59008
12 changed files with 76 additions and 6 deletions
|
@ -302,17 +302,20 @@ void clear_image_pos(struct gui_wps *gwps, struct gui_img *img)
|
||||||
gwps->display->set_drawmode(DRMODE_SOLID);
|
gwps->display->set_drawmode(DRMODE_SOLID);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wps_draw_image(struct gui_wps *gwps, struct gui_img *img, int subimage)
|
void wps_draw_image(struct gui_wps *gwps, struct gui_img *img,
|
||||||
|
int subimage, struct viewport* vp)
|
||||||
{
|
{
|
||||||
struct screen *display = gwps->display;
|
struct screen *display = gwps->display;
|
||||||
img->bm.data = core_get_data(img->buflib_handle);
|
img->bm.data = core_get_data(img->buflib_handle);
|
||||||
display->set_drawmode(DRMODE_SOLID);
|
display->set_drawmode(DRMODE_SOLID);
|
||||||
|
|
||||||
|
if (img->is_9_segment)
|
||||||
|
display->nine_segment_bmp(&img->bm, 0, 0, vp->width, vp->height);
|
||||||
|
else
|
||||||
display->bmp_part(&img->bm, 0, img->subimage_height * subimage,
|
display->bmp_part(&img->bm, 0, img->subimage_height * subimage,
|
||||||
img->x, img->y, img->bm.width, img->subimage_height);
|
img->x, img->y, img->bm.width, img->subimage_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void wps_display_images(struct gui_wps *gwps, struct viewport* vp)
|
void wps_display_images(struct gui_wps *gwps, struct viewport* vp)
|
||||||
{
|
{
|
||||||
if(!gwps || !gwps->data || !gwps->display)
|
if(!gwps || !gwps->data || !gwps->display)
|
||||||
|
@ -334,7 +337,7 @@ void wps_display_images(struct gui_wps *gwps, struct viewport* vp)
|
||||||
{
|
{
|
||||||
if (img->display >= 0)
|
if (img->display >= 0)
|
||||||
{
|
{
|
||||||
wps_draw_image(gwps, img, img->display);
|
wps_draw_image(gwps, img, img->display, vp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
list = SKINOFFSETTOPTR(get_skin_buffer(data), list->next);
|
list = SKINOFFSETTOPTR(get_skin_buffer(data), list->next);
|
||||||
|
|
|
@ -34,7 +34,6 @@ void draw_progressbar(struct gui_wps *gwps, int line, struct progressbar *pb);
|
||||||
void draw_playlist_viewer_list(struct gui_wps *gwps, struct playlistviewer *viewer);
|
void draw_playlist_viewer_list(struct gui_wps *gwps, struct playlistviewer *viewer);
|
||||||
/* clears the area where the image was shown */
|
/* clears the area where the image was shown */
|
||||||
void clear_image_pos(struct gui_wps *gwps, struct gui_img *img);
|
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);
|
void wps_display_images(struct gui_wps *gwps, struct viewport* vp);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -344,6 +344,9 @@ static int parse_image_display(struct skin_element *element,
|
||||||
token->type = SKIN_TOKEN_IMAGE_DISPLAY_LISTICON;
|
token->type = SKIN_TOKEN_IMAGE_DISPLAY_LISTICON;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (token->type == SKIN_TOKEN_IMAGE_DISPLAY_9SEGMENT)
|
||||||
|
img->is_9_segment = true;
|
||||||
|
|
||||||
if (element->params_count > 1)
|
if (element->params_count > 1)
|
||||||
{
|
{
|
||||||
if (get_param(element, 1)->type == CODE)
|
if (get_param(element, 1)->type == CODE)
|
||||||
|
@ -417,6 +420,7 @@ static int parse_image_load(struct skin_element *element,
|
||||||
img->display = -1;
|
img->display = -1;
|
||||||
img->using_preloaded_icons = false;
|
img->using_preloaded_icons = false;
|
||||||
img->buflib_handle = -1;
|
img->buflib_handle = -1;
|
||||||
|
img->is_9_segment = false;
|
||||||
|
|
||||||
/* save current viewport */
|
/* save current viewport */
|
||||||
img->vp = PTRTOSKINOFFSET(skin_buffer, &curr_vp->vp);
|
img->vp = PTRTOSKINOFFSET(skin_buffer, &curr_vp->vp);
|
||||||
|
@ -2181,6 +2185,7 @@ static int skin_element_callback(struct skin_element* element, void* data)
|
||||||
token->value.data = get_param(element, 0)->data.text;
|
token->value.data = get_param(element, 0)->data.text;
|
||||||
break;
|
break;
|
||||||
case SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY:
|
case SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY:
|
||||||
|
case SKIN_TOKEN_IMAGE_DISPLAY_9SEGMENT:
|
||||||
function = parse_image_display;
|
function = parse_image_display;
|
||||||
break;
|
break;
|
||||||
case SKIN_TOKEN_IMAGE_PRELOAD:
|
case SKIN_TOKEN_IMAGE_PRELOAD:
|
||||||
|
|
|
@ -231,6 +231,7 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
|
||||||
break;
|
break;
|
||||||
case SKIN_TOKEN_IMAGE_DISPLAY_LISTICON:
|
case SKIN_TOKEN_IMAGE_DISPLAY_LISTICON:
|
||||||
case SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY:
|
case SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY:
|
||||||
|
case SKIN_TOKEN_IMAGE_DISPLAY_9SEGMENT:
|
||||||
{
|
{
|
||||||
struct image_display *id = SKINOFFSETTOPTR(skin_buffer, token->value.data);
|
struct image_display *id = SKINOFFSETTOPTR(skin_buffer, token->value.data);
|
||||||
const char* label = SKINOFFSETTOPTR(skin_buffer, id->label);
|
const char* label = SKINOFFSETTOPTR(skin_buffer, id->label);
|
||||||
|
|
|
@ -82,6 +82,7 @@ struct gui_img {
|
||||||
bool loaded; /* load state */
|
bool loaded; /* load state */
|
||||||
int display;
|
int display;
|
||||||
bool using_preloaded_icons; /* using the icon system instead of a bmp */
|
bool using_preloaded_icons; /* using the icon system instead of a bmp */
|
||||||
|
bool is_9_segment;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct image_display {
|
struct image_display {
|
||||||
|
|
|
@ -195,6 +195,7 @@ struct screen screens[NB_SCREENS] =
|
||||||
#endif
|
#endif
|
||||||
.bmp = &lcd_bmp,
|
.bmp = &lcd_bmp,
|
||||||
.bmp_part = &lcd_bmp_part,
|
.bmp_part = &lcd_bmp_part,
|
||||||
|
.nine_segment_bmp = &lcd_nine_segment_bmp,
|
||||||
#if LCD_DEPTH > 1
|
#if LCD_DEPTH > 1
|
||||||
#if defined(HAVE_LCD_COLOR) && defined(LCD_REMOTE_DEPTH) && LCD_REMOTE_DEPTH > 1
|
#if defined(HAVE_LCD_COLOR) && defined(LCD_REMOTE_DEPTH) && LCD_REMOTE_DEPTH > 1
|
||||||
.color_to_native=&lcd_color_to_native,
|
.color_to_native=&lcd_color_to_native,
|
||||||
|
|
|
@ -167,6 +167,10 @@ struct screen
|
||||||
unsigned start, unsigned end);
|
unsigned start, unsigned end);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(HAVE_LCD_BITMAP)
|
||||||
|
void (*nine_segment_bmp)(const struct bitmap* bm, int x, int y,
|
||||||
|
int width, int height);
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(HAVE_LCD_BITMAP) || defined(HAVE_REMOTE_LCD)
|
#if defined(HAVE_LCD_BITMAP) || defined(HAVE_REMOTE_LCD)
|
||||||
|
|
|
@ -615,3 +615,48 @@ void LCDFN(bmp)(const struct bitmap* bm, int x, int y)
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void LCDFN(nine_segment_bmp)(const struct bitmap* bm, int x, int y,
|
||||||
|
int width, int height)
|
||||||
|
{
|
||||||
|
int seg_w = bm->width / 3;
|
||||||
|
int seg_h = bm->height / 3;
|
||||||
|
int src_x, src_y, dst_x, dst_y;
|
||||||
|
|
||||||
|
/* top */
|
||||||
|
src_x = seg_w; src_y = 0;
|
||||||
|
dst_x = seg_w; dst_y = 0;
|
||||||
|
for (; dst_x < width - seg_w; dst_x += seg_w)
|
||||||
|
LCDFN(bmp_part)(bm, src_x, src_y, dst_x, dst_y, seg_w, seg_h);
|
||||||
|
/* bottom */
|
||||||
|
src_x = seg_w; src_y = bm->height - seg_h;
|
||||||
|
dst_x = seg_w; dst_y = height - seg_h;
|
||||||
|
for (; dst_x < width - seg_w; dst_x += seg_w)
|
||||||
|
LCDFN(bmp_part)(bm, src_x, src_y, dst_x, dst_y, seg_w, seg_h);
|
||||||
|
|
||||||
|
/* left */
|
||||||
|
src_x = 0; src_y = seg_h;
|
||||||
|
dst_x = 0; dst_y = seg_h;
|
||||||
|
for (; dst_y < height - seg_h; dst_y += seg_h)
|
||||||
|
LCDFN(bmp_part)(bm, src_x, src_y, dst_x, dst_y, seg_w, seg_h);
|
||||||
|
/* right */
|
||||||
|
src_x = bm->width - seg_w; src_y = seg_h;
|
||||||
|
dst_x = width - seg_w; dst_y = seg_h;
|
||||||
|
for (; dst_y < height - seg_h; dst_y += seg_h)
|
||||||
|
LCDFN(bmp_part)(bm, src_x, src_y, dst_x, dst_y, seg_w, seg_h);
|
||||||
|
/* center */
|
||||||
|
dst_y = seg_h; src_y = seg_h; src_x = seg_w;
|
||||||
|
for (; dst_y < height - seg_h; dst_y += seg_h)
|
||||||
|
{
|
||||||
|
dst_x = seg_w;
|
||||||
|
for (; dst_x < width - seg_w; dst_x += seg_w)
|
||||||
|
LCDFN(bmp_part)(bm, src_x, src_y, dst_x, dst_y, seg_w, seg_h);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 4 corners */
|
||||||
|
LCDFN(bmp_part)(bm, 0, 0, x, y, seg_w, seg_h);
|
||||||
|
LCDFN(bmp_part)(bm, bm->width - seg_w, 0, width - seg_w, 0, seg_w, seg_h);
|
||||||
|
LCDFN(bmp_part)(bm, 0, bm->width - seg_h, 0, height - seg_h, seg_w, seg_h);
|
||||||
|
LCDFN(bmp_part)(bm, bm->width - seg_w, bm->width - seg_h,
|
||||||
|
width - seg_w, height - seg_h, seg_w, seg_h);
|
||||||
|
}
|
||||||
|
|
|
@ -568,6 +568,8 @@ extern void lcd_bitmap_transparent(const fb_data *src, int x, int y,
|
||||||
extern void lcd_bmp_part(const struct bitmap* bm, int src_x, int src_y,
|
extern void lcd_bmp_part(const struct bitmap* bm, int src_x, int src_y,
|
||||||
int x, int y, int width, int height);
|
int x, int y, int width, int height);
|
||||||
extern void lcd_bmp(const struct bitmap* bm, int x, int y);
|
extern void lcd_bmp(const struct bitmap* bm, int x, int y);
|
||||||
|
extern void lcd_nine_segment_bmp(const struct bitmap* bm, int x, int y,
|
||||||
|
int width, int height);
|
||||||
#endif /* HAVE_LCD_BITMAP */
|
#endif /* HAVE_LCD_BITMAP */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -179,6 +179,7 @@ static const struct tag_info legal_tags[] =
|
||||||
{ SKIN_TOKEN_IMAGE_PRELOAD, "xl", "SF|III", 0|NOBREAK },
|
{ SKIN_TOKEN_IMAGE_PRELOAD, "xl", "SF|III", 0|NOBREAK },
|
||||||
{ SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY, "xd", "S|[IT]I", 0 },
|
{ SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY, "xd", "S|[IT]I", 0 },
|
||||||
{ SKIN_TOKEN_IMAGE_DISPLAY, "x", "SF|II", SKIN_REFRESH_STATIC|NOBREAK },
|
{ SKIN_TOKEN_IMAGE_DISPLAY, "x", "SF|II", SKIN_REFRESH_STATIC|NOBREAK },
|
||||||
|
{ SKIN_TOKEN_IMAGE_DISPLAY_9SEGMENT, "x9", "S", 0 },
|
||||||
|
|
||||||
{ SKIN_TOKEN_LOAD_FONT, "Fl" , "IF|I", 0|NOBREAK },
|
{ SKIN_TOKEN_LOAD_FONT, "Fl" , "IF|I", 0|NOBREAK },
|
||||||
{ SKIN_TOKEN_ALBUMART_LOAD, "Cl" , "IIII|ss", 0|NOBREAK },
|
{ SKIN_TOKEN_ALBUMART_LOAD, "Cl" , "IIII|ss", 0|NOBREAK },
|
||||||
|
|
|
@ -163,6 +163,7 @@ enum skin_token_type {
|
||||||
SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY,
|
SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY,
|
||||||
SKIN_TOKEN_IMAGE_DISPLAY,
|
SKIN_TOKEN_IMAGE_DISPLAY,
|
||||||
SKIN_TOKEN_IMAGE_DISPLAY_LISTICON,
|
SKIN_TOKEN_IMAGE_DISPLAY_LISTICON,
|
||||||
|
SKIN_TOKEN_IMAGE_DISPLAY_9SEGMENT,
|
||||||
|
|
||||||
/* Albumart */
|
/* Albumart */
|
||||||
SKIN_TOKEN_ALBUMART_LOAD,
|
SKIN_TOKEN_ALBUMART_LOAD,
|
||||||
|
|
|
@ -403,6 +403,13 @@ Examples:
|
||||||
use the first subimage when \config{\%mh} is on and the second when it is off\newline
|
use the first subimage when \config{\%mh} is on and the second when it is off\newline
|
||||||
\config{offset}: (optional) Add this number to the value from the \config{tag} when
|
\config{offset}: (optional) Add this number to the value from the \config{tag} when
|
||||||
chosing the subimage (may be negative)\\
|
chosing the subimage (may be negative)\\
|
||||||
|
\config{\%x9(n)}
|
||||||
|
& Display an image as a 9-patch bitmap covering the entire viewport.\newline
|
||||||
|
9-patch images are bitmaps split into 9 segments where the four corners
|
||||||
|
are unscaled, the four middle sections are scaled along one axis and the middle
|
||||||
|
section is scaled on both axis.\newline
|
||||||
|
\config{n}: image ID\\
|
||||||
|
|
||||||
\end{tagmap}
|
\end{tagmap}
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue