File indexing completed on 2024-05-12 04:35:06

0001 /* This file is part of the TikZKit project.
0002  *
0003  * Copyright (C) 2014 Dominik Haumann <dhaumann@kde.org>
0004  *
0005  * This library is free software; you can redistribute it and/or modify
0006  * it under the terms of the GNU Library General Public License as published
0007  * by the Free Software Foundation, either version 2 of the License, or
0008  * (at your option) any later version.
0009  *
0010  * This library is distributed in the hope that it will be useful,
0011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0013  * GNU Library General Public License for more details.
0014  *
0015  * You should have received a copy of the GNU Library General Public License
0016  * along with this library; see the file COPYING.LIB.  If not, see
0017  * <http://www.gnu.org/licenses/>.
0018  */
0019 #ifndef TIKZ_POS_H
0020 #define TIKZ_POS_H
0021 
0022 #include "Value.h"
0023 #include <QPointF>
0024 
0025 namespace tikz
0026 {
0027 
0028 class TIKZKITCORE_EXPORT Pos
0029 {
0030     public:
0031         /**
0032          * Default constructor, setting the position to 0, 0 in unit pt.
0033          */
0034         constexpr Pos() = default;
0035 
0036         /**
0037          * Constructor setting the position to @p x and @p y in @p unit..
0038          */
0039         constexpr Pos(const Value & x, const Value & y)
0040             : m_x(x)
0041             , m_y(y)
0042         {
0043         }
0044 
0045         /**
0046          * Constructor setting the position to @p x and @p y in @p unit..
0047          */
0048         constexpr Pos(qreal x, qreal y, Unit unit = Unit::Point)
0049             : m_x(x, unit)
0050             , m_y(y, unit)
0051         {
0052         }
0053 
0054         /**
0055          * Construct a Pos object from the QPointF object @p point.
0056          * The size is interpreted according to @p unit.
0057          */
0058         constexpr Pos(const QPointF & point, Unit unit = Unit::Point)
0059             : m_x(point.x(), unit)
0060             , m_y(point.y(), unit)
0061         {
0062         }
0063 
0064         /**
0065          * Check whether this value is a finite value, i.e. other than NaN or infinity.
0066          */
0067         inline bool isValid() const noexcept
0068         {
0069             return m_x.isValid() && m_y.isValid();
0070         }
0071 
0072         /**
0073          * Return the x coordinate of this Pos.
0074          */
0075         inline constexpr tikz::Value x() const noexcept
0076         {
0077             return m_x;
0078         }
0079 
0080         /**
0081          * Return a reference to the x coordinate of this Pos.
0082          */
0083         inline tikz::Value & rx() noexcept
0084         {
0085             return m_x;
0086         }
0087 
0088         /**
0089          * Return the y coordinate of this Pos.
0090          */
0091         inline constexpr tikz::Value y() const noexcept
0092         {
0093             return m_y;
0094         }
0095 
0096         /**
0097          * Return a reference to the y coordinate of this Pos.
0098          */
0099         inline tikz::Value & ry() noexcept
0100         {
0101             return m_y;
0102         }
0103 
0104         /**
0105          * Return a Pos where both x and y coordinates are in @p unit.
0106          */
0107         inline constexpr Pos convertTo(Unit unit) const noexcept
0108         {
0109             return Pos(m_x.convertTo(unit), m_y.convertTo(unit));
0110         }
0111 
0112         /**
0113          * Convert this Pos to a string in the form "(x, y)".
0114          */
0115         QString toString() const;
0116 
0117         /**
0118          * Convert @p str of the form "(x, y)" to a Pos.
0119          */
0120         static Pos fromString(const QString & str);
0121 
0122     //
0123     // operators
0124     //
0125     public:
0126         /**
0127          * Implicit cast to QPointF.
0128          * @warning the returned value \e always is of type Unit::Point!
0129          */
0130         inline constexpr operator QPointF () const noexcept
0131         {
0132             return QPointF(m_x.toPoint(),
0133                            m_y.toPoint());
0134         }
0135 
0136         /**
0137          * Adds @p pos to this Pos and returns a reference to this Pos.
0138          */
0139         inline Pos & operator+=(const Pos & pos) noexcept
0140         {
0141             Q_ASSERT(isValid());
0142             Q_ASSERT(pos.isValid());
0143             m_x += pos.m_x;
0144             m_y += pos.m_y;
0145             return *this;
0146         }
0147 
0148         /**
0149          * Subtracts @p pos to this Pos and returns a reference to this Pos.
0150          */
0151         inline Pos & operator-=(const Pos & pos) noexcept
0152         {
0153             Q_ASSERT(isValid());
0154             Q_ASSERT(pos.isValid());
0155             m_x -= pos.m_x;
0156             m_y -= pos.m_y;
0157             return *this;
0158         }
0159 
0160         /**
0161          * Multiplies this Pos with @p factor and returns a reference to this Pos.
0162          */
0163         inline Pos & operator*=(qreal factor) noexcept
0164         {
0165             Q_ASSERT(isValid());
0166             m_x *= factor;
0167             m_y *= factor;
0168             return *this;
0169         }
0170 
0171         /**
0172          * Divides this Pos by @p divisor and returns a reference to this Pos.
0173          */
0174         inline Pos & operator/=(qreal divisor) noexcept
0175         {
0176             Q_ASSERT(isValid());
0177             m_x /= divisor;
0178             m_y /= divisor;
0179             return *this;
0180         }
0181 
0182     public:
0183         /**
0184          * QDebug support.
0185          */
0186         inline friend QDebug operator<<(QDebug s, const tikz::Pos & pos)
0187         {
0188             s.nospace() << pos.toString();
0189             return s.space();
0190         }
0191 
0192     private:
0193         // the x and y coordinate of this Pos
0194         Value m_x;
0195         Value m_y;
0196 };
0197 
0198 //
0199 // operators
0200 //
0201 
0202 /**
0203  * Check for equality with (p1 == p2).
0204  */
0205 inline bool operator==(const Pos & p1, const Pos & p2) noexcept
0206 {
0207     return (p1.x() == p2.x()) && (p1.y() == p2.y());
0208 }
0209 
0210 /**
0211  * Check for inequality with (val1 != val2).
0212  */
0213 inline bool operator!=(const Pos & p1, const Pos & p2) noexcept
0214 {
0215     return ! (p1 == p2);
0216 }
0217 
0218 /**
0219  * Returns a Pos that is the sum of @p p1 and @p p2.
0220  */
0221 inline Pos operator+(const Pos & p1, const Pos & p2) noexcept
0222 {
0223     Q_ASSERT(p1.isValid());
0224     Q_ASSERT(p2.isValid());
0225     return Pos(p1.x() + p2.x(), p1.y() + p2.y());
0226 }
0227 
0228 /**
0229  * Returns a Pos that is the difference of @p p1 and @p p2.
0230  */
0231 inline Pos operator-(const Pos & p1, const Pos & p2) noexcept
0232 {
0233     Q_ASSERT(p1.isValid());
0234     Q_ASSERT(p2.isValid());
0235     return Pos(p1.x() - p2.x(), p1.y() - p2.y());
0236 }
0237 
0238 /**
0239  * Returns a copy of @p pos, multiplied by @p factor.
0240  */
0241 inline Pos operator*(const Pos & pos, qreal factor) noexcept
0242 {
0243     return Pos(pos.x() * factor, pos.y() * factor);
0244 }
0245 
0246 /**
0247  * Returns a copy of @p pos, multiplied by @p factor.
0248  */
0249 inline Pos operator*(qreal factor, const Pos & pos) noexcept
0250 {
0251     return Pos(pos.x() * factor, pos.y() * factor);
0252 }
0253 
0254 /**
0255  * Returns a copy of @p pos, divided by @p factor.
0256  */
0257 inline Pos operator/(const Pos & pos, qreal divisor)
0258 {
0259     Q_ASSERT(divisor != 0);
0260     return Pos(pos.x() / divisor, pos.y() / divisor);
0261 }
0262 
0263 /**
0264  * Returns a copy of @p pos, divided by @p factor.
0265  */
0266 inline Pos operator/(qreal divisor, const Pos & pos)
0267 {
0268     Q_ASSERT(divisor != 0);
0269     return Pos(pos.x() / divisor, pos.y() / divisor);
0270 }
0271 
0272 }
0273 
0274 namespace QTest
0275 {
0276     // forward declaration of template in qtestcase.h
0277     template<typename T> char* toString(const T&);
0278     
0279     template<>
0280     TIKZKITCORE_EXPORT char *toString(const tikz::Pos & pos);
0281 }
0282 
0283 /**
0284  * Declare as movable, since the members of Pos are primitive types.
0285  */
0286 Q_DECLARE_TYPEINFO(tikz::Pos, Q_MOVABLE_TYPE);
0287 Q_DECLARE_METATYPE(tikz::Pos)
0288 
0289 #endif // TIKZ_POS_H
0290 
0291 // kate: indent-width 4; replace-tabs on;