/xbmc/guilib/Geometry.h

http://github.com/xbmc/xbmc · C++ Header · 280 lines · 210 code · 46 blank · 24 comment · 29 complexity · 128b0255ac2ea0bb540b96ffc0954ca6 MD5 · raw file

  1. /*
  2. * Copyright (C) 2005-2013 Team XBMC
  3. * http://xbmc.org
  4. *
  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)
  8. * any later version.
  9. *
  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.
  14. *
  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/>.
  18. *
  19. */
  20. #pragma once
  21. #ifdef __GNUC__
  22. // under gcc, inline will only take place if optimizations are applied (-O). this will force inline even whith optimizations.
  23. #define XBMC_FORCE_INLINE __attribute__((always_inline))
  24. #else
  25. #define XBMC_FORCE_INLINE
  26. #endif
  27. #include <vector>
  28. #include <algorithm>
  29. template <typename T> class CPointGen
  30. {
  31. public:
  32. typedef CPointGen<T> this_type;
  33. CPointGen<T>()
  34. {
  35. x = 0; y = 0;
  36. };
  37. CPointGen<T>(T a, T b)
  38. {
  39. x = a;
  40. y = b;
  41. };
  42. template <class U> CPointGen<T>(const CPointGen<U>& rhs)
  43. {
  44. x = rhs.x;
  45. y = rhs.y;
  46. }
  47. this_type operator+(const this_type &point) const
  48. {
  49. this_type ans;
  50. ans.x = x + point.x;
  51. ans.y = y + point.y;
  52. return ans;
  53. };
  54. const this_type &operator+=(const this_type &point)
  55. {
  56. x += point.x;
  57. y += point.y;
  58. return *this;
  59. };
  60. this_type operator-(const this_type &point) const
  61. {
  62. CPointGen<T> ans;
  63. ans.x = x - point.x;
  64. ans.y = y - point.y;
  65. return ans;
  66. };
  67. const this_type &operator-=(const this_type &point)
  68. {
  69. x -= point.x;
  70. y -= point.y;
  71. return *this;
  72. };
  73. bool operator !=(const this_type &point) const
  74. {
  75. if (x != point.x) return true;
  76. if (y != point.y) return true;
  77. return false;
  78. };
  79. T x, y;
  80. };
  81. template <typename T> class CRectGen
  82. {
  83. public:
  84. typedef CRectGen<T> this_type;
  85. CRectGen<T>() { x1 = y1 = x2 = y2 = 0;};
  86. CRectGen<T>(T left, T top, T right, T bottom) { x1 = left; y1 = top; x2 = right; y2 = bottom; };
  87. CRectGen<T>(const CPointGen<T> &p1, const CPointGen<T> &p2)
  88. {
  89. x1 = p1.x;
  90. y1 = p1.y;
  91. x2 = p2.x;
  92. y2 = p2.y;
  93. }
  94. template <class U> CRectGen<T>(const CRectGen<U>& rhs)
  95. {
  96. x1 = rhs.x1;
  97. y1 = rhs.y1;
  98. x2 = rhs.x2;
  99. y2 = rhs.y2;
  100. }
  101. void SetRect(T left, T top, T right, T bottom) { x1 = left; y1 = top; x2 = right; y2 = bottom; };
  102. bool PtInRect(const CPointGen<T> &point) const
  103. {
  104. if (x1 <= point.x && point.x <= x2 && y1 <= point.y && point.y <= y2)
  105. return true;
  106. return false;
  107. };
  108. inline const this_type &operator -=(const CPointGen<T> &point) XBMC_FORCE_INLINE
  109. {
  110. x1 -= point.x;
  111. y1 -= point.y;
  112. x2 -= point.x;
  113. y2 -= point.y;
  114. return *this;
  115. };
  116. inline const this_type &operator +=(const CPointGen<T> &point) XBMC_FORCE_INLINE
  117. {
  118. x1 += point.x;
  119. y1 += point.y;
  120. x2 += point.x;
  121. y2 += point.y;
  122. return *this;
  123. };
  124. const this_type &Intersect(const this_type &rect)
  125. {
  126. x1 = clamp_range(x1, rect.x1, rect.x2);
  127. x2 = clamp_range(x2, rect.x1, rect.x2);
  128. y1 = clamp_range(y1, rect.y1, rect.y2);
  129. y2 = clamp_range(y2, rect.y1, rect.y2);
  130. return *this;
  131. };
  132. const this_type &Union(const this_type &rect)
  133. {
  134. if (IsEmpty())
  135. *this = rect;
  136. else if (!rect.IsEmpty())
  137. {
  138. x1 = std::min(x1,rect.x1);
  139. y1 = std::min(y1,rect.y1);
  140. x2 = std::max(x2,rect.x2);
  141. y2 = std::max(y2,rect.y2);
  142. }
  143. return *this;
  144. };
  145. inline bool IsEmpty() const XBMC_FORCE_INLINE
  146. {
  147. return (x2 - x1) * (y2 - y1) == 0;
  148. };
  149. inline CPointGen<T> P1() const XBMC_FORCE_INLINE
  150. {
  151. return CPointGen<T>(x1, y1);
  152. }
  153. inline CPointGen<T> P2() const XBMC_FORCE_INLINE
  154. {
  155. return CPointGen<T>(x2, y2);
  156. }
  157. inline T Width() const XBMC_FORCE_INLINE
  158. {
  159. return x2 - x1;
  160. };
  161. inline T Height() const XBMC_FORCE_INLINE
  162. {
  163. return y2 - y1;
  164. };
  165. inline T Area() const XBMC_FORCE_INLINE
  166. {
  167. return Width() * Height();
  168. };
  169. std::vector<this_type> SubtractRect(this_type splitterRect)
  170. {
  171. std::vector<this_type> newRectaglesList;
  172. this_type intersection = splitterRect.Intersect(*this);
  173. if (!intersection.IsEmpty())
  174. {
  175. this_type add;
  176. // add rect above intersection if not empty
  177. add = this_type(x1, y1, x2, intersection.y1);
  178. if (!add.IsEmpty())
  179. newRectaglesList.push_back(add);
  180. // add rect below intersection if not empty
  181. add = this_type(x1, intersection.y2, x2, y2);
  182. if (!add.IsEmpty())
  183. newRectaglesList.push_back(add);
  184. // add rect left intersection if not empty
  185. add = this_type(x1, intersection.y1, intersection.x1, intersection.y2);
  186. if (!add.IsEmpty())
  187. newRectaglesList.push_back(add);
  188. // add rect right intersection if not empty
  189. add = this_type(intersection.x2, intersection.y1, x2, intersection.y2);
  190. if (!add.IsEmpty())
  191. newRectaglesList.push_back(add);
  192. }
  193. else
  194. {
  195. newRectaglesList.push_back(*this);
  196. }
  197. return newRectaglesList;
  198. }
  199. std::vector<this_type> SubtractRects(std::vector<this_type > intersectionList)
  200. {
  201. std::vector<this_type> fragmentsList;
  202. fragmentsList.push_back(*this);
  203. for (typename std::vector<this_type>::iterator splitter = intersectionList.begin(); splitter != intersectionList.end(); ++splitter)
  204. {
  205. typename std::vector<this_type> toAddList;
  206. for (typename std::vector<this_type>::iterator fragment = fragmentsList.begin(); fragment != fragmentsList.end(); ++fragment)
  207. {
  208. std::vector<this_type> newFragmentsList = fragment->SubtractRect(*splitter);
  209. toAddList.insert(toAddList.end(), newFragmentsList.begin(), newFragmentsList.end());
  210. }
  211. fragmentsList.clear();
  212. fragmentsList.insert(fragmentsList.end(), toAddList.begin(), toAddList.end());
  213. }
  214. return fragmentsList;
  215. }
  216. bool operator !=(const this_type &rect) const
  217. {
  218. if (x1 != rect.x1) return true;
  219. if (x2 != rect.x2) return true;
  220. if (y1 != rect.y1) return true;
  221. if (y2 != rect.y2) return true;
  222. return false;
  223. };
  224. T x1, y1, x2, y2;
  225. private:
  226. inline static T clamp_range(T x, T l, T h) XBMC_FORCE_INLINE
  227. {
  228. return (x > h) ? h : ((x < l) ? l : x);
  229. }
  230. };
  231. typedef CPointGen<float> CPoint;
  232. typedef CPointGen<int> CPointInt;
  233. typedef CRectGen<float> CRect;
  234. typedef CRectGen<int> CRectInt;