File indexing completed on 2024-05-12 15:58:14
0001 /* 0002 * SPDX-FileCopyrightText: 2010 Cyrille Berger <cberger@cberger.net> 0003 * SPDX-FileCopyrightText: 2013 Dmitry Kazakov <dimula73@gmail.com> 0004 * 0005 * SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #ifndef _KIS_DISTANCE_INFORMATION_H_ 0009 #define _KIS_DISTANCE_INFORMATION_H_ 0010 0011 #include <QPointF> 0012 #include <QVector2D> 0013 #include <QDomDocument> 0014 #include <QDomElement> 0015 #include "kritaimage_export.h" 0016 #include <boost/optional.hpp> 0017 0018 class KisPaintInformation; 0019 class KisSpacingInformation; 0020 class KisTimingInformation; 0021 class KisDistanceInformation; 0022 0023 /** 0024 * Represents some information that can be used to initialize a KisDistanceInformation object. The 0025 * main purpose of this class is to allow serialization of KisDistanceInformation initial settings 0026 * to XML. 0027 */ 0028 class KRITAIMAGE_EXPORT KisDistanceInitInfo { 0029 0030 public: 0031 0032 /** 0033 * Creates a KisDistanceInitInfo with no initial last dab information, and spacing and timing 0034 * update intervals set to LONG_TIME. 0035 */ 0036 explicit KisDistanceInitInfo(); 0037 0038 /** 0039 * Creates a KisDistanceInitInfo with no initial last dab information, and the specified spacing 0040 * and timing update intervals. 0041 */ 0042 explicit KisDistanceInitInfo(qreal spacingUpdateInterval, qreal timingUpdateInterval, int currentDabSeqNo); 0043 0044 /** 0045 * Creates a KisDistanceInitInfo with the specified last dab information, and spacing and timing 0046 * update intervals set to LONG_TIME. 0047 */ 0048 explicit KisDistanceInitInfo(const QPointF &lastPosition, qreal lastAngle, int currentDabSeqNo); 0049 0050 /** 0051 * Creates a KisDistanceInitInfo with the specified last dab information and spacing and timing 0052 * update intervals. 0053 */ 0054 explicit KisDistanceInitInfo(const QPointF &lastPosition, qreal lastAngle, 0055 qreal spacingUpdateInterval, qreal timingUpdateInterval, int currentDabSeqNo); 0056 0057 KisDistanceInitInfo(const KisDistanceInitInfo &rhs); 0058 0059 ~KisDistanceInitInfo(); 0060 0061 bool operator==(const KisDistanceInitInfo &other) const; 0062 0063 bool operator!=(const KisDistanceInitInfo &other) const; 0064 0065 KisDistanceInitInfo &operator=(const KisDistanceInitInfo &rhs); 0066 0067 /** 0068 * Constructs a KisDistanceInformation with initial settings based on this object. 0069 */ 0070 KisDistanceInformation makeDistInfo(); 0071 0072 void toXML(QDomDocument &doc, QDomElement &elt) const; 0073 0074 static KisDistanceInitInfo fromXML(const QDomElement &elt); 0075 0076 private: 0077 struct Private; 0078 Private * const m_d; 0079 }; 0080 0081 /** 0082 * This structure keeps track of distance and timing information during a stroke, e.g. the time or 0083 * distance moved since the last dab. 0084 */ 0085 class KRITAIMAGE_EXPORT KisDistanceInformation { 0086 public: 0087 KisDistanceInformation(); 0088 KisDistanceInformation(qreal spacingUpdateInterval, qreal timingUpdateInterval, int currentDabSeqNo = 0); 0089 KisDistanceInformation(const QPointF &lastPosition, qreal lastAngle); 0090 /** 0091 * @param spacingUpdateInterval The amount of time allowed between spacing updates, in 0092 * milliseconds. Use LONG_TIME to only allow spacing updates when a 0093 * dab is painted. 0094 * @param timingUpdateInterval The amount of time allowed between time-based spacing updates, in 0095 * milliseconds. Use LONG_TIME to only allow timing updates when a 0096 * dab is painted. 0097 */ 0098 KisDistanceInformation(const QPointF &lastPosition, qreal lastAngle, 0099 qreal spacingUpdateInterval, qreal timingUpdateInterval, int currentDabSeqNo); 0100 KisDistanceInformation(const KisDistanceInformation &rhs); 0101 KisDistanceInformation(const KisDistanceInformation &rhs, int levelOfDetail); 0102 KisDistanceInformation& operator=(const KisDistanceInformation &rhs); 0103 0104 ~KisDistanceInformation(); 0105 0106 const KisSpacingInformation& currentSpacing() const; 0107 void updateSpacing(const KisSpacingInformation &spacing); 0108 /** 0109 * Returns true if this KisDistanceInformation should have its spacing information updated 0110 * immediately (regardless of whether a dab is ready to be painted). 0111 */ 0112 bool needsSpacingUpdate() const; 0113 0114 const KisTimingInformation ¤tTiming() const; 0115 void updateTiming(const KisTimingInformation &timing); 0116 /** 0117 * Returns true if this KisDistanceInformation should have its timing information updated 0118 * immediately (regardless of whether a dab is ready to be painted). 0119 */ 0120 bool needsTimingUpdate() const; 0121 0122 bool hasLastDabInformation() const; 0123 QPointF lastPosition() const; 0124 qreal lastDrawingAngle() const; 0125 0126 bool hasLastPaintInformation() const; 0127 const KisPaintInformation& lastPaintInformation() const; 0128 0129 int currentDabSeqNo() const; 0130 0131 qreal maxPressure() const; 0132 0133 /** 0134 * @param spacing The new effective spacing after the dab. (Painting a dab is always supposed to 0135 * cause a spacing update.) 0136 * @param timing The new effective timing after the dab. (Painting a dab is always supposed to 0137 * cause a timing update.) 0138 */ 0139 void registerPaintedDab(const KisPaintInformation &info, 0140 const KisSpacingInformation &spacing, 0141 const KisTimingInformation &timing); 0142 0143 qreal getNextPointPosition(const QPointF &start, 0144 const QPointF &end, 0145 qreal startTime, 0146 qreal endTime); 0147 0148 qreal getSpacingInterval() const; 0149 qreal getTimingUpdateInterval() const; 0150 0151 /** 0152 * \return true if at least one dab has been painted with this 0153 * distance information 0154 */ 0155 bool isStarted() const; 0156 0157 boost::optional<qreal> lockedDrawingAngleOptional() const; 0158 0159 /** 0160 * Lock current drawing angle for the rest of the stroke. The new value is blended 0161 * into the result proportional to the length of the stroke. 0162 */ 0163 void lockCurrentDrawingAngle(const KisPaintInformation &info) const; 0164 0165 qreal scalarDistanceApprox() const; 0166 0167 void overrideLastValues(const QPointF &lastPosition, qreal lastAngle); 0168 0169 private: 0170 qreal getNextPointPositionIsotropic(const QPointF &start, 0171 const QPointF &end); 0172 qreal getNextPointPositionAnisotropic(const QPointF &start, 0173 const QPointF &end); 0174 qreal getNextPointPositionTimed(qreal startTime, 0175 qreal endTime); 0176 void resetAccumulators(); 0177 0178 private: 0179 struct Private; 0180 Private * const m_d; 0181 }; 0182 0183 #endif