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