2 * Copyright (C) 2005-2013 Team XBMC
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with XBMC; see the file COPYING. If not, see
17 * <http://www.gnu.org/licenses/>.
24 // under gcc, inline will only take place if optimizations are applied (-O). this will force inline even whith optimizations.
25 #define XBMC_FORCE_INLINE __attribute__((always_inline))
27 #define XBMC_FORCE_INLINE
33 template <typename T> class CPointGen
36 typedef CPointGen<T> this_type;
43 CPointGen<T>(T a, T b)
49 template <class U> CPointGen<T>(const CPointGen<U>& rhs)
55 this_type operator+(const this_type &point) const
63 const this_type &operator+=(const this_type &point)
70 this_type operator-(const this_type &point) const
78 const this_type &operator-=(const this_type &point)
88 template <typename T> class CRectGen
91 typedef CRectGen<T> this_type;
93 CRectGen<T>() { x1 = y1 = x2 = y2 = 0;};
94 CRectGen<T>(T left, T top, T right, T bottom) { x1 = left; y1 = top; x2 = right; y2 = bottom; };
95 CRectGen<T>(const CPointGen<T> &p1, const CPointGen<T> &p2)
103 template <class U> CRectGen<T>(const CRectGen<U>& rhs)
111 void SetRect(T left, T top, T right, T bottom) { x1 = left; y1 = top; x2 = right; y2 = bottom; };
113 bool PtInRect(const CPointGen<T> &point) const
115 if (x1 <= point.x && point.x <= x2 && y1 <= point.y && point.y <= y2)
120 inline const this_type &operator -=(const CPointGen<T> &point) XBMC_FORCE_INLINE
129 inline const this_type &operator +=(const CPointGen<T> &point) XBMC_FORCE_INLINE
138 const this_type &Intersect(const this_type &rect)
140 x1 = clamp_range(x1, rect.x1, rect.x2);
141 x2 = clamp_range(x2, rect.x1, rect.x2);
142 y1 = clamp_range(y1, rect.y1, rect.y2);
143 y2 = clamp_range(y2, rect.y1, rect.y2);
147 const this_type &Union(const this_type &rect)
151 else if (!rect.IsEmpty())
153 x1 = std::min(x1,rect.x1);
154 y1 = std::min(y1,rect.y1);
156 x2 = std::max(x2,rect.x2);
157 y2 = std::max(y2,rect.y2);
163 inline bool IsEmpty() const XBMC_FORCE_INLINE
165 return (x2 - x1) * (y2 - y1) == 0;
168 inline CPointGen<T> P1() const XBMC_FORCE_INLINE
170 return CPointGen<T>(x1, y1);
173 inline CPointGen<T> P2() const XBMC_FORCE_INLINE
175 return CPointGen<T>(x2, y2);
178 inline T Width() const XBMC_FORCE_INLINE
183 inline T Height() const XBMC_FORCE_INLINE
188 inline T Area() const XBMC_FORCE_INLINE
190 return Width() * Height();
193 std::vector<this_type> SubtractRect(this_type splitterRect)
195 std::vector<this_type> newRectaglesList;
196 this_type intersection = splitterRect.Intersect(*this);
198 if (!intersection.IsEmpty())
202 // add rect above intersection if not empty
203 add = this_type(x1, y1, x2, intersection.y1);
205 newRectaglesList.push_back(add);
207 // add rect below intersection if not empty
208 add = this_type(x1, intersection.y2, x2, y2);
210 newRectaglesList.push_back(add);
212 // add rect left intersection if not empty
213 add = this_type(x1, intersection.y1, intersection.x1, intersection.y2);
215 newRectaglesList.push_back(add);
217 // add rect right intersection if not empty
218 add = this_type(intersection.x2, intersection.y1, x2, intersection.y2);
220 newRectaglesList.push_back(add);
224 newRectaglesList.push_back(*this);
227 return newRectaglesList;
230 std::vector<this_type> SubtractRects(std::vector<this_type > intersectionList)
232 std::vector<this_type> fragmentsList;
233 fragmentsList.push_back(*this);
235 for (typename std::vector<this_type>::iterator splitter = intersectionList.begin(); splitter != intersectionList.end(); ++splitter)
237 typename std::vector<this_type> toAddList;
239 for (typename std::vector<this_type>::iterator fragment = fragmentsList.begin(); fragment != fragmentsList.end(); ++fragment)
241 std::vector<this_type> newFragmentsList = fragment->SubtractRect(*splitter);
242 toAddList.insert(toAddList.end(), newFragmentsList.begin(), newFragmentsList.end());
245 fragmentsList.clear();
246 fragmentsList.insert(fragmentsList.end(), toAddList.begin(), toAddList.end());
249 return fragmentsList;
252 bool operator !=(const this_type &rect) const
254 if (x1 != rect.x1) return true;
255 if (x2 != rect.x2) return true;
256 if (y1 != rect.y1) return true;
257 if (y2 != rect.y2) return true;
263 inline static float clamp_range(T x, T l, T h) XBMC_FORCE_INLINE
265 return (x > h) ? h : ((x < l) ? l : x);
269 typedef CPointGen<float> CPoint;
270 typedef CPointGen<int> CPointInt;
272 typedef CRectGen<float> CRect;
273 typedef CRectGen<int> CRectInt;