1 /*
2 * Copyright (c) 2014 Dmitry Kazakov <dimula73@gmail.com>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 */
18
19 #include "kis_recalculate_transform_mask_job.h"
20
21 #include "kis_transform_mask.h"
22 #include "kis_debug.h"
23 #include "kis_layer.h"
24 #include "kis_image.h"
25 #include "kis_image_animation_interface.h"
26 #include "kis_abstract_projection_plane.h"
27 #include "kis_transform_mask_params_interface.h"
28
KisRecalculateTransformMaskJob(KisTransformMaskSP mask)29 KisRecalculateTransformMaskJob::KisRecalculateTransformMaskJob(KisTransformMaskSP mask)
30 : m_mask(mask)
31 {
32 setExclusive(true);
33 }
34
overrides(const KisSpontaneousJob * _otherJob)35 bool KisRecalculateTransformMaskJob::overrides(const KisSpontaneousJob *_otherJob)
36 {
37 const KisRecalculateTransformMaskJob *otherJob =
38 dynamic_cast<const KisRecalculateTransformMaskJob*>(_otherJob);
39
40 return otherJob && otherJob->m_mask == m_mask;
41 }
42
run()43 void KisRecalculateTransformMaskJob::run()
44 {
45 /**
46 * The mask might have been deleted from the layers stack. In
47 * such a case, don't try do update it.
48 */
49 if (!m_mask->parent()) return;
50 if (!m_mask->visible()) return;
51
52 m_mask->recaclulateStaticImage();
53
54 KisLayerSP layer = qobject_cast<KisLayer*>(m_mask->parent().data());
55
56 if (!layer) {
57 warnKrita << "WARNING: KisRecalculateTransformMaskJob::run() Mask has no parent layer! Skipping projection update!";
58 return;
59 }
60
61 KisImageSP image = layer->image();
62 Q_ASSERT(image);
63
64 /**
65 * Depending on whether the mask is hidden we should either
66 * update it entirely via the setDirty() call, or we can use a
67 * lightweight approach by directly regenerating the
68 * precalculated static image using
69 * KisRecalculateTransformMaskJob.
70 */
71 if (m_mask->transformParams()->isHidden()) {
72 QRect updateRect = m_mask->extent();
73
74 if (layer->original()) {
75 updateRect |= layer->original()->defaultBounds()->bounds();
76 }
77
78 if (layer->isAnimated()) {
79 m_mask->setDirty(updateRect);
80 } else {
81 m_mask->setDirtyDontResetAnimationCache(updateRect);
82 }
83 } else {
84 /**
85 * When we call requestProjectionUpdateNoFilthy() on a layer,
86 * its masks' change rect is not counted, because it is considered
87 * to be N_ABOVE_FILTHY. Therefore, we should expand the dirty
88 * rect manually to get the correct update
89 */
90
91 QRect updateRect = layer->projectionPlane()->changeRect(layer->extent(), KisLayer::N_FILTHY);
92 image->requestProjectionUpdateNoFilthy(layer, updateRect, image->bounds(),layer->isAnimated());
93 }
94 }
95
levelOfDetail() const96 int KisRecalculateTransformMaskJob::levelOfDetail() const
97 {
98 return 0;
99 }
100
debugName() const101 QString KisRecalculateTransformMaskJob::debugName() const
102 {
103 QString result;
104 QDebug dbg(&result);
105 dbg << "KisRecalculateTransformMaskJob" << m_mask;
106 return result;
107 }
108