summaryrefslogtreecommitdiff
path: root/apps/plugins/lua/rocklib_img.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/lua/rocklib_img.c')
-rw-r--r--apps/plugins/lua/rocklib_img.c150
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 */
85static 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
99static 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 */
118static 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 */
85enum rli_info {RLI_INFO_ALL = 0, RLI_INFO_TYPE, RLI_INFO_WIDTH, 136enum 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
264static struct rocklua_image* rli_checktype(lua_State *L, int arg) 315static 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
343static 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
293static struct rocklua_image * alloc_rlimage(lua_State *L, bool alloc_data, 351static 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
522static void d_line(struct rocklua_image *img, 581static 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
640static 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 */
580static void d_ellipse_elements(struct rocklua_image * img, 671static void d_ellipse_elements(struct rocklua_image * img,
@@ -1266,9 +1357,21 @@ RB_WRAP(lcd_clear_display)
1266 1357
1267RB_WRAP(lcd_set_drawmode) 1358RB_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
1444static inline struct viewport* opt_viewport(lua_State *L, 1547static 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
1468RB_WRAP(set_viewport) 1581RB_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);