/* * (c) Copyright Ascensio System SIA 2010-2014 * * This program is a free software product. You can redistribute it and/or * modify it under the terms of the GNU Affero General Public License (AGPL) * version 3 as published by the Free Software Foundation. In accordance with * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect * that Ascensio System SIA expressly excludes the warranty of non-infringement * of any third-party rights. * * This program is distributed WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html * * You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, * EU, LV-1021. * * The interactive user interfaces in modified source and object code versions * of the Program must display Appropriate Legal Notices, as required under * Section 5 of the GNU AGPL version 3. * * Pursuant to Section 7(b) of the License you must retain the original Product * logo when distributing the program. Pursuant to Section 7(e) we decline to * grant you any rights under trademark law for use of our trademarks. * * All the Product's GUI elements, including illustrations and icon sets, as * well as technical writing content are licensed under the terms of the * Creative Commons Attribution-ShareAlike 4.0 International. See the License * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode * */ #pragma once #ifndef UTILITY_UNIT_INCLUDE_H_ #define UTILITY_UNIT_INCLUDE_H_ #include #include "Exception/UnitError.h" #include "ASCStlUtils.h" template class UnitConverter; template class UnitFactory; template class Unit { public: Unit() : m_value() { U::it_not_unit_type(); } Unit(const V& value) : m_value(value) { U::it_not_unit_type(); } const Unit& operator =(const V& value) { m_value = value; return *this; } Unit(const std::string& value) { U::it_not_unit_type(); fromString(value); } const Unit& operator =(const std::string& value) { fromString(value); return *this; } template Unit(const Unit& unit) { fromUnit(unit); } template const Unit& operator =(const Unit& unit) { fromUnit(unit); return *this; } operator const V() const { return m_value; } const Unit& operator -=(const Unit& rhs) { m_value -= rhs.m_value; return *this; } const Unit& operator +=(const Unit& rhs) { m_value += rhs.m_value; return *this; } const Unit& operator +=(const V rhs) { m_value += rhs; return *this; } const Unit& operator -=(const V rhs) { m_value -= rhs; return *this; } const Unit& operator /=(const V rhs) { m_value /= rhs; return *this; } const Unit& operator *=(const V rhs) { m_value *= rhs; return *this; } const Unit operator -(const Unit& rhs) const { Unit result(*this); return result -= rhs; } const Unit operator +(const Unit& rhs) const { Unit result(*this); return result += rhs; } const Unit operator +(const V& rhs) const { Unit result(*this); return result += rhs; } const Unit operator -(const V& rhs) const { Unit result(*this); return result -= rhs; } const Unit operator /(const V& rhs) const { Unit result(*this); return result /= rhs; } const Unit operator *(const V& rhs) const { Unit result(*this); return result *= rhs; } const Unit operator-() const { Unit value = -m_value; return value; } template const Unit& operator +=(const Unit& rhs) { return *this += Unit(rhs); } template const Unit& operator -=(const Unit& rhs) { return *this -= Unit(rhs); } template const Unit operator +(const Unit& rhs) { Unit result(*this); return result += rhs; } template const Unit operator -(const Unit& rhs) { Unit result(*this); return result -= rhs; } public: inline const std::string ToString() const { return ToString(m_value) + U::ToString(); } inline const V value() const { return m_value; } private: inline void fromString(const std::string& value) { if (value.empty()) { m_value = V(); } else { *this = UnitFactory::create(value); } } inline const std::string ToString(const int value) const { return StlUtils::IntToString(value); } inline const std::string ToString(const double value) const { std::string format = std::string("%0.") + StlUtils::IntToString(P) + std::string("f"); char strValue[256]; sprintf_s(strValue, 256, format.c_str(), value); return std::string(strValue); } template void fromUnit(const Unit& unit) { m_value = UnitConverter::convert(unit.value()); } private: V m_value; }; class Cm { public: static void it_not_unit_type() {} static const std::string ToString() {return "cm";} }; class Pt { public: static void it_not_unit_type() {} static const std::string ToString() {return "pt";} }; class Px { public: static void it_not_unit_type() {} static const std::string ToString() {return "px";} }; class Mm { public: static void it_not_unit_type() {} static const std::string ToString() {return "mm";} }; class Dx { public: static void it_not_unit_type() {} static const std::string ToString() {return "";} }; class Sx { public: static void it_not_unit_type() {} static const std::string ToString() {return "";} }; class Multi { public: static void it_not_unit_type() {} static const std::string ToString() {return "*";} }; class Percent { public: static void it_not_unit_type() {} static const std::string ToString() {return "%";} }; class Inch { public: static void it_not_unit_type() {} static const std::string ToString() {return "in";} }; template class UnitConverter { public: template static const V convert(const double value) { return static_cast(value); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value * 10); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value * 72 / 2.54); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value * 72 * 4 / 3 / 2.54); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value / 2.54); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value * 72 * 20 / 2.54); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value * 72 * 100 * 1000 / 20); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value * 72 * 20 / 2.54); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value / 10); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value * 72 / 10 / 2.54); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value * 72 * 4 / 3 / 10 / 2.54); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value / 2.54 / 10); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value * 72 * 20 / 10 / 2.54); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value * 72 * 100 * 1000 / 10 / 20); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value * 72 * 20 / 10 / 2.54); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value * 2.54 / 72); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value * 2.54 * 10 / 72); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value * 4 / 3); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value / 72); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value * 20); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value * 2.54 * 100 * 1000 / 20); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value * 20); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value * 2.54 * 3/ 72 / 4); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value * 2.54 * 10 * 3/ 72 /4); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value * 3 / 4); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value * 3 / 72 / 4); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value * 20 * 3 / 4); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value * 2.54 * 100 * 1000 * 3/ 20 / 4); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value * 20 * 3 / 4); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value * 2.54); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value * 2.54 * 10); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value * 72); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value * 72 * 4 / 3); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value * 72 * 20); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value * 1000 * 100 * 2.54 * 72 / 20 ); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value * 72 * 20); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value * 2.54 / 72 / 20); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value * 2.54 * 10 / 72 / 20); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value / 20); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value * 4 / 3 / 20); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value / 20 / 72); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value * 1000 * 1000 * 2.54 / 100 / 1000 ); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value * 20 / 72 / 100 / 1000); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value * 20 / 72 / 100 / 1000 * 10); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value * 20 / 100 / 1000 / 2.54); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value * 20 * 4 / 3 / 100 / 1000 / 2.54); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value * 20 / 2.54 / 72 / 100 / 1000); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value * 20 * 20 / 2.54 / 100 / 1000); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value * 20 * 20 / 2.54 / 100 / 1000); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value * 2.54 / 72 / 20); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value * 2.54 * 10 / 72 / 20); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value / 20); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value * 4 / 3 / 20); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value / 20 / 72); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value * 1000 * 1000 * 2.54 / 100 / 1000 ); } }; template<> class UnitConverter { public: template static const V convert(const double value) { return static_cast(value); } }; template class UnitFactory { public: inline static const Unit create(const std::string& str) { try { const size_t pos = str.find_first_not_of("-.0123456789"); if (pos == std::string::npos) { if (std::string::npos != str.find('.')) return Unit((V)StlUtils::ToDouble(str)); return Unit((V)StlUtils::ToInteger(str)); } const std::string unit = str.substr(pos, str.size() - pos); if (0 == pos) { return Unit(0); } V value; if (std::string::npos != str.find('.')) value = (V)StlUtils::ToDouble(str.substr(0, pos)); else value = (V)StlUtils::ToInteger(str.substr(0, pos)); if (unit == Cm::ToString()) return Unit(value); else if (unit == Mm::ToString()) return Unit(value); else if (unit == Pt::ToString()) return Unit(value); else if (unit == Px::ToString()) return Unit(value); else if (unit == Multi::ToString()) return Unit(value); else if (unit == Percent::ToString()) return Unit(value); else if (unit == Inch::ToString()) return Unit(value); else throw UnitError("Bad unit"); } catch (...) { return Unit(0); } } }; #endif // UTILITY_UNIT_INCLUDE_H_