1 /*
2  *  Copyright (c) 2011 Dmitry Kazakov <dimula73@gmail.com>
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18 
19 #ifndef __KIS_PAINTER_BASED_STROKE_STRATEGY_H
20 #define __KIS_PAINTER_BASED_STROKE_STRATEGY_H
21 
22 #include <QVector>
23 
24 #include "KisRunnableBasedStrokeStrategy.h"
25 #include "kis_resources_snapshot.h"
26 #include "kis_selection.h"
27 
28 class KisPainter;
29 class KisDistanceInformation;
30 class KisTransaction;
31 class KisFreehandStrokeInfo;
32 class KisMaskedFreehandStrokePainter;
33 class KisMaskingBrushRenderer;
34 class KisRunnableStrokeJobData;
35 
36 
37 class KRITAUI_EXPORT KisPainterBasedStrokeStrategy : public KisRunnableBasedStrokeStrategy
38 {
39 public:
40     KisPainterBasedStrokeStrategy(const QLatin1String &id,
41                                   const KUndo2MagicString &name,
42                                   KisResourcesSnapshotSP resources,
43                                   QVector<KisFreehandStrokeInfo*> strokeInfos, bool useMergeID = false);
44 
45     KisPainterBasedStrokeStrategy(const QLatin1String &id,
46                                   const KUndo2MagicString &name,
47                                   KisResourcesSnapshotSP resources,
48                                   KisFreehandStrokeInfo *strokeInfo, bool useMergeID = false);
49 
50     ~KisPainterBasedStrokeStrategy();
51 
52     void initStrokeCallback() override;
53     void finishStrokeCallback() override;
54     void cancelStrokeCallback() override;
55 
56     void suspendStrokeCallback() override;
57     void resumeStrokeCallback() override;
58 
59 protected:
60     KisNodeSP targetNode() const;
61     KisPaintDeviceSP targetDevice() const;
62     KisSelectionSP activeSelection() const;
63 
64     KisMaskedFreehandStrokePainter* maskedPainter(int strokeInfoId);
65     int numMaskedPainters() const;
66 
67     void setUndoEnabled(bool value);
68 
69     /**
70      * Return true if the descendant should execute a few more jobs before issuing setDirty()
71      * call on the layer.
72      *
73      * If the returned value is true, then the stroke actually paints **not** on the
74      * layer's paint device, but on some intermediate device owned by
75      * KisPainterBasedStrokeStrategy and one should merge it first before asking the
76      * update.
77      *
78      * The value can be true only when the stroke is declared to support masked brush!
79      * \see supportsMaskingBrush()
80      */
81     bool needsMaskingUpdates() const;
82 
83     /**
84      * Create a list of update jobs that should be run before issuing the setDirty()
85      * call on the node
86      *
87      * \see needsMaskingUpdates()
88      */
89     QVector<KisRunnableStrokeJobData*> doMaskingBrushUpdates(const QVector<QRect> &rects);
90 
91 protected:
92 
93     /**
94      * The descendants may declare if this stroke should support auto-creation
95      * of the masked brush. Default value: false
96      */
97     void setSupportsMaskingBrush(bool value);
98 
99     /**
100      * Return if the stroke should auto-create a masked brush from the provided
101      * paintop preset or not
102      */
103     bool supportsMaskingBrush() const;
104 
105     void setSupportsIndirectPainting(bool value);
106     bool supportsIndirectPainting() const;
107 
108 protected:
109     KisPainterBasedStrokeStrategy(const KisPainterBasedStrokeStrategy &rhs, int levelOfDetail);
110 
111 private:
112     void init();
113     void initPainters(KisPaintDeviceSP targetDevice, KisPaintDeviceSP maskingDevice,
114                       KisSelectionSP selection,
115                       bool hasIndirectPainting,
116                       const QString &indirectPaintingCompositeOp);
117     void deletePainters();
timedID(const QString & id)118     inline int timedID(const QString &id){
119         return int(qHash(id));
120     }
121 
122 private:
123     KisResourcesSnapshotSP m_resources;
124     QVector<KisFreehandStrokeInfo*> m_strokeInfos;
125     QVector<KisFreehandStrokeInfo*> m_maskStrokeInfos;
126     QVector<KisMaskedFreehandStrokePainter*> m_maskedPainters;
127 
128     KisTransaction *m_transaction;
129 
130     QScopedPointer<KisMaskingBrushRenderer> m_maskingBrushRenderer;
131 
132     KisPaintDeviceSP m_targetDevice;
133     KisSelectionSP m_activeSelection;
134     bool m_useMergeID;
135 
136     bool m_supportsMaskingBrush;
137     bool m_supportsIndirectPainting;
138 };
139 
140 #endif /* __KIS_PAINTER_BASED_STROKE_STRATEGY_H */
141