Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_time_span.h
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2015 Dmitry Kazakov <dimula73@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7#ifndef __KIS_TIME_RANGE_H
8#define __KIS_TIME_RANGE_H
9
10#include "kritaimage_export.h"
11
12#include <algorithm>
13#include <limits>
14#include <QMetaType>
15#include <boost/operators.hpp>
16#include "kis_types.h"
17#include <kis_dom_utils.h>
18
19class KRITAIMAGE_EXPORT KisTimeSpan : public boost::equality_comparable<KisTimeSpan>
20{
21private:
22 inline KisTimeSpan(int start, int end)
23 : m_start(start),
24 m_end(end)
25 {
26 }
27
28public:
29 inline KisTimeSpan()
30 : m_start(0),
31 m_end(-1)
32 {
33 }
34
35 inline int start() const {
36 return m_start;
37 }
38
39 inline int end() const {
40 return m_end;
41 }
42
43 inline int duration() const {
44 return m_end >= m_start ? m_end - m_start + 1 : 0;
45 }
46
47 inline bool isInfinite() const {
48 return m_end == std::numeric_limits<int>::min();
49 }
50
51 inline bool isValid() const {
52 return (m_end >= m_start) || (m_end == std::numeric_limits<int>::min() && m_start >= 0);
53 }
54
55 inline bool contains(int time) const {
56 if (m_end == std::numeric_limits<int>::min()) {
57 return m_start <= time;
58 }
59
60 return m_start <= time && time <= m_end;
61 }
62
63 inline void include(int time) {
64 m_start = qMin(time, m_start);
65 m_end = qMax(time, m_end);
66 }
67
68 inline bool overlaps(const KisTimeSpan& other) const {
69 // If either are "invalid", we should probably return false.
70 if (!isValid() || !other.isValid()) {
71 return false;
72 }
73
74 // Handle infinite cases...
75 if (other.isInfinite()) {
76 return (other.contains(start()) || other.contains(end()));
77 } else if (isInfinite()) {
78 return (contains(other.start()) || contains(other.end()));
79 }
80
81 const int selfMin = qMin(start(), end());
82 const int selfMax = qMax(start(), end());
83 const int otherMin = qMin(other.start(), other.end());
84 const int otherMax = qMax(other.start(), other.end());
85 return (selfMax >= otherMin) && (selfMin <= otherMax );
86 }
87
88 static inline KisTimeSpan fromTimeToTime(int start, int end) {
89 return KisTimeSpan(start, end);
90 }
91
92 static inline KisTimeSpan fromTimeWithDuration(int start, int duration) {
93 return KisTimeSpan( start, start + duration - 1);
94 }
95
96 static inline KisTimeSpan infinite(int start) {
97 return KisTimeSpan(start, std::numeric_limits<int>::min());
98 }
99
100 static KisTimeSpan calculateIdenticalFramesRecursive(const KisNode *node, int time);
101 static KisTimeSpan calculateAffectedFramesRecursive(const KisNode *node, int time);
102
103 static KisTimeSpan calculateNodeIdenticalFrames(const KisNode *node, int time);
104 static KisTimeSpan calculateNodeAffectedFrames(const KisNode *node, int time);
105
106 bool operator==(const KisTimeSpan &rhs) const {
107 return rhs.m_start == m_start && rhs.m_end == m_end;
108 }
109
111 KisTimeSpan result = *this;
112
113 if (!result.isValid()) {
114 result.m_start = rhs.start();
115 } else if (rhs.isValid()) {
116 result.m_start = std::min(result.m_start, rhs.start());
117 }
118
119 if (rhs.isInfinite() || result.isInfinite()) {
120 result.m_end = std::numeric_limits<int>::min();
121 } else if (!isValid()) {
122 result.m_end = rhs.m_end;
123 } else {
124 result.m_end = std::max(m_end, rhs.m_end);
125 }
126
127 return result;
128 }
129
130 const KisTimeSpan& operator|=(const KisTimeSpan &rhs) {
131 KisTimeSpan result = (*this | rhs);
132 this->m_start = result.m_start;
133 this->m_end = result.m_end;
134 return *this;
135 }
136
138 KisTimeSpan result = *this;
139
140 if (!isValid()) {
141 return result;
142 } else if (!rhs.isValid()) {
143 result.m_start = rhs.start();
144 result.m_end = rhs.m_end;
145 return result;
146 } else {
147 result.m_start = std::max(result.m_start, rhs.start());
148 }
149
150 if (isInfinite()) {
151 result.m_end = rhs.m_end;
152 } else if (!rhs.isInfinite()) {
153 result.m_end = std::min(result.m_end, rhs.m_end);
154 }
155
156 return result;
157 }
158
159 const KisTimeSpan& operator&=(const KisTimeSpan &rhs) {
160 KisTimeSpan result = (*this & rhs);
161 this->m_start = result.m_start;
162 this->m_end = result.m_end;
163 return *this;
164 }
165
166private:
168 int m_end;
169};
170
171namespace KisDomUtils {
172 void KRITAIMAGE_EXPORT saveValue(QDomElement *parent, const QString &tag, const KisTimeSpan &range);
173 bool KRITAIMAGE_EXPORT loadValue(const QDomElement &parent, const QString &tag, KisTimeSpan *range);
174}
175
176
177
179
180KRITAIMAGE_EXPORT QDebug operator<<(QDebug dbg, const KisTimeSpan &r);
181
182
183#endif /* __KIS_TIME_RANGE_H */
bool contains(int time) const
int start() const
KisTimeSpan operator|(const KisTimeSpan &rhs) const
bool isInfinite() const
const KisTimeSpan & operator|=(const KisTimeSpan &rhs)
int duration() const
KisTimeSpan(int start, int end)
const KisTimeSpan & operator&=(const KisTimeSpan &rhs)
static KisTimeSpan infinite(int start)
void include(int time)
static KisTimeSpan fromTimeWithDuration(int start, int duration)
bool operator==(const KisTimeSpan &rhs) const
int end() const
KisTimeSpan operator&(const KisTimeSpan &rhs) const
static KisTimeSpan fromTimeToTime(int start, int end)
bool overlaps(const KisTimeSpan &other) const
bool isValid() const
Q_DECLARE_METATYPE(KisPaintopLodLimitations)
KRITAIMAGE_EXPORT QDebug operator<<(QDebug dbg, const KisTimeSpan &r)
void saveValue(QDomElement *parent, const QString &tag, const QSize &size)
bool loadValue(const QDomElement &e, float *v)