GRAPHICS: Added FloodFill class to Surface.
Moved from WAGE engine and is using stack-based classic floodfill implementation.
This commit is contained in:
parent
2c7976e4e9
commit
531b190d59
4 changed files with 78 additions and 67 deletions
|
@ -422,7 +422,7 @@ void Design::drawBitmap(Graphics::ManagedSurface *surface, Common::SeekableReadS
|
|||
int x2 = in.readSint16BE();
|
||||
int w = x2 - x1;
|
||||
int h = y2 - y1;
|
||||
Graphics::ManagedSurface tmp;
|
||||
Graphics::Surface tmp;
|
||||
|
||||
tmp.create(w, h, Graphics::PixelFormat::createFormatCLUT8());
|
||||
|
||||
|
@ -477,7 +477,7 @@ void Design::drawBitmap(Graphics::ManagedSurface *surface, Common::SeekableReadS
|
|||
if (_boundsCalculationMode)
|
||||
return;
|
||||
|
||||
FloodFill ff(&tmp, kColorWhite, kColorGreen);
|
||||
Graphics::FloodFill ff(&tmp, kColorWhite, kColorGreen);
|
||||
for (int yy = 0; yy < h; yy++) {
|
||||
ff.addSeed(0, yy);
|
||||
ff.addSeed(w - 1, yy);
|
||||
|
@ -541,54 +541,4 @@ void Design::drawVLine(Graphics::ManagedSurface *surface, int x, int y1, int y2,
|
|||
Graphics::drawVLine(x, y1, y2, color, drawPixel, &pd);
|
||||
}
|
||||
|
||||
FloodFill::FloodFill(Graphics::ManagedSurface *surface, byte color1, byte color2) {
|
||||
_surface = surface;
|
||||
_color1 = color1;
|
||||
_color2 = color2;
|
||||
_w = surface->w;
|
||||
_h = surface->h;
|
||||
|
||||
_visited = (byte *)calloc(_w * _h, 1);
|
||||
}
|
||||
|
||||
FloodFill::~FloodFill() {
|
||||
while(!_queue.empty()) {
|
||||
Common::Point *p = _queue.front();
|
||||
|
||||
delete p;
|
||||
_queue.pop_front();
|
||||
}
|
||||
|
||||
free(_visited);
|
||||
}
|
||||
|
||||
void FloodFill::addSeed(int x, int y) {
|
||||
byte *p;
|
||||
|
||||
if (x >= 0 && x < _w && y >= 0 && y < _h) {
|
||||
if (!_visited[y * _w + x] && *(p = (byte *)_surface->getBasePtr(x, y)) == _color1) {
|
||||
_visited[y * _w + x] = 1;
|
||||
*p = _color2;
|
||||
|
||||
Common::Point *pt = new Common::Point(x, y);
|
||||
|
||||
_queue.push_back(pt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FloodFill::fill() {
|
||||
while (!_queue.empty()) {
|
||||
Common::Point *p = _queue.front();
|
||||
_queue.pop_front();
|
||||
addSeed(p->x , p->y - 1);
|
||||
addSeed(p->x - 1, p->y );
|
||||
addSeed(p->x , p->y + 1);
|
||||
addSeed(p->x + 1, p->y );
|
||||
|
||||
delete p;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // End of namespace Wage
|
||||
|
|
|
@ -100,21 +100,6 @@ private:
|
|||
void drawBitmap(Graphics::ManagedSurface *surface, Common::SeekableReadStream &in);
|
||||
};
|
||||
|
||||
class FloodFill {
|
||||
public:
|
||||
FloodFill(Graphics::ManagedSurface *surface, byte color1, byte color2);
|
||||
~FloodFill();
|
||||
void addSeed(int x, int y);
|
||||
void fill();
|
||||
|
||||
private:
|
||||
Common::List<Common::Point *> _queue;
|
||||
Graphics::ManagedSurface *_surface;
|
||||
byte _color1, _color2;
|
||||
byte *_visited;
|
||||
int _w, _h;
|
||||
};
|
||||
|
||||
} // End of namespace Wage
|
||||
|
||||
#endif
|
||||
|
|
|
@ -498,4 +498,64 @@ Graphics::Surface *Surface::convertTo(const PixelFormat &dstFormat, const byte *
|
|||
return surface;
|
||||
}
|
||||
|
||||
FloodFill::FloodFill(Graphics::Surface *surface, uint32 oldColor, uint32 fillColor) {
|
||||
_surface = surface;
|
||||
_oldColor = oldColor;
|
||||
_fillColor = fillColor;
|
||||
_w = surface->w;
|
||||
_h = surface->h;
|
||||
|
||||
_visited = (byte *)calloc(_w * _h, 1);
|
||||
}
|
||||
|
||||
FloodFill::~FloodFill() {
|
||||
while(!_queue.empty()) {
|
||||
Common::Point *p = _queue.front();
|
||||
|
||||
delete p;
|
||||
_queue.pop_front();
|
||||
}
|
||||
|
||||
free(_visited);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (_surface->format.bytesPerPixel == 1) {
|
||||
if (*((byte *)p) == _oldColor)
|
||||
*((byte *)p) = _fillColor;
|
||||
} else if (_surface->format.bytesPerPixel == 2) {
|
||||
if (READ_UINT16(p) == _oldColor)
|
||||
WRITE_UINT16(p, _fillColor);
|
||||
} else if (_surface->format.bytesPerPixel == 4) {
|
||||
if (READ_UINT32(p) == _oldColor)
|
||||
WRITE_UINT32(p, _fillColor);
|
||||
} else {
|
||||
error("Unsupported bpp in FloodFill");
|
||||
}
|
||||
|
||||
Common::Point *pt = new Common::Point(x, y);
|
||||
|
||||
_queue.push_back(pt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FloodFill::fill() {
|
||||
while (!_queue.empty()) {
|
||||
Common::Point *p = _queue.front();
|
||||
_queue.pop_front();
|
||||
addSeed(p->x , p->y - 1);
|
||||
addSeed(p->x - 1, p->y );
|
||||
addSeed(p->x , p->y + 1);
|
||||
addSeed(p->x + 1, p->y );
|
||||
|
||||
delete p;
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Graphics
|
||||
|
|
|
@ -24,9 +24,11 @@
|
|||
#define GRAPHICS_SURFACE_H
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "common/list.h"
|
||||
|
||||
namespace Common {
|
||||
struct Rect;
|
||||
struct Point;
|
||||
}
|
||||
|
||||
#include "graphics/pixelformat.h"
|
||||
|
@ -341,6 +343,20 @@ struct SharedPtrSurfaceDeleter {
|
|||
}
|
||||
};
|
||||
|
||||
class FloodFill {
|
||||
public:
|
||||
FloodFill(Surface *surface, uint32 oldColor, uint32 fillColor);
|
||||
~FloodFill();
|
||||
void addSeed(int x, int y);
|
||||
void fill();
|
||||
|
||||
private:
|
||||
Common::List<Common::Point *> _queue;
|
||||
Surface *_surface;
|
||||
uint32 _oldColor, _fillColor;
|
||||
byte *_visited;
|
||||
int _w, _h;
|
||||
};
|
||||
|
||||
} // End of namespace Graphics
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue