File indexing completed on 2024-05-12 15:59:06

0001 /*
0002  * SPDX-FileCopyrightText: 2017 Boudewijn Rempt <boud@valdyas.org>
0003  *
0004  * SPDX-License-Identifier: LGPL-2.0-or-later
0005  */
0006 
0007 #ifndef MANAGEDCOLOR_H
0008 #define MANAGEDCOLOR_H
0009 
0010 #include <QObject>
0011 #include <QVector>
0012 #include <QScopedPointer>
0013 
0014 #include "kritalibkis_export.h"
0015 #include "libkis.h"
0016 
0017 class KoColor;
0018 
0019 /**
0020  * @brief The ManagedColor class is a class to handle colors that are color managed.
0021  * A managed color is a color of which we know the model(RGB, LAB, CMYK, etc), the bitdepth and
0022  * the specific properties of its colorspace, such as the whitepoint, chromacities, trc, etc, as represented
0023  * by the color profile.
0024  *
0025  * Krita has two color management systems. LCMS and OCIO.
0026  * LCMS is the one handling the ICC profile stuff, and the major one handling that ManagedColor deals with.
0027  * OCIO support is only in the display of the colors. ManagedColor has some support for it in colorForCanvas()
0028  *
0029  * All colors in Krita are color managed. QColors are understood as RGB-type colors in the sRGB space.
0030  *
0031  * We recommend you make a color like this:
0032  *
0033  * @code
0034  * colorYellow = ManagedColor("RGBA", "U8", "")
0035  * QVector<float> yellowComponents = colorYellow.components()
0036  * yellowComponents[0] = 1.0
0037  * yellowComponents[1] = 1.0
0038  * yellowComponents[2] = 0
0039  * yellowComponents[3] = 1.0
0040  *
0041  * colorYellow.setComponents(yellowComponents)
0042  * QColor yellow = colorYellow.colorForCanvas(canvas)
0043  * @endcode
0044  */
0045 class KRITALIBKIS_EXPORT ManagedColor : public QObject
0046 {
0047     Q_OBJECT
0048 public:
0049     /**
0050      * @brief ManagedColor
0051      * Create a ManagedColor that is black and transparent.
0052      */
0053     explicit ManagedColor(QObject *parent = 0);
0054     /**
0055      * @brief ManagedColor create a managed color with the given color space properties.
0056      * @see setColorModel() for more details.
0057      */
0058     ManagedColor(const QString &colorModel, const QString &colorDepth, const QString &colorProfile, QObject *parent = 0);
0059     ManagedColor(KoColor color, QObject *parent = 0);
0060     ~ManagedColor() override;
0061 
0062     bool operator==(const ManagedColor &other) const;
0063 
0064     /**
0065      * @brief colorForCanvas
0066      * @param canvas the canvas whose color management you'd like to use. In Krita, different views have
0067      * separate canvasses, and these can have different OCIO configurations active.
0068      * @return the QColor as it would be displaying on the canvas. This result can be used to draw widgets with
0069      * the correct configuration applied.
0070      */
0071     QColor colorForCanvas(Canvas *canvas) const;
0072 
0073     /**
0074      * @brief fromQColor is the (approximate) reverse of colorForCanvas()
0075      * @param qcolor the QColor to convert to a KoColor.
0076      * @param canvas the canvas whose color management you'd like to use.
0077      * @return the approximated ManagedColor, to use for canvas resources.
0078      */
0079     static ManagedColor *fromQColor(const QColor &qcolor, Canvas *canvas = 0);
0080 
0081     /**
0082      * colorDepth A string describing the color depth of the image:
0083      * <ul>
0084      * <li>U8: unsigned 8 bits integer, the most common type</li>
0085      * <li>U16: unsigned 16 bits integer</li>
0086      * <li>F16: half, 16 bits floating point. Only available if Krita was built with OpenEXR</li>
0087      * <li>F32: 32 bits floating point</li>
0088      * </ul>
0089      * @return the color depth.
0090      */
0091     QString colorDepth() const;
0092 
0093     /**
0094      * @brief colorModel retrieve the current color model of this document:
0095      * <ul>
0096      * <li>A: Alpha mask</li>
0097      * <li>RGBA: RGB with alpha channel (The actual order of channels is most often BGR!)</li>
0098      * <li>XYZA: XYZ with alpha channel</li>
0099      * <li>LABA: LAB with alpha channel</li>
0100      * <li>CMYKA: CMYK with alpha channel</li>
0101      * <li>GRAYA: Gray with alpha channel</li>
0102      * <li>YCbCrA: YCbCr with alpha channel</li>
0103      * </ul>
0104      * @return the internal color model string.
0105      */
0106     QString colorModel() const;
0107 
0108     /**
0109      * @return the name of the current color profile
0110      */
0111     QString colorProfile() const;
0112 
0113     /**
0114      * @brief setColorProfile set the color profile of the image to the given profile. The profile has to
0115      * be registered with krita and be compatible with the current color model and depth; the image data
0116      * is <i>not</i> converted.
0117      * @param colorProfile
0118      * @return false if the colorProfile name does not correspond to to a registered profile or if assigning
0119      * the profile failed.
0120      */
0121     bool setColorProfile(const QString &colorProfile);
0122 
0123     /**
0124      * @brief setColorSpace convert the nodes and the image to the given colorspace. The conversion is
0125      * done with Perceptual as intent, High Quality and No LCMS Optimizations as flags and no blackpoint
0126      * compensation.
0127      *
0128      * @param colorModel A string describing the color model of the image:
0129      * <ul>
0130      * <li>A: Alpha mask</li>
0131      * <li>RGBA: RGB with alpha channel (The actual order of channels is most often BGR!)</li>
0132      * <li>XYZA: XYZ with alpha channel</li>
0133      * <li>LABA: LAB with alpha channel</li>
0134      * <li>CMYKA: CMYK with alpha channel</li>
0135      * <li>GRAYA: Gray with alpha channel</li>
0136      * <li>YCbCrA: YCbCr with alpha channel</li>
0137      * </ul>
0138      * @param colorDepth A string describing the color depth of the image:
0139      * <ul>
0140      * <li>U8: unsigned 8 bits integer, the most common type</li>
0141      * <li>U16: unsigned 16 bits integer</li>
0142      * <li>F16: half, 16 bits floating point. Only available if Krita was built with OpenEXR</li>
0143      * <li>F32: 32 bits floating point</li>
0144      * </ul>
0145      * @param colorProfile a valid color profile for this color model and color depth combination.
0146      * @return false the combination of these arguments does not correspond to a colorspace.
0147      */
0148     bool setColorSpace(const QString &colorModel, const QString &colorDepth, const QString &colorProfile);
0149 
0150     /**
0151      * @brief components
0152      * @return a QVector containing the channel/components of this color normalized. This includes the alphachannel.
0153      */
0154     QVector<float> components() const;
0155 
0156     /**
0157      * @brief componentsOrdered()
0158      * @return same as Components, except the values are ordered to the display.
0159      */
0160     QVector<float> componentsOrdered() const;
0161 
0162     /**
0163      * @brief setComponents
0164      * Set the channel/components with normalized values. For integer colorspace, this obviously means the limit
0165      * is between 0.0-1.0, but for floating point colorspaces, 2.4 or 103.5 are still meaningful (if bright) values.
0166      * @param values the QVector containing the new channel/component values. These should be normalized.
0167      */
0168     void setComponents(const QVector<float> &values);
0169 
0170     /**
0171      * Serialize this color following Create's swatch color specification available
0172      * at https://web.archive.org/web/20110826002520/http://create.freedesktop.org/wiki/Swatches_-_color_file_format/Draft
0173      */
0174     QString toXML() const;
0175 
0176     /**
0177      * Unserialize a color following Create's swatch color specification available
0178      * at https://web.archive.org/web/20110826002520/http://create.freedesktop.org/wiki/Swatches_-_color_file_format/Draft
0179      *
0180      * @param xml an XML color
0181      *
0182      * @return the unserialized color, or an empty color object if the function failed
0183      *         to unserialize the color
0184      */
0185     void fromXML(const QString &xml);
0186 
0187     /**
0188      * @brief toQString create a user-visible string of the channel names and the channel values
0189      * @return a string that can be used to display the values of this color to the user.
0190      */
0191     QString toQString();
0192 
0193 
0194 private:
0195 
0196     friend class View;
0197     friend class PaletteView;
0198     friend class Swatch;
0199 
0200     KoColor color() const;
0201 
0202     struct Private;
0203     const QScopedPointer<Private> d;
0204 
0205 };
0206 
0207 #endif // MANAGEDCOLOR_H