Krita Source Code Documentation
Loading...
Searching...
No Matches
KoColor Class Reference

#include <KoColor.h>

+ Inheritance diagram for KoColor:

Public Member Functions

void add (const KoColor &value)
 
KoColor added (const KoColor &value) const
 
void addMetadata (QString key, QVariant value)
 
void clearMetadata ()
 clearMetadata clear th metadata map inside the KoColor.
 
const KoColorSpacecolorSpace () const
 return the current colorSpace
 
KoColor convertedTo (const KoColorSpace *cs) const
 
KoColor convertedTo (const KoColorSpace *cs, KoColorConversionTransformation::Intent renderingIntent, KoColorConversionTransformation::ConversionFlags conversionFlags) const
 
void convertTo (const KoColorSpace *cs)
 
void convertTo (const KoColorSpace *cs, KoColorConversionTransformation::Intent renderingIntent, KoColorConversionTransformation::ConversionFlags conversionFlags)
 
quint8 * data ()
 
const quint8 * data () const
 
void dump () const
 use qDebug calls to print internal info
 
void fromKoColor (const KoColor &src)
 
void fromQColor (const QColor &c)
 Convenient function for converting from a QColor.
 
 KoColor ()
 Create an empty KoColor. It will be valid, but also black and transparent.
 
 KoColor (const KoColor &rhs)
 Copy constructor – deep copies the colors.
 
 KoColor (const KoColor &src, const KoColorSpace *colorSpace)
 Create a KoColor by converting src into another colorspace.
 
 KoColor (const KoColorSpace *colorSpace)
 Create a null KoColor. It will be valid, but all channels will be set to 0.
 
 KoColor (const QColor &color, const KoColorSpace *colorSpace)
 
 KoColor (const quint8 *data, const KoColorSpace *colorSpace)
 Create a KoColor using a native color strategy. The data is copied.
 
QMap< QString, QVariant > metadata () const
 
qreal opacityF () const
 
quint8 opacityU8 () const
 
KoColoroperator= (const KoColor &rhs)
 
bool operator== (const KoColor &other) const
 
const KoColorProfileprofile () const
 return the current profile
 
void setColor (const quint8 *data, const KoColorSpace *colorSpace=0)
 
void setOpacity (qreal alpha)
 
void setOpacity (quint8 alpha)
 
void setProfile (const KoColorProfile *profile)
 assign new profile without converting pixel data
 
void subtract (const KoColor &value)
 
KoColor subtracted (const KoColor &value) const
 
QColor toQColor () const
 a convenience method for the above.
 
void toQColor (QColor *c) const
 a convenience method for the above.
 
QString toSVG11 (QHash< QString, const KoColorProfile * > *profileList) const
 toSVG11
 
QString toXML () const
 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.
 
void toXML (QDomDocument &doc, QDomElement &colorElt) const
 

Static Public Member Functions

static KoColor createTransparent (const KoColorSpace *cs)
 
static KoColor fromSVG11 (const QString value, QHash< QString, const KoColorProfile * > profileList, KoColor current=KoColor())
 fromSVG11 Parses a color attribute value and returns a KoColor. SVG defines the colorprofiles elsewhere in the file, so this function expects you to first figure out the profiles and which colorspaces these match to, and it will then use those colorspaces to generate the kocolor. If it cannot find the appropriate colorspace, it will return the color fallback. If that doesn't work, an empty KoColor. This function ignores url() values. Colors will be F32 unless they are lab and cmyk, in which case they'll be U16.
 
static KoColor fromXML (const QDomElement &elt, const QString &channelDepthId)
 
static KoColor fromXML (const QDomElement &elt, const QString &channelDepthId, bool *ok)
 
static KoColor fromXML (const QString &xml)
 fromXML restores a KoColor from a string saved with toXML(). If the string does not contain the "channeldepth" attribute, 16 bit integer is assumed.
 
static QString toQString (const KoColor &color)
 toQString create a user-visible string of the channel names and the channel values
 

Private Member Functions

void assertPermanentColorspace ()
 

Private Attributes

const KoColorSpacem_colorSpace
 
quint8 m_data [MAX_PIXEL_SIZE]
 
QMap< QString, QVariant > m_metadata
 
quint8 m_size
 

Detailed Description

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.

Definition at line 30 of file KoColor.h.

Constructor & Destructor Documentation

◆ KoColor() [1/6]

KoColor::KoColor ( )

Create an empty KoColor. It will be valid, but also black and transparent.

Definition at line 75 of file KoColor.cpp.

76 : m_colorSpace(s_defaultKoColor->value->m_colorSpace)
77 , m_size(s_defaultKoColor->value->m_size)
78{
79 memcpy(m_data, s_defaultKoColor->value->m_data, m_size);
80}
quint8 m_size
Definition KoColor.h:322
const KoColorSpace * m_colorSpace
Definition KoColor.h:320
quint8 m_data[MAX_PIXEL_SIZE]
Definition KoColor.h:321

References m_data, and m_size.

◆ KoColor() [2/6]

KoColor::KoColor ( const KoColorSpace * colorSpace)
explicit

Create a null KoColor. It will be valid, but all channels will be set to 0.

Definition at line 82 of file KoColor.cpp.

83{
84 Q_ASSERT(colorSpace);
87 Q_ASSERT(m_size <= MAX_PIXEL_SIZE);
88 memset(m_data, 0, m_size);
89}
const int MAX_PIXEL_SIZE
virtual quint32 pixelSize() const =0
const KoColorSpace * colorSpace() const
return the current colorSpace
Definition KoColor.h:82
const KoColorSpace * permanentColorspace(const KoColorSpace *_colorSpace)
static KoColorSpaceRegistry * instance()

References colorSpace(), KoColorSpaceRegistry::instance(), m_colorSpace, m_data, m_size, MAX_PIXEL_SIZE, KoColorSpaceRegistry::permanentColorspace(), and KoColorSpace::pixelSize().

◆ KoColor() [3/6]

KoColor::KoColor ( const QColor & color,
const KoColorSpace * colorSpace )

Create a KoColor from a QColor. The QColor is immediately converted to native. The QColor is assumed to have the current monitor profile.

Definition at line 91 of file KoColor.cpp.

92{
93 Q_ASSERT(color.isValid());
94 Q_ASSERT(colorSpace);
96
98 Q_ASSERT(m_size <= MAX_PIXEL_SIZE);
99 memset(m_data, 0, m_size);
100
102}
virtual void fromQColor(const QColor &color, quint8 *dst) const =0

References colorSpace(), KoColorSpace::fromQColor(), KoColorSpaceRegistry::instance(), m_colorSpace, m_data, m_size, MAX_PIXEL_SIZE, KoColorSpaceRegistry::permanentColorspace(), and KoColorSpace::pixelSize().

◆ KoColor() [4/6]

KoColor::KoColor ( const quint8 * data,
const KoColorSpace * colorSpace )

Create a KoColor using a native color strategy. The data is copied.

Definition at line 104 of file KoColor.cpp.

105{
106 Q_ASSERT(colorSpace);
107 Q_ASSERT(data);
110 Q_ASSERT(m_size <= MAX_PIXEL_SIZE);
111 memmove(m_data, data, m_size);
112}
quint8 * data()
Definition KoColor.h:144

References colorSpace(), data(), KoColorSpaceRegistry::instance(), m_colorSpace, m_data, m_size, MAX_PIXEL_SIZE, KoColorSpaceRegistry::permanentColorspace(), and KoColorSpace::pixelSize().

◆ KoColor() [5/6]

◆ KoColor() [6/6]

KoColor::KoColor ( const KoColor & rhs)
inline

Copy constructor – deep copies the colors.

Definition at line 51 of file KoColor.h.

53 , m_size(rhs.m_size)
55 {
56 memcpy(m_data, rhs.m_data, m_size);
57 }
QMap< QString, QVariant > m_metadata
Definition KoColor.h:323

References m_data.

Member Function Documentation

◆ add()

void KoColor::add ( const KoColor & value)

Channelwise adds value to *this and stores the result in *this

Throws a safe assert if the colorspaces of the two colors are different

Definition at line 244 of file KoColor.cpp.

245{
247
250
252 m_colorSpace->normalisedChannelsValue(value.data(), channels2);
253
254 for (int i = 0; i < channels1.size(); i++) {
255 channels1[i] += channels2[i];
256 }
257
259}
float value(const T *src, size_t ch)
virtual quint32 channelCount() const =0
virtual void normalisedChannelsValue(const quint8 *pixel, QVector< float > &channels) const =0
virtual void fromNormalisedChannelsValue(quint8 *pixel, const QVector< float > &values) const =0
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:128

References KoColorSpace::channelCount(), KoColorSpace::fromNormalisedChannelsValue(), KIS_SAFE_ASSERT_RECOVER_RETURN, m_colorSpace, m_data, KoColorSpace::normalisedChannelsValue(), and value().

◆ added()

KoColor KoColor::added ( const KoColor & value) const

Channelwise adds value to a copy of *this and returns the result

Throws a safe assert if the colorspaces of the two colors are different

Definition at line 261 of file KoColor.cpp.

262{
263 KoColor result(*this);
264 result.add(value);
265 return result;
266}

References add(), and value().

◆ addMetadata()

void KoColor::addMetadata ( QString key,
QVariant value )

store the given key, value pair in a KoColor.

Definition at line 666 of file KoColor.cpp.

667{
668 m_metadata.insert(key, value);
669}

References m_metadata, and value().

◆ assertPermanentColorspace()

void KoColor::assertPermanentColorspace ( )
inlineprivate

Definition at line 312 of file KoColor.h.

312 {
313#ifndef NODEBUG
314 if (m_colorSpace) {
315 Q_ASSERT(*m_colorSpace == *KoColorSpaceRegistry::instance()->permanentColorspace(m_colorSpace));
316 }
317#endif
318 }

References KoColorSpaceRegistry::instance().

◆ clearMetadata()

void KoColor::clearMetadata ( )

clearMetadata clear th metadata map inside the KoColor.

Definition at line 676 of file KoColor.cpp.

677{
678 m_metadata.clear();
679}

References m_metadata.

◆ colorSpace()

const KoColorSpace * KoColor::colorSpace ( ) const
inline

return the current colorSpace

Definition at line 82 of file KoColor.h.

82 {
83 return m_colorSpace;
84 }

◆ convertedTo() [1/2]

KoColor KoColor::convertedTo ( const KoColorSpace * cs) 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

Definition at line 170 of file KoColor.cpp.

171{
172 return convertedTo(cs,
175}
KoColor convertedTo(const KoColorSpace *cs, KoColorConversionTransformation::Intent renderingIntent, KoColorConversionTransformation::ConversionFlags conversionFlags) const
Definition KoColor.cpp:163

References convertedTo(), KoColorConversionTransformation::internalConversionFlags(), and KoColorConversionTransformation::internalRenderingIntent().

◆ convertedTo() [2/2]

KoColor 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

Definition at line 163 of file KoColor.cpp.

164{
165 KoColor result(*this);
166 result.convertTo(cs, renderingIntent, conversionFlags);
167 return result;
168}

References convertTo().

◆ convertTo() [1/2]

void KoColor::convertTo ( const KoColorSpace * cs)

Definition at line 156 of file KoColor.cpp.

157{
158 convertTo(cs,
161}
void convertTo(const KoColorSpace *cs, KoColorConversionTransformation::Intent renderingIntent, KoColorConversionTransformation::ConversionFlags conversionFlags)
Definition KoColor.cpp:136

References convertTo(), KoColorConversionTransformation::internalConversionFlags(), and KoColorConversionTransformation::internalRenderingIntent().

◆ convertTo() [2/2]

void KoColor::convertTo ( const KoColorSpace * cs,
KoColorConversionTransformation::Intent renderingIntent,
KoColorConversionTransformation::ConversionFlags conversionFlags )

Convert this KoColor to the specified colorspace. If the specified colorspace is the same as the original colorspace, do nothing

Definition at line 136 of file KoColor.cpp.

137{
138 //dbgPigment <<"Our colormodel:" << d->colorSpace->id().name()
139 // << ", new colormodel: " << cs->id().name() << "\n";
140
141 if (*m_colorSpace == *cs)
142 return;
143
144 quint8 data[MAX_PIXEL_SIZE];
145 const size_t size = cs->pixelSize();
146 Q_ASSERT(size <= MAX_PIXEL_SIZE);
147 memset(data, 0, size);
148
149 m_colorSpace->convertPixelsTo(m_data, data, cs, 1, renderingIntent, conversionFlags);
150
151 memcpy(m_data, data, size);
152 m_size = size;
154}
virtual bool convertPixelsTo(const quint8 *src, quint8 *dst, const KoColorSpace *dstColorSpace, quint32 numPixels, KoColorConversionTransformation::Intent renderingIntent, KoColorConversionTransformation::ConversionFlags conversionFlags) const
int size(const Forest< T > &forest)
Definition KisForest.h:1232

References KoColorSpace::convertPixelsTo(), data(), KoColorSpaceRegistry::instance(), m_colorSpace, m_data, m_size, MAX_PIXEL_SIZE, KoColorSpaceRegistry::permanentColorspace(), and KoColorSpace::pixelSize().

◆ createTransparent()

KoColor KoColor::createTransparent ( const KoColorSpace * cs)
static

Not all color spaces support creation of a color from QColor, so we should create the default backdrop color explicitly.

See also
KoColorSpace::transparentColor

Definition at line 681 of file KoColor.cpp.

682{
683 KoColor result;
684
686 result.m_size = cs->pixelSize();
687 cs->transparentColor(result.m_data, 1);
688
689 return result;
690}
virtual void transparentColor(quint8 *dst, quint32 nPixels) const

References KoColorSpaceRegistry::instance(), m_colorSpace, m_data, m_size, KoColorSpaceRegistry::permanentColorspace(), KoColorSpace::pixelSize(), and KoColorSpace::transparentColor().

◆ data() [1/2]

quint8 * KoColor::data ( )
inline
Returns
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

Definition at line 144 of file KoColor.h.

144 {
145 return m_data;
146 }

◆ data() [2/2]

const quint8 * KoColor::data ( ) const
inline
Returns
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

Definition at line 153 of file KoColor.h.

153 {
154 return m_data;
155 }

◆ dump()

void KoColor::dump ( ) const

use qDebug calls to print internal info

Definition at line 269 of file KoColor.cpp.

270{
271 dbgPigment <<"KoColor (" << this <<")," << m_colorSpace->id() <<"";
273
274 QList<KoChannelInfo *>::const_iterator begin = channels.constBegin();
275 QList<KoChannelInfo *>::const_iterator end = channels.constEnd();
276
277 for (QList<KoChannelInfo *>::const_iterator it = begin; it != end; ++it) {
278 KoChannelInfo * ch = (*it);
279 // XXX: setNum always takes a byte.
280 if (ch->size() == sizeof(quint8)) {
281 // Byte
282 dbgPigment <<"Channel (byte):" << ch->name() <<":" << QString().setNum(m_data[ch->pos()]) <<"";
283 } else if (ch->size() == sizeof(quint16)) {
284 // Short (may also by an nvidia half)
285 dbgPigment <<"Channel (short):" << ch->name() <<":" << QString().setNum(*((const quint16 *)(m_data+ch->pos()))) <<"";
286 } else if (ch->size() == sizeof(quint32)) {
287 // Integer (may also be float... Find out how to distinguish these!)
288 dbgPigment <<"Channel (int):" << ch->name() <<":" << QString().setNum(*((const quint32 *)(m_data+ch->pos()))) <<"";
289 }
290 }
291}
#define dbgPigment
qint32 size() const
qint32 pos() const
QString name() const
QList< KoChannelInfo * > channels

References KoColorSpace::channels, dbgPigment, KoColorSpace::id, m_colorSpace, m_data, KoChannelInfo::name(), KoChannelInfo::pos(), and KoChannelInfo::size().

◆ fromKoColor()

void KoColor::fromKoColor ( const KoColor & src)

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.

Definition at line 294 of file KoColor.cpp.

References colorSpace(), KoColorConversionTransformation::internalConversionFlags(), KoColorConversionTransformation::internalRenderingIntent(), and m_data.

◆ fromQColor()

void KoColor::fromQColor ( const QColor & c)

Convenient function for converting from a QColor.

Definition at line 213 of file KoColor.cpp.

214{
215 if (m_colorSpace) {
217 }
218}

References KoColorSpace::fromQColor(), m_colorSpace, and m_data.

◆ fromSVG11()

KoColor KoColor::fromSVG11 ( const QString value,
QHash< QString, const KoColorProfile * > profileList,
KoColor current = KoColor() )
static

fromSVG11 Parses a color attribute value and returns a KoColor. SVG defines the colorprofiles elsewhere in the file, so this function expects you to first figure out the profiles and which colorspaces these match to, and it will then use those colorspaces to generate the kocolor. If it cannot find the appropriate colorspace, it will return the color fallback. If that doesn't work, an empty KoColor. This function ignores url() values. Colors will be F32 unless they are lab and cmyk, in which case they'll be U16.

https://www.w3.org/TR/SVG11/types.html#DataTypeColor for hex, rgb() and colornames https://www.w3.org/TR/SVG11/types.html#DataTypeICCColor for icc-color() https://www.w3.org/TR/SVG11/painting.html#SpecifyingPaint

Parameters
valuethe content of the svg color value
profileListlist of KoColorProfiles that were found inside the svg file, with the reference names.
currentthe current color.
Returns
a KoColor as parsed from the value string.

Definition at line 534 of file KoColor.cpp.

535{
536 KoColor parsed(KoColorSpaceRegistry::instance()->rgb16(KoColorSpaceRegistry::instance()->p709SRGBProfile()));
537 parsed.setOpacity(1.0);
538
539 if (value.toLower() == "none") {
540 return parsed;
541 }
542
543 // add the sRGB default name.
544 profileList.insert("sRGB", KoColorSpaceRegistry::instance()->p709SRGBProfile());
545 // first, try to split at \w\d\‍) space.
546 // we want to split up a string like... colorcolor none rgb(0.8, 0.1, 200%) #ff0000 icc-color(blah, 0.0, 1.0, 1.0, 0.0);
547 QRegExp splitDefinitions("(#?\\w+|[\\w\\-]*\\(.+\\))\\s");
548 int pos = 0;
549 int pos2 = 0;
550 QStringList colorDefinitions;
551 QString valueAdjust = value.split(";").first();
552 valueAdjust.append(" ");
553 while ((pos2 = splitDefinitions.indexIn(valueAdjust, pos)) != -1) {
554 colorDefinitions.append(splitDefinitions.cap(1).trimmed());
555 pos = pos2 + splitDefinitions.matchedLength();
556 }
557 if (pos < value.length()) {
558 QString remainder = value.right(value.length()-pos);
559 remainder.remove(";");
560 colorDefinitions.append(remainder);
561 }
562 dbgPigment << "Color definitions found during svg11parsing" << colorDefinitions;
563
564 for (QString def : colorDefinitions) {
565 if (def.toLower() == "currentcolor") {
566 parsed = current;
567 } else if (QColor::isValidColor(def)) {
568 parsed.fromQColor(QColor(def));
569 } else if (def.toLower().startsWith("rgb")) {
570 QString parse = def.trimmed();
571 QStringList colors = parse.split(',');
572 QString r = colors[0].right((colors[0].length() - 4)).trimmed();
573 QString g = colors[1].trimmed();
574 QString b = colors[2].left((colors[2].length() - 1)).trimmed();
575
576 if (r.contains('%')) {
577 r = r.left(r.length() - 1);
578 r = QString::number(int((double(255 * r.toDouble()) / 100.0)));
579 }
580
581 if (g.contains('%')) {
582 g = g.left(g.length() - 1);
583 g = QString::number(int((double(255 * g.toDouble()) / 100.0)));
584 }
585
586 if (b.contains('%')) {
587 b = b.left(b.length() - 1);
588 b = QString::number(int((double(255 * b.toDouble()) / 100.0)));
589 }
590 parsed.fromQColor(QColor(r.toInt(), g.toInt(), b.toInt()));
591
592 } else if (def.toLower().startsWith("icc-color")) {
593 QStringList values = def.split(",");
594 QString iccprofilename = values.first().split("(").last();
595 values.removeFirst();
596
597 // svg11 docs say that searching the name should be case-insensitive.
598 QStringList entry = QStringList(profileList.keys()).filter(iccprofilename, Qt::CaseInsensitive);
599 if (entry.empty()) {
600 continue;
601 }
602 const KoColorProfile *profile = profileList.value(entry.first());
603 if (!profile) {
604 continue;
605 }
606 QString colormodel = profile->colorModelID();
607 QString depth = "F32";
608 if (colormodel == LABAColorModelID.id()) {
609 // let our xml handling deal with lab
610 QVector<float> labV(3);
611 for (int i = 0; i < values.size(); i++) {
612 if (i<labV.size()) {
613 QString entry = values.at(i);
614 entry = entry.split(")").first();
615 labV[i] = entry.toDouble();
616 }
617 }
618 QString lab = QString("<Lab space='%1' L='%2' a='%3' b='%4' />")
619 .arg(profile->name())
620 .arg(labV[0])
621 .arg(labV[1])
622 .arg(labV[2]);
623 QDomDocument doc;
624 doc.setContent(lab);
625 parsed = KoColor::fromXML(doc.documentElement(), "U16");
626 continue;
627 } else if (colormodel == CMYKAColorModelID.id()) {
628 depth = "U16";
629 } else if (colormodel == XYZAColorModelID.id()) {
630 // Inkscape decided to have X and Z go from 0 to 2, and I can't for the live of me figure out why.
631 // So we're just not parsing XYZ.
632 continue;
633 }
634 const KoColorSpace * cs = KoColorSpaceRegistry::instance()->colorSpace(colormodel, depth, profile);
635 if (!cs) {
636 continue;
637 }
638 parsed = KoColor(cs);
639 QVector<float> channelValues(parsed.colorSpace()->channelCount());
640 channelValues.fill(0.0);
641 channelValues[parsed.colorSpace()->alphaPos()] = 1.0;
642 for (int channel = 0; channel < values.size(); channel++) {
643 int location = KoChannelInfo::displayPositionToChannelIndex(channel, parsed.colorSpace()->channels());
644 QString entry = values.at(channel);
645 entry = entry.split(")").first();
646 channelValues[location] = entry.toFloat();
647 }
648 parsed.colorSpace()->fromNormalisedChannelsValue(parsed.data(), channelValues);
649 }
650 }
651
652 return parsed;
653}
qreal length(const QPointF &vec)
Definition Ellipse.cc:82
QList< QString > QStringList
const KoID XYZAColorModelID("XYZA", ki18n("XYZ/Alpha"))
const KoID CMYKAColorModelID("CMYKA", ki18n("CMYK/Alpha"))
const KoID LABAColorModelID("LABA", ki18n("L*a*b*/Alpha"))
static int displayPositionToChannelIndex(int displayPosition, const QList< KoChannelInfo * > &channels)
static KoColor fromXML(const QDomElement &elt, const QString &channelDepthId)
Definition KoColor.cpp:350
const KoColorProfile * profile() const
return the current profile
Definition KoColor.cpp:299
void fromQColor(const QColor &c)
Convenient function for converting from a QColor.
Definition KoColor.cpp:213
KoColor()
Create an empty KoColor. It will be valid, but also black and transparent.
Definition KoColor.cpp:75
QString id() const
Definition KoID.cpp:63
int depth(typename Forest< T >::const_child_iterator beginIt, typename Forest< T >::const_child_iterator endIt)
Definition KisForest.h:1213
virtual QString colorModelID() const
const KoColorSpace * colorSpace(const QString &colorModelId, const QString &colorDepthId, const KoColorProfile *profile)

References KoColorSpace::alphaPos(), KoColorSpace::channelCount(), KoColorSpace::channels, CMYKAColorModelID, KoColorProfile::colorModelID(), colorSpace(), KoColorSpaceRegistry::colorSpace(), data(), dbgPigment, KoChannelInfo::displayPositionToChannelIndex(), KoColorSpace::fromNormalisedChannelsValue(), fromQColor(), fromXML(), KoID::id(), KoColorSpaceRegistry::instance(), KoColor(), LABAColorModelID, length(), KoColorProfile::name, profile(), setOpacity(), value(), and XYZAColorModelID.

◆ fromXML() [1/3]

KoColor KoColor::fromXML ( const QDomElement & elt,
const QString & channelDepthId )
static

Unserialize a color following Create's swatch color specification available at https://web.archive.org/web/20110826002520/http://create.freedesktop.org/wiki/Swatches_-_color_file_format/Draft

Parameters
eltthe element to unserialize (<CMYK />, <sRGB />, <RGB />)
channelDepthIdthe bit depth is unspecified by the spec, this allow to select a preferred bit depth for creating the KoColor object (if that bit depth isn't available, this function will randomly select another bit depth)
Returns
the unserialize color, or an empty color object if the function failed to unserialize the color

Definition at line 350 of file KoColor.cpp.

351{
352 bool ok;
353 return fromXML(elt, channelDepthId, &ok);
354}

References fromXML().

◆ fromXML() [2/3]

KoColor KoColor::fromXML ( const QDomElement & elt,
const QString & channelDepthId,
bool * ok )
static

Unserialize a color following Create's swatch color specification available at https://web.archive.org/web/20110826002520/http://create.freedesktop.org/wiki/Swatches_-_color_file_format/Draft

Parameters
eltthe element to unserialize (<CMYK />, <sRGB />, <RGB />)
channelDepthIdthe bit depth is unspecified by the spec, this allow to select a preferred bit depth for creating the KoColor object (if that bit depth isn't available, this function will randomly select another bit depth)
okIf a an error occurs, *ok is set to false; otherwise it's set to true
Returns
the unserialize color, or an empty color object if the function failed to unserialize the color

Definition at line 356 of file KoColor.cpp.

357{
358 *ok = true;
359
360 QString modelId;
361 QString modelName = elt.tagName();
362 if (modelName == "CMYK") {
363 modelId = CMYKAColorModelID.id();
364 } else if (modelName == "RGB") {
365 modelId = RGBAColorModelID.id();
366 } else if (modelName == "sRGB") {
367 modelId = RGBAColorModelID.id();
368 } else if (modelName == "Lab") {
369 modelId = LABAColorModelID.id();
370 } else if (modelName == "XYZ") {
371 modelId = XYZAColorModelID.id();
372 } else if (modelName == "Gray") {
373 modelId = GrayAColorModelID.id();
374 } else if (modelName == "YCbCr") {
375 modelId = YCbCrAColorModelID.id();
376 }
377
379
380 QString profileName;
381 if (modelName == "sRGB") {
382 const KoColorProfile *profile = colorSpaceRegistry->p709SRGBProfile();
383 if (profile) {
384 profileName = profile->name();
385 }
386 } else {
387 profileName = elt.attribute("space", "");
388 if (!colorSpaceRegistry->profileByName(profileName)) {
389 profileName.clear();
390 }
391 }
392
393 const KoColorSpace* cs = colorSpaceRegistry->colorSpace(modelId, channelDepthId, profileName);
394 if (!cs) {
395 QList<KoID> list = colorSpaceRegistry->colorDepthList(modelId, KoColorSpaceRegistry::AllColorSpaces);
396 if (!list.empty()) {
397 cs = colorSpaceRegistry->colorSpace(modelId, list[0].id(), profileName);
398 }
399 }
400
401 if (!cs) {
402 *ok = false;
403 return KoColor();
404 }
405
406 KoColor c(cs);
407 // TODO: Provide a way for colorFromXML() to notify the caller if parsing failed.
408 // Currently it returns default values on failure.
409 cs->colorFromXML(c.data(), elt);
410
411 QDomElement e = elt.nextSiblingElement("metadata");
412 for (; !e.isNull(); e = e.nextSiblingElement("metadata")) {
413 const QString name = e.attribute("name");
414 const QString type = e.attribute("type");
415 const QString value = e.attribute("value");
416
417 QVariant v;
418 if (type == "string") {
420 } else if (type == "int") {
422 } else if (type == "double") {
424 } else if (type == "bool") {
426 } else {
427 continue;
428 }
429
430 c.addMetadata(name , v);
431 }
432
433 return c;
434}
qreal v
const KoID YCbCrAColorModelID("YCbCrA", ki18n("YCbCr/Alpha"))
const KoID GrayAColorModelID("GRAYA", ki18n("Grayscale/Alpha"))
const KoID RGBAColorModelID("RGBA", ki18n("RGB/Alpha"))
virtual void colorFromXML(quint8 *pixel, const QDomElement &elt) const =0
const char * name(StandardAction id)
double toDouble(const QString &str, bool *ok=nullptr)
int toInt(const QString &str, bool *ok=nullptr)
QString toString(const QString &value)
const KoColorProfile * profileByName(const QString &name) const
QList< KoID > colorDepthList(const KoID &colorModelId, ColorSpaceListVisibility option) const
const KoColorProfile * p709SRGBProfile() const
@ AllColorSpaces
All color space even those not visible to the user.

References addMetadata(), KoColorSpaceRegistry::AllColorSpaces, CMYKAColorModelID, KoColorSpaceRegistry::colorDepthList(), KoColorSpace::colorFromXML(), KoColorSpaceRegistry::colorSpace(), data(), GrayAColorModelID, KoID::id(), KoColorSpaceRegistry::instance(), KoColor(), LABAColorModelID, KoColorProfile::name, KoColorSpaceRegistry::p709SRGBProfile(), profile(), KoColorSpaceRegistry::profileByName(), RGBAColorModelID, KisDomUtils::toDouble(), KisDomUtils::toInt(), KisDomUtils::toString(), v, value(), XYZAColorModelID, and YCbCrAColorModelID.

◆ fromXML() [3/3]

KoColor KoColor::fromXML ( const QString & xml)
static

fromXML restores a KoColor from a string saved with toXML(). If the string does not contain the "channeldepth" attribute, 16 bit integer is assumed.

Parameters
xmla valid XML document
Returns
a new KoColor object

Definition at line 446 of file KoColor.cpp.

447{
448 KoColor c;
449 QDomDocument doc;
450 if (!doc.setContent(xml)) {
451 return c;
452 }
453
454 QDomElement root = doc.documentElement();
455 QDomElement child = root.firstChildElement();
456 QString channelDepthID = root.attribute("channeldepth", Integer16BitsColorDepthID.id());
457
458 bool ok;
459 if (child.hasAttribute("space") || child.tagName().toLower() == "srgb") {
460 c = KoColor::fromXML(child, channelDepthID, &ok);
461 } else if (root.hasAttribute("space") || root.tagName().toLower() == "srgb"){
462 c = KoColor::fromXML(root, channelDepthID, &ok);
463 } else {
464 qWarning() << "Cannot parse color from xml" << xml;
465 }
466
467 return c;
468}
const KoID Integer16BitsColorDepthID("U16", ki18n("16-bit integer/channel"))

References fromXML(), KoID::id(), and Integer16BitsColorDepthID.

◆ metadata()

QMap< QString, QVariant > KoColor::metadata ( ) const

Get a map with all the metadata The metadata is used by parsing functions to store extra data, like for example spot color names, or the original parsing model.

Definition at line 671 of file KoColor.cpp.

672{
673 return m_metadata;
674}

References m_metadata.

◆ opacityF()

qreal KoColor::opacityF ( ) const

Definition at line 345 of file KoColor.cpp.

346{
348}
virtual qreal opacityF(const quint8 *pixel) const =0

References m_colorSpace, m_data, and KoColorSpace::opacityF().

◆ opacityU8()

quint8 KoColor::opacityU8 ( ) const

Convenient function that return the opacity of the color

Definition at line 341 of file KoColor.cpp.

342{
344}
virtual quint8 opacityU8(const quint8 *pixel) const =0

References m_colorSpace, m_data, and KoColorSpace::opacityU8().

◆ operator=()

KoColor & KoColor::operator= ( const KoColor & rhs)
inline

assignment operator to copy the data from the param color into this one.

Parameters
rhsthe color we are going to copy
Returns
this color

Definition at line 64 of file KoColor.h.

64 {
65 if (&rhs == this) {
66 return *this;
67 }
68
71 m_size = rhs.m_size;
72 memcpy(m_data, rhs.m_data, m_size);
73
75
76 return *this;
77 }
void assertPermanentColorspace()
Definition KoColor.h:312

References m_colorSpace, m_data, m_metadata, and m_size.

◆ operator==()

bool KoColor::operator== ( const KoColor & other) const

Definition at line 126 of file KoColor.cpp.

126 {
127 if (*colorSpace() != *other.colorSpace()) {
128 return false;
129 }
130 if (m_size != other.m_size) {
131 return false;
132 }
133 return memcmp(m_data, other.m_data, m_size) == 0;
134}

References colorSpace(), m_data, and m_size.

◆ profile()

const KoColorProfile * KoColor::profile ( ) const

return the current profile

Definition at line 299 of file KoColor.cpp.

300{
301 return m_colorSpace->profile();
302}
virtual const KoColorProfile * profile() const =0

References m_colorSpace, and KoColorSpace::profile().

◆ setColor()

void KoColor::setColor ( const quint8 * data,
const KoColorSpace * colorSpace = 0 )

Replace the existing color data, and colorspace with the specified data. The data is copied.

Definition at line 186 of file KoColor.cpp.

187{
188 Q_ASSERT(colorSpace);
189
191 Q_ASSERT(m_size <= MAX_PIXEL_SIZE);
192
193 memcpy(m_data, data, m_size);
195}

References colorSpace(), data(), KoColorSpaceRegistry::instance(), m_colorSpace, m_data, m_size, MAX_PIXEL_SIZE, KoColorSpaceRegistry::permanentColorspace(), and KoColorSpace::pixelSize().

◆ setOpacity() [1/2]

void KoColor::setOpacity ( qreal alpha)

Definition at line 337 of file KoColor.cpp.

338{
339 m_colorSpace->setOpacity(m_data, alpha, 1);
340}
virtual void setOpacity(quint8 *pixels, quint8 alpha, qint32 nPixels) const =0

References m_colorSpace, m_data, and KoColorSpace::setOpacity().

◆ setOpacity() [2/2]

void KoColor::setOpacity ( quint8 alpha)

Convenient function to set the opacity of the color.

Definition at line 333 of file KoColor.cpp.

334{
335 m_colorSpace->setOpacity(m_data, alpha, 1);
336}

References m_colorSpace, m_data, and KoColorSpace::setOpacity().

◆ setProfile()

void KoColor::setProfile ( const KoColorProfile * profile)

assign new profile without converting pixel data

Definition at line 177 of file KoColor.cpp.

178{
179 const KoColorSpace *dstColorSpace =
180 KoColorSpaceRegistry::instance()->colorSpace(colorSpace()->colorModelId().id(), colorSpace()->colorDepthId().id(), profile);
181 if (!dstColorSpace) return;
182
184}

References colorSpace(), KoColorSpaceRegistry::colorSpace(), KoColorSpaceRegistry::instance(), m_colorSpace, KoColorSpaceRegistry::permanentColorspace(), and profile().

◆ subtract()

void KoColor::subtract ( const KoColor & value)

Channelwise subtracts value from *this and stores the result in *this

Throws a safe assert if the colorspaces of the two colors are different

Definition at line 220 of file KoColor.cpp.

221{
223
226
228 m_colorSpace->normalisedChannelsValue(value.data(), channels2);
229
230 for (int i = 0; i < channels1.size(); i++) {
231 channels1[i] -= channels2[i];
232 }
233
235}

References KoColorSpace::channelCount(), KoColorSpace::fromNormalisedChannelsValue(), KIS_SAFE_ASSERT_RECOVER_RETURN, m_colorSpace, m_data, KoColorSpace::normalisedChannelsValue(), and value().

◆ subtracted()

KoColor KoColor::subtracted ( const KoColor & value) const

Channelwise subtracts value from a copy of *this and returns the result

Throws a safe assert if the colorspaces of the two colors are different

Definition at line 237 of file KoColor.cpp.

238{
239 KoColor result(*this);
240 result.subtract(value);
241 return result;
242}

References subtract(), and value().

◆ toQColor() [1/2]

QColor KoColor::toQColor ( ) const

a convenience method for the above.

Definition at line 206 of file KoColor.cpp.

207{
208 QColor c;
209 toQColor(&c);
210 return c;
211}
QColor toQColor() const
a convenience method for the above.
Definition KoColor.cpp:206

References toQColor().

◆ toQColor() [2/2]

void KoColor::toQColor ( QColor * c) const

a convenience method for the above.

Definition at line 198 of file KoColor.cpp.

199{
200 Q_ASSERT(c);
201 if (m_colorSpace) {
203 }
204}
virtual void toQColor(const quint8 *src, QColor *c) const =0

References m_colorSpace, m_data, and KoColorSpace::toQColor().

◆ toQString()

QString KoColor::toQString ( const KoColor & color)
static

toQString create a user-visible string of the channel names and the channel values

Parameters
colorthe color to create the string from
Returns
a string that can be used to display the values of this color to the user.

Definition at line 655 of file KoColor.cpp.

656{
657 QStringList ls;
658 Q_FOREACH (KoChannelInfo *channel, KoChannelInfo::displayOrderSorted(color.colorSpace()->channels())) {
660 ls << channel->name();
661 ls << color.colorSpace()->channelValueText(color.data(), realIndex);
662 }
663 return ls.join(" ");
664}
static QList< KoChannelInfo * > displayOrderSorted(const QList< KoChannelInfo * > &channels)
qint32 displayPosition() const
virtual QString channelValueText(const quint8 *pixel, quint32 channelIndex) const =0

References KoColorSpace::channels, KoColorSpace::channelValueText(), colorSpace(), data(), KoChannelInfo::displayOrderSorted(), KoChannelInfo::displayPosition(), KoChannelInfo::displayPositionToChannelIndex(), and KoChannelInfo::name().

◆ toSVG11()

QString KoColor::toSVG11 ( QHash< QString, const KoColorProfile * > * profileList) const

toSVG11

Parameters
profileListlist of profiles, this will map the profile to a name, so it may be embedded.
Returns
a color definition string with both a srgb hexcode fallback as well as a icc-color definition.

Definition at line 470 of file KoColor.cpp.

471{
472 QStringList colorDefinitions;
473 colorDefinitions.append(toQColor().name());
474
475 QVector<float> channelValues(colorSpace()->channelCount());
476 channelValues.fill(0.0);
477 colorSpace()->normalisedChannelsValue(data(), channelValues);
478
479 bool sRGB = false;
480 if (colorSpace() && colorSpace()->profile()
481 && colorSpace()->profile()->getColorPrimaries() == ColorPrimaries::PRIMARIES_ITU_R_BT_709_5
482 && colorSpace()->profile()->getTransferCharacteristics() != TransferCharacteristics::TRC_LINEAR) {
483 sRGB = true;
484 }
485
486 // We don't write a icc-color definition for XYZ and 8bit sRGB.
487 if (!(sRGB && colorSpace()->colorDepthId() == Integer8BitsColorDepthID) &&
488 colorSpace()->colorModelId() != XYZAColorModelID) {
489 QStringList iccColor;
490 QString csName = colorSpace()->profile()->name();
491 // remove forbidden characters
492 // https://www.w3.org/TR/SVG11/types.html#DataTypeName
493#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
494 csName.remove(QRegExp("[\\(\\),\\s]"));
495#else
496 QRegExp reg("[\\(\\),\\s]");
497 reg.removeIn(csName);
498#endif
499 //reuse existing name if possible. We're looking for the color profile, because svg doesn't care about depth.
500 csName = profileList->key(colorSpace()->profile(), csName);
501
502 if (sRGB) {
503 csName = "sRGB";
504 }
505
506 iccColor.append(csName);
507
508 if (colorSpace()->colorModelId() == LABAColorModelID) {
509 QDomDocument doc;
510 QDomElement el = doc.createElement("color");
511 toXML(doc, el);
512 QDomElement lab = el.firstChildElement();
513 iccColor.append(lab.attribute("L", "0.0"));
514 iccColor.append(lab.attribute("a", "0.0"));
515 iccColor.append(lab.attribute("b", "0.0"));
516 }
517 else {
518 for (int i = 0; i < channelValues.size(); i++) {
519 int location = KoChannelInfo::displayPositionToChannelIndex(i, colorSpace()->channels());
520 if (i != int(colorSpace()->alphaPos())) {
521 iccColor.append(QString::number(channelValues.at(location), 'g', 10));
522 }
523 }
524 }
525 colorDefinitions.append(QString("icc-color(%1)").arg(iccColor.join(", ")));
526 if (!profileList->contains(csName) && !sRGB) {
527 profileList->insert(csName, colorSpace()->profile());
528 }
529 }
530
531 return colorDefinitions.join(" ");
532}
const KoID Integer8BitsColorDepthID("U8", ki18n("8-bit integer/channel"))
@ PRIMARIES_ITU_R_BT_709_5
void toXML(QDomDocument &doc, QDomElement &colorElt) const
Definition KoColor.cpp:304

References colorSpace(), data(), KoChannelInfo::displayPositionToChannelIndex(), Integer8BitsColorDepthID, LABAColorModelID, KoColorProfile::name, KoColorSpace::normalisedChannelsValue(), PRIMARIES_ITU_R_BT_709_5, profile(), KoColorSpace::profile(), toQColor(), toXML(), TRC_LINEAR, and XYZAColorModelID.

◆ toXML() [1/2]

QString KoColor::toXML ( ) const

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.

Returns
a valid XML document in a string

Definition at line 436 of file KoColor.cpp.

437{
438 QDomDocument cdataDoc = QDomDocument("color");
439 QDomElement cdataRoot = cdataDoc.createElement("color");
440 cdataDoc.appendChild(cdataRoot);
441 cdataRoot.setAttribute("channeldepth", colorSpace()->colorDepthId().id());
442 toXML(cdataDoc, cdataRoot);
443 return cdataDoc.toString();
444}

References colorSpace(), and toXML().

◆ toXML() [2/2]

void KoColor::toXML ( QDomDocument & doc,
QDomElement & colorElt ) const

Serialize this color following Create's swatch color specification available at https://web.archive.org/web/20110826002520/http://create.freedesktop.org/wiki/Swatches_-_color_file_format/Draft

This function doesn't create the <color /> element but rather the <CMYK />, <sRGB />, <RGB /> ... elements. It is assumed that colorElt is the <color /> element.

Parameters
colorEltroot element for the serialization, it is assumed that this element is <color />
docis the document containing colorElt

Definition at line 304 of file KoColor.cpp.

305{
306 m_colorSpace->colorToXML(m_data, doc, colorElt);
307
308 for (QString key : m_metadata.keys()) {
309
310 QDomElement e = doc.createElement("metadata");
311 e.setAttribute("name", QString(key.toLatin1()));
312 QVariant v = m_metadata.value(key);
313 e.setAttribute("type", v.typeName());
314
315 QString attrName = "value";
316 if(v.type() == QVariant::String ) {
317 e.setAttribute(attrName, v.toString());
318 e.setAttribute("type", "string");
319 } else if(v.type() == QVariant::Int ) {
320 e.setAttribute(attrName, v.toInt());
321 } else if(v.type() == QVariant::Double ) {
322 e.setAttribute(attrName, v.toDouble());
323 } else if(v.type() == QVariant::Bool ) {
324 e.setAttribute(attrName, v.toBool());
325 } else {
326 qWarning() << "no KoColor serialization for QVariant type:" << v.type();
327 }
328 colorElt.appendChild(e);
329 }
330
331}
virtual void colorToXML(const quint8 *pixel, QDomDocument &doc, QDomElement &colorElt) const =0

References KoColorSpace::colorToXML(), m_colorSpace, m_data, m_metadata, and v.

Member Data Documentation

◆ m_colorSpace

const KoColorSpace* KoColor::m_colorSpace
private

Definition at line 320 of file KoColor.h.

◆ m_data

quint8 KoColor::m_data[MAX_PIXEL_SIZE]
private

Definition at line 321 of file KoColor.h.

◆ m_metadata

QMap<QString, QVariant> KoColor::m_metadata
private

Definition at line 323 of file KoColor.h.

◆ m_size

quint8 KoColor::m_size
private

Definition at line 322 of file KoColor.h.


The documentation for this class was generated from the following files: