File indexing completed on 2024-05-19 04:26:22
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 cut/copy-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 int thumbnailSeqNo() const override; 0180 0181 void testingInitSelection(const QRect &rect, KisLayerSP parentLayer); 0182 0183 bool supportsLodPainting() const override; 0184 0185 protected: 0186 /** 0187 * Apply the effect the projection using the mask as a selection. 0188 * Made public in KisEffectMask 0189 */ 0190 void apply(KisPaintDeviceSP projection, const QRect & applyRect, const QRect & needRect, PositionToFilthy maskPos) const; 0191 0192 virtual void mergeInMaskInternal(KisPaintDeviceSP projection, 0193 KisSelectionSP effectiveSelection, 0194 const QRect &applyRect, const QRect &preparedNeedRect, 0195 PositionToFilthy maskPos) const; 0196 0197 /** 0198 * A special callback for calling selection->updateProjection() during 0199 * the projection calculation process. Some masks (e.g. selection masks) 0200 * don't need it, because they do it separately. 0201 */ 0202 virtual void flattenSelectionProjection(KisSelectionSP selection, const QRect &dirtyRect) const; 0203 0204 virtual QRect decorateRect(KisPaintDeviceSP &src, 0205 KisPaintDeviceSP &dst, 0206 const QRect & rc, 0207 PositionToFilthy maskPos) const; 0208 0209 virtual bool paintsOutsideSelection() const; 0210 0211 KisKeyframeChannel *requestKeyframeChannel(const QString &id) override; 0212 bool supportsKeyframeChannel(const QString &id) override; 0213 0214 void baseNodeChangedCallback() override; 0215 0216 private: 0217 friend class KisMaskProjectionPlane; 0218 0219 private: 0220 0221 struct Private; 0222 0223 Private * const m_d; 0224 0225 }; 0226 0227 0228 #endif