diff options
Diffstat (limited to 'plugingui/painter.cc')
-rw-r--r-- | plugingui/painter.cc | 191 |
1 files changed, 139 insertions, 52 deletions
diff --git a/plugingui/painter.cc b/plugingui/painter.cc index e207811..025363c 100644 --- a/plugingui/painter.cc +++ b/plugingui/painter.cc @@ -26,97 +26,184 @@ */ #include "painter.h" -#include "globalcontext.h" -#include "widgetcontext.h" +#include "window.h" -Painter::Painter(GlobalContext *gctx, WidgetContext *wctx) +#include <string.h> + +GUI::Painter::Painter(GUI::Widget *widget) { - this->gctx = gctx; - this->wctx = wctx; + this->widget = widget; + widget->window()->beginPaint(); + pixbuf = &widget->pixbuf; + colour = Colour(0, 0, 0, 0.5); } -Painter::~Painter() +GUI::Painter::~Painter() { + widget->window()->endPaint(); flush(); } -void Painter::setColour(Colour colour) +void GUI::Painter::setColour(Colour colour) { this->colour = colour; -#ifdef X11 - // Tell the GC we draw using the white color - XSetForeground(gctx->display, wctx->gc, colour.getColour(gctx)); -#endif/*X11*/ } -void Painter::drawLine(int x1, int y1, int x2, int y2) +void GUI::Painter::drawLine(int x0, int y0, int x1, int y1) { -#ifdef X11 - XDrawLine(gctx->display, wctx->window, wctx->gc, x1, y1, x2, y2); -#endif/*X11*/ + int dx = abs(x1 - x0); + int dy = abs(y1 - y0); + + int sx; + if(x0 < x1) sx = 1; + else sx = -1; + + int sy; + if(y0 < y1) sy = 1; + else sy = -1; + + int err = dx-dy; + + while(true) { + drawPoint(x0, y0); + if(x0 == x1 && y0 == y1) break; + int e2 = 2 * err; + if(e2 > -dy) { + err -= dy; + x0 += sx; + } + if(e2 < dx) { + err += dx; + y0 += sy; + } + } } -void Painter::drawRectangle(int x1, int y1, int x2, int y2) +void GUI::Painter::drawRectangle(int x1, int y1, int x2, int y2) { -#ifdef X11 - XDrawRectangle(gctx->display, wctx->window, wctx->gc, x1, y1, x2, y2); -#endif/*X11*/ + drawLine(x1, y1, x2, y1); + drawLine(x2, y1, x2, y2); + drawLine(x1, y2, x2, y2); + drawLine(x1, y1, x1, y2); } -void Painter::drawFilledRectangle(int x1, int y1, int x2, int y2) +void GUI::Painter::drawFilledRectangle(int x1, int y1, int x2, int y2) { -#ifdef X11 - for(int i = x1; i < x2; i++) { - for(int j = y1; j < y2; j++) { - XDrawPoint(gctx->display, wctx->window, wctx->gc, i, j); + for(int x = x1; x < x2; x++) { + for(int y = y1; y < y2; y++) { + drawPoint(x, y); } } -#endif/*X11*/ } -void Painter::drawText(int x, int y, std::string text) +void GUI::Painter::drawText(int x0, int y0, GUI::Font &font, std::string text) { -#ifdef X11 - XTextItem item; - item.chars = (char*)text.data(); - item.nchars = text.length(); - item.delta = 0; - item.font = None; + PixelBufferAlpha *textbuf = font.render(widget->window()->gctx, text); - XDrawText(gctx->display, wctx->window, wctx->gc, x, y, &item, 1); -#endif/*X11*/ + for(size_t x = 0; x < textbuf->width; x++) { + for(size_t y = 0; y < textbuf->height; y++) { + unsigned char r,g,b,a; + textbuf->pixel(x, y, &r, &g, &b, &a); + if(a) drawPoint(x + x0, y + y0 - textbuf->height); + } + } + + delete textbuf; + } -void Painter::drawPoint(int x, int y) +#include <stdio.h> +void GUI::Painter::drawPoint(int x, int y) { -#ifdef X11 - XDrawPoint(gctx->display, wctx->window, wctx->gc, x, y); -#endif/*X11*/ + // printf("Painter::drawPoint: green %f\n", colour.green); fflush(stdout); + pixbuf->setPixel(x, y, + (unsigned char)(colour.red * 255.0), + (unsigned char)(colour.green * 255.0), + (unsigned char)(colour.blue * 255.0), + (unsigned char)(colour.alpha * 255.0)); } -void Painter::drawCircle(int x, int y, int r) +static void plot4points(GUI::Painter *p, int cx, int cy, int x, int y) { -#ifdef X11 - XDrawArc(gctx->display, wctx->window, wctx->gc, x, y, r, r, 0, 360 * 64); -#endif/*X11*/ + p->drawPoint(cx + x, cy + y); + if(x != 0) p->drawPoint(cx - x, cy + y); + if(y != 0) p->drawPoint(cx + x, cy - y); + if(x != 0 && y != 0) p->drawPoint(cx - x, cy - y); } -void Painter::drawFilledCircle(int x, int y, int r) +void GUI::Painter::drawCircle(int cx, int cy, int radius) { -#ifdef X11 - r *= 2; - for(int s = 1; s < r; s++) - XDrawArc(gctx->display, wctx->window, wctx->gc, - x - s / 2, y - s / 2, s, s, - 0, 360 * 64); -#endif/*X11*/ + int error = -radius; + int x = radius; + int y = 0; + + while(x >= y) { + plot4points(this, cx, cy, x, y); + if(x != y) plot4points(this, cx, cy, y, x); + + error += y; + ++y; + error += y; + + if(error >= 0) { + --x; + error -= x; + error -= x; + } + } +} + +static void plot4lines(GUI::Painter *p, int cx, int cy, int x, int y) +{ + p->drawLine(cx + x, cy + y, cx - x, cy + y); + if(x != 0) p->drawLine(cx - x, cy + y, cx + x, cy + y); + if(y != 0) p->drawLine(cx + x, cy - y, cx - x, cy - y); + if(x != 0 && y != 0) p->drawLine(cx - x, cy - y, cx + x, cy - y); +} + +void GUI::Painter::drawFilledCircle(int cx, int cy, int radius) +{ + int error = -radius; + int x = radius; + int y = 0; + + while(x >= y) { + plot4lines(this, cx, cy, x, y); + if(x != y) plot4lines(this, cx, cy, y, x); + + error += y; + ++y; + error += y; + + if(error >= 0) { + --x; + error -= x; + error -= x; + } + } +} + +void GUI::Painter::drawImage(int x0, int y0, struct __img__ * img) +{ + size_t fw = img->width; + + for(size_t x = 0; x < fw; x++) { + for(size_t y = 0; y < img->height; y++) { + unsigned int pixel = img->pixels[x + y * fw]; + unsigned int order = img->order; + unsigned char *c = (unsigned char *)&pixel; + unsigned char *o = (unsigned char *)ℴ + + pixbuf->setPixel(x0 + x, y0 + y, c[o[1]], c[o[2]], c[o[3]], c[o[0]]); + } + } } -void Painter::flush() +void GUI::Painter::flush() { #ifdef X11 // Send the "DrawLine" request to the server - XFlush(gctx->display); + //XFlush(gctx->display); #endif/*X11*/ } |