File indexing completed on 2024-06-16 04:16:01

0001 /*
0002  *  SPDX-FileCopyrightText: 2010 Adam Celarek <kdedev at xibo dot at>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #include "kis_color_selector_simple.h"
0008 #include <QImage>
0009 #include <QPainter>
0010 #include <QColor>
0011 #include <cmath>
0012 #include <kconfig.h>
0013 #include <kconfiggroup.h>
0014 #include <ksharedconfig.h>
0015 
0016 #include "kis_display_color_converter.h"
0017 #include "kis_acs_pixel_cache_renderer.h"
0018 
0019 
0020 KisColorSelectorSimple::KisColorSelectorSimple(KisColorSelector *parent) :
0021     KisColorSelectorComponent(parent),
0022     m_lastClickPos(-1,-1)
0023 {
0024 }
0025 
0026 KoColor KisColorSelectorSimple::selectColor(int x, int y)
0027 {
0028     m_lastClickPos.setX(x/qreal(width()));
0029     m_lastClickPos.setY(y/qreal(height()));
0030 
0031     qreal xRel = x/qreal(width());
0032     qreal yRel = 1.-y/qreal(height());
0033     qreal relPos;
0034     if(height()>width())
0035         relPos = 1.-y/qreal(height());
0036     else
0037         relPos = x/qreal(width());
0038 
0039     switch (m_parameter) {
0040     case KisColorSelectorConfiguration::H:
0041         emit paramChanged(relPos, -1, -1, -1, -1, -1, -1, -1, -1);
0042         break;
0043     case KisColorSelectorConfiguration::Hluma:
0044         emit paramChanged(relPos, -1, -1, -1, -1, -1, -1, -1, -1);
0045         break;
0046     case KisColorSelectorConfiguration::hsvS:
0047         emit paramChanged(-1, relPos, -1, -1, -1, -1, -1, -1, -1);
0048         break;
0049     case KisColorSelectorConfiguration::hslS:
0050         emit paramChanged(-1, -1, -1, relPos, -1, -1, -1, -1, -1);
0051         break;
0052     case KisColorSelectorConfiguration::hsiS:
0053         emit paramChanged(-1, -1, -1, -1, -1, relPos, -1, -1, -1);
0054         break;
0055     case KisColorSelectorConfiguration::hsyS:
0056         emit paramChanged(-1, -1, -1, -1, -1, -1, -1, relPos, -1);
0057         break;
0058     case KisColorSelectorConfiguration::V:
0059         emit paramChanged(-1, -1, relPos, -1, -1, -1, -1, -1, -1);
0060         break;
0061     case KisColorSelectorConfiguration::L:
0062         emit paramChanged(-1, -1, -1, -1, relPos, -1, -1, -1, -1);
0063         break;
0064     case KisColorSelectorConfiguration::I:
0065         emit paramChanged(-1, -1, -1, -1, -1, -1, relPos, -1, -1);
0066         break;
0067     case KisColorSelectorConfiguration::Y:
0068         emit paramChanged(-1, -1, -1, -1, -1, -1, -1, -1, relPos);
0069         break;
0070     case KisColorSelectorConfiguration::SL:
0071         emit paramChanged(-1, -1, -1, xRel, yRel, -1, -1, -1, -1);
0072         break;
0073     case KisColorSelectorConfiguration::SI:
0074         emit paramChanged(-1, -1, -1, -1, -1, xRel, yRel, -1, -1);
0075         break;
0076     case KisColorSelectorConfiguration::SY:
0077         emit paramChanged(-1, -1, -1, -1, -1, -1, -1, xRel, yRel);
0078         break;
0079     case KisColorSelectorConfiguration::SV2:
0080     case KisColorSelectorConfiguration::SV:
0081         emit paramChanged(-1, xRel, yRel, -1, -1, -1, -1, -1, -1);
0082         break;
0083     case KisColorSelectorConfiguration::hsvSH:
0084         emit paramChanged(xRel, yRel, -1, -1, -1, -1, -1, -1, -1);
0085         break;
0086     case KisColorSelectorConfiguration::hslSH:
0087         emit paramChanged(xRel, -1, -1, yRel, -1, -1, -1, -1, -1);
0088         break;
0089     case KisColorSelectorConfiguration::hsiSH:
0090         emit paramChanged(xRel, -1, -1, -1, -1, yRel, -1, -1, -1);
0091         break;
0092     case KisColorSelectorConfiguration::hsySH:
0093         emit paramChanged(xRel, -1, -1, -1, -1, -1, -1, yRel, -1);
0094         break;
0095     case KisColorSelectorConfiguration::VH:
0096         emit paramChanged(xRel, -1, yRel, -1, -1, -1, -1, -1, -1);
0097         break;
0098     case KisColorSelectorConfiguration::LH:
0099         emit paramChanged(xRel, -1, -1, -1, yRel, -1, -1, -1, -1);
0100         break;
0101     case KisColorSelectorConfiguration::IH:
0102         emit paramChanged(xRel, -1, -1, -1, -1, -1, yRel, -1, -1);
0103         break;
0104     case KisColorSelectorConfiguration::YH:
0105         emit paramChanged(xRel, -1, -1, -1, -1, -1, -1, -1, yRel);
0106         break;
0107     }
0108 
0109     emit update();
0110     return colorAt(x, y);
0111 }
0112 
0113 void KisColorSelectorSimple::setColor(const KoColor &color)
0114 {
0115     qreal hsvH, hsvS, hsvV;
0116     qreal hslH, hslS, hslL;
0117     qreal hsiH, hsiS, hsiI;
0118     qreal hsyH, hsyS, hsyY;
0119     KConfigGroup cfg = KSharedConfig::openConfig()->group("advancedColorSelector");
0120     R = cfg.readEntry("lumaR", 0.2126);
0121     G = cfg.readEntry("lumaG", 0.7152);
0122     B = cfg.readEntry("lumaB", 0.0722);
0123     Gamma = cfg.readEntry("gamma", 2.2);
0124     m_parent->converter()->getHsvF(color, &hsvH, &hsvS, &hsvV);
0125     m_parent->converter()->getHslF(color, &hslH, &hslS, &hslL);
0126     //here we add our converter options
0127     m_parent->converter()->getHsiF(color, &hsiH, &hsiS, &hsiI);
0128     m_parent->converter()->getHsyF(color, &hsyH, &hsyS, &hsyY, R, G, B, Gamma);
0129 
0130     switch (m_parameter) {
0131     case KisColorSelectorConfiguration::SL:
0132         m_lastClickPos.setX(hslS);
0133         m_lastClickPos.setY(1 - hslL);
0134         emit paramChanged(-1, -1, -1, hslS, hslL, -1, -1, -1, -1);
0135         break;
0136     case KisColorSelectorConfiguration::SI:
0137         m_lastClickPos.setX(hsiS);
0138         m_lastClickPos.setY(1 - hsiI);
0139         emit paramChanged(-1, -1, -1, -1, -1, hsiS, hsiI, -1, -1);
0140         break;
0141     case KisColorSelectorConfiguration::SY:
0142         m_lastClickPos.setX(hsyS);
0143         m_lastClickPos.setY(1 - hsyY);
0144         emit paramChanged(-1, -1, -1, -1, -1, -1, -1, hsyS, hsyY);
0145         break;
0146     case KisColorSelectorConfiguration::LH:
0147         m_lastClickPos.setX(qBound<qreal>(0., hslH, 1.));
0148         m_lastClickPos.setY(1 - hslL);
0149         emit paramChanged(hslH, -1, -1, -1, hslL, -1, -1, -1, -1);
0150         break;
0151     case KisColorSelectorConfiguration::SV:
0152         m_lastClickPos.setX(hsvS);
0153         m_lastClickPos.setY(1 - hsvV);
0154         emit paramChanged(-1, hsvS, hsvV, -1, -1, -1, -1, -1, -1);
0155         break;
0156     case KisColorSelectorConfiguration::SV2: {
0157         qreal xRel = hsvS;
0158         qreal yRel = 0.5;
0159 
0160         if(xRel != 1.0)
0161             yRel = 1.0 - qBound<qreal>(0.0, (hsvV - xRel) / (1.0 - xRel), 1.0);
0162 
0163         m_lastClickPos.setX(xRel);
0164         m_lastClickPos.setY(yRel);
0165         emit paramChanged(-1, -1, -1, xRel, yRel, -1, -1, -1, -1);
0166         break;
0167     }
0168     case KisColorSelectorConfiguration::VH:
0169         m_lastClickPos.setX(qBound<qreal>(0., hsvH, 1.));
0170         m_lastClickPos.setY(1 - hsvV);
0171         emit paramChanged(hsvH, -1, hsvV, -1, -1, -1, -1, -1, -1);
0172         break;
0173     case KisColorSelectorConfiguration::IH:
0174         m_lastClickPos.setX(qBound<qreal>(0., hsiH, 1.));
0175         m_lastClickPos.setY(1 - hsiI);
0176         emit paramChanged(hsiH, -1, -1, -1, -1, -1, hsiI, -1, -1);
0177         break;
0178     case KisColorSelectorConfiguration::YH:
0179         m_lastClickPos.setX(qBound<qreal>(0., hsyH, 1.));
0180         m_lastClickPos.setY(1 - hsyY);
0181         emit paramChanged(hsyH, -1, -1, -1, -1, -1, -1, -1, hsyY);
0182         break;
0183     case KisColorSelectorConfiguration::hsvSH:
0184         m_lastClickPos.setX(qBound<qreal>(0., hsvH, 1.));
0185         m_lastClickPos.setY(1 - hsvS);
0186         emit paramChanged(hsvH, hsvS, -1, -1, -1, -1, -1, -1, -1);
0187         break;
0188     case KisColorSelectorConfiguration::hslSH:
0189         m_lastClickPos.setX(qBound<qreal>(0., hslH, 1.));
0190         m_lastClickPos.setY(1 - hslS);
0191         emit paramChanged(hslH, -1, -1, hslS, -1, -1, -1, -1, -1);
0192         break;
0193 
0194     case KisColorSelectorConfiguration::hsiSH:
0195         m_lastClickPos.setX(qBound<qreal>(0., hsiH, 1.));
0196         m_lastClickPos.setY(1 - hsiS);
0197         emit paramChanged(hsiH, -1, -1, hsiS, -1, -1, -1, -1, -1);
0198         break;
0199 
0200     case KisColorSelectorConfiguration::hsySH:
0201         m_lastClickPos.setX(qBound<qreal>(0., hsyH, 1.));
0202         m_lastClickPos.setY(1 - hsyS);
0203         emit paramChanged(hsyH, -1, -1, -1, -1, -1, -1, hsyS, -1);
0204         break;
0205     case KisColorSelectorConfiguration::L:
0206         m_lastClickPos.setX(qBound<qreal>(0., hslL, 1.));
0207         emit paramChanged(-1, -1, -1, -1, hslL, -1, -1, -1, -1);
0208         break;
0209     case KisColorSelectorConfiguration::I:
0210         m_lastClickPos.setX(qBound<qreal>(0., hsiI, 1.));
0211         emit paramChanged(-1, -1, -1, -1, -1, -1, hsiI, -1, -1);
0212         break;
0213     case KisColorSelectorConfiguration::V:
0214         m_lastClickPos.setX(hsvV);
0215         emit paramChanged(-1, -1, hsvV, -1, -1, -1, -1, -1, -1);
0216         break;
0217     case KisColorSelectorConfiguration::Y:
0218         m_lastClickPos.setX(qBound<qreal>(0., hsyY, 1.));
0219         emit paramChanged(-1, -1, -1, -1, -1, -1, -1, -1, hsyY);
0220         break;
0221     case KisColorSelectorConfiguration::hsvS:
0222         m_lastClickPos.setX( hsvS );
0223         emit paramChanged(-1, hsvS, -1, -1, -1, -1, -1, -1, -1);
0224         break;
0225     case KisColorSelectorConfiguration::hslS:
0226         m_lastClickPos.setX( hslS );
0227         emit paramChanged(-1, -1, -1, hslS, -1, -1, -1, -1, -1);
0228         break;
0229     case KisColorSelectorConfiguration::hsiS:
0230         m_lastClickPos.setX( hsiS );
0231         emit paramChanged(-1, -1, -1, -1, -1, hsiS, -1, -1, -1);
0232         break;
0233     case KisColorSelectorConfiguration::hsyS:
0234         m_lastClickPos.setX( hsyS );
0235         emit paramChanged(-1, -1, -1, -1, -1, -1, -1, hsyS, -1);
0236         break;
0237     case KisColorSelectorConfiguration::H:
0238         m_lastClickPos.setX(qBound<qreal>(0., hsvH, 1.));
0239         emit paramChanged(hsvH, -1, -1, -1, -1, -1, -1, -1, -1);
0240         break;
0241     case KisColorSelectorConfiguration::Hluma:
0242         m_lastClickPos.setX(qBound<qreal>(0., hsyH, 1.));
0243         emit paramChanged(hsyH, -1, -1, -1, -1, -1, -1, -1, -1);
0244         break;
0245     default:
0246         Q_ASSERT(false);
0247         break;
0248     }
0249     emit update();
0250     //Workaround for bug 317648
0251     setLastMousePosition((m_lastClickPos.x()*width()), (m_lastClickPos.y()*height()));
0252     KisColorSelectorComponent::setColor(color);
0253 }
0254 
0255 void KisColorSelectorSimple::paint(QPainter* painter)
0256 {
0257     if(isDirty()) {
0258         KisPaintDeviceSP realPixelCache;
0259         QPoint pixelCacheOffset;
0260         Acs::PixelCacheRenderer::render(this,
0261                                         m_parent->converter(),
0262                                         QRect(0, 0, width(), height()),
0263                                         realPixelCache,
0264                                         m_pixelCache,
0265                                         pixelCacheOffset,
0266                                         painter->device()->devicePixelRatioF());
0267 
0268 //        if (!pixelCacheOffset.isNull()) {
0269 //            warnKrita << "WARNING: offset of the rectangle selector is not null!";
0270 //        }
0271     }
0272 
0273     painter->drawImage(0,0, m_pixelCache);
0274 
0275     // draw blip
0276     if(m_lastClickPos!=QPointF(-1,-1) && m_parent->displayBlip()) {
0277         switch (m_parameter) {
0278         case KisColorSelectorConfiguration::H:
0279         case KisColorSelectorConfiguration::Hluma:
0280         case KisColorSelectorConfiguration::hsvS:
0281         case KisColorSelectorConfiguration::hslS:
0282         case KisColorSelectorConfiguration::hsiS:
0283         case KisColorSelectorConfiguration::hsyS:
0284         case KisColorSelectorConfiguration::V:
0285         case KisColorSelectorConfiguration::L:
0286         case KisColorSelectorConfiguration::I:
0287         case KisColorSelectorConfiguration::Y:
0288             if(width()>height()) {
0289                 painter->setPen(QColor(0,0,0));
0290                 painter->drawLine(m_lastClickPos.x()*width()-1, 0, m_lastClickPos.x()*width()-1, height());
0291                 painter->setPen(QColor(255,255,255));
0292                 painter->drawLine(m_lastClickPos.x()*width()+1, 0, m_lastClickPos.x()*width()+1, height());
0293             }
0294             else {
0295                 painter->setPen(QColor(0,0,0));
0296                 painter->drawLine(0, m_lastClickPos.x()*height()-1, width(), m_lastClickPos.x()*height()-1);
0297                 painter->setPen(QColor(255,255,255));
0298                 painter->drawLine(0, m_lastClickPos.x()*height()+1, width(), m_lastClickPos.x()*height()+1);
0299             }
0300             break;
0301         case KisColorSelectorConfiguration::SL:
0302         case KisColorSelectorConfiguration::SV:
0303         case KisColorSelectorConfiguration::SV2:
0304         case KisColorSelectorConfiguration::SI:
0305         case KisColorSelectorConfiguration::SY:
0306         case KisColorSelectorConfiguration::hslSH:
0307         case KisColorSelectorConfiguration::hsvSH:
0308         case KisColorSelectorConfiguration::hsiSH:
0309         case KisColorSelectorConfiguration::hsySH:
0310         case KisColorSelectorConfiguration::VH:
0311         case KisColorSelectorConfiguration::LH:
0312         case KisColorSelectorConfiguration::IH:
0313         case KisColorSelectorConfiguration::YH:
0314             painter->setPen(QColor(0,0,0));
0315             painter->drawEllipse(m_lastClickPos.x()*width()-5, m_lastClickPos.y()*height()-5, 10, 10);
0316             painter->setPen(QColor(255,255,255));
0317             painter->drawEllipse(m_lastClickPos.x()*width()-4, m_lastClickPos.y()*height()-4, 8, 8);
0318             break;
0319         }
0320 
0321     }
0322 }
0323 
0324 KoColor KisColorSelectorSimple::colorAt(float x, float y)
0325 {
0326     qreal xRel = x/qreal(width());
0327     qreal yRel = 1.-y/qreal(height());
0328     qreal relPos;
0329     if(height()>width())
0330         relPos = 1.-y/qreal(height());
0331     else
0332         relPos = x/qreal(width());
0333 
0334     KoColor color = KoColor::createTransparent(m_parent->colorSpace());
0335 
0336     switch(m_parameter) {
0337     case KisColorSelectorConfiguration::SL:
0338         color = m_parent->converter()->fromHslF(m_hue, xRel, yRel);
0339         break;
0340     case KisColorSelectorConfiguration::SV:
0341         color = m_parent->converter()->fromHsvF(m_hue, xRel, yRel);
0342         break;
0343     case KisColorSelectorConfiguration::SV2:
0344         color = m_parent->converter()->fromHsvF(m_hue, xRel, xRel + (1.0-xRel)*yRel);
0345         break;
0346     case KisColorSelectorConfiguration::SI:
0347         color = m_parent->converter()->fromHsiF(m_hue, xRel, yRel);
0348         break;
0349     case KisColorSelectorConfiguration::SY:
0350         color = m_parent->converter()->fromHsyF(m_hue, xRel, yRel, R, G, B, Gamma);
0351         break;
0352     case KisColorSelectorConfiguration::hsvSH:
0353         color = m_parent->converter()->fromHsvF(xRel, yRel, m_value);
0354         break;
0355     case KisColorSelectorConfiguration::hslSH:
0356         color = m_parent->converter()->fromHslF(xRel, yRel, m_lightness);
0357         break;
0358     case KisColorSelectorConfiguration::hsiSH:
0359         color = m_parent->converter()->fromHsiF(xRel, yRel, m_intensity);
0360         break;
0361     case KisColorSelectorConfiguration::hsySH:
0362         color = m_parent->converter()->fromHsyF(xRel, yRel, m_luma, R, G, B, Gamma);
0363         break;
0364     case KisColorSelectorConfiguration::VH:
0365         color = m_parent->converter()->fromHsvF(xRel, m_hsvSaturation, yRel);
0366         break;
0367     case KisColorSelectorConfiguration::LH:
0368         color = m_parent->converter()->fromHslF(xRel, m_hslSaturation, yRel);
0369         break;
0370     case KisColorSelectorConfiguration::IH:
0371         color = m_parent->converter()->fromHsiF(xRel, m_hsiSaturation, yRel);
0372         break;
0373     case KisColorSelectorConfiguration::YH:
0374         color = m_parent->converter()->fromHsyF(xRel, m_hsySaturation, yRel, R, G, B, Gamma);
0375         break;
0376     case KisColorSelectorConfiguration::H:
0377         color = m_parent->converter()->fromHsvF(relPos, 1, 1);
0378         break;
0379     case KisColorSelectorConfiguration::Hluma:
0380         color = m_parent->converter()->fromHsyF(relPos, 1, m_luma, R, G, B, Gamma);
0381         break;
0382     case KisColorSelectorConfiguration::hsvS:
0383         color = m_parent->converter()->fromHsvF(m_hue, relPos, m_value);
0384         break;
0385     case KisColorSelectorConfiguration::hslS:
0386         color = m_parent->converter()->fromHslF(m_hue, relPos, m_lightness);
0387         break;
0388     case KisColorSelectorConfiguration::V:
0389         color = m_parent->converter()->fromHsvF(m_hue, m_hsvSaturation, relPos);
0390         break;
0391     case KisColorSelectorConfiguration::L:
0392         color = m_parent->converter()->fromHslF(m_hue, m_hslSaturation, relPos);
0393         break;
0394     case KisColorSelectorConfiguration::hsiS:
0395         color = m_parent->converter()->fromHsiF(m_hue, relPos, m_intensity);
0396         break;
0397     case KisColorSelectorConfiguration::I:
0398         color = m_parent->converter()->fromHsiF(m_hue, m_hsiSaturation, relPos);
0399         break;
0400     case KisColorSelectorConfiguration::hsyS:
0401         color = m_parent->converter()->fromHsyF(m_hue, relPos, m_luma, R, G, B, Gamma);
0402         break;
0403     case KisColorSelectorConfiguration::Y:
0404         color = m_parent->converter()->fromHsyF(m_hue, m_hsySaturation, relPos, R, G, B, Gamma);
0405         break;
0406     default:
0407         Q_ASSERT(false);
0408 
0409         return color;
0410     }
0411 
0412     return color;
0413 }