File indexing completed on 2024-12-22 04:11:45

0001 /*
0002     SPDX-FileCopyrightText: 2007 Sven Langkamp <sven.langkamp@gmail.com>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-or-later
0005  */
0006 #ifndef KOSTOPGRADIENT_H
0007 #define KOSTOPGRADIENT_H
0008 
0009 #include <QPair>
0010 #include <QGradient>
0011 #include <QtAlgorithms>
0012 
0013 #include "KoColor.h"
0014 #include <resources/KoAbstractGradient.h>
0015 #include <KoResource.h>
0016 #include <kritapigment_export.h>
0017 #include <boost/operators.hpp>
0018 
0019 enum KoGradientStopType 
0020 {
0021     COLORSTOP,
0022     FOREGROUNDSTOP,
0023     BACKGROUNDSTOP
0024 };
0025 
0026 struct KoGradientStop : public boost::equality_comparable<KoGradientStop>
0027 {
0028     KoGradientStopType type;
0029     KoColor color;
0030     qreal position;
0031 
0032     KoGradientStop(qreal _position = 0.0, KoColor _color = KoColor(), KoGradientStopType _type = COLORSTOP) 
0033     {
0034         type = _type;
0035         color = _color;
0036         position = _position;
0037     }
0038 
0039     bool operator == (const KoGradientStop& other) 
0040     { 
0041         return this->type == other.type && this->color == other.color && this->position == other.position;
0042     }
0043 
0044 
0045 
0046     QString typeString() const 
0047     {
0048         switch (type) {
0049         case COLORSTOP:
0050             return "color-stop";
0051         case FOREGROUNDSTOP:
0052             return "foreground-stop";
0053         case BACKGROUNDSTOP:
0054             return "background-stop";
0055         default:
0056             return "color-stop";
0057         }
0058     }
0059 
0060     static KoGradientStopType typeFromString(QString typestring) {
0061         if (typestring == "foreground-stop") {
0062             return FOREGROUNDSTOP;
0063         } else if (typestring == "background-stop") {
0064             return BACKGROUNDSTOP;
0065         } else {
0066             return COLORSTOP;
0067         }
0068     }
0069 };
0070 
0071 
0072 struct KoGradientStopValueSort
0073 {
0074     inline bool operator() (const KoGradientStop& a, const KoGradientStop& b) {
0075         return (a.color.toQColor().valueF() < b.color.toQColor().valueF());
0076     }
0077 };
0078 
0079 struct KoGradientStopHueSort
0080 {
0081     inline bool operator() (const KoGradientStop& a, const KoGradientStop& b) {
0082         return (a.color.toQColor().hueF() < b.color.toQColor().hueF());
0083     }
0084 };
0085 
0086 /**
0087  * Resource for colorstop based gradients like SVG gradients
0088  */
0089 class KRITAPIGMENT_EXPORT KoStopGradient : public KoAbstractGradient, public boost::equality_comparable<KoStopGradient>
0090 {
0091 
0092 public:
0093     
0094     explicit KoStopGradient(const QString &filename = QString());
0095     ~KoStopGradient() override;
0096     KoStopGradient(const KoStopGradient &rhs);
0097     bool operator==(const KoStopGradient &rhs) const;
0098     KoStopGradient &operator=(const KoStopGradient &rhs) = delete;
0099     KoResourceSP clone() const override;
0100 
0101     bool loadFromDevice(QIODevice *dev, KisResourcesInterfaceSP resourcesInterface) override;
0102     bool saveToDevice(QIODevice* dev) const override;
0103 
0104     QPair<QString, QString> resourceType() const override {
0105         return QPair<QString, QString>(ResourceType::Gradients, ResourceSubType::StopGradients);
0106     }
0107 
0108     /// reimplemented
0109     QGradient* toQGradient() const override;
0110 
0111     /// Find stops surrounding position, returns false if position outside gradient
0112     bool stopsAt(KoGradientStop& leftStop, KoGradientStop& rightStop, qreal t) const;
0113 
0114     /// reimplemented
0115     void colorAt(KoColor&, qreal t) const override;
0116 
0117     /// Creates KoStopGradient from a QGradient
0118     static QSharedPointer<KoStopGradient> fromQGradient(const QGradient *gradient);
0119 
0120     /// Sets the gradient stops
0121     void setStops(QList<KoGradientStop> stops);
0122     QList<KoGradientStop> stops() const;    
0123 
0124     QList<int> requiredCanvasResources() const override;
0125     void bakeVariableColors(KoCanvasResourcesInterfaceSP canvasResourcesInterface) override;
0126     void updateVariableColors(KoCanvasResourcesInterfaceSP canvasResourcesInterface) override;
0127 
0128 
0129     /// reimplemented
0130     QString defaultFileExtension() const override;
0131 
0132     /**
0133      * @brief toXML
0134      * Convert the gradient to an XML string.
0135      */
0136     void toXML(QDomDocument& doc, QDomElement& gradientElt) const;
0137     /**
0138      * @brief fromXML
0139      * convert a gradient from xml.
0140      * @return a gradient.
0141      */
0142     static KoStopGradient fromXML(const QDomElement& elt);
0143 
0144     QString saveSvgGradient() const;
0145 
0146 protected:
0147 
0148     QList<KoGradientStop> m_stops;
0149     bool m_hasVariableStops = false;
0150     QPointF m_start;
0151     QPointF m_stop;
0152     QPointF m_focalPoint;
0153 
0154 private:
0155 
0156     void loadSvgGradient(QIODevice *file);
0157     void parseSvgGradient(const QDomElement& element, QHash<QString, const KoColorProfile*> profiles);
0158 };
0159 
0160 typedef QSharedPointer<KoStopGradient> KoStopGradientSP;
0161 
0162 #endif // KOSTOPGRADIENT_H
0163