File indexing completed on 2024-05-19 04:26:19
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 * Descendants 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, bool skipPaintingThisLayer = false); 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 int thumbnailSeqNo() const override; 0240 0241 QImage createThumbnailForFrame(qint32 w, qint32 h, int time, Qt::AspectRatioMode aspectRatioMode = Qt::IgnoreAspectRatio) override; 0242 0243 /** 0244 * Return a tight rectangle, where the contents of the layer 0245 * is placed from user's point of view. This rectangle includes 0246 * all the masks and effects the layer has (excluding layer 0247 * styles, they report their bounds via projection plane). 0248 */ 0249 QRect tightUserVisibleBounds() const; 0250 0251 public: 0252 /** 0253 * Returns true if there are any effect masks present 0254 */ 0255 bool hasEffectMasks() const; 0256 0257 /** 0258 * @return the list of effect masks 0259 */ 0260 QList<KisEffectMaskSP> effectMasks() const; 0261 0262 /** 0263 * @return the list of effect masks up to a certain node 0264 */ 0265 QList<KisEffectMaskSP> effectMasks(KisNodeSP lastNode) const; 0266 0267 /** 0268 * Get the group layer that contains this layer. 0269 */ 0270 KisLayerSP parentLayer() const; 0271 0272 /** 0273 * @return the metadata object associated with this object. 0274 */ 0275 KisMetaData::Store* metaData(); 0276 0277 protected: 0278 /** 0279 * Internal projection device that should be updated in the 0280 * changeRect pass even when the change rect is cropped by 0281 * masks or something like that 0282 */ 0283 virtual QRect amortizedProjectionRectForCleanupInChangePass() const; 0284 0285 // override from KisNode 0286 QRect changeRect(const QRect &rect, PositionToFilthy pos = N_FILTHY) const override; 0287 0288 void childNodeChanged(KisNodeSP changedChildNode) override; 0289 0290 protected: 0291 0292 /** 0293 * Ask the layer to assemble its data & apply all the effect masks 0294 * to it. 0295 */ 0296 QRect updateProjection(const QRect& rect, KisNodeSP filthyNode); 0297 0298 /** 0299 * Layers can override this method to get some special behavior 0300 * when copying data from \p original to \p projection, e.g. blend 0301 * in indirect painting device. If you need to modify data 0302 * outside \p rect, please also override outgoingChangeRect() 0303 * method. 0304 */ 0305 virtual void copyOriginalToProjection(const KisPaintDeviceSP original, 0306 KisPaintDeviceSP projection, 0307 const QRect& rect) const; 0308 /** 0309 * For KisLayer classes change rect transformation consists of two 0310 * parts: incoming and outgoing. 0311 * 0312 * 1) incomingChangeRect(rect) chande rect transformation 0313 * performed by the transformations done basing on global 0314 * projection. It is performed in KisAsyncMerger + 0315 * KisUpdateOriginalVisitor classes. It happens before data 0316 * coming to KisLayer::original() therefore it is 0317 * 'incoming'. See KisAdjustmentLayer for example of usage. 0318 * 0319 * 2) outgoingChangeRect(rect) change rect transformation that 0320 * happens in KisLayer::copyOriginalToProjection(). It applies 0321 * *only* when the layer is 'filthy', that is was the cause of 0322 * the merge process. See KisCloneLayer for example of usage. 0323 * 0324 * The flow of changed areas can be illustrated in the 0325 * following way: 0326 * 0327 * 1. Current projection of size R1 is stored in KisAsyncMerger::m_currentProjection 0328 * | 0329 * | <-- KisUpdateOriginalVisitor writes data into layer's original() device. 0330 * | The changed area on KisLayer::original() is 0331 * | R2 = KisLayer::incomingChangeRect(R1) 0332 * | 0333 * 2. KisLayer::original() / changed rect: R2 0334 * | 0335 * | <-- KisLayer::updateProjection() starts composing a layer 0336 * | It calls KisLayer::copyOriginalToProjection() which copies some area 0337 * | to a temporary device. The temporary device now stores 0338 * | R3 = KisLayer::outgoingChangeRect(R2) 0339 * | 0340 * 3. Temporary device / changed rect: R3 0341 * | 0342 * | <-- KisLayer::updateProjection() continues composing a layer. It merges a mask. 0343 * | R4 = KisMask::changeRect(R3) 0344 * | 0345 * 4. KisLayer::original() / changed rect: R4 0346 * 0347 * So in the end rect R4 will be passed up to the next layers in the stack. 0348 */ 0349 virtual QRect incomingChangeRect(const QRect &rect) const; 0350 0351 /** 0352 * \see incomingChangeRect() 0353 */ 0354 virtual QRect outgoingChangeRect(const QRect &rect) const; 0355 0356 /** 0357 * Return need rect that should be prepared on original() 0358 * device of the layer to get \p rect on its projection. 0359 * 0360 * This method is used either for layers that can have other 0361 * layers as children (yes, KisGroupLayer, I'm looking at you!), 0362 * or for layers that depend on the lower nodes (it's you, 0363 * KisAdjustmentLayer!). 0364 * 0365 * These layers may have some filter masks that need a bit 0366 * more pixels than requested, therefore child nodes should do 0367 * a bit more work to prepare them. 0368 */ 0369 QRect needRectForOriginal(const QRect &rect) const; 0370 0371 /** 0372 * @param rectVariesFlag (out param) a flag, showing whether 0373 * a rect varies from mask to mask 0374 * @return an area that should be updated because of 0375 * the change of @requestedRect of the layer 0376 */ 0377 QRect masksChangeRect(const QList<KisEffectMaskSP> &masks, 0378 const QRect &requestedRect, 0379 bool &rectVariesFlag) const; 0380 0381 /** 0382 * Get needRects for all masks 0383 * @param changeRect requested rect to be updated on final 0384 * projection. Should be a return value 0385 * of @ref masksChangedRect() 0386 * @param applyRects (out param) a stack of the rects where filters 0387 * should be applied 0388 * @param rectVariesFlag (out param) a flag, showing whether 0389 * a rect varies from mask to mask 0390 * @return a needRect that should be prepared on the layer's 0391 * paintDevice for all masks to succeed 0392 */ 0393 QRect masksNeedRect(const QList<KisEffectMaskSP> &masks, 0394 const QRect &changeRect, 0395 QStack<QRect> &applyRects, 0396 bool &rectVariesFlag) const; 0397 0398 QRect applyMasks(const KisPaintDeviceSP source, 0399 KisPaintDeviceSP destination, 0400 const QRect &requestedRect, 0401 KisNodeSP filthyNode, KisNodeSP lastNode) const; 0402 0403 bool canMergeAndKeepBlendOptions(KisLayerSP otherLayer); 0404 0405 QList<KisEffectMaskSP> searchEffectMasks(KisNodeSP lastNode) const; 0406 0407 private: 0408 friend class KisLayerMasksCache; 0409 friend class KisLayerProjectionPlane; 0410 friend class KisTransformMask; 0411 friend class KisLayerTest; 0412 0413 private: 0414 QRect layerExtentImpl(bool exactBounds) const; 0415 0416 private: 0417 struct Private; 0418 Private * const m_d; 0419 }; 0420 0421 Q_DECLARE_METATYPE(KisLayerSP) 0422 0423 #endif // KIS_LAYER_H_