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 */