/* ** Command & Conquer Renegade(tm) ** Copyright 2025 Electronic Arts Inc. ** ** This program is free software: you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation, either version 3 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program. If not, see . */ /*********************************************************************************************** *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** *********************************************************************************************** * * * Project Name : Command & Conquer * * * * $Archive:: /Commando/Code/wwlib/trect.h $* * * * $Author:: Byon_g $* * * * $Modtime:: 11/28/00 2:37p $* * * * $Revision:: 2 $* * * *---------------------------------------------------------------------------------------------* * Functions: * * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ #if _MSC_VER >= 1000 #pragma once #endif // _MSC_VER >= 1000 #ifndef TRECT_H #define TRECT_H #include "point.h" /* ** This class manages a rectangle. */ template class TRect { public: TRect(T x=0, T y=0, T w=0, T h=0) : X(x), Y(y), Width(w), Height(h) {} TRect(TPoint2D const & point, T w, T h) : X(point.X), Y(point.Y), Width(w), Height(h) {} // Equality comparison operators. bool operator == (TRect const & rvalue) const {return(X==rvalue.X && Y==rvalue.Y && Width==rvalue.Width && Height==rvalue.Height);} bool operator != (TRect const & rvalue) const {return(X!=rvalue.X || Y!=rvalue.Y || Width!=rvalue.Width || Height!=rvalue.Height);} // Addition and subtraction operators. TRect const & operator += (TPoint2D const & point) {X += point.X;Y += point.Y;return(*this);} TRect const & operator -= (TPoint2D const & point) {X -= point.X;Y -= point.Y;return(*this);} TRect const operator + (TPoint2D const & point) {return(TRect(X + point.X, Y + point.Y, Width, Height));} TRect const operator - (TPoint2D const & point) {return(TRect(X - point.X, Y - point.Y, Width, Height));} TRect const Intersect(TRect const & rectangle, T * x=NULL, T * y=NULL) const; TRect const Union(TRect const & rect2) const; /* ** Bias this rectangle within another. */ TRect const Bias_To(TRect const & rect) const {return(TRect(X + rect.X, Y + rect.Y, Width, Height));} /* ** Determine if two rectangles overlap. */ bool Is_Overlapping(TRect const & rect) const {return(X < rect.X+rect.Width && Y < rect.Y+rect.Height && X+Width > rect.X && Y+Height > rect.Y);} /* ** Determine is rectangle is valid. */ bool Is_Valid(void) const {return(Width > 0 && Height > 0);} /* ** Returns size of rectangle if each discrete location within it is presumed ** to be of size 1. */ int Size(void) const {return(int(Width) * int(Height));} /* ** Fetch points of rectangle (used as a convenience for the programmer). */ TPoint2D Top_Left(void) const {return(TPoint2D(X, Y));} TPoint2D Top_Right(void) const {return(TPoint2D(X + Width - 1, Y));} TPoint2D Bottom_Left(void) const {return(TPoint2D(X, Y + Height - 1));} TPoint2D Bottom_Right(void) const {return(TPoint2D(X + Width - 1, Y + Height - 1));} /* ** Determine if a point lies within the rectangle. */ bool Is_Point_Within(TPoint2D const & point) const {return(point.X >= X && point.X < X+Width && point.Y >= Y && point.Y < Y+Height);} public: /* ** Coordinate of upper left corner of rectangle. */ T X; T Y; /* ** Dimensions of rectangle. If the width or height is less than or equal to ** zero, then the rectangle is in an invalid state. */ T Width; T Height; }; template TRect const TRect::Intersect(TRect const & rectangle, T * x, T * y) const { TRect rect(0, 0, 0, 0); // Dummy (illegal) rectangle. TRect r = rectangle; // Working rectangle. /* ** Both rectangles must be valid or else no intersection can occur. In such ** a case, return an illegal rectangle. */ if (!Is_Valid() || !rectangle.Is_Valid()) return(rect); /* ** The rectangle spills past the left edge. */ if (r.X < X) { r.Width -= X - r.X; r.X = X; } if (r.Width < 1) return(rect); /* ** The rectangle spills past top edge. */ if (r.Y < Y) { r.Height -= Y - r.Y; r.Y = Y; } if (r.Height < 1) return(rect); /* ** The rectangle spills past the right edge. */ if (r.X + r.Width > X + Width) { r.Width -= (r.X + r.Width) - (X + Width); } if (r.Width < 1) return(rect); /* ** The rectangle spills past the bottom edge. */ if (r.Y + r.Height > Y + Height) { r.Height -= (r.Y + r.Height) - (Y + Height); } if (r.Height < 1) return(rect); /* ** Adjust Height relative draw position according to Height new rectangle ** union. */ if (x != NULL) { *x -= (r.X-X); } if (y != NULL) { *y -= (r.Y-Y); } return(r); } template TRect const TRect::Union(TRect const & rect2) const { if (Is_Valid()) { if (rect2.Is_Valid()) { TRect result = *this; if (result.X > rect2.X) { result.Width += result.X-rect2.X; result.X = rect2.X; } if (result.Y > rect2.Y) { result.Height += result.Y-rect2.Y; result.Y = rect2.Y; } if (result.X+result.Width < rect2.X+rect2.Width) { result.Width = ((rect2.X+rect2.Width)-result.X)+1; } if (result.Y+result.Height < rect2.Y+rect2.Height) { result.Height = ((rect2.Y+rect2.Height)-result.Y)+1; } return(result); } return(*this); } return(rect2); } template TPoint2D const TPoint2D::Bias_To(TRect const & rect) const { return(TPoint2D(X + rect.X, Y + rect.Y)); } /* ** This typedef provides an uncluttered type name for a rectangle that ** is composed of integers. */ typedef TRect Rect; #endif