File indexing completed on 2024-05-12 15:58:31
0001 /* 0002 * SPDX-FileCopyrightText: 2002 patrick julien <freak@codepimps.org> 0003 * SPDX-FileCopyrightText: 2006 Boudewijn Rempt <boud@valdyas.org> 0004 * SPDX-FileCopyrightText: 2021 L. E. Segovia <amy@amyspark.me> 0005 * 0006 * SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 #ifndef KIS_PAINT_DEVICE_IMPL_H_ 0009 #define KIS_PAINT_DEVICE_IMPL_H_ 0010 0011 #include <QObject> 0012 #include <QRect> 0013 #include <QVector> 0014 0015 #include "kis_debug.h" 0016 0017 #include <KoColorConversionTransformation.h> 0018 0019 #include "kis_types.h" 0020 #include "kis_shared.h" 0021 #include "kis_default_bounds_base.h" 0022 0023 #include <kritaimage_export.h> 0024 0025 class KUndo2Command; 0026 class QRect; 0027 class QImage; 0028 class QPoint; 0029 class QString; 0030 class QColor; 0031 class QIODevice; 0032 0033 class KoColor; 0034 class KoColorSpace; 0035 class KoColorProfile; 0036 0037 class KisRegion; 0038 class KisDataManager; 0039 class KisPaintDeviceWriter; 0040 class KisKeyframe; 0041 class KisRasterKeyframeChannel; 0042 0043 class KisPaintDeviceFramesInterface; 0044 0045 class KisInterstrokeData; 0046 using KisInterstrokeDataSP = QSharedPointer<KisInterstrokeData>; 0047 0048 typedef KisSharedPtr<KisDataManager> KisDataManagerSP; 0049 0050 namespace KritaUtils { 0051 enum DeviceCopyMode { 0052 CopySnapshot = 0, 0053 CopyAllFrames 0054 }; 0055 } 0056 0057 0058 /** 0059 * A paint device contains the actual pixel data and offers methods 0060 * to read and write pixels. A paint device has an integer x, y position 0061 * (it is not positioned on the image with sub-pixel accuracy). 0062 * A KisPaintDevice doesn't have any fixed size, the size changes dynamically 0063 * when pixels are accessed by an iterator. 0064 */ 0065 class KRITAIMAGE_EXPORT KisPaintDevice 0066 : public QObject 0067 , public KisShared 0068 { 0069 0070 Q_OBJECT 0071 0072 public: 0073 0074 /** 0075 * Create a new paint device with the specified colorspace. 0076 * 0077 * @param colorSpace the colorspace of this paint device 0078 * @param name for debugging purposes 0079 */ 0080 explicit KisPaintDevice(const KoColorSpace * colorSpace, const QString& name = QString()); 0081 0082 /** 0083 * Create a new paint device with the specified colorspace. The 0084 * parent node will be notified of changes to this paint device. 0085 * 0086 * @param parent the node that contains this paint device 0087 * @param colorSpace the colorspace of this paint device 0088 * @param defaultBounds boundaries of the device in case it is empty 0089 * @param name for debugging purposes 0090 */ 0091 KisPaintDevice(KisNodeWSP parent, const KoColorSpace * colorSpace, KisDefaultBoundsBaseSP defaultBounds = KisDefaultBoundsBaseSP(), const QString& name = QString()); 0092 0093 /** 0094 * Creates a copy of this device. 0095 * 0096 * If \p copyMode is CopySnapshot, the newly created device clones the 0097 * current frame of \p rhs only (default and efficient 0098 * behavior). If \p copyFrames is CopyAllFrames, the new device is a deep 0099 * copy of the source with all the frames included. 0100 */ 0101 KisPaintDevice(const KisPaintDevice& rhs, KritaUtils::DeviceCopyMode copyMode = KritaUtils::CopySnapshot, KisNode *newParentNode = 0); 0102 ~KisPaintDevice() override; 0103 0104 void makeFullCopyFrom(const KisPaintDevice& rhs, KritaUtils::DeviceCopyMode copyMode = KritaUtils::CopySnapshot, KisNode *newParentNode = 0); 0105 0106 protected: 0107 /** 0108 * A special constructor for usage in KisPixelSelection. It allows 0109 * two paint devices to share a data manager. 0110 * 0111 * @param explicitDataManager data manager to use inside paint device 0112 * @param src source paint device to copy parameters from 0113 * @param name for debugging purposes 0114 */ 0115 KisPaintDevice(KisDataManagerSP explicitDataManager, 0116 KisPaintDeviceSP src, const QString& name = QString()); 0117 0118 public: 0119 0120 /** 0121 * Write the pixels of this paint device into the specified file store. 0122 */ 0123 bool write(KisPaintDeviceWriter &store); 0124 0125 /** 0126 * Fill this paint device with the pixels from the specified file store. 0127 */ 0128 bool read(QIODevice *stream); 0129 0130 public: 0131 0132 /** 0133 * set the parent node of the paint device 0134 */ 0135 void setParentNode(KisNodeWSP parent); 0136 0137 /** 0138 * set the default bounds for the paint device when 0139 * the default pixel is not completely transparent 0140 */ 0141 void setDefaultBounds(KisDefaultBoundsBaseSP bounds); 0142 0143 /** 0144 * the default bounds rect of the paint device 0145 */ 0146 KisDefaultBoundsBaseSP defaultBounds() const; 0147 0148 /** 0149 * Moves the device to these new coordinates (no incremental move) 0150 */ 0151 void moveTo(qint32 x, qint32 y); 0152 0153 /** 0154 * Convenience method for the above. 0155 */ 0156 virtual void moveTo(const QPoint& pt); 0157 0158 /** 0159 * Return an X,Y offset of the device in a convenient form 0160 */ 0161 QPoint offset() const; 0162 0163 /** 0164 * The X offset of the paint device 0165 */ 0166 qint32 x() const; 0167 0168 /** 0169 * The Y offset of the paint device 0170 */ 0171 qint32 y() const; 0172 0173 /** 0174 * set the X offset of the paint device 0175 */ 0176 void setX(qint32 x); 0177 0178 /** 0179 * set the Y offset of the paint device 0180 */ 0181 void setY(qint32 y); 0182 0183 /** 0184 * Retrieve the bounds of the paint device. The size is not exact, 0185 * but may be larger if the underlying datamanager works that way. 0186 * For instance, the tiled datamanager keeps the extent to the nearest 0187 * multiple of 64. 0188 * 0189 * If default pixel is not transparent, then the actual extent 0190 * rect is united with the defaultBounds()->bounds() value 0191 * (the size of the image, usually). 0192 */ 0193 QRect extent() const; 0194 0195 /// Convenience method for the above 0196 void extent(qint32 &x, qint32 &y, qint32 &w, qint32 &h) const; 0197 0198 /** 0199 * Get the exact bounds of this paint device. The real solution is 0200 * very slow because it does a linear scanline search, but it 0201 * uses caching, so calling to this function without changing 0202 * the device is quite cheap. 0203 * 0204 * Exactbounds follows these rules: 0205 * 0206 * <ul> 0207 * <li>if default pixel is transparent, then exact bounds 0208 * of actual pixel data are returned 0209 * <li>if default pixel is not transparent, then the union 0210 * (defaultBounds()->bounds() | nonDefaultPixelArea()) is 0211 * returned 0212 * </ul> 0213 * \see calculateExactBounds() 0214 */ 0215 QRect exactBounds() const; 0216 0217 /** 0218 * Relaxed version of the exactBounds() that can be used in tight 0219 * loops. If the exact bounds value is present in the paint 0220 * device cache, returns this value. If the cache is invalidated, 0221 * returns extent() and tries to recalculate the exact bounds not 0222 * faster than once in 1000 ms. 0223 */ 0224 QRect exactBoundsAmortized() const; 0225 0226 /** 0227 * Returns exact rectangle of the paint device that contains 0228 * non-default pixels. For paint devices with fully transparent 0229 * default pixel is equivalent to exactBounds(). 0230 * 0231 * nonDefaultPixelArea() follows these rules: 0232 * 0233 * <ul> 0234 * <li>if default pixel is transparent, then exact bounds 0235 * of actual pixel data are returned. The same as exactBounds() 0236 * <li>if default pixel is not transparent, then calculates the 0237 * rectangle of non-default pixels. May be smaller or greater 0238 * than image bounds 0239 * </ul> 0240 * \see calculateExactBounds() 0241 */ 0242 QRect nonDefaultPixelArea() const; 0243 0244 0245 /** 0246 * Returns a rough approximation of region covered by device. 0247 * For tiled data manager, it region will consist of a number 0248 * of rects each corresponding to a tile. 0249 */ 0250 KisRegion region() const; 0251 0252 /** 0253 * The slow version of region() that searches for exact bounds of 0254 * each rectangle in the region 0255 */ 0256 KisRegion regionExact() const; 0257 0258 /** 0259 * Cut the paint device down to the specified rect. If the crop 0260 * area is bigger than the paint device, nothing will happen. 0261 */ 0262 void crop(qint32 x, qint32 y, qint32 w, qint32 h); 0263 0264 /// Convenience method for the above 0265 void crop(const QRect & r); 0266 0267 /** 0268 * Complete erase the current paint device. Its size will become 0. This 0269 * does not take the selection into account. 0270 */ 0271 virtual void clear(); 0272 0273 /** 0274 * Clear the given rectangle to transparent black. The paint device will expand to 0275 * contain the given rect. 0276 */ 0277 void clear(const QRect & rc); 0278 0279 /** 0280 * Frees the memory occupied by the pixels containing default 0281 * values. The extents() and exactBounds() of the paint device will 0282 * probably also shrink 0283 */ 0284 void purgeDefaultPixels(); 0285 0286 /** 0287 * Sets the default pixel. New data will be initialised with this pixel. The pixel is copied: the 0288 * caller still owns the pointer and needs to delete it to avoid memory leaks. 0289 * If frame ID is given, set default pixel for that frame. Otherwise use active frame. 0290 */ 0291 void setDefaultPixel(const KoColor &defPixel); 0292 0293 /** 0294 * Get a pointer to the default pixel. 0295 * If the frame parameter is given, get the default pixel of 0296 * specified frame. Otherwise use currently active frame. 0297 */ 0298 KoColor defaultPixel() const; 0299 0300 /** 0301 * Fill the given rectangle with the given pixel. The paint device will expand to 0302 * contain the given rect. 0303 */ 0304 void fill(const QRect & rc, const KoColor &color); 0305 0306 /** 0307 * Overloaded function. For legacy purposes only. 0308 * Please use fill(const QRect & rc, const KoColor &color) instead 0309 */ 0310 void fill(qint32 x, qint32 y, qint32 w, qint32 h, const quint8 *fillPixel); 0311 0312 public: 0313 0314 /** 0315 * Prepares the device for fastBitBlt operation. It clears 0316 * the device, switches x,y shifts and colorspace if needed. 0317 * After this call fastBitBltPossible will return true. 0318 * May be used for initialization of temporary devices. 0319 */ 0320 void prepareClone(KisPaintDeviceSP src); 0321 0322 /** 0323 * Make this device to become a clone of \a src. It will have the same 0324 * x,y shifts, colorspace and will share pixels inside \a rect. 0325 * After calling this function: 0326 * (this->extent() >= this->exactBounds() == rect). 0327 * 0328 * Rule of thumb: 0329 * 0330 * "Use makeCloneFrom() or makeCloneFromRough() if and only if you 0331 * are the only owner of the destination paint device and you are 0332 * 100% sure no other thread has access to it" 0333 */ 0334 void makeCloneFrom(KisPaintDeviceSP src, const QRect &rect); 0335 0336 /** 0337 * Make this device to become a clone of \a src. It will have the same 0338 * x,y shifts, colorspace and will share pixels inside \a rect. 0339 * Be careful, this function will copy *at least* \a rect 0340 * of pixels. Actual copy area will be a bigger - it will 0341 * be aligned by tiles borders. So after calling this function: 0342 * (this->extent() == this->exactBounds() >= rect). 0343 * 0344 * Rule of thumb: 0345 * 0346 * "Use makeCloneFrom() or makeCloneFromRough() if and only if you 0347 * are the only owner of the destination paint device and you are 0348 * 100% sure no other thread has access to it" 0349 */ 0350 void makeCloneFromRough(KisPaintDeviceSP src, const QRect &minimalRect); 0351 0352 0353 protected: 0354 friend class KisPaintDeviceTest; 0355 friend class DataReaderThread; 0356 0357 /** 0358 * Checks whether a src paint device can be used as source 0359 * of fast bitBlt operation. The result of the check may 0360 * depend on whether color spaces coincide, whether there is 0361 * any shift of tiles between the devices and etc. 0362 * 0363 * WARNING: This check must be done <i>before</i> performing any 0364 * fast bitBlt operation! 0365 * 0366 * \see fastBitBlt 0367 * \see fastBitBltRough 0368 */ 0369 bool fastBitBltPossible(KisPaintDeviceSP src); 0370 0371 /** 0372 * Clones rect from another paint device. The cloned area will be 0373 * shared between both paint devices as much as possible using 0374 * copy-on-write. Parts of the rect that cannot be shared 0375 * (cross tiles) are deep-copied, 0376 * 0377 * \see fastBitBltPossible 0378 * \see fastBitBltRough 0379 */ 0380 void fastBitBlt(KisPaintDeviceSP src, const QRect &rect); 0381 0382 /** 0383 * The same as \ref fastBitBlt() but reads old data 0384 */ 0385 void fastBitBltOldData(KisPaintDeviceSP src, const QRect &rect); 0386 0387 /** 0388 * Clones rect from another paint device in a rough and fast way. 0389 * All the tiles touched by rect will be shared, between both 0390 * devices, that means it will copy a bigger area than was 0391 * requested. This method is supposed to be used for bitBlt'ing 0392 * into temporary paint devices. 0393 * 0394 * \see fastBitBltPossible 0395 * \see fastBitBlt 0396 */ 0397 void fastBitBltRough(KisPaintDeviceSP src, const QRect &rect); 0398 0399 /** 0400 * The same as \ref fastBitBltRough() but reads old data 0401 */ 0402 void fastBitBltRoughOldData(KisPaintDeviceSP src, const QRect &rect); 0403 0404 public: 0405 /** 0406 * Read the bytes representing the rectangle described by x, y, w, h into 0407 * data. If data is not big enough, Krita will gladly overwrite the rest 0408 * of your precious memory. 0409 * 0410 * Since this is a copy, you need to make sure you have enough memory. 0411 * 0412 * Reading from areas not previously initialized will read the default 0413 * pixel value into data but not initialize that region. 0414 */ 0415 void readBytes(quint8 * data, qint32 x, qint32 y, qint32 w, qint32 h) const; 0416 0417 /** 0418 * Read the bytes representing the rectangle rect into 0419 * data. If data is not big enough, Krita will gladly overwrite the rest 0420 * of your precious memory. 0421 * 0422 * Since this is a copy, you need to make sure you have enough memory. 0423 * 0424 * Reading from areas not previously initialized will read the default 0425 * pixel value into data but not initialize that region. 0426 * @param data The address of the memory to receive the bytes read 0427 * @param rect The rectangle in the paint device to read from 0428 */ 0429 void readBytes(quint8 * data, const QRect &rect) const; 0430 0431 /** 0432 * Copy the bytes in data into the rect specified by x, y, w, h. If the 0433 * data is too small or uninitialized, Krita will happily read parts of 0434 * memory you never wanted to be read. 0435 * 0436 * If the data is written to areas of the paint device not previously initialized, 0437 * the paint device will grow. 0438 */ 0439 void writeBytes(const quint8 * data, qint32 x, qint32 y, qint32 w, qint32 h); 0440 0441 /** 0442 * Copy the bytes in data into the rectangle rect. If the 0443 * data is too small or uninitialized, Krita will happily read parts of 0444 * memory you never wanted to be read. 0445 * 0446 * If the data is written to areas of the paint device not previously initialized, 0447 * the paint device will grow. 0448 * @param data The address of the memory to write bytes from 0449 * @param rect The rectangle in the paint device to write to 0450 */ 0451 void writeBytes(const quint8 * data, const QRect &rect); 0452 0453 /** 0454 * Copy the bytes in the paint device into a vector of arrays of bytes, 0455 * where the number of arrays is the number of channels in the 0456 * paint device. If the specified area is larger than the paint 0457 * device's extent, the default pixel will be read. 0458 */ 0459 QVector<quint8*> readPlanarBytes(qint32 x, qint32 y, qint32 w, qint32 h) const; 0460 0461 /** 0462 * Write the data in the separate arrays to the channels. If there 0463 * are less vectors than channels, the remaining channels will not 0464 * be copied. If any of the arrays points to 0, the channel in 0465 * that location will not be touched. If the specified area is 0466 * larger than the paint device, the paint device will be 0467 * extended. There are no guards: if the area covers more pixels 0468 * than there are bytes in the arrays, krita will happily fill 0469 * your paint device with areas of memory you never wanted to be 0470 * read. Krita may also crash. 0471 * 0472 * XXX: what about undo? 0473 */ 0474 void writePlanarBytes(QVector<quint8*> planes, qint32 x, qint32 y, qint32 w, qint32 h); 0475 0476 /** 0477 * Converts the paint device to a different colorspace 0478 */ 0479 void convertTo(const KoColorSpace *dstColorSpace, 0480 KoColorConversionTransformation::Intent renderingIntent = KoColorConversionTransformation::internalRenderingIntent(), 0481 KoColorConversionTransformation::ConversionFlags conversionFlags = KoColorConversionTransformation::internalConversionFlags(), 0482 KUndo2Command *parentCommand = nullptr, 0483 KoUpdater *progressUpdater = nullptr); 0484 0485 /** 0486 * Changes the profile of the colorspace of this paint device to the given 0487 * profile. If the given profile is 0, nothing happens. 0488 */ 0489 bool setProfile(const KoColorProfile * profile, KUndo2Command *parentCommand); 0490 0491 /** 0492 * Fill this paint device with the data from image; starting at (offsetX, offsetY) 0493 * @param image the image 0494 * @param profile name of the RGB profile to interpret the image as. 0 is interpreted as sRGB 0495 * @param offsetX x offset 0496 * @param offsetY y offset 0497 */ 0498 void convertFromQImage(const QImage& image, const KoColorProfile *profile, qint32 offsetX = 0, qint32 offsetY = 0); 0499 0500 /** 0501 * Create an RGBA QImage from a rectangle in the paint device. 0502 * 0503 * @param dstProfile RGB profile to use in conversion. May be 0, in which 0504 * case it's up to the color strategy to choose a profile (most 0505 * like sRGB). 0506 * @param x Left coordinate of the rectangle 0507 * @param y Top coordinate of the rectangle 0508 * @param w Width of the rectangle in pixels 0509 * @param h Height of the rectangle in pixels 0510 * @param renderingIntent Rendering intent 0511 * @param conversionFlags Conversion flags 0512 */ 0513 QImage convertToQImage(const KoColorProfile *dstProfile, qint32 x, qint32 y, qint32 w, qint32 h, 0514 KoColorConversionTransformation::Intent renderingIntent = KoColorConversionTransformation::internalRenderingIntent(), 0515 KoColorConversionTransformation::ConversionFlags conversionFlags = KoColorConversionTransformation::internalConversionFlags()) const; 0516 0517 /** 0518 * Overridden method for convenience 0519 */ 0520 QImage convertToQImage(const KoColorProfile *dstProfile, 0521 const QRect &rc, 0522 KoColorConversionTransformation::Intent renderingIntent = KoColorConversionTransformation::internalRenderingIntent(), 0523 KoColorConversionTransformation::ConversionFlags conversionFlags = KoColorConversionTransformation::internalConversionFlags()) const; 0524 0525 /** 0526 * Create an RGBA QImage from a rectangle in the paint device. The 0527 * rectangle is defined by the parent image's bounds. 0528 * 0529 * @param dstProfile RGB profile to use in conversion. May be 0, in which 0530 * case it's up to the color strategy to choose a profile (most 0531 * like sRGB). 0532 * @param renderingIntent Rendering intent 0533 * @param conversionFlags Conversion flags 0534 */ 0535 QImage convertToQImage(const KoColorProfile * dstProfile, 0536 KoColorConversionTransformation::Intent renderingIntent = KoColorConversionTransformation::internalRenderingIntent(), 0537 KoColorConversionTransformation::ConversionFlags conversionFlags = KoColorConversionTransformation::internalConversionFlags()) const; 0538 0539 /** 0540 * Creates a paint device thumbnail of the paint device, retaining 0541 * the aspect ratio. The width and height of the returned device 0542 * won't exceed \p maxw and \p maxw, but they may be smaller. 0543 * 0544 * @param w maximum width 0545 * @param h maximum height 0546 * @param rect only this rect will be used for the thumbnail 0547 * @param outputRect output rectangle 0548 * 0549 */ 0550 KisPaintDeviceSP createThumbnailDevice(qint32 w, qint32 h, QRect rect = QRect(), QRect outputRect = QRect()) const; 0551 KisPaintDeviceSP createThumbnailDeviceOversampled(qint32 w, qint32 h, qreal oversample, QRect rect = QRect(), QRect outputRect = QRect()) const; 0552 0553 /** 0554 * Creates a thumbnail of the paint device, retaining the aspect ratio. 0555 * The width and height of the returned QImage won't exceed \p maxw and \p maxw, but they may be smaller. 0556 * The colors are not corrected for display! 0557 * 0558 * @param maxw: maximum width 0559 * @param maxh: maximum height 0560 * @param rect: only this rect will be used for the thumbnail 0561 * @param oversample: ratio used for antialiasing 0562 * @param renderingIntent Rendering intent 0563 * @param conversionFlags Conversion flags 0564 */ 0565 QImage createThumbnail(qint32 maxw, qint32 maxh, QRect rect, qreal oversample = 1, 0566 KoColorConversionTransformation::Intent renderingIntent = KoColorConversionTransformation::internalRenderingIntent(), 0567 KoColorConversionTransformation::ConversionFlags conversionFlags = KoColorConversionTransformation::internalConversionFlags()); 0568 0569 /** 0570 * Cached version of createThumbnail(qint32 maxw, qint32 maxh, const KisSelection *selection, QRect rect) 0571 */ 0572 QImage createThumbnail(qint32 maxw, qint32 maxh, qreal oversample = 1, 0573 KoColorConversionTransformation::Intent renderingIntent = KoColorConversionTransformation::internalRenderingIntent(), 0574 KoColorConversionTransformation::ConversionFlags conversionFlags = KoColorConversionTransformation::internalConversionFlags()); 0575 0576 /** 0577 * Cached version of createThumbnail that also adjusts aspect ratio of the 0578 * thumbnail to fit the extents of the paint device. 0579 */ 0580 QImage createThumbnail(qint32 maxw, qint32 maxh, 0581 Qt::AspectRatioMode aspectRatioMode, 0582 qreal oversample = 1, 0583 KoColorConversionTransformation::Intent renderingIntent = KoColorConversionTransformation::internalRenderingIntent(), 0584 KoColorConversionTransformation::ConversionFlags conversionFlags = KoColorConversionTransformation::internalConversionFlags()); 0585 0586 /** 0587 * Fill c and opacity with the values found at x and y. 0588 * 0589 * The color values will be transformed from the profile of 0590 * this paint device to the display profile. 0591 * 0592 * @return true if the operation was successful. 0593 */ 0594 bool pixel(qint32 x, qint32 y, QColor *c) const; 0595 0596 /** 0597 * Fill kc with the values found at x and y. This method differs 0598 * from the above in using KoColor, which can be of any colorspace 0599 * 0600 * The color values will be transformed from the profile of 0601 * this paint device to the display profile. 0602 * 0603 * @return true if the operation was successful. 0604 */ 0605 bool pixel(qint32 x, qint32 y, KoColor * kc) const; 0606 0607 /** 0608 * Return pixel value in a form of KoColor. Please don't use this method 0609 * for iteration, it is highly inefficient. Use iterators instead. 0610 */ 0611 KoColor pixel(const QPoint &pos) const; 0612 0613 /** 0614 * Set the specified pixel to the specified color. Note that this 0615 * bypasses KisPainter. the PaintDevice is here used as an equivalent 0616 * to QImage, not QPixmap. This means that this is not undoable; also, 0617 * there is no compositing with an existing value at this location. 0618 * 0619 * The color values will be transformed from the display profile to 0620 * the paint device profile. 0621 * 0622 * Note that this will use 8-bit values and may cause a significant 0623 * degradation when used on 16-bit or hdr quality images. 0624 * 0625 * @return true if the operation was successful 0626 */ 0627 bool setPixel(qint32 x, qint32 y, const QColor& c); 0628 0629 /// Convenience method for the above 0630 bool setPixel(qint32 x, qint32 y, const KoColor& kc); 0631 0632 /** 0633 * @return the colorspace of the pixels in this paint device 0634 */ 0635 const KoColorSpace* colorSpace() const; 0636 0637 /** 0638 * There is quite a common technique in Krita. It is used in 0639 * cases, when we want to paint something over a paint device 0640 * using the composition, opacity or selection. E.g. painting a 0641 * dab in a paint op, filling the selection in the Fill Tool. 0642 * Such work is usually done in the following way: 0643 * 0644 * 1) Create a paint device 0645 * 0646 * 2) Fill it with the desired color or data 0647 * 0648 * 3) Create a KisPainter and set all the properties of the 0649 * transaction: selection, compositeOp, opacity and etc. 0650 * 0651 * 4) Paint a newly created paint device over the destination 0652 * device. 0653 * 0654 * The following two methods (createCompositionSourceDevice() or 0655 * createCompositionSourceDeviceFixed())should be used for the 0656 * accomplishing the step 1). The point is that the desired color 0657 * space of the temporary device may not coincide with the color 0658 * space of the destination. That is the case, for example, for 0659 * the alpha8() colorspace used in the selections. So for such 0660 * devices the temporary target would have a different (grayscale) 0661 * color space. 0662 * 0663 * So there are two rules of thumb: 0664 * 0665 * 1) If you need a temporary device which you are going to fill 0666 * with some data and then paint over the paint device, create 0667 * it with either createCompositionSourceDevice() or 0668 * createCompositionSourceDeviceFixed(). 0669 * 0670 * 2) Do *not* expect that the color spaces of the destination and 0671 * the temporary device would coincide. If you need to copy a 0672 * single pixel from one device to another, you can use 0673 * KisCrossDeviceColorSampler class, that will handle all the 0674 * necessary conversions for you. 0675 * 0676 * \see createCompositionSourceDeviceFixed() 0677 * \see compositionSourceColorSpace() 0678 * \see KisCrossDeviceColorSampler 0679 * \see KisCrossDeviceColorSamplerInt 0680 */ 0681 KisPaintDeviceSP createCompositionSourceDevice() const; 0682 0683 /** 0684 * The same as createCompositionSourceDevice(), but initializes the 0685 * newly created device with the content of \p cloneSource 0686 * 0687 * \see createCompositionSourceDevice() 0688 */ 0689 KisPaintDeviceSP createCompositionSourceDevice(KisPaintDeviceSP cloneSource) const; 0690 0691 /** 0692 * The same as createCompositionSourceDevice(), but initializes 0693 * the newly created device with the *rough* \p roughRect of 0694 * \p cloneSource. 0695 * 0696 * "Rough rect" means that it may copy a bit more than 0697 * requested. It is expected that the caller will not use the area 0698 * outside \p roughRect. 0699 * 0700 * \see createCompositionSourceDevice() 0701 */ 0702 KisPaintDeviceSP createCompositionSourceDevice(KisPaintDeviceSP cloneSource, const QRect roughRect) const; 0703 0704 /** 0705 * This is a convenience method for createCompositionSourceDevice() 0706 * 0707 * \see createCompositionSourceDevice() 0708 */ 0709 KisFixedPaintDeviceSP createCompositionSourceDeviceFixed() const; 0710 0711 /** 0712 * This is a lowlevel method for the principle used in 0713 * createCompositionSourceDevice(). In most of the cases the paint 0714 * device creation methods should be used instead of this function. 0715 * 0716 * \see createCompositionSourceDevice() 0717 * \see createCompositionSourceDeviceFixed() 0718 */ 0719 virtual const KoColorSpace* compositionSourceColorSpace() const; 0720 0721 /** 0722 * @return the internal datamanager that keeps the pixels. 0723 */ 0724 KisDataManagerSP dataManager() const; 0725 0726 /** 0727 * Replace the pixel data, color strategy, and profile. 0728 */ 0729 void setDataManager(KisDataManagerSP data, const KoColorSpace * colorSpace = 0); 0730 0731 /** 0732 * Return the number of bytes a pixel takes. 0733 */ 0734 quint32 pixelSize() const; 0735 0736 /** 0737 * Return the number of channels a pixel takes 0738 */ 0739 quint32 channelCount() const; 0740 0741 /** 0742 * @return interstroke data that is atteched to the paint device. 0743 * 0744 * This data is managed by KisTransaction and can be used by brushes 0745 * to store some data that can be shared betweet the strokes. For 0746 * example, information about drying of the pigment. 0747 * 0748 * The interstroke data is stored in a per-frame manner, that is, 0749 * there is a separate per-stroke data for each frame. 0750 */ 0751 KisInterstrokeDataSP interstrokeData() const; 0752 0753 /** 0754 * @brief set interstroke data to the device 0755 * 0756 * Interstroke data is managed by KisTransaction, don't call this 0757 * method manually unless you really know what you are doing. 0758 * 0759 * @see interstrokeData() 0760 */ 0761 KUndo2Command* createChangeInterstrokeDataCommand(KisInterstrokeDataSP data); 0762 0763 /** 0764 * Create a keyframe channel for the content on this device. 0765 * @param id identifier for the channel 0766 * @return keyframe channel or 0 if there is not one 0767 */ 0768 KisRasterKeyframeChannel *createKeyframeChannel(const KoID &id); 0769 0770 KisRasterKeyframeChannel* keyframeChannel() const; 0771 0772 /** 0773 * An interface to modify/load/save frames stored inside this device 0774 */ 0775 KisPaintDeviceFramesInterface* framesInterface(); 0776 0777 /** 0778 * @brief burnKeyframe 0779 * 0780 * Take a frame from the keyframe channel, 0781 * Copy the contents onto the "base" frame, 0782 * and completely remove the keyframe channel. 0783 * 0784 * Should be useful for copy+paste operations where 0785 * we shouldn't expect keyframe data to persist. 0786 * 0787 * Parameterless version simply gets the current frameID. 0788 * 0789 * @param frameID -- frameID (from the framesInterface, **not the time**) to burn to device. 0790 * @return success 0791 */ 0792 bool burnKeyframe(int frameID); 0793 bool burnKeyframe(); 0794 0795 public: 0796 0797 /** 0798 * Add the specified rect to the parent layer's set of dirty rects 0799 * (if there is a parent layer) 0800 */ 0801 void setDirty(const QRect & rc); 0802 0803 void setDirty(const KisRegion ®ion); 0804 0805 /** 0806 * Set the parent layer completely dirty, if this paint device has 0807 * as parent layer. 0808 */ 0809 void setDirty(); 0810 0811 void setDirty(const QVector<QRect> &rects); 0812 0813 /** 0814 * Called by KisTransactionData when it thinks current time should 0815 * be changed. And the requests is forwarded to the image if 0816 * needed. 0817 */ 0818 void requestTimeSwitch(int time); 0819 0820 /** 0821 * \return a sequence number corresponding to the current paint 0822 * device state. Every time the paint device is changed, 0823 * the sequence number is increased 0824 */ 0825 int sequenceNumber() const; 0826 0827 0828 void estimateMemoryStats(qint64 &imageData, qint64 &temporaryData, qint64 &lodData) const; 0829 0830 public: 0831 0832 KisHLineIteratorSP createHLineIteratorNG(qint32 x, qint32 y, qint32 w); 0833 KisHLineConstIteratorSP createHLineConstIteratorNG(qint32 x, qint32 y, qint32 w) const; 0834 0835 KisVLineIteratorSP createVLineIteratorNG(qint32 x, qint32 y, qint32 h); 0836 KisVLineConstIteratorSP createVLineConstIteratorNG(qint32 x, qint32 y, qint32 h) const; 0837 0838 KisRandomAccessorSP createRandomAccessorNG(); 0839 KisRandomConstAccessorSP createRandomConstAccessorNG() const; 0840 0841 /** 0842 * Create an iterator that will "artificially" extend the paint device with the 0843 * value of the border when trying to access values outside the range of data. 0844 * 0845 * @param x x of top left corner 0846 * @param y y of top left corner 0847 * @param w width of the border 0848 * @param _dataWidth indicates the rectangle that truly contains data 0849 */ 0850 KisRepeatHLineConstIteratorSP createRepeatHLineConstIterator(qint32 x, qint32 y, qint32 w, const QRect& _dataWidth) const; 0851 /** 0852 * Create an iterator that will "artificially" extend the paint device with the 0853 * value of the border when trying to access values outside the range of data. 0854 * 0855 * @param x x of top left corner 0856 * @param y y of top left corner 0857 * @param h height of the border 0858 * @param _dataWidth indicates the rectangle that truly contains data 0859 */ 0860 KisRepeatVLineConstIteratorSP createRepeatVLineConstIterator(qint32 x, qint32 y, qint32 h, const QRect& _dataWidth) const; 0861 0862 /** 0863 * This function create a random accessor which can easily access to sub pixel values. 0864 */ 0865 KisRandomSubAccessorSP createRandomSubAccessor() const; 0866 0867 0868 /** Clear the selected pixels from the paint device */ 0869 void clearSelection(KisSelectionSP selection); 0870 0871 /** 0872 * Converts a paint device into a "new" paint device, that has 0873 * unconnected history. That is, after reincarnation, the device's 0874 * life starts a new page. No history. No memories. 0875 * 0876 * When the device is fed up with the new life, it can reincarnate 0877 * back to its previous life by undoing the command returned by 0878 * reincarnateWithDetachedHistory(). The old undo will continue 0879 * working as if nothing has happened. 0880 * 0881 * NOTE: reincarnation affects only the current lod plane and/or 0882 * current frame. All other frames are kept unaffected. 0883 * 0884 * @param copyContent decides if the device should take its current 0885 * content to the new life 0886 * @return undo command for execution and undoing of the reincarnation 0887 */ 0888 KUndo2Command* reincarnateWithDetachedHistory(bool copyContent); 0889 0890 Q_SIGNALS: 0891 0892 void profileChanged(const KoColorProfile * profile); 0893 void colorSpaceChanged(const KoColorSpace *colorspace); 0894 0895 public: 0896 friend class PaintDeviceCache; 0897 0898 /** 0899 * Caclculates exact bounds of the device. Used internally 0900 * by a transparent caching system. The solution is very slow 0901 * because it does a linear scanline search. So the complexity 0902 * is n*n at worst. 0903 * 0904 * \see exactBounds(), nonDefaultPixelArea() 0905 */ 0906 QRect calculateExactBounds(bool nonDefaultOnly) const; 0907 0908 public: 0909 struct MemoryReleaseObject : public QObject { 0910 ~MemoryReleaseObject() override; 0911 }; 0912 0913 static MemoryReleaseObject* createMemoryReleaseObject(); 0914 0915 public: 0916 struct LodDataStruct { 0917 virtual ~LodDataStruct(); 0918 }; 0919 0920 KisRegion regionForLodSyncing() const; 0921 LodDataStruct* createLodDataStruct(int lod); 0922 void updateLodDataStruct(LodDataStruct *dst, const QRect &srcRect); 0923 void uploadLodDataStruct(LodDataStruct *dst); 0924 0925 void generateLodCloneDevice(KisPaintDeviceSP dst, const QRect &originalRect, int lod); 0926 0927 void setProjectionDevice(bool value); 0928 void tesingFetchLodDevice(KisPaintDeviceSP targetDevice); 0929 0930 private: 0931 KisPaintDevice& operator=(const KisPaintDevice&); 0932 void init(const KoColorSpace *colorSpace, 0933 KisDefaultBoundsBaseSP defaultBounds, 0934 KisNodeWSP parent, const QString& name); 0935 0936 // Only KisPainter is allowed to have access to these low-level methods 0937 friend class KisPainter; 0938 0939 /** 0940 * Return a vector with in order the size in bytes of the channels 0941 * in the colorspace of this paint device. 0942 */ 0943 QVector<qint32> channelSizes() const; 0944 0945 void emitColorSpaceChanged(); 0946 void emitProfileChanged(); 0947 0948 private: 0949 friend class KisPaintDeviceFramesInterface; 0950 0951 protected: 0952 friend class KisSelectionTest; 0953 KisNodeWSP parentNode() const; 0954 0955 private: 0956 struct Private; 0957 Private * const m_d; 0958 }; 0959 0960 #endif // KIS_PAINT_DEVICE_IMPL_H_