diff options
-rw-r--r-- | include/shape.h | 46 | ||||
-rw-r--r-- | lib/shape.cc | 79 |
2 files changed, 125 insertions, 0 deletions
diff --git a/include/shape.h b/include/shape.h index fdae6af..720d4a2 100644 --- a/include/shape.h +++ b/include/shape.h @@ -12,6 +12,52 @@ namespace mogltk { CENTER, RIGHT } align_t; + class fillwalker : public Base { + public: + fillwalker(); + virtual ~fillwalker(); + virtual void step(int x, int y); + }; + class fill : public Base { + public: + fill(); + virtual ~fill(); + void walk(fillwalker *); + void insert(int, int); + private: + class sline : public Base { + public: + sline(int, fill *); + virtual ~sline(); + int GetY() const; + void insert(int, int); + void walk(fillwalker *); + private: + class point : public Base { + public: + point(int, sline *); + virtual ~point(); + int GetX() const; + int GetY() const; + void walk(fillwalker *); + private: + int x; + point * next; + sline * header; + point * look(int); + }; + int y; + sline * next; + sline * look(int); + protected: + point * pheader; + fill * header; + friend class point; + }; + protected: + sline * header; + friend class sline; + }; class shape : public Base { public: virtual void pixel(int x, int y, ColorP = WHITE); diff --git a/lib/shape.cc b/lib/shape.cc index 972600c..b9bdd87 100644 --- a/lib/shape.cc +++ b/lib/shape.cc @@ -9,6 +9,85 @@ #define ENTER bool flag = Enter() #define LEAVE Leave(flag) +mogltk::fillwalker::fillwalker() { +} + +mogltk::fillwalker::~fillwalker() { +} + +mogltk::fill::fill() : header(0) { +} + +mogltk::fill::~fill() { + if (header) + delete header; +} + +void mogltk::fill::walk(fillwalker * w) { + header->walk(w); +} + +void mogltk::fill::insert(int x, int y) { + if (!header) + new sline(y, this); + header->insert(x, y); +} + +mogltk::fill::sline::sline(int _y, fill * _header) : y(_y), pheader(0), header(_header) { + if (!header->header) { + header->header = this; + } else { + if (header->header->y > y) { + next = header->header; + header->header = this; + } else { + sline * p; + for (p = header->header; p->next; p = p->next) { + if (p->next->y > y) { + next = p->next; + p->next = this; + return; + } + } + p->next = this; + next = 0; + } + } +} + +mogltk::fill::sline::~sline() { + if (header) + delete header; + if (next) + delete next; +} + +int mogltk::fill::sline::GetY() { + return y; +} + +void mogltk::fill::sline::insert(int ax, int ay) { + sline * f; + + if (ay == y) { + if (!pheader) + new point(ax, this); + else if (!pheader->look(ax)) + new point(ax, this); + } else { + f = look(y); + + if (!f) + f = new sline(y, header); + + f->insert(ax, ay); + } +} + +void mogltk::fill::sline::walk(fillwalker * w) { + w->step(GetX(), GetY()); +} + void mogltk::shape::box(int x1, int y1, int x2, int y2, ColorP c) { ENTER; |