File indexing completed on 2024-05-12 15:58:39
0001 /* 0002 * SPDX-FileCopyrightText: 2014 Dmitry Kazakov <dimula73@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "kis_recalculate_transform_mask_job.h" 0008 0009 #include "kis_transform_mask.h" 0010 #include "kis_debug.h" 0011 #include "kis_layer.h" 0012 #include "kis_image.h" 0013 #include "kis_image_animation_interface.h" 0014 #include "kis_abstract_projection_plane.h" 0015 #include "kis_transform_mask_params_interface.h" 0016 0017 KisRecalculateTransformMaskJob::KisRecalculateTransformMaskJob(KisTransformMaskSP mask) 0018 : m_mask(mask) 0019 { 0020 setExclusive(true); 0021 } 0022 0023 bool KisRecalculateTransformMaskJob::overrides(const KisSpontaneousJob *_otherJob) 0024 { 0025 const KisRecalculateTransformMaskJob *otherJob = 0026 dynamic_cast<const KisRecalculateTransformMaskJob*>(_otherJob); 0027 0028 return otherJob && otherJob->m_mask == m_mask; 0029 } 0030 0031 void KisRecalculateTransformMaskJob::run() 0032 { 0033 /** 0034 * The mask might have been deleted from the layers stack. In 0035 * such a case, don't try do update it. 0036 */ 0037 if (!m_mask->parent()) return; 0038 if (!m_mask->visible()) return; 0039 0040 const QRect oldMaskExtent = m_mask->extent(); 0041 m_mask->recaclulateStaticImage(); 0042 0043 KisLayerSP layer = qobject_cast<KisLayer*>(m_mask->parent().data()); 0044 0045 if (!layer) { 0046 warnKrita << "WARNING: KisRecalculateTransformMaskJob::run() Mask has no parent layer! Skipping projection update!"; 0047 return; 0048 } 0049 0050 KisImageSP image = layer->image(); 0051 Q_ASSERT(image); 0052 0053 /** 0054 * Depending on whether the mask is hidden we should either 0055 * update it entirely via the setDirty() call, or we can use a 0056 * lightweight approach by directly regenerating the 0057 * precalculated static image using 0058 * KisRecalculateTransformMaskJob. 0059 */ 0060 if (m_mask->transformParams()->isHidden()) { 0061 QRect updateRect = m_mask->extent() | oldMaskExtent; 0062 0063 if (layer->original()) { 0064 updateRect |= layer->original()->defaultBounds()->bounds(); 0065 } 0066 0067 if (layer->isAnimated()) { 0068 m_mask->setDirty(updateRect); 0069 } else { 0070 m_mask->setDirtyDontResetAnimationCache(updateRect); 0071 } 0072 } else { 0073 /** 0074 * When we call requestProjectionUpdateNoFilthy() on a layer, 0075 * its masks' change rect is not counted, because it is considered 0076 * to be N_ABOVE_FILTHY. Therefore, we should expand the dirty 0077 * rect manually to get the correct update 0078 */ 0079 QRect updateRect = oldMaskExtent | 0080 layer->projectionPlane()->changeRect(layer->extent(), KisLayer::N_FILTHY); 0081 0082 if (!m_mask->isAnimated()) { 0083 image->requestProjectionUpdateNoFilthy(layer, updateRect, image->bounds(), false); // Should there be a case where this is flushed? 0084 } 0085 } 0086 } 0087 0088 int KisRecalculateTransformMaskJob::levelOfDetail() const 0089 { 0090 return 0; 0091 } 0092 0093 QString KisRecalculateTransformMaskJob::debugName() const 0094 { 0095 QString result; 0096 QDebug dbg(&result); 0097 dbg << "KisRecalculateTransformMaskJob" << m_mask; 0098 return result; 0099 }