File indexing completed on 2024-12-22 04:12:56

0001 /*
0002  *  SPDX-FileCopyrightText: 2011 Dmitry Kazakov <dimula73@gmail.com>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #ifndef __FREEHAND_STROKE_H
0008 #define __FREEHAND_STROKE_H
0009 
0010 
0011 #include <QPen>
0012 #include "kritaui_export.h"
0013 #include "kis_types.h"
0014 #include "kis_node.h"
0015 #include "kis_painter_based_stroke_strategy.h"
0016 #include <kis_distance_information.h>
0017 #include <brushengine/kis_paint_information.h>
0018 #include "kis_lod_transform.h"
0019 #include "KoColor.h"
0020 
0021 
0022 
0023 class KRITAUI_EXPORT FreehandStrokeStrategy : public KisPainterBasedStrokeStrategy
0024 {
0025 public:
0026     enum Flag {
0027         None = 0x0,
0028         SupportsContinuedInterstrokeData = 0x1,
0029         SupportsTimedMergeId = 0x2
0030     };
0031     Q_DECLARE_FLAGS(Flags, Flag)
0032 
0033 public:
0034     class Data : public KisStrokeJobData {
0035     public:
0036         enum DabType {
0037             POINT,
0038             LINE,
0039             CURVE,
0040             POLYLINE,
0041             POLYGON,
0042             RECT,
0043             ELLIPSE,
0044             PAINTER_PATH,
0045             QPAINTER_PATH,
0046             QPAINTER_PATH_FILL
0047         };
0048 
0049         Data(int _strokeInfoId,
0050              const KisPaintInformation &_pi)
0051             : KisStrokeJobData(KisStrokeJobData::UNIQUELY_CONCURRENT),
0052               strokeInfoId(_strokeInfoId),
0053               type(POINT), pi1(_pi)
0054         {}
0055 
0056         Data(int _strokeInfoId,
0057              const KisPaintInformation &_pi1,
0058              const KisPaintInformation &_pi2)
0059             : KisStrokeJobData(KisStrokeJobData::UNIQUELY_CONCURRENT),
0060               strokeInfoId(_strokeInfoId),
0061               type(LINE), pi1(_pi1), pi2(_pi2)
0062         {}
0063 
0064         Data(int _strokeInfoId,
0065              const KisPaintInformation &_pi1,
0066              const QPointF &_control1,
0067              const QPointF &_control2,
0068              const KisPaintInformation &_pi2)
0069             : KisStrokeJobData(KisStrokeJobData::UNIQUELY_CONCURRENT),
0070               strokeInfoId(_strokeInfoId),
0071               type(CURVE), pi1(_pi1), pi2(_pi2),
0072               control1(_control1), control2(_control2)
0073         {}
0074 
0075         Data(int _strokeInfoId,
0076              DabType _type,
0077              const vQPointF &_points)
0078             : KisStrokeJobData(KisStrokeJobData::UNIQUELY_CONCURRENT),
0079               strokeInfoId(_strokeInfoId),
0080             type(_type), points(_points)
0081         {}
0082 
0083         Data(int _strokeInfoId,
0084              DabType _type,
0085              const QRectF &_rect)
0086             : KisStrokeJobData(KisStrokeJobData::UNIQUELY_CONCURRENT),
0087               strokeInfoId(_strokeInfoId),
0088             type(_type), rect(_rect)
0089         {}
0090 
0091         Data(int _strokeInfoId,
0092              DabType _type,
0093              const QPainterPath &_path)
0094             : KisStrokeJobData(KisStrokeJobData::UNIQUELY_CONCURRENT),
0095               strokeInfoId(_strokeInfoId),
0096             type(_type), path(_path)
0097         {}
0098 
0099         Data(int _strokeInfoId,
0100              DabType _type,
0101              const QPainterPath &_path,
0102              const QPen &_pen, const KoColor &_customColor)
0103             : KisStrokeJobData(KisStrokeJobData::UNIQUELY_CONCURRENT),
0104               strokeInfoId(_strokeInfoId),
0105             type(_type), path(_path),
0106             pen(_pen), customColor(_customColor)
0107         {}
0108 
0109         KisStrokeJobData* createLodClone(int levelOfDetail) override {
0110             return new Data(*this, levelOfDetail);
0111         }
0112 
0113     private:
0114         Data(const Data &rhs, int levelOfDetail)
0115             : KisStrokeJobData(rhs),
0116               strokeInfoId(rhs.strokeInfoId),
0117               type(rhs.type)
0118         {
0119             KisLodTransform t(levelOfDetail);
0120 
0121             switch(type) {
0122             case Data::POINT:
0123                 pi1 = t.map(rhs.pi1);
0124                 break;
0125             case Data::LINE:
0126                 pi1 = t.map(rhs.pi1);
0127                 pi2 = t.map(rhs.pi2);
0128                 break;
0129             case Data::CURVE:
0130                 pi1 = t.map(rhs.pi1);
0131                 pi2 = t.map(rhs.pi2);
0132                 control1 = t.map(rhs.control1);
0133                 control2 = t.map(rhs.control2);
0134                 break;
0135             case Data::POLYLINE:
0136                 points = t.map(rhs.points);
0137                 break;
0138             case Data::POLYGON:
0139                 points = t.map(rhs.points);
0140                 break;
0141             case Data::RECT:
0142                 rect = t.map(rhs.rect);
0143                 break;
0144             case Data::ELLIPSE:
0145                 rect = t.map(rhs.rect);
0146                 break;
0147             case Data::PAINTER_PATH:
0148                 path = t.map(rhs.path);
0149                 break;
0150             case Data::QPAINTER_PATH:
0151                 path = t.map(rhs.path);
0152                 pen = rhs.pen;
0153                 break;
0154             case Data::QPAINTER_PATH_FILL:
0155                 path = t.map(rhs.path);
0156                 pen = rhs.pen;
0157                 customColor = rhs.customColor;
0158                 break;
0159             };
0160         }
0161     public:
0162         int strokeInfoId;
0163 
0164         DabType type;
0165         KisPaintInformation pi1;
0166         KisPaintInformation pi2;
0167         QPointF control1;
0168         QPointF control2;
0169 
0170         vQPointF points;
0171         QRectF rect;
0172         QPainterPath path;
0173         QPen pen;
0174         KoColor customColor;
0175     };
0176 
0177 public:
0178     FreehandStrokeStrategy(KisResourcesSnapshotSP resources,
0179                            KisFreehandStrokeInfo *strokeInfo,
0180                            const KUndo2MagicString &name,
0181                            Flags flags = None);
0182 
0183     FreehandStrokeStrategy(KisResourcesSnapshotSP resources,
0184                            QVector<KisFreehandStrokeInfo*> strokeInfos,
0185                            const KUndo2MagicString &name,
0186                            Flags flags = None);
0187 
0188     ~FreehandStrokeStrategy() override;
0189 
0190     void initStrokeCallback() override;
0191     void finishStrokeCallback() override;
0192 
0193     void doStrokeCallback(KisStrokeJobData *data) override;
0194 
0195     KisStrokeStrategy* createLodClone(int levelOfDetail) override;
0196 
0197     void notifyUserStartedStroke() override;
0198     void notifyUserEndedStroke() override;
0199 
0200 protected:
0201     FreehandStrokeStrategy(const FreehandStrokeStrategy &rhs, int levelOfDetail);
0202 
0203 private:
0204     void init(FreehandStrokeStrategy::Flags flags);
0205 
0206     void tryDoUpdate(bool forceEnd = false);
0207     void issueSetDirtySignals();
0208 
0209 private:
0210     struct Private;
0211     const QScopedPointer<Private> m_d;
0212 };
0213 
0214 Q_DECLARE_OPERATORS_FOR_FLAGS(FreehandStrokeStrategy::Flags)
0215 
0216 #endif /* __FREEHAND_STROKE_H */