1246149Ssjg//------------------------------------------------------------------------------
2246149Ssjg//	Copyright (c) 2001-2004, Haiku, Inc.
3246149Ssjg//
4246149Ssjg//	Permission is hereby granted, free of charge, to any person obtaining a
5246149Ssjg//	copy of this software and associated documentation files (the "Software"),
6246149Ssjg//	to deal in the Software without restriction, including without limitation
7246149Ssjg//	the rights to use, copy, modify, merge, publish, distribute, sublicense,
8246149Ssjg//	and/or sell copies of the Software, and to permit persons to whom the
9246149Ssjg//	Software is furnished to do so, subject to the following conditions:
10246149Ssjg//
11246149Ssjg//	The above copyright notice and this permission notice shall be included in
12246149Ssjg//	all copies or substantial portions of the Software.
13246149Ssjg//
14246149Ssjg//	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15246149Ssjg//	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16246149Ssjg//	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17246149Ssjg//	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18246149Ssjg//	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19246149Ssjg//	FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20246149Ssjg//	DEALINGS IN THE SOFTWARE.
21246149Ssjg//
22246149Ssjg//	File Name:		clipping.h
23246149Ssjg//	Author:			Stefano Ceccherini (burton666@libero.it)
24246149Ssjg//	Description:	Helper methods to manipulate clipping_rects
25246149Ssjg//------------------------------------------------------------------------------
26246149Ssjg#ifndef __CLIPPING_H
27246149Ssjg#define __CLIPPING_H
28246149Ssjg
29246149Ssjg#include <Region.h>
30#include <SupportDefs.h>
31
32
33/*	Some methods to manipulate clipping_rects.
34	basically you can do almost everything you do with
35	BRects, just that clipping_rects can only have integer
36	coordinates (a thing that makes these perfect for drawing
37	calculations).
38*/
39
40
41// Returns the union of the given rects.
42static inline clipping_rect
43union_rect(const clipping_rect &r1, const clipping_rect &r2)
44{
45	clipping_rect rect;
46
47	rect.left = min_c(r1.left, r2.left);
48	rect.top = min_c(r1.top, r2.top);
49	rect.right = max_c(r1.right, r2.right);
50	rect.bottom = max_c(r1.bottom, r2.bottom);
51
52	return rect;
53}
54
55
56// Returns the intersection of the given rects.
57// The caller should check if the returned rect is valid. If it isn't valid,
58// then the two rectangles don't intersect.
59static inline clipping_rect
60sect_rect(const clipping_rect &r1, const clipping_rect &r2)
61{
62	clipping_rect rect;
63
64	rect.left = max_c(r1.left, r2.left);
65	rect.top = max_c(r1.top, r2.top);
66	rect.right = min_c(r1.right, r2.right);
67	rect.bottom = min_c(r1.bottom, r2.bottom);
68
69	return rect;
70}
71
72
73// Adds the given offsets to the given rect.
74static inline void
75offset_rect(clipping_rect &rect, int32 x, int32 y)
76{
77	rect.left += x;
78	rect.top += y;
79	rect.right += x;
80	rect.bottom += y;
81}
82
83
84// Converts the given clipping_rect to a BRect
85static inline BRect
86to_BRect(const clipping_rect &rect)
87{
88	return BRect((float)rect.left, (float)rect.top,
89				 (float)rect.right, (float)rect.bottom);
90}
91
92
93// Converts the given BRect to a clipping_rect.
94static inline clipping_rect
95to_clipping_rect(const BRect &rect)
96{
97	clipping_rect clipRect;
98
99// NOTE: test fractional coords BRects -> BRegion on R5
100// and compare with this implementation...
101//	clipRect.left = (int32)floorf(rect.left);
102//	clipRect.top = (int32)floorf(rect.top);
103//	clipRect.right = (int32)ceilf(rect.right);
104//	clipRect.bottom = (int32)ceilf(rect.bottom);
105
106	// NOTE: clipping_rects are used as "pixel indices"
107	// therefor, it should be ok to convert them like this:
108	clipRect.left = (int32)rect.left;
109	clipRect.top = (int32)rect.top;
110	clipRect.right = (int32)rect.right;
111	clipRect.bottom = (int32)rect.bottom;
112
113	return clipRect;
114}
115
116
117// Checks if the given point lies in the given rect's area
118static inline bool
119point_in(const clipping_rect &rect, int32 px, int32 py)
120{
121	if (px >= rect.left && px <= rect.right
122			&& py >= rect.top && py <= rect.bottom)
123		return true;
124	return false;
125}
126
127
128// Same as above, but it accepts a BPoint parameter
129static inline bool
130point_in(const clipping_rect &rect, const BPoint &pt)
131{
132	if (pt.x >= rect.left && pt.x <= rect.right
133			&& pt.y >= rect.top && pt.y <= rect.bottom)
134		return true;
135	return false;
136}
137
138
139static inline bool
140rect_contains(const clipping_rect &rect, const clipping_rect &testRect)
141{
142	return rect.top <= testRect.top && rect.bottom >= testRect.bottom
143			&& rect.left <= testRect.left && rect.right >= testRect.right;
144}
145
146
147// Checks if the rect is valid
148static inline bool
149valid_rect(const clipping_rect &rect)
150{
151	if (rect.left <= rect.right && rect.top <= rect.bottom)
152		return true;
153	return false;
154}
155
156
157// Checks if the two rects intersect.
158static inline bool
159rects_intersect(const clipping_rect &rectA, const clipping_rect &rectB)
160{
161	// We behave like BRect::Intersects() does:
162	// we return false if one of the two rects is not valid
163	if (!valid_rect(rectA) || !valid_rect(rectB))
164		return false;
165
166	// TODO: Is there a better algorithm ?
167	// the one we used is faster than
168	// ' return valid_rect(sect_rect(rectA, rectB)); ', though.
169
170	return !(rectA.left > rectB.right || rectA.top > rectB.bottom
171			|| rectA.right < rectB.left || rectA.bottom < rectB.top);
172}
173
174
175// Returns the width of the given rect.
176static inline int32
177rect_width(const clipping_rect &rect)
178{
179	return rect.right - rect.left;
180}
181
182
183// Returns the height of the given rect.
184static inline int32
185rect_height(const clipping_rect &rect)
186{
187	return rect.bottom - rect.top;
188}
189
190#endif // __CLIPPING_H
191