1 /* 2 * Copyright (c) 2009 Boudewijn Rempt <boud@valdyas.org> 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 */ 18 #ifndef KIS_FIXED_PAINT_DEVICE_H 19 #define KIS_FIXED_PAINT_DEVICE_H 20 21 #include <kritaimage_export.h> 22 #include <KoColorSpace.h> 23 #include "kis_shared.h" 24 #include <kis_shared_ptr.h> 25 26 #include <QRect> 27 #include <QImage> 28 #include "KisOptimizedByteArray.h" 29 30 class KoColor; 31 32 33 /** 34 * A fixed paint device is a simple paint device that consists of an array 35 * of bytes and a rectangle. It cannot grow, it cannot shrink, all you can 36 * do is fill the paint device with the right bytes and use it as an argument 37 * to KisPainter or use the bytes as an argument to KoColorSpace functions. 38 */ 39 class KRITAIMAGE_EXPORT KisFixedPaintDevice : public KisShared 40 { 41 42 public: 43 44 KisFixedPaintDevice(const KoColorSpace* colorSpace, 45 KisOptimizedByteArray::MemoryAllocatorSP allocator = KisOptimizedByteArray::MemoryAllocatorSP()); 46 virtual ~KisFixedPaintDevice(); 47 48 /** 49 * Deep copy the fixed paint device, including the data. 50 */ 51 KisFixedPaintDevice(const KisFixedPaintDevice& rhs); 52 53 /** 54 * Deep copy the fixed paint device, including the data. 55 */ 56 KisFixedPaintDevice& operator=(const KisFixedPaintDevice& rhs); 57 58 /** 59 * setRect sets the rect of the fixed paint device to rect. 60 * This will _not_ create the associated data area. 61 * 62 * @param rc the bounds in pixels. The x,y of the rect represent the origin 63 * of the fixed paint device. 64 */ 65 void setRect(const QRect& rc); 66 67 /** 68 * @return the rect that the data represents 69 */ 70 QRect bounds() const; 71 72 /** 73 * @return the amount of allocated pixels (you can fake the size with setRect/bounds) 74 * It is useful to know the accumulated memory size in pixels (not in bytes) for optimizations to avoid re-allocation. 75 */ 76 int allocatedPixels() const; 77 78 79 /** 80 * @return the pixelSize associated with this fixed paint device. 81 */ 82 quint32 pixelSize() const; 83 colorSpace()84 const KoColorSpace* colorSpace() const { 85 return m_colorSpace; 86 } 87 88 /** 89 * initializes the paint device. 90 * 91 * @param defaultValue the default byte with which all pixels will be filled. 92 * @return false if the allocation failed. 93 */ 94 bool initialize(quint8 defaultValue = 0); 95 96 /** 97 * Changed the size of the internal buffer to accommodate the exact number of bytes 98 * needed to store area bounds(). The allocated data is *not* initialized! 99 */ 100 void reallocateBufferWithoutInitialization(); 101 102 /** 103 * If the size of the internal buffer is smaller than the one needed to accommodate 104 * bounds(), resize the buffer. Otherwise, do nothing. The allocated data is neither 105 * copying or initialized! 106 */ 107 void lazyGrowBufferWithoutInitialization(); 108 109 /** 110 * @return a pointer to the beginning of the data associated with this fixed paint device. 111 */ 112 quint8* data(); 113 114 const quint8* constData() const; 115 116 quint8* data() const; 117 118 /** 119 * Read the bytes representing the rectangle described by x, y, w, h into 120 * data. If data is not big enough, Krita will gladly overwrite the rest 121 * of your precious memory. 122 * 123 * Since this is a copy, you need to make sure you have enough memory. 124 * 125 * The reading is done only if the rectangular area x,y,w,h is inside the bounds of the device 126 * and the device is not empty 127 */ 128 void readBytes(quint8 * dstData, qint32 x, qint32 y, qint32 w, qint32 h) const; 129 130 /** 131 * Converts the paint device to a different colorspace 132 */ 133 void convertTo(const KoColorSpace * dstColorSpace = 0, 134 KoColorConversionTransformation::Intent renderingIntent = KoColorConversionTransformation::internalRenderingIntent(), 135 KoColorConversionTransformation::ConversionFlags conversionFlags = KoColorConversionTransformation::internalConversionFlags()); 136 137 /** 138 * Set color profile for the device without converting actual pixel data 139 */ 140 void setProfile(const KoColorProfile *profile); 141 142 /** 143 * Fill this paint device with the data from image 144 * 145 * @param image the image 146 * @param srcProfileName name of the RGB profile to interpret the image as. 0 is interpreted as sRGB 147 */ 148 virtual void convertFromQImage(const QImage& image, const QString &srcProfileName); 149 150 /** 151 * Create an RGBA QImage from a rectangle in the paint device. 152 * 153 * @param dstProfile RGB profile to use in conversion. May be 0, in which 154 * case it's up to the color strategy to choose a profile (most 155 * like sRGB). 156 * @param x Left coordinate of the rectangle 157 * @param y Top coordinate of the rectangle 158 * @param w Width of the rectangle in pixels 159 * @param h Height of the rectangle in pixels 160 * @param renderingIntent Rendering intent 161 * @param conversionFlags Conversion flags 162 */ 163 virtual QImage convertToQImage(const KoColorProfile *dstProfile, qint32 x, qint32 y, qint32 w, qint32 h, 164 KoColorConversionTransformation::Intent renderingIntent = KoColorConversionTransformation::internalRenderingIntent(), 165 KoColorConversionTransformation::ConversionFlags conversionFlags = KoColorConversionTransformation::internalConversionFlags()) const; 166 167 /** 168 * Create an RGBA QImage from a rectangle in the paint device. The 169 * rectangle is defined by the parent image's bounds. 170 * 171 * @param dstProfile RGB profile to use in conversion. May be 0, in which 172 * case it's up to the color strategy to choose a profile (most 173 * like sRGB). 174 * @param renderingIntent The rendering intent of conversion. 175 * @param conversionFlags The conversion flags. 176 */ 177 virtual QImage convertToQImage(const KoColorProfile *dstProfile, 178 KoColorConversionTransformation::Intent renderingIntent = KoColorConversionTransformation::internalRenderingIntent(), 179 KoColorConversionTransformation::ConversionFlags conversionFlags = KoColorConversionTransformation::internalConversionFlags()) const; 180 181 /** 182 * Clear the given rectangle to transparent black. 183 * 184 * XXX: this will not (yet) expand the paint device to contain the specified rect 185 * but if the paintdevice has not been initialized, it will be. 186 */ 187 void clear(const QRect & rc); 188 189 /** 190 * Fill the given rectangle with the given pixel. This does not take the 191 * selection into account. 192 * 193 * XXX: this will not (yet) expand the paint device to contain the specified rect 194 * but if the paintdevice has not been initialized, it will be. 195 */ 196 void fill(qint32 x, qint32 y, qint32 w, qint32 h, const quint8 *fillPixel); 197 198 void fill(const QRect &rc, const KoColor &color); 199 200 201 /** 202 * Mirrors the device. 203 */ 204 void mirror(bool horizontal, bool vertical); 205 206 private: 207 208 const KoColorSpace* m_colorSpace; 209 QRect m_bounds; 210 KisOptimizedByteArray m_data; 211 }; 212 213 #endif 214