File indexing completed on 2024-05-12 04:44:29
0001 // SPDX-FileCopyrightText: Lukas Sommer <sommerluk@gmail.com> 0002 // SPDX-License-Identifier: BSD-2-Clause OR MIT 0003 0004 #ifndef CHROMAHUEIMAGEPARAMETERS_H 0005 #define CHROMAHUEIMAGEPARAMETERS_H 0006 0007 #include <qglobal.h> 0008 #include <qmetatype.h> 0009 #include <qsharedpointer.h> 0010 #include <qvariant.h> 0011 0012 namespace PerceptualColor 0013 { 0014 class AsyncImageRenderCallback; 0015 class RgbColorSpace; 0016 0017 /** @internal 0018 * 0019 * @brief Parameters for an image of a chroma hue plane. 0020 * 0021 * For usage with @ref AsyncImageProvider. 0022 * 0023 * @warning The default constructor constructs an object with an empty 0024 * @ref rgbColorSpace. Before using this object, you should initialize 0025 * @ref rgbColorSpace. 0026 * 0027 * This is a cut through the gamut body. The cut is orthogonal to 0028 * the L axis, so it shows the a‑b diagram (speaking in terms of 0029 * LAB color model) respectively chroma‑hue diagram (speaking in terms 0030 * of LCH color model). The center of the coordinate system is in 0031 * the center of the image (floating point precision). 0032 * 0033 * Each pixel has the color that corresponds to the coordinate point <em>at 0034 * the middle</em> of the pixel for in-gamut coordinate points, and 0035 * a solid background color for out-of-gamut coordinate points. 0036 * 0037 * The <tt>QImage</tt> that is provided by this class has the 0038 * size <tt>QSize(@ref ChromaHueImageParameters::imageSizePhysical, 0039 * @ref ChromaHueImageParameters::imageSizePhysical)</tt>. There is an 0040 * imaginary circle in the center of the <tt>QImage</tt> with a distance 0041 * of @ref ChromaHueImageParameters::borderPhysical to the border of 0042 * the <tt>QImage</tt>. All pixels within this imaginary circle, plus an 0043 * overlap for safety, are calculated correctly. All other pixels 0044 * have arbitrary values. Therefore, when you paint this 0045 * image somewhere, you have to clip the painting to the imaginary circle. 0046 * Thanks to the overlap, there will be no rendering artefacts, regardless 0047 * of whether you render the circle with or without antialiasing. 0048 * 0049 * This type is declared as type to Qt’s type system via 0050 * <tt>Q_DECLARE_METATYPE</tt>. Depending on your use case (for 0051 * example if you want to use for <em>queued</em> signal-slot connections), 0052 * you might consider calling <tt>qRegisterMetaType()</tt> for 0053 * this type, once you have a QApplication object. 0054 * 0055 * @internal 0056 * 0057 * @todo Why does @ref ChromaHueImageParameters::render() not make everything 0058 * outside the circle transparent? Because it would look ugly without 0059 * antialiasing. And when we use antialiasing various times to cut of 0060 * unwanted artefacts, half-opaque pixel become quarter-opaque and so on, 0061 * so this would be ugly, too. However, we could use a single image to 0062 * work on, and for each interlacing pass result, create a copy and 0063 * apply the antialiased circle only to the copy. This would of course 0064 * require more memory. On the other hand: When calling 0065 * @ref AsyncImageRenderThread::deliverInterlacingPass() a signal will 0066 * be emitted, which will create a copy anyway… */ 0067 struct ChromaHueImageParameters final { 0068 public: 0069 /** @brief The border size, measured in physical pixels. */ 0070 qreal borderPhysical = 0; 0071 /** @brief The device pixel ratio as floating point. */ 0072 qreal devicePixelRatioF = 1; 0073 /** @brief Image size, measured in physical pixels. */ 0074 int imageSizePhysical = 0; 0075 /** @brief Lightness. 0076 * 0077 * This is the lightness (L) value in the LCH color model. 0078 * 0079 * Range: <tt>[0, 100]</tt> */ 0080 qreal lightness = 50; 0081 /** @brief Pointer to @ref RgbColorSpace object 0082 * 0083 * @warning The default constructor constructs an object with an empty 0084 * @ref rgbColorSpace. Before using this object, you must initialize 0085 * @ref rgbColorSpace. */ 0086 QSharedPointer<PerceptualColor::RgbColorSpace> rgbColorSpace = nullptr; 0087 [[nodiscard]] bool operator==(const ChromaHueImageParameters &other) const; 0088 [[nodiscard]] bool operator!=(const ChromaHueImageParameters &other) const; 0089 0090 static void render(const QVariant &variantParameters, AsyncImageRenderCallback &callbackObject); 0091 }; 0092 0093 } // namespace PerceptualColor 0094 0095 Q_DECLARE_METATYPE(PerceptualColor::ChromaHueImageParameters) 0096 0097 #endif // CHROMAHUEIMAGEPARAMETERS_H