summaryrefslogtreecommitdiff
path: root/plugingui/painter.cc
diff options
context:
space:
mode:
authorBent Bisballe Nyeng <deva@aasimon.org>2012-01-23 20:08:12 +0100
committerBent Bisballe Nyeng <deva@aasimon.org>2012-01-23 20:08:12 +0100
commitaf9c9091ed69394171485aa4c4814504f86f2004 (patch)
tree070b911dc8faed486c8e8829f0f41aec7d5b4350 /plugingui/painter.cc
parent5e4cb10f72ef69d73fbd2c1bc42465c9111a4c41 (diff)
Simple image blit. New slider class. New filenamelineedit. New pixelbuffer used for drawing everything but the root window - with alpha blending...
Diffstat (limited to 'plugingui/painter.cc')
-rw-r--r--plugingui/painter.cc191
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 *)&order;
+
+ 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*/
}