File indexing completed on 2024-05-19 04:24:17

0001 /*
0002  *  SPDX-FileCopyrightText: 2022 Dmitry Kazakov <dimula73@gmail.com>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #ifndef KISBRUSHMODEL_H
0008 #define KISBRUSHMODEL_H
0009 
0010 #include <QtGlobal>
0011 #include <QSize>
0012 #include <QGuiApplication>
0013 #include <QFont>
0014 #include <KoResourceSignature.h>
0015 #include <lager/cursor.hpp>
0016 #include <lager/extra/qt.hpp>
0017 #include <boost/operators.hpp>
0018 #include <optional>
0019 
0020 #include "kis_paintop_settings.h"
0021 
0022 #include "kritabrush_export.h"
0023 
0024 // TODO: move enumBrushApplication into a separate file
0025 #include <kis_brush.h>
0026 
0027 namespace KisBrushModel {
0028 struct BRUSH_EXPORT CommonData : public boost::equality_comparable<CommonData>
0029 {
0030     inline friend bool operator==(const CommonData &lhs, const CommonData &rhs) {
0031         return qFuzzyCompare(lhs.angle, rhs.angle) &&
0032                 qFuzzyCompare(lhs.spacing, rhs.spacing) &&
0033                 lhs.useAutoSpacing == rhs.useAutoSpacing &&
0034                 qFuzzyCompare(lhs.autoSpacingCoeff, rhs.autoSpacingCoeff);
0035     }
0036 
0037     qreal angle = 0.0;
0038     qreal spacing = 0.05;
0039     bool useAutoSpacing = false;
0040     qreal autoSpacingCoeff = 1.0;
0041 
0042     // TODO: preview image
0043 };
0044 
0045 enum AutoBrushGeneratorShape {
0046     Circle = 0,
0047     Rectangle
0048 };
0049 
0050 enum AutoBrushGeneratorType {
0051     Default = 0,
0052     Soft,
0053     Gaussian
0054 };
0055 
0056 struct BRUSH_EXPORT AutoBrushGeneratorData : public boost::equality_comparable<AutoBrushGeneratorData>
0057 {
0058     inline friend bool operator==(const AutoBrushGeneratorData &lhs, const AutoBrushGeneratorData &rhs) {
0059         return qFuzzyCompare(lhs.diameter, rhs.diameter) &&
0060                 qFuzzyCompare(lhs.ratio, rhs.ratio) &&
0061                 qFuzzyCompare(lhs.horizontalFade, rhs.horizontalFade) &&
0062                 qFuzzyCompare(lhs.verticalFade, rhs.verticalFade) &&
0063                 lhs.spikes == rhs.spikes &&
0064                 lhs.antialiasEdges == rhs.antialiasEdges &&
0065                 lhs.shape == rhs.shape &&
0066                 lhs.type == rhs.type &&
0067                 lhs.curveString == rhs.curveString;
0068     }
0069 
0070     qreal diameter = 42.0;
0071     qreal ratio = 1.0;
0072     qreal horizontalFade = 1.0;
0073     qreal verticalFade = 1.0;
0074     int spikes = 2;
0075     bool antialiasEdges = true;
0076     AutoBrushGeneratorShape shape = Circle;
0077     AutoBrushGeneratorType type = Default;
0078     QString curveString;
0079 };
0080 
0081 struct BRUSH_EXPORT AutoBrushData : public boost::equality_comparable<AutoBrushData>
0082 {
0083     inline friend bool operator==(const AutoBrushData &lhs, const AutoBrushData &rhs) {
0084         return qFuzzyCompare(lhs.randomness, rhs.randomness) &&
0085                 qFuzzyCompare(lhs.density, rhs.density) &&
0086                 lhs.generator == rhs.generator;
0087     }
0088 
0089     qreal randomness = 0.0;
0090     qreal density = 1.0;
0091     AutoBrushGeneratorData generator;
0092 };
0093 
0094 struct BRUSH_EXPORT PredefinedBrushData : public boost::equality_comparable<PredefinedBrushData>
0095 {
0096     inline friend bool operator==(const PredefinedBrushData &lhs, const PredefinedBrushData &rhs) {
0097         return lhs.resourceSignature == rhs.resourceSignature &&
0098                 lhs.subtype == rhs.subtype &&
0099                 lhs.baseSize == rhs.baseSize &&
0100                 qFuzzyCompare(lhs.scale, rhs.scale) &&
0101                 lhs.application == rhs.application &&
0102                 lhs.brushType == rhs.brushType &&
0103                 lhs.hasColorAndTransparency == rhs.hasColorAndTransparency &&
0104                 lhs.autoAdjustMidPoint == rhs.autoAdjustMidPoint &&
0105                 lhs.adjustmentMidPoint == rhs.adjustmentMidPoint &&
0106                 qFuzzyCompare(lhs.brightnessAdjustment, rhs.brightnessAdjustment) &&
0107                 qFuzzyCompare(lhs.contrastAdjustment, rhs.contrastAdjustment) &&
0108                 lhs.parasiteSelection == rhs.parasiteSelection;
0109     }
0110 
0111     KoResourceSignature resourceSignature;
0112 
0113     QString subtype;
0114     QSize baseSize = QSize(42, 42);
0115     qreal scale = 1.0;
0116     enumBrushApplication application = ALPHAMASK;
0117     enumBrushType brushType = MASK;
0118     bool hasColorAndTransparency = false;
0119     bool autoAdjustMidPoint = true;
0120     quint8 adjustmentMidPoint = 127;
0121     qreal brightnessAdjustment = 0.0;
0122     qreal contrastAdjustment = 0.0;
0123     QString parasiteSelection;
0124 };
0125 
0126 struct BRUSH_EXPORT TextBrushData : boost::equality_comparable<TextBrushData>
0127 {
0128     inline friend bool operator==(const TextBrushData &lhs, const TextBrushData &rhs) {
0129         return lhs.baseSize == rhs.baseSize &&
0130                 qFuzzyCompare(lhs.scale, rhs.scale) &&
0131                 lhs.text == rhs.text &&
0132                 lhs.font == rhs.font &&
0133                 lhs.usePipeMode == rhs.usePipeMode;
0134     }
0135 
0136     QSize baseSize = QSize(42, 42);
0137     qreal scale = 1.0;
0138     QString text = "The quick brown fox ate your text";
0139     QString font = QGuiApplication::font().toString();
0140     bool usePipeMode = false;
0141 };
0142 
0143 enum BrushType {
0144     Auto = 0,
0145     Predefined,
0146     Text
0147 };
0148 
0149 struct BRUSH_EXPORT BrushData : public boost::equality_comparable<BrushData> {
0150     inline friend bool operator==(const BrushData &lhs, const BrushData &rhs) {
0151         return lhs.common == rhs.common &&
0152                 lhs.type == rhs.type &&
0153                 lhs.autoBrush == rhs.autoBrush &&
0154                 lhs.predefinedBrush == rhs.predefinedBrush &&
0155                 lhs.textBrush == rhs.textBrush;
0156     }
0157 
0158     /**
0159      * We don't use std::variant here because we want
0160      * to keep user's settings when he/she switches
0161      * from one type of the brush to another.
0162      */
0163 
0164     CommonData common;
0165     BrushType type = Auto;
0166     AutoBrushData autoBrush;
0167     PredefinedBrushData predefinedBrush;
0168     TextBrushData textBrush;
0169 
0170     void write(KisPropertiesConfiguration *settings) const;
0171     static std::optional<BrushData> read(const KisPropertiesConfiguration *settings, KisResourcesInterfaceSP resourcesInterface);
0172 };
0173 
0174 
0175 KisPaintopLodLimitations BRUSH_EXPORT brushLodLimitations(const BrushData &data);
0176 qreal BRUSH_EXPORT effectiveSizeForBrush(BrushType type,
0177                                          const AutoBrushData &autoBrush,
0178                                          const PredefinedBrushData &predefinedBrush,
0179                                          const TextBrushData &textBrush);
0180 qreal BRUSH_EXPORT effectiveSizeForBrush(const BrushData &brush);
0181 
0182 
0183 void BRUSH_EXPORT setEffectiveSizeForBrush(const BrushType type,
0184                                            AutoBrushData &autoBrush,
0185                                            PredefinedBrushData &predefinedBrush,
0186                                            TextBrushData &textBrush,
0187                                            qreal value);
0188 
0189 qreal BRUSH_EXPORT lightnessModeActivated(BrushType type,
0190                                           const PredefinedBrushData &predefinedBrush);
0191 
0192 }
0193 
0194 #endif // KISBRUSHMODEL_H