KoColor.h 10.4 KB
Newer Older
1 2
/*
 *  Copyright (c) 2005 Boudewijn Rempt <boud@valdyas.org>
Thomas Zander's avatar
Thomas Zander committed
3
 *  Copyright (C) 2007 Thomas Zander <zander@kde.org>
4
 *
5 6 7 8
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
9
 *
10 11 12 13
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
14
 *
15 16 17 18 19
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
*/
20 21
#ifndef KOCOLOR_H
#define KOCOLOR_H
22

23 24
#include <QColor>
#include <QMetaType>
25
#include <QtGlobal>
26
#include "kritapigment_export.h"
27
#include "KoColorConversionTransformation.h"
28 29
#include "KoColorSpaceRegistry.h"
#include "KoColorSpaceTraits.h"
30
#include <boost/operators.hpp>
31

32

33 34 35
class QDomDocument;
class QDomElement;

Cyrille Berger's avatar
Cyrille Berger committed
36 37
class KoColorProfile;
class KoColorSpace;
38

39
/**
Cyrille Berger's avatar
Cyrille Berger committed
40 41
 * A KoColor describes a color in a certain colorspace. The color is stored in a buffer
 * that can be manipulated by the function of the color space.
42
 */
43
class KRITAPIGMENT_EXPORT KoColor : public boost::equality_comparable<KoColor>
44
{
45 46 47

public:
    /// Create an empty KoColor. It will be valid, but also black and transparent
48
    KoColor();
49

50
    /// Create a null KoColor. It will be valid, but all channels will be set to 0
51
    explicit KoColor(const KoColorSpace * colorSpace);
52

53 54
    /// Create a KoColor from a QColor. The QColor is immediately converted to native. The QColor
    /// is assumed to have the current monitor profile.
55
    KoColor(const QColor & color, const KoColorSpace * colorSpace);
56 57

    /// Create a KoColor using a native color strategy. The data is copied.
58
    KoColor(const quint8 * data, const KoColorSpace * colorSpace);
59 60

    /// Create a KoColor by converting src into another colorspace
61
    KoColor(const KoColor &src, const KoColorSpace * colorSpace);
62

63
    /// Copy constructor -- deep copies the colors.
64 65 66
    KoColor(const KoColor & rhs) {
        *this = rhs;
    }
67

Thomas Zander's avatar
Thomas Zander committed
68 69
    /**
     * assignment operator to copy the data from the param color into this one.
70
     * @param rhs the color we are going to copy
Thomas Zander's avatar
Thomas Zander committed
71 72
     * @return this color
     */
73 74 75 76 77 78 79 80 81 82 83 84 85
    inline KoColor &operator=(const KoColor &rhs) {
        if (&rhs == this) {
            return *this;
        }

        m_colorSpace = rhs.m_colorSpace;
        m_size = rhs.m_size;
        memcpy(m_data, rhs.m_data, m_size);

        assertPermanentColorspace();

        return *this;
    }
86

87
    bool operator==(const KoColor &other) const {
88
        if (*colorSpace() != *other.colorSpace()) {
89
            return false;
90 91 92 93
        }
        if (m_size != other.m_size) {
            return false;
        }
94 95
        return memcmp(m_data, other.m_data, m_size) == 0;
    }
96

Thomas Zander's avatar
Thomas Zander committed
97
    /// return the current colorSpace
98 99 100
    const KoColorSpace * colorSpace() const {
        return m_colorSpace;
    }
101

Thomas Zander's avatar
Thomas Zander committed
102
    /// return the current profile
103
    const KoColorProfile *profile() const;
104 105

    /// Convert this KoColor to the specified colorspace. If the specified colorspace is the
106
    /// same as the original colorspace, do nothing
107 108 109 110
    void convertTo(const KoColorSpace * cs,
                   KoColorConversionTransformation::Intent renderingIntent,
                   KoColorConversionTransformation::ConversionFlags conversionFlags);

111
    void convertTo(const KoColorSpace * cs);
112

113 114 115 116 117 118 119 120 121 122 123 124
    /// Copies this color and converts it to the specified colorspace. If the specified colorspace is the
    /// same as the original colorspace, just returns a copy
    KoColor convertedTo(const KoColorSpace * cs,
                        KoColorConversionTransformation::Intent renderingIntent,
                        KoColorConversionTransformation::ConversionFlags conversionFlags) const;

    /// Copies this color and converts it to the specified colorspace. If the specified colorspace is the
    /// same as the original colorspace, just returns a copy
    KoColor convertedTo(const KoColorSpace * cs) const;



125 126 127
    /// assign new profile without converting pixel data
    void setProfile(const KoColorProfile *profile);

128
    /// Replace the existing color data, and colorspace with the specified data.
Boudewijn Rempt's avatar
Boudewijn Rempt committed
129
    /// The data is copied.
130
    void setColor(const quint8 * data, const KoColorSpace * colorSpace = 0);
Thomas Zander's avatar
Thomas Zander committed
131

132 133 134
    /// Convert the color from src and replace the value of the current color with the converted data.
    /// Don't convert the color if src and this have the same colorspace.
    void fromKoColor(const KoColor& src);
Thomas Zander's avatar
Thomas Zander committed
135 136 137 138 139

    /// a convenience method for the above.
    void toQColor(QColor *c) const;
    /// a convenience method for the above.
    QColor toQColor() const;
140

141 142 143
    /**
     * Convenient function to set the opacity of the color.
     */
144
    void setOpacity(quint8 alpha);
145
    void setOpacity(qreal alpha);
146 147 148
    /**
     * Convenient function that return the opacity of the color
     */
149 150
    quint8 opacityU8() const;
    qreal opacityF() const;
151

152
    /// Convenient function for converting from a QColor
153
    void fromQColor(const QColor& c);
154

Cyrille Berger's avatar
Cyrille Berger committed
155 156 157 158 159
    /**
     * @return the buffer associated with this color object to be used with the
     *         transformation object created by the color space of this KoColor
     *         or to copy to a different buffer from the same color space
     */
160 161 162
    quint8 * data() {
        return m_data;
    }
Thomas Zander's avatar
Thomas Zander committed
163

Cyrille Berger's avatar
Cyrille Berger committed
164 165 166 167 168
    /**
     * @return the buffer associated with this color object to be used with the
     *         transformation object created by the color space of this KoColor
     *         or to copy to a different buffer from the same color space
     */
169 170 171
    const quint8 * data() const {
        return m_data;
    }
172

173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201

    /**
     * Channelwise subtracts \p value from *this and stores the result in *this
     *
     * Throws a safe assert if the colorspaces of the two colors are different
     */
    void subtract(const KoColor &value);

    /**
     * Channelwise subtracts \p value from a copy of *this and returns the result
     *
     * Throws a safe assert if the colorspaces of the two colors are different
     */
    KoColor subtracted(const KoColor &value) const;

    /**
     * Channelwise adds \p value to *this and stores the result in *this
     *
     * Throws a safe assert if the colorspaces of the two colors are different
     */
    void add(const KoColor &value);

    /**
     * Channelwise adds \p value to a copy of *this and returns the result
     *
     * Throws a safe assert if the colorspaces of the two colors are different
     */
    KoColor added(const KoColor &value) const;

202 203 204
    /**
     * Serialize this color following Create's swatch color specification available
     * at http://create.freedesktop.org/wiki/index.php/Swatches_-_colour_file_format
205
     *
206 207
     * This function doesn't create the \<color /\> element but rather the \<CMYK /\>,
     * \<sRGB /\>, \<RGB /\> ... elements. It is assumed that colorElt is the \<color /\>
208
     * element.
209
     *
210
     * @param colorElt root element for the serialization, it is assumed that this
211
     *                 element is \<color /\>
212 213 214
     * @param doc is the document containing colorElt
     */
    void toXML(QDomDocument& doc, QDomElement& colorElt) const;
215

216 217 218
    /**
     * Unserialize a color following Create's swatch color specification available
     * at http://create.freedesktop.org/wiki/index.php/Swatches_-_colour_file_format
219
     *
220
     * @param elt the element to unserialize (\<CMYK /\>, \<sRGB /\>, \<RGB /\>)
221
     * @param channelDepthId the bit depth is unspecified by the spec, this allow to select
222 223 224 225 226 227
     *                   a preferred bit depth for creating the KoColor object (if that
     *                   bit depth isn't available, this function will randomly select
     *                   an other bit depth)
     * @return the unserialize color, or an empty color object if the function failed
     *         to unserialize the color
     */
228
    static KoColor fromXML(const QDomElement& elt, const QString & channelDepthId);
229

230 231 232 233
    /**
     * Unserialize a color following Create's swatch color specification available
     * at http://create.freedesktop.org/wiki/index.php/Swatches_-_colour_file_format
     *
234
     * @param elt the element to unserialize (\<CMYK /\>, \<sRGB /\>, \<RGB /\>)
235
     * @param channelDepthId the bit depth is unspecified by the spec, this allow to select
236 237 238 239 240 241 242
     *                   a preferred bit depth for creating the KoColor object (if that
     *                   bit depth isn't available, this function will randomly select
     *                   an other bit depth)
     * @param ok If a an error occurs, *ok is set to false; otherwise it's set to true
     * @return the unserialize color, or an empty color object if the function failed
     *         to unserialize the color
     */
243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260
    static KoColor fromXML(const QDomElement& elt, const QString & channelDepthId, bool* ok);


    /**
     * @brief toXML creates a string with XML that represents the current color. The XML
     * is extended with a "channeldepth" attribute so we can restore the color to the same
     * channel depth.
     * @return a valid XML document in a string
     */
    QString toXML() const;

    /**
     * @brief fromXML restores a KoColor from a string saved with toXML(). If the
     * string does not contain the "channeldepth" attribute, 16 bit integer is assumed.
     * @param xml a valid XML document
     * @return a new KoColor object
     */
    static KoColor fromXML(const QString &xml);
261

262 263 264 265 266
    /**
     * @brief toQString create a user-visible string of the channel names and the channel values
     * @param color the color to create the string from
     * @return a string that can be used to display the values of this color to the user.
     */
267 268
    static QString toQString(const KoColor &color);

Thomas Zander's avatar
Thomas Zander committed
269
#ifndef NODEBUG
270
    /// use qDebug calls to print internal info
271
    void dump() const;
Thomas Zander's avatar
Thomas Zander committed
272
#endif
273

274
private:
275 276 277 278 279 280 281 282 283 284 285
    inline void assertPermanentColorspace() {
#ifndef NODEBUG
        if (m_colorSpace) {
            Q_ASSERT(*m_colorSpace == *KoColorSpaceRegistry::instance()->permanentColorspace(m_colorSpace));
        }
#endif
    }

    const KoColorSpace *m_colorSpace;
    quint8 m_data[MAX_PIXEL_SIZE];
    quint8 m_size;
286 287
};

288
Q_DECLARE_METATYPE(KoColor)
289

290 291 292
KRITAPIGMENT_EXPORT QDebug operator<<(QDebug dbg, const KoColor &color);


293
#endif