blob: 144753980ed50ecaadf86897369315a6acc6b13b [file]
#ifdef WITH_RIVE_SCRIPTING
#include "lua.h"
#include "lualib.h"
#include "rive/lua/rive_lua_libs.hpp"
using namespace rive;
// Defined in lua_gpu.cpp (compiled as ObjC++ on Apple, has ore includes).
#ifdef RIVE_ORE
extern int riveImageViewImpl(lua_State* L);
#endif
// Out-of-line destructor. The rcp<ore::TextureView> member (when
// RIVE_CANVAS && RIVE_ORE) prevents implicit ~ScriptedImage() in TUs
// that don't include the full ore headers. When ore is not enabled the
// default-generated body is fine.
#if !(defined(RIVE_CANVAS) && defined(RIVE_ORE))
ScriptedImage::~ScriptedImage() = default;
ScriptedImage* ScriptedImage::luaNew(lua_State* L)
{
return lua_newrive<ScriptedImage>(L);
}
#endif
static void image_direct_width(void* udata, void* result)
{
auto* self = (ScriptedImage*)udata;
lua_userdatadirectfield_setnumber(result,
self->image ? (double)self->image->width()
: 0);
}
static void image_direct_height(void* udata, void* result)
{
auto* self = (ScriptedImage*)udata;
lua_userdatadirectfield_setnumber(
result,
self->image ? (double)self->image->height() : 0);
}
static int image_index(lua_State* L)
{
auto image = lua_torive<ScriptedImage>(L, 1);
int atom;
const char* name = lua_tostringatom(L, 2, &atom);
if (!name)
{
luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING));
}
switch (atom)
{
case (int)LuaAtoms::width:
lua_pushnumber(L, image->image ? image->image->width() : 0);
return 1;
case (int)LuaAtoms::height:
lua_pushnumber(L, image->image ? image->image->height() : 0);
return 1;
#ifdef RIVE_ORE
case (int)LuaAtoms::view:
lua_pushcfunction(L, riveImageViewImpl, "Image.view");
return 1;
#endif
}
luaL_error(L,
"'%s' is not a valid index of %s",
name,
ScriptedImage::luaName);
return 0;
}
static int imagesampler_construct(lua_State* L)
{
int wrapXAtom;
const char* wrapXName = lua_tostringatom(L, 1, &wrapXAtom);
if (!wrapXName)
{
luaL_typeerrorL(L, 1, lua_typename(L, LUA_TSTRING));
}
int wrapYAtom;
const char* wrapYName = lua_tostringatom(L, 2, &wrapYAtom);
if (!wrapYName)
{
luaL_typeerrorL(L, 2, lua_typename(L, LUA_TSTRING));
}
int imageFilterAtom;
const char* imageFilterName = lua_tostringatom(L, 3, &imageFilterAtom);
if (!imageFilterName)
{
luaL_typeerrorL(L, 3, lua_typename(L, LUA_TSTRING));
}
ImageWrap wrapX = ImageWrap::clamp;
ImageWrap wrapY = ImageWrap::clamp;
ImageFilter filter = ImageFilter::bilinear;
switch (wrapXAtom)
{
case (int)LuaAtoms::clamp:
break;
case (int)LuaAtoms::repeat:
wrapX = ImageWrap::repeat;
break;
case (int)LuaAtoms::mirror:
wrapX = ImageWrap::mirror;
break;
default:
luaL_error(L, "'%s' is not a valid ImageWrap", wrapXName);
break;
}
switch (wrapYAtom)
{
case (int)LuaAtoms::clamp:
break;
case (int)LuaAtoms::repeat:
wrapY = ImageWrap::repeat;
break;
case (int)LuaAtoms::mirror:
wrapY = ImageWrap::mirror;
break;
default:
luaL_error(L, "'%s' is not a valid ImageWrap", wrapYName);
break;
}
switch (imageFilterAtom)
{
case (int)LuaAtoms::bilinear:
break;
case (int)LuaAtoms::nearest:
filter = ImageFilter::nearest;
break;
default:
luaL_error(L, "'%s' is not a valid ImageFilter", imageFilterName);
break;
}
lua_newrive<ScriptedImageSampler>(L, wrapX, wrapY, filter);
return 1;
}
int luaopen_rive_image(lua_State* L)
{
lua_register_rive<ScriptedImage>(L);
lua_pushcfunction(L, image_index, nullptr);
lua_setfield(L, -2, "__index");
lua_setreadonly(L, -1, true);
lua_pop(L, 1);
lua_registeruserdatadirectfieldget(L,
ScriptedImage::luaTag,
"width",
image_direct_width);
lua_registeruserdatadirectfieldget(L,
ScriptedImage::luaTag,
"height",
image_direct_height);
lua_pushcfunction(L, imagesampler_construct, ScriptedImageSampler::luaName);
lua_setfield(L, LUA_GLOBALSINDEX, ScriptedImageSampler::luaName);
lua_register_rive<ScriptedImageSampler>(L);
return 0;
}
#endif