/* * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #ifndef VGLOBAL_H #define VGLOBAL_H #include #include #include #include #include #if !defined(V_NAMESPACE) #define V_USE_NAMESPACE #define V_BEGIN_NAMESPACE #define V_END_NAMESPACE #else /* user namespace */ #define V_USE_NAMESPACE using namespace ::V_NAMESPACE; #define V_BEGIN_NAMESPACE namespace V_NAMESPACE { #define V_END_NAMESPACE } #endif #ifndef __has_attribute # define __has_attribute(x) 0 #endif /* !__has_attribute */ #if __has_attribute(unused) # define V_UNUSED __attribute__((__unused__)) #else # define V_UNUSED #endif /* V_UNUSED */ #if __has_attribute(warn_unused_result) # define V_REQUIRED_RESULT __attribute__((__warn_unused_result__)) #else # define V_REQUIRED_RESULT #endif /* V_REQUIRED_RESULT */ #define V_CONSTEXPR constexpr #define V_NOTHROW noexcept #include "vdebug.h" #if __GNUC__ >= 7 #define VECTOR_FALLTHROUGH __attribute__ ((fallthrough)); #else #define VECTOR_FALLTHROUGH #endif #ifdef LOTTIE_THREAD_SUPPORT #define vthread_local thread_local #else #define vthread_local #endif #if defined(_MSC_VER) #define V_ALWAYS_INLINE __forceinline #else #define V_ALWAYS_INLINE __attribute__((always_inline)) #endif template V_CONSTEXPR inline const T &vMin(const T &a, const T &b) { return (a < b) ? a : b; } template V_CONSTEXPR inline const T &vMax(const T &a, const T &b) { return (a < b) ? b : a; } static const double EPSILON_DOUBLE = 0.000000000001f; static const float EPSILON_FLOAT = 0.000001f; static inline bool vCompare(float p1, float p2) { return (std::abs(p1 - p2) < EPSILON_FLOAT); } static inline bool vIsZero(float f) { return (std::abs(f) <= EPSILON_FLOAT); } static inline bool vIsZero(double f) { return (std::abs(f) <= EPSILON_DOUBLE); } class vFlagHelper { int i; public: explicit constexpr inline vFlagHelper(int ai) noexcept : i(ai) {} constexpr inline operator int() const noexcept { return i; } explicit constexpr inline vFlagHelper(uint32_t ai) noexcept : i(int(ai)) {} explicit constexpr inline vFlagHelper(short ai) noexcept : i(int(ai)) {} explicit constexpr inline vFlagHelper(uint16_t ai) noexcept : i(int(uint32_t(ai))) { } constexpr inline operator uint32_t() const noexcept { return uint32_t(i); } }; template class vFlag { public: static_assert( (sizeof(Enum) <= sizeof(int)), "vFlag only supports int as storage so bigger type will overflow"); static_assert((std::is_enum::value), "vFlag is only usable on enumeration types."); using Int = typename std::conditional< std::is_unsigned::type>::value, uint32_t, signed int>::type; using enum_type = Enum; // compiler-generated copy/move ctor/assignment operators are fine! vFlag() = default; constexpr vFlag(Enum f) noexcept : i(Int(f)) {} explicit constexpr vFlag(vFlagHelper f) noexcept : i(f) {} inline vFlag &operator&=(int mask) noexcept { i &= mask; return *this; } inline vFlag &operator&=(uint32_t mask) noexcept { i &= mask; return *this; } inline vFlag &operator&=(Enum mask) noexcept { i &= Int(mask); return *this; } inline vFlag &operator|=(vFlag f) noexcept { i |= f.i; return *this; } inline vFlag &operator|=(Enum f) noexcept { i |= Int(f); return *this; } inline vFlag &operator^=(vFlag f) noexcept { i ^= f.i; return *this; } inline vFlag &operator^=(Enum f) noexcept { i ^= Int(f); return *this; } constexpr inline operator Int() const noexcept { return i; } constexpr inline vFlag operator|(vFlag f) const { return vFlag(vFlagHelper(i | f.i)); } constexpr inline vFlag operator|(Enum f) const noexcept { return vFlag(vFlagHelper(i | Int(f))); } constexpr inline vFlag operator^(vFlag f) const noexcept { return vFlag(vFlagHelper(i ^ f.i)); } constexpr inline vFlag operator^(Enum f) const noexcept { return vFlag(vFlagHelper(i ^ Int(f))); } constexpr inline vFlag operator&(int mask) const noexcept { return vFlag(vFlagHelper(i & mask)); } constexpr inline vFlag operator&(uint32_t mask) const noexcept { return vFlag(vFlagHelper(i & mask)); } constexpr inline vFlag operator&(Enum f) const noexcept { return vFlag(vFlagHelper(i & Int(f))); } constexpr inline vFlag operator~() const noexcept { return vFlag(vFlagHelper(~i)); } constexpr inline bool operator!() const noexcept { return !i; } constexpr inline bool testFlag(Enum f) const noexcept { return (i & Int(f)) == Int(f) && (Int(f) != 0 || i == Int(f)); } inline vFlag &setFlag(Enum f, bool on = true) noexcept { return on ? (*this |= f) : (*this &= ~f); } Int i{0}; }; class VColor { public: VColor() = default; explicit VColor(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha = 255) noexcept : a(alpha), r(red), g(green), b(blue) { } inline uint8_t red() const noexcept { return r; } inline uint8_t green() const noexcept { return g; } inline uint8_t blue() const noexcept { return b; } inline uint8_t alpha() const noexcept { return a; } inline void setRed(uint8_t red) noexcept { r = red; } inline void setGreen(uint8_t green) noexcept { g = green; } inline void setBlue(uint8_t blue) noexcept { b = blue; } inline void setAlpha(uint8_t alpha) noexcept { a = alpha; } inline bool isOpaque() const { return a == 255; } inline bool isTransparent() const { return a == 0; } inline bool operator==(const VColor &o) const { return ((a == o.a) && (r == o.r) && (g == o.g) && (b == o.b)); } uint32_t premulARGB() const { int pr = (r * a) / 255; int pg = (g * a) / 255; int pb = (b * a) / 255; return uint32_t((a << 24) | (pr << 16) | (pg << 8) | (pb)); } uint32_t premulARGB(float opacity) const { int alpha = int(a * opacity); int pr = (r * alpha) / 255; int pg = (g * alpha) / 255; int pb = (b * alpha) / 255; return uint32_t((alpha << 24) | (pr << 16) | (pg << 8) | (pb)); } public: uint8_t a{0}; uint8_t r{0}; uint8_t g{0}; uint8_t b{0}; }; enum class FillRule: unsigned char { EvenOdd, Winding }; enum class JoinStyle: unsigned char { Miter, Bevel, Round }; enum class CapStyle: unsigned char { Flat, Square, Round }; enum class BlendMode { Src, SrcOver, DestIn, DestOut, Last, }; #ifndef V_CONSTRUCTOR_FUNCTION #define V_CONSTRUCTOR_FUNCTION0(AFUNC) \ namespace { \ static const struct AFUNC##_ctor_class_ { \ inline AFUNC##_ctor_class_() { AFUNC(); } \ } AFUNC##_ctor_instance_; \ } #define V_CONSTRUCTOR_FUNCTION(AFUNC) V_CONSTRUCTOR_FUNCTION0(AFUNC) #endif #endif // VGLOBAL_H