File indexing completed on 2024-05-12 15:58:49

0001 /*
0002  *  SPDX-FileCopyrightText: 2020 Dmitry Kazakov <dimula73@gmail.com>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #ifndef KISBEZIERGRADIENTMESH_H
0008 #define KISBEZIERGRADIENTMESH_H
0009 
0010 #include "kritaimage_export.h"
0011 #include <KisBezierMesh.h>
0012 
0013 #include <QColor>
0014 
0015 namespace KisBezierGradientMeshDetail {
0016 
0017 inline QColor lerp(const QColor &c1, const QColor &c2, qreal t) {
0018     using KisAlgebra2D::lerp;
0019 
0020     return QColor::fromRgbF(lerp(c1.redF(), c2.redF(), t),
0021                             lerp(c1.greenF(), c2.greenF(), t),
0022                             lerp(c1.blueF(), c2.blueF(), t),
0023                             lerp(c1.alphaF(), c2.alphaF(), t));
0024 }
0025 
0026 struct GradientMeshPatch : public KisBezierPatch {
0027     std::array<QColor, 4> colors;
0028 };
0029 
0030 struct GradientMeshNode : public KisBezierMeshDetails::BaseMeshNode, public boost::equality_comparable<GradientMeshNode>
0031 {
0032     using BaseMeshNode::BaseMeshNode;
0033     QColor color;
0034 
0035     bool operator==(const GradientMeshNode &rhs) const {
0036         return static_cast<const KisBezierMeshDetails::BaseMeshNode&>(*this) ==
0037                 static_cast<const KisBezierMeshDetails::BaseMeshNode&>(rhs) &&
0038                 color == rhs.color;
0039     }
0040 };
0041 
0042 inline void lerpNodeData(const GradientMeshNode &left, const GradientMeshNode &right, qreal t, GradientMeshNode &dst)
0043 {
0044     dst.color = lerp(left.color, right.color, t);
0045 }
0046 
0047 inline void assignPatchData(GradientMeshPatch *patch,
0048                      const QRectF &srcRect,
0049                      const GradientMeshNode &tl,
0050                      const GradientMeshNode &tr,
0051                      const GradientMeshNode &bl,
0052                      const GradientMeshNode &br)
0053 {
0054     Q_UNUSED(srcRect);
0055 
0056     patch->originalRect = QRectF(0.0, 0.0, 1.0, 1.0);
0057     patch->colors[0] = tl.color;
0058     patch->colors[1] = tr.color;
0059     patch->colors[2] = bl.color;
0060     patch->colors[3] = br.color;
0061 }
0062 
0063 class KRITAIMAGE_EXPORT KisBezierGradientMesh : public KisBezierMeshBase<GradientMeshNode, GradientMeshPatch>
0064 {
0065 public:
0066 
0067     PatchIndex hitTestPatch(const QPointF &pt, QPointF *localPointResult) const;
0068 
0069     static void renderPatch(const GradientMeshPatch &patch,
0070                      const QPoint &dstQImageOffset,
0071                      QImage *dstImage);
0072 
0073     void renderMesh(const QPoint &dstQImageOffset,
0074                     QImage *dstImage) const;
0075 
0076     friend KRITAIMAGE_EXPORT void saveValue(QDomElement *parent, const QString &tag, const KisBezierGradientMesh &mesh);
0077     friend KRITAIMAGE_EXPORT bool loadValue(const QDomElement &parent, const QString &tag, KisBezierGradientMesh *mesh);
0078 };
0079 
0080 KRITAIMAGE_EXPORT
0081 void saveValue(QDomElement *parent, const QString &tag, const GradientMeshNode &node);
0082 
0083 KRITAIMAGE_EXPORT
0084 bool loadValue(const QDomElement &parent, GradientMeshNode *node);
0085 
0086 KRITAIMAGE_EXPORT
0087 void saveValue(QDomElement *parent, const QString &tag, const KisBezierGradientMesh &mesh);
0088 
0089 KRITAIMAGE_EXPORT
0090 bool loadValue(const QDomElement &parent, const QString &tag, KisBezierGradientMesh *mesh);
0091 }
0092 
0093 namespace KisDomUtils {
0094 using KisBezierGradientMeshDetail::loadValue;
0095 using KisBezierGradientMeshDetail::saveValue;
0096 }
0097 
0098 using KisBezierGradientMesh = KisBezierGradientMeshDetail::KisBezierGradientMesh;
0099 
0100 #endif // KISBEZIERGRADIENTMESH_H