1 | // Aseprite |
2 | // Copyright (C) 2019 Igara Studio S.A. |
3 | // Copyright (C) 2017-2018 David Capello |
4 | // |
5 | // This program is distributed under the terms of |
6 | // the End-User License Agreement for Aseprite. |
7 | |
8 | #ifdef HAVE_CONFIG_H |
9 | #include "config.h" |
10 | #endif |
11 | |
12 | #include "app/script/luacpp.h" |
13 | #include "fmt/format.h" |
14 | #include "gfx/point.h" |
15 | #include "gfx/rect.h" |
16 | |
17 | namespace app { |
18 | namespace script { |
19 | |
20 | namespace { |
21 | |
22 | gfx::Rect Rectangle_new(lua_State* L, int index) |
23 | { |
24 | gfx::Rect rc(0, 0, 0, 0); |
25 | // Copy other rectangle |
26 | if (auto rc2 = may_get_obj<gfx::Rect>(L, index)) { |
27 | rc = *rc2; |
28 | } |
29 | // Convert { x, y, width, height } into a Rectangle |
30 | else if (lua_istable(L, index)) { |
31 | const int type = lua_getfield(L, index, "x" ); |
32 | if (VALID_LUATYPE(type)) { |
33 | lua_getfield(L, index, "y" ); |
34 | lua_getfield(L, index, "width" ); |
35 | lua_getfield(L, index, "height" ); |
36 | rc.x = lua_tointeger(L, -4); |
37 | rc.y = lua_tointeger(L, -3); |
38 | rc.w = lua_tointeger(L, -2); |
39 | rc.h = lua_tointeger(L, -1); |
40 | lua_pop(L, 4); |
41 | } |
42 | else { |
43 | lua_pop(L, 1); |
44 | lua_geti(L, index, 1); |
45 | lua_geti(L, index, 2); |
46 | lua_geti(L, index, 3); |
47 | lua_geti(L, index, 4); |
48 | rc.x = lua_tointeger(L, -4); |
49 | rc.y = lua_tointeger(L, -3); |
50 | rc.w = lua_tointeger(L, -2); |
51 | rc.h = lua_tointeger(L, -1); |
52 | lua_pop(L, 4); |
53 | } |
54 | } |
55 | else { |
56 | rc.x = lua_tointeger(L, index); |
57 | rc.y = lua_tointeger(L, index+1); |
58 | rc.w = lua_tointeger(L, index+2); |
59 | rc.h = lua_tointeger(L, index+3); |
60 | } |
61 | return rc; |
62 | } |
63 | |
64 | int Rectangle_new(lua_State* L) |
65 | { |
66 | push_obj(L, Rectangle_new(L, 1)); |
67 | return 1; |
68 | } |
69 | |
70 | int Rectangle_gc(lua_State* L) |
71 | { |
72 | get_obj<gfx::Rect>(L, 1)->~RectT(); |
73 | return 0; |
74 | } |
75 | |
76 | int Rectangle_eq(lua_State* L) |
77 | { |
78 | const auto a = get_obj<gfx::Rect>(L, 1); |
79 | const auto b = get_obj<gfx::Rect>(L, 2); |
80 | lua_pushboolean(L, *a == *b); |
81 | return 1; |
82 | } |
83 | |
84 | int Rectangle_tostring(lua_State* L) |
85 | { |
86 | const auto rc = get_obj<gfx::Rect>(L, 1); |
87 | lua_pushstring(L, fmt::format("Rectangle{{ x={}, y={}, width={}, height={} }}" , |
88 | rc->x, rc->y, rc->w, rc->h).c_str()); |
89 | return 1; |
90 | } |
91 | |
92 | int Rectangle_contains(lua_State* L) |
93 | { |
94 | const auto a = get_obj<gfx::Rect>(L, 1); |
95 | const auto b = get_obj<gfx::Rect>(L, 2); |
96 | lua_pushboolean(L, a->contains(*b)); |
97 | return 1; |
98 | } |
99 | |
100 | int Rectangle_intersects(lua_State* L) |
101 | { |
102 | const auto a = get_obj<gfx::Rect>(L, 1); |
103 | const auto b = get_obj<gfx::Rect>(L, 2); |
104 | lua_pushboolean(L, a->intersects(*b)); |
105 | return 1; |
106 | } |
107 | |
108 | int Rectangle_union(lua_State* L) |
109 | { |
110 | const auto a = get_obj<gfx::Rect>(L, 1); |
111 | const auto b = get_obj<gfx::Rect>(L, 2); |
112 | push_obj(L, a->createUnion(*b)); |
113 | return 1; |
114 | } |
115 | |
116 | int Rectangle_intersect(lua_State* L) |
117 | { |
118 | const auto a = get_obj<gfx::Rect>(L, 1); |
119 | const auto b = get_obj<gfx::Rect>(L, 2); |
120 | push_obj(L, a->createIntersection(*b)); |
121 | return 1; |
122 | } |
123 | |
124 | int Rectangle_get_x(lua_State* L) |
125 | { |
126 | const auto rc = get_obj<gfx::Rect>(L, 1); |
127 | lua_pushinteger(L, rc->x); |
128 | return 1; |
129 | } |
130 | |
131 | int Rectangle_get_y(lua_State* L) |
132 | { |
133 | const auto rc = get_obj<gfx::Rect>(L, 1); |
134 | lua_pushinteger(L, rc->y); |
135 | return 1; |
136 | } |
137 | |
138 | int Rectangle_get_width(lua_State* L) |
139 | { |
140 | const auto rc = get_obj<gfx::Rect>(L, 1); |
141 | lua_pushinteger(L, rc->w); |
142 | return 1; |
143 | } |
144 | |
145 | int Rectangle_get_height(lua_State* L) |
146 | { |
147 | const auto rc = get_obj<gfx::Rect>(L, 1); |
148 | lua_pushinteger(L, rc->h); |
149 | return 1; |
150 | } |
151 | |
152 | int Rectangle_set_x(lua_State* L) |
153 | { |
154 | auto rc = get_obj<gfx::Rect>(L, 1); |
155 | rc->x = lua_tointeger(L, 2); |
156 | return 0; |
157 | } |
158 | |
159 | int Rectangle_set_y(lua_State* L) |
160 | { |
161 | auto rc = get_obj<gfx::Rect>(L, 1); |
162 | rc->y = lua_tointeger(L, 2); |
163 | return 0; |
164 | } |
165 | |
166 | int Rectangle_set_width(lua_State* L) |
167 | { |
168 | auto rc = get_obj<gfx::Rect>(L, 1); |
169 | rc->w = lua_tointeger(L, 2); |
170 | return 0; |
171 | } |
172 | |
173 | int Rectangle_set_height(lua_State* L) |
174 | { |
175 | auto rc = get_obj<gfx::Rect>(L, 1); |
176 | rc->h = lua_tointeger(L, 2); |
177 | return 0; |
178 | } |
179 | |
180 | int Rectangle_get_isEmpty(lua_State* L) |
181 | { |
182 | const auto rc = get_obj<gfx::Rect>(L, 1); |
183 | lua_pushboolean(L, rc->isEmpty()); |
184 | return 1; |
185 | } |
186 | |
187 | const luaL_Reg Rectangle_methods[] = { |
188 | { "__gc" , Rectangle_gc }, |
189 | { "__eq" , Rectangle_eq }, |
190 | { "__tostring" , Rectangle_tostring }, |
191 | { "__band" , Rectangle_intersect }, |
192 | { "__bor" , Rectangle_union }, |
193 | { "contains" , Rectangle_contains }, |
194 | { "intersects" , Rectangle_intersects }, |
195 | { "union" , Rectangle_union }, |
196 | { "intersect" , Rectangle_intersect }, |
197 | { nullptr, nullptr } |
198 | }; |
199 | |
200 | const Property Rectangle_properties[] = { |
201 | { "x" , Rectangle_get_x, Rectangle_set_x }, |
202 | { "y" , Rectangle_get_y, Rectangle_set_y }, |
203 | { "width" , Rectangle_get_width, Rectangle_set_width }, |
204 | { "height" , Rectangle_get_height, Rectangle_set_height }, |
205 | { "isEmpty" , Rectangle_get_isEmpty, nullptr }, |
206 | { nullptr, nullptr, nullptr } |
207 | }; |
208 | |
209 | } // anonymous namespace |
210 | |
211 | DEF_MTNAME(gfx::Rect); |
212 | |
213 | void register_rect_class(lua_State* L) |
214 | { |
215 | using Rectangle = gfx::Rect; |
216 | REG_CLASS(L, Rectangle); |
217 | REG_CLASS_NEW(L, Rectangle); |
218 | REG_CLASS_PROPERTIES(L, Rectangle); |
219 | } |
220 | |
221 | gfx::Rect convert_args_into_rect(lua_State* L, int index) |
222 | { |
223 | return Rectangle_new(L, index); |
224 | } |
225 | |
226 | } // namespace script |
227 | } // namespace app |
228 | |