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

0001 /*
0002  * KDE. Krita Project.
0003  *
0004  * SPDX-FileCopyrightText: 2022 Deif Lou <ginoba@gmail.com>
0005  *
0006  * SPDX-License-Identifier: GPL-2.0-or-later
0007  */
0008 
0009 #ifndef KISENCLOSEANDFILLPAINTER_H
0010 #define KISENCLOSEANDFILLPAINTER_H
0011 
0012 #include <QVector>
0013 #include <QPoint>
0014 #include <QRect>
0015 #include <QScopedPointer>
0016 
0017 #include <kis_pixel_selection.h>
0018 #include <kis_paint_device.h>
0019 #include <kis_fill_painter.h>
0020 #include <KoColor.h>
0021 #include <kritaimage_export.h>
0022 
0023 class KRITAIMAGE_EXPORT KisEncloseAndFillPainter : public KisFillPainter
0024 {
0025 public:
0026     /**
0027      * Different methods of selecting pixels when using flood fill related
0028      * functionality
0029      */
0030     enum RegionSelectionMethod
0031     {
0032         /**
0033          * Select all the closed regions inside the enclosing region, no matter
0034          * their color
0035          */
0036         SelectAllRegions,
0037         /**
0038          * Select all the closed regions inside the enclosing region, as long as
0039          * they are the same color as the specified region selection color
0040          */
0041         SelectRegionsFilledWithSpecificColor,
0042         /**
0043          * Select all the closed regions inside the enclosing region, as long as
0044          * they are transparent
0045          */
0046         SelectRegionsFilledWithTransparent,
0047         /**
0048          * Select all the closed regions inside the enclosing region, as long as
0049          * they are the same color as the specified region selection color
0050          * or transparent
0051          */
0052         SelectRegionsFilledWithSpecificColorOrTransparent,
0053         /**
0054          * Select all the closed regions inside the enclosing region, as long as
0055          * they are not the same color as the specified region selection color
0056          */
0057         SelectAllRegionsExceptFilledWithSpecificColor,
0058         /**
0059          * Select all the closed regions inside the enclosing region, as long as
0060          * they are not transparent
0061          */
0062         SelectAllRegionsExceptFilledWithTransparent,
0063         /**
0064          * Select all the closed regions inside the enclosing region, as long as
0065          * they are not the same color as the specified region selection color
0066          * or transparent
0067          */
0068         SelectAllRegionsExceptFilledWithSpecificColorOrTransparent,
0069         /**
0070          * Select all the closed regions inside the enclosing region, as long as
0071          * they are surrounded by the region selection color
0072          */
0073         SelectRegionsSurroundedBySpecificColor,
0074         /**
0075          * Select all the closed regions inside the enclosing region, as long as
0076          * they are surrounded by transparent
0077          */
0078         SelectRegionsSurroundedByTransparent,
0079         /**
0080          * Select all the closed regions inside the enclosing region, as long as
0081          * they are surrounded by the region selection color or transparent
0082          */
0083         SelectRegionsSurroundedBySpecificColorOrTransparent
0084     };
0085 
0086     /**
0087      * Construct an empty painter. Use the begin(KisPaintDeviceSP) method to attach
0088      * to a paint device
0089      */
0090     KisEncloseAndFillPainter(const QSize &imageSize);
0091     /**
0092      * Start painting on the specified paint device
0093      */
0094     KisEncloseAndFillPainter(KisPaintDeviceSP device, const QSize &imageSize);
0095 
0096     KisEncloseAndFillPainter(KisPaintDeviceSP device, KisSelectionSP selection, const QSize &imageSize);
0097 
0098     ~KisEncloseAndFillPainter() override;
0099 
0100     /**
0101      * Finds the closed areas inside the enclosing mask and fills them with the
0102      * set color. If there is a selection, the whole selection is filled. Note
0103      * that you must have set the width and height on the painter if you
0104      * don't have a selection.
0105      *
0106      * @param enclosingMask a mask representing where to search for the closed regions
0107      * @param referenceDevice the reference device that determines the areas that
0108      * are filled if sampleMerged is on
0109      */
0110     void encloseAndFillColor(KisPixelSelectionSP enclosingMask, KisPaintDeviceSP referenceDevice);
0111 
0112     /**
0113      * Finds the closed areas inside the enclosing mask and fills them with the
0114      * set pattern. If there is a selection, the whole selection is filled. Note
0115      * that you must have set the width and height on the painter if you
0116      * don't have a selection.
0117      *
0118      * @param enclosingMask a mask representing where to search for the closed regions
0119      * @param referenceDevice the reference device that determines the areas that
0120      * are filled if sampleMerged is on
0121      * @param patternTransform transform applied to the pattern
0122      */
0123     void encloseAndFillPattern(KisPixelSelectionSP enclosingMask,
0124                                KisPaintDeviceSP referenceDevice,
0125                                QTransform patternTransform = QTransform());
0126 
0127     /**
0128      * Returns a selection mask for the closed regions inside of the enclosing mask.
0129      * This variant basically creates a new selection object and passes it down
0130      * to the other variant of the function.
0131      *
0132      * @param enclosingMask a mask representing where to search for the closed regions
0133      * @param referenceDevice the reference device that determines the area that
0134      * is floodfilled if sampleMerged is on
0135      * @param existingSelection the selection used when useSelectionAsBoundary is true
0136      */
0137     KisPixelSelectionSP createEncloseAndFillSelection(KisPixelSelectionSP enclosingMask,
0138                                                       KisPaintDeviceSP referenceDevice,
0139                                                       KisPixelSelectionSP existingSelection);
0140 
0141     /**
0142      * Returns a selection mask for the closed regions inside of the enclosing mask.
0143      * This variant requires an empty selection object. It is used in cases where the pointer
0144      * to the selection must be known beforehand, for example when the selection is filled
0145      * in a stroke and then the pointer to the pixel selection is needed later.
0146      *
0147      * @param selection empty new selection object
0148      * @param enclosingMask a mask representing where to search for the closed regions
0149      * @param referenceDevice the reference device that determines the area that
0150      * is floodfilled if sampleMerged is on
0151      * @param existingSelection the selection used when useSelectionAsBoundary is true
0152      */
0153     KisPixelSelectionSP createEncloseAndFillSelection(KisPixelSelectionSP newSelection,
0154                                                       KisPixelSelectionSP enclosingMask,
0155                                                       KisPaintDeviceSP referenceDevice,
0156                                                       KisPixelSelectionSP existingSelection);
0157 
0158     /** Sets the region type of the closed regions in the enclose and fill */
0159     void setRegionSelectionMethod(RegionSelectionMethod regionSelectionMethod);
0160 
0161     /** Gets the region type of the closed regions in the enclose and fill */
0162     RegionSelectionMethod regionSelectionMethod() const;
0163 
0164     /** Sets the color to use when regionSelectionMethod is set to
0165      *  custom color in the enclose and fill
0166      */
0167     void setRegionSelectionColor(const KoColor &color);
0168 
0169     /** Gets the color to use when regionSelectionMethod is set to
0170      *  custom color in the enclose and fill
0171      */
0172     KoColor regionSelectionColor() const;
0173 
0174     /** Sets if the selection mask should be inverted */
0175     void setRegionSelectionInvert(bool invert);
0176 
0177     /** Gets if the selection mask should be inverted */
0178     bool regionSelectionInvert() const;
0179 
0180     /** Sets if the regions that touch the enclosing area contour should be kept or excluded */
0181     void setRegionSelectionIncludeContourRegions(bool include);
0182 
0183     /** Gets if the regions that touch the enclosing area contour should be kept or excluded */
0184     bool regionSelectionIncludeContourRegions() const;
0185 
0186     /**
0187      *  Sets if the surrounding regions of the specific selected color should
0188      *  be kept or excluded when using @ref SelectRegionsSurroundedBySpecificColor,
0189      *  @ref SelectRegionsSurroundedByTransparent or
0190      *  @ref SelectRegionsSurroundedBySpecificColorOrTransparent as the region
0191      *  selection method
0192      */
0193     void setRegionSelectionIncludeSurroundingRegions(bool include);
0194 
0195     /**
0196      *  Gets if the surrounding regions of the specific selected color should
0197      *  be kept or excluded when using @ref SelectRegionsSurroundedBySpecificColor,
0198      *  @ref SelectRegionsSurroundedByTransparent or
0199      *  @ref SelectRegionsSurroundedBySpecificColorOrTransparent as the region
0200      *  selection method
0201      */
0202     bool regionSelectionIncludeSurroundingRegions() const;
0203 
0204 protected:
0205     void genericEncloseAndFillStart(KisPixelSelectionSP enclosingMask, KisPaintDeviceSP referenceDevice);
0206     void genericEncloseAndFillEnd(KisPaintDeviceSP filled);
0207 
0208 private:
0209     class Private;
0210     QScopedPointer<Private> m_d;
0211 };
0212 
0213 #endif