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