File indexing completed on 2024-05-19 04:26:37
0001 /* 0002 * SPDX-FileCopyrightText: 2015 Dmitry Kazakov <dimula73@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "kis_time_span.h" 0008 0009 #include <QDebug> 0010 #include "kis_keyframe_channel.h" 0011 #include "kis_node.h" 0012 #include "kis_layer_utils.h" 0013 #include <KisStaticInitializer.h> 0014 0015 KIS_DECLARE_STATIC_INITIALIZER { 0016 qRegisterMetaType<KisTimeSpan>("KisTimeSpan"); 0017 } 0018 0019 QDebug operator<<(QDebug dbg, const KisTimeSpan &r) 0020 { 0021 dbg.nospace() << "KisTimeSpan(" << r.start() << ", " << r.end() << ")"; 0022 0023 return dbg.space(); 0024 } 0025 0026 KisTimeSpan KisTimeSpan::calculateIdenticalFramesRecursive(const KisNode *node, int time) 0027 { 0028 KisTimeSpan range = KisTimeSpan::infinite(0); 0029 0030 KisLayerUtils::recursiveApplyNodes(node, 0031 [&range, time] (const KisNode *node) { 0032 if (node->visible()) { 0033 range &= calculateNodeIdenticalFrames(node, time); 0034 } 0035 }); 0036 0037 return range; 0038 } 0039 0040 KisTimeSpan KisTimeSpan::calculateAffectedFramesRecursive(const KisNode *node, int time) 0041 { 0042 KisTimeSpan range; 0043 0044 KisLayerUtils::recursiveApplyNodes(node, 0045 [&range, time] (const KisNode *node) { 0046 if (node->visible()) { 0047 range |= calculateNodeIdenticalFrames(node, time); 0048 } 0049 }); 0050 0051 return range; 0052 } 0053 0054 KisTimeSpan KisTimeSpan::calculateNodeIdenticalFrames(const KisNode *node, int time) 0055 { 0056 KisTimeSpan range = KisTimeSpan::infinite(0); 0057 0058 const QMap<QString, KisKeyframeChannel*> channels = 0059 node->keyframeChannels(); 0060 0061 Q_FOREACH (const KisKeyframeChannel *channel, channels) { 0062 // Intersection 0063 range &= channel->identicalFrames(time); 0064 } 0065 0066 return range; 0067 } 0068 0069 KisTimeSpan KisTimeSpan::calculateNodeAffectedFrames(const KisNode *node, int time) 0070 { 0071 KisTimeSpan range; 0072 0073 if (!node->visible()) return range; 0074 0075 const QMap<QString, KisKeyframeChannel*> channels = 0076 node->keyframeChannels(); 0077 0078 // TODO: channels should report to the image which channel exactly has changed 0079 // to avoid the dirty range to be stretched into infinity! 0080 0081 if (channels.isEmpty() || 0082 !channels.contains(KisKeyframeChannel::Raster.id())) { 0083 range = KisTimeSpan::infinite(0); 0084 return range; 0085 } 0086 0087 Q_FOREACH (const KisKeyframeChannel *channel, channels) { 0088 // Union 0089 range |= channel->affectedFrames(time); 0090 } 0091 0092 return range; 0093 } 0094 0095 namespace KisDomUtils { 0096 0097 void saveValue(QDomElement *parent, const QString &tag, const KisTimeSpan &range) 0098 { 0099 QDomDocument doc = parent->ownerDocument(); 0100 QDomElement e = doc.createElement(tag); 0101 parent->appendChild(e); 0102 0103 e.setAttribute("type", "timerange"); 0104 0105 if (range.isValid()) { 0106 e.setAttribute("from", toString(range.start())); 0107 0108 if (!range.isInfinite()) { 0109 e.setAttribute("to", toString(range.end())); 0110 } 0111 } 0112 } 0113 0114 0115 bool loadValue(const QDomElement &parent, const QString &tag, KisTimeSpan *range) 0116 { 0117 QDomElement e; 0118 if (!findOnlyElement(parent, tag, &e)) return false; 0119 0120 if (!Private::checkType(e, "timerange")) return false; 0121 0122 int start = toInt(e.attribute("from", "-1")); 0123 int end = toInt(e.attribute("to", "-1")); 0124 0125 if (start == -1) { 0126 *range = KisTimeSpan(); 0127 } else if (end == -1) { 0128 *range = KisTimeSpan::infinite(start); 0129 } else { 0130 *range = KisTimeSpan::fromTimeToTime(start, end); 0131 } 0132 return true; 0133 } 0134 0135 }