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 #include "ManagedColor.h"
0008 #include <KoColor.h>
0009 #include <KoColorSpaceRegistry.h>
0010 #include <KoColorProfile.h>
0011 #include <KoColorModelStandardIds.h>
0012 #include <KoChannelInfo.h>
0013 
0014 #include <QDomDocument>
0015 #include <QDomElement>
0016 
0017 #include <Canvas.h>
0018 
0019 #include <kis_display_color_converter.h>
0020 #include <KoColorDisplayRendererInterface.h>
0021 
0022 struct ManagedColor::Private {
0023     KoColor color;
0024 };
0025 
0026 ManagedColor::ManagedColor(QObject *parent)
0027     : QObject(parent)
0028     , d(new Private())
0029 {
0030     // Default black rgb color
0031 }
0032 
0033 ManagedColor::ManagedColor(const QString &colorModel, const QString &colorDepth, const QString &colorProfile, QObject *parent)
0034     : QObject(parent)
0035     , d(new Private())
0036 {
0037     const KoColorSpace *colorSpace = KoColorSpaceRegistry::instance()->colorSpace(colorModel, colorDepth, colorProfile);
0038     if (colorSpace) {
0039         d->color = KoColor(colorSpace);
0040     }
0041 }
0042 
0043 
0044 ManagedColor::ManagedColor(KoColor color, QObject *parent)
0045     : QObject(parent)
0046     , d(new Private())
0047 {
0048     d->color = color;
0049 }
0050 
0051 ManagedColor::~ManagedColor()
0052 {
0053 }
0054 
0055 bool ManagedColor::operator==(const ManagedColor &other) const
0056 {
0057     return d->color == other.d->color;
0058 }
0059 
0060 QColor ManagedColor::colorForCanvas(Canvas *canvas) const
0061 {
0062     QColor c = QColor(0,0,0);
0063     if (canvas && canvas->displayColorConverter() && canvas->displayColorConverter()->displayRendererInterface()) {
0064         KoColorDisplayRendererInterface *converter = canvas->displayColorConverter()->displayRendererInterface();
0065         if (converter) {
0066             c = converter->toQColor(d->color);
0067         } else {
0068             c = KoDumbColorDisplayRenderer::instance()->toQColor(d->color);
0069         }
0070     } else {
0071         c = KoDumbColorDisplayRenderer::instance()->toQColor(d->color);
0072     }
0073     return c;
0074 }
0075 
0076 ManagedColor *ManagedColor::fromQColor(const QColor &qcolor, Canvas *canvas)
0077 {
0078     KoColor c;
0079     if (canvas && canvas->displayColorConverter() && canvas->displayColorConverter()->displayRendererInterface()) {
0080         KoColorDisplayRendererInterface *converter = canvas->displayColorConverter()->displayRendererInterface();
0081         if (converter) {
0082             c = converter->approximateFromRenderedQColor(qcolor);
0083         } else {
0084             c = KoDumbColorDisplayRenderer::instance()->approximateFromRenderedQColor(qcolor);
0085         }
0086     } else {
0087         c = KoDumbColorDisplayRenderer::instance()->approximateFromRenderedQColor(qcolor);
0088     }
0089     return new ManagedColor(c);
0090 }
0091 
0092 QString ManagedColor::colorDepth() const
0093 {
0094     return d->color.colorSpace()->colorDepthId().id();
0095 }
0096 
0097 QString ManagedColor::colorModel() const
0098 {
0099     return d->color.colorSpace()->colorModelId().id();
0100 }
0101 
0102 QString ManagedColor::colorProfile() const
0103 {
0104     return d->color.colorSpace()->profile()->name();
0105 }
0106 
0107 bool ManagedColor::setColorProfile(const QString &colorProfile)
0108 {
0109     const KoColorProfile *profile = KoColorSpaceRegistry::instance()->profileByName(colorProfile);
0110     if (!profile) return false;
0111     d->color.setProfile(profile);
0112     return true;
0113 }
0114 
0115 bool ManagedColor::setColorSpace(const QString &colorModel, const QString &colorDepth, const QString &colorProfile)
0116 {
0117     const KoColorSpace *colorSpace = KoColorSpaceRegistry::instance()->colorSpace(colorModel, colorDepth, colorProfile);
0118     if (!colorSpace) return false;
0119     d->color.convertTo(colorSpace);
0120     return true;
0121 }
0122 
0123 QVector<float> ManagedColor::components() const
0124 {
0125     QVector<float> values(d->color.colorSpace()->channelCount());
0126     d->color.colorSpace()->normalisedChannelsValue(d->color.data(), values);
0127     return values;
0128 }
0129 
0130 QVector<float> ManagedColor::componentsOrdered() const
0131 {
0132     QVector<float> valuesUnsorted = components();
0133     QVector<float> values(d->color.colorSpace()->channelCount());
0134     for (int i=0; i<values.size();i++) {
0135         int location = KoChannelInfo::displayPositionToChannelIndex(i, d->color.colorSpace()->channels());
0136         values[location] = valuesUnsorted[i];
0137     }
0138     return values;
0139 }
0140 
0141 void ManagedColor::setComponents(const QVector<float> &values)
0142 {
0143     d->color.colorSpace()->fromNormalisedChannelsValue(d->color.data(), values);
0144 }
0145 
0146 QString ManagedColor::toXML() const
0147 {
0148     QDomDocument doc;
0149     QDomElement root = doc.createElement("Color");
0150     root.setAttribute("bitdepth", colorDepth());
0151     doc.appendChild(root);
0152     d->color.toXML(doc, root);
0153     return doc.toString();
0154 }
0155 
0156 void ManagedColor::fromXML(const QString &xml)
0157 {
0158     QDomDocument doc;
0159     doc.setContent(xml);
0160     QDomElement e = doc.documentElement();
0161     QDomElement c = e.firstChildElement("Color");
0162     KoColor kc;
0163     if (!c.isNull()) {
0164         QString colorDepthId = c.attribute("bitdepth", Integer8BitsColorDepthID.id());
0165         d->color = KoColor::fromXML(c, colorDepthId);
0166     }
0167 
0168 }
0169 
0170 QString ManagedColor::toQString()
0171 {
0172     return KoColor::toQString(d->color);
0173 }
0174 
0175 KoColor ManagedColor::color() const
0176 {
0177     return d->color;
0178 }