File indexing completed on 2024-05-12 15:58:27
0001 /* 0002 * SPDX-FileCopyrightText: 2006 Boudewijn Rempt <boud@valdyas.org> 0003 * SPDX-FileCopyrightText: 2009 Dmitry Kazakov <dimula73@gmail.com> 0004 * 0005 * 0006 * SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 #ifndef _KIS_MASK_ 0009 #define _KIS_MASK_ 0010 0011 #include <QRect> 0012 0013 #include "kis_types.h" 0014 #include "kis_global.h" 0015 #include "kis_node.h" 0016 #include "kis_indirect_painting_support.h" 0017 0018 #include <kritaimage_export.h> 0019 0020 /** 0021 KisMask is the base class for all single channel 0022 mask-like paint devices in Krita. Masks can be rendered in different 0023 ways at different moments during the rendering stack. Masks are 0024 "owned" by layers (of any type), and cannot occur by themselves on 0025 themselves. 0026 0027 The properties that masks implement are made available through the 0028 iterators created on their parent layer, or through iterators that 0029 can be created on the paint device that holds the mask data: masks 0030 are just paint devices, too. 0031 0032 Masks should show up in the layerbox as sub-layers for the layer they 0033 are associated with and be ccp'able and draggable to other layers. 0034 0035 Examples of masks are: 0036 0037 - filter masks: like the alpha filter mask that is the most common 0038 type of mask and is simply known as "mask" in the 0039 gui. Other filter masks use any of krita's filters to 0040 filter the pixels of their parent. (In this they 0041 differ from adjustment layers, which filter all 0042 layers under them in their group stack). 0043 0044 - selections: the selection mask is rendered after composition and 0045 zooming and determines the selectedness of the pixels of the parent 0046 layer. 0047 0048 - painterly overlays: painterly overlays indicate a particular 0049 property of the pixel in the parent paint device they are associated 0050 with, like wetness, height or gravity. 0051 0052 XXX: For now, all masks are 8 bit. Make the channel depth settable. 0053 0054 */ 0055 class KRITAIMAGE_EXPORT KisMask : public KisNode, public KisIndirectPaintingSupport 0056 { 0057 0058 Q_OBJECT 0059 0060 public: 0061 0062 /** 0063 * Create a new KisMask. 0064 */ 0065 KisMask(KisImageWSP image, const QString &name); 0066 0067 /** 0068 * Copy the mask 0069 */ 0070 KisMask(const KisMask& rhs); 0071 0072 ~KisMask() override; 0073 0074 void setImage(KisImageWSP image) override; 0075 0076 bool allowAsChild(KisNodeSP node) const override; 0077 0078 /** 0079 * @brief initSelection initializes the selection for the mask from 0080 * the given selection's projection. 0081 * @param copyFrom the selection we base the mask on 0082 * @param parentLayer the parent of this mask; it determines the default bounds of the mask. 0083 */ 0084 void initSelection(KisSelectionSP copyFrom, KisLayerSP parentLayer); 0085 0086 /** 0087 * @brief initSelection initializes the selection for the mask from 0088 * the given paint device. 0089 * @param copyFromDevice the paint device we base the mask on 0090 * @param parentLayer the parent of this mask; it determines the default bounds of the mask. 0091 */ 0092 void initSelection(KisPaintDeviceSP copyFromDevice, KisLayerSP parentLayer); 0093 0094 /** 0095 * @brief initSelection initializes an empty selection 0096 * @param parentLayer the parent of this mask; it determines the default bounds of the mask. 0097 */ 0098 void initSelection(KisLayerSP parentLayer); 0099 0100 const KoColorSpace * colorSpace() const override; 0101 const KoCompositeOp * compositeOp() const override; 0102 0103 /** 0104 * Return the selection associated with this mask. A selection can 0105 * contain both a paint device and shapes. 0106 */ 0107 KisSelectionSP selection() const; 0108 0109 /** 0110 * @return the selection: if you paint on mask, you paint on the selections 0111 */ 0112 KisPaintDeviceSP paintDevice() const override; 0113 0114 /** 0115 * @return the same as paintDevice() 0116 */ 0117 KisPaintDeviceSP original() const override; 0118 0119 /** 0120 * @return the same as paintDevice() 0121 */ 0122 KisPaintDeviceSP projection() const override; 0123 0124 KisAbstractProjectionPlaneSP projectionPlane() const override; 0125 0126 /** 0127 * Change the selection to the specified selection object. The 0128 * selection is deep copied. 0129 */ 0130 void setSelection(KisSelectionSP selection); 0131 0132 /** 0133 * Selected the specified rect with the specified amount of selectedness. 0134 */ 0135 void select(const QRect & rc, quint8 selectedness = MAX_SELECTED); 0136 0137 /** 0138 * The extent and bounds of the mask are those of the selection inside 0139 */ 0140 QRect extent() const override; 0141 QRect exactBounds() const override; 0142 0143 /** 0144 * overridden from KisBaseNode 0145 */ 0146 qint32 x() const override; 0147 0148 /** 0149 * overridden from KisBaseNode 0150 */ 0151 void setX(qint32 x) override; 0152 0153 /** 0154 * overridden from KisBaseNode 0155 */ 0156 qint32 y() const override; 0157 0158 /** 0159 * overridden from KisBaseNode 0160 */ 0161 void setY(qint32 y) override; 0162 0163 /** 0164 * Usually masks themselves do not have any paint device and 0165 * all their final effect on the layer stack is computed using 0166 * the changeRect() of the dirty rect of the parent layer. Their 0167 * extent() and exectBounds() methods work the same way: by taking 0168 * the extent of the parent layer and computing the rect basing 0169 * on it. But some of the masks like Colorize Mask may have their 0170 * own "projection", which is painted independently from the changed 0171 * area of the parent layer. This additional "non-dependent" extent 0172 * is added to the extent of the parent layer. 0173 */ 0174 virtual QRect nonDependentExtent() const; 0175 0176 QRect needRect(const QRect &rect, PositionToFilthy pos = N_FILTHY) const override; 0177 QRect changeRect(const QRect &rect, PositionToFilthy pos = N_FILTHY) const override; 0178 QImage createThumbnail(qint32 w, qint32 h, Qt::AspectRatioMode aspectRatioMode = Qt::IgnoreAspectRatio) override; 0179 0180 void testingInitSelection(const QRect &rect, KisLayerSP parentLayer); 0181 0182 bool supportsLodPainting() const override; 0183 0184 protected: 0185 /** 0186 * Apply the effect the projection using the mask as a selection. 0187 * Made public in KisEffectMask 0188 */ 0189 void apply(KisPaintDeviceSP projection, const QRect & applyRect, const QRect & needRect, PositionToFilthy maskPos) const; 0190 0191 virtual void mergeInMaskInternal(KisPaintDeviceSP projection, 0192 KisSelectionSP effectiveSelection, 0193 const QRect &applyRect, const QRect &preparedNeedRect, 0194 PositionToFilthy maskPos) const; 0195 0196 /** 0197 * A special callback for calling selection->updateProjection() during 0198 * the projection calculation process. Some masks (e.g. selection masks) 0199 * don't need it, because they do it separately. 0200 */ 0201 virtual void flattenSelectionProjection(KisSelectionSP selection, const QRect &dirtyRect) const; 0202 0203 virtual QRect decorateRect(KisPaintDeviceSP &src, 0204 KisPaintDeviceSP &dst, 0205 const QRect & rc, 0206 PositionToFilthy maskPos) const; 0207 0208 virtual bool paintsOutsideSelection() const; 0209 0210 KisKeyframeChannel *requestKeyframeChannel(const QString &id) override; 0211 bool supportsKeyframeChannel(const QString &id) override; 0212 0213 void baseNodeChangedCallback() override; 0214 0215 private: 0216 friend class KisMaskProjectionPlane; 0217 0218 private: 0219 0220 struct Private; 0221 0222 Private * const m_d; 0223 0224 }; 0225 0226 0227 #endif