RECT.CPP (10162B)
1 // 2 // Copyright 2020 Electronic Arts Inc. 3 // 4 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free 5 // software: you can redistribute it and/or modify it under the terms of 6 // the GNU General Public License as published by the Free Software Foundation, 7 // either version 3 of the License, or (at your option) any later version. 8 9 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed 10 // in the hope that it will be useful, but with permitted additional restrictions 11 // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT 12 // distributed with this program. You should have received a copy of the 13 // GNU General Public License along with permitted additional restrictions 14 // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection 15 16 /* $Header: /CounterStrike/RECT.CPP 1 3/03/97 10:25a Joe_bostic $ */ 17 /*********************************************************************************************** 18 *** 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 *** 19 *********************************************************************************************** 20 * * 21 * Project Name : Command & Conquer * 22 * * 23 * File Name : RECT.CPP * 24 * * 25 * Programmer : Joe L. Bostic * 26 * * 27 * Start Date : 07/22/96 * 28 * * 29 * Last Update : July 22, 1996 [JLB] * 30 * * 31 *---------------------------------------------------------------------------------------------* 32 * Functions: * 33 * Rect::Rect -- Constructs a rectangle object. * 34 * Rect::Is_Valid -- Determines if the rectangle is valid. * 35 * Rect::Intersect -- Find the intersection between two rectangles. * 36 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 37 38 39 #include "rect.h" 40 41 42 /*********************************************************************************************** 43 * Rect::Rect -- Constructs a rectangle object. * 44 * * 45 * This will construct a rectangle object according to the parameters specified. * 46 * * 47 * INPUT: x,y -- The X and Y values of the upper left corner of the rectangle. * 48 * * 49 * w,h -- The width and height values of the rectangle. * 50 * * 51 * OUTPUT: none * 52 * * 53 * WARNINGS: none * 54 * * 55 * HISTORY: * 56 * 07/22/1996 JLB : Created. * 57 *=============================================================================================*/ 58 Rect::Rect(int x, int y, int w, int h) : 59 X(x), 60 Y(y), 61 Width(w), 62 Height(h) 63 { 64 } 65 66 67 /*********************************************************************************************** 68 * Rect::Is_Valid -- Determines if the rectangle is valid. * 69 * * 70 * An invalid rectangle has values that do not make any sense. This is a useful state since * 71 * this can be used to determine if a rectangle has been initialized correctly or for * 72 * detecting an error return condition for rectangle manipulation routines. * 73 * * 74 * INPUT: none * 75 * * 76 * OUTPUT: bool; Does this rectangle appear valid? * 77 * * 78 * WARNINGS: An invalid rectangle is one that has a width or height of less than one. * 79 * * 80 * HISTORY: * 81 * 07/22/1996 JLB : Created. * 82 *=============================================================================================*/ 83 bool Rect::Is_Valid(void) const 84 { 85 return(Width > 0 && Height > 0); 86 } 87 88 89 /*********************************************************************************************** 90 * Rect::Intersect -- Find the intersection between two rectangles. * 91 * * 92 * This routine will take the specified rectangle and use it like a "cookie cutter" on this * 93 * rectangle. The intersection of these two rectangles is returned. An optional X and * 94 * Y parameter is supplied so that an absolute coordinate can be maintained to the new * 95 * rectangle. * 96 * * 97 * INPUT: rectangle -- Reference to the rectangle to use as a cookie cutter. * 98 * * 99 * x,y -- Optional pointer to a coordinate that will be adjusted to stay * 100 * in an absolute position in coordinates even though it is a * 101 * relative offset. * 102 * * 103 * OUTPUT: Returns with the rectangle that is the intersection of the one specified and * 104 * this rectangle. * 105 * * 106 * WARNINGS: The rectangle returned may be invalid. This can occur if there is no legal * 107 * intersection between the rectangles. * 108 * * 109 * HISTORY: * 110 * 07/22/1996 JLB : Created. * 111 *=============================================================================================*/ 112 Rect const Rect::Intersect(Rect const & rectangle, int * x, int * y) const 113 { 114 Rect rect(0, 0, 0, 0); // Dummy (illegal) rectangle. 115 Rect r = rectangle; // Working rectangle. 116 117 /* 118 ** Both rectangles must be valid or else no intersection can occur. In such 119 ** a case, return an illegal rectangle. 120 */ 121 if (!Is_Valid() || !rectangle.Is_Valid()) return(rect); 122 123 /* 124 ** The rectangle spills past the left edge. 125 */ 126 if (r.X < X) { 127 r.Width -= X - r.X; 128 r.X = X; 129 } 130 if (r.Width < 1) return(rect); 131 132 /* 133 ** The rectangle spills past top edge. 134 */ 135 if (r.Y < Y) { 136 r.Height -= Y - r.Y; 137 r.Y = Y; 138 } 139 if (r.Height < 1) return(rect); 140 141 /* 142 ** The rectangle spills past the right edge. 143 */ 144 if (r.X + r.Width > X + Width) { 145 r.Width -= (r.X + r.Width) - (X + Width); 146 } 147 if (r.Width < 1) return(rect); 148 149 /* 150 ** The rectangle spills past the bottom edge. 151 */ 152 if (r.Y + r.Height > Y + Height) { 153 r.Height -= (r.Y + r.Height) - (Y + Height); 154 } 155 if (r.Height < 1) return(rect); 156 157 /* 158 ** Adjust Height relative draw position according to Height new rectangle 159 ** union. 160 */ 161 if (x != NULL) { 162 *x -= (r.X-X); 163 } 164 if (y != NULL) { 165 *y -= (r.Y-Y); 166 } 167 168 return(r); 169 } 170 171 172 Rect const Union(Rect const & rect1, Rect const & rect2) 173 { 174 if (rect1.Is_Valid()) { 175 if (rect2.Is_Valid()) { 176 Rect result = rect1; 177 178 if (result.X > rect2.X) { 179 result.Width += result.X-rect2.X; 180 result.X = rect2.X; 181 } 182 if (result.Y > rect2.Y) { 183 result.Height += result.Y-rect2.Y; 184 result.Y = rect2.Y; 185 } 186 if (result.X+result.Width < rect2.X+rect2.Width) { 187 result.Width = ((rect2.X+rect2.Width)-result.X)+1; 188 } 189 if (result.Y+result.Height < rect2.Y+rect2.Height) { 190 result.Height = ((rect2.Y+rect2.Height)-result.Y)+1; 191 } 192 return(result); 193 } 194 return(rect1); 195 } 196 return(rect2); 197 }