File indexing completed on 2024-05-12 15:58:21
0001 /* 0002 * SPDX-FileCopyrightText: 2002 Patrick Julien <freak@codepimps.org> 0003 * SPDX-FileCopyrightText: 2007 Boudewijn Rempt <boud@valdyas.org> 0004 * 0005 * SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 #ifndef KIS_IMAGE_H_ 0008 #define KIS_IMAGE_H_ 0009 0010 #include <QObject> 0011 #include <QString> 0012 #include <QPainter> 0013 #include <QRect> 0014 #include <QBitArray> 0015 0016 #include <KoColorConversionTransformation.h> 0017 0018 #include "kis_types.h" 0019 #include "kis_shared.h" 0020 #include "kis_node_graph_listener.h" 0021 #include "kis_node_facade.h" 0022 #include "kis_image_interfaces.h" 0023 #include "kis_strokes_queue_undo_result.h" 0024 #include "KisLodPreferences.h" 0025 0026 #include <kritaimage_export.h> 0027 0028 class KoColorSpace; 0029 class KoColor; 0030 0031 class KisCompositeProgressProxy; 0032 class KisUndoStore; 0033 class KisUndoAdapter; 0034 class KisImageSignalRouter; 0035 class KisPostExecutionUndoAdapter; 0036 class KisFilterStrategy; 0037 class KoColorProfile; 0038 class KisLayerComposition; 0039 class KisSpontaneousJob; 0040 class KisImageAnimationInterface; 0041 class KUndo2MagicString; 0042 class KisProofingConfiguration; 0043 class KisPaintDevice; 0044 0045 namespace KisMetaData 0046 { 0047 class MergeStrategy; 0048 } 0049 0050 /** 0051 * This is the image class, it contains a tree of KisLayer stack and 0052 * meta information about the image. And it also provides some 0053 * functions to manipulate the whole image. 0054 */ 0055 class KRITAIMAGE_EXPORT KisImage : public QObject, 0056 public KisStrokesFacade, 0057 public KisStrokeUndoFacade, 0058 public KisUpdatesFacade, 0059 public KisProjectionUpdateListener, 0060 public KisNodeFacade, 0061 public KisNodeGraphListener, 0062 public KisShared 0063 { 0064 0065 Q_OBJECT 0066 0067 public: 0068 /// @p colorSpace can be null. In that case, it will be initialised to a default color space. 0069 KisImage(KisUndoStore *undoStore, qint32 width, qint32 height, const KoColorSpace *colorSpace, const QString& name); 0070 ~KisImage() override; 0071 0072 static KisImageSP fromQImage(const QImage &image, KisUndoStore *undoStore); 0073 0074 public: // KisNodeGraphListener implementation 0075 0076 void aboutToAddANode(KisNode *parent, int index) override; 0077 void nodeHasBeenAdded(KisNode *parent, int index) override; 0078 void aboutToRemoveANode(KisNode *parent, int index) override; 0079 void nodeChanged(KisNode * node) override; 0080 void nodeCollapsedChanged(KisNode *node) override; 0081 void invalidateAllFrames() override; 0082 void notifySelectionChanged() override; 0083 void requestProjectionUpdate(KisNode *node, const QVector<QRect> &rects, bool resetAnimationCache) override; 0084 void invalidateFrames(const KisTimeSpan &range, const QRect &rect) override; 0085 void requestTimeSwitch(int time) override; 0086 KisNode* graphOverlayNode() const override; 0087 0088 void keyframeChannelHasBeenAdded(KisNode *node, KisKeyframeChannel *channel) override; 0089 void keyframeChannelAboutToBeRemoved(KisNode *node, KisKeyframeChannel *channel) override; 0090 0091 public: // KisProjectionUpdateListener implementation 0092 void notifyProjectionUpdated(const QRect &rc) override; 0093 0094 public: 0095 0096 /** 0097 * Set the number of threads used by the image's working threads 0098 */ 0099 void setWorkingThreadsLimit(int value); 0100 0101 /** 0102 * Return the number of threads available to the image's working threads 0103 */ 0104 int workingThreadsLimit() const; 0105 0106 /** 0107 * Makes a copy of the image with all the layers. If possible, shallow 0108 * copies of the layers are made. 0109 * 0110 * \p exactCopy shows if the copied image should look *exactly* the same as 0111 * the other one (according to it's .kra xml representation). It means that 0112 * the layers will have the same UUID keys and, therefore, you are not 0113 * expected to use the copied image anywhere except for saving. Don't use 0114 * this option if you plan to work with the copied image later. 0115 */ 0116 KisImage *clone(bool exactCopy = false); 0117 0118 void copyFromImage(const KisImage &rhs); 0119 0120 private: 0121 0122 // must specify exactly one from CONSTRUCT or REPLACE. 0123 enum CopyPolicy { 0124 CONSTRUCT = 1, ///< we are copy-constructing a new KisImage 0125 REPLACE = 2, ///< we are replacing the current KisImage with another 0126 EXACT_COPY = 4, /// we need an exact copy of the original image 0127 }; 0128 0129 void copyFromImageImpl(const KisImage &rhs, int policy); 0130 0131 public: 0132 0133 /** 0134 * Render the projection onto a QImage. 0135 */ 0136 QImage convertToQImage(qint32 x1, 0137 qint32 y1, 0138 qint32 width, 0139 qint32 height, 0140 const KoColorProfile * profile); 0141 0142 /** 0143 * Render the projection onto a QImage. 0144 * (this is an overloaded function) 0145 */ 0146 QImage convertToQImage(QRect imageRect, 0147 const KoColorProfile * profile); 0148 0149 0150 /** 0151 * Render a thumbnail of the projection onto a QImage. 0152 */ 0153 QImage convertToQImage(const QSize& scaledImageSize, const KoColorProfile *profile); 0154 0155 /** 0156 * [low-level] Lock the image without waiting for all the internal job queues are processed 0157 * 0158 * WARNING: Don't use it unless you really know what you are doing! Use barrierLock() instead! 0159 * 0160 * Waits for all the **currently running** internal jobs to complete and locks the image 0161 * for writing. Please note that this function does **not** wait for all the internal 0162 * queues to process, so there might be some non-finished actions pending. It means that 0163 * you just postpone these actions until you unlock() the image back. Until then, then image 0164 * might easily be frozen in some inconsistent state. 0165 * 0166 * The only sane usage for this function is to lock the image for **emergency** 0167 * processing, when some internal action or scheduler got hung up, and you just want 0168 * to fetch some data from the image without races. 0169 * 0170 * In all other cases, please use barrierLock() instead! 0171 */ 0172 void immediateLockForReadOnly(); 0173 0174 /** 0175 * Unlocks the image and starts/resumes all the pending internal jobs. If the image 0176 * has been locked for a non-readOnly access, then all the internal caches of the image 0177 * (e.g. lod-planes) are reset and regeneration jobs are scheduled. 0178 */ 0179 void unlock(); 0180 0181 /** 0182 * @return return true if the image is in a locked state, i.e. all the internal 0183 * jobs are blocked from execution by calling either lock() or barrierLock(). 0184 * 0185 * When the image is locked, the user can do some modifications to the image 0186 * contents safely without a perspective having race conditions with internal 0187 * image jobs. 0188 */ 0189 bool locked() const; 0190 0191 /** 0192 * Sets the mask (it must be a part of the node hierarchy already) to be paited on 0193 * the top of all layers. This method does all the locking and syncing for you. It 0194 * is executed asynchronously. 0195 */ 0196 void setOverlaySelectionMask(KisSelectionMaskSP mask); 0197 0198 /** 0199 * \see setOverlaySelectionMask 0200 */ 0201 KisSelectionMaskSP overlaySelectionMask() const; 0202 0203 /** 0204 * \see setOverlaySelectionMask 0205 */ 0206 bool hasOverlaySelectionMask() const; 0207 0208 /** 0209 * @return the global selection object or 0 if there is none. The 0210 * global selection is always read-write. 0211 */ 0212 KisSelectionSP globalSelection() const; 0213 0214 /** 0215 * Retrieve the next automatic layername (XXX: fix to add option to return Mask X) 0216 */ 0217 QString nextLayerName(const QString &baseName = "") const; 0218 0219 /** 0220 * @brief start asynchronous operation on resizing the image 0221 * 0222 * The method will resize the image to fit the new size without 0223 * dropping any pixel data. The GUI will get correct 0224 * notification with old and new sizes, so it adjust canvas origin 0225 * accordingly and avoid jumping of the canvas on screen 0226 * 0227 * @param newRect the rectangle of the image which will be visible 0228 * after operation is completed 0229 * 0230 * Please note that the actual operation starts asynchronously in 0231 * a background, so you cannot expect the image having new size 0232 * right after this call. 0233 */ 0234 void resizeImage(const QRect& newRect); 0235 0236 /** 0237 * @brief start asynchronous operation on cropping the image 0238 * 0239 * The method will **drop** all the image data outside \p newRect 0240 * and resize the image to fit the new size. The GUI will get correct 0241 * notification with old and new sizes, so it adjust canvas origin 0242 * accordingly and avoid jumping of the canvas on screen 0243 * 0244 * @param newRect the rectangle of the image which will be cut-out 0245 * 0246 * Please note that the actual operation starts asynchronously in 0247 * a background, so you cannot expect the image having new size 0248 * right after this call. 0249 */ 0250 void cropImage(const QRect& newRect); 0251 0252 /** 0253 * @brief purge all pixels that have default pixel to free up memory 0254 * @param isCancellable if true, the scheduler is allower to stop and 0255 * cancel purging operation as soon as the user starts any action. 0256 * If \p isCancellable is false, then the user will not be allowed to do 0257 * anything until purging operation is completed. 0258 */ 0259 void purgeUnusedData(bool isCancellable); 0260 0261 /** 0262 * @brief start asynchronous operation on cropping a subtree of nodes starting at \p node 0263 * 0264 * The method will **drop** all the layer data outside \p newRect. Neither 0265 * image nor a layer will be moved anywhere 0266 * 0267 * @param node node to crop 0268 * @param newRect the rectangle of the layer which will be cut-out 0269 * @param activeFrameOnly whether to crop every animation frame or just the current one. 0270 * 0271 * Please note that the actual operation starts asynchronously in 0272 * a background, so you cannot expect the image having new size 0273 * right after this call. 0274 */ 0275 void cropNode(KisNodeSP node, const QRect& newRect, const bool activeFrameOnly = false); 0276 0277 /** 0278 * @brief start asynchronous operation on scaling the image 0279 * @param size new image size in pixels 0280 * @param xres new image x-resolution pixels-per-pt 0281 * @param yres new image y-resolution pixels-per-pt 0282 * @param filterStrategy filtering strategy 0283 * 0284 * Please note that the actual operation starts asynchronously in 0285 * a background, so you cannot expect the image having new size 0286 * right after this call. 0287 */ 0288 void scaleImage(const QSize &size, qreal xres, qreal yres, KisFilterStrategy *filterStrategy); 0289 0290 /** 0291 * @brief start asynchronous operation on scaling a subtree of nodes starting at \p node 0292 * @param node node to scale 0293 * @param center the center of the scaling 0294 * @param scaleX x-scale coefficient to be applied to the node 0295 * @param scaleY y-scale coefficient to be applied to the node 0296 * @param filterStrategy filtering strategy 0297 * @param selection the selection we based on 0298 * 0299 * Please note that the actual operation starts asynchronously in 0300 * a background, so you cannot expect the image having new size 0301 * right after this call. 0302 */ 0303 void scaleNode(KisNodeSP node, const QPointF ¢er, qreal scaleX, qreal scaleY, KisFilterStrategy *filterStrategy, KisSelectionSP selection); 0304 0305 /** 0306 * @brief start asynchronous operation on rotating the image 0307 * 0308 * The image is resized to fit the rotated rectangle 0309 * 0310 * @param radians rotation angle in radians 0311 * 0312 * Please note that the actual operation starts asynchronously in 0313 * a background, so you cannot expect the operation being completed 0314 * right after the call 0315 */ 0316 void rotateImage(double radians); 0317 0318 /** 0319 * @brief start asynchronous operation on rotating a subtree of nodes starting at \p node 0320 * 0321 * The image is not resized! 0322 * 0323 * @param node the root of the subtree to rotate 0324 * @param radians rotation angle in radians 0325 * @param selection the selection we based on 0326 * 0327 * Please note that the actual operation starts asynchronously in 0328 * a background, so you cannot expect the operation being completed 0329 * right after the call 0330 */ 0331 void rotateNode(KisNodeSP node, double radians, KisSelectionSP selection); 0332 0333 /** 0334 * @brief start asynchronous operation on shearing the image 0335 * 0336 * The image is resized to fit the sheared polygon 0337 * 0338 * @p angleX, @p angleY are given in degrees. 0339 * 0340 * Please note that the actual operation starts asynchronously in 0341 * a background, so you cannot expect the operation being completed 0342 * right after the call 0343 */ 0344 void shear(double angleX, double angleY); 0345 0346 /** 0347 * @brief start asynchronous operation on shearing a subtree of nodes starting at \p node 0348 * 0349 * The image is not resized! 0350 * 0351 * @param node the root of the subtree to rotate 0352 * @param angleX x-shear given in degrees. 0353 * @param angleY y-shear given in degrees. 0354 * @param selection the selection we based on 0355 * 0356 * Please note that the actual operation starts asynchronously in 0357 * a background, so you cannot expect the operation being completed 0358 * right after the call 0359 */ 0360 void shearNode(KisNodeSP node, double angleX, double angleY, KisSelectionSP selection); 0361 0362 /** 0363 * Convert image projection to \p dstColorSpace, keeping all the layers intouched. 0364 */ 0365 void convertImageProjectionColorSpace(const KoColorSpace *dstColorSpace); 0366 0367 /** 0368 * Convert the image and all its layers to the dstColorSpace 0369 */ 0370 void convertImageColorSpace(const KoColorSpace *dstColorSpace, 0371 KoColorConversionTransformation::Intent renderingIntent, 0372 KoColorConversionTransformation::ConversionFlags conversionFlags); 0373 0374 /** 0375 * Convert layer and all its child layers to dstColorSpace 0376 */ 0377 void convertLayerColorSpace(KisNodeSP node, 0378 const KoColorSpace *dstColorSpace, 0379 KoColorConversionTransformation::Intent renderingIntent, 0380 KoColorConversionTransformation::ConversionFlags conversionFlags); 0381 0382 0383 // Get the profile associated with this image 0384 const KoColorProfile * profile() const; 0385 0386 /** 0387 * Set the profile of the layer and all its children to the new profile. 0388 * It doesn't do any pixel conversion. 0389 * 0390 * This is essential if you have loaded an image that didn't 0391 * have an embedded profile to which you want to attach the right profile. 0392 * 0393 * @returns false if the profile could not be assigned 0394 */ 0395 bool assignLayerProfile(KisNodeSP node, const KoColorProfile *profile); 0396 0397 /** 0398 * Set the profile of the image to the new profile and do the same for 0399 * all layers that have the same colorspace and profile of the image. 0400 * It doesn't do any pixel conversion. 0401 * 0402 * This is essential if you have loaded an image that didn't 0403 * have an embedded profile to which you want to attach the right profile. 0404 * 0405 * @returns false if the profile could not be assigned 0406 */ 0407 bool assignImageProfile(const KoColorProfile *profile, bool blockAllUpdates = false); 0408 0409 /** 0410 * Returns the current undo adapter. You can add new commands to the 0411 * undo stack using the adapter. This adapter is used for a backward 0412 * compatibility for old commands created before strokes. It blocks 0413 * all the processing at the scheduler, waits until it's finished 0414 * and executes commands exclusively. 0415 */ 0416 KisUndoAdapter* undoAdapter() const; 0417 0418 /** 0419 * This adapter is used by the strokes system. The commands are added 0420 * to it *after* redo() is done (in the scheduler context). They are 0421 * wrapped into a special command and added to the undo stack. redo() 0422 * in not called. 0423 */ 0424 KisPostExecutionUndoAdapter* postExecutionUndoAdapter() const override; 0425 0426 /** 0427 * Return the lastly executed LoD0 command. It is effectively the same 0428 * as to call undoAdapter()->presentCommand(); 0429 */ 0430 const KUndo2Command* lastExecutedCommand() const override; 0431 0432 /** 0433 * Replace current undo store with the new one. The old store 0434 * will be deleted. 0435 * This method is used by KisDocument for dropping all the commands 0436 * during file loading. 0437 */ 0438 void setUndoStore(KisUndoStore *undoStore); 0439 0440 /** 0441 * Return current undo store of the image 0442 */ 0443 KisUndoStore* undoStore(); 0444 0445 /** 0446 * Tell the image it's modified without creation of an undo command. 0447 * It may happen when e.g. layer visibility has changed. 0448 * 0449 * This function emits both, sigImageModified() and 0450 * sigImageModifiedWithoutUndo() 0451 * 0452 * For normal modifications with undo information the signal 0453 * emission is triggered by the undo stack 0454 */ 0455 void setModifiedWithoutUndo(); 0456 0457 /** 0458 * The default colorspace of this image: new layers will have this 0459 * colorspace and the projection will have this colorspace. 0460 */ 0461 const KoColorSpace * colorSpace() const; 0462 0463 /** 0464 * X resolution in pixels per pt 0465 */ 0466 double xRes() const; 0467 0468 /** 0469 * Y resolution in pixels per pt 0470 */ 0471 double yRes() const; 0472 0473 /** 0474 * Set the resolution in pixels per pt. 0475 */ 0476 void setResolution(double xres, double yres); 0477 0478 /** 0479 * Convert a document coordinate to a pixel coordinate. 0480 * 0481 * @param documentCoord PostScript Pt coordinate to convert. 0482 */ 0483 QPointF documentToPixel(const QPointF &documentCoord) const; 0484 0485 /** 0486 * Convert a document coordinate to an integer pixel coordinate rounded down. 0487 * 0488 * @param documentCoord PostScript Pt coordinate to convert. 0489 */ 0490 QPoint documentToImagePixelFloored(const QPointF &documentCoord) const; 0491 0492 /** 0493 * Convert a document rectangle to a pixel rectangle. 0494 * 0495 * @param documentRect PostScript Pt rectangle to convert. 0496 */ 0497 QRectF documentToPixel(const QRectF &documentRect) const; 0498 0499 /** 0500 * Convert a pixel coordinate to a document coordinate. 0501 * 0502 * @param pixelCoord pixel coordinate to convert. 0503 */ 0504 QPointF pixelToDocument(const QPointF &pixelCoord) const; 0505 0506 /** 0507 * Convert an integer pixel coordinate to a document coordinate. 0508 * The document coordinate is at the centre of the pixel. 0509 * 0510 * @param pixelCoord pixel coordinate to convert. 0511 */ 0512 QPointF pixelToDocument(const QPoint &pixelCoord) const; 0513 0514 /** 0515 * Convert a document rectangle to an integer pixel rectangle. 0516 * 0517 * @param pixelCoord pixel coordinate to convert. 0518 */ 0519 QRectF pixelToDocument(const QRectF &pixelCoord) const; 0520 0521 /** 0522 * Return the width of the image 0523 */ 0524 qint32 width() const; 0525 0526 /** 0527 * Return the height of the image 0528 */ 0529 qint32 height() const; 0530 0531 /** 0532 * Return the size of the image 0533 */ 0534 QSize size() const { 0535 return QSize(width(), height()); 0536 } 0537 0538 /** 0539 * @return the root node of the image node graph 0540 */ 0541 KisGroupLayerSP rootLayer() const; 0542 0543 /** 0544 * Return the projection; that is, the complete, composited 0545 * representation of this image. 0546 */ 0547 KisPaintDeviceSP projection() const; 0548 0549 /** 0550 * Return the number of layers (not other nodes) that are in this 0551 * image. 0552 */ 0553 qint32 nlayers() const; 0554 0555 /** 0556 * Return the number of layers (not other node types) that are in 0557 * this image and that are hidden. 0558 */ 0559 qint32 nHiddenLayers() const; 0560 0561 /* 0562 * Return the number of layers (not other node tyoes) that are 0563 * descendants of the rootLayer in this image. 0564 */ 0565 qint32 nChildLayers() const; 0566 0567 /** 0568 * Merge all visible layers and discard hidden ones. 0569 */ 0570 void flatten(KisNodeSP activeNode); 0571 0572 /** 0573 * Merge the specified layer with the layer 0574 * below this layer, remove the specified layer. 0575 */ 0576 void mergeDown(KisLayerSP l, const KisMetaData::MergeStrategy* strategy); 0577 0578 /** 0579 * flatten the layer: that is, the projection becomes the layer 0580 * and all subnodes are removed. If this is not a paint layer, it will morph 0581 * into a paint layer. 0582 */ 0583 void flattenLayer(KisLayerSP layer); 0584 0585 /** 0586 * Merges layers in \p mergedLayers and creates a new layer above 0587 * \p putAfter 0588 */ 0589 void mergeMultipleLayers(QList<KisNodeSP> mergedLayers, KisNodeSP putAfter); 0590 0591 /// @return the exact bounds of the image in pixel coordinates. 0592 QRect bounds() const override; 0593 0594 /** 0595 * Returns the actual bounds of the image, taking LevelOfDetail 0596 * into account. This value is used as a bounds() value of 0597 * KisDefaultBounds object. 0598 */ 0599 QRect effectiveLodBounds() const; 0600 0601 /// use if the layers have changed _completely_ (eg. when flattening) 0602 void notifyLayersChanged(); 0603 0604 /** 0605 * Sets the default color of the root layer projection. All the layers 0606 * will be merged on top of this very color 0607 */ 0608 void setDefaultProjectionColor(const KoColor &color); 0609 0610 /** 0611 * \see setDefaultProjectionColor() 0612 */ 0613 KoColor defaultProjectionColor() const; 0614 0615 void setRootLayer(KisGroupLayerSP rootLayer); 0616 0617 /** 0618 * Add an annotation for this image. This can be anything: Gamma, EXIF, etc. 0619 * Note that the "icc" annotation is reserved for the color strategies. 0620 * If the annotation already exists, overwrite it with this one. 0621 */ 0622 void addAnnotation(KisAnnotationSP annotation); 0623 0624 /** get the annotation with the given type, can return 0 */ 0625 KisAnnotationSP annotation(const QString& type); 0626 0627 /** delete the annotation, if the image contains it */ 0628 void removeAnnotation(const QString& type); 0629 0630 /** 0631 * Start of an iteration over the annotations of this image (including the ICC Profile) 0632 */ 0633 vKisAnnotationSP_it beginAnnotations(); 0634 0635 /** end of an iteration over the annotations of this image */ 0636 vKisAnnotationSP_it endAnnotations(); 0637 0638 /** 0639 * Called before the image is deleted and sends the sigAboutToBeDeleted signal 0640 */ 0641 void notifyAboutToBeDeleted(); 0642 0643 KisImageSignalRouter* signalRouter(); 0644 0645 /** 0646 * Returns whether we can reselect current global selection 0647 * 0648 * \see reselectGlobalSelection() 0649 */ 0650 bool canReselectGlobalSelection(); 0651 0652 /** 0653 * Returns the layer compositions for the image 0654 */ 0655 QList<KisLayerCompositionSP> compositions(); 0656 0657 /** 0658 * Adds a new layer composition, will be saved with the image 0659 */ 0660 void addComposition(KisLayerCompositionSP composition); 0661 0662 /** 0663 * Remove the layer compostion 0664 */ 0665 void removeComposition(KisLayerCompositionSP composition); 0666 0667 /** 0668 * Move a composition up in the composition list 0669 */ 0670 void moveCompositionUp(KisLayerCompositionSP composition); 0671 0672 /** 0673 * Move a composition down in the composition list 0674 */ 0675 void moveCompositionDown(KisLayerCompositionSP composition); 0676 0677 /** 0678 * Permit or deny the wrap-around mode for all the paint devices 0679 * of the image. Note that permitting the wraparound mode will not 0680 * necessarily activate it right now. To be activated the wrap 0681 * around mode should be 1) permitted; 2) supported by the 0682 * currently running stroke. 0683 */ 0684 void setWrapAroundModePermitted(bool value); 0685 0686 /** 0687 * \return whether the wrap-around mode is permitted for this 0688 * image. If the wrap around mode is permitted and the 0689 * currently running stroke supports it, the mode will be 0690 * activated for all paint devices of the image. 0691 * 0692 * \see setWrapAroundMode 0693 */ 0694 bool wrapAroundModePermitted() const; 0695 0696 0697 /** 0698 * \return whether the wraparound mode is activated for all the 0699 * devices of the image. The mode is activated when both 0700 * factors are true: the user permitted it and the stroke 0701 * supports it 0702 */ 0703 bool wrapAroundModeActive() const; 0704 0705 /** 0706 * \return current level of detail which is used when processing the image. 0707 * Current working zoom = 2 ^ (- currentLevelOfDetail()). Default value is 0708 * null, which means we work on the original image. 0709 */ 0710 int currentLevelOfDetail() const; 0711 0712 /** 0713 * Relative position of the mirror axis center 0714 * 0,0 - topleft corner of the image 0715 * 1,1 - bottomright corner of the image 0716 */ 0717 QPointF mirrorAxesCenter() const; 0718 0719 /** 0720 * Sets the relative position of the axes center 0721 * \see mirrorAxesCenter() for details 0722 */ 0723 void setMirrorAxesCenter(const QPointF &value) const; 0724 0725 /** 0726 * Configure the image to allow masks on the root not (as reported by 0727 * root()->allowAsChild()). By default it is not allowed (because it 0728 * looks weird from GUI point of view) 0729 */ 0730 void setAllowMasksOnRootNode(bool value); 0731 0732 /** 0733 * \see setAllowMasksOnRootNode() 0734 */ 0735 bool allowMasksOnRootNode() const; 0736 0737 public Q_SLOTS: 0738 0739 /** 0740 * Explicitly start regeneration of LoD planes of all the devices 0741 * in the image. This call should be performed when the user is idle, 0742 * just to make the quality of image updates better. 0743 */ 0744 void explicitRegenerateLevelOfDetail(); 0745 0746 public: 0747 0748 /** 0749 * Set preferences for the level-of-detail functionality. 0750 * Due to multithreading considerations they may be applied 0751 * not immediately, but some time later. 0752 */ 0753 void setLodPreferences(const KisLodPreferences &value); 0754 0755 /** 0756 * Return current lod-preferences used by the strokes queue. They 0757 * may differ from the preferences that has been assigned before 0758 * due to multi-stage application process (due to multithreading 0759 * considerations) 0760 */ 0761 KisLodPreferences lodPreferences() const; 0762 0763 KisImageAnimationInterface *animationInterface() const; 0764 0765 /** 0766 * @brief setProofingConfiguration, this sets the image's proofing configuration, and signals 0767 * the proofingConfiguration has changed. 0768 * @param proofingConfig - the kis proofing config that will be used instead. 0769 */ 0770 void setProofingConfiguration(KisProofingConfigurationSP proofingConfig); 0771 /** 0772 * @brief proofingConfiguration 0773 * @return the proofing configuration of the image. 0774 */ 0775 KisProofingConfigurationSP proofingConfiguration() const; 0776 0777 public Q_SLOTS: 0778 bool startIsolatedMode(KisNodeSP node, bool isolateLayer, bool isolateGroup); 0779 void stopIsolatedMode(); 0780 0781 public: 0782 KisNodeSP isolationRootNode() const; 0783 bool isIsolatingLayer() const; 0784 bool isIsolatingGroup() const; 0785 0786 Q_SIGNALS: 0787 0788 /** 0789 * Emitted whenever an action has caused the image to be 0790 * recomposited. Parameter is the rect that has been recomposited. 0791 */ 0792 void sigImageUpdated(const QRect &); 0793 0794 /** 0795 Emitted whenever the image has been modified, so that it 0796 doesn't match with the version saved on disk. 0797 */ 0798 void sigImageModified(); 0799 0800 /** 0801 Emitted whenever the image has been modified without creation 0802 of an undo command 0803 */ 0804 void sigImageModifiedWithoutUndo(); 0805 0806 /** 0807 * The signal is emitted when the size of the image is changed. 0808 * \p oldStillPoint and \p newStillPoint give the receiver the 0809 * hint about how the new and old rect of the image correspond to 0810 * each other. They specify the point of the image around which 0811 * the conversion was done. This point will stay still on the 0812 * user's screen. That is the \p newStillPoint of the new image 0813 * will be painted at the same screen position, where \p 0814 * oldStillPoint of the old image was painted. 0815 * 0816 * \param oldStillPoint is a still point represented in *old* 0817 * image coordinates 0818 * 0819 * \param newStillPoint is a still point represented in *new* 0820 * image coordinates 0821 */ 0822 void sigSizeChanged(const QPointF &oldStillPoint, const QPointF &newStillPoint); 0823 0824 void sigProfileChanged(const KoColorProfile * profile); 0825 void sigColorSpaceChanged(const KoColorSpace* cs); 0826 void sigResolutionChanged(double xRes, double yRes); 0827 void sigRequestNodeReselection(KisNodeSP activeNode, const KisNodeList &selectedNodes); 0828 0829 /** 0830 * Inform the model that a node was changed 0831 */ 0832 void sigNodeChanged(KisNodeSP node); 0833 0834 /** 0835 * Inform that the image is going to be deleted 0836 */ 0837 void sigAboutToBeDeleted(); 0838 0839 /** 0840 * The signal is emitted right after a node has been connected 0841 * to the graph of the nodes. 0842 * 0843 * WARNING: you must not request any graph-related information 0844 * about the node being run in a not-scheduler thread. If you need 0845 * information about the parent/siblings of the node connect 0846 * with Qt::DirectConnection, get needed information and then 0847 * emit another Qt::AutoConnection signal to pass this information 0848 * to your thread. See details of the implementation 0849 * in KisDummiesfacadeBase. 0850 */ 0851 void sigNodeAddedAsync(KisNodeSP node); 0852 0853 /** 0854 * This signal is emitted right before a node is going to removed 0855 * from the graph of the nodes. 0856 * 0857 * WARNING: you must not request any graph-related information 0858 * about the node being run in a not-scheduler thread. 0859 * 0860 * \see comment in sigNodeAddedAsync() 0861 */ 0862 void sigRemoveNodeAsync(KisNodeSP node); 0863 0864 /** 0865 * Emitted when the root node of the image has changed. 0866 * It happens, e.g. when we flatten the image. When 0867 * this happens the receiver should reload information 0868 * about the image 0869 */ 0870 void sigLayersChangedAsync(); 0871 0872 /** 0873 * Emitted when the UI has requested the undo of the last stroke's 0874 * operation. The point is, we cannot deal with the internals of 0875 * the stroke without its creator knowing about it (which most 0876 * probably cause a crash), so we just forward this request from 0877 * the UI to the creator of the stroke. 0878 * 0879 * If your tool supports undoing part of its work, just listen to 0880 * this signal and undo when it comes 0881 */ 0882 void sigUndoDuringStrokeRequested(); 0883 0884 /** 0885 * Emitted when the UI has requested the redo of the last undo 0886 * operation. 0887 * 0888 * If your tool supports undoing/redoing part of its work, just listen 0889 * to this signal and undo when it comes 0890 */ 0891 void sigRedoDuringStrokeRequested(); 0892 0893 /** 0894 * Emitted when the UI has requested the cancellation of 0895 * the stroke. The point is, we cannot cancel the stroke 0896 * without its creator knowing about it (which most probably 0897 * cause a crash), so we just forward this request from the UI 0898 * to the creator of the stroke. 0899 * 0900 * If your tool supports cancelling of its work in the middle 0901 * of operation, just listen to this signal and cancel 0902 * the stroke when it comes 0903 */ 0904 void sigStrokeCancellationRequested(); 0905 0906 /** 0907 * Emitted when the image decides that the stroke should better 0908 * be ended. The point is, we cannot just end the stroke 0909 * without its creator knowing about it (which most probably 0910 * cause a crash), so we just forward this request from the UI 0911 * to the creator of the stroke. 0912 * 0913 * If your tool supports long strokes that may involve multiple 0914 * mouse actions in one stroke, just listen to this signal and 0915 * end the stroke when it comes. 0916 */ 0917 void sigStrokeEndRequested(); 0918 0919 /** 0920 * Same as sigStrokeEndRequested() but is not emitted when the active node 0921 * is changed. 0922 */ 0923 void sigStrokeEndRequestedActiveNodeFiltered(); 0924 0925 /** 0926 * Emitted when the isolated mode status has changed. 0927 * 0928 * Can be used by the receivers to catch a fact of forcefully 0929 * stopping the isolated mode by the image when some complex 0930 * action was requested 0931 */ 0932 void sigIsolatedModeChanged(); 0933 0934 /** 0935 * Emitted when one or more nodes changed the collapsed state 0936 * 0937 */ 0938 void sigNodeCollapsedChanged(); 0939 0940 /** 0941 * Emitted when the proofing configuration of the image is being changed. 0942 * 0943 */ 0944 void sigProofingConfigChanged(); 0945 0946 /** 0947 * Internal signal for asynchronously requesting isolated mode to stop. Don't use it 0948 * outside KisImage, use sigIsolatedModeChanged() instead. 0949 */ 0950 void sigInternalStopIsolatedModeRequested(); 0951 0952 public Q_SLOTS: 0953 KisCompositeProgressProxy* compositeProgressProxy(); 0954 0955 bool isIdle(bool allowLocked = false); 0956 0957 /** 0958 * @brief Wait until all the queued background jobs are completed and lock the image. 0959 * 0960 * KisImage object has a local scheduler that executes long-running image 0961 * rendering/modifying jobs (we call them "strokes") in a background. Basically, 0962 * one should either access the image from the scope of such jobs (strokes) or 0963 * just lock the image before using. 0964 * 0965 * Calling barrierLock() will wait until all the queued operations are finished 0966 * and lock the image, so you can start accessing it in a safe way. 0967 * 0968 * @p readOnly tells the image if the caller is going to modify the image during 0969 * holding the lock. Locking with non-readOnly access will reset all 0970 * the internal caches of the image (lod-planes) when the lock status 0971 * will be lifted. 0972 */ 0973 void barrierLock(bool readOnly = false); 0974 0975 /** 0976 * @brief Tries to lock the image without waiting for the jobs to finish 0977 * 0978 * Same as barrierLock(), but doesn't block execution of the calling thread 0979 * until all the background jobs are finished. Instead, in case of presence of 0980 * unfinished jobs in the queue, it just returns false 0981 * 0982 * @return whether the lock has been acquired 0983 * @see barrierLock 0984 */ 0985 bool tryBarrierLock(bool readOnly = false); 0986 0987 /** 0988 * Wait for all the internal image jobs to complete and return without locking 0989 * the image. This function is handly for tests or other synchronous actions, 0990 * when one needs to wait for the result of his actions. 0991 */ 0992 void waitForDone(); 0993 0994 KisStrokeId startStroke(KisStrokeStrategy *strokeStrategy) override; 0995 void addJob(KisStrokeId id, KisStrokeJobData *data) override; 0996 void endStroke(KisStrokeId id) override; 0997 bool cancelStroke(KisStrokeId id) override; 0998 0999 /** 1000 * @brief blockUpdates block updating the image projection 1001 */ 1002 void blockUpdates() override; 1003 1004 /** 1005 * @brief unblockUpdates unblock updating the image project. This 1006 * only restarts the scheduler and does not schedule a full refresh. 1007 */ 1008 void unblockUpdates() override; 1009 1010 /** 1011 * Disables notification of the UI about the changes in the image. 1012 * This feature is used by KisProcessingApplicator. It is needed 1013 * when we change the size of the image. In this case, the whole 1014 * image will be reloaded into UI by sigSizeChanged(), so there is 1015 * no need to inform the UI about individual dirty rects. 1016 * 1017 * The last call to enableUIUpdates() will return the list of updates 1018 * that were requested while they were blocked. 1019 */ 1020 void disableUIUpdates() override; 1021 1022 /** 1023 * Notify GUI about a bunch of updates planned. GUI is expected to wait 1024 * until all the updates are completed, and render them on screen only 1025 * in the very and of the batch. 1026 */ 1027 void notifyBatchUpdateStarted() override; 1028 1029 /** 1030 * Notify GUI that batch update has been completed. Now GUI can start 1031 * showing all of them on screen. 1032 */ 1033 void notifyBatchUpdateEnded() override; 1034 1035 /** 1036 * Notify GUI that rect \p rc is now prepared in the image and 1037 * GUI can read data from it. 1038 * 1039 * WARNING: GUI will read the data right in the handler of this 1040 * signal, so exclusive access to the area must be guaranteed 1041 * by the caller. 1042 */ 1043 void notifyUIUpdateCompleted(const QRect &rc) override; 1044 1045 /** 1046 * \see disableUIUpdates 1047 */ 1048 QVector<QRect> enableUIUpdates() override; 1049 1050 /** 1051 * Disables the processing of all the setDirty() requests that 1052 * come to the image. The incoming requests are effectively 1053 * *dropped*. 1054 * 1055 * This feature is used by KisProcessingApplicator. For many cases 1056 * it provides its own updates interface, which recalculates the 1057 * whole subtree of nodes. But while we change any particular 1058 * node, it can ask for an update itself. This method is a way of 1059 * blocking such intermediate (and excessive) requests. 1060 * 1061 * NOTE: this is a convenience function for addProjectionUpdatesFilter() 1062 * that installs a predefined filter that eats everything. Please 1063 * note that these calls are *not* recursive. 1064 * 1065 * WARNING: The calls to enable/disable must be balanced. 1066 */ 1067 void disableDirtyRequests() override; 1068 1069 /** 1070 * \see disableDirtyRequests() 1071 */ 1072 void enableDirtyRequests() override; 1073 1074 /** 1075 * Installs a filter object that will filter all the incoming projection update 1076 * requests. If the filter return true, the incoming update is dropped. 1077 * 1078 * NOTE: you can add multiple filters to the image, **but** the calls to add/remove 1079 * must be nested and balanced. E.g. 1080 * 1081 * \code{.cpp} 1082 * 1083 * auto cookie1 = image->addProjectionUpdatesFilter(filter1); 1084 * auto cookie2 = image->addProjectionUpdatesFilter(filter2); 1085 * 1086 * /// ...do something... 1087 * 1088 * /// correct: 1089 * image->removeProjectionUpdatesFilter(cookie2) 1090 * image->removeProjectionUpdatesFilter(cookie1) 1091 * 1092 * /// incorrect: 1093 * // image->removeProjectionUpdatesFilter(cookie1) 1094 * // image->removeProjectionUpdatesFilter(cookie2) 1095 * \endcode 1096 */ 1097 KisProjectionUpdatesFilterCookie addProjectionUpdatesFilter(KisProjectionUpdatesFilterSP filter) override; 1098 1099 /** 1100 * @brief removes already installed filter from the stack of updates filers 1101 * @param cookie a cookie object returned by addProjectionUpdatesFilter() on intallation 1102 * @return the installed filter. If the cookie is invalid, or nesting rule has been 1103 * broken, then removeProjectionUpdatesFilter() may safe-assert and return nullptr. 1104 * 1105 * NOTE: some weird code (e.g. KisRegenerateFrameStrokeStrategy) needs to temporary remove 1106 * all the filters and then install them back. Current implementation ensures that after removal 1107 * and the following installation, cookies will be preserved. So this operation is considered 1108 * safe. 1109 * 1110 * \see addProjectionUpdatesFilter() 1111 */ 1112 KisProjectionUpdatesFilterSP removeProjectionUpdatesFilter(KisProjectionUpdatesFilterCookie cookie) override; 1113 1114 /** 1115 * Return the cookie of the lastly-installed filter 1116 * 1117 * \see addProjectionUpdatesFilter() 1118 */ 1119 KisProjectionUpdatesFilterCookie currentProjectionUpdatesFilter() const override; 1120 1121 1122 void refreshGraphAsync(KisNodeSP root = KisNodeSP(), UpdateFlags flags = None) override; 1123 void refreshGraphAsync(KisNodeSP root, const QRect &rc, UpdateFlags flags = None) override; 1124 void refreshGraphAsync(KisNodeSP root, const QRect &rc, const QRect &cropRect, UpdateFlags flags = None) override; 1125 void refreshGraphAsync(KisNodeSP root, const QVector<QRect> &rects, const QRect &cropRect, UpdateFlags flags = None) override; 1126 1127 /** 1128 * Triggers synchronous recomposition of the projection 1129 */ 1130 void refreshGraph(KisNodeSP root = KisNodeSP()); 1131 void refreshGraph(KisNodeSP root, const QRect& rc, const QRect &cropRect); 1132 void initialRefreshGraph(); 1133 1134 /** 1135 * Initiate a stack regeneration skipping the recalculation of the 1136 * filthy node's projection. 1137 * 1138 * Works exactly as pseudoFilthy->setDirty() with the only 1139 * exception that pseudoFilthy::updateProjection() will not be 1140 * called. That is used by KisRecalculateTransformMaskJob to avoid 1141 * cyclic dependencies. 1142 */ 1143 void requestProjectionUpdateNoFilthy(KisNodeSP pseudoFilthy, const QRect &rc, const QRect &cropRect); 1144 1145 void requestProjectionUpdateNoFilthy(KisNodeSP pseudoFilthy, const QRect &rc, const QRect &cropRect, const bool notifyFrameChange ); 1146 1147 void requestProjectionUpdateNoFilthy(KisNodeSP pseudoFilthy, const QVector<QRect> &rects, const QRect &cropRect, const bool resetAnimationCache); 1148 1149 /** 1150 * Adds a spontaneous job to the updates queue. 1151 * 1152 * A spontaneous job may do some trivial tasks in the background, 1153 * like updating the outline of selection or purging unused tiles 1154 * from the existing paint devices. 1155 */ 1156 void addSpontaneousJob(KisSpontaneousJob *spontaneousJob); 1157 1158 /** 1159 * \return true if there are some updates in the updates queue. 1160 * Please note, that is doesn't guarantee that there are no updates 1161 * running in the updater context at the very moment. To guarantee that 1162 * there are no updates left at all, please use barrier jobs instead. 1163 */ 1164 bool hasUpdatesRunning() const override; 1165 1166 /** 1167 * This method is called by the UI (*not* by the creator of the 1168 * stroke) when it thinks the current stroke should undo its last 1169 * action, for example, when the user presses Ctrl+Z while some 1170 * stroke is active. 1171 * 1172 * If the creator of the stroke supports undoing of intermediate 1173 * actions, it will be notified about this request and can undo 1174 * its last action. 1175 */ 1176 void requestUndoDuringStroke(); 1177 1178 /** 1179 * This method is called by the UI (*not* by the creator of the 1180 * stroke) when it thinks the current stroke should redo its last 1181 * undo, for example, when the user presses Ctrl+Shift+Z while some 1182 * stroke is active. 1183 * 1184 * If the creator of the stroke supports undoing/redoing of an 1185 * intermediate actions, it will be notified about this request and 1186 * can undo its last action. 1187 */ 1188 void requestRedoDuringStroke(); 1189 1190 /** 1191 * This method is called by the UI (*not* by the creator of the 1192 * stroke) when it thinks current stroke should be cancelled. If 1193 * there is a running stroke that has already been detached from 1194 * its creator (ended or cancelled), it will be forcefully 1195 * cancelled and reverted. If there is an open stroke present, and 1196 * if its creator supports cancelling, it will be notified about 1197 * the request and the stroke will be cancelled 1198 */ 1199 void requestStrokeCancellation(); 1200 1201 /** 1202 * This method requests the last stroke executed on the image to become undone. 1203 * If the stroke is not ended, or if all the Lod0 strokes are completed, the method 1204 * returns UNDO_FAIL. If the last Lod0 is going to be finished soon, then UNDO_WAIT 1205 * is returned and the caller should just wait for its completion and call global undo 1206 * instead. UNDO_OK means one unfinished stroke has been undone. 1207 */ 1208 UndoResult tryUndoUnfinishedLod0Stroke(); 1209 1210 /** 1211 * This method is called when image or some other part of Krita 1212 * (*not* the creator of the stroke) decides that the stroke 1213 * should be ended. If the creator of the stroke supports it, it 1214 * will be notified and the stroke will be cancelled 1215 */ 1216 void requestStrokeEnd(); 1217 1218 /** 1219 * Same as requestStrokeEnd() but is called by view manager when 1220 * the current node is changed. Use to distinguish 1221 * sigStrokeEndRequested() and 1222 * sigStrokeEndRequestedActiveNodeFiltered() which are used by 1223 * KisNodeJugglerCompressed 1224 */ 1225 void requestStrokeEndActiveNode(); 1226 1227 private: 1228 1229 KisImage(const KisImage& rhs, KisUndoStore *undoStore, bool exactCopy); 1230 KisImage& operator=(const KisImage& rhs); 1231 1232 void emitSizeChanged(); 1233 1234 void resizeImageImpl(const QRect& newRect, bool cropLayers); 1235 void rotateImpl(const KUndo2MagicString &actionName, KisNodeSP rootNode, double radians, 1236 bool resizeImage, KisSelectionSP selection); 1237 void shearImpl(const KUndo2MagicString &actionName, KisNodeSP rootNode, 1238 bool resizeImage, double angleX, double angleY, KisSelectionSP selection); 1239 1240 void safeRemoveTwoNodes(KisNodeSP node1, KisNodeSP node2); 1241 1242 void refreshHiddenArea(KisNodeSP rootNode, const QRect &preparedArea); 1243 1244 void requestProjectionUpdateImpl(KisNode *node, 1245 const QVector<QRect> &rects, 1246 const QRect &cropRect); 1247 1248 friend class KisImageResizeCommand; 1249 void setSize(const QSize& size); 1250 1251 void setProjectionColorSpace(const KoColorSpace * colorSpace); 1252 1253 1254 friend class KisDeselectGlobalSelectionCommand; 1255 friend class KisReselectGlobalSelectionCommand; 1256 friend class KisSetGlobalSelectionCommand; 1257 friend class KisImageTest; 1258 friend class Document; // For libkis 1259 1260 /** 1261 * Replaces the current global selection with globalSelection. If 1262 * \p globalSelection is empty, removes the selection object, so that 1263 * \ref globalSelection() will return 0 after that. 1264 */ 1265 void setGlobalSelection(KisSelectionSP globalSelection); 1266 1267 /** 1268 * Deselects current global selection. 1269 * \ref globalSelection() will return 0 after that. 1270 */ 1271 void deselectGlobalSelection(); 1272 1273 /** 1274 * Reselects current deselected selection 1275 * 1276 * \see deselectGlobalSelection() 1277 */ 1278 void reselectGlobalSelection(); 1279 1280 private: 1281 class KisImagePrivate; 1282 KisImagePrivate * m_d; 1283 }; 1284 1285 #endif // KIS_IMAGE_H_