File indexing completed on 2024-05-26 04:33:04

0001 /*
0002  * This file is part of Krita
0003  *
0004  * SPDX-FileCopyrightText: 2018 Jouni Pentikainen <joupent@gmail.com>
0005  * SPDX-FileCopyrightText: 2020 L. E. Segovia <amy@amyspark.me>
0006  *
0007  *  SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 
0010 #ifndef _KIS_MULTICHANNEL_FILTER_BASE_H_
0011 #define _KIS_MULTICHANNEL_FILTER_BASE_H_
0012 
0013 #include <QPair>
0014 #include <QList>
0015 
0016 #include <filter/kis_color_transformation_filter.h>
0017 #include <filter/kis_color_transformation_configuration.h>
0018 #include <kis_config_widget.h>
0019 #include <kis_paint_device.h>
0020 #include "ui_wdg_perchannel.h"
0021 
0022 #include "virtual_channel_info.h"
0023 
0024 /**
0025  * Base class for filters which use curves to operate on multiple channels.
0026  */
0027 class KisMultiChannelFilter : public KisColorTransformationFilter
0028 {
0029 public:
0030     bool needsTransparentPixels(const KisFilterConfigurationSP config, const KoColorSpace *cs) const override;
0031 
0032     /**
0033      * Get a list of adjustable channels for the color space.
0034      * If maxChannels is non-negative, the number of channels is capped to the number. This is useful configurations
0035      * from older documents (created in versions which supported fewer channels).
0036      */
0037     static QVector<VirtualChannelInfo> getVirtualChannels(const KoColorSpace *cs, int maxChannels = -1);
0038     static int findChannel(const QVector<VirtualChannelInfo> &virtualChannels, const VirtualChannelInfo::Type &channelType);
0039 
0040 protected:
0041     KisMultiChannelFilter(const KoID &id, const QString &entry);
0042 };
0043 
0044 /**
0045  * Base class for configurations of KisMultiChannelFilter subclasses
0046  */
0047 class KisMultiChannelFilterConfiguration : public KisColorTransformationConfiguration
0048 {
0049 public:
0050     KisMultiChannelFilterConfiguration(int channelCount, const QString & name, qint32 version, KisResourcesInterfaceSP resourcesInterface);
0051     KisMultiChannelFilterConfiguration(const KisMultiChannelFilterConfiguration &rhs);
0052     ~KisMultiChannelFilterConfiguration() override;
0053 
0054     using KisFilterConfiguration::fromXML;
0055     using KisFilterConfiguration::toXML;
0056     using KisFilterConfiguration::fromLegacyXML;
0057 
0058     void fromLegacyXML(const QDomElement& root) override;
0059 
0060     void fromXML(const QDomElement& e) override;
0061     void toXML(QDomDocument& doc, QDomElement& root) const override;
0062 
0063     void setCurves(QList<KisCubicCurve> &curves) override;
0064     bool isCompatible(const KisPaintDeviceSP) const override;
0065 
0066     const QVector<QVector<quint16> >& transfers() const;
0067     const QList<KisCubicCurve>& curves() const override;
0068 
0069     virtual bool compareTo(const KisPropertiesConfiguration* rhs) const override;
0070 
0071     bool hasProperty(const QString& name) const override;
0072     void setProperty(const QString& name, const QVariant& value) override;
0073     bool getProperty(const QString& name, QVariant & value) const override;
0074     QVariant getProperty(const QString& name) const override;
0075     QMap<QString, QVariant> getProperties() const override;
0076 
0077 protected:
0078     int m_channelCount {0};
0079     QList<KisCubicCurve> m_curves;
0080     QVector<QVector<quint16>> m_transfers;
0081 
0082     void init();
0083     void updateTransfer(int index);
0084     void updateTransfers();
0085 
0086     virtual KisCubicCurve getDefaultCurve() = 0;
0087 
0088     /**
0089      * @brief Takes a curve property name with format "curve#", where # is the
0090      *        index of the channel and puts the index on the "curveIndex"
0091      *        parameter
0092      * @param name A string with format "curve#"
0093      * @param curveIndex An int where the decoded channel index is stored
0094      * @return true if "name" had a valid format
0095      * @return false if "name" had an invalid format
0096      */
0097     bool curveIndexFromCurvePropertyName(const QString& name, int& curveIndex) const;
0098 };
0099 
0100 class WdgPerChannel : public QWidget, public Ui::WdgPerChannel
0101 {
0102     Q_OBJECT
0103 
0104 public:
0105     WdgPerChannel(QWidget *parent) : QWidget(parent) {
0106         setupUi(this);
0107     }
0108 };
0109 
0110 /**
0111  * Base class for configuration widgets of KisMultiChannelFilter subclasses
0112  */
0113 class KisMultiChannelConfigWidget : public KisConfigWidget
0114 {
0115     Q_OBJECT
0116 
0117 public:
0118     KisMultiChannelConfigWidget(QWidget * parent, KisPaintDeviceSP dev, Qt::WindowFlags f = Qt::WindowFlags());
0119     ~KisMultiChannelConfigWidget() override;
0120 
0121     void setConfiguration(const KisPropertiesConfigurationSP config) override;
0122 
0123 protected Q_SLOTS:
0124     void logHistView();
0125     void resetCurve();
0126     void slotChannelSelected(int index);
0127 
0128 protected:
0129     void init();
0130     void resetCurves();
0131     void setActiveChannel(int ch);
0132 
0133     virtual void updateChannelControls() = 0;
0134     virtual KisPropertiesConfigurationSP getDefaultConfiguration() = 0;
0135 
0136     inline QPixmap getHistogram();
0137     inline QPixmap createGradient(Qt::Orientation orient /*, int invert (not used now) */);
0138 
0139     QVector<VirtualChannelInfo> m_virtualChannels;
0140     int m_activeVChannel {0};
0141     mutable QList<KisCubicCurve> m_curves;
0142 
0143     KisPaintDeviceSP m_dev;
0144     WdgPerChannel * m_page {nullptr};
0145     KisHistogram *m_histogram {nullptr};
0146 };
0147 
0148 #endif