File indexing completed on 2024-05-19 04:26:56

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     const QList<KoChannelInfo *> channelInfo = d->color.colorSpace()->channels();
0133     QVector<float> valuesUnsorted = components();
0134     QVector<float> values(channelInfo.size());
0135     for (int i=0; i<values.size();i++) {
0136         int location = KoChannelInfo::displayPositionToChannelIndex(i, channelInfo);
0137         values[location] = valuesUnsorted[i];
0138     }
0139     return values;
0140 }
0141 
0142 void ManagedColor::setComponents(const QVector<float> &values)
0143 {
0144     d->color.colorSpace()->fromNormalisedChannelsValue(d->color.data(), values);
0145 }
0146 
0147 QString ManagedColor::toXML() const
0148 {
0149     QDomDocument doc;
0150     QDomElement root = doc.createElement("Color");
0151     root.setAttribute("bitdepth", colorDepth());
0152     doc.appendChild(root);
0153     d->color.toXML(doc, root);
0154     return doc.toString();
0155 }
0156 
0157 void ManagedColor::fromXML(const QString &xml)
0158 {
0159     QDomDocument doc;
0160     doc.setContent(xml);
0161     QDomElement e = doc.documentElement();
0162     QDomElement c = e.firstChildElement("Color");
0163     KoColor kc;
0164     if (!c.isNull()) {
0165         QString colorDepthId = c.attribute("bitdepth", Integer8BitsColorDepthID.id());
0166         d->color = KoColor::fromXML(c, colorDepthId);
0167     }
0168 
0169 }
0170 
0171 QString ManagedColor::toQString()
0172 {
0173     return KoColor::toQString(d->color);
0174 }
0175 
0176 KoColor ManagedColor::color() const
0177 {
0178     return d->color;
0179 }