143 lines
3.6 KiB
C
143 lines
3.6 KiB
C
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
*
|
|
* The contents of this file are subject to the Netscape Public
|
|
* License Version 1.1 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.mozilla.org/NPL/
|
|
*
|
|
* Software distributed under the License is distributed on an "AS
|
|
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
* implied. See the License for the specific language governing
|
|
* rights and limitations under the License.
|
|
*
|
|
* The Original Code is mozilla.org code.
|
|
*
|
|
* The Initial Developer of the Original Code is Netscape
|
|
* Communications Corporation. Portions created by Netscape are
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All
|
|
* Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
*/
|
|
/*
|
|
* xp_rect.c - Simple rectangle operations
|
|
*/
|
|
|
|
|
|
#include "xp.h"
|
|
#include "xp_rect.h"
|
|
|
|
#ifndef MIN
|
|
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
|
|
#endif
|
|
|
|
#ifndef MAX
|
|
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
|
|
#endif
|
|
|
|
void
|
|
XP_CopyRect(XP_Rect *src, XP_Rect *dest)
|
|
{
|
|
XP_MEMCPY(dest, src, sizeof (XP_Rect));
|
|
}
|
|
|
|
PRBool
|
|
XP_EqualRect(XP_Rect *r1, XP_Rect *r2)
|
|
{
|
|
return ((r1->left == r2->left) && (r1->top == r2->top) &&
|
|
(r1->bottom == r2->bottom) && (r1->right == r2->right));
|
|
}
|
|
|
|
/* Offset rectangle in 2D space. This could be a macro */
|
|
void
|
|
XP_OffsetRect(XP_Rect *rect, int32 x_offset, int32 y_offset)
|
|
{
|
|
XP_ASSERT(rect);
|
|
|
|
rect->left += x_offset;
|
|
rect->top += y_offset;
|
|
rect->right += x_offset;
|
|
rect->bottom += y_offset;
|
|
}
|
|
|
|
/* TRUE if point is within the boundary of the rect */
|
|
PRBool
|
|
XP_PointInRect(XP_Rect *rect, int32 x, int32 y)
|
|
{
|
|
XP_ASSERT(rect);
|
|
|
|
return (PRBool)((rect->left <= x) &&
|
|
(rect->top <= y) &&
|
|
(rect->right > x) &&
|
|
(rect->bottom > y));
|
|
}
|
|
|
|
/* TRUE if any parts of the two rectangles overlap */
|
|
PRBool
|
|
XP_RectsOverlap(XP_Rect *rect1, XP_Rect *rect2)
|
|
{
|
|
XP_ASSERT(rect1);
|
|
XP_ASSERT(rect2);
|
|
|
|
return (PRBool)((rect1->right > rect2->left) &&
|
|
(rect1->left < rect2->right) &&
|
|
(rect1->bottom > rect2->top) &&
|
|
(rect1->top < rect2->bottom));
|
|
}
|
|
|
|
/* TRUE if rect2 is entirely contained within rect1 */
|
|
PRBool
|
|
XP_RectContainsRect(XP_Rect *rect1, XP_Rect *rect2)
|
|
{
|
|
XP_ASSERT(rect1);
|
|
XP_ASSERT(rect2);
|
|
|
|
return (PRBool)((rect1->right >= rect2->right) &&
|
|
(rect1->left <= rect2->left) &&
|
|
(rect1->bottom >= rect2->bottom) &&
|
|
(rect1->top <= rect2->top));
|
|
}
|
|
|
|
/* dst = src1 intersect src2. dst can be one of src1 or src2 */
|
|
void
|
|
XP_IntersectRect(XP_Rect *src1, XP_Rect *src2, XP_Rect *dst)
|
|
{
|
|
XP_ASSERT(src1);
|
|
XP_ASSERT(src2);
|
|
XP_ASSERT(dst);
|
|
|
|
if (!XP_RectsOverlap(src1, src2)) {
|
|
dst->left = dst->top = dst->right = dst->bottom = 0;
|
|
}
|
|
else {
|
|
dst->left = MAX(src1->left, src2->left);
|
|
dst->top = MAX(src1->top, src2->top);
|
|
dst->right = MIN(src1->right, src2->right);
|
|
dst->bottom = MIN(src1->bottom, src2->bottom);
|
|
}
|
|
}
|
|
|
|
/* dst = bounding box of src1 and src2. dst can be one of src1 or src2 */
|
|
void
|
|
XP_RectsBbox(XP_Rect *src1, XP_Rect *src2, XP_Rect *dst)
|
|
{
|
|
XP_ASSERT(src1);
|
|
XP_ASSERT(src2);
|
|
XP_ASSERT(dst);
|
|
|
|
dst->left = MIN(src1->left, src2->left);
|
|
dst->top = MIN(src1->top, src2->top);
|
|
dst->right = MAX(src1->right, src2->right);
|
|
dst->bottom = MAX(src1->bottom, src2->bottom);
|
|
}
|
|
|
|
/* Does the rectangle enclose any pixels? */
|
|
PRBool
|
|
XP_IsEmptyRect(XP_Rect *rect)
|
|
{
|
|
XP_ASSERT(rect);
|
|
|
|
return (PRBool)((rect->left == rect->right) ||
|
|
(rect->top == rect->bottom));
|
|
}
|