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