File indexing completed on 2024-05-12 04:44:30
0001 // SPDX-FileCopyrightText: Lukas Sommer <sommerluk@gmail.com> 0002 // SPDX-License-Identifier: BSD-2-Clause OR MIT 0003 0004 #ifndef CHROMALIGHTNESSIMAGEPARAMETERS_H 0005 #define CHROMALIGHTNESSIMAGEPARAMETERS_H 0006 0007 #include <qglobal.h> 0008 #include <qmetatype.h> 0009 #include <qsharedpointer.h> 0010 #include <qsize.h> 0011 #include <qvariant.h> 0012 0013 namespace PerceptualColor 0014 { 0015 0016 class AsyncImageRenderCallback; 0017 class RgbColorSpace; 0018 0019 /** @internal 0020 * 0021 * @brief An image of a chroma-lightness plane. 0022 * 0023 * This is a cut through the gamut body at a given hue. 0024 * 0025 * For the y axis, its height covers the lightness range [0, 100]. 0026 * Coordinate point <tt>(0)</tt> corresponds to value 100. 0027 * Coordinate point <tt>height</tt> corresponds to value 0. 0028 * Its x axis uses always the same scale as the y axis. So if the size 0029 * is a square, both x range and y range are from 0 to 100. If the 0030 * width is larger than the height, the x range goes beyond 100. The 0031 * image paints all the LCH values that are within the gamut and x/y range. 0032 * Each pixel show the color of the coordinate point at its center. So 0033 * the pixel at pixel position <tt>(2, 3)</tt> shows the color corresponding 0034 * to coordinate point <tt>(2.5, 3.5)</tt>. 0035 * 0036 * @todo Solve the problem with nearestNeighborSearch to respond immediately, 0037 * without waiting for the rendering to complete, to avoid using things like 0038 * <a href="https://api.kde.org/frameworks/kwidgetsaddons/html/classKBusyIndicatorWidget.html"> 0039 * KBusyIndicatorWidget</a>. 0040 * 0041 * @note Intentionally there is no anti-aliasing because this would be much 0042 * slower: As there is no mathematical description of the shape of the color 0043 * solid, the only easy way to get anti-aliasing would be to render at a 0044 * higher resolution (say two times higher, which would yet mean four times 0045 * more data), and then downscale it to the final resolution. This would be 0046 * too slow. */ 0047 class ChromaLightnessImageParameters final 0048 { 0049 public: 0050 [[nodiscard]] bool operator==(const ChromaLightnessImageParameters &other) const; 0051 [[nodiscard]] bool operator!=(const ChromaLightnessImageParameters &other) const; 0052 static void render(const QVariant &variantParameters, AsyncImageRenderCallback &callbackObject); 0053 0054 /** @brief The LCH-hue. 0055 * 0056 * Valid range: 0° ≤ value < 360° */ 0057 qreal hue = 0; 0058 /** @brief Image size, measured in physical pixels. */ 0059 QSize imageSizePhysical; 0060 /** @brief Pointer to @ref RgbColorSpace object */ 0061 QSharedPointer<PerceptualColor::RgbColorSpace> rgbColorSpace; 0062 0063 private: 0064 /** @internal @brief Only for unit tests. */ 0065 friend class TestChromaLightnessImageParameters; 0066 0067 /** @brief Calculate one-dimensional index for given <tt>x</tt> and 0068 * <tt>y</tt> coordinates. 0069 * 0070 * @param x The <tt>x</tt> coordinate 0071 * @param y The <tt>y</tt> coordinate 0072 * @param imageSizePhysical The image size 0073 * @returns The corresponding index, assuming a one-dimensional array 0074 * that contains one element for each pixel, starting with the elements 0075 * <tt>(0, 0)</tt>, than <tt>(0, 1)</tt> and so on, line by line. */ 0076 [[nodiscard]] static constexpr int maskIndex(const int x, const int y, const QSize imageSizePhysical) 0077 { 0078 return x + y * imageSizePhysical.width(); 0079 } 0080 }; 0081 0082 } // namespace PerceptualColor 0083 0084 Q_DECLARE_METATYPE(PerceptualColor::ChromaLightnessImageParameters) 0085 0086 #endif // CHROMALIGHTNESSIMAGEPARAMETERS_H