Commit b1c1ba3a authored by Dmitry Kazakov's avatar Dmitry Kazakov

Added a Background Color feature to KisImage

Now the user can choose the Background color for the projection.
Just go to Image->Properties->Background Color and choose the one
you want. And you'll never see the checkers anymore :)

This also fixes EXR images, which should have a black BG color

BUG:301443
parent 00dfc827
......@@ -187,16 +187,22 @@ KisPaintDeviceSP KisGroupLayer::tryObligeChild() const
const KisLayer *child = onlyMeaningfulChild();
if (child &&
child->channelFlags().isEmpty() &&
child->projection() &&
child->visible() &&
(child->compositeOpId() == COMPOSITE_OVER ||
child->compositeOpId() == COMPOSITE_ALPHA_DARKEN ||
child->compositeOpId() == COMPOSITE_COPY) &&
child->opacity() == OPACITY_OPAQUE_U8 &&
*child->projection()->colorSpace() == *colorSpace()) {
return child->projection();
child->channelFlags().isEmpty() &&
child->projection() &&
child->visible() &&
(child->compositeOpId() == COMPOSITE_OVER ||
child->compositeOpId() == COMPOSITE_ALPHA_DARKEN ||
child->compositeOpId() == COMPOSITE_COPY) &&
child->opacity() == OPACITY_OPAQUE_U8 &&
*child->projection()->colorSpace() == *colorSpace()) {
quint8 defaultOpacity =
m_d->paintDevice->colorSpace()->opacityU8(
m_d->paintDevice->defaultPixel());
if(defaultOpacity == OPACITY_TRANSPARENT_U8) {
return child->projection();
}
}
return 0;
......
......@@ -1266,18 +1266,48 @@ KisActionRecorder* KisImage::actionRecorder() const
return m_d->recorder;
}
void KisImage::setDefaultProjectionColor(KoColor color)
{
KIS_ASSERT_RECOVER_RETURN(m_d->rootLayer);
KisPaintDeviceSP original = m_d->rootLayer->original();
color.convertTo(original->colorSpace());
original->setDefaultPixel(color.data());
}
KoColor KisImage::defaultProjectionColor() const
{
KIS_ASSERT_RECOVER(m_d->rootLayer) {
return KoColor(Qt::transparent, m_d->colorSpace);
}
KisPaintDeviceSP original = m_d->rootLayer->original();
KoColor color(original->defaultPixel(), original->colorSpace());
return color;
}
void KisImage::setRootLayer(KisGroupLayerSP rootLayer)
{
stopIsolatedMode();
KoColor defaultProjectionColor(Qt::transparent, m_d->colorSpace);
if (m_d->rootLayer) {
m_d->rootLayer->setGraphListener(0);
m_d->rootLayer->disconnect();
KisPaintDeviceSP original = m_d->rootLayer->original();
defaultProjectionColor.setColor(original->defaultPixel(), original->colorSpace());
}
m_d->rootLayer = rootLayer;
m_d->rootLayer->disconnect();
m_d->rootLayer->setGraphListener(this);
KisPaintDeviceSP newOriginal = m_d->rootLayer->original();
defaultProjectionColor.convertTo(newOriginal->colorSpace());
newOriginal->setDefaultPixel(defaultProjectionColor.data());
setRoot(m_d->rootLayer.data());
}
......
......@@ -430,6 +430,17 @@ public:
/// use if the layers have changed _completely_ (eg. when flattening)
void notifyLayersChanged();
/**
* Sets the default color of the root layer projection. All the layers
* will be merged on top of this very color
*/
void setDefaultProjectionColor(KoColor color);
/**
* \see setDefaultProjectionColor()
*/
KoColor defaultProjectionColor() const;
void setRootLayer(KisGroupLayerSP rootLayer);
/**
......
......@@ -36,6 +36,7 @@
#include <KoCompositeOpRegistry.h>
#include <KoColorSpaceTraits.h>
#include <KoColorModelStandardIds.h>
#include <KoColor.h>
#include <kis_doc2.h>
#include <kis_group_layer.h>
......@@ -557,6 +558,8 @@ KisImageBuilder_Result exrConverter::decode(const KUrl& uri)
return KisImageBuilder_RESULT_FAILURE;
}
m_d->image->setDefaultProjectionColor(KoColor(Qt::black, colorSpace));
// Create group layers
for (int i = 0; i < groups.size(); ++i) {
ExrGroupLayerInfo& info = groups[i];
......
......@@ -34,12 +34,16 @@
#include <KoUnitDoubleSpinBox.h>
#include <KoColorSpace.h>
#include "KoColorProfile.h"
#include "KoColor.h"
#include "KoColorPopupAction.h"
#include "KoIcon.h"
#include "KoID.h"
#include "kis_types.h"
#include "kis_image.h"
#include "kis_annotation.h"
#include "kis_config.h"
#include "kis_factory2.h"
#include "kis_signal_compressor.h"
#include "widgets/kis_cmb_idlist.h"
#include "widgets/squeezedcombobox.h"
......@@ -64,6 +68,18 @@ KisDlgImageProperties::KisDlgImageProperties(KisImageWSP image, QWidget *parent,
m_page->lblResolutionValue->setText(KGlobal::locale()->formatNumber(image->xRes()*72, 2)); // XXX: separate values for x & y?
m_defaultColorAction = new KoColorPopupAction(this);
m_defaultColorAction->setCurrentColor(m_image->defaultProjectionColor());
m_defaultColorAction->setIcon(koIcon("format-stroke-color"));
m_defaultColorAction->setToolTip(i18n("Change the background color of the image"));
m_page->bnBackgroundColor->setDefaultAction(m_defaultColorAction);
KisSignalCompressor *compressor = new KisSignalCompressor(500 /* ms */, KisSignalCompressor::POSTPONE, this);
connect(m_defaultColorAction, SIGNAL(colorChanged(const KoColor&)), compressor, SLOT(start()));
connect(compressor, SIGNAL(timeout()), this, SLOT(setCurrentColor()));
connect(m_defaultColorAction, SIGNAL(colorChanged(const KoColor&)), this, SLOT(setCurrentColor()));
m_page->colorSpaceSelector->setCurrentColorSpace(image->colorSpace());
vKisAnnotationSP_it beginIt = image->beginAnnotations();
......@@ -96,6 +112,13 @@ const KoColorSpace * KisDlgImageProperties::colorSpace()
return m_page->colorSpaceSelector->currentColorSpace();
}
void KisDlgImageProperties::setCurrentColor()
{
qDebug() << "Update current color";
m_image->setDefaultProjectionColor(m_defaultColorAction->currentKoColor());
m_image->refreshGraph();
}
void KisDlgImageProperties::setAnnotation(const QString &type)
{
KisAnnotationSP annotation = m_image->annotation(type);
......
......@@ -25,6 +25,8 @@
class KoID;
class KoColorSpace;
class KoColor;
class KoColorPopupAction;
class WdgImageProperties : public QWidget, public Ui::WdgImageProperties
{
......@@ -52,10 +54,12 @@ public:
private slots:
void setAnnotation(const QString& type);
void setCurrentColor();
private:
WdgImageProperties * m_page;
KisImageWSP m_image;
KoColorPopupAction *m_defaultColorAction;
};
......
......@@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>438</width>
<width>468</width>
<height>101</height>
</rect>
</property>
......@@ -98,12 +98,6 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
</widget>
</item>
<item>
......
......@@ -17,12 +17,25 @@
<item row="0" column="0">
<widget class="QGroupBox" name="grpImage">
<property name="title">
<string>Image Size</string>
<string/>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<layout class="QVBoxLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>95</width>
<height>61</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="lblWidth">
<property name="text">
<string>Width:</string>
......@@ -32,38 +45,24 @@
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblHeight">
<item row="0" column="1">
<widget class="QLabel" name="lblWidthValue">
<property name="text">
<string>Height:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
<string comment="KDE::DoNotExtract">TextLabel</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblResolution">
<item row="1" column="0">
<widget class="QLabel" name="lblHeight">
<property name="text">
<string>Resolution:</string>
<string>Height:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="lblWidthValue">
<property name="text">
<string comment="KDE::DoNotExtract">TextLabel</string>
</property>
</widget>
</item>
<item row="1" column="0">
<item row="1" column="1">
<widget class="QLabel" name="lblHeightValue">
<property name="text">
<string comment="KDE::DoNotExtract">TextLabel</string>
......@@ -71,19 +70,50 @@
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="lblResolutionValue">
<widget class="QLabel" name="lblResolution">
<property name="text">
<string comment="KDE::DoNotExtract">TextLabel</string>
<string>Resolution:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="label">
<property name="toolTip">
<string>pixels-per-inch</string>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="lblResolutionValue">
<property name="text">
<string comment="KDE::DoNotExtract">TextLabel</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label">
<property name="toolTip">
<string>pixels-per-inch</string>
</property>
<property name="text">
<string>ppi</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="3" column="0">
<widget class="QLabel" name="lblBgColor">
<property name="text">
<string comment="The background color of the image's projection">Background Color</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QToolButton" name="bnBackgroundColor">
<property name="text">
<string>ppi</string>
<string>...</string>
</property>
<property name="popupMode">
<enum>QToolButton::InstantPopup</enum>
</property>
</widget>
</item>
......@@ -99,7 +129,7 @@
</property>
<property name="sizeHint" stdset="0">
<size>
<width>191</width>
<width>95</width>
<height>61</height>
</size>
</property>
......
......@@ -253,6 +253,17 @@ KisImageWSP KisKraLoader::loadXML(const KoXmlElement& element)
loadNodes(element, image, const_cast<KisGroupLayer*>(image->rootLayer().data()));
KoXmlNode child;
for (child = element.lastChild(); !child.isNull(); child = child.previousSibling()) {
KoXmlElement e = child.toElement();
if(e.tagName() == "ProjectionBackgroundColor") {
if (e.hasAttribute("ColorData")) {
QByteArray colorData = QByteArray::fromBase64(e.attribute("ColorData").toLatin1());
KoColor color((const quint8*)colorData.data(), image->colorSpace());
image->setDefaultProjectionColor(color);
}
}
}
for (child = element.lastChild(); !child.isNull(); child = child.previousSibling()) {
KoXmlElement e = child.toElement();
if(e.tagName() == "compositions") {
......
......@@ -98,6 +98,7 @@ QDomElement KisKraSaver::saveXML(QDomDocument& doc, KisImageWSP image)
m_d->nodeFileNames = visitor.nodeFileNames();
saveBackgroundColor(doc, imageElement, image);
saveCompositions(doc, imageElement, image);
saveAssistantsList(doc,imageElement);
return imageElement;
......@@ -178,6 +179,15 @@ QStringList KisKraSaver::errorMessages() const
return m_d->errorMessages;
}
void KisKraSaver::saveBackgroundColor(QDomDocument& doc, QDomElement& element, KisImageWSP image)
{
QDomElement e = doc.createElement("ProjectionBackgroundColor");
KoColor color = image->defaultProjectionColor();
QByteArray colorData = QByteArray::fromRawData((const char*)color.data(), color.colorSpace()->pixelSize());
e.setAttribute("ColorData", QString(colorData.toBase64()));
element.appendChild(e);
}
void KisKraSaver::saveCompositions(QDomDocument& doc, QDomElement& element, KisImageWSP image)
{
if (!image->compositions().isEmpty()) {
......
......@@ -44,6 +44,7 @@ public:
QStringList errorMessages() const;
private:
void saveBackgroundColor(QDomDocument& doc, QDomElement& element, KisImageWSP image);
void saveCompositions(QDomDocument& doc, QDomElement& element, KisImageWSP image);
bool saveAssistants(KoStore *store,QString uri, bool external);
bool saveAssistantsList(QDomDocument& doc, QDomElement& element);
......
......@@ -49,6 +49,8 @@
void KisKraSaverTest::testRoundTrip()
{
KisDoc2* doc = createCompleteDocument();
KoColor bgColor(Qt::red, doc->image()->colorSpace());
doc->image()->setDefaultProjectionColor(bgColor);
doc->saveNativeFormat("roundtriptest.kra");
QStringList list;
KisCountVisitor cv1(list, KoProperties());
......@@ -61,6 +63,9 @@ void KisKraSaverTest::testRoundTrip()
KisCountVisitor cv2(list, KoProperties());
doc2.image()->rootLayer()->accept(cv2);
QCOMPARE(cv1.count(), cv2.count());
// check whether the BG color is saved correctly
QCOMPARE(doc2.image()->defaultProjectionColor(), bgColor);
}
void KisKraSaverTest::testSaveEmpty()
......
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