File indexing completed on 2024-12-22 04:10:06
0001 /* 0002 * SPDX-FileCopyrightText: 2014 Dmitry Kazakov <dimula73@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #ifndef __KIS_SCANLINE_FILL_H 0008 #define __KIS_SCANLINE_FILL_H 0009 0010 #include <QScopedPointer> 0011 0012 #include <kritaimage_export.h> 0013 #include <kis_types.h> 0014 #include <kis_paint_device.h> 0015 0016 class KisFillInterval; 0017 class KisFillIntervalMap; 0018 0019 class KRITAIMAGE_EXPORT KisScanlineFill 0020 { 0021 public: 0022 KisScanlineFill(KisPaintDeviceSP device, const QPoint &startPoint, const QRect &boundingRect); 0023 ~KisScanlineFill(); 0024 0025 /** 0026 * Fill the source device with \p fillColor 0027 */ 0028 void fill(const KoColor &fillColor); 0029 0030 /** 0031 * Fill the source device with \p fillColor until \p boundaryColor is reached 0032 */ 0033 void fillUntilColor(const KoColor &fillColor, const KoColor &boundaryColor); 0034 0035 /** 0036 * Fill \p externalDevice with \p fillColor basing on the contents 0037 * of the source device. 0038 */ 0039 void fill(const KoColor &fillColor, KisPaintDeviceSP externalDevice); 0040 0041 /** 0042 * Fill \p externalDevice with \p fillColor basing on the contents 0043 * of the source device. Fills until \p boundaryColor is reached 0044 */ 0045 void fillUntilColor(const KoColor &fillColor, const KoColor &boundaryColor, KisPaintDeviceSP externalDevice); 0046 0047 /** 0048 * Fill \p pixelSelection with the opacity of the contiguous area. 0049 * This method uses an existing selection as boundary for the flood fill. 0050 */ 0051 void fillSelection(KisPixelSelectionSP pixelSelection, KisPaintDeviceSP boundarySelection); 0052 0053 /** 0054 * Fill \p pixelSelection with the opacity of the contiguous area 0055 */ 0056 void fillSelection(KisPixelSelectionSP pixelSelection); 0057 0058 /** 0059 * Fill \p pixelSelection with the opacity of the contiguous area, which 0060 * encompass all the connected pixels as long as the color in the 0061 * pixels of the source device is not similar to \p boundaryColor. 0062 * This method uses an existing selection as boundary for the flood fill. 0063 */ 0064 void fillSelectionUntilColor(KisPixelSelectionSP pixelSelection, const KoColor &boundaryColor, KisPaintDeviceSP boundarySelection); 0065 0066 /** 0067 * Fill \p pixelSelection with the opacity of the contiguous area, which 0068 * encompass all the connected pixels as long as the color in the 0069 * pixels of the source device is not similar to \p boundaryColor. 0070 */ 0071 void fillSelectionUntilColor(KisPixelSelectionSP pixelSelection, const KoColor &boundaryColor); 0072 0073 /** 0074 * Fill \p pixelSelection with the opacity of the contiguous area, which 0075 * encompass all the connected pixels as long as the color in the 0076 * pixels of the source device is not similar to \p boundaryColor or transparent. 0077 * This method uses an existing selection as boundary for the flood fill. 0078 */ 0079 void fillSelectionUntilColorOrTransparent(KisPixelSelectionSP pixelSelection, const KoColor &boundaryColor, KisPaintDeviceSP boundarySelection); 0080 0081 /** 0082 * Fill \p pixelSelection with the opacity of the contiguous area, which 0083 * encompass all the connected pixels as long as the color in the 0084 * pixels of the source device is not similar to \p boundaryColor or transparent. 0085 */ 0086 void fillSelectionUntilColorOrTransparent(KisPixelSelectionSP pixelSelection, const KoColor &boundaryColor); 0087 0088 /** 0089 * Clear the contiguous non-zero area of the device 0090 * 0091 * WARNING: the threshold parameter is not counted! 0092 */ 0093 void clearNonZeroComponent(); 0094 0095 /** 0096 * A special filler algorithm for the Watershed initialization routine: 0097 * 0098 * 1) Clear the contiguous area in the destination device 0099 * 2) At the same time, fill the corresponding area of \p groupMapDevice with 0100 * value \p groupIndex 0101 * 3) \p groupMapDevice **must** store 4 bytes per pixel 0102 */ 0103 void fillContiguousGroup(KisPaintDeviceSP groupMapDevice, qint32 groupIndex); 0104 0105 /** 0106 * Set the threshold of the filling operation 0107 * 0108 * Used in all functions except clearNonZeroComponent() 0109 */ 0110 void setThreshold(int threshold); 0111 0112 /** 0113 * Set the opacity spread for floodfill. The range is 0-100: 0% means that 0114 * the fully opaque area only encompasses the pixels exactly equal to the 0115 * seed point with the other pixels of the selected region being 0116 * semi-transparent (depending on how similar they are to the seed pixel) 0117 * up to the region boundary (given by the threshold value). 100 means that 0118 * the fully opaque area will encompass all the pixels of the selected 0119 * region up to the contour. Any value in between will make the fully opaque 0120 * portion of the region vary in size, with semi-transparent pixels 0121 * in between it and the region boundary 0122 */ 0123 void setOpacitySpread(int opacitySpread); 0124 0125 private: 0126 friend class KisScanlineFillTest; 0127 Q_DISABLE_COPY(KisScanlineFill) 0128 0129 template <typename DifferencePolicy, typename SelectionPolicy, typename PixelAccessPolicy> 0130 void processLine(KisFillInterval interval, const int rowIncrement, 0131 DifferencePolicy &differencePolicy, 0132 SelectionPolicy &selectionPolicy, 0133 PixelAccessPolicy &pixelAccessPolicy); 0134 0135 template <typename DifferencePolicy, typename SelectionPolicy, typename PixelAccessPolicy> 0136 void extendedPass(KisFillInterval *currentInterval, int srcRow, bool extendRight, 0137 DifferencePolicy &differencePolicy, 0138 SelectionPolicy &selectionPolicy, 0139 PixelAccessPolicy &pixelAccessPolicy); 0140 0141 template <typename DifferencePolicy, typename SelectionPolicy, typename PixelAccessPolicy> 0142 void runImpl(DifferencePolicy &differencePolicy, 0143 SelectionPolicy &selectionPolicy, 0144 PixelAccessPolicy &pixelAccessPolicy); 0145 0146 template <template <typename SrcPixelType> typename OptimizedDifferencePolicy, 0147 typename SlowDifferencePolicy, 0148 typename SelectionPolicy, typename PixelAccessPolicy> 0149 void selectDifferencePolicyAndRun(const KoColor &srcColor, 0150 SelectionPolicy &selectionPolicy, 0151 PixelAccessPolicy &pixelAccessPolicy); 0152 0153 private: 0154 void testingProcessLine(const KisFillInterval &processInterval); 0155 QVector<KisFillInterval> testingGetForwardIntervals() const; 0156 KisFillIntervalMap* testingGetBackwardIntervals() const; 0157 private: 0158 struct Private; 0159 const QScopedPointer<Private> m_d; 0160 }; 0161 0162 #endif /* __KIS_SCANLINE_FILL_H */