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 __KIS_PAINTER_BASED_STROKE_STRATEGY_H
0008 #define __KIS_PAINTER_BASED_STROKE_STRATEGY_H
0009 
0010 #include <QVector>
0011 
0012 #include "KisRunnableBasedStrokeStrategy.h"
0013 #include "kis_resources_snapshot.h"
0014 #include "kis_selection.h"
0015 #include "kis_indirect_painting_support.h"
0016 
0017 class KisPainter;
0018 class KisDistanceInformation;
0019 class KisTransaction;
0020 class KisFreehandStrokeInfo;
0021 class KisMaskedFreehandStrokePainter;
0022 class KisMaskingBrushRenderer;
0023 class KisRunnableStrokeJobData;
0024 class KisUndoStore;
0025 
0026 class KRITAUI_EXPORT KisPainterBasedStrokeStrategy : public KisRunnableBasedStrokeStrategy
0027 {
0028 public:
0029     KisPainterBasedStrokeStrategy(const QLatin1String &id,
0030                                   const KUndo2MagicString &name,
0031                                   KisResourcesSnapshotSP resources,
0032                                   QVector<KisFreehandStrokeInfo*> strokeInfos);
0033 
0034     KisPainterBasedStrokeStrategy(const QLatin1String &id,
0035                                   const KUndo2MagicString &name,
0036                                   KisResourcesSnapshotSP resources,
0037                                   KisFreehandStrokeInfo *strokeInfo);
0038 
0039     ~KisPainterBasedStrokeStrategy();
0040 
0041     void initStrokeCallback() override;
0042     void finishStrokeCallback() override;
0043     void cancelStrokeCallback() override;
0044 
0045     void suspendStrokeCallback() override;
0046     void resumeStrokeCallback() override;
0047 
0048 protected:
0049     KisNodeSP targetNode() const;
0050     KisPaintDeviceSP targetDevice() const;
0051     KisSelectionSP activeSelection() const;
0052 
0053     KisMaskedFreehandStrokePainter* maskedPainter(int strokeInfoId);
0054     int numMaskedPainters() const;
0055 
0056     void setUndoEnabled(bool value);
0057 
0058     /**
0059      * Return true if the descendant should execute a few more jobs before issuing setDirty()
0060      * call on the layer.
0061      *
0062      * If the returned value is true, then the stroke actually paints **not** on the
0063      * layer's paint device, but on some intermediate device owned by
0064      * KisPainterBasedStrokeStrategy and one should merge it first before asking the
0065      * update.
0066      *
0067      * The value can be true only when the stroke is declared to support masked brush!
0068      * \see supportsMaskingBrush()
0069      */
0070     bool needsMaskingUpdates() const;
0071 
0072     /**
0073      * Create a list of update jobs that should be run before issuing the setDirty()
0074      * call on the node
0075      *
0076      * \see needsMaskingUpdates()
0077      */
0078     QVector<KisRunnableStrokeJobData*> doMaskingBrushUpdates(const QVector<QRect> &rects);
0079 
0080 protected:
0081 
0082     /**
0083      * The descendants may declare if this stroke should support auto-creation
0084      * of the masked brush. Default value: false
0085      */
0086     void setSupportsMaskingBrush(bool value);
0087 
0088     /**
0089      * Return if the stroke should auto-create a masked brush from the provided
0090      * paintop preset or not
0091      */
0092     bool supportsMaskingBrush() const;
0093 
0094     void setSupportsIndirectPainting(bool value);
0095     bool supportsIndirectPainting() const;
0096 
0097     bool supportsContinuedInterstrokeData() const;
0098     void setSupportsContinuedInterstrokeData(bool value);
0099 
0100     bool supportsTimedMergeId() const;
0101     void setSupportsTimedMergeId(bool value);
0102 
0103 protected:
0104     KisPainterBasedStrokeStrategy(const KisPainterBasedStrokeStrategy &rhs, int levelOfDetail);
0105 
0106 private:
0107     void init();
0108     void initPainters(KisPaintDeviceSP targetDevice, KisPaintDeviceSP maskingDevice,
0109                       KisSelectionSP selection,
0110                       bool hasIndirectPainting,
0111                       const QString &indirectPaintingCompositeOp);
0112     void deletePainters();
0113     inline int timedID(const QString &id){
0114         return int(qHash(id));
0115     }
0116 
0117 private:
0118     KisResourcesSnapshotSP m_resources;
0119     QVector<KisFreehandStrokeInfo*> m_strokeInfos;
0120     QVector<KisFreehandStrokeInfo*> m_maskStrokeInfos;
0121     QVector<KisMaskedFreehandStrokePainter*> m_maskedPainters;
0122 
0123     QScopedPointer<KisTransaction> m_transaction;
0124 
0125     QScopedPointer<KisMaskingBrushRenderer> m_maskingBrushRenderer;
0126 
0127     KisPaintDeviceSP m_targetDevice;
0128     KisSelectionSP m_activeSelection;
0129 
0130     QScopedPointer<KUndo2Command> m_autokeyCommand;
0131 
0132     bool m_useMergeID {false};
0133 
0134     bool m_supportsMaskingBrush {false};
0135     bool m_supportsIndirectPainting {false};
0136     bool m_supportsContinuedInterstrokeData {false};
0137 
0138     KisIndirectPaintingSupport::FinalMergeSuspenderSP m_finalMergeSuspender;
0139 
0140     struct FakeUndoData {
0141         FakeUndoData();
0142         ~FakeUndoData();
0143         QScopedPointer<KisUndoStore> undoStore;
0144         QScopedPointer<KisPostExecutionUndoAdapter> undoAdapter;
0145     };
0146     QScopedPointer<FakeUndoData> m_fakeUndoData;
0147 
0148 };
0149 
0150 #endif /* __KIS_PAINTER_BASED_STROKE_STRATEGY_H */