1 /**
2  * Copyright (c) 2006-2016 LOVE Development Team
3  *
4  * This software is provided 'as-is', without any express or implied
5  * warranty.  In no event will the authors be held liable for any damages
6  * arising from the use of this software.
7  *
8  * Permission is granted to anyone to use this software for any purpose,
9  * including commercial applications, and to alter it and redistribute it
10  * freely, subject to the following restrictions:
11  *
12  * 1. The origin of this software must not be misrepresented; you must not
13  *    claim that you wrote the original software. If you use this software
14  *    in a product, an acknowledgment in the product documentation would be
15  *    appreciated but is not required.
16  * 2. Altered source versions must be plainly marked as such, and must not be
17  *    misrepresented as being the original software.
18  * 3. This notice may not be removed or altered from any source distribution.
19  **/
20 
21 #include "wrap_Canvas.h"
22 #include "Graphics.h"
23 
24 namespace love
25 {
26 namespace graphics
27 {
28 namespace opengl
29 {
30 
luax_checkcanvas(lua_State * L,int idx)31 Canvas *luax_checkcanvas(lua_State *L, int idx)
32 {
33 	return luax_checktype<Canvas>(L, idx, GRAPHICS_CANVAS_ID);
34 }
35 
w_Canvas_renderTo(lua_State * L)36 int w_Canvas_renderTo(lua_State *L)
37 {
38 	Canvas *canvas = luax_checkcanvas(L, 1);
39 	luaL_checktype(L, 2, LUA_TFUNCTION);
40 
41 	auto graphics = Module::getInstance<Graphics>(Module::M_GRAPHICS);
42 
43 	if (graphics)
44 	{
45 		// Save the current Canvas so we can restore it when we're done.
46 		std::vector<Canvas *> oldcanvases = graphics->getCanvas();
47 
48 		for (Canvas *c : oldcanvases)
49 			c->retain();
50 
51 		luax_catchexcept(L, [&](){ graphics->setCanvas(canvas); });
52 
53 		lua_settop(L, 2); // make sure the function is on top of the stack
54 		int status = lua_pcall(L, 0, 0, 0);
55 
56 		graphics->setCanvas(oldcanvases);
57 
58 		for (Canvas *c : oldcanvases)
59 			c->release();
60 
61 		if (status != 0)
62 			return lua_error(L);
63 	}
64 
65 	return 0;
66 }
67 
w_Canvas_newImageData(lua_State * L)68 int w_Canvas_newImageData(lua_State *L)
69 {
70 	Canvas *canvas = luax_checkcanvas(L, 1);
71 	love::image::Image *image = luax_getmodule<love::image::Image>(L, MODULE_IMAGE_ID);
72 	int x = (int) luaL_optnumber(L, 2, 0);
73 	int y = (int) luaL_optnumber(L, 3, 0);
74 	int w = (int) luaL_optnumber(L, 4, canvas->getWidth());
75 	int h = (int) luaL_optnumber(L, 5, canvas->getHeight());
76 
77 	love::image::ImageData *img = nullptr;
78 	luax_catchexcept(L, [&](){ img = canvas->newImageData(image, x, y, w, h); });
79 
80 	luax_pushtype(L, IMAGE_IMAGE_DATA_ID, img);
81 	img->release();
82 	return 1;
83 }
84 
w_Canvas_getFormat(lua_State * L)85 int w_Canvas_getFormat(lua_State *L)
86 {
87 	Canvas *canvas = luax_checkcanvas(L, 1);
88 	Canvas::Format format = canvas->getTextureFormat();
89 	const char *str;
90 	if (!Canvas::getConstant(format, str))
91 		return luaL_error(L, "Unknown Canvas format.");
92 
93 	lua_pushstring(L, str);
94 	return 1;
95 }
96 
w_Canvas_getMSAA(lua_State * L)97 int w_Canvas_getMSAA(lua_State *L)
98 {
99 	Canvas *canvas = luax_checkcanvas(L, 1);
100 	lua_pushinteger(L, canvas->getMSAA());
101 	return 1;
102 }
103 
104 static const luaL_Reg w_Canvas_functions[] =
105 {
106 	{ "renderTo", w_Canvas_renderTo },
107 	{ "newImageData", w_Canvas_newImageData },
108 	{ "getFormat", w_Canvas_getFormat },
109 	{ "getMSAA", w_Canvas_getMSAA },
110 	{ 0, 0 }
111 };
112 
luaopen_canvas(lua_State * L)113 extern "C" int luaopen_canvas(lua_State *L)
114 {
115 	return luax_register_type(L, GRAPHICS_CANVAS_ID, "Canvas", w_Texture_functions, w_Canvas_functions, nullptr);
116 }
117 
118 } // opengl
119 } // graphics
120 } // love
121