Commit ce9ab366 authored by Halla Rempt's avatar Halla Rempt
Browse files

Add display options to the overview docker

Next to exposure there's gamma, the display profile and rendering
intent/blackpoint compensation (the last two options are broken, have
been broken for way too long!)
parent 6f408dfa
......@@ -18,8 +18,9 @@
uniform sampler2D image;
uniform vec4 exposure;
uniform vec4 gamma
const vec4 gamma = vec4(0.45, 0.45, 0.45, 1.0);
/*const vec4 gamma = vec4(0.45, 0.45, 0.45, 1.0);*/
const vec4 grey = vec4(84.66 / 255.0, 84.66 / 255.0, 84.66 / 255.0, 1.0);
void main(void)
......
......@@ -23,21 +23,28 @@
#include <QPixmap>
#include <QPainter>
#include <QImage>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QFormLayout>
#include <QCheckBox>
#include <QApplication>
#include <QDesktopWidget>
#include <klocale.h>
#include <kcombobox.h>
#include <KoColorSpace.h>
#include <KoColorSpaceFactory.h>
#include <KoColorSpaceRegistry.h>
#include <KoColorProfile.h>
#include <kis_view2.h>
#include <kis_doc2.h>
#include <kis_config.h>
#include <kis_canvas2.h>
#include <kis_canvas_resource_provider.h>
#include <kis_config_notifier.h>
#include <widgets/kis_double_widget.h>
#include <canvas/kis_canvas2.h>
#include <kis_image.h>
#include <kis_canvas_resource_provider.h>
#include "widgets/squeezedcombobox.h"
KisBirdEyeBox::KisBirdEyeBox()
: QDockWidget(i18n("Overview"))
......@@ -48,21 +55,11 @@ KisBirdEyeBox::KisBirdEyeBox()
QWidget * w = new QWidget(this);
setWidget(w);
QVBoxLayout * l = new QVBoxLayout(w);
QHBoxLayout * hl = new QHBoxLayout();
l->addLayout(hl);
m_exposureLabel = new QLabel(i18n("Exposure:"), w);
hl->addWidget(m_exposureLabel);
QFormLayout *layout = new QFormLayout(w);
m_exposureDoubleWidget = new KisDoubleWidget(-10, 10, w);
m_exposureDoubleWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
m_exposureDoubleWidget->setToolTip(i18n("Select the exposure (stops) for HDR images"));
hl->addWidget(m_exposureDoubleWidget);
l->addItem(new QSpacerItem(0, 1, QSizePolicy::Minimum, QSizePolicy::MinimumExpanding));
m_exposureDoubleWidget->setToolTip(i18n("Select the exposure (stops) for HDR images."));
m_exposureDoubleWidget->setPrecision(1);
m_exposureDoubleWidget->setValue(0);
m_exposureDoubleWidget->setSingleStep(0.1);
......@@ -72,7 +69,38 @@ KisBirdEyeBox::KisBirdEyeBox()
connect(m_exposureDoubleWidget, SIGNAL(sliderPressed()), SLOT(exposureSliderPressed()));
connect(m_exposureDoubleWidget, SIGNAL(sliderReleased()), SLOT(exposureSliderReleased()));
m_draggingExposureSlider = false;
m_gammaDoubleWidget = new KisDoubleWidget(0, 5, w);
m_gammaDoubleWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
m_gammaDoubleWidget->setToolTip(i18n("Select the amount of gamma modificiation for display. This does not affect the pixels of your image."));
m_gammaDoubleWidget->setPrecision(2);
m_gammaDoubleWidget->setValue(2.2);
m_gammaDoubleWidget->setSingleStep(0.1);
m_gammaDoubleWidget->setPageStep(1);
connect(m_gammaDoubleWidget, SIGNAL(valueChanged(double)), SLOT(gammaValueChanged(double)));
connect(m_gammaDoubleWidget, SIGNAL(sliderPressed()), SLOT(gammaSliderPressed()));
connect(m_gammaDoubleWidget, SIGNAL(sliderReleased()), SLOT(gammaSliderReleased()));
m_cmbDisplayProfile = new SqueezedComboBox(w);
m_cmbDisplayProfile->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
connect(m_cmbDisplayProfile, SIGNAL(activated(int)), SLOT(updateDisplaySettings()));
m_cmbMonitorIntent = new KComboBox(w);
m_cmbMonitorIntent->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
m_cmbMonitorIntent->addItems(QStringList() << i18n("Perceptual") << i18n("Relative Colorimetric") << i18n("Saturation") << i18n("Absolute Colorimetric"));
connect(m_cmbMonitorIntent, SIGNAL(activated(int)), SLOT(updateDisplaySettings()));
m_chkBlackPoint = new QCheckBox(i18n("Use Blackpoint Compensation"));
connect(m_chkBlackPoint, SIGNAL(toggled(bool)), SLOT(updateDisplaySettings()));
m_draggingSlider = false;
layout->addRow(i18n("Exposure:"), m_exposureDoubleWidget);
layout->addRow(i18n("Gamma:"), m_gammaDoubleWidget);
layout->addRow(i18n("Display profile"), m_cmbDisplayProfile);
layout->addRow(i18n("Rendering Intent"), m_cmbMonitorIntent);
layout->addWidget(m_chkBlackPoint);
layout->addItem(new QSpacerItem(0, 1, QSizePolicy::Minimum, QSizePolicy::MinimumExpanding));
}
KisBirdEyeBox::~KisBirdEyeBox()
......@@ -83,36 +111,90 @@ void KisBirdEyeBox::setCanvas(KoCanvasBase* _canvas)
{
if (KisCanvas2* canvas = dynamic_cast<KisCanvas2*>(_canvas)) {
m_canvas = canvas;
m_exposureDoubleWidget->setValue(m_canvas->view()->resourceProvider()->HDRExposure());
m_gammaDoubleWidget->setValue(m_canvas->view()->resourceProvider()->HDRGamma());
connect(m_canvas->image(), SIGNAL(sigColorSpaceChanged(const KoColorSpace*)), SLOT(slotImageColorSpaceChanged(const KoColorSpace*)), Qt::UniqueConnection);
const KoColorSpaceFactory * csf = KoColorSpaceRegistry::instance()->colorSpaceFactory("RGBA");
m_cmbDisplayProfile->clear();
if (csf) {
QList<const KoColorProfile *> profileList = KoColorSpaceRegistry::instance()->profilesFor(csf);
foreach(const KoColorProfile *profile, profileList) {
if (profile->isSuitableForDisplay())
m_cmbDisplayProfile->addSqueezedItem(profile->name());
}
KoColorProfile *monitorProfile = m_canvas->monitorProfile();
if (monitorProfile) {
m_cmbDisplayProfile->setCurrent(monitorProfile->name());
}
else {
m_cmbDisplayProfile->setCurrent(csf->defaultProfile());
}
}
KisConfig cfg;
m_chkBlackPoint->setChecked(cfg.useBlackPointCompensation());
m_cmbMonitorIntent->setCurrentIndex(cfg.renderIntent());
}
}
void KisBirdEyeBox::slotImageColorSpaceChanged(const KoColorSpace *cs)
{
if (cs->hasHighDynamicRange()) {
m_exposureDoubleWidget->show();
m_exposureLabel->show();
} else {
m_exposureDoubleWidget->hide();
m_exposureLabel->hide();
}
m_exposureDoubleWidget->setEnabled(cs->hasHighDynamicRange() && m_canvas->canvasIsOpenGL());
m_gammaDoubleWidget->setEnabled(cs->hasHighDynamicRange() && m_canvas->canvasIsOpenGL());
}
void KisBirdEyeBox::exposureValueChanged(double exposure)
{
if (m_canvas && (!m_draggingExposureSlider || m_canvas->usingHDRExposureProgram())) {
if (m_canvas && (!m_draggingSlider || m_canvas->usingHDRExposureProgram())) {
m_canvas->view()->resourceProvider()->setHDRExposure(exposure);
}
}
void KisBirdEyeBox::exposureSliderPressed()
{
m_draggingExposureSlider = true;
m_draggingSlider = true;
}
void KisBirdEyeBox::exposureSliderReleased()
{
m_draggingExposureSlider = false;
m_draggingSlider = false;
exposureValueChanged(m_exposureDoubleWidget->value());
}
void KisBirdEyeBox::gammaValueChanged(double gamma)
{
if (m_canvas && (!m_draggingSlider || m_canvas->usingHDRExposureProgram())) {
m_canvas->view()->resourceProvider()->setHDRGamma(gamma);
}
}
void KisBirdEyeBox::gammaSliderPressed()
{
m_draggingSlider = true;
}
void KisBirdEyeBox::gammaSliderReleased()
{
m_draggingSlider = false;
gammaValueChanged(m_gammaDoubleWidget->value());
}
void KisBirdEyeBox::updateDisplaySettings()
{
KisConfig cfg;
cfg.setMonitorProfile(m_cmbDisplayProfile->itemHighlighted(), true);
cfg.setUseBlackPointCompensation(m_chkBlackPoint->isChecked());
cfg.setRenderIntent(m_cmbMonitorIntent->currentIndex());
KisConfigNotifier::instance()->notifyConfigChanged();
m_canvas->view()->resourceProvider()->resetDisplayProfile(QApplication::desktop()->screenNumber(this));
}
#include "kis_birdeye_box.moc"
......@@ -34,7 +34,9 @@ class KoBirdEyePanel;
class KisDoubleWidget;
class KoZoomAdapter;
class KoColorSpace;
class SqueezedComboBox;
class QCheckBox;
class KComboBox;
/**
* Image overview docker
*
......@@ -57,19 +59,28 @@ public:
private slots:
void slotImageColorSpaceChanged(const KoColorSpace *cs);
void slotImageColorSpaceChanged(const KoColorSpace*);
void exposureValueChanged(double exposure);
void exposureSliderPressed();
void exposureSliderReleased();
void gammaValueChanged(double exposure);
void gammaSliderPressed();
void gammaSliderReleased();
void updateDisplaySettings();
private:
KisCanvas2* m_canvas;
KisCanvas2 *m_canvas;
KoBirdEyePanel *m_birdEyePanel;
KisDoubleWidget *m_exposureDoubleWidget;
KisDoubleWidget *m_gammaDoubleWidget;
SqueezedComboBox *m_cmbDisplayProfile;
KComboBox *m_cmbMonitorIntent;
QCheckBox *m_chkBlackPoint;
KoBirdEyePanel * m_birdEyePanel;
KisDoubleWidget * m_exposureDoubleWidget;
QLabel *m_exposureLabel;
bool m_draggingExposureSlider;
bool m_draggingSlider;
};
......
......@@ -266,7 +266,7 @@
<item>
<widget class="QCheckBox" name="chkBlackpoint">
<property name="text">
<string>Use Blackpoint compensation</string>
<string>Use Blackpoint Compensation</string>
</property>
<property name="checked">
<bool>true</bool>
......
......@@ -78,6 +78,9 @@ void KisCanvasResourceProvider::setResourceManager(KoCanvasResourceManager *reso
setMirrorHorizontal(false);
setMirrorVertical(false);
m_resourceManager->setResource(HdrExposure, 0.0);
m_resourceManager->setResource(HdrGamma, 2.2);
connect(m_resourceManager, SIGNAL(resourceChanged(int, const QVariant &)),
this, SLOT(slotResourceChanged(int, const QVariant&)));
}
......@@ -106,13 +109,28 @@ float KisCanvasResourceProvider::HDRExposure() const
void KisCanvasResourceProvider::setHDRExposure(float exposure)
{
m_resourceManager->setResource(HdrExposure, static_cast<double>(exposure));
KisExposureVisitor eV(exposure);
KisProfilePropertyVisitor eV("exposure", exposure);
m_view->image()->projection()->colorSpace()->profile()->setProperty("exposure", exposure);
m_view->image()->rootLayer()->accept(eV);
m_view->canvasBase()->updateCanvas();
m_view->canvasBase()->startUpdateCanvasProjection(m_view->image()->bounds());
}
float KisCanvasResourceProvider::HDRGamma() const
{
return static_cast<float>(m_resourceManager->resource(HdrGamma).toDouble());
}
void KisCanvasResourceProvider::setHDRGamma(float gamma)
{
m_resourceManager->setResource(HdrGamma, static_cast<double>(gamma));
KisProfilePropertyVisitor eV("gamma", gamma);
m_view->image()->projection()->colorSpace()->profile()->setProperty("gamma", gamma);
m_view->image()->rootLayer()->accept(eV);
m_view->canvasBase()->updateCanvas();
m_view->canvasBase()->startUpdateCanvasProjection(m_view->image()->bounds());
}
KisPattern * KisCanvasResourceProvider::currentPattern() const
{
......
......@@ -62,7 +62,8 @@ public:
MirrorHorizontal,
MirrorVertical,
MirrorAxisCenter,
Opacity
Opacity,
HdrGamma
};
......@@ -83,6 +84,9 @@ public:
float HDRExposure() const;
void setHDRExposure(float exposure);
float HDRGamma() const;
void setHDRGamma(float gamma);
KisPattern *currentPattern() const;
KoAbstractGradient *currentGradient() const;
......@@ -166,8 +170,8 @@ signals:
private:
KisView2 * m_view;
KoCanvasResourceManager * m_resourceManager;
const KoColorProfile * m_displayProfile;
KoCanvasResourceManager *m_resourceManager;
const KoColorProfile *m_displayProfile;
bool m_fGChanged;
QList<KisAbstractPerspectiveGrid*> m_perspectiveGrids;
......
......@@ -177,8 +177,9 @@ QString KisConfig::monitorProfile() const
return m_cfg.readEntry("monitorProfile", "");
}
void KisConfig::setMonitorProfile(const QString & monitorProfile)
void KisConfig::setMonitorProfile(const QString & monitorProfile, bool override)
{
m_cfg.writeEntry("monitorProfile/OverrideX11", override);
m_cfg.writeEntry("monitorProfile", monitorProfile);
}
......@@ -225,7 +226,14 @@ const KoColorProfile *KisConfig::displayProfile(int screen)
{
// first try to get the screen profile set by the X11 _ICC_PROFILE atom (compatible with colord,
// but colord can set the atom to none, in which case we cannot create a suitable profile)
const KoColorProfile *profile = KisConfig::getScreenProfile(screen);
// if the user plays with the settings, they can override the display profile, in which case
// we don't want the X11 atom setting.
bool override = m_cfg.readEntry("monitorProfile/OverrideX11", false);
const KoColorProfile *profile = 0;
if (!override) {
profile = KisConfig::getScreenProfile(screen);
}
// if it fails. check the configuration
if (!profile || !profile->isSuitableForDisplay()) {
......
......@@ -88,7 +88,7 @@ public:
void setCursorStyle(enumCursorStyle style);
QString monitorProfile() const;
void setMonitorProfile(const QString & monitorProfile);
void setMonitorProfile(const QString & monitorProfile, bool override = false);
static const KoColorProfile* getScreenProfile(int screen = -1);
const KoColorProfile *displayProfile(int screen = -1);
......
......@@ -25,38 +25,40 @@
#include "kis_paint_device.h"
#include "generator/kis_generator_layer.h"
KisExposureVisitor::KisExposureVisitor(double exposure) : m_exposure(exposure)
KisProfilePropertyVisitor::KisProfilePropertyVisitor(const QString &property, double value)
: m_property(property)
, m_value(value)
{
}
void KisExposureVisitor::setExposureToProfile(KoColorProfile* profile)
void KisProfilePropertyVisitor::setPropertyToProfile(KoColorProfile* profile)
{
profile->setProperty("exposure", m_exposure);
profile->setProperty(m_property, m_value);
}
bool KisExposureVisitor::visit(KisExternalLayer * e)
bool KisProfilePropertyVisitor::visit(KisExternalLayer * e)
{
Q_UNUSED(e);
return true;
}
bool KisExposureVisitor::visit(KisPaintLayer *layer)
bool KisProfilePropertyVisitor::visit(KisPaintLayer *layer)
{
setExposureToProfile(layer->original()->colorSpace()->profile());
setPropertyToProfile(layer->original()->colorSpace()->profile());
layer->setDirty();
return true;
}
bool KisExposureVisitor::visit(KisGeneratorLayer *layer)
bool KisProfilePropertyVisitor::visit(KisGeneratorLayer *layer)
{
setExposureToProfile(layer->original()->colorSpace()->profile());
setPropertyToProfile(layer->original()->colorSpace()->profile());
layer->setDirty();
return true;
}
bool KisExposureVisitor::visit(KisGroupLayer *layer)
bool KisProfilePropertyVisitor::visit(KisGroupLayer *layer)
{
setExposureToProfile(layer->original()->colorSpace()->profile());
setPropertyToProfile(layer->original()->colorSpace()->profile());
layer->setDirty();
KisLayerSP child = dynamic_cast<KisLayer*>(layer->firstChild().data());
while (child) {
......@@ -65,7 +67,7 @@ bool KisExposureVisitor::visit(KisGroupLayer *layer)
}
return true;
}
bool KisExposureVisitor::visit(KisAdjustmentLayer* layer)
bool KisProfilePropertyVisitor::visit(KisAdjustmentLayer* layer)
{
Q_UNUSED(layer);
return true;
......
......@@ -24,12 +24,12 @@
class KoColorProfile;
/**
* Set the exposure
* Set the exposure and gamma
*/
class KisExposureVisitor : public KisNodeVisitor
class KisProfilePropertyVisitor : public KisNodeVisitor
{
public:
KisExposureVisitor(double exposure);
KisProfilePropertyVisitor(const QString &property, double value);
using KisNodeVisitor::visit;
......@@ -55,9 +55,10 @@ public:
}
protected:
void setExposureToProfile(KoColorProfile* profile);
void setPropertyToProfile(KoColorProfile* profile);
private:
double m_exposure;
QString m_property;
double m_value;
};
......
......@@ -257,7 +257,8 @@ void KisOpenGLCanvas2::drawImage()
if (m_d->openGLImageTextures->usingHDRExposureProgram()) {
m_d->openGLImageTextures->activateHDRExposureProgram();
}
m_d->openGLImageTextures->setHDRExposure(canvas()->view()->resourceProvider()->HDRExposure());
m_d->openGLImageTextures->setHDRExposure(canvas()->view()->resourceProvider()->HDRExposure(),
canvas()->view()->resourceProvider()->HDRGamma());
}
makeCurrent();
......
......@@ -27,6 +27,7 @@
KisOpenGLHDRExposureProgram::KisOpenGLHDRExposureProgram()
{
m_exposure = 0;
m_gamma = 2.2;
createProgram();
}
......@@ -39,6 +40,15 @@ void KisOpenGLHDRExposureProgram::setExposure(float exposure)
}
}
void KisOpenGLHDRExposureProgram::setGamma(float gamma)
{
m_gamma = gamma;
if (active()) {
setGammaUniformVariable();
}
}
void KisOpenGLHDRExposureProgram::setExposureUniformVariable()
{
Q_ASSERT(active());
......@@ -48,10 +58,19 @@ void KisOpenGLHDRExposureProgram::setExposureUniformVariable()
setUniformVariable("exposure", exposure, exposure, exposure, 1.0);
}
void KisOpenGLHDRExposureProgram::setGammaUniformVariable()
{
Q_ASSERT(active());
float gamma = 1.0 / m_gamma;
setUniformVariable("gamma", gamma, gamma, gamma, 1.0);
}
void KisOpenGLHDRExposureProgram::activate()
{
KisOpenGLProgram::activate();
setExposureUniformVariable();
setGammaUniformVariable();
setUniformVariable("image", ImageTextureUnit);
}
......
......@@ -39,6 +39,13 @@ public:
*/
void setExposure(float exposure);
/**
* @brief setGamma set the gamma correction
* @param gamma in a range from 0 to 5; 2.2 is "standard"
*/
void setGamma(float gamma);
/**
* Activate the program ready for rendering.
*/
......@@ -47,11 +54,13 @@ public:
private:
virtual void createProgram();
void setExposureUniformVariable();
void setGammaUniformVariable();
static const GLint ImageTextureUnit = 0;
static const GLint ImageTextureUnitEnum = GL_TEXTURE0 + ImageTextureUnit;
GLfloat m_exposure;
GLfloat m_gamma;
};
#endif // KIS_OPENGL_HDR_EXPOSURE_PROGRAM_H_
......
......@@ -301,7 +301,7 @@ void KisOpenGLImageTextures::setMonitorProfile(KoColorProfile *monitorProfile)
}
}
void KisOpenGLImageTextures::setHDRExposure(float exposure)
void KisOpenGLImageTextures::setHDRExposure(float exposure, float gamma)
{
if (exposure != m_exposure) {
m_exposure = exposure;
......@@ -310,6 +310,7 @@ void KisOpenGLImageTextures::setHDRExposure(float exposure)
#ifdef HAVE_GLEW
if (m_usingHDRExposureProgram) {
HDRExposureProgram->setExposure(exposure);
HDRExposureProgram->setGamma(gamma);
} else {
#endif
......
......@@ -80,8 +80,9 @@ public:
* Set the exposure level used to display high dynamic range images. Typical values
* are between -10 and 10.
* @param exposure The exposure level
* @param gamma The gamma correction
*/
void setHDRExposure(float exposure);
void setHDRExposure(float exposure, float gamma = 2.2);
/**
* Generate a background texture from the given QImage. This is used for the checker
......
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