1 /*- 2 * Copyright (c) 2024 Netflix, Inc. 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7 /* Copied from a file that likely shoulve have had this at the top */ 8 /*- 9 * SPDX-License-Identifier: BSD-2-Clause 10 * 11 * Copyright 2020 Toomas Soome 12 * Copyright 2020 RackTop Systems, Inc. 13 * 14 * Redistribution and use in source and binary forms, with or without 15 * modification, are permitted provided that the following conditions 16 * are met: 17 * 1. Redistributions of source code must retain the above copyright 18 * notice, this list of conditions and the following disclaimer. 19 * 2. Redistributions in binary form must reproduce the above copyright 20 * notice, this list of conditions and the following disclaimer in the 21 * documentation and/or other materials provided with the distribution. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36 #include "lua.h" 37 #include "lauxlib.h" 38 #include "lutils.h" 39 #include <gfx_fb.h> 40 #include <pnglite.h> 41 42 /* 43 * put image using terminal coordinates. 44 */ 45 static int 46 lua_term_putimage(lua_State *L) 47 { 48 const char *name; 49 png_t png; 50 uint32_t x1, y1, x2, y2, f; 51 int nargs, ret = 0, error; 52 53 nargs = lua_gettop(L); 54 if (nargs != 6) { 55 lua_pushboolean(L, 0); 56 return 1; 57 } 58 59 name = luaL_checkstring(L, 1); 60 x1 = luaL_checknumber(L, 2); 61 y1 = luaL_checknumber(L, 3); 62 x2 = luaL_checknumber(L, 4); 63 y2 = luaL_checknumber(L, 5); 64 f = luaL_checknumber(L, 6); 65 66 x1 = gfx_state.tg_origin.tp_col + x1 * gfx_state.tg_font.vf_width; 67 y1 = gfx_state.tg_origin.tp_row + y1 * gfx_state.tg_font.vf_height; 68 if (x2 != 0) { 69 x2 = gfx_state.tg_origin.tp_col + 70 x2 * gfx_state.tg_font.vf_width; 71 } 72 if (y2 != 0) { 73 y2 = gfx_state.tg_origin.tp_row + 74 y2 * gfx_state.tg_font.vf_height; 75 } 76 77 if ((error = png_open(&png, name)) != PNG_NO_ERROR) { 78 if (f & FL_PUTIMAGE_DEBUG) 79 printf("%s\n", png_error_string(error)); 80 } else { 81 if (gfx_fb_putimage(&png, x1, y1, x2, y2, f) == 0) 82 ret = 1; 83 (void) png_close(&png); 84 } 85 lua_pushboolean(L, ret); 86 return 1; 87 } 88 89 static int 90 lua_fb_putimage(lua_State *L) 91 { 92 const char *name; 93 png_t png; 94 uint32_t x1, y1, x2, y2, f; 95 int nargs, ret = 0, error; 96 97 nargs = lua_gettop(L); 98 if (nargs != 6) { 99 lua_pushboolean(L, 0); 100 return 1; 101 } 102 103 name = luaL_checkstring(L, 1); 104 x1 = luaL_checknumber(L, 2); 105 y1 = luaL_checknumber(L, 3); 106 x2 = luaL_checknumber(L, 4); 107 y2 = luaL_checknumber(L, 5); 108 f = luaL_checknumber(L, 6); 109 110 if ((error = png_open(&png, name)) != PNG_NO_ERROR) { 111 if (f & FL_PUTIMAGE_DEBUG) 112 printf("%s\n", png_error_string(error)); 113 } else { 114 if (gfx_fb_putimage(&png, x1, y1, x2, y2, f) == 0) 115 ret = 1; 116 (void) png_close(&png); 117 } 118 lua_pushboolean(L, ret); 119 return 1; 120 } 121 122 static int 123 lua_fb_setpixel(lua_State *L) 124 { 125 uint32_t x, y; 126 int nargs; 127 128 nargs = lua_gettop(L); 129 if (nargs != 2) { 130 lua_pushnil(L); 131 return 1; 132 } 133 134 x = luaL_checknumber(L, 1); 135 y = luaL_checknumber(L, 2); 136 gfx_fb_setpixel(x, y); 137 return 0; 138 } 139 140 static int 141 lua_fb_line(lua_State *L) 142 { 143 uint32_t x0, y0, x1, y1, wd; 144 int nargs; 145 146 nargs = lua_gettop(L); 147 if (nargs != 5) { 148 lua_pushnil(L); 149 return 1; 150 } 151 152 x0 = luaL_checknumber(L, 1); 153 y0 = luaL_checknumber(L, 2); 154 x1 = luaL_checknumber(L, 3); 155 y1 = luaL_checknumber(L, 4); 156 wd = luaL_checknumber(L, 5); 157 gfx_fb_line(x0, y0, x1, y1, wd); 158 return 0; 159 } 160 161 static int 162 lua_fb_bezier(lua_State *L) 163 { 164 uint32_t x0, y0, x1, y1, x2, y2, width; 165 int nargs; 166 167 nargs = lua_gettop(L); 168 if (nargs != 7) { 169 lua_pushnil(L); 170 return 1; 171 } 172 173 x0 = luaL_checknumber(L, 1); 174 y0 = luaL_checknumber(L, 2); 175 x1 = luaL_checknumber(L, 3); 176 y1 = luaL_checknumber(L, 4); 177 x2 = luaL_checknumber(L, 5); 178 y2 = luaL_checknumber(L, 6); 179 width = luaL_checknumber(L, 7); 180 gfx_fb_bezier(x0, y0, x1, y1, x2, y2, width); 181 return 0; 182 } 183 184 static int 185 lua_fb_drawrect(lua_State *L) 186 { 187 uint32_t x0, y0, x1, y1, fill; 188 int nargs; 189 190 nargs = lua_gettop(L); 191 if (nargs != 5) { 192 lua_pushnil(L); 193 return 1; 194 } 195 196 x0 = luaL_checknumber(L, 1); 197 y0 = luaL_checknumber(L, 2); 198 x1 = luaL_checknumber(L, 3); 199 y1 = luaL_checknumber(L, 4); 200 fill = luaL_checknumber(L, 5); 201 gfx_fb_drawrect(x0, y0, x1, y1, fill); 202 return 0; 203 } 204 205 static int 206 lua_term_drawrect(lua_State *L) 207 { 208 uint32_t x0, y0, x1, y1; 209 int nargs; 210 211 nargs = lua_gettop(L); 212 if (nargs != 4) { 213 lua_pushnil(L); 214 return 1; 215 } 216 217 x0 = luaL_checknumber(L, 1); 218 y0 = luaL_checknumber(L, 2); 219 x1 = luaL_checknumber(L, 3); 220 y1 = luaL_checknumber(L, 4); 221 gfx_term_drawrect(x0, y0, x1, y1); 222 return 0; 223 } 224 225 #define REG_SIMPLE(n) { #n, lua_ ## n } 226 static const struct luaL_Reg gfxlib[] = { 227 REG_SIMPLE(fb_bezier), 228 REG_SIMPLE(fb_drawrect), 229 REG_SIMPLE(fb_line), 230 REG_SIMPLE(fb_putimage), 231 REG_SIMPLE(fb_setpixel), 232 REG_SIMPLE(term_drawrect), 233 REG_SIMPLE(term_putimage), 234 { NULL, NULL }, 235 }; 236 237 int 238 luaopen_gfx(lua_State *L) 239 { 240 luaL_newlib(L, gfxlib); 241 return 1; 242 } 243 244 void 245 gfx_interp_ref(void) 246 { 247 } 248 249 static void 250 gfx_init_md(lua_State *L) 251 { 252 luaL_requiref(L, "gfx", luaopen_gfx, 1); 253 lua_pop(L, 1); /* Remove lib */ 254 255 /* 256 * Add in the compatibility references in the loader table. Doing it with 257 * a pseudo-embedded script is easier than the raw calls. 258 */ 259 if (luaL_dostring(L, 260 "loader.fb_bezier = gfx.fb_bezier\n" 261 "loader.fb_drawrect = gfx.fb_drawrect\n" 262 "loader.fb_line = gfx.fb_line\n" 263 "loader.fb_putimage = gfx.fb_putimage\n" 264 "loader.fb_setpixel = gfx.fb_setpixel\n" 265 "loader.term_drawrect = gfx.term_drawrect\n" 266 "loader.term_putimage = gfx.term_putimage") != 0) { 267 lua_pop(L, 1); 268 const char *errstr = lua_tostring(L, -1); 269 errstr = errstr == NULL ? "unknown" : errstr; 270 printf("Error adding compat loader bindings: %s.\n", errstr); 271 } 272 } 273 274 LUA_COMPILE_SET(gfx_init_md); 275