dc37a14010
floodfill — скан-строчная заливка области до границы (self-bracket чтение: корректно, но медленно; raw-оптимизация в TODO). pieslice/sector — залитые сектора круга/эллипса: границу (центр→дуга→ центр) прогоняем через _bgi_poly_edge и заливаем min/max по строкам, как fillpoly (для >180° возможен перелив — упрощение). Проверено в MAME (tests/bgitest): floodfill круга, круговая диаграмма, штрих-сектор. Доки/справочник/память обновлены (Ф2a-c готовы; Ф2d = images/viewport/ text-style/line-style — осталось). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
71 lines
2.6 KiB
C
71 lines
2.6 KiB
C
/*
|
|
* floodfill — заливка связной области с (x,y) до границы цвета border.
|
|
*
|
|
* Скан-строчный (span) flood: заполняем горизонтальный отрезок текущим
|
|
* цветом заливки, затем ищем новые «затравки» в строках сверху/снизу.
|
|
* Стоп-условие пикселя: вне экрана / цвет == border / цвет уже == цвет
|
|
* заливки (иначе не сойдётся). Паттерн в floodfill не применяется —
|
|
* заливаем сплошным _bgi_fill_color (упрощение).
|
|
*
|
|
* Чтение/запись — self-bracket (_bgi_read/_bgi_hspan): чуть медленнее,
|
|
* зато не держим DI на всю (возможно большую) заливку.
|
|
*
|
|
* Стек затравок ограничен FF_STACK; при переполнении лишние затравки
|
|
* отбрасываются (заливка может остаться неполной на очень «рваных»
|
|
* фигурах) — компромисс по памяти.
|
|
*/
|
|
|
|
#include "_bgi.h"
|
|
|
|
#define FF_STACK 300
|
|
static int ff_sx[FF_STACK];
|
|
static int ff_sy[FF_STACK];
|
|
static int ff_sp;
|
|
|
|
/* 1 = пиксель нельзя заливать (стоп): вне экрана / border / уже залит. */
|
|
static int ff_stop(int x, int y, int border)
|
|
{
|
|
int c;
|
|
if (x < 0 || x > _bgi_maxx || y < 0 || y > _bgi_maxy) return 1;
|
|
c = _bgi_read(x, y);
|
|
return (c == border || c == _bgi_fill_color);
|
|
}
|
|
|
|
static void ff_push(int x, int y)
|
|
{
|
|
if (ff_sp < FF_STACK) { ff_sx[ff_sp] = x; ff_sy[ff_sp] = y; ff_sp++; }
|
|
}
|
|
|
|
void floodfill(int x, int y, int border)
|
|
{
|
|
int xl, xr, xi, yy, d;
|
|
uint8_t fc = _bgi_fill_color;
|
|
|
|
if (ff_stop(x, y, border)) return;
|
|
|
|
ff_sp = 0;
|
|
ff_push(x, y);
|
|
|
|
while (ff_sp > 0) {
|
|
ff_sp--;
|
|
x = ff_sx[ff_sp];
|
|
y = ff_sy[ff_sp];
|
|
if (ff_stop(x, y, border)) continue;
|
|
|
|
for (xl = x; !ff_stop(xl - 1, y, border); ) xl--;
|
|
for (xr = x; !ff_stop(xr + 1, y, border); ) xr++;
|
|
_bgi_hspan(xl, y, xr - xl + 1, fc);
|
|
|
|
for (d = -1; d <= 1; d += 2) {
|
|
yy = y + d;
|
|
xi = xl;
|
|
while (xi <= xr) {
|
|
while (xi <= xr && ff_stop(xi, yy, border)) xi++;
|
|
if (xi > xr) break;
|
|
while (xi <= xr && !ff_stop(xi, yy, border)) xi++;
|
|
ff_push(xi - 1, yy); /* правый край найденного пробега */
|
|
}
|
|
}
|
|
}
|
|
}
|