From 6fe5d100f024d162b5d8d37c7dbadc3016021e5b Mon Sep 17 00:00:00 2001 From: Daniel Kolesa Date: Mon, 7 Apr 2014 14:46:49 +0100 Subject: [PATCH] elua: done binding eina_rectangle (all inline funcs rewritten) --- src/bindings/luajit/eina/rectangle.lua | 190 ++++++++++++++++++++++++- 1 file changed, 187 insertions(+), 3 deletions(-) diff --git a/src/bindings/luajit/eina/rectangle.lua b/src/bindings/luajit/eina/rectangle.lua index f872a7b14e..edcadba5c3 100644 --- a/src/bindings/luajit/eina/rectangle.lua +++ b/src/bindings/luajit/eina/rectangle.lua @@ -44,18 +44,202 @@ end cutil.init_module(init, shutdown) +local spans_intersect = function(c1, l1, c2, l2) + return not (((c2 + l2) <= c1) or (c2 >= (c1 + l1))) +end + +M.spans_intersect = spans_intersect + M.Rectangle = ffi.metatype("Eina_Rectangle", { __new = function(self, x, y, w, h) return ffi.gc(eina.eina_rectangle_new(x, y, w, h), self.free) end, __index = { free = function(self) eina.eina_rectangle_free(ffi.gc(self, nil)) end, - set = function(self, x, y, w, h) - self.x, self.y, self.w, self.h = x, y, w, h - end, + get_pool = function(self) local v = eina.eina_rectangle_pool_get(self) return v ~= nil and v or nil + end, + + is_empty = function(self) + return (self.w < 1) or (self.h < 1) + end, + + coords_from = function(self, x, y, w, h) + self.x, self.y, self.w, self.h = x, y, w, h + end, + + intersects = function(self, other) + return spans_intersect(self.x, self.w, other.x, other.w) + and spans_interscet(self.y, self.h, other.y, other.h) + end, + + xcoord_inside = function(self, x) + return ((x >= self.x) and (x < (self.x + self.w))) + end, + + ycoord_inside = function(self, y) + return ((y >= self.y) and (y < (self.y + self.h))) + end, + + coords_inside = function(self, x, y) + return self:xcoord_inside(x) and self:ycoord_inside(y) + end, + + union = function(dst, src) + if dst.x > src.x then + dst.w = dst.w + dst.x - src.x + dst.x = src.x + end + if (dst.x + dst.w) < (src.x + src.w) then + dst.w = src.x + src.w - dst.x + end + if dst.y > src.y then + dst.h = dst.h + dst.y - src.y + dst.y = src.y + end + if (dst.y + dst.h) < (src.y + src.h) then + dst.h = src.y + src.h - dst.y + end + end, + + intersection = function(dst, src) + if not dst:intersects(src) then + return false + end + + if dst.x < src.x then + dst.w = dst.w + dst.x - src.x + dst.x = src.x + if dst.w < 0 then dst.w = 0 end + end + if (dst.x + dst.w) > (src.x + src.w) then + dst.w = src.x + src.w - dst.x + end + if dst.y < src.y then + dst.h = dst.h + dst.y - src.y + dst.y = src.y + if dst.h < 0 then dst.h = 0 end + end + if (dst.y + dst.h) > (src.y + src.h) then + dst.h = src.y + src.h - dst.y + end + + return true + end, + + rescale_in = function(self, inr, outr) + self.x = inr.x - outr.x + self.y = inr.y - outr.y + self.w = inr.w + self.h = inr.h + end, + + rescale_out = function(self, inr, outr) + self.x = outr.x + inr.x + self.y = outr.y + inr.y + self.w = outr.w + self.h = outr.h + end, + + is_valid = function(self) + return self.w > 0 and self.h > 0 + end, + + max_x = function(self) return self.x + self.w end, + max_y = function(self) return self.y + self.h end, + + x_cut = function(self, slice, leftover, amount) + if amount > self.w then return false end + if slice then + slice:coords_from(self.x, self.y, amount, self.h) + end + if leftover then + leftover:coords_from(self.x + amount, self.y, + self.w - amount, self.h) + end + return true + end, + + y_cut = function(self, slice, leftover, amount) + if amount > self.h then return false end + if slice then + slice:coords_from(self.x, self.y, self.w, amount) + end + if leftover then + leftover:coords_from(self.x, self.y + amount, + self.w, self.h - amount) + end + return true + end, + + width_cut = function(self, slice, leftover, amount) + if (self.w - amount) < 0 then return false end + if slice then + slice:coords_from(self.x + (self.w - amount), self.y, + amount, self.h) + end + if leftover then + leftover:coords_from(self.x, self.y, self.w - amount, self.h) + end + return true + end, + + height_cut = function(self, slice, leftover, amount) + if (self.h - amount) < 0 then return false end + if slice then + slice:coords_from(self.x, self.y + (self.h - amount), + self.w, amount) + end + if leftover then + leftover:coords_from(self.x, self.y, self.w, self.h - amount) + end + return true + end, + + subtract = function(self, other) + if not self:is_valid() then return false end + + local o1, o2, o3, o4 = ffi.new("Eina_Rectangle"), + ffi.new("Eina_Rectangle"), + ffi.new("Eina_Rectangle"), + ffi.new("Eina_Rectangle") + + local intersection = ffi.new("Eina_Rectangle", self) + if not intersection:intersection(other) then + o1:coords_from(self) + return true, o1, o2, o3, o4 + end + + local leftover = ffi.new("Eina_Rectangle") + + local cut = self.h - (intersection.y - self.y) + if cut > self.h then cut = self.h end + self:height_cut(self, leftover, o1, cut) + + local tmp = ffi.new("Eina_Rectangle", leftover) + if tmp:intersection(intersection) then + cut = leftover.h - (leftover:max_y() - tmp:max_y()) + if cut > leftover.h then cut = leftover.h end + leftover:y_cut(leftover, o2, cut) + end + + local tmp = ffi.new("Eina_Rectangle", leftover) + if tmp:intersection(intersection) then + cut = leftover.w - (tmp.x - leftover.x) + if cut > leftover.w then cut = leftover.w end + leftover:width_cut(leftover, o3, cut) + end + + local tmp = ffi.new("Eina_Rectangle", leftover) + if tmp:intersection(intersection) then + cut = leftover.w - (leftover:max_x() - tmp:max_x()) + if cut > leftover.w then cut = leftover.w end + leftover:x_cut(leftover, o4, cut) + end + + return true, o1, o2, o3, o4 end } })