File indexing completed on 2024-05-12 15:58:24

0001 /*
0002  *  SPDX-FileCopyrightText: 2002 Patrick Julien <freak@codepimps.org>
0003  *  SPDX-FileCopyrightText: 2005 C. Boemann <cbo@boemann.dk>
0004  *  SPDX-FileCopyrightText: 2007 Boudewijn Rempt <boud@valdyas.org>
0005  *  SPDX-FileCopyrightText: 2009 Dmitry Kazakov <dimula73@gmail.com>
0006  *
0007  *  SPDX-License-Identifier: GPL-2.0-or-later
0008  */
0009 #ifndef KIS_LAYER_H_
0010 #define KIS_LAYER_H_
0011 
0012 #include <QRect>
0013 #include <QMetaType>
0014 #include <QObject>
0015 
0016 #include "kritaimage_export.h"
0017 
0018 #include "kis_base_node.h"
0019 
0020 #include "kis_types.h"
0021 #include "kis_node.h"
0022 #include "kis_psd_layer_style.h"
0023 
0024 template <class T>
0025 class QStack;
0026 
0027 class QBitArray;
0028 class KisCloneLayer;
0029 class KisPSDLayerStyle;
0030 class KisAbstractProjectionPlane;
0031 class KisLayerProjectionPlane;
0032 typedef QSharedPointer<KisLayerProjectionPlane> KisLayerProjectionPlaneSP;
0033 
0034 
0035 namespace KisMetaData
0036 {
0037 class Store;
0038 }
0039 
0040 /**
0041  * Abstract class that represents the concept of a Layer in Krita. This is not related
0042  * to the paint devices: this is merely an abstraction of how layers can be stacked and
0043  * rendered differently.
0044  * Regarding the previous-, first-, next- and lastChild() calls, first means that it the layer
0045  * is at the top of the group in the layerlist, using next will iterate to the bottom to last,
0046  * whereas previous will go up to first again.
0047  *
0048  *
0049  * TODO: Add a layer mode whereby the projection of the layer is used
0050  * as a clipping path?
0051  **/
0052 class KRITAIMAGE_EXPORT KisLayer : public KisNode
0053 {
0054 
0055     Q_OBJECT
0056 
0057 public:
0058 
0059     /**
0060      * @param image is the pointer of the image or null
0061      * @param opacity is a value between OPACITY_TRANSPARENT_U8 and OPACITY_OPAQUE_U8
0062     **/
0063     KisLayer(KisImageWSP image, const QString &name, quint8 opacity);
0064     KisLayer(const KisLayer& rhs);
0065     ~KisLayer() override;
0066 
0067     /// returns the image's colorSpace or null, if there is no image
0068     const KoColorSpace * colorSpace() const override;
0069 
0070     /// returns the layer's composite op for the colorspace of the layer's parent.
0071     const KoCompositeOp * compositeOp() const override;
0072 
0073     KisPSDLayerStyleSP layerStyle() const;
0074     void setLayerStyle(KisPSDLayerStyleSP layerStyle);
0075 
0076     /**
0077      * \see a comment in KisNode::projectionPlane()
0078      */
0079     KisAbstractProjectionPlaneSP projectionPlane() const override;
0080 
0081     /**
0082      * The projection plane representing the layer itself without any
0083      * styles or anything else. It is used by the layer styles projection
0084      * plane to stack up the planes.
0085      */
0086     virtual KisLayerProjectionPlaneSP internalProjectionPlane() const;
0087 
0088     QRect partialChangeRect(KisNodeSP lastNode, const QRect& rect);
0089     void buildProjectionUpToNode(KisPaintDeviceSP projection, KisNodeSP lastNode, const QRect& rect);
0090 
0091     virtual bool needProjection() const;
0092 
0093     /**
0094      * Return the fully rendered representation of this layer: its
0095      * data and its effect masks
0096      */
0097     KisPaintDeviceSP projection() const override;
0098 
0099     /**
0100      * Return the layer data before the effect masks have had their go
0101      * at it.
0102      */
0103     KisPaintDeviceSP original() const override = 0;
0104 
0105     /**
0106      * @return the selection associated with this layer, if there is
0107      * one. Otherwise, return 0;
0108      */
0109     virtual KisSelectionMaskSP selectionMask() const;
0110 
0111     /**
0112      * @return the selection contained in the first KisSelectionMask associated
0113      * with this layer or the image, if either exists, otherwise, return 0.
0114      */
0115     virtual KisSelectionSP selection() const;
0116 
0117     KisBaseNode::PropertyList sectionModelProperties() const override;
0118     void setSectionModelProperties(const KisBaseNode::PropertyList &properties) override;
0119 
0120     /**
0121      * set/unset the channel flag for the alpha channel of this layer
0122      */
0123     void disableAlphaChannel(bool disable);
0124 
0125     /**
0126      * returns true if the channel flag for the alpha channel
0127      * of this layer is not set.
0128      * returns false otherwise.
0129      */
0130     bool alphaChannelDisabled() const;
0131 
0132     /**
0133      * set the channelflags for this layer to the specified bit array.
0134      * The bit array must have exactly the same number of channels as
0135      * the colorspace this layer is in, or be empty, in which case all
0136      * channels are active.
0137      */
0138     virtual void setChannelFlags(const QBitArray & channelFlags);
0139 
0140     /**
0141      * Return a bit array where each bit indicates whether a
0142      * particular channel is active or not. If the channelflags bit
0143      * array is empty, all channels are active.
0144      */
0145     QBitArray & channelFlags() const;
0146 
0147     /**
0148      * Returns true if this layer is temporary: i.e., it should not
0149      * appear in the layerbox, even though it is temporarily in the
0150      * layer stack and taken into account on recomposition.
0151      */
0152     bool temporary() const;
0153 
0154     /**
0155      * Set to true if this layer should not appear in the layerbox,
0156      * even though it is temporarily in the layer stack and taken into
0157      * account on recomposition.
0158      */
0159     void setTemporary(bool t);
0160 
0161     /**
0162      * Set the image this layer belongs to.
0163      */
0164     void setImage(KisImageWSP image) override;
0165 
0166     /**
0167      * Create and return a layer that is the result of merging
0168      * this with layer.
0169      *
0170      * This method is designed to be called only within KisImage::mergeLayerDown().
0171      *
0172      * Decendands override this to create specific merged types when possible.
0173      * The KisLayer one creates a KisPaintLayerSP via a bitBlt, and can work on all layer types.
0174      *
0175      * Descendants that perform their own version do NOT call KisLayer::createMergedLayer
0176      */
0177     virtual KisLayerSP createMergedLayerTemplate(KisLayerSP prevLayer);
0178     virtual void fillMergedLayerTemplate(KisLayerSP dstLayer, KisLayerSP prevLayer);
0179 
0180     /**
0181      * Clones should be informed about updates of the original
0182      * layer, so this is a way to register them
0183      */
0184     void registerClone(KisCloneLayerWSP clone);
0185 
0186     /**
0187      * Deregisters the clone from the update list
0188      *
0189      * \see registerClone()
0190      */
0191     void unregisterClone(KisCloneLayerWSP clone);
0192 
0193     /**
0194      * Return the list of the clones of this node. Be careful
0195      * with the list, because it is not thread safe.
0196      */
0197     const QList<KisCloneLayerWSP> registeredClones() const;
0198 
0199 
0200     /**
0201      * Returns whether we have a clone.
0202      *
0203      * Be careful with it. It is not thread safe to add/remove
0204      * clone while checking hasClones(). So there should be no updates.
0205      */
0206     bool hasClones() const;
0207 
0208     /**
0209      * It is called by the async merger after projection update is done
0210      */
0211     void updateClones(const QRect &rect);
0212 
0213     /**
0214      * Informs this layers that its masks might have changed.
0215      */
0216     void notifyChildMaskChanged();
0217 
0218 public:
0219     qint32 x() const override;
0220     qint32 y() const override;
0221 
0222     void setX(qint32 x) override;
0223     void setY(qint32 y) override;
0224 
0225     /**
0226      * Returns an approximation of where the bounds
0227      * of actual data of this layer are
0228      */
0229     QRect extent() const override;
0230 
0231     /**
0232      * Returns the exact bounds of where the actual data
0233      * of this layer resides
0234      */
0235     QRect exactBounds() const override;
0236 
0237     QImage createThumbnail(qint32 w, qint32 h, Qt::AspectRatioMode aspectRatioMode = Qt::IgnoreAspectRatio) override;
0238 
0239     QImage createThumbnailForFrame(qint32 w, qint32 h, int time, Qt::AspectRatioMode aspectRatioMode = Qt::IgnoreAspectRatio) override;
0240 
0241     /**
0242      * Return a tight rectangle, where the contents of the layer
0243      * is placed from user's point of view. This rectangle includes
0244      * all the masks and effects the layer has (excluding layer
0245      * styles, they report their bounds via projection plane).
0246      */
0247     QRect tightUserVisibleBounds() const;
0248 
0249 public:
0250     /**
0251      * Returns true if there are any effect masks present
0252      */
0253     bool hasEffectMasks() const;
0254 
0255     /**
0256      * @return the list of effect masks
0257      */
0258     QList<KisEffectMaskSP> effectMasks() const;
0259 
0260     /**
0261      * @return the list of effect masks up to a certain node
0262      */
0263     QList<KisEffectMaskSP> effectMasks(KisNodeSP lastNode) const;
0264 
0265     /**
0266      * Get the group layer that contains this layer.
0267      */
0268     KisLayerSP parentLayer() const;
0269 
0270     /**
0271      * @return the metadata object associated with this object.
0272      */
0273     KisMetaData::Store* metaData();
0274 
0275 protected:
0276     /**
0277      * Internal projection device that should be updated in the
0278      * changeRect pass even when the change rect is cropped by
0279      * masks or something like that
0280      */
0281     virtual QRect amortizedProjectionRectForCleanupInChangePass() const;
0282 
0283     // override from KisNode
0284     QRect changeRect(const QRect &rect, PositionToFilthy pos = N_FILTHY) const override;
0285 
0286     void childNodeChanged(KisNodeSP changedChildNode) override;
0287 
0288 protected:
0289 
0290     /**
0291      * Ask the layer to assemble its data & apply all the effect masks
0292      * to it.
0293      */
0294     QRect updateProjection(const QRect& rect, KisNodeSP filthyNode);
0295 
0296     /**
0297      * Layers can override this method to get some special behavior
0298      * when copying data from \p original to \p projection, e.g. blend
0299      * in indirect painting device.  If you need to modify data
0300      * outside \p rect, please also override outgoingChangeRect()
0301      * method.
0302      */
0303     virtual void copyOriginalToProjection(const KisPaintDeviceSP original,
0304                                           KisPaintDeviceSP projection,
0305                                           const QRect& rect) const;
0306     /**
0307      * For KisLayer classes change rect transformation consists of two
0308      * parts: incoming and outgoing.
0309      *
0310      * 1) incomingChangeRect(rect) chande rect transformation
0311      *    performed by the transformations done basing on global
0312      *    projection. It is performed in KisAsyncMerger +
0313      *    KisUpdateOriginalVisitor classes. It happens before data
0314      *    coming to KisLayer::original() therefore it is
0315      *    'incoming'. See KisAdjustmentLayer for example of usage.
0316      *
0317      * 2) outgoingChangeRect(rect) change rect transformation that
0318      *    happens in KisLayer::copyOriginalToProjection(). It applies
0319      *    *only* when the layer is 'filthy', that is was the cause of
0320      *    the merge process. See KisCloneLayer for example of usage.
0321      *
0322      * The flow of changed areas can be illustrated in the
0323      * following way:
0324      *
0325      * 1. Current projection of size R1 is stored in KisAsyncMerger::m_currentProjection
0326      *      |
0327      *      | <-- KisUpdateOriginalVisitor writes data into layer's original() device.
0328      *      |     The changed area on KisLayer::original() is
0329      *      |     R2 = KisLayer::incomingChangeRect(R1)
0330      *      |
0331      * 2. KisLayer::original() / changed rect: R2
0332      *      |
0333      *      | <-- KisLayer::updateProjection() starts composing a layer
0334      *      |     It calls KisLayer::copyOriginalToProjection() which copies some area
0335      *      |     to a temporaty device. The temporary device now stores
0336      *      |     R3 = KisLayer::outgoingChangeRect(R2)
0337      *      |
0338      * 3. Temporary device / changed rect: R3
0339      *      |
0340      *      | <-- KisLayer::updateProjection() continues composing a layer. It merges a mask.
0341      *      |     R4 = KisMask::changeRect(R3)
0342      *      |
0343      * 4. KisLayer::original() / changed rect: R4
0344      *
0345      * So in the end rect R4 will be passed up to the next layers in the stack.
0346      */
0347     virtual QRect incomingChangeRect(const QRect &rect) const;
0348 
0349     /**
0350      * \see incomingChangeRect()
0351      */
0352     virtual QRect outgoingChangeRect(const QRect &rect) const;
0353 
0354     /**
0355      * Return need rect that should be prepared on original()
0356      * device of the layer to get \p rect on its projection.
0357      *
0358      * This method is used either for layers that can have other
0359      * layers as children (yes, KisGroupLayer, I'm looking at you!),
0360      * or for layers that depend on the lower nodes (it's you,
0361      * KisAdjustmentLayer!).
0362      *
0363      * These layers may have some filter masks that need a bit
0364      * more pixels than requested, therefore child nodes should do
0365      * a bit more work to prepare them.
0366      */
0367     QRect needRectForOriginal(const QRect &rect) const;
0368 
0369     /**
0370      * @param rectVariesFlag (out param) a flag, showing whether
0371      *        a rect varies from mask to mask
0372      * @return an area that should be updated because of
0373      *         the change of @requestedRect of the layer
0374      */
0375     QRect masksChangeRect(const QList<KisEffectMaskSP> &masks,
0376                           const QRect &requestedRect,
0377                           bool &rectVariesFlag) const;
0378 
0379     /**
0380      * Get needRects for all masks
0381      * @param changeRect requested rect to be updated on final
0382      *        projection. Should be a return value
0383      *        of @ref masksChangedRect()
0384      * @param applyRects (out param) a stack of the rects where filters
0385      *        should be applied
0386      * @param rectVariesFlag (out param) a flag, showing whether
0387      *        a rect varies from mask to mask
0388      * @return a needRect that should be prepared on the layer's
0389      *         paintDevice for all masks to succeed
0390      */
0391     QRect masksNeedRect(const QList<KisEffectMaskSP> &masks,
0392                         const QRect &changeRect,
0393                         QStack<QRect> &applyRects,
0394                         bool &rectVariesFlag) const;
0395 
0396     QRect applyMasks(const KisPaintDeviceSP source,
0397                      KisPaintDeviceSP destination,
0398                      const QRect &requestedRect,
0399                      KisNodeSP filthyNode, KisNodeSP lastNode) const;
0400 
0401     bool canMergeAndKeepBlendOptions(KisLayerSP otherLayer);
0402 
0403     QList<KisEffectMaskSP> searchEffectMasks(KisNodeSP lastNode) const;
0404 
0405 private:
0406     friend class KisLayerMasksCache;
0407     friend class KisLayerProjectionPlane;
0408     friend class KisTransformMask;
0409     friend class KisLayerTest;
0410 
0411 private:
0412     QRect layerExtentImpl(bool exactBounds) const;
0413 
0414 private:
0415     struct Private;
0416     Private * const m_d;
0417 };
0418 
0419 Q_DECLARE_METATYPE(KisLayerSP)
0420 
0421 #endif // KIS_LAYER_H_