Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

rect.c

Go to the documentation of this file.
00001 /****************************** Module Header ******************************\ 00002 * Module Name: rect.c 00003 * 00004 * Copyright (c) 1985 - 1999, Microsoft Corporation 00005 * 00006 * This module contains the various rectangle manipulation APIs. 00007 * 00008 * History: 00009 * 10-20-90 DarrinM Grabbed 'C' rect routines from Portable PM. 00010 \***************************************************************************/ 00011 00012 #ifdef _USERK_ 00013 #define VALIDATERECT(prc, retval) UserAssert(prc) 00014 #else 00015 #define VALIDATERECT(prc, retval) if (prc == NULL) return retval 00016 #endif 00017 00018 /***********************************************************************\ 00019 * SetRect (API) 00020 * 00021 * This function fills a rectangle structure with the passed in coordinates. 00022 * 00023 * History: 00024 * 10-20-90 DarrinM Translated from PMese to Windowses. 00025 \***********************************************************************/ 00026 00027 BOOL APIENTRY SetRect( 00028 LPRECT prc, 00029 int left, 00030 int top, 00031 int right, 00032 int bottom) 00033 { 00034 VALIDATERECT(prc, FALSE); 00035 00036 prc->left = left; 00037 prc->top = top; 00038 prc->right = right; 00039 prc->bottom = bottom; 00040 return TRUE; 00041 } 00042 00043 /************************************************************************\ 00044 * CopyInflateRect (API) 00045 * 00046 * This function copies the rect from prcSrc to prcDst, and inflates it. 00047 * 00048 * History: 00049 * 12-16-93 FritzS 00050 \************************************************************************/ 00051 00052 BOOL APIENTRY CopyInflateRect( 00053 LPRECT prcDst, 00054 CONST RECT *prcSrc, 00055 int cx, int cy) 00056 { 00057 prcDst->left = prcSrc->left - cx; 00058 prcDst->right = prcSrc->right + cx; 00059 prcDst->top = prcSrc->top - cy; 00060 prcDst->bottom = prcSrc->bottom + cy; 00061 return TRUE; 00062 } 00063 00064 /************************************************************************\ 00065 * CopyOffsetRect (API) 00066 * 00067 * This function copies the rect from prcSrc to prcDst, and offsets it. 00068 * 00069 * History: 00070 * 01-03-94 FritzS 00071 \************************************************************************/ 00072 00073 BOOL APIENTRY CopyOffsetRect( 00074 LPRECT prcDst, 00075 CONST RECT *prcSrc, 00076 int cx, int cy) 00077 { 00078 prcDst->left = prcSrc->left + cx; 00079 prcDst->right = prcSrc->right + cx; 00080 prcDst->top = prcSrc->top + cy; 00081 prcDst->bottom = prcSrc->bottom + cy; 00082 return TRUE; 00083 } 00084 00085 /************************************************************************\ 00086 * IsRectEmpty (API) 00087 * 00088 * This function returns TRUE if *prc is an empty rect, FALSE 00089 * otherwise. An empty rect is one that has no area: right is 00090 * less than or equal to left, bottom is less than or equal to top. 00091 * 00092 * Warning: 00093 * This function assumes that the rect is in device coordinates 00094 * mode where left and top coordinate are smaller than right and 00095 * bottom. 00096 * 00097 * History: 00098 * 10-20-90 DarrinM Translated from PMese to Windowses. 00099 \************************************************************************/ 00100 00101 BOOL APIENTRY IsRectEmpty( 00102 CONST RECT *prc) 00103 { 00104 VALIDATERECT(prc, TRUE); 00105 00106 return ((prc->left >= prc->right) || (prc->top >= prc->bottom)); 00107 } 00108 00109 /***********************************************************************\ 00110 * PtInRect (API) 00111 * 00112 * This function returns TRUE if *ppt falls inside of *prc. 00113 * 00114 * History: 00115 * 10-20-90 DarrinM Translated from PMese to Windowses. 00116 \************************************************************************/ 00117 00118 BOOL APIENTRY PtInRect( 00119 CONST RECT *prc, 00120 POINT pt) 00121 { 00122 VALIDATERECT(prc, FALSE); 00123 00124 return ((pt.x >= prc->left) && (pt.x < prc->right) && 00125 (pt.y >= prc->top) && (pt.y < prc->bottom)); 00126 } 00127 00128 /************************************************************************\ 00129 * OffsetRect (API) 00130 * 00131 * This function offsets the coordinates of *prc by adding cx to 00132 * both the left and right coordinates, and cy to both the top and 00133 * bottom coordinates. 00134 * 00135 * History: 00136 * 10-20-90 DarrinM Translated from PMese to Windowses. 00137 \************************************************************************/ 00138 00139 BOOL APIENTRY OffsetRect( 00140 LPRECT prc, 00141 int cx, 00142 int cy) 00143 { 00144 VALIDATERECT(prc, FALSE); 00145 00146 prc->left += cx; 00147 prc->right += cx; 00148 prc->bottom += cy; 00149 prc->top += cy; 00150 return TRUE; 00151 } 00152 00153 /************************************************************************\ 00154 * InflateRect (API) 00155 * 00156 * This function expands the given rect by cx horizantally and cy 00157 * vertically on all sides. If cx or cy are negative, the rect 00158 * is inset. cx is subtracted from the left and added to the right, 00159 * and cy is subtracted from the top and added to the bottom. 00160 * 00161 * History: 00162 * 10-20-90 DarrinM Translated from PMese to Windowses. 00163 \************************************************************************/ 00164 00165 BOOL APIENTRY InflateRect( 00166 LPRECT prc, 00167 int cx, 00168 int cy) 00169 { 00170 VALIDATERECT(prc, FALSE); 00171 00172 prc->left -= cx; 00173 prc->right += cx; 00174 prc->top -= cy; 00175 prc->bottom += cy; 00176 return TRUE; 00177 } 00178 00179 /************************************************************************\ 00180 * IntersectRect (API) 00181 * 00182 * Calculates the intersection between *prcSrc1 and *prcSrc2, 00183 * returning the resulting rect in *prcDst. Returns TRUE if 00184 * *prcSrc1 intersects *prcSrc2, FALSE otherwise. If there is no 00185 * intersection, an empty rect is returned in *prcDst 00186 * 00187 * History: 00188 * 10-20-90 DarrinM Translated from PMese to Windowses. 00189 \************************************************************************/ 00190 00191 BOOL APIENTRY IntersectRect( 00192 LPRECT prcDst, 00193 CONST RECT *prcSrc1, 00194 CONST RECT *prcSrc2) 00195 00196 { 00197 VALIDATERECT(prcDst, FALSE); 00198 VALIDATERECT(prcSrc1, FALSE); 00199 VALIDATERECT(prcSrc2, FALSE); 00200 00201 prcDst->left = max(prcSrc1->left, prcSrc2->left); 00202 prcDst->right = min(prcSrc1->right, prcSrc2->right); 00203 00204 /* 00205 * check for empty rect 00206 */ 00207 if (prcDst->left < prcDst->right) { 00208 00209 prcDst->top = max(prcSrc1->top, prcSrc2->top); 00210 prcDst->bottom = min(prcSrc1->bottom, prcSrc2->bottom); 00211 00212 /* 00213 * check for empty rect 00214 */ 00215 if (prcDst->top < prcDst->bottom) { 00216 return TRUE; // not empty 00217 } 00218 } 00219 00220 /* 00221 * empty rect 00222 */ 00223 SetRectEmpty(prcDst); 00224 00225 return FALSE; 00226 } 00227 00228 /********************************************************************\ 00229 * UnionRect (API) 00230 * 00231 * This function calculates a rect that bounds *prcSrc1 and 00232 * *prcSrc2, returning the result in *prcDst. If either 00233 * *prcSrc1 or *prcSrc2 are empty, then the other rect is 00234 * returned. Returns TRUE if *prcDst is a non-empty rect, 00235 * FALSE otherwise. 00236 * 00237 * History: 00238 * 10-20-90 DarrinM Translated from PMese to Windowses. 00239 \*******************************************************************/ 00240 00241 BOOL APIENTRY UnionRect( 00242 LPRECT prcDst, 00243 CONST RECT *prcSrc1, 00244 CONST RECT *prcSrc2) 00245 { 00246 BOOL frc1Empty, frc2Empty; 00247 00248 VALIDATERECT(prcDst, FALSE); 00249 VALIDATERECT(prcSrc1, FALSE); 00250 VALIDATERECT(prcSrc2, FALSE); 00251 00252 frc1Empty = ((prcSrc1->left >= prcSrc1->right) || 00253 (prcSrc1->top >= prcSrc1->bottom)); 00254 00255 frc2Empty = ((prcSrc2->left >= prcSrc2->right) || 00256 (prcSrc2->top >= prcSrc2->bottom)); 00257 00258 if (frc1Empty && frc2Empty) { 00259 SetRectEmpty(prcDst); 00260 return FALSE; 00261 } 00262 00263 if (frc1Empty) { 00264 *prcDst = *prcSrc2; 00265 return TRUE; 00266 } 00267 00268 if (frc2Empty) { 00269 *prcDst = *prcSrc1; 00270 return TRUE; 00271 } 00272 00273 /* 00274 * form the union of the two non-empty rects 00275 */ 00276 prcDst->left = min(prcSrc1->left, prcSrc2->left); 00277 prcDst->top = min(prcSrc1->top, prcSrc2->top); 00278 prcDst->right = max(prcSrc1->right, prcSrc2->right); 00279 prcDst->bottom = max(prcSrc1->bottom, prcSrc2->bottom); 00280 00281 return TRUE; 00282 } 00283 00284 /********************************************************************\ 00285 * EqualRect (API) 00286 * 00287 * This function returns TRUE if *prc1 and *prc2 are identical, 00288 * FALSE otherwise. 00289 * 00290 * History: 00291 * 10-20-90 DarrinM Translated from PMese to Windowses. 00292 \*****************************************************************/ 00293 00294 #undef EqualRect // don't let macro interfere with API 00295 BOOL APIENTRY EqualRect( 00296 CONST RECT *prc1, 00297 CONST RECT *prc2) 00298 { 00299 VALIDATERECT(prc1, FALSE); 00300 VALIDATERECT(prc2, FALSE); 00301 00302 /* 00303 * Test equality only. This is what win31 does. win31 does not check to 00304 * see if the rectangles are "empty" first. 00305 */ 00306 return RtlEqualMemory(prc1, prc2, sizeof(RECT)); 00307 } 00308 00309 /**********************************************************************\ 00310 * SubtractRect (API) 00311 * 00312 * This function subtracts *prc2 from *prc1, returning the result in *prcDst 00313 * Returns FALSE if *lprDst is empty, TRUE otherwise. 00314 * 00315 * Warning: 00316 * Subtracting one rect from another may not always result in a 00317 * rectangular area; in this case SubtractRect will return *prc1 in 00318 * *prcDst. For this reason, SubractRect provides only an 00319 * approximation of subtraction. However, the area described by 00320 * *prcDst will always be greater than or equal to the "true" result 00321 * of the subtraction. 00322 * 00323 * History: 00324 * 10-20-90 DarrinM Translated from PMese to Windowsese. 00325 \**********************************************************************/ 00326 00327 BOOL APIENTRY SubtractRect( 00328 LPRECT prcDst, 00329 CONST RECT *prcSrc1, 00330 CONST RECT *prcSrc2) 00331 { 00332 int cSidesOut; 00333 BOOL fIntersect; 00334 RECT rcInt; 00335 00336 VALIDATERECT(prcDst, FALSE); 00337 VALIDATERECT(prcSrc1, FALSE); 00338 VALIDATERECT(prcSrc2, FALSE); 00339 00340 fIntersect = IntersectRect(&rcInt, prcSrc1, prcSrc2); 00341 00342 /* 00343 * this is done after the intersection in case prcDst is the same 00344 * pointer as prcSrc2 00345 */ 00346 *prcDst = *prcSrc1; 00347 00348 if (fIntersect) { 00349 /* 00350 * exactly any 3 sides of prc2 must be outside prc1 to subtract 00351 */ 00352 cSidesOut = 0; 00353 if (rcInt.left <= prcSrc1->left) 00354 cSidesOut++; 00355 if (rcInt.top <= prcSrc1->top) 00356 cSidesOut++; 00357 if (rcInt.right >= prcSrc1->right) 00358 cSidesOut++; 00359 if (rcInt.bottom >= prcSrc1->bottom) 00360 cSidesOut++; 00361 00362 if (cSidesOut == 4) { 00363 /* 00364 * result is the empty rect 00365 */ 00366 SetRectEmpty(prcDst); 00367 return FALSE; 00368 } 00369 00370 if (cSidesOut == 3) { 00371 /* 00372 * subtract the intersecting rect 00373 */ 00374 if (rcInt.left > prcSrc1->left) 00375 prcDst->right = rcInt.left; 00376 00377 else if (rcInt.right < prcSrc1->right) 00378 prcDst->left = rcInt.right; 00379 00380 else if (rcInt.top > prcSrc1->top) 00381 prcDst->bottom = rcInt.top; 00382 00383 else if (rcInt.bottom < prcSrc1->bottom) 00384 prcDst->top = rcInt.bottom; 00385 } 00386 } 00387 00388 if ((prcDst->left >= prcDst->right) || (prcDst->top >= prcDst->bottom)) 00389 return FALSE; 00390 00391 return TRUE; 00392 } 00393 00394 /************************************************************************\ 00395 * CopyRect (API) 00396 * 00397 * This function copies the rect from prcSrc to prcDst. 00398 * 00399 * History: 00400 * 10-20-90 DarrinM Translated from PMese to Windowses. 00401 \************************************************************************/ 00402 00403 #undef CopyRect // don't let macro interfere with API 00404 BOOL APIENTRY CopyRect( 00405 LPRECT prcDst, 00406 CONST RECT *prcSrc) 00407 { 00408 VALIDATERECT(prcDst, FALSE); 00409 VALIDATERECT(prcSrc, FALSE); 00410 00411 *prcDst = *prcSrc; 00412 return TRUE; 00413 } 00414 00415 00416 /************************************************************************\ 00417 * SetRectEmpty (API) 00418 * 00419 * This fuction sets *prc to an empty rect by setting each field to 0. 00420 * Equivalent to SetRect(prc, 0, 0, 0, 0). 00421 * 00422 * History: 00423 * 10-20-90 DarrinM Translated from PMese to Windowses. 00424 \************************************************************************/ 00425 00426 #undef SetRectEmpty // don't let macro interfere with API 00427 BOOL APIENTRY SetRectEmpty( 00428 LPRECT prc) 00429 { 00430 VALIDATERECT(prc, FALSE); 00431 00432 RtlZeroMemory(prc, sizeof(RECT)); 00433 return TRUE; 00434 } 00435 00436 00437 00438 /***************************************************************************\ 00439 * RECTFromSIZERECT 00440 * 00441 * This function converts a SIZERECT to a RECT. 00442 * 00443 * History: 00444 * 24-Sep-1996 adams Created. 00445 \***************************************************************************/ 00446 00447 void 00448 RECTFromSIZERECT(PRECT prc, PCSIZERECT psrc) 00449 { 00450 prc->left = psrc->x; 00451 prc->top = psrc->y; 00452 prc->right = psrc->x + psrc->cx; 00453 prc->bottom = psrc->y + psrc->cy; 00454 } 00455 00456 00457 /***************************************************************************\ 00458 * SIZERECTFromRECT 00459 * 00460 * Converts a RECT to a SIZERECT. 00461 * 00462 * History: 00463 * 09-May-1997 adams Created. 00464 \***************************************************************************/ 00465 00466 void 00467 SIZERECTFromRECT(PSIZERECT psrc, LPCRECT prc) 00468 { 00469 psrc->x = prc->left; 00470 psrc->y = prc->top; 00471 psrc->cx = prc->right - prc->left; 00472 psrc->cy = prc->bottom - prc->top; 00473 }

Generated on Sat May 15 19:41:37 2004 for test by doxygen 1.3.7