File indexing completed on 2024-05-12 15:58:36

0001 /*
0002  *  SPDX-FileCopyrightText: 2004 Boudewijn Rempt <boud@valdyas.org>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 #ifndef KIS_PIXEL_SELECTION_H_
0007 #define KIS_PIXEL_SELECTION_H_
0008 
0009 #include <QRect>
0010 #include <QPainterPath>
0011 
0012 #include "kis_types.h"
0013 #include "kis_global.h"
0014 #include "kis_paint_device.h"
0015 #include "kis_selection_component.h"
0016 #include "kis_selection.h"
0017 #include <kritaimage_export.h>
0018 
0019 
0020 /**
0021  * KisPixelSelection contains a byte-map representation of a layer, where
0022  * the value of a byte signifies whether a corresponding pixel is selected, or not.
0023  */
0024 class KRITAIMAGE_EXPORT KisPixelSelection : public KisPaintDevice, public KisSelectionComponent
0025 {
0026 
0027 public:
0028 
0029     /**
0030      * Create a new KisPixelSelection. This selection will not have a
0031      * parent paint device.
0032      */
0033     KisPixelSelection(KisDefaultBoundsBaseSP defaultBounds = KisDefaultBoundsBaseSP(), KisSelectionWSP parentSelection = KisSelectionWSP());
0034 
0035     /**
0036      * Copy the selection
0037      */
0038     KisPixelSelection(const KisPixelSelection& rhs, KritaUtils::DeviceCopyMode copyMode = KritaUtils::CopySnapshot);
0039 
0040     /**
0041      * Create a new selection using the content of copySource as the mask.
0042      */
0043     KisPixelSelection(const KisPaintDeviceSP copySource, KritaUtils::DeviceCopyMode copyMode = KritaUtils::CopySnapshot, KisSelectionWSP parentSelection = KisSelectionWSP());
0044 
0045     ~KisPixelSelection() override;
0046 
0047     KisSelectionComponent* clone(KisSelection*) override;
0048 
0049     const KoColorSpace* compositionSourceColorSpace() const override;
0050 
0051     bool read(QIODevice *stream);
0052 
0053     /**
0054      * Fill the specified rect with the specified selectedness.
0055      */
0056     void select(const QRect & r, quint8 selectedness = MAX_SELECTED);
0057 
0058     /**
0059      * Invert the total selection. This will also invert the default value
0060      * of the selection paint device, from MIN_SELECTED to MAX_SELECTED or
0061      * back.
0062      */
0063     void invert();
0064 
0065     /**
0066      * Set the specified rect to MIN_SELECTED.
0067      */
0068     void clear(const QRect & r);
0069 
0070     /**
0071      * Reset the entire selection. The selectedRect and selectedExactRect
0072      * will be empty. The selection will be completely deselected.
0073      */
0074     void clear() override;
0075 
0076     /**
0077      * Copies alpha channel form the specified \p src device
0078      */
0079     void copyAlphaFrom(KisPaintDeviceSP src, const QRect &processRect);
0080 
0081     /**
0082      * Apply a selection to the selection using the specified selection mode
0083      */
0084     void applySelection(KisPixelSelectionSP selection, SelectionAction action);
0085 
0086     /// Tests if the rect is totally outside the selection
0087     bool isTotallyUnselected(const QRect & r) const;
0088 
0089     /**
0090      * Rough, but fastish way of determining the area
0091      * of the tiles used by the selection.
0092      */
0093     QRect selectedRect() const;
0094 
0095     /**
0096      * Slow, but exact way of determining the rectangle
0097      * that encloses the selection.
0098      */
0099     QRect selectedExactRect() const;
0100 
0101     /**
0102      * @brief outline returns the outline of the current selection
0103      * @return a vector of polygons that can be used to draw the outline
0104      */
0105     QVector<QPolygon> outline() const;
0106 
0107     /**
0108      * Overridden from KisPaintDevice to handle outline cache moves
0109      */
0110     void moveTo(const QPoint& pt) override;
0111     using KisPaintDevice::moveTo;
0112 
0113     bool isEmpty() const override;
0114     QPainterPath outlineCache() const override;
0115     bool outlineCacheValid() const override;
0116     void recalculateOutlineCache() override;
0117 
0118     void setOutlineCache(const QPainterPath &cache);
0119     void invalidateOutlineCache();
0120 
0121     bool thumbnailImageValid() const;
0122     QImage thumbnailImage() const;
0123     QTransform thumbnailImageTransform() const;
0124     void recalculateThumbnailImage(const QColor &maskColor);
0125 
0126 
0127     void setParentSelection(KisSelectionWSP selection);
0128     KisSelectionWSP parentSelection() const;
0129 
0130     void renderToProjection(KisPaintDeviceSP projection) override;
0131     void renderToProjection(KisPaintDeviceSP projection, const QRect& r) override;
0132 
0133 private:
0134     /**
0135      * Add a selection
0136      */
0137     void addSelection(KisPixelSelectionSP selection);
0138 
0139     /**
0140      * Subtracts a selection
0141      */
0142     void subtractSelection(KisPixelSelectionSP selection);
0143 
0144     /**
0145      * Intersects a selection using min-T-norm for this.
0146      */
0147     void intersectSelection(KisPixelSelectionSP selection);
0148 
0149     /**
0150      * Invert a selection or intersect with the inverse of a selection
0151      */
0152     void symmetricdifferenceSelection(KisPixelSelectionSP selection);
0153 
0154 private:
0155     // We don't want these methods to be used on selections:
0156     using KisPaintDevice::extent;
0157     using KisPaintDevice::exactBounds;
0158 
0159 private:
0160 
0161     struct Private;
0162     Private * const m_d;
0163 };
0164 
0165 #endif // KIS_PIXEL_SELECTION_H_