Commit d390ef10 authored by Boudewijn Rempt's avatar Boudewijn Rempt

Add a ManagedColor class and unittest

parent 743d001e
......@@ -8,6 +8,7 @@ set(kritalibkis_LIB_SRCS
Filter.cpp
InfoObject.cpp
Krita.cpp
ManagedColor.cpp
Node.cpp
Notifier.cpp
PresetChooser
......
......@@ -111,6 +111,12 @@ View *Canvas::view() const
return view;
}
KisDisplayColorConverter *Canvas::displayColorConverter() const
{
if (!d->canvas) return 0;
return d->canvas->displayColorConverter();
}
bool Canvas::wrapAroundMode() const
{
if (!d->canvas) return false;
......
......@@ -24,6 +24,7 @@
#include "libkis.h"
class KoCanvasBase;
class KisDisplayColorConverter;
/**
* Canvas wraps the canvas inside a view on an image/document.
......@@ -40,7 +41,7 @@ public:
bool operator==(const Canvas &other) const;
bool operator!=(const Canvas &other) const;
public Q_SLOTS:
/**
......@@ -111,6 +112,11 @@ public Q_SLOTS:
View *view() const;
private:
friend class ManagedColor;
KisDisplayColorConverter *displayColorConverter() const;
struct Private;
Private *const d;
......
/*
* Copyright (C) 2017 Boudewijn Rempt <boud@valdyas.org>
*
* 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.
*
* 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.
*
* 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.
*/
#include "ManagedColor.h"
#include <KoColor.h>
#include <KoColorSpaceRegistry.h>
#include <KoColorProfile.h>
#include <KoColorModelStandardIds.h>
#include <QDomDocument>
#include <QDomElement>
#include <Canvas.h>
#include <kis_display_color_converter.h>
struct ManagedColor::Private {
KoColor color;
};
ManagedColor::ManagedColor(QObject *parent)
: QObject(parent)
, d(new Private())
{
// Default black rgb color
}
ManagedColor::ManagedColor(const QString &colorModel, const QString &colorDepth, const QString &colorProfile, QObject *parent)
: QObject(parent)
, d(new Private())
{
const KoColorSpace *colorSpace = KoColorSpaceRegistry::instance()->colorSpace(colorModel, colorDepth, colorProfile);
if (colorSpace) {
d->color = KoColor(colorSpace);
}
}
ManagedColor::ManagedColor(KoColor color, QObject *parent)
: QObject(parent)
, d(new Private())
{
d->color = color;
}
ManagedColor::~ManagedColor()
{
}
bool ManagedColor::operator==(const ManagedColor &other) const
{
return d->color == other.d->color;
}
QColor ManagedColor::colorForCanvas(Canvas *canvas) const
{
KisDisplayColorConverter *converter = canvas->displayColorConverter();
return converter->toQColor(d->color);
}
QString ManagedColor::colorDepth() const
{
return d->color.colorSpace()->colorDepthId().id();
}
QString ManagedColor::colorModel() const
{
return d->color.colorSpace()->colorModelId().id();
}
QString ManagedColor::colorProfile() const
{
return d->color.colorSpace()->profile()->name();
}
bool ManagedColor::setColorProfile(const QString &colorProfile)
{
const KoColorProfile *profile = KoColorSpaceRegistry::instance()->profileByName(colorProfile);
if (!profile) return false;
d->color.setProfile(profile);
return true;
}
bool ManagedColor::setColorSpace(const QString &colorModel, const QString &colorDepth, const QString &colorProfile)
{
const KoColorSpace *colorSpace = KoColorSpaceRegistry::instance()->colorSpace(colorModel, colorDepth, colorProfile);
if (!colorSpace) return false;
d->color.convertTo(colorSpace);
return true;
}
QVector<float> ManagedColor::components() const
{
QVector<float> values(d->color.colorSpace()->channelCount());
d->color.colorSpace()->normalisedChannelsValue(d->color.data(), values);
return values;
}
void ManagedColor::setComponents(const QVector<float> &values)
{
d->color.colorSpace()->fromNormalisedChannelsValue(d->color.data(), values);
}
QString ManagedColor::toXML() const
{
QDomDocument doc;
QDomElement root = doc.createElement("Color");
root.setAttribute("bitdepth", colorDepth());
doc.appendChild(root);
d->color.toXML(doc, root);
return doc.toString();
}
void ManagedColor::fromXML(const QString &xml)
{
QDomDocument doc;
doc.setContent(xml);
QDomElement e = doc.documentElement();
QDomElement c = e.firstChildElement("Color");
KoColor kc;
if (!c.isNull()) {
QString colorDepthId = c.attribute("bitdepth", Integer8BitsColorDepthID.id());
d->color = KoColor::fromXML(c, colorDepthId);
}
}
QString ManagedColor::toQString()
{
return KoColor::toQString(d->color);
}
/*
* Copyright (C) 2017 Boudewijn Rempt <boud@valdyas.org>
*
* 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.
*
* 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.
*
* 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.
*/
#ifndef MANAGEDCOLOR_H
#define MANAGEDCOLOR_H
#include <QObject>
#include <QVector>
#include <QScopedPointer>
#include "kritalibkis_export.h"
#include "libkis.h"
class KoColor;
/**
* @brief The ManagedColor class ...
*/
class KRITALIBKIS_EXPORT ManagedColor : public QObject
{
Q_OBJECT
public:
explicit ManagedColor(QObject *parent = 0);
ManagedColor(const QString &colorModel, const QString &colorDepth, const QString &colorProfile, QObject *parent = 0);
ManagedColor(KoColor color, QObject *parent = 0);
~ManagedColor() override;
bool operator==(const ManagedColor &other) const;
QColor colorForCanvas(Canvas *canvas) const;
/**
* colorDepth A string describing the color depth of the image:
* <ul>
* <li>U8: unsigned 8 bits integer, the most common type</li>
* <li>U16: unsigned 16 bits integer</li>
* <li>F16: half, 16 bits floating point. Only available if Krita was built with OpenEXR</li>
* <li>F32: 32 bits floating point</li>
* </ul>
* @return the color depth.
*/
QString colorDepth() const;
/**
* @brief colorModel retrieve the current color model of this document:
* <ul>
* <li>A: Alpha mask</li>
* <li>RGBA: RGB with alpha channel (The actual order of channels is most often BGR!)</li>
* <li>XYZA: XYZ with alpha channel</li>
* <li>LABA: LAB with alpha channel</li>
* <li>CMYKA: CMYK with alpha channel</li>
* <li>GRAYA: Gray with alpha channel</li>
* <li>YCbCrA: YCbCr with alpha channel</li>
* </ul>
* @return the internal color model string.
*/
QString colorModel() const;
/**
* @return the name of the current color profile
*/
QString colorProfile() const;
/**
* @brief setColorProfile set the color profile of the image to the given profile. The profile has to
* be registered with krita and be compatible with the current color model and depth; the image data
* is <i>not</i> converted.
* @param colorProfile
* @return false if the colorProfile name does not correspond to to a registered profile or if assigning
* the profile failed.
*/
bool setColorProfile(const QString &colorProfile);
/**
* @brief setColorSpace convert the nodes and the image to the given colorspace. The conversion is
* done with Perceptual as intent, High Quality and No LCMS Optimizations as flags and no blackpoint
* compensation.
*
* @param colorModel A string describing the color model of the image:
* <ul>
* <li>A: Alpha mask</li>
* <li>RGBA: RGB with alpha channel (The actual order of channels is most often BGR!)</li>
* <li>XYZA: XYZ with alpha channel</li>
* <li>LABA: LAB with alpha channel</li>
* <li>CMYKA: CMYK with alpha channel</li>
* <li>GRAYA: Gray with alpha channel</li>
* <li>YCbCrA: YCbCr with alpha channel</li>
* </ul>
* @param colorDepth A string describing the color depth of the image:
* <ul>
* <li>U8: unsigned 8 bits integer, the most common type</li>
* <li>U16: unsigned 16 bits integer</li>
* <li>F16: half, 16 bits floating point. Only available if Krita was built with OpenEXR</li>
* <li>F32: 32 bits floating point</li>
* </ul>
* @param colorProfile a valid color profile for this color model and color depth combination.
* @return false the combination of these arguments does not correspond to a colorspace.
*/
bool setColorSpace(const QString &colorModel, const QString &colorDepth, const QString &colorProfile);
/**
* @brief components
* @return
*/
QVector<float> components() const;
/**
* @brief setComponents
* @param values
*/
void setComponents(const QVector<float> &values);
/**
* Serialize this color following Create's swatch color specification available
* at http://create.freedesktop.org/wiki/index.php/Swatches_-_colour_file_format
*/
QString toXML() const;
/**
* Unserialize a color following Create's swatch color specification available
* at http://create.freedesktop.org/wiki/index.php/Swatches_-_colour_file_format
*
* @param XXX
*
* @return the unserialized color, or an empty color object if the function failed
* to unserialize the color
*/
void fromXML(const QString &xml);
/**
* @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.
*/
QString toQString();
private:
struct Private;
const QScopedPointer<Private> d;
};
#endif // MANAGEDCOLOR_H
......@@ -27,6 +27,11 @@ Palette::Palette(Resource *resource): d(new Private()) {
d->palette = dynamic_cast<KoColorSet*>(resource->resource());
}
Palette::~Palette()
{
delete d;
}
int Palette::columnCount()
{
return d->palette->columnCount();
......
......@@ -35,6 +35,8 @@ class KRITALIBKIS_EXPORT Palette : public QObject
{
public:
Palette(Resource *resource);
~Palette() override;
/**
* @brief columnCount
......
......@@ -11,5 +11,6 @@ ecm_add_tests(
TestDocument.cpp
TestNode.cpp
TestFilter.cpp
TestManagedColor.cpp
NAME_PREFIX "libs-kritalibkis-"
LINK_LIBRARIES kritalibkis Qt5::Test)
/* Copyright (C) 2017 Boudewijn Rempt <boud@valdyas.org>
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.
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.
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.
*/
#include "TestManagedColor.h"
#include <QTest>
#include <QColor>
#include <QVector>
#include <KritaVersionWrapper.h>
#include <ManagedColor.h>
#include <KoColorSpaceRegistry.h>
#include <KoColorProfile.h>
#include <KoColor.h>
QTEST_MAIN(TestManagedColor)
void TestManagedColor::testOperatorIs()
{
ManagedColor c1("RGBA", "U8", "");
ManagedColor c2("RGBA", "U8", "");
ManagedColor c3("RGBA", "U16", "");
QVERIFY(c1 == c2);
}
void TestManagedColor::testSetColorSpace()
{
ManagedColor c("RGBA", "U8", "");
c.setColorSpace("LABA", "U16", "");
QVERIFY(c.colorDepth() == "U16");
QVERIFY(c.colorModel() == "LABA");
}
void TestManagedColor::testComponentsRoundTrip()
{
ManagedColor c("RGBA", "U8", "");
QVector<float> components = c.components();
QVERIFY(components.size() == 4);
QVERIFY(components[0] == 0);
QVERIFY(components[1] == 0);
QVERIFY(components[2] == 0);
QVERIFY(components[3] == 0);
components[0] = 0.5;
components[1] = 0.5;
components[2] = 0.5;
components[3] = 0.5;
c.setComponents(components);
QVERIFY(c.toQString() == "Red 127 Green 127 Blue 127 Alpha 127");
}
void TestManagedColor::testXMLRoundTrip()
{
ManagedColor c("RGBA", "U8", "");
QVector<float> components;
components << 0.5 << 0.5 << 0.5 << 0.5;
c.setComponents(components);
QString xml = c.toXML();
c.fromXML(xml);
components = c.components();
QVERIFY(components.size() == 4);
QVERIFY(c.toQString() == "Red 127 Green 127 Blue 127 Alpha 127");
}
void TestManagedColor::testToQString()
{
ManagedColor c("RGBA", "U8", "");
QVector<float> components;
components << 0.5 << 0.5 << 0.5 << 0.5;
c.setComponents(components);
QVERIFY(c.toQString() == "Red 127 Green 127 Blue 127 Alpha 127");
}
/* This file is part of the KDE project
Copyright (C) 2017 Boudewijn Rempt
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.
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.
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.
*/
#ifndef TESTMANAGEDCOLOR_H
#define TESTMANAGEDCOLOR_H
#include <QObject>
class TestManagedColor : public QObject
{
Q_OBJECT
private Q_SLOTS:
void testOperatorIs();
void testSetColorSpace();
void testComponentsRoundTrip();
void testXMLRoundTrip();
void testToQString();
};
#endif
......@@ -241,7 +241,7 @@ void KoColor::fromKoColor(const KoColor& src)
src.colorSpace()->convertPixelsTo(src.d->data, d->data, colorSpace(), 1, KoColorConversionTransformation::internalRenderingIntent(), KoColorConversionTransformation::internalConversionFlags());
}
const KoColorProfile * KoColor::profile() const
const KoColorProfile *KoColor::profile() const
{
return d->colorSpace->profile();
}
......
......@@ -74,7 +74,7 @@ public:
const KoColorSpace * colorSpace() const;
/// return the current profile
const KoColorProfile * profile() const;
const KoColorProfile *profile() const;
/// Convert this KoColor to the specified colorspace. If the specified colorspace is the
/// same as the original colorspace, do nothing. Returns the converted KoColor.
......@@ -157,6 +157,11 @@ public:
*/
static KoColor fromXML(const QDomElement& elt, const QString & bitDepthId);
/**
* @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.
*/
static QString toQString(const KoColor &color);
#ifndef NODEBUG
......
class ManagedColor : QObject
{
%TypeHeaderCode
#include "ManagedColor.h"
%End
ManagedColor(const Palette & __0);
public:
ManagedColor(const QString &colorModel, const QString &colorDepth, const QString &colorProfile, QObject *parent = 0);
bool operator==(const ManagedColor &other) const;
QColor colorForCanvas(Canvas *canvas) const;
QString colorDepth() const;
QString colorModel() const;
QString colorProfile() const;
bool setColorProfile(const QString &colorProfile);
bool setColorSpace(const QString &colorModel, const QString &colorDepth, const QString &colorProfile);
QVector<float> components() const;
void setComponents(const QVector<float> &values);
QString toXML() const;
void fromXML(const QString &xml);
QString toQString();
private:
};
......@@ -29,5 +29,6 @@
%Include Extension.sip
%Include PresetChooser.sip
%Include Palette.sip
%Include ManagedColor.sip
%Include KisCubicCurve.sip
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment