/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
- /*
- * Copyright (C) 2005-2013 Team XBMC
- * http://xbmc.org
- *
- * This Program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This Program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with XBMC; see the file COPYING. If not, see
- * <http://www.gnu.org/licenses/>.
- *
- */
- #pragma once
- #ifdef __GNUC__
- // under gcc, inline will only take place if optimizations are applied (-O). this will force inline even whith optimizations.
- #define XBMC_FORCE_INLINE __attribute__((always_inline))
- #else
- #define XBMC_FORCE_INLINE
- #endif
- #include <vector>
- #include <algorithm>
- template <typename T> class CPointGen
- {
- public:
- typedef CPointGen<T> this_type;
- CPointGen<T>()
- {
- x = 0; y = 0;
- };
- CPointGen<T>(T a, T b)
- {
- x = a;
- y = b;
- };
- template <class U> CPointGen<T>(const CPointGen<U>& rhs)
- {
- x = rhs.x;
- y = rhs.y;
- }
- this_type operator+(const this_type &point) const
- {
- this_type ans;
- ans.x = x + point.x;
- ans.y = y + point.y;
- return ans;
- };
- const this_type &operator+=(const this_type &point)
- {
- x += point.x;
- y += point.y;
- return *this;
- };
- this_type operator-(const this_type &point) const
- {
- CPointGen<T> ans;
- ans.x = x - point.x;
- ans.y = y - point.y;
- return ans;
- };
- const this_type &operator-=(const this_type &point)
- {
- x -= point.x;
- y -= point.y;
- return *this;
- };
- bool operator !=(const this_type &point) const
- {
- if (x != point.x) return true;
- if (y != point.y) return true;
- return false;
- };
- T x, y;
- };
- template <typename T> class CRectGen
- {
- public:
- typedef CRectGen<T> this_type;
- CRectGen<T>() { x1 = y1 = x2 = y2 = 0;};
- CRectGen<T>(T left, T top, T right, T bottom) { x1 = left; y1 = top; x2 = right; y2 = bottom; };
- CRectGen<T>(const CPointGen<T> &p1, const CPointGen<T> &p2)
- {
- x1 = p1.x;
- y1 = p1.y;
- x2 = p2.x;
- y2 = p2.y;
- }
- template <class U> CRectGen<T>(const CRectGen<U>& rhs)
- {
- x1 = rhs.x1;
- y1 = rhs.y1;
- x2 = rhs.x2;
- y2 = rhs.y2;
- }
- void SetRect(T left, T top, T right, T bottom) { x1 = left; y1 = top; x2 = right; y2 = bottom; };
- bool PtInRect(const CPointGen<T> &point) const
- {
- if (x1 <= point.x && point.x <= x2 && y1 <= point.y && point.y <= y2)
- return true;
- return false;
- };
- inline const this_type &operator -=(const CPointGen<T> &point) XBMC_FORCE_INLINE
- {
- x1 -= point.x;
- y1 -= point.y;
- x2 -= point.x;
- y2 -= point.y;
- return *this;
- };
- inline const this_type &operator +=(const CPointGen<T> &point) XBMC_FORCE_INLINE
- {
- x1 += point.x;
- y1 += point.y;
- x2 += point.x;
- y2 += point.y;
- return *this;
- };
- const this_type &Intersect(const this_type &rect)
- {
- x1 = clamp_range(x1, rect.x1, rect.x2);
- x2 = clamp_range(x2, rect.x1, rect.x2);
- y1 = clamp_range(y1, rect.y1, rect.y2);
- y2 = clamp_range(y2, rect.y1, rect.y2);
- return *this;
- };
- const this_type &Union(const this_type &rect)
- {
- if (IsEmpty())
- *this = rect;
- else if (!rect.IsEmpty())
- {
- x1 = std::min(x1,rect.x1);
- y1 = std::min(y1,rect.y1);
- x2 = std::max(x2,rect.x2);
- y2 = std::max(y2,rect.y2);
- }
- return *this;
- };
- inline bool IsEmpty() const XBMC_FORCE_INLINE
- {
- return (x2 - x1) * (y2 - y1) == 0;
- };
- inline CPointGen<T> P1() const XBMC_FORCE_INLINE
- {
- return CPointGen<T>(x1, y1);
- }
- inline CPointGen<T> P2() const XBMC_FORCE_INLINE
- {
- return CPointGen<T>(x2, y2);
- }
- inline T Width() const XBMC_FORCE_INLINE
- {
- return x2 - x1;
- };
- inline T Height() const XBMC_FORCE_INLINE
- {
- return y2 - y1;
- };
- inline T Area() const XBMC_FORCE_INLINE
- {
- return Width() * Height();
- };
- std::vector<this_type> SubtractRect(this_type splitterRect)
- {
- std::vector<this_type> newRectaglesList;
- this_type intersection = splitterRect.Intersect(*this);
- if (!intersection.IsEmpty())
- {
- this_type add;
- // add rect above intersection if not empty
- add = this_type(x1, y1, x2, intersection.y1);
- if (!add.IsEmpty())
- newRectaglesList.push_back(add);
- // add rect below intersection if not empty
- add = this_type(x1, intersection.y2, x2, y2);
- if (!add.IsEmpty())
- newRectaglesList.push_back(add);
- // add rect left intersection if not empty
- add = this_type(x1, intersection.y1, intersection.x1, intersection.y2);
- if (!add.IsEmpty())
- newRectaglesList.push_back(add);
- // add rect right intersection if not empty
- add = this_type(intersection.x2, intersection.y1, x2, intersection.y2);
- if (!add.IsEmpty())
- newRectaglesList.push_back(add);
- }
- else
- {
- newRectaglesList.push_back(*this);
- }
- return newRectaglesList;
- }
- std::vector<this_type> SubtractRects(std::vector<this_type > intersectionList)
- {
- std::vector<this_type> fragmentsList;
- fragmentsList.push_back(*this);
- for (typename std::vector<this_type>::iterator splitter = intersectionList.begin(); splitter != intersectionList.end(); ++splitter)
- {
- typename std::vector<this_type> toAddList;
- for (typename std::vector<this_type>::iterator fragment = fragmentsList.begin(); fragment != fragmentsList.end(); ++fragment)
- {
- std::vector<this_type> newFragmentsList = fragment->SubtractRect(*splitter);
- toAddList.insert(toAddList.end(), newFragmentsList.begin(), newFragmentsList.end());
- }
- fragmentsList.clear();
- fragmentsList.insert(fragmentsList.end(), toAddList.begin(), toAddList.end());
- }
- return fragmentsList;
- }
- bool operator !=(const this_type &rect) const
- {
- if (x1 != rect.x1) return true;
- if (x2 != rect.x2) return true;
- if (y1 != rect.y1) return true;
- if (y2 != rect.y2) return true;
- return false;
- };
- T x1, y1, x2, y2;
- private:
- inline static T clamp_range(T x, T l, T h) XBMC_FORCE_INLINE
- {
- return (x > h) ? h : ((x < l) ? l : x);
- }
- };
- typedef CPointGen<float> CPoint;
- typedef CPointGen<int> CPointInt;
- typedef CRectGen<float> CRect;
- typedef CRectGen<int> CRectInt;