xref: /haiku/headers/private/interface/clipping.h (revision d3d8b26997fac34a84981e6d2b649521de2cc45a)
1 //------------------------------------------------------------------------------
2 //	Copyright (c) 2001-2004, Haiku, Inc.
3 //
4 //	Permission is hereby granted, free of charge, to any person obtaining a
5 //	copy of this software and associated documentation files (the "Software"),
6 //	to deal in the Software without restriction, including without limitation
7 //	the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 //	and/or sell copies of the Software, and to permit persons to whom the
9 //	Software is furnished to do so, subject to the following conditions:
10 //
11 //	The above copyright notice and this permission notice shall be included in
12 //	all copies or substantial portions of the Software.
13 //
14 //	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 //	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 //	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 //	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 //	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 //	FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 //	DEALINGS IN THE SOFTWARE.
21 //
22 //	File Name:		clipping.h
23 //	Author:			Stefano Ceccherini (burton666@libero.it)
24 //	Description:	Helper methods to manipulate clipping_rects
25 //------------------------------------------------------------------------------
26 #ifndef __CLIPPING_H
27 #define __CLIPPING_H
28 
29 #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.
42 static inline clipping_rect
43 union_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.
59 static inline clipping_rect
60 sect_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.
74 static inline void
75 offset_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
85 static inline BRect
86 to_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.
94 static inline clipping_rect
95 to_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
118 static inline bool
119 point_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
129 static inline bool
130 point_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 
139 static inline bool
140 rect_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
148 static inline bool
149 valid_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.
158 static inline bool
159 rects_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.
176 static inline int32
177 rect_width(const clipping_rect &rect)
178 {
179 	return rect.right - rect.left;
180 }
181 
182 
183 // Returns the height of the given rect.
184 static inline int32
185 rect_height(const clipping_rect &rect)
186 {
187 	return rect.bottom - rect.top;
188 }
189 
190 #endif // __CLIPPING_H
191