File indexing completed on 2024-10-13 04:16:23

0001 // SPDX-FileCopyrightText: Lukas Sommer <sommerluk@gmail.com>
0002 // SPDX-License-Identifier: BSD-2-Clause OR MIT
0003 
0004 #ifndef LCHADOUBLE_H
0005 #define LCHADOUBLE_H
0006 
0007 #include "importexport.h"
0008 #include <qdebug.h>
0009 #include <qmetatype.h>
0010 
0011 namespace PerceptualColor
0012 {
0013 /** @brief A LCH color with alpha channel.
0014  *
0015  * Storage of floating point LCH values with <tt>double</tt> precision.
0016  *
0017  * The data is not default-initialized; it is undefined when the object
0018  * is created.
0019  *
0020  * Example:
0021  * @snippet testlchadouble.cpp Use LchaDouble
0022  *
0023  * More details about the valid range: @ref lchrange
0024  *
0025  * @note This class intentionally does not provide the operators
0026  * <em>equal to</em> (<tt>operator==</tt>) and <em>not equal to</em>
0027  * (<tt>operator!=</tt>). As LCH colors are polar coordinates,
0028  * there are various valid representations of the same angle.
0029  * And h is even meaningless when C is zero; on the other hand,
0030  * there might nevertheless be an interest in preserving h. And
0031  * invalid values with L=200 or L=300: Should they be equal because
0032  * both are invalid? Or are they different? The answer to all
0033  * these questions depends on your use case. To avoid confusion,
0034  * no comparison operators are provided by this class. See also
0035  * @ref hasSameCoordinates.
0036  *
0037  * This type is declared as type to Qt’s type system via
0038  * <tt>Q_DECLARE_METATYPE</tt>. Depending on your use case (for
0039  * example if you want to use for <em>queued</em> signal-slot connections),
0040  * you might consider calling <tt>qRegisterMetaType()</tt> for
0041  * this type, once you have a QApplication object.
0042  *
0043  * This data type can be passed to QDebug thanks to
0044  * @ref operator<<(QDebug dbg, const PerceptualColor::LchaDouble &value)
0045  *
0046  * @internal
0047  *
0048  * @todo We could normalize @ref LchaDouble values, just like @ref PolarPointF
0049  * also does. Performance should not matter for this use case! But: Does
0050  * it make sense? */
0051 struct PERCEPTUALCOLOR_IMPORTEXPORT LchaDouble {
0052 public:
0053     /** @brief Lightness, mesured in percent.
0054      *
0055      * The valid range is <tt>[0, 100]</tt>. */
0056     double l;
0057     /** @brief Chroma.
0058      *
0059      * <tt>0</tt> means no chroma (grayscale). The maximum value depends on
0060      * the gamut. For sRGB for example it’s a given value, but other gamuts
0061      * can be bigger, but the practical limit is the gamut of the
0062      * @ref lchrange "human perception", beyond which a
0063      * Chroma value does not make sense. */
0064     double c;
0065     /** @brief Hue, measured in degree.
0066      *
0067      * The valid range is <tt>[0, 360[</tt>. */
0068     double h;
0069     /** @brief Opacity (alpha channel)
0070      *
0071      * The valid range is <tt>[0, 1]</tt>. <tt>0</tt> is fully
0072      * transparent, <tt>1</tt> is fully opaque. */
0073     double a;
0074     [[nodiscard]] bool hasSameCoordinates(const LchaDouble &other) const;
0075 };
0076 
0077 PERCEPTUALCOLOR_IMPORTEXPORT QDebug operator<<(QDebug dbg, const PerceptualColor::LchaDouble &value);
0078 
0079 } // namespace PerceptualColor
0080 
0081 Q_DECLARE_METATYPE(PerceptualColor::LchaDouble)
0082 
0083 #endif // LCHADOUBLE_H