1 //------------------------------------------------------------------------------
2 // Copyright (c) 2001-2004, Haiku, Inc.
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:
11 // The above copyright notice and this permission notice shall be included in
12 // all copies or substantial portions of the Software.
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.
22 // File Name: clipping.h
23 // Author: Stefano Ceccherini (burton666@libero.it)
24 // Description: Helper methods to manipulate clipping_rects
25 //------------------------------------------------------------------------------
30 #include <SupportDefs.h>
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
41 // Returns the union of the given rects.
42 static inline clipping_rect
43 union_rect(const clipping_rect
&r1
, const clipping_rect
&r2
)
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
);
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
)
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
);
73 // Adds the given offsets to the given rect.
75 offset_rect(clipping_rect
&rect
, int32 x
, int32 y
)
85 scale_rect(clipping_rect
& rect
, float x
, float y
)
87 rect
.left
= (int)(rect
.left
* x
);
88 rect
.top
= (int)(rect
.top
* y
);
89 rect
.right
= (int)((rect
.right
+ 1) * x
) - 1;
90 rect
.bottom
= (int)((rect
.bottom
+ 1) * y
) - 1;
94 // Converts the given clipping_rect to a BRect
96 to_BRect(const clipping_rect
&rect
)
98 return BRect((float)rect
.left
, (float)rect
.top
,
99 (float)rect
.right
, (float)rect
.bottom
);
103 // Converts the given BRect to a clipping_rect.
104 static inline clipping_rect
105 to_clipping_rect(const BRect
&rect
)
107 clipping_rect clipRect
;
109 // NOTE: test fractional coords BRects -> BRegion on R5
110 // and compare with this implementation...
111 // clipRect.left = (int32)floorf(rect.left);
112 // clipRect.top = (int32)floorf(rect.top);
113 // clipRect.right = (int32)ceilf(rect.right);
114 // clipRect.bottom = (int32)ceilf(rect.bottom);
116 // NOTE: clipping_rects are used as "pixel indices"
117 // therefor, it should be ok to convert them like this:
118 clipRect
.left
= (int32
)rect
.left
;
119 clipRect
.top
= (int32
)rect
.top
;
120 clipRect
.right
= (int32
)rect
.right
;
121 clipRect
.bottom
= (int32
)rect
.bottom
;
127 // Checks if the given point lies in the given rect's area
129 point_in(const clipping_rect
&rect
, int32 px
, int32 py
)
131 if (px
>= rect
.left
&& px
<= rect
.right
132 && py
>= rect
.top
&& py
<= rect
.bottom
)
138 // Same as above, but it accepts a BPoint parameter
140 point_in(const clipping_rect
&rect
, const BPoint
&pt
)
142 if (pt
.x
>= rect
.left
&& pt
.x
<= rect
.right
143 && pt
.y
>= rect
.top
&& pt
.y
<= rect
.bottom
)
150 rect_contains(const clipping_rect
&rect
, const clipping_rect
&testRect
)
152 return rect
.top
<= testRect
.top
&& rect
.bottom
>= testRect
.bottom
153 && rect
.left
<= testRect
.left
&& rect
.right
>= testRect
.right
;
157 // Checks if the rect is valid
159 valid_rect(const clipping_rect
&rect
)
161 if (rect
.left
<= rect
.right
&& rect
.top
<= rect
.bottom
)
167 // Checks if the two rects intersect.
169 rects_intersect(const clipping_rect
&rectA
, const clipping_rect
&rectB
)
171 // We behave like BRect::Intersects() does:
172 // we return false if one of the two rects is not valid
173 if (!valid_rect(rectA
) || !valid_rect(rectB
))
176 // TODO: Is there a better algorithm ?
177 // the one we used is faster than
178 // ' return valid_rect(sect_rect(rectA, rectB)); ', though.
180 return !(rectA
.left
> rectB
.right
|| rectA
.top
> rectB
.bottom
181 || rectA
.right
< rectB
.left
|| rectA
.bottom
< rectB
.top
);
185 // Returns the width of the given rect.
187 rect_width(const clipping_rect
&rect
)
189 return rect
.right
- rect
.left
;
193 // Returns the height of the given rect.
195 rect_height(const clipping_rect
&rect
)
197 return rect
.bottom
- rect
.top
;
200 #endif // __CLIPPING_H