summaryrefslogtreecommitdiff
path: root/lib/shape.cc
diff options
context:
space:
mode:
Diffstat (limited to 'lib/shape.cc')
-rw-r--r--lib/shape.cc147
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;
}