diff options
Diffstat (limited to 'apps/plugins/lua/rocklib_img.c')
-rw-r--r-- | apps/plugins/lua/rocklib_img.c | 150 |
1 files changed, 135 insertions, 15 deletions
diff --git a/apps/plugins/lua/rocklib_img.c b/apps/plugins/lua/rocklib_img.c index 68e5325ce0..1857fbec5d 100644 --- a/apps/plugins/lua/rocklib_img.c +++ b/apps/plugins/lua/rocklib_img.c | |||
@@ -81,6 +81,57 @@ struct rli_iter_d | |||
81 | struct rocklua_image *img; | 81 | struct rocklua_image *img; |
82 | }; | 82 | }; |
83 | 83 | ||
84 | /* viewport for rliimages to use rb functions */ | ||
85 | static struct viewport img_vp = | ||
86 | { | ||
87 | .x = 0, | ||
88 | .y = 0, | ||
89 | .width = 0, | ||
90 | .height = 0, | ||
91 | .font = FONT_UI, | ||
92 | .drawmode = DRMODE_SOLID, | ||
93 | #if LCD_DEPTH > 1 | ||
94 | .fg_pattern = LCD_WHITE, | ||
95 | .bg_pattern = LCD_BLACK, | ||
96 | #endif | ||
97 | }; | ||
98 | |||
99 | static void *img_address_fn(int x, int y) | ||
100 | { | ||
101 | /* Address lookup function | ||
102 | * core will use this to get an address from x/y coord | ||
103 | * depending on the lcd function core sometimes uses this for | ||
104 | * only the first and last address | ||
105 | * and handles subsequent address based on stride */ | ||
106 | |||
107 | struct frame_buffer_t *fb = img_vp.buffer; | ||
108 | /* LCD_STRIDEFORMAT & LCD_NATIVE_STRIDE macros allow Horiz screens to work with RB */ | ||
109 | #if LCD_STRIDEFORMAT == VERTICAL_STRIDE | ||
110 | size_t element = (x * LCD_NATIVE_STRIDE(fb->stride)) + y; | ||
111 | #else | ||
112 | size_t element = (y * LCD_NATIVE_STRIDE(fb->stride)) + x; | ||
113 | #endif | ||
114 | /* use mod fb->elems to protect from buffer ovfl */ | ||
115 | return fb->fb_ptr + (element % fb->elems); | ||
116 | } | ||
117 | /* sets an image into a vp to be used by rockbox image functions */ | ||
118 | static void img_set_as_vp(struct rocklua_image *img, struct viewport *vp) | ||
119 | { | ||
120 | int w = img->width; | ||
121 | int h = img->height; | ||
122 | vp->x = 0; | ||
123 | vp->y = 0; | ||
124 | vp->width = w; | ||
125 | vp->height = h; | ||
126 | |||
127 | static struct frame_buffer_t fb;/* warning passed to external fns */ | ||
128 | fb.elems = LCD_NBELEMS(w, h); /* recalculate these rb expects num pixels */ | ||
129 | fb.stride = STRIDE_MAIN(w, h); /* recalculate these */ | ||
130 | fb.data = img->data; | ||
131 | fb.get_address_fn = &img_address_fn; | ||
132 | rb->viewport_set_buffer(vp, &fb, SCREEN_MAIN); /* not multiscreen aware yet */ | ||
133 | } | ||
134 | |||
84 | /* __tostring information enums */ | 135 | /* __tostring information enums */ |
85 | enum rli_info {RLI_INFO_ALL = 0, RLI_INFO_TYPE, RLI_INFO_WIDTH, | 136 | enum rli_info {RLI_INFO_ALL = 0, RLI_INFO_TYPE, RLI_INFO_WIDTH, |
86 | RLI_INFO_HEIGHT, RLI_INFO_ELEMS, RLI_INFO_BYTES, | 137 | RLI_INFO_HEIGHT, RLI_INFO_ELEMS, RLI_INFO_BYTES, |
@@ -261,7 +312,7 @@ static void bounds_check_xy(lua_State *L, struct rocklua_image *img, | |||
261 | luaL_argerror(L, narg, ERR_IDX_RANGE); | 312 | luaL_argerror(L, narg, ERR_IDX_RANGE); |
262 | } /* bounds_check_xy */ | 313 | } /* bounds_check_xy */ |
263 | 314 | ||
264 | static struct rocklua_image* rli_checktype(lua_State *L, int arg) | 315 | static struct rocklua_image* rli_checktype_opt(lua_State *L, int arg) |
265 | { | 316 | { |
266 | #if 0 | 317 | #if 0 |
267 | return (struct rocklua_image*) luaL_checkudata(L, arg, ROCKLUA_IMAGE); | 318 | return (struct rocklua_image*) luaL_checkudata(L, arg, ROCKLUA_IMAGE); |
@@ -284,10 +335,17 @@ static struct rocklua_image* rli_checktype(lua_State *L, int arg) | |||
284 | } | 335 | } |
285 | } | 336 | } |
286 | } | 337 | } |
287 | 338 | /* Not a ROCKLUA IMAGE */ | |
288 | luaL_typerror(L, arg, ROCKLUA_IMAGE); /* else error */ | 339 | return NULL; |
289 | return NULL; /* to avoid warnings */ | ||
290 | #endif | 340 | #endif |
341 | } /* rli_checktype_opt*/ | ||
342 | |||
343 | static struct rocklua_image* rli_checktype(lua_State *L, int arg) | ||
344 | { | ||
345 | struct rocklua_image *img = rli_checktype_opt(L, arg); | ||
346 | if (img == NULL) | ||
347 | luaL_typerror(L, arg, ROCKLUA_IMAGE); | ||
348 | return img; | ||
291 | } /* rli_checktype */ | 349 | } /* rli_checktype */ |
292 | 350 | ||
293 | static struct rocklua_image * alloc_rlimage(lua_State *L, bool alloc_data, | 351 | static struct rocklua_image * alloc_rlimage(lua_State *L, bool alloc_data, |
@@ -519,6 +577,7 @@ static bool next_rli_iter(struct rli_iter_d *d) | |||
519 | return true; | 577 | return true; |
520 | } /* next_rli_iter */ | 578 | } /* next_rli_iter */ |
521 | 579 | ||
580 | #if 0 | ||
522 | static void d_line(struct rocklua_image *img, | 581 | static void d_line(struct rocklua_image *img, |
523 | int x1, int y1, | 582 | int x1, int y1, |
524 | int x2, int y2, | 583 | int x2, int y2, |
@@ -575,6 +634,38 @@ static void d_line(struct rocklua_image *img, | |||
575 | } | 634 | } |
576 | 635 | ||
577 | } /* d_line */ | 636 | } /* d_line */ |
637 | #endif | ||
638 | |||
639 | |||
640 | static void d_line(struct rocklua_image *img, | ||
641 | int x1, int y1, | ||
642 | int x2, int y2, | ||
643 | fb_data *clr) | ||
644 | { | ||
645 | /* NOTE! clr passed as pointer */ | ||
646 | #if LCD_DEPTH == 2 | ||
647 | img_vp.fg_pattern = 0x55 * (~(*clr) & 3); | ||
648 | img_vp.drawmode = DRMODE_FG; | ||
649 | #elif LCD_DEPTH > 1 | ||
650 | img_vp.fg_pattern = *clr; | ||
651 | img_vp.drawmode = DRMODE_FG; | ||
652 | #else /* bit of a hack to make sure lines show properly from lua */ | ||
653 | /* use rb.lcd_drawline if you want full control */ | ||
654 | |||
655 | img_vp.drawmode = *clr & (DRMODE_SOLID|DRMODE_INVERSEVID); | ||
656 | if (img_vp.drawmode != (DRMODE_SOLID|DRMODE_INVERSEVID)) | ||
657 | img_vp.drawmode = DRMODE_SOLID; | ||
658 | #endif | ||
659 | |||
660 | img_set_as_vp(img, &img_vp); | ||
661 | |||
662 | struct viewport *oldvp = rb->screens[SCREEN_MAIN]->set_viewport(&img_vp); | ||
663 | |||
664 | rb->lcd_drawline(x1 - 1, y1 - 1 , x2 - 1, y2 - 1); | ||
665 | |||
666 | rb->screens[SCREEN_MAIN]->set_viewport(oldvp); | ||
667 | |||
668 | } /* d_line */ | ||
578 | 669 | ||
579 | /* ellipse worker function */ | 670 | /* ellipse worker function */ |
580 | static void d_ellipse_elements(struct rocklua_image * img, | 671 | static void d_ellipse_elements(struct rocklua_image * img, |
@@ -1266,9 +1357,21 @@ RB_WRAP(lcd_clear_display) | |||
1266 | 1357 | ||
1267 | RB_WRAP(lcd_set_drawmode) | 1358 | RB_WRAP(lcd_set_drawmode) |
1268 | { | 1359 | { |
1360 | int previous; | ||
1269 | int mode = (int) luaL_checkint(L, 1); | 1361 | int mode = (int) luaL_checkint(L, 1); |
1270 | RB_SCREENS(L, 2, set_drawmode, mode); | 1362 | if (rli_checktype_opt(L, 2) != NULL) /* is rliimage? */ |
1271 | return 0; | 1363 | { |
1364 | previous = img_vp.drawmode; | ||
1365 | img_vp.drawmode = mode; | ||
1366 | } | ||
1367 | else | ||
1368 | { | ||
1369 | struct viewport *vp = *(RB_SCREEN_STRUCT(L, 2)->current_viewport); | ||
1370 | previous = vp->drawmode; | ||
1371 | RB_SCREENS(L, 2, set_drawmode, mode); | ||
1372 | } | ||
1373 | lua_pushinteger(L, previous); | ||
1374 | return 1; | ||
1272 | } | 1375 | } |
1273 | 1376 | ||
1274 | /* helper function for lcd_puts functions */ | 1377 | /* helper function for lcd_puts functions */ |
@@ -1443,6 +1546,7 @@ RB_WRAP(lcd_scroll_stop) | |||
1443 | 1546 | ||
1444 | static inline struct viewport* opt_viewport(lua_State *L, | 1547 | static inline struct viewport* opt_viewport(lua_State *L, |
1445 | int narg, | 1548 | int narg, |
1549 | bool set_coords, | ||
1446 | struct viewport* vp, | 1550 | struct viewport* vp, |
1447 | struct viewport* alt) | 1551 | struct viewport* alt) |
1448 | { | 1552 | { |
@@ -1450,14 +1554,23 @@ static inline struct viewport* opt_viewport(lua_State *L, | |||
1450 | return alt; | 1554 | return alt; |
1451 | 1555 | ||
1452 | luaL_checktype(L, narg, LUA_TTABLE); | 1556 | luaL_checktype(L, narg, LUA_TTABLE); |
1453 | 1557 | if (set_coords) | |
1454 | vp->x = check_tablevalue(L, "x", narg); | 1558 | { |
1455 | vp->y = check_tablevalue(L, "y", narg); | 1559 | vp->x = check_tablevalue(L, "x", narg); |
1456 | vp->width = check_tablevalue(L, "width", narg); | 1560 | vp->y = check_tablevalue(L, "y", narg); |
1457 | vp->height = check_tablevalue(L, "height", narg); | 1561 | vp->width = check_tablevalue(L, "width", narg); |
1458 | vp->font = check_tablevalue(L, "font", narg); | 1562 | vp->height = check_tablevalue(L, "height", narg); |
1563 | } | ||
1564 | vp->font = check_tablevalue_def(L, "font", narg, FONT_UI); | ||
1459 | vp->drawmode = check_tablevalue_def(L, "drawmode", narg, DRMODE_SOLID); | 1565 | vp->drawmode = check_tablevalue_def(L, "drawmode", narg, DRMODE_SOLID); |
1460 | #if LCD_DEPTH > 1 | 1566 | |
1567 | #if LCD_DEPTH == 2 | ||
1568 | unsigned int fg = check_tablevalue(L, "fg_pattern", narg); | ||
1569 | unsigned int bg = check_tablevalue(L, "bg_pattern", narg); | ||
1570 | /*invert fg and bg patterns (3-)*/ | ||
1571 | vp->fg_pattern = 0x55 * (3 - (~(fg) & 3)); | ||
1572 | vp->bg_pattern = 0x55 * (3 - (~(bg) & 3)); | ||
1573 | #elif LCD_DEPTH > 1 | ||
1461 | vp->fg_pattern = (unsigned int) check_tablevalue(L, "fg_pattern", narg); | 1574 | vp->fg_pattern = (unsigned int) check_tablevalue(L, "fg_pattern", narg); |
1462 | vp->bg_pattern = (unsigned int) check_tablevalue(L, "bg_pattern", narg); | 1575 | vp->bg_pattern = (unsigned int) check_tablevalue(L, "bg_pattern", narg); |
1463 | #endif | 1576 | #endif |
@@ -1467,8 +1580,15 @@ static inline struct viewport* opt_viewport(lua_State *L, | |||
1467 | 1580 | ||
1468 | RB_WRAP(set_viewport) | 1581 | RB_WRAP(set_viewport) |
1469 | { | 1582 | { |
1583 | void *ud = rli_checktype_opt(L, 1); | ||
1584 | if (ud != NULL) | ||
1585 | { | ||
1586 | img_set_as_vp((struct rocklua_image*) ud, &img_vp); | ||
1587 | RB_SCREENS(L, 3, set_viewport, opt_viewport(L, 2, false, &img_vp, &img_vp)); | ||
1588 | return 0; | ||
1589 | } | ||
1470 | static struct viewport vp; | 1590 | static struct viewport vp; |
1471 | RB_SCREENS(L, 2, set_viewport, opt_viewport(L, 1, &vp, NULL)); | 1591 | RB_SCREENS(L, 2, set_viewport, opt_viewport(L, 1, true, &vp, NULL)); |
1472 | return 0; | 1592 | return 0; |
1473 | } | 1593 | } |
1474 | 1594 | ||
@@ -1489,7 +1609,7 @@ RB_WRAP(font_getstringsize) | |||
1489 | else | 1609 | else |
1490 | fontnumber = FONT_SYSFIXED; | 1610 | fontnumber = FONT_SYSFIXED; |
1491 | 1611 | ||
1492 | if lua_isnil(L, 2) | 1612 | if lua_isnoneornil(L, 2) |
1493 | result = RB_SCREENS(L, 3, getstringsize, str, &w, &h); | 1613 | result = RB_SCREENS(L, 3, getstringsize, str, &w, &h); |
1494 | else | 1614 | else |
1495 | result = rb->font_getstringsize(str, &w, &h, fontnumber); | 1615 | result = rb->font_getstringsize(str, &w, &h, fontnumber); |