diff options
Diffstat (limited to 'lib/shape.cc')
-rw-r--r-- | lib/shape.cc | 1856 |
1 files changed, 928 insertions, 928 deletions
diff --git a/lib/shape.cc b/lib/shape.cc index 032ea23..2a493cb 100644 --- a/lib/shape.cc +++ b/lib/shape.cc @@ -1,928 +1,928 @@ -/* - * mogltk - * Copyright (C) 1999-2004 Nicolas "Pixel" Noble - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* $Id: shape.cc,v 1.17 2004-07-15 14:21:31 pixel Exp $ */ - -#include <math.h> -#include <limits.h> -#include <SDL.h> -#include <sys/types.h> -#include <generic.h> -#include "engine.h" -#include "base.h" -#include "shape.h" -#include "texture.h" -#include "font.h" - -#define ENTER bool flag = Enter() -#define LEAVE Leave(flag) - -mogltk::fillwalker::fillwalker() { -} - -mogltk::fillwalker::~fillwalker() { -} - -void mogltk::fillwalker::step(int x, int y) { -} - -mogltk::segwalker::segwalker() { -} - -mogltk::segwalker::~segwalker() { -} - -void mogltk::segwalker::step(int x1, int y1, int x2, int y2) { -} - -mogltk::fill::fill() : minX(INT_MAX), minY(INT_MAX), maxX(INT_MIN), maxY(INT_MIN), cached(0), scached(0), header(0) { -} - -mogltk::fill::~fill() { - if (header) - delete header; - - if (cached) - delete cached; - - if (scached) - delete scached; -} - -void mogltk::fill::walk(fillwalker * w) { - if (header) - header->walk(w); -} - -void mogltk::fill::swalk(segwalker * s) { - std::vector<struct segment>::iterator i; - - for (i = segments.begin(); i != segments.end(); i++) { - s->step(i->x1, i->y1, i->x2, i->y2); - } -} - -void mogltk::fill::insert(int x, int y) { - if (cached) { - delete cached; - cached = 0; - } - - if (scached) { - delete scached; - scached = 0; - } - - if (!header) { - new sline(y, this); - } - header->insert(x, y); - - if (x > maxX) - maxX = x; - - if (x < minX) - minX = x; - - if (y > maxY) - maxY = y; - - if (y < minY) - minY = y; -} - -void mogltk::fill::insert(int x1, int y1, int x2, int y2) { - int dx, dy, y; - double x, i, i2; - - struct segment s; - s.x1 = x1; - s.y1 = y1; - s.x2 = x2; - s.y2 = y2; - segments.push_back(s); - - if (y1 == y2) - return; - - if (y2 < y1) { - SWAP(x1, x2); - SWAP(y1, y2); - } - - dx = x1 - x2; - dy = y1 - y2; - - x = x1; - i = ((double) dx) / ((double) dy); - i2 = i / 2; - for (y = y1; y < y2; y++, x += i) - insert(x + i2, y); -} - -void mogltk::fill::insertfix(int x, int y) { - if (!header) - return; - - header->insertfix(x, y); -} - -int mogltk::fill::GetMaxX() const { - return maxX; -} - -int mogltk::fill::GetMaxY() const { - return maxY; -} - -int mogltk::fill::GetMinX() const { - return minX; -} - -int mogltk::fill::GetMinY() const { - return minY; -} - -mogltk::texture * mogltk::fill::GetTexture() { - return cached; -} - -mogltk::texture * mogltk::fill::GetSTexture() { - return scached; -} - -mogltk::texture * mogltk::fill::Talloc() { - if (cached) - return cached; - - int x; int y; - - for (x = 1; x <= (maxX - minX); x <<= 1); - for (y = 1; y <= (maxY - minY); y <<= 1); - - cached = new texture(x, y, true); - return cached; -} - -mogltk::texture * mogltk::fill::STalloc() { - if (scached) - return scached; - - int x; int y; - - for (x = 1; x <= (maxX - minX); x <<= 1); - for (y = 1; y <= (maxY - minY); y <<= 1); - - scached = new texture(x, y, true); - return scached; -} - -mogltk::fill::sline::sline(int _y, fill * _header) : y(_y), header(_header), pheader(0) { - 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 (pheader) - delete pheader; - if (next) - delete next; -} - -int mogltk::fill::sline::GetY() const { - 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 = header->header->look(ay); - - if (!f) { - f = new sline(ay, header); - } - - f->insert(ax, ay); - } -} - -void mogltk::fill::sline::insertfix(int ax, int ay) { - sline * f; - - if (ay == y) { - if (count() & 1) { - insert(ax, ay); - } - } else { - f = header->header->look(ay); - if (!f) - return; - - f->insertfix(ax, ay); - } -} - -int mogltk::fill::sline::count() const { - int r = 0; - - if (next) - r = next->count(); - - return r + 1; -} - -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); -} - -mogltk::shape::shape(SDL_Surface * _surf) : surf(_surf) { - if (!surf) - surf = mogltk::engine::base_o->getsurface(); -} - -SDL_Surface * mogltk::shape::GetSurf() { - return surf; -} - -void mogltk::shape::box(int x1, int y1, int x2, int y2, ColorP c) { - ENTER; - - SDL_Rect rect; - - rect.x = x1; rect.y = y1; rect.w = x2 - x1 + 1; rect.h = y2 - y1 + 1; - SDL_FillRect(surf, &rect, c.toSDL(surf->format)); - - LEAVE; -} - -void mogltk::shape::hline(int x1, int x2, int y, ColorP c) { - for (; x1 <= x2; x1++) { - pixel(x1, y, c); - } -} - -void mogltk::shape::hline3d(int x1, int x2, int y, ColorP shade1, ColorP shade2, bool bevel) { - ENTER; - - if (!bevel) { - hline(x1, x2, y, shade2); - hline(x1, x2, y + 1, shade1); - } else { - hline(x1, x2, y, shade1); - hline(x1, x2, y + 1, shade2); - } - - LEAVE; -} - -void mogltk::shape::vline(int x, int y1, int y2, ColorP c) { - for (; y1 <= y2; y1++) { - pixel(x, y1, c); - } -} - -void mogltk::shape::vline3d(int x, int y1, int y2, ColorP shade1, ColorP shade2, bool bevel) { - ENTER; - - if (!bevel) { - vline(x, y1, y2, shade2); - vline(x + 1, y1, y2, shade1); - } else { - vline(x, y1, y2, shade1); - vline(x + 1, y1, y2, shade2); - } - - LEAVE; -} - -void mogltk::shape::bsubline_1(int x1, int y1, int x2, int y2, ColorP c) { - int x, y, ddx, ddy, e; - ddx = abs(x2 - x1); - ddy = abs(y2 - y1) << 1; - e = ddx - ddy; - ddx <<= 1; - - if (x1 > x2) { - SWAP(x1, x2); - SWAP(y1, y2); - } - - ENTER; - - for (x = x1, y = y1; x <= x2; x++) { - pixel(x, y, c); - if (e < 0) { - y++; - e += ddx - ddy; - } else { - e -= ddy; - } - } - - LEAVE; -} - -void mogltk::shape::bsubline_2(int x1, int y1, int x2, int y2, ColorP c) { - int x, y, ddx, ddy, e; - ddx = abs(x2 - x1) << 1; - ddy = abs(y2 - y1); - e = ddy - ddx; - ddy <<= 1; - - if (y1 > y2) { - SWAP(x1, x2); - SWAP(y1, y2); - } - - ENTER; - - for (y = y1, x = x1; y <= y2; y++) { - pixel(x, y, c); - if (e < 0) { - x++; - e += ddy - ddx; - } else { - e -= ddx; - } - } - - LEAVE; -} - -void mogltk::shape::bsubline_3(int x1, int y1, int x2, int y2, ColorP c) { - int x, y, ddx, ddy, e; - ddx = abs(x1 - x2) << 1; - ddy = abs(y2 - y1); - e = ddy - ddx; - ddy <<= 1; - - if (y1 > y2) { - SWAP(x1, x2); - SWAP(y1, y2); - } - - ENTER; - - for (y = y1, x = x1; y <= y2; y++) { - pixel(x, y, c); - if (e < 0) { - x--; - e += ddy - ddx; - } else { - e -= ddx; - } - } - - LEAVE; -} - -void mogltk::shape::bsubline_4(int x1, int y1, int x2, int y2, ColorP c) { - int x, y, ddx, ddy, e; - ddy = abs(y2 - y1) << 1; - ddx = abs(x1 - x2); - e = ddx - ddy; - ddx <<= 1; - - if (x1 > x2) { - SWAP(x1, x2); - SWAP(y1, y2); - } - - for (x = x1, y = y1; x <= x2; x++) { - pixel(x, y, c); - if (e < 0) { - y--; - e += ddx - ddy; - } else { - e -= ddy; - } - } -} - -void mogltk::shape::line(int x1, int y1, int x2, int y2, ColorP c) { - if ((x1 == x2) && (y1 == y2)) { - printm(M_INFO, "Line is a pixel...\n"); - pixel(x1, y1, c); - return; - } - - if (x1 == x2) { - vline(x1, MIN(y1, y2), MAX(y1, y2), c); - return; - } - - if (y1 == y2) { - hline(MIN(x1, x2), MAX(x1, x2), y1, c); - return; - } - - float k = float(y2 - y1) / float(x2 - x1); - - if ((k >= 0) && (k <= 1)) { - bsubline_1(x1, y1, x2, y2, c); - } else if (k > 1) { - bsubline_2(x1, y1, x2, y2, c); - } else if ((k < 0) && (k >= -1)) { - bsubline_4(x1, y1, x2, y2, c); - } else { - bsubline_3(x1, y1, x2, y2, c); - } -} - -void mogltk::shape::pixel(int x, int y, ColorP c) { - ENTER; - - int bpp = surf->format->BytesPerPixel; - Uint8 *p = (Uint8 *)surf->pixels + y * surf->pitch + x * bpp; - Uint32 pixel = c.toSDL(surf->format); - - if ((x < 0) || (y < 0) || (x >= surf->w) || (y >= surf->h)) { - printm(M_INFO, "Pixel culling, out of bounds.\n"); - return; - } - - switch(bpp) { - case 1: - *p = pixel; - break; - - case 2: - *(Uint16 *)p = pixel; - break; - - case 3: - if(SDL_BYTEORDER == SDL_BIG_ENDIAN) { - p[0] = (pixel >> 16) & 0xff; - p[1] = (pixel >> 8) & 0xff; - p[2] = pixel & 0xff; - } else { - p[0] = pixel & 0xff; - p[1] = (pixel >> 8) & 0xff; - p[2] = (pixel >> 16) & 0xff; - } - break; - - case 4: - *(Uint32 *)p = pixel; - break; - } - - LEAVE; -} - -void mogltk::shape::circle(int x0, int y0, int r, ColorP c) { - ENTER; - - int x = 0; - int y = r - 1; - int d = 3 - 2 * r; - int dI = 10 - 4 * r; - int rI = 6; - - while (x <= y) { - pixel(x0 + x, y0 + y, c); - pixel(x0 - x, y0 + y, c); - pixel(x0 + x, y0 - y, c); - pixel(x0 - x, y0 - y, c); - pixel(x0 + y, y0 + x, c); - pixel(x0 - y, y0 + x, c); - pixel(x0 + y, y0 - x, c); - pixel(x0 - y, y0 - x, c); - if (d >= 0) { - d += dI; - dI += 8; - y -= 1; - } else { - d += rI; - dI += 4; - } - rI += 4; - x += 1; - } - - LEAVE; -} - -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 = false; - int ox = 0, oy = 0; - - while (x <= y) { -/* - 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 (t) { - f->insert(x0 - ox, y0 - oy, x0 - x, y0 - y); - f->insert(x0 + ox, y0 - oy, x0 + x, y0 - y); - f->insert(x0 - ox, y0 + oy, x0 - x, y0 + y); - f->insert(x0 + ox, y0 + oy, x0 + x, y0 + y); - f->insert(x0 - oy, y0 - ox, x0 - y, y0 - x); - f->insert(x0 + oy, y0 - ox, x0 + y, y0 - x); - f->insert(x0 - oy, y0 + ox, x0 - y, y0 + x); - f->insert(x0 + oy, y0 + ox, x0 + y, y0 + x); - } - ox = x; - oy = y; - t = true; - if (d >= 0) { - d += dI; - dI += 8; - y -= 1; - } else { - d += rI; - dI += 4; - } - 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; -} - -mogltk::filldrawer::filldrawer(fill * _f, texture * _t, ColorP _c) : f(_f), t(_t), c(_c), oldx(-1), oldy(-1) { -} - -mogltk::filldrawer::~filldrawer() { -} - -void mogltk::filldrawer::step(int x, int y) { - if (oldy != y) { - oldx = -1; - } - if (oldx == -1) { - oldx = x; - } else { -/* s->hline(oldx, x, y, c); */ - Uint32 * p = t->GetPixels(); - int i, - first = t->GetWidth() * (y - f->GetMinY()) + oldx - f->GetMinX(), - last = first - oldx + x; - SDL_PixelFormat * format = t->GetFormat(); - - for (i = first; i <= last; i++) { - if (i > (t->GetWidth() * t->GetHeight())) { - printm(M_ERROR, "Big problem here. i = %i and W, H = %i, %i\n", i, t->GetWidth(), t->GetHeight()); - printm(M_ERROR, "Initially, wanted to draw hline(%i, %i, %i)\n", oldx, x, y); - printm(M_ERROR, "With MinX = %i and MinY = %i --> hline(%i, %i, %i)\n", f->GetMinX(), f->GetMinY(), oldx - f->GetMinX(), x - f->GetMinX(), y - f->GetMinY()); - printm(M_ERROR, "For info, MaxX = %i and MaxY = %i\n", f->GetMaxX(), f->GetMaxY()); - exit(-1); - } - p[i] = c.toSDL(format); - } - - oldx = -1; - } - oldy = y; -} - -void mogltk::shape::fdraw(fill * f, ColorP c, int sx, int sy) { - ENTER; - if (!f) - return; - if (!f->GetTexture()) { - filldrawer * w = new filldrawer(f, f->Talloc(), c); - f->walk(w); - delete w; - f->last = c.c; - } - SDL_PixelFormat * format = f->GetTexture()->GetFormat(); - - if (f->last == c.c) { - Uint32 * p = f->GetTexture()->GetPixels(); - int i, n = f->GetTexture()->GetWidth() * f->GetTexture()->GetHeight(); - for (i = 0; i < n; i++) - if (p[i] & 0xff000000) - p[i] = c.toSDL(format); - } - SDL_Rect r; - r.x = f->GetMinX() + sx; - r.y = f->GetMinY() + sy; - SDL_BlitSurface(f->GetTexture()->GetSurface(), 0, surf, &r); - - f->last = c.c; - LEAVE; -} - -mogltk::segdrawer::segdrawer(fill * _f, texture * _t, ColorP _c) : f(_f), t(_t), c(_c), sh(new shape(_t->GetSurface())) { -} - -mogltk::segdrawer::~segdrawer() { - delete sh; -} - -void mogltk::segdrawer::step(int x1, int y1, int x2, int y2) { - sh->line(x1 - f->GetMinX(), y1 - f->GetMinY(), x2 - f->GetMinX(), y2 - f->GetMinY(), c); -} - -void mogltk::shape::sdraw(fill * f, ColorP c, int sx, int sy) { - ENTER; - - if (!f) - return; - - if (!f->GetSTexture()) { - segdrawer * w = new segdrawer(f, f->STalloc(), c); - f->swalk(w); - delete w; - f->last = c.c; - } - SDL_PixelFormat * format = f->GetSTexture()->GetFormat(); - - if (f->last == c.c) { - Uint32 * p = f->GetSTexture()->GetPixels(); - int i, n = f->GetSTexture()->GetWidth() * f->GetSTexture()->GetHeight(); - for (i = 0; i < n; i++) - if (p[i] & 0xff000000) - p[i] = c.toSDL(format); - } - SDL_Rect r; - r.x = f->GetMinX() + sx; - r.y = f->GetMinY() + sy; - SDL_BlitSurface(f->GetSTexture()->GetSurface(), 0, surf, &r); - - f->last = c.c; - LEAVE; -} - -void mogltk::shape::obox(int x1, int y1, int x2, int y2, ColorP c) { - ENTER; - - hline(x1, x2, y1, c); - hline(x1, x2, y2, c); - vline(x1, y1 + 1, y2 - 1, c); - vline(x2, y1 + 1, y2 - 1, c); - - LEAVE; -} - -void mogltk::shape::box3d(int x1, int y1, int x2, int y2, ColorP face, ColorP shade1, ColorP shade2, int depth, bool bevel) { - ENTER; - - int i; - - for (i = 0; i < depth; i++) { - hline(x1 + i, x2 - i, y1 + i, bevel ? shade2 : shade1); - vline(x1 + i, y1 + i, y2 - i, bevel ? shade2 : shade1); - } - - for (i = 0; i < depth; i++) { - hline(x1 + i, x2 - i, y2 - i, bevel ? shade1 : shade2); - vline(x2 - i, y1 + i, y2 - i, bevel ? shade1 : shade2); - } - - box(x1 + depth, y1 + depth, x2 - depth, y2 - depth, face); - - LEAVE; -} - -void mogltk::shape::obox3d(int x1, int y1, int x2, int y2, ColorP shade1, ColorP shade2, bool bevel) { - ENTER; - - if (!bevel) { - obox(x1 + 1, y1 + 1, x2, y2, shade1); - obox(x1, y1, x2 - 1, y2 - 1, shade2); - } else { - obox(x1, y1, x2 - 1, y2 - 1, shade1); - obox(x1 + 1, y1 + 1, x2, y2, shade2); - } - - LEAVE; -} - -void mogltk::shape::window(int x1, int y1, int x2, int y2, const String & title, - ColorP titlecolor, ColorP titlebackcolor, - ColorP front, ColorP shade1, ColorP shade2) { - ENTER; - - box3d(x1, y1, x2, y2, front, shade1, shade2); - hline3d(x1 + 2, x2 - 2, y1 + 19, shade1, shade2, 1); - box(x1 + 2, y1 + 2, x2 - 2, y1 + 18, titlebackcolor); - text((x1 + x2) / 2, y1 + 2, title, titlecolor, CENTER); - - LEAVE; -} - -void mogltk::shape::text(int x, int y, const String & text, ColorP textcolor, align_t align) { - int tsize = SystemFont->singletextsize(text); - switch (align) { - case LEFT: - SystemFont->putcursor(x, y); - break; - case CENTER: - SystemFont->putcursor(x - (tsize / 2), y); - break; - case RIGHT: - SystemFont->putcursor(x - tsize, y); - break; - } - SystemFont->setcolor(textcolor); - SystemFont->setshadow(0); - SystemFont->printf(text); -} - -void mogltk::shape::text3d(int x, int y, const String & atext, ColorP textcolor, - ColorP shade1, ColorP shade2, - align_t align, bool bevel) { - ENTER; - - SystemFont->setwspace(1); - if (!bevel) { - text(x - 1, y - 1, atext, shade2, align); - text(x + 1, y + 1, atext, shade1, align); - } else { - text(x - 1, y - 1, atext, shade1, align); - text(x + 1, y + 1, atext, shade2, align); - } - text(x, y, atext, textcolor, align); - SystemFont->setwspace(0); - - LEAVE; -} - -void mogltk::shape::button(int x1, int y1, int x2, int y2, - const String & atext, bool bevel, - ColorP front, ColorP shade1, ColorP shade2, - ColorP round, ColorP textcolor, - ColorP tshade1, ColorP tshade2) { - ENTER; - - box3d(x1, y1, x2, y2, front, shade1, shade2, 2, bevel); - hline(x1, x2, y1 - 1, round); - hline(x1, x2, y2 + 1, round); - vline(x1 - 1, y1, y2, round); - vline(x2 + 1, y1, y2, round); - pixel(x1, y1, round); - pixel(x1, y2, round); - pixel(x2, y1, round); - pixel(x2, y2, round); - text3d((x1 + x2) / 2, (y1 + y2) / 2 - 8, atext, textcolor, tshade1, tshade2, CENTER, bevel); - - LEAVE; -} - -bool mogltk::shape::Enter() { - if (SDL_MUSTLOCK(surf)) { - SDL_LockSurface(surf); - return true; - } else { - return false; - } -} - -void mogltk::shape::Leave(bool locked) { - if (locked) - SDL_UnlockSurface(surf); -} - -void mogltk::shape::tbox(texture *, int x1, int y1, int x2, int y2, int tx, int ty, double f, ColorP c) { -} - -void mogltk::shape::tbox(texture *, int x1, int y1, int x2, int y2, int tx1, int ty1, int tx2, int ty2, ColorP c) { -} - -void mogltk::shape::tbox(texture *, int x1, int y1, int x2, int y2, ColorP, ColorP, ColorP, ColorP, int tx, int ty, double f) { -} - -void mogltk::shape::tbox(texture *, int x1, int y1, int x2, int y2, ColorP, ColorP, ColorP, ColorP, int tx1, int ty1, int tx2, int ty2) { -} - -void mogltk::shape::vline(int x, int y1, int y2, ColorP c1, ColorP c2) { -} - -void mogltk::shape::hline(int x1, int x2, int y, ColorP c1, ColorP c2) { -} - -void mogltk::shape::box(int x1, int y1, int x2, int y2, ColorP c1, ColorP c2, ColorP c3, ColorP c4) { -} - -void mogltk::shape::obox(int x1, int y1, int x2, int y2, ColorP c1, ColorP c2, ColorP c3, ColorP c4) { -} +/*
+ * mogltk
+ * Copyright (C) 1999-2004 Nicolas "Pixel" Noble
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* $Id: shape.cc,v 1.18 2004-11-27 21:44:53 pixel Exp $ */
+
+#include <math.h>
+#include <limits.h>
+#include <SDL.h>
+#include <sys/types.h>
+#include <generic.h>
+#include "engine.h"
+#include "base.h"
+#include "shape.h"
+#include "texture.h"
+#include "font.h"
+
+#define ENTER bool flag = Enter()
+#define LEAVE Leave(flag)
+
+mogltk::fillwalker::fillwalker() {
+}
+
+mogltk::fillwalker::~fillwalker() {
+}
+
+void mogltk::fillwalker::step(int x, int y) {
+}
+
+mogltk::segwalker::segwalker() {
+}
+
+mogltk::segwalker::~segwalker() {
+}
+
+void mogltk::segwalker::step(int x1, int y1, int x2, int y2) {
+}
+
+mogltk::fill::fill() : minX(INT_MAX), minY(INT_MAX), maxX(INT_MIN), maxY(INT_MIN), cached(0), scached(0), header(0) {
+}
+
+mogltk::fill::~fill() {
+ if (header)
+ delete header;
+
+ if (cached)
+ delete cached;
+
+ if (scached)
+ delete scached;
+}
+
+void mogltk::fill::walk(fillwalker * w) {
+ if (header)
+ header->walk(w);
+}
+
+void mogltk::fill::swalk(segwalker * s) {
+ std::vector<struct segment>::iterator i;
+
+ for (i = segments.begin(); i != segments.end(); i++) {
+ s->step(i->x1, i->y1, i->x2, i->y2);
+ }
+}
+
+void mogltk::fill::insert(int x, int y) {
+ if (cached) {
+ delete cached;
+ cached = 0;
+ }
+
+ if (scached) {
+ delete scached;
+ scached = 0;
+ }
+
+ if (!header) {
+ new sline(y, this);
+ }
+ header->insert(x, y);
+
+ if (x > maxX)
+ maxX = x;
+
+ if (x < minX)
+ minX = x;
+
+ if (y > maxY)
+ maxY = y;
+
+ if (y < minY)
+ minY = y;
+}
+
+void mogltk::fill::insert(int x1, int y1, int x2, int y2) {
+ int dx, dy, y;
+ double x, i, i2;
+
+ struct segment s;
+ s.x1 = x1;
+ s.y1 = y1;
+ s.x2 = x2;
+ s.y2 = y2;
+ segments.push_back(s);
+
+ if (y1 == y2)
+ return;
+
+ if (y2 < y1) {
+ SWAP(x1, x2);
+ SWAP(y1, y2);
+ }
+
+ dx = x1 - x2;
+ dy = y1 - y2;
+
+ x = x1;
+ i = ((double) dx) / ((double) dy);
+ i2 = i / 2;
+ for (y = y1; y < y2; y++, x += i)
+ insert(x + i2, y);
+}
+
+void mogltk::fill::insertfix(int x, int y) {
+ if (!header)
+ return;
+
+ header->insertfix(x, y);
+}
+
+int mogltk::fill::GetMaxX() const {
+ return maxX;
+}
+
+int mogltk::fill::GetMaxY() const {
+ return maxY;
+}
+
+int mogltk::fill::GetMinX() const {
+ return minX;
+}
+
+int mogltk::fill::GetMinY() const {
+ return minY;
+}
+
+mogltk::texture * mogltk::fill::GetTexture() {
+ return cached;
+}
+
+mogltk::texture * mogltk::fill::GetSTexture() {
+ return scached;
+}
+
+mogltk::texture * mogltk::fill::Talloc() {
+ if (cached)
+ return cached;
+
+ int x; int y;
+
+ for (x = 1; x <= (maxX - minX); x <<= 1);
+ for (y = 1; y <= (maxY - minY); y <<= 1);
+
+ cached = new texture(x, y, true);
+ return cached;
+}
+
+mogltk::texture * mogltk::fill::STalloc() {
+ if (scached)
+ return scached;
+
+ int x; int y;
+
+ for (x = 1; x <= (maxX - minX); x <<= 1);
+ for (y = 1; y <= (maxY - minY); y <<= 1);
+
+ scached = new texture(x, y, true);
+ return scached;
+}
+
+mogltk::fill::sline::sline(int _y, fill * _header) : y(_y), header(_header), pheader(0) {
+ 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 (pheader)
+ delete pheader;
+ if (next)
+ delete next;
+}
+
+int mogltk::fill::sline::GetY() const {
+ 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 = header->header->look(ay);
+
+ if (!f) {
+ f = new sline(ay, header);
+ }
+
+ f->insert(ax, ay);
+ }
+}
+
+void mogltk::fill::sline::insertfix(int ax, int ay) {
+ sline * f;
+
+ if (ay == y) {
+ if (count() & 1) {
+ insert(ax, ay);
+ }
+ } else {
+ f = header->header->look(ay);
+ if (!f)
+ return;
+
+ f->insertfix(ax, ay);
+ }
+}
+
+int mogltk::fill::sline::count() const {
+ int r = 0;
+
+ if (next)
+ r = next->count();
+
+ return r + 1;
+}
+
+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);
+}
+
+mogltk::shape::shape(SDL_Surface * _surf) : surf(_surf) {
+ if (!surf)
+ surf = mogltk::engine::base_o->getsurface();
+}
+
+SDL_Surface * mogltk::shape::GetSurf() {
+ return surf;
+}
+
+void mogltk::shape::box(int x1, int y1, int x2, int y2, ColorP c) {
+ ENTER;
+
+ SDL_Rect rect;
+
+ rect.x = x1; rect.y = y1; rect.w = x2 - x1 + 1; rect.h = y2 - y1 + 1;
+ SDL_FillRect(surf, &rect, c.toSDL(surf->format));
+
+ LEAVE;
+}
+
+void mogltk::shape::hline(int x1, int x2, int y, ColorP c) {
+ for (; x1 <= x2; x1++) {
+ pixel(x1, y, c);
+ }
+}
+
+void mogltk::shape::hline3d(int x1, int x2, int y, ColorP shade1, ColorP shade2, bool bevel) {
+ ENTER;
+
+ if (!bevel) {
+ hline(x1, x2, y, shade2);
+ hline(x1, x2, y + 1, shade1);
+ } else {
+ hline(x1, x2, y, shade1);
+ hline(x1, x2, y + 1, shade2);
+ }
+
+ LEAVE;
+}
+
+void mogltk::shape::vline(int x, int y1, int y2, ColorP c) {
+ for (; y1 <= y2; y1++) {
+ pixel(x, y1, c);
+ }
+}
+
+void mogltk::shape::vline3d(int x, int y1, int y2, ColorP shade1, ColorP shade2, bool bevel) {
+ ENTER;
+
+ if (!bevel) {
+ vline(x, y1, y2, shade2);
+ vline(x + 1, y1, y2, shade1);
+ } else {
+ vline(x, y1, y2, shade1);
+ vline(x + 1, y1, y2, shade2);
+ }
+
+ LEAVE;
+}
+
+void mogltk::shape::bsubline_1(int x1, int y1, int x2, int y2, ColorP c) {
+ int x, y, ddx, ddy, e;
+ ddx = abs(x2 - x1);
+ ddy = abs(y2 - y1) << 1;
+ e = ddx - ddy;
+ ddx <<= 1;
+
+ if (x1 > x2) {
+ SWAP(x1, x2);
+ SWAP(y1, y2);
+ }
+
+ ENTER;
+
+ for (x = x1, y = y1; x <= x2; x++) {
+ pixel(x, y, c);
+ if (e < 0) {
+ y++;
+ e += ddx - ddy;
+ } else {
+ e -= ddy;
+ }
+ }
+
+ LEAVE;
+}
+
+void mogltk::shape::bsubline_2(int x1, int y1, int x2, int y2, ColorP c) {
+ int x, y, ddx, ddy, e;
+ ddx = abs(x2 - x1) << 1;
+ ddy = abs(y2 - y1);
+ e = ddy - ddx;
+ ddy <<= 1;
+
+ if (y1 > y2) {
+ SWAP(x1, x2);
+ SWAP(y1, y2);
+ }
+
+ ENTER;
+
+ for (y = y1, x = x1; y <= y2; y++) {
+ pixel(x, y, c);
+ if (e < 0) {
+ x++;
+ e += ddy - ddx;
+ } else {
+ e -= ddx;
+ }
+ }
+
+ LEAVE;
+}
+
+void mogltk::shape::bsubline_3(int x1, int y1, int x2, int y2, ColorP c) {
+ int x, y, ddx, ddy, e;
+ ddx = abs(x1 - x2) << 1;
+ ddy = abs(y2 - y1);
+ e = ddy - ddx;
+ ddy <<= 1;
+
+ if (y1 > y2) {
+ SWAP(x1, x2);
+ SWAP(y1, y2);
+ }
+
+ ENTER;
+
+ for (y = y1, x = x1; y <= y2; y++) {
+ pixel(x, y, c);
+ if (e < 0) {
+ x--;
+ e += ddy - ddx;
+ } else {
+ e -= ddx;
+ }
+ }
+
+ LEAVE;
+}
+
+void mogltk::shape::bsubline_4(int x1, int y1, int x2, int y2, ColorP c) {
+ int x, y, ddx, ddy, e;
+ ddy = abs(y2 - y1) << 1;
+ ddx = abs(x1 - x2);
+ e = ddx - ddy;
+ ddx <<= 1;
+
+ if (x1 > x2) {
+ SWAP(x1, x2);
+ SWAP(y1, y2);
+ }
+
+ for (x = x1, y = y1; x <= x2; x++) {
+ pixel(x, y, c);
+ if (e < 0) {
+ y--;
+ e += ddx - ddy;
+ } else {
+ e -= ddy;
+ }
+ }
+}
+
+void mogltk::shape::line(int x1, int y1, int x2, int y2, ColorP c) {
+ if ((x1 == x2) && (y1 == y2)) {
+ printm(M_INFO, "Line is a pixel...\n");
+ pixel(x1, y1, c);
+ return;
+ }
+
+ if (x1 == x2) {
+ vline(x1, MIN(y1, y2), MAX(y1, y2), c);
+ return;
+ }
+
+ if (y1 == y2) {
+ hline(MIN(x1, x2), MAX(x1, x2), y1, c);
+ return;
+ }
+
+ float k = float(y2 - y1) / float(x2 - x1);
+
+ if ((k >= 0) && (k <= 1)) {
+ bsubline_1(x1, y1, x2, y2, c);
+ } else if (k > 1) {
+ bsubline_2(x1, y1, x2, y2, c);
+ } else if ((k < 0) && (k >= -1)) {
+ bsubline_4(x1, y1, x2, y2, c);
+ } else {
+ bsubline_3(x1, y1, x2, y2, c);
+ }
+}
+
+void mogltk::shape::pixel(int x, int y, ColorP c) {
+ ENTER;
+
+ int bpp = surf->format->BytesPerPixel;
+ Uint8 *p = (Uint8 *)surf->pixels + y * surf->pitch + x * bpp;
+ Uint32 pixel = c.toSDL(surf->format);
+
+ if ((x < 0) || (y < 0) || (x >= surf->w) || (y >= surf->h)) {
+ printm(M_INFO, "Pixel culling, out of bounds.\n");
+ return;
+ }
+
+ switch(bpp) {
+ case 1:
+ *p = pixel;
+ break;
+
+ case 2:
+ *(Uint16 *)p = pixel;
+ break;
+
+ case 3:
+ if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
+ p[0] = (pixel >> 16) & 0xff;
+ p[1] = (pixel >> 8) & 0xff;
+ p[2] = pixel & 0xff;
+ } else {
+ p[0] = pixel & 0xff;
+ p[1] = (pixel >> 8) & 0xff;
+ p[2] = (pixel >> 16) & 0xff;
+ }
+ break;
+
+ case 4:
+ *(Uint32 *)p = pixel;
+ break;
+ }
+
+ LEAVE;
+}
+
+void mogltk::shape::circle(int x0, int y0, int r, ColorP c) {
+ ENTER;
+
+ int x = 0;
+ int y = r - 1;
+ int d = 3 - 2 * r;
+ int dI = 10 - 4 * r;
+ int rI = 6;
+
+ while (x <= y) {
+ pixel(x0 + x, y0 + y, c);
+ pixel(x0 - x, y0 + y, c);
+ pixel(x0 + x, y0 - y, c);
+ pixel(x0 - x, y0 - y, c);
+ pixel(x0 + y, y0 + x, c);
+ pixel(x0 - y, y0 + x, c);
+ pixel(x0 + y, y0 - x, c);
+ pixel(x0 - y, y0 - x, c);
+ if (d >= 0) {
+ d += dI;
+ dI += 8;
+ y -= 1;
+ } else {
+ d += rI;
+ dI += 4;
+ }
+ rI += 4;
+ x += 1;
+ }
+
+ LEAVE;
+}
+
+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 = false;
+ int ox = 0, oy = 0;
+
+ while (x <= y) {
+/*
+ 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 (t) {
+ f->insert(x0 - ox, y0 - oy, x0 - x, y0 - y);
+ f->insert(x0 + ox, y0 - oy, x0 + x, y0 - y);
+ f->insert(x0 - ox, y0 + oy, x0 - x, y0 + y);
+ f->insert(x0 + ox, y0 + oy, x0 + x, y0 + y);
+ f->insert(x0 - oy, y0 - ox, x0 - y, y0 - x);
+ f->insert(x0 + oy, y0 - ox, x0 + y, y0 - x);
+ f->insert(x0 - oy, y0 + ox, x0 - y, y0 + x);
+ f->insert(x0 + oy, y0 + ox, x0 + y, y0 + x);
+ }
+ ox = x;
+ oy = y;
+ t = true;
+ if (d >= 0) {
+ d += dI;
+ dI += 8;
+ y -= 1;
+ } else {
+ d += rI;
+ dI += 4;
+ }
+ 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;
+}
+
+mogltk::filldrawer::filldrawer(fill * _f, texture * _t, ColorP _c) : f(_f), t(_t), c(_c), oldx(-1), oldy(-1) {
+}
+
+mogltk::filldrawer::~filldrawer() {
+}
+
+void mogltk::filldrawer::step(int x, int y) {
+ if (oldy != y) {
+ oldx = -1;
+ }
+ if (oldx == -1) {
+ oldx = x;
+ } else {
+/* s->hline(oldx, x, y, c); */
+ Uint32 * p = t->GetPixels();
+ int i,
+ first = t->GetWidth() * (y - f->GetMinY()) + oldx - f->GetMinX(),
+ last = first - oldx + x;
+ SDL_PixelFormat * format = t->GetFormat();
+
+ for (i = first; i <= last; i++) {
+ if (i > (t->GetWidth() * t->GetHeight())) {
+ printm(M_ERROR, "Big problem here. i = %i and W, H = %i, %i\n", i, t->GetWidth(), t->GetHeight());
+ printm(M_ERROR, "Initially, wanted to draw hline(%i, %i, %i)\n", oldx, x, y);
+ printm(M_ERROR, "With MinX = %i and MinY = %i --> hline(%i, %i, %i)\n", f->GetMinX(), f->GetMinY(), oldx - f->GetMinX(), x - f->GetMinX(), y - f->GetMinY());
+ printm(M_ERROR, "For info, MaxX = %i and MaxY = %i\n", f->GetMaxX(), f->GetMaxY());
+ exit(-1);
+ }
+ p[i] = c.toSDL(format);
+ }
+
+ oldx = -1;
+ }
+ oldy = y;
+}
+
+void mogltk::shape::fdraw(fill * f, ColorP c, int sx, int sy) {
+ ENTER;
+ if (!f)
+ return;
+ if (!f->GetTexture()) {
+ filldrawer * w = new filldrawer(f, f->Talloc(), c);
+ f->walk(w);
+ delete w;
+ f->last = c.c;
+ }
+ SDL_PixelFormat * format = f->GetTexture()->GetFormat();
+
+ if (f->last == c.c) {
+ Uint32 * p = f->GetTexture()->GetPixels();
+ int i, n = f->GetTexture()->GetWidth() * f->GetTexture()->GetHeight();
+ for (i = 0; i < n; i++)
+ if (p[i] & 0xff000000)
+ p[i] = c.toSDL(format);
+ }
+ SDL_Rect r;
+ r.x = f->GetMinX() + sx;
+ r.y = f->GetMinY() + sy;
+ SDL_BlitSurface(f->GetTexture()->GetSurface(), 0, surf, &r);
+
+ f->last = c.c;
+ LEAVE;
+}
+
+mogltk::segdrawer::segdrawer(fill * _f, texture * _t, ColorP _c) : f(_f), t(_t), c(_c), sh(new shape(_t->GetSurface())) {
+}
+
+mogltk::segdrawer::~segdrawer() {
+ delete sh;
+}
+
+void mogltk::segdrawer::step(int x1, int y1, int x2, int y2) {
+ sh->line(x1 - f->GetMinX(), y1 - f->GetMinY(), x2 - f->GetMinX(), y2 - f->GetMinY(), c);
+}
+
+void mogltk::shape::sdraw(fill * f, ColorP c, int sx, int sy) {
+ ENTER;
+
+ if (!f)
+ return;
+
+ if (!f->GetSTexture()) {
+ segdrawer * w = new segdrawer(f, f->STalloc(), c);
+ f->swalk(w);
+ delete w;
+ f->last = c.c;
+ }
+ SDL_PixelFormat * format = f->GetSTexture()->GetFormat();
+
+ if (f->last == c.c) {
+ Uint32 * p = f->GetSTexture()->GetPixels();
+ int i, n = f->GetSTexture()->GetWidth() * f->GetSTexture()->GetHeight();
+ for (i = 0; i < n; i++)
+ if (p[i] & 0xff000000)
+ p[i] = c.toSDL(format);
+ }
+ SDL_Rect r;
+ r.x = f->GetMinX() + sx;
+ r.y = f->GetMinY() + sy;
+ SDL_BlitSurface(f->GetSTexture()->GetSurface(), 0, surf, &r);
+
+ f->last = c.c;
+ LEAVE;
+}
+
+void mogltk::shape::obox(int x1, int y1, int x2, int y2, ColorP c) {
+ ENTER;
+
+ hline(x1, x2, y1, c);
+ hline(x1, x2, y2, c);
+ vline(x1, y1 + 1, y2 - 1, c);
+ vline(x2, y1 + 1, y2 - 1, c);
+
+ LEAVE;
+}
+
+void mogltk::shape::box3d(int x1, int y1, int x2, int y2, ColorP face, ColorP shade1, ColorP shade2, int depth, bool bevel) {
+ ENTER;
+
+ int i;
+
+ for (i = 0; i < depth; i++) {
+ hline(x1 + i, x2 - i, y1 + i, bevel ? shade2 : shade1);
+ vline(x1 + i, y1 + i, y2 - i, bevel ? shade2 : shade1);
+ }
+
+ for (i = 0; i < depth; i++) {
+ hline(x1 + i, x2 - i, y2 - i, bevel ? shade1 : shade2);
+ vline(x2 - i, y1 + i, y2 - i, bevel ? shade1 : shade2);
+ }
+
+ box(x1 + depth, y1 + depth, x2 - depth, y2 - depth, face);
+
+ LEAVE;
+}
+
+void mogltk::shape::obox3d(int x1, int y1, int x2, int y2, ColorP shade1, ColorP shade2, bool bevel) {
+ ENTER;
+
+ if (!bevel) {
+ obox(x1 + 1, y1 + 1, x2, y2, shade1);
+ obox(x1, y1, x2 - 1, y2 - 1, shade2);
+ } else {
+ obox(x1, y1, x2 - 1, y2 - 1, shade1);
+ obox(x1 + 1, y1 + 1, x2, y2, shade2);
+ }
+
+ LEAVE;
+}
+
+void mogltk::shape::window(int x1, int y1, int x2, int y2, const String & title,
+ ColorP titlecolor, ColorP titlebackcolor,
+ ColorP front, ColorP shade1, ColorP shade2) {
+ ENTER;
+
+ box3d(x1, y1, x2, y2, front, shade1, shade2);
+ hline3d(x1 + 2, x2 - 2, y1 + 19, shade1, shade2, 1);
+ box(x1 + 2, y1 + 2, x2 - 2, y1 + 18, titlebackcolor);
+ text((x1 + x2) / 2, y1 + 2, title, titlecolor, CENTER);
+
+ LEAVE;
+}
+
+void mogltk::shape::text(int x, int y, const String & text, ColorP textcolor, align_t align) {
+ int tsize = SystemFont->singletextsize(text);
+ switch (align) {
+ case LEFT:
+ SystemFont->putcursor(x, y);
+ break;
+ case CENTER:
+ SystemFont->putcursor(x - (tsize / 2), y);
+ break;
+ case RIGHT:
+ SystemFont->putcursor(x - tsize, y);
+ break;
+ }
+ SystemFont->setcolor(textcolor);
+ SystemFont->setshadow(0);
+ SystemFont->printf(text);
+}
+
+void mogltk::shape::text3d(int x, int y, const String & atext, ColorP textcolor,
+ ColorP shade1, ColorP shade2,
+ align_t align, bool bevel) {
+ ENTER;
+
+ SystemFont->setwspace(1);
+ if (!bevel) {
+ text(x - 1, y - 1, atext, shade2, align);
+ text(x + 1, y + 1, atext, shade1, align);
+ } else {
+ text(x - 1, y - 1, atext, shade1, align);
+ text(x + 1, y + 1, atext, shade2, align);
+ }
+ text(x, y, atext, textcolor, align);
+ SystemFont->setwspace(0);
+
+ LEAVE;
+}
+
+void mogltk::shape::button(int x1, int y1, int x2, int y2,
+ const String & atext, bool bevel,
+ ColorP front, ColorP shade1, ColorP shade2,
+ ColorP round, ColorP textcolor,
+ ColorP tshade1, ColorP tshade2) {
+ ENTER;
+
+ box3d(x1, y1, x2, y2, front, shade1, shade2, 2, bevel);
+ hline(x1, x2, y1 - 1, round);
+ hline(x1, x2, y2 + 1, round);
+ vline(x1 - 1, y1, y2, round);
+ vline(x2 + 1, y1, y2, round);
+ pixel(x1, y1, round);
+ pixel(x1, y2, round);
+ pixel(x2, y1, round);
+ pixel(x2, y2, round);
+ text3d((x1 + x2) / 2, (y1 + y2) / 2 - 8, atext, textcolor, tshade1, tshade2, CENTER, bevel);
+
+ LEAVE;
+}
+
+bool mogltk::shape::Enter() {
+ if (SDL_MUSTLOCK(surf)) {
+ SDL_LockSurface(surf);
+ return true;
+ } else {
+ return false;
+ }
+}
+
+void mogltk::shape::Leave(bool locked) {
+ if (locked)
+ SDL_UnlockSurface(surf);
+}
+
+void mogltk::shape::tbox(texture *, int x1, int y1, int x2, int y2, int tx, int ty, double f, ColorP c) {
+}
+
+void mogltk::shape::tbox(texture *, int x1, int y1, int x2, int y2, int tx1, int ty1, int tx2, int ty2, ColorP c) {
+}
+
+void mogltk::shape::tbox(texture *, int x1, int y1, int x2, int y2, ColorP, ColorP, ColorP, ColorP, int tx, int ty, double f) {
+}
+
+void mogltk::shape::tbox(texture *, int x1, int y1, int x2, int y2, ColorP, ColorP, ColorP, ColorP, int tx1, int ty1, int tx2, int ty2) {
+}
+
+void mogltk::shape::vline(int x, int y1, int y2, ColorP c1, ColorP c2) {
+}
+
+void mogltk::shape::hline(int x1, int x2, int y, ColorP c1, ColorP c2) {
+}
+
+void mogltk::shape::box(int x1, int y1, int x2, int y2, ColorP c1, ColorP c2, ColorP c3, ColorP c4) {
+}
+
+void mogltk::shape::obox(int x1, int y1, int x2, int y2, ColorP c1, ColorP c2, ColorP c3, ColorP c4) {
+}
|