17#include "bitmapbucket.h"
23#include "layermanager.h"
25#include "layerbitmap.h"
27BitmapBucket::BitmapBucket()
31BitmapBucket::BitmapBucket(
Editor* editor,
37 mMaxFillRegion(maxFillRegion),
38 mProperties(properties)
41 Layer* initialLayer = editor->layers()->currentLayer();
42 int initialLayerIndex = mEditor->currentLayerIndex();
43 int frameIndex = mEditor->currentFrame();
45 mBucketColor = qPremultiply(color.
rgba());
47 mTargetFillToLayer = initialLayer;
48 mTargetFillToLayerIndex = initialLayerIndex;
50 mTolerance = mProperties.toleranceEnabled ?
static_cast<int>(mProperties.tolerance) : 0;
51 const QPoint& point =
QPoint(qFloor(fillPoint.
x()), qFloor(fillPoint.
y()));
53 Q_ASSERT(mTargetFillToLayer);
55 BitmapImage singleLayerImage = *
static_cast<BitmapImage*
>(initialLayer->getLastKeyFrameAtPosition(frameIndex));
56 if (properties.bucketFillReferenceMode == 1)
58 mReferenceImage = flattenBitmapLayersToImage();
60 mReferenceImage = singleLayerImage;
62 mStartReferenceColor = mReferenceImage.constScanLine(point.
x(), point.
y());
63 mUseDragToFill = canUseDragToFill(point, color, singleLayerImage);
70 QRgb pressReferenceColorSingleLayer = referenceImage.constScanLine(fillPoint.
x(), fillPoint.
y());
71 QRgb startRef = qUnpremultiply(pressReferenceColorSingleLayer);
73 if (mProperties.fillMode == 0 && ((
QColor(qRed(startRef), qGreen(startRef), qBlue(startRef)) == bucketColor.
rgb() && qAlpha(startRef) == 255) || bucketColor.
alpha() == 0)) {
77 }
else if (mProperties.fillMode == 2 && qAlpha(startRef) == 255) {
92 return allowContinuousFill(checkPoint, checkColor);
95bool BitmapBucket::allowContinuousFill(
const QPoint& checkPoint,
const QRgb& checkColor)
const
97 if (!mUseDragToFill) {
101 const QRgb& colorOfReferenceImage = mReferenceImage.constScanLine(checkPoint.
x(), checkPoint.
y());
103 if (checkColor == mBucketColor && (mProperties.fillMode == 1 || qAlpha(checkColor) == 255))
116 const int currentFrameIndex = mEditor->currentFrame();
118 BitmapImage* targetImage =
static_cast<LayerBitmap*
>(mTargetFillToLayer)->getLastBitmapImageAtFrame(currentFrameIndex, 0);
119 if (targetImage ==
nullptr || !targetImage->isLoaded()) {
return; }
121 QPoint point =
QPoint(qFloor(updatedPoint.
x()), qFloor(updatedPoint.
y()));
122 if (!mReferenceImage.contains(point))
125 point = mReferenceImage.topLeft();
128 const QRgb& targetPixelColor = targetImage->constScanLine(point.
x(), point.
y());
130 if (!
allowFill(point, targetPixelColor)) {
134 QRgb fillColor = mBucketColor;
135 if (mProperties.fillMode == 1)
143 fillColor = tempColor.
rgba();
148 int expandValue = mProperties.bucketFillExpandEnabled ? mProperties.bucketFillExpand : 0;
149 bool didFloodFill = BitmapImage::floodFill(&replaceImage,
161 Q_ASSERT(replaceImage !=
nullptr);
163 state(BucketState::WillFillTarget, mTargetFillToLayerIndex, currentFrameIndex);
165 if (mProperties.fillMode == 0)
167 targetImage->paste(replaceImage);
169 else if (mProperties.fillMode == 2)
181 targetImage->paste(&properColor);
184 targetImage->modification();
187 state(BucketState::DidFillTarget, mTargetFillToLayerIndex, currentFrameIndex);
191BitmapImage BitmapBucket::flattenBitmapLayersToImage()
194 int currentFrame = mEditor->currentFrame();
195 auto layerMan = mEditor->layers();
196 for (
int i = 0; i < layerMan->count(); i++)
198 Layer* layer = layerMan->getLayer(i);
200 if (layer->type() == Layer::BITMAP && layer->visible())
204 flattenImage.paste(image);
bool canUseDragToFill(const QPoint &fillPoint, const QColor &bucketColor, const BitmapImage &referenceImage)
Determines whether fill to drag feature can be used.
bool allowFill(const QPoint &checkPoint, const QRgb &checkColor) const
Based on the various factors dependant on which tool properties are set, the result will:
void paint(const QPointF &updatedPoint, std::function< void(BucketState, int, int)> progress)
Will paint at the given point, given that it makes sense.
static bool compareColor(QRgb newColor, QRgb oldColor, int tolerance, QHash< QRgb, bool > *cache)
Compare colors for the purposes of flood filling.
QColor fromRgba(QRgb rgba)
void setAlphaF(qreal alpha)
CompositionMode_DestinationOver