aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Sandulenko2016-06-03 16:39:03 +0200
committerEugene Sandulenko2016-06-03 16:39:03 +0200
commit60297cb9fa51dcc2c145fa9aeb86a924c59c8b76 (patch)
treed77ed7d00e85bd12f46b77ff4cea0411a9a7bdea
parente171d21fc5fa8e0b918593ca57860835012085a1 (diff)
downloadscummvm-rg350-60297cb9fa51dcc2c145fa9aeb86a924c59c8b76.tar.gz
scummvm-rg350-60297cb9fa51dcc2c145fa9aeb86a924c59c8b76.tar.bz2
scummvm-rg350-60297cb9fa51dcc2c145fa9aeb86a924c59c8b76.zip
GRAPHICS: Add mask mode to FloodFill class and document the class.
-rw-r--r--graphics/surface.cpp42
-rw-r--r--graphics/surface.h52
2 files changed, 87 insertions, 7 deletions
diff --git a/graphics/surface.cpp b/graphics/surface.cpp
index 2fe6a73010..c5d4cf0cbd 100644
--- a/graphics/surface.cpp
+++ b/graphics/surface.cpp
@@ -505,6 +505,9 @@ FloodFill::FloodFill(Graphics::Surface *surface, uint32 oldColor, uint32 fillCol
_w = surface->w;
_h = surface->h;
+ _mask = nullptr;
+ _maskMode = false;
+
_visited = (byte *)calloc(_w * _h, 1);
}
@@ -517,28 +520,45 @@ FloodFill::~FloodFill() {
}
free(_visited);
+
+ if (_mask)
+ delete _mask;
}
void FloodFill::addSeed(int x, int y) {
if (x >= 0 && x < _w && y >= 0 && y < _h) {
if (!_visited[y * _w + x]) {
_visited[y * _w + x] = 1;
- void *p = _surface->getBasePtr(x, y);
+ void *src = _surface->getBasePtr(x, y);
+ void *dst;
bool changed = false;
+ if (_maskMode)
+ dst = _mask->getBasePtr(x, y);
+ else
+ dst = src;
+
if (_surface->format.bytesPerPixel == 1) {
- if (*((byte *)p) == _oldColor) {
- *((byte *)p) = _fillColor;
+ if (*((byte *)src) == _oldColor) {
+ *((byte *)dst) = _maskMode ? 255 : _fillColor;
changed = true;
}
} else if (_surface->format.bytesPerPixel == 2) {
- if (READ_UINT16(p) == _oldColor) {
- WRITE_UINT16(p, _fillColor);
+ if (READ_UINT16(src) == _oldColor) {
+ if (!_maskMode)
+ WRITE_UINT16(src, _fillColor);
+ else
+ *((byte *)dst) = 255;
+
changed = true;
}
} else if (_surface->format.bytesPerPixel == 4) {
- if (READ_UINT32(p) == _oldColor) {
- WRITE_UINT32(p, _fillColor);
+ if (READ_UINT32(src) == _oldColor) {
+ if (!_maskMode)
+ WRITE_UINT32(src, _fillColor);
+ else
+ *((byte *)dst) = 255;
+
changed = true;
}
} else {
@@ -567,4 +587,12 @@ void FloodFill::fill() {
}
}
+void FloodFill::fillMask() {
+ _mask = new Graphics::Surface();
+ _mask->create(_w, _h, Graphics::PixelFormat::createFormatCLUT8()); // Uses calloc()
+ _maskMode = true;
+
+ fill();
+}
+
} // End of namespace Graphics
diff --git a/graphics/surface.h b/graphics/surface.h
index e5685bf997..414a734683 100644
--- a/graphics/surface.h
+++ b/graphics/surface.h
@@ -343,19 +343,71 @@ struct SharedPtrSurfaceDeleter {
}
};
+/**
+ * Stack-based flood fill algorithm for arbitrary Surfaces.
+ *
+ * It could be used in 2 ways. One is to fill the pixels of oldColor
+ * with fillColor. Second is when the surface stays intact but another
+ * surface with mask is created, where filled colors are marked with 255.
+ *
+ * Before running fill() or fillMask(), the initial pixels must be addSeed
+ * with addSeed() method.
+ */
class FloodFill {
public:
+ /**
+ * Construct a simple Surface object.
+ *
+ * @param surface Input surface
+ * @param oldColor Color on the surface to change
+ * @param fillColor Color to fill with
+ */
FloodFill(Surface *surface, uint32 oldColor, uint32 fillColor);
~FloodFill();
+
+ /**
+ * Add pixels to the fill queue.
+ *
+ * @param x The x coordinate of the pixel.
+ * @param y The x coordinate of the pixel.
+ */
void addSeed(int x, int y);
+
+ /**
+ * Fill the surface as requested.
+ *
+ * It uses pixels which were added with addSeed() method.
+ *
+ * @see addSeed
+ */
void fill();
+ /**
+ * Fill the mask. The mask is a CLUT8 Surface with pixels 0 and 255.
+ * 255 means that the pixel has been filled.
+ *
+ * It uses pixels which were added with addSeed() method.
+ *
+ * @see addSeed
+ */
+ void fillMask();
+
+ /**
+ * Get the resulting mask.
+ *
+ * @see fillMask
+ */
+ Surface *getMask() { return _mask; }
+
private:
Common::List<Common::Point *> _queue;
Surface *_surface;
+ Surface *_mask;
uint32 _oldColor, _fillColor;
byte *_visited;
int _w, _h;
+
+ bool _maskMode;
};
} // End of namespace Graphics