//====================================================================== // Copyright (C) 2002 Daniel Heck // // 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. //====================================================================== #include "drawable.hh" #include "video.hh" using namespace px; using namespace std; //---------------------------------------------------------------------- // Drawable implementation //---------------------------------------------------------------------- void Drawable::set_pixels(int n, const int* x, const int* y, Uint32 color) { const int *xp = x, *yp = y; for (int i=n; i; --i) set_pixel(*xp++, *yp++, color); } void Drawable::hline(int x, int y, int w, Uint32 color) { for (int i=w; i; --i) set_pixel(x++, y, color); } void Drawable::vline(int x, int y, int h, Uint32 color) { for (int i=h; i; --i) set_pixel(x, y++, color); } void Drawable::box(int x, int y, int w, int h, Uint32 color) { for (int i=h; i; --i) hline(x, y--, w, color); } void Drawable::line(int x1, int y1, int x2, int y2, Uint32 color) { } //---------------------------------------------------------------------- // GC implementation //---------------------------------------------------------------------- GC::GC(Drawable* d) : drawable(d), cliprect(d->size()), color(0) { xoff = yoff = 0; } GC::GC(Surface *s) : drawable(s->get_drawable()), cliprect(s->size()), color(0) { xoff = yoff = 0; } void GC::hline(int x, int y, int w) { x += xoff; y += yoff; if (y < cliprect.y || y >= cliprect.y + cliprect.h) return; int d = x - cliprect.x; if (d < 0) { w += d; x = cliprect.x; } d = cliprect.x+cliprect.w - (x+w); if (d < 0) w += d; drawable->hline(x, y, w, color); } void GC::vline(int x, int y, int h) { x += xoff; y += yoff; if (x < cliprect.x || x >= cliprect.x + cliprect.w) return; int d = y - cliprect.y; if (d < 0) { h += d; y = cliprect.y; } d = cliprect.y+cliprect.h - (y+h); if (d < 0) h += d; drawable->vline(x, y, h, color); } void GC::line(int x1, int y1, int x2, int y2) { x1+=xoff; x2+=xoff; y1+=yoff; y2+=yoff; if (x1 == x2) vline(x1, y1, y2-y1+1); else if (y1 == y2) hline(x1, y1, x1-x1+1); else { // TODO: Clip line drawable->line(x1, y1, x2, y2, color); } } void GC::blit(int x, int y, Surface* s, const Rect &r) const { x += xoff; y += yoff; Rect cr = cliprect; cr.x += r.x-x; cr.y += r.y-y; Rect rr = intersect(r, cr); if (rr.w > 0 && rr.h > 0) { drawable->blit(x+rr.x-r.x, y+rr.y-r.y, s, rr); } } void GC::blit(int x, int y, Surface* s) const { blit(x,y,s,Rect(0, 0, s->width(), s->height())); } void GC::box(const Rect& r) { Rect rr(r.x + xoff, r.y + yoff, r.w, r.h); rr.intersect(cliprect); drawable->box(rr.x, rr.y, rr.w, rr.h, color); } void px::frame(GC & gc, int x, int y, int w, int h) { hline(gc, x, y, w); hline(gc, x, y+h-1, w); vline(gc, x, y, h); vline(gc, x+w-1, y, h); }