Implement selection addition and difference

Selection difference is something I have found myself wanting a lot when
working on levels, and have had to defer to a clunkier xor-then-and
approach. This commit implements the TODO-ed addition and subtraction
operators on two sets.

I don't see how the addition operator would be any different from
logical or, so it just calls l_selection_or rather than implement a new
function.
This commit is contained in:
copperwater
2022-03-14 11:14:46 -04:00
committed by Pasi Kallinen
parent a61a97856b
commit b4a460f81b
2 changed files with 41 additions and 5 deletions

View File

@@ -793,11 +793,13 @@ Example:
=== Logical or
Choose locations that are selected in either or both selections.
Choose locations that are selected in either or both selections. The
addition operator also does this.
Example:
local sel = selection.area(4,5, 40,10) | selection.rect(7,8, 60,14);
local sel = selection.area(4,5, 40,10) + selection.rect(7,8, 60,14);
=== Logical xor
@@ -809,6 +811,15 @@ Example:
local sel = selection.area(4,5, 40,10) ~ selection.rect(7,8, 60,14);
=== Logical difference
Choose locations in the first selection but not in the second selection.
Example:
local sel = selection.area(10,10, 20,20) - selection.area(14,14, 17,17);
=== area
Alias for <<_fillrect>>.

View File

@@ -33,6 +33,10 @@ static int l_selection_and(lua_State *);
static int l_selection_or(lua_State *);
static int l_selection_xor(lua_State *);
static int l_selection_not(lua_State *);
/* There doesn't seem to be a point in having a l_selection_add since it would
* do the same thing as l_selection_or. The addition operator is mapped to
* l_selection_or. */
static int l_selection_sub(lua_State *);
#if 0
/* the following do not appear to currently be
used and because they are static, the OSX
@@ -40,8 +44,6 @@ static int l_selection_not(lua_State *);
if ifdef'd out the prototype here and the
function body below.
*/
static int l_selection_add(lua_State *);
static int l_selection_sub(lua_State *);
static int l_selection_ipairs(lua_State *);
static struct selectionvar *l_selection_to(lua_State *, int);
#endif
@@ -277,6 +279,29 @@ l_selection_xor(lua_State *L)
return 1;
}
/* local sel = selection.area(10,10, 20,20) - selection.area(14,14, 17,17)
* - i.e. points that are in A but not in B */
static int
l_selection_sub(lua_State *L)
{
int x,y;
struct selectionvar *sela = l_selection_check(L, 1);
struct selectionvar *selb = l_selection_check(L, 2);
struct selectionvar *selr = l_selection_push(L);
for (x = 0; x < selr->wid; x++) {
for (y = 0; y < selr->hei; y++) {
xchar a_pt = selection_getpoint(x, y, sela);
xchar b_pt = selection_getpoint(x, y, selb);
int val = (a_pt ^ b_pt) & a_pt;
selection_setpoint(x, y, selr, val);
}
}
lua_remove(L, 1);
lua_remove(L, 1);
return 1;
}
/* local s = selection.percentage(sel, 50); */
static int
@@ -822,9 +847,9 @@ static const luaL_Reg l_selection_meta[] = {
{ "__bor", l_selection_or },
{ "__bxor", l_selection_xor },
{ "__bnot", l_selection_not },
{ "__add", l_selection_or }, /* this aliases + to be the same as | */
{ "__sub", l_selection_sub },
/* TODO: http://lua-users.org/wiki/MetatableEvents
{ "__add", l_selection_add },
{ "__sub", l_selection_sub },
{ "__ipairs", l_selection_ipairs },
*/
{ NULL, NULL }