File indexing completed on 2024-06-16 04:09:57
0001 0002 /* 0003 Copyright (c) 2003-2007 Clarence Dang <dang@kde.org> 0004 All rights reserved. 0005 0006 Redistribution and use in source and binary forms, with or without 0007 modification, are permitted provided that the following conditions 0008 are met: 0009 0010 1. Redistributions of source code must retain the above copyright 0011 notice, this list of conditions and the following disclaimer. 0012 2. Redistributions in binary form must reproduce the above copyright 0013 notice, this list of conditions and the following disclaimer in the 0014 documentation and/or other materials provided with the distribution. 0015 0016 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 0017 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 0018 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 0019 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 0020 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 0021 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 0022 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 0023 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 0024 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 0025 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 0026 */ 0027 0028 0029 #ifndef kpAbstractImageSelection_H 0030 #define kpAbstractImageSelection_H 0031 0032 0033 #include "kpImageSelectionTransparency.h" 0034 #include "layers/selections/kpAbstractSelection.h" 0035 #include "imagelib/kpImage.h" 0036 0037 0038 // 0039 // An abstract selection with optional image content and background 0040 // subtraction. If there is image content, it is known as a "floating 0041 // selection" that hovers above the document. Otherwise, it is an 0042 // image selection "border", that highlights pixels of the document, and 0043 // may later be upgraded to a floating selection by giving it an image 0044 // consisting of those pixels. 0045 // 0046 // The images passed to this class (known as "base images") should have all 0047 // pixels, outside of the border, set to transparent. However, nothing 0048 // enforces this. Pixels on, or inside, the border might be opaque or 0049 // transparent, depending on the content. 0050 // 0051 // The "transparent image" is the base image with background subtraction 0052 // (kpImageSelectionTransparency) applied. This is automatically computed. 0053 // 0054 // The boundingRect() is the size of the border. The base image must be of 0055 // exactly the same size, except that the base image is allowed to be null 0056 // (for a selection that only consists of a border). 0057 // 0058 // Instead of copying selections' images to the clipboard, we copy 0059 // selections, to preserve the border across KolourPaint instances. 0060 // Background subtraction is not copied to the clipboard so that the base 0061 // image is affected by the background subtraction of the destination 0062 // KolourPaint window. 0063 // 0064 class kpAbstractImageSelection : public kpAbstractSelection 0065 { 0066 Q_OBJECT 0067 0068 // 0069 // Initialization 0070 // 0071 0072 protected: 0073 // (Call these in subclass constructors) 0074 kpAbstractImageSelection (const kpImageSelectionTransparency &transparency = 0075 kpImageSelectionTransparency ()); 0076 0077 kpAbstractImageSelection (const QRect &rect, 0078 const kpImage &baseImage = kpImage (), 0079 const kpImageSelectionTransparency &transparency = 0080 kpImageSelectionTransparency ()); 0081 0082 kpAbstractImageSelection (const QRect &rect, 0083 const kpImageSelectionTransparency &transparency = 0084 kpImageSelectionTransparency ()); 0085 0086 // (Call this in subclass implementations of operator=) 0087 kpAbstractImageSelection &operator= (const kpAbstractImageSelection &rhs); 0088 0089 public: 0090 // (Covariant return-type specialization of superclass pure virtual method) 0091 kpAbstractImageSelection *clone () const override = 0; 0092 0093 ~kpAbstractImageSelection () override; 0094 0095 0096 // 0097 // Marshalling 0098 // 0099 0100 public: 0101 // You must override this if you have extra serializable fields. 0102 // Remember to call this base implementation before your code. 0103 bool readFromStream (QDataStream &stream) override; 0104 0105 // You must override this if you have extra serializable fields. 0106 // Remember to call this base implementation before your code. 0107 void writeToStream (QDataStream &stream) const override; 0108 0109 0110 // 0111 // General Queries 0112 // 0113 0114 public: 0115 QString name () const override; 0116 0117 // You must override this, if you have extra fields that take a 0118 // non-constant amount of space, and add the size returned by this 0119 // implementation. 0120 kpCommandSize::SizeType size () const override; 0121 0122 // Same as virtual size() (it even calls it) but subtracts the size of the 0123 // baseImage(). 0124 // 0125 // kpCommand's store the kpImage's they are working on. These images may 0126 // be from documents or selections. In the case of a selection, the 0127 // selection's baseImage() is identical to that image, but takes no extra 0128 // space due to kpImage's copy-on-write. This method fixes that 0129 // double-counting of baseImage()'s size. 0130 // 0131 // The size of the internal transparency() mask is still included 0132 // (see recalculateTransparencyMask()). 0133 // 0134 // sync: kpImage copy-on-write behavior 0135 // 0136 // TODO: Check all size() implementations are correct since we've 0137 // started removing the old kpSelection::setPixmap(QPixmap()) 0138 // (now kpAbstractImageSelection::setBaseImage(kpImage()) or 0139 // kpAbstractImageSelection::deleteContent()) space saving hack. 0140 kpCommandSize::SizeType sizeWithoutImage () const; 0141 0142 0143 // 0144 // Dimensions 0145 // 0146 0147 public: 0148 int minimumWidth () const override; 0149 int minimumHeight () const override; 0150 0151 0152 // 0153 // Shape Mask 0154 // 0155 // These methods do not access any class instance fields. 0156 // 0157 0158 public: 0159 // Returns the mask corresponding to the shape of the selection. 0160 // 0161 // If <nullForRectangular> is set, the method _may_ return a null 0162 // bitmap if the selection is rectangular. 0163 // 0164 // This base implementation calls calculatePoints() and ignores 0165 // <nullForRectangular>. 0166 // 0167 // You should override this if you can implement it more efficiently or 0168 // if you can honor <nullForRectangular>. 0169 // 0170 // Note: This must be consistent with the outputs of calculatePoints() and 0171 // shapeRegion(). 0172 // 0173 // TODO: Try to get rid of this method since it's slow. 0174 virtual QBitmap shapeBitmap (bool nullForRectangular = false) const; 0175 0176 // Returns the region corresponding to the shape of the selection 0177 // e.g. elliptical region for an elliptical selection. 0178 // 0179 // Very slow. 0180 // 0181 // Note: This must be consistent with the outputs of calculatePoints() and 0182 // shapeRegion(). 0183 // 0184 // OPT: QRegion is probably incredibly slow - cache 0185 virtual QRegion shapeRegion () const = 0; 0186 0187 // Returns the given <image> with the pixels outside of the selection's 0188 // shape set to transparent. 0189 // 0190 // Very slow. 0191 // 0192 // ASSUMPTION: The image has the same dimensions as the selection. 0193 kpImage givenImageMaskedByShape (const kpImage &image) const; 0194 0195 0196 // 0197 // Content - Base Image 0198 // 0199 0200 public: 0201 // Returns whether there's a non-null base image. 0202 bool hasContent () const override; 0203 0204 void deleteContent () override; 0205 0206 public: 0207 kpImage baseImage () const; 0208 void setBaseImage (const kpImage &baseImage); 0209 0210 0211 // 0212 // Background Subtraction 0213 // 0214 0215 public: 0216 kpImageSelectionTransparency transparency () const; 0217 0218 // Returns whether or not the selection changed due to setting the 0219 // transparency info. If <checkTransparentPixmapChanged> is set, 0220 // it will try harder to return false (although the check is 0221 // expensive). 0222 bool setTransparency (const kpImageSelectionTransparency &transparency, 0223 bool checkTransparentPixmapChanged = false); 0224 0225 private: 0226 // Updates the selection transparency (a.k.a. background subtraction) mask 0227 // so that transparentImage() will work. 0228 // 0229 // Called when the base image or selection transparency changes. 0230 void recalculateTransparencyMaskCache (); 0231 0232 public: 0233 // Returns baseImage() after applying kpImageSelectionTransparency 0234 kpImage transparentImage () const; 0235 0236 0237 // 0238 // Mutation - Effects 0239 // 0240 0241 public: 0242 // Overwrites the base image with the selection's shape (e.g. ellipse) 0243 // filled in with <color>. See shapeBitmap(). 0244 void fill (const kpColor &color); 0245 0246 virtual void flip (bool horiz, bool vert); 0247 0248 0249 // 0250 // Rendering 0251 // 0252 0253 public: 0254 // (using transparent image) 0255 void paint (QImage *destPixmap, const QRect &docRect) const override; 0256 0257 // (using base image) 0258 void paintWithBaseImage (QImage *destPixmap, const QRect &docRect) const; 0259 0260 0261 private: 0262 struct kpAbstractImageSelectionPrivate * const d; 0263 }; 0264 0265 0266 #endif // kpAbstractImageSelection_H