diff options
Diffstat (limited to 'lib/shape.cc')
-rw-r--r-- | lib/shape.cc | 147 |
1 files changed, 132 insertions, 15 deletions
diff --git a/lib/shape.cc b/lib/shape.cc index b9bdd87..9ba4f0c 100644 --- a/lib/shape.cc +++ b/lib/shape.cc @@ -15,6 +15,9 @@ mogltk::fillwalker::fillwalker() { mogltk::fillwalker::~fillwalker() { } +void mogltk::fillwalker::step(int x, int y) { +} + mogltk::fill::fill() : header(0) { } @@ -28,12 +31,13 @@ void mogltk::fill::walk(fillwalker * w) { } void mogltk::fill::insert(int x, int y) { - if (!header) + if (!header) { new sline(y, this); + } header->insert(x, y); } -mogltk::fill::sline::sline(int _y, fill * _header) : y(_y), pheader(0), header(_header) { +mogltk::fill::sline::sline(int _y, fill * _header) : y(_y), header(_header), pheader(0) { if (!header->header) { header->header = this; } else { @@ -56,13 +60,13 @@ mogltk::fill::sline::sline(int _y, fill * _header) : y(_y), pheader(0), header(_ } mogltk::fill::sline::~sline() { - if (header) - delete header; + if (pheader) + delete pheader; if (next) delete next; } -int mogltk::fill::sline::GetY() { +int mogltk::fill::sline::GetY() const { return y; } @@ -75,17 +79,88 @@ void mogltk::fill::sline::insert(int ax, int ay) { else if (!pheader->look(ax)) new point(ax, this); } else { - f = look(y); + f = header->header->look(ay); - if (!f) - f = new sline(y, header); + if (!f) { + f = new sline(ay, header); + } f->insert(ax, ay); } } void mogltk::fill::sline::walk(fillwalker * w) { + if (pheader) + pheader->walk(w); + if (next) + next->walk(w); +} + +mogltk::fill::sline::point::point(int _x, sline * _header) : x(_x), header(_header) { + if (!header->pheader) { + header->pheader = this; + } else { + if (header->pheader->x > x) { + next = header->pheader; + header->pheader = this; + } else { + point * p; + for (p = header->pheader; p->next; p = p->next) { + if (p->next->x > x) { + next = p->next; + p->next = this; + return; + } + } + p->next = this; + next = 0; + } + } +} + +mogltk::fill::sline::point::~point() { + if (next) + delete next; +} + +int mogltk::fill::sline::point::GetX() const { + return x; +} + +int mogltk::fill::sline::point::GetY() const { + return header->GetY(); +} + +void mogltk::fill::sline::point::walk(fillwalker * w) { w->step(GetX(), GetY()); + if (next) + next->walk(w); +} + +mogltk::fill::sline::point * mogltk::fill::sline::point::look(int _x) { + if (x > _x) + return 0; + + if (x == _x) + return this; + + if (!next) + return 0; + + return next->look(_x); +} + +mogltk::fill::sline * mogltk::fill::sline::look(int _y) { + if (y > _y) + return 0; + + if (y == _y) + return this; + + if (!next) + return 0; + + return next->look(_y); } void mogltk::shape::box(int x1, int y1, int x2, int y2, ColorP c) { @@ -205,32 +280,74 @@ void mogltk::shape::circle(int x0, int y0, int r, ColorP c) { LEAVE; } -void mogltk::shape::pcircle(int x0, int y0, int r, ColorP c) { - ENTER; - +mogltk::fill * mogltk::shape::fcircle(int x0, int y0, int r) { int x = 0; int y = r - 1; int d = 3 - 2 * r; int dI = 10 - 4 * r; int rI = 6; + mogltk::fill * f = new fill(); + bool t = true; while (x <= y) { - hline(x0 - x, x0 + x, y0 + y, c); - hline(x0 - x, x0 + x, y0 - y, c); - hline(x0 - y, x0 + y, y0 + x, c); - hline(x0 - y, x0 + y, y0 - x, c); + if (t) { + f->insert(x0 - x, y0 - y); + f->insert(x0 + x, y0 - y); + f->insert(x0 - x, y0 + y); + f->insert(x0 + x, y0 + y); + } + f->insert(x0 - y, y0 - x); + f->insert(x0 + y, y0 - x); + f->insert(x0 - y, y0 + x); + f->insert(x0 + y, y0 + x); if (d >= 0) { d += dI; dI += 8; y -= 1; + t = true; } else { d += rI; dI += 4; + t = false; } rI += 4; x += 1; } + return f; +} +void mogltk::shape::pcircle(int x, int y, int r, ColorP c) { + fill * f = fcircle(x, y, r); + fdraw(f, c); + delete f; +} + +class filldrawer : public mogltk::fillwalker { + public: + filldrawer(mogltk::shape * _s, mogltk::ColorP _c = DOS_WHITE) : s(_s), c(_c), oldx(-1), oldy(-1) { } + virtual ~filldrawer() { } + virtual void step(int x, int y) { + if (oldy != y) + oldx = -1; + if (oldx == -1) { + oldx = x; + } else { + s->hline(oldx, x, y, c); + oldx = -1; + } + oldy = y; + } + private: + mogltk::shape * s; + mogltk::ColorP c; + int oldx, oldy; +}; + +void mogltk::shape::fdraw(fill * f, ColorP c) { + ENTER; + filldrawer * w = new filldrawer(this, c); + f->walk(w); + delete w; LEAVE; } |