note description: "Rectangular areas." legal: "See notice at end of class." status: "See notice at end of class." date: "$Date$" revision: "$Revision$" class EV_RECTANGLE inherit DEBUG_OUTPUT redefine out end create default_create, make, set feature {NONE} -- Initialization make, set (a_x, a_y, a_width, a_height: INTEGER) -- Initialize with `a_x', `a_y', `a_width', `a_height'. require a_width_positive: a_width >= 0 a_height_positive: a_height >= 0 do x := a_x y := a_y width := a_width height := a_height end feature -- Access x: INTEGER -- Horizontal position. y: INTEGER -- Vertical position. width: INTEGER -- Width of `Current'. height: INTEGER -- Height of `Current'. left: INTEGER -- Horizontal position of left side do Result := x end top: INTEGER -- Vertical position of top. do Result := y end right: INTEGER -- Horizontal position of right side. do Result := x + width end bottom: INTEGER -- Vertical position of bottom. do Result := y + height end feature -- Status report has_area: BOOLEAN -- Does `Current' have area? do Result := width > 0 and then height > 0 end upper_left: EV_COORDINATE -- Upper-left corner of `Current'. do create Result.set (left, top) ensure Result_exists: Result /= Void Result_assigned: Result.x = x and then Result.y = y end upper_right: EV_COORDINATE -- Upper-right corner of `Current'. do create Result.set (right, top) ensure Result_exists: Result /= Void Result_assigned: Result.x = x + width and then Result.y = y end lower_left: EV_COORDINATE -- Lower-left corner of `Current'. do create Result.set (left, bottom) ensure Result_exists: Result /= Void Result_assigned: Result.x = x and then Result.y = y + height end lower_right: EV_COORDINATE -- Lower-right corner of `Current'. do create Result.set (right, bottom) ensure Result_exists: Result /= Void Result_assigned: Result.x = x + width and then Result.y = y + height end feature -- Status report has (c: EV_COORDINATE): BOOLEAN -- Is `c' inside `Current'? require c_not_void: c /= Void do Result := c.x >= left and then c.x <= right and then c.y >= top and then c.y <= bottom end has_x_y (a_x, a_y: INTEGER): BOOLEAN -- Is (`a_x', `a_y') inside `Current'? local l_x, l_y: INTEGER do l_x := x l_y := y Result := a_x >= l_x and then a_x <= l_x + width and then a_y >= l_y and then a_y <= l_y + height end contains (other: like Current): BOOLEAN -- Does `Current' contain `other' entirely? do Result := x <= other.x and y <= other.y and other.bottom <= bottom and other.right <= right end intersects (other: like Current): BOOLEAN -- Does `other' at least partially overlap `Current'? require other_not_void: other /= Void do Result := has_area and then other.has_area and then not (left >= other.right or right <= other.left or top >= other.bottom or bottom <= other.top) end intersection (other: like Current): like Current -- Intersection of `other' with `Current'. -- If there is not intersection `Result' has default values. require other_not_void: other /= Void local l_top, l_bottom, l_left, l_right: INTEGER do create Result if intersects (other) then l_top := top.max (other.top) l_bottom := bottom.min (other.bottom) l_left := left.max (other.left) l_right := right.min (other.right) if l_top < 0 then Result.set_top (l_top) Result.set_bottom (l_bottom) else Result.set_bottom (l_bottom) Result.set_top (l_top) end if l_left < 0 then Result.set_left (l_left) Result.set_right (l_right) else Result.set_right (l_right) Result.set_left (l_left) end end ensure result_not_void: Result /= Void result_intersects_if_not_default: Result.width /= 0 or else Result.height /= 0 implies Result.intersects (other) result_default_if_no_intersection: Result.width = 0 or else Result.height = 0 implies not Result.intersects (other) end feature -- Element change include_point (c: EV_COORDINATE) -- Enlarge so that `c' is in `Current'. require c_not_void: c /= Void do include (c.x, c.y) ensure has_c: has (c) end include (a_x, a_y: INTEGER) -- Enlarge so that `a_x', `a_y' is in `Current'. do set_left (left.min (a_x)) set_top (top.min (a_y)) set_right (right.max (a_x)) set_bottom (bottom.max (a_y)) end merge (other: like Current) -- Enlarge `Current' so that `other' fits inside. require other_not_void: other /= Void do set_left (left.min (other.left)) set_top (top.min (other.top)) set_right (right.max (other.right)) set_bottom (bottom.max (other.bottom)) end grow_left (i: INTEGER) -- Increment size by `i' to west. require width + i > 0 do x := x - i width := width + i end grow_right (i: INTEGER) -- Increment size by `i' to east. do width := width + i end grow_top (i: INTEGER) -- Increment size by `i' to north. require height + i > 0 do y := y - i height := height + i end grow_bottom (i: INTEGER) -- Increment size by `i' to south. do height := height + i end set_left (i: INTEGER) -- Assign `i' to `left'. require i <= right do width := width - i + x x := i ensure assigned: left = i right_same: right = old right end set_right (i: INTEGER) -- Assign `i' to `right'. require i - x >= 0 do width := i - x ensure assigned: right = i end set_top (i: INTEGER) -- Assign `i' to `top'. require i <= bottom do height := height - i + y y := i ensure assigned: top = i bottom_same: bottom = old bottom end set_bottom (i: INTEGER) -- Assign `i' to `bottom'. require i - y >= 0 do height := i - y ensure assigned: bottom = i end set_x (new_x: INTEGER) -- Assign `new_x' to `x'. do x := new_x ensure x_set: x = new_x end set_y (new_y: INTEGER) -- Assign `new_y' to `y'. do y := new_y ensure y_set: y = new_y end set_width (new_width: INTEGER) -- Assign `new_width' to 'width'. require new_width_positive: new_width >= 0 do width := new_width ensure width_assigned: width = new_width end set_height (new_height: INTEGER) -- Assign `new_height' to `height'. require new_height_positive: new_height >= 0 do height := new_height ensure height_assigned: height = new_height end resize (a_width, a_height: INTEGER) -- Resize to `a_width' and `a_height'. require a_width_positive: a_width >= 0 a_height_positive: a_height >= 0 do width := a_width height := a_height ensure width_assigned: width = a_width height_assigned: height = a_height end move (a_x, a_y: INTEGER) -- Move to `a_x' and `a_y'. do x := a_x y := a_y ensure x_assigned: x = a_x y_assigned: y = a_y end move_and_resize (a_x, a_y, a_width, a_height: INTEGER) -- Move to `a_x' and `a_y' and resize to `a_width' and `a_height'. require a_width_positive: a_width >= 0 a_height_positive: a_height >= 0 do x := a_x y := a_y width := a_width height := a_height ensure x_assigned: x = a_x y_assigned: y = a_y width_assigned: width = a_width height_assigned: height = a_height end feature -- Output debug_output, out: STRING -- Return readable string. do Result := "(X: " + x.out + ", Y: " + y.out + ", Width: " + width.out + ", Height: " + height.out + ")" end invariant width_positive: width >= 0 height_positive: height >= 0 note copyright: "Copyright (c) 1984-2014, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" source: "[ Eiffel Software 5949 Hollister Ave., Goleta, CA 93117 USA Telephone 805-685-1006, Fax 805-685-6869 Website http://www.eiffel.com Customer support http://support.eiffel.com ]" end -- class EV_RECTANGLE