summaryrefslogtreecommitdiff
path: root/plugingui
diff options
context:
space:
mode:
authorBent Bisballe Nyeng <deva@aasimon.org>2015-11-09 21:26:57 +0100
committerBent Bisballe Nyeng <deva@aasimon.org>2015-11-09 21:26:57 +0100
commitc18090169d6bb49e877956701e77e8af338ed675 (patch)
tree7a18b46d809fc839acc56c4b0fd2e1938614513c /plugingui
parent74ab9aea168bb5706e9c36aa6252f366926f5b41 (diff)
Refactor PixelBuffer, and remove unnecessary calls to setPixel and addPixel.
Diffstat (limited to 'plugingui')
-rw-r--r--plugingui/painter.cc95
-rw-r--r--plugingui/painter.h28
-rw-r--r--plugingui/pixelbuffer.cc199
-rw-r--r--plugingui/pixelbuffer.h94
-rw-r--r--plugingui/window.cc16
5 files changed, 235 insertions, 197 deletions
diff --git a/plugingui/painter.cc b/plugingui/painter.cc
index c1ab811..38f960d 100644
--- a/plugingui/painter.cc
+++ b/plugingui/painter.cc
@@ -59,8 +59,14 @@ void Painter::setColour(const Colour& colour)
this->colour = colour;
}
-void Painter::plot(int x, int y, double c)
+static void plot(PixelBufferAlpha* pixbuf, const Colour& colour,
+ int x, int y, double c)
{
+ if((x >= (int)pixbuf->width) || (y >= (int)pixbuf->height))
+ {
+ return;
+ }
+
// plot the pixel at (x, y) with brightness c (where 0 ≤ c ≤ 1)
pixbuf->addPixel(x, y,
(unsigned char)(colour.red * 255.0),
@@ -70,12 +76,12 @@ void Painter::plot(int x, int y, double c)
}
-double Painter::fpart(double x)
+static inline double fpart(double x)
{
return x - std::floor(x);// fractional part of x
}
-double Painter::rfpart(double x)
+static inline double rfpart(double x)
{
return 1 - fpart(x); // reverse fractional part of x
}
@@ -108,11 +114,11 @@ void Painter::drawLine(int x0, int y0, int x1, int y1)
if(steep)
{
- plot(ypxl1, xpxl1, 1);
+ plot(pixbuf, colour, ypxl1, xpxl1, 1);
}
else
{
- plot(xpxl1, ypxl1, 1);
+ plot(pixbuf, colour, xpxl1, ypxl1, 1);
}
double intery = yend + gradient; // first y-intersection for the main loop
@@ -126,11 +132,11 @@ void Painter::drawLine(int x0, int y0, int x1, int y1)
if(steep)
{
- plot(ypxl2, xpxl2, 1);
+ plot(pixbuf, colour, ypxl2, xpxl2, 1);
}
else
{
- plot(xpxl2, ypxl2, 1);
+ plot(pixbuf, colour, xpxl2, ypxl2, 1);
}
// main loop
@@ -138,13 +144,13 @@ void Painter::drawLine(int x0, int y0, int x1, int y1)
{
if(steep)
{
- plot(std::floor(intery) , x, rfpart(intery));
- plot(std::floor(intery)+1, x, fpart(intery));
+ plot(pixbuf, colour, std::floor(intery) , x, rfpart(intery));
+ plot(pixbuf, colour, std::floor(intery)+1, x, fpart(intery));
}
else
{
- plot(x, std::floor(intery), rfpart(intery));
- plot(x, std::floor(intery)+1, fpart(intery));
+ plot(pixbuf, colour, x, std::floor(intery), rfpart(intery));
+ plot(pixbuf, colour, x, std::floor(intery)+1, fpart(intery));
}
intery += gradient;
}
@@ -182,27 +188,48 @@ void Painter::drawText(int x0, int y0, const Font &font,
{
PixelBufferAlpha* textbuf = font.render(text);
+ y0 -= textbuf->height; // The y0 offset (baseline) is the bottom of the text.
+
+ // If the text offset is outside the buffer; skip it.
+ if((x0 > (int)pixbuf->width) || (y0 > (int)pixbuf->height))
+ {
+ return;
+ }
+
+ // Make sure we don't try to draw outside the pixbuf.
+ int renderWidth = textbuf->width;
+ if(renderWidth > (int)(pixbuf->width - x0))
+ {
+ renderWidth = pixbuf->width - x0;
+ }
+
+ int renderHeight = textbuf->height;
+ if(renderHeight > ((int)pixbuf->height - y0))
+ {
+ renderHeight = ((int)pixbuf->height - y0);
+ }
+
if(nocolour)
{
- for(size_t x = 0; x < textbuf->width; ++x)
+ for(int y = 0; y < renderHeight; ++y)
{
- for(size_t y = 0; y < textbuf->height; ++y)
+ for(int x = 0; x < renderWidth; ++x)
{
unsigned char r, g, b, a;
textbuf->pixel(x, y, &r, &g, &b, &a);
- pixbuf->addPixel(x + x0, y + y0 - textbuf->height, r, g, b, a);
+ pixbuf->addPixel(x + x0, y + y0, r, g, b, a);
}
}
}
else
{
- for(size_t x = 0; x < textbuf->width; ++x)
+ for(int y = 0; y < renderHeight; ++y)
{
- for(size_t y = 0; y < textbuf->height; ++y)
+ for(int x = 0; x < renderWidth; ++x)
{
unsigned char r,g,b,a;
textbuf->pixel(x, y, &r, &g, &b, &a);
- pixbuf->addPixel(x + x0, y + y0 - textbuf->height,
+ pixbuf->addPixel(x + x0, y + y0,
colour.red * 255,
colour.green * 255,
colour.blue * 255,
@@ -322,6 +349,17 @@ void Painter::drawImage(int x0, int y0, const Image& image)
size_t fw = image.width();
size_t fh = image.height();
+ // Make sure we don't try to draw outside the pixbuf.
+ if(fw > (pixbuf->width - x0))
+ {
+ fw = (pixbuf->width - x0);
+ }
+
+ if(fh > (pixbuf->height - y0))
+ {
+ fh = (pixbuf->height - y0);
+ }
+
for(size_t y = 0; y < fh; ++y)
{
for(size_t x = 0; x < fw; ++x)
@@ -333,9 +371,9 @@ void Painter::drawImage(int x0, int y0, const Image& image)
}
void Painter::drawImageStretched(int x0, int y0, const Image& image,
- int w, int h)
+ int width, int height)
{
- if((w < 1) || (h < 1))
+ if((width < 1) || (height < 1))
{
return;
}
@@ -343,12 +381,23 @@ void Painter::drawImageStretched(int x0, int y0, const Image& image,
float fw = image.width();
float fh = image.height();
- for(int y = 0; y < h; ++y)
+ // Make sure we don't try to draw outside the pixbuf.
+ if(width > (int)(pixbuf->width - x0))
+ {
+ width = pixbuf->width - x0;
+ }
+
+ if(height > (int)(pixbuf->height - y0))
+ {
+ height = pixbuf->height - y0;
+ }
+
+ for(int y = 0; y < height; ++y)
{
- for(int x = 0; x < w; ++x)
+ for(int x = 0; x < width; ++x)
{
- int lx = ((float)x / (float)w) * fw;
- int ly = ((float)y / (float)h) * fh;
+ int lx = ((float)x / (float)width) * fw;
+ int ly = ((float)y / (float)height) * fh;
Colour c = image.getPixel(lx, ly);
pixbuf->addPixel(x0 + x, y0 + y, c);
}
diff --git a/plugingui/painter.h b/plugingui/painter.h
index 40747a7..009ebde 100644
--- a/plugingui/painter.h
+++ b/plugingui/painter.h
@@ -58,32 +58,28 @@ public:
int width, int height);
typedef struct {
- Image *topLeft;
- Image *top;
- Image *topRight;
- Image *left;
- Image *right;
- Image *bottomLeft;
- Image *bottom;
- Image *bottomRight;
- Image *center;
+ Image* topLeft;
+ Image* top;
+ Image* topRight;
+ Image* left;
+ Image* right;
+ Image* bottomLeft;
+ Image* bottom;
+ Image* bottomRight;
+ Image* center;
} Box;
void drawBox(int x, int y, const Box& box, int width, int height);
typedef struct {
- Image *left;
- Image *right;
- Image *center;
+ Image* left;
+ Image* right;
+ Image* center;
} Bar;
void drawBar(int x, int y, const Bar& bar, int width, int height);
void clear();
private:
- void plot(int x, int y, double c);
- double fpart(double x);
- double rfpart(double x);
-
Widget& widget;
PixelBufferAlpha* pixbuf;
Colour colour;
diff --git a/plugingui/pixelbuffer.cc b/plugingui/pixelbuffer.cc
index 2a6bf6f..962091e 100644
--- a/plugingui/pixelbuffer.cc
+++ b/plugingui/pixelbuffer.cc
@@ -26,155 +26,140 @@
*/
#include "pixelbuffer.h"
-#include <stdio.h>
+#include <cassert>
-GUI::PixelBuffer::PixelBuffer(size_t width, size_t height)
+namespace GUI {
+
+PixelBuffer::PixelBuffer(size_t width, size_t height)
+ : buf(nullptr)
{
- buf = NULL;
- realloc(width, height);
+ realloc(width, height);
}
-GUI::PixelBuffer::~PixelBuffer()
+PixelBuffer::~PixelBuffer()
{
- if(buf) free(buf);
+ free(buf);
}
-void GUI::PixelBuffer::realloc(size_t width, size_t height)
+void PixelBuffer::realloc(size_t width, size_t height)
{
- if(buf) free(buf);
- buf = (unsigned char *)calloc(width * height, 3);
- this->width = width;
- this->height = height;
+ free(buf);
+ buf = (unsigned char *)calloc(width * height, 3);
+ this->width = width;
+ this->height = height;
}
-#define PX(k) (x + y * width) * 3 + k
-void GUI::PixelBuffer::setPixel(size_t x, size_t y,
- unsigned char red,
- unsigned char green,
- unsigned char blue,
- unsigned char alpha)
+#define PX(k) ((x + y * width) * 3 + k)
+void PixelBuffer::setPixel(size_t x, size_t y,
+ unsigned char red,
+ unsigned char green,
+ unsigned char blue,
+ unsigned char alpha)
{
- if(x >= width || y >= height) return;
- /*
- float a,b;
- getAlpha(alpha, 255, a, b);
-
- buf[PX(0)] = (unsigned char)((float)red * a + (float)buf[PX(0)] * b);
- buf[PX(0)] /= (a + b);
- buf[PX(1)] = (unsigned char)((float)green * a + (float)buf[PX(1)] * b);
- buf[PX(1)] /= (a + b);
- buf[PX(2)] = (unsigned char)((float)blue * a + (float)buf[PX(2)] * b);
- buf[PX(2)] /= (a + b);
- */
- unsigned int a = alpha;
- unsigned int b = 255 - alpha;
-
- buf[PX(0)] = (unsigned char)(((int)red * a + (int)buf[PX(0)] * b) / 255);
- buf[PX(1)] = (unsigned char)(((int)green * a + (int)buf[PX(1)] * b) / 255);
- buf[PX(2)] = (unsigned char)(((int)blue * a + (int)buf[PX(2)] * b) / 255);
+ assert(x < width);
+ assert(y < height);
+
+ unsigned int a = alpha;
+ unsigned int b = 255 - alpha;
+
+ buf[PX(0)] = (unsigned char)(((int)red * a + (int)buf[PX(0)] * b) / 255);
+ buf[PX(1)] = (unsigned char)(((int)green * a + (int)buf[PX(1)] * b) / 255);
+ buf[PX(2)] = (unsigned char)(((int)blue * a + (int)buf[PX(2)] * b) / 255);
}
-static int idx = 0;
-GUI::PixelBufferAlpha::PixelBufferAlpha(size_t width, size_t height)
+PixelBufferAlpha::PixelBufferAlpha(size_t width, size_t height)
+ : buf(nullptr)
+ , x(0)
+ , y(0)
{
- this->idx = ::idx++;
- buf = NULL;
- x = y = 10;
- realloc(width, height);
+ realloc(width, height);
}
-GUI::PixelBufferAlpha::~PixelBufferAlpha()
+PixelBufferAlpha::~PixelBufferAlpha()
{
- if(buf) free(buf);
+ free(buf);
}
-void GUI::PixelBufferAlpha::realloc(size_t width, size_t height)
+void PixelBufferAlpha::realloc(size_t width, size_t height)
{
- if(buf) free(buf);
- buf = (unsigned char *)calloc(width * height, 4);
- this->width = width;
- this->height = height;
+ free(buf);
+ buf = (unsigned char *)calloc(width * height, 4);
+ this->width = width;
+ this->height = height;
}
#undef PX
-#define PX(k) (x + y * width) * 4 + k
-void GUI::PixelBufferAlpha::setPixel(size_t x, size_t y,
- unsigned char red,
- unsigned char green,
- unsigned char blue,
- unsigned char alpha)
+#define PX(k) ((x + y * width) * 4 + k)
+void PixelBufferAlpha::setPixel(size_t x, size_t y,
+ unsigned char red,
+ unsigned char green,
+ unsigned char blue,
+ unsigned char alpha)
{
- if(x >= width || y >= height) return;
+ assert(x < width);
+ assert(y < height);
- buf[PX(0)] = red;
- buf[PX(1)] = green;
- buf[PX(2)] = blue;
- buf[PX(3)] = alpha;
+ buf[PX(0)] = red;
+ buf[PX(1)] = green;
+ buf[PX(2)] = blue;
+ buf[PX(3)] = alpha;
}
// http://en.wikipedia.org/wiki/Alpha_compositing
-static void getAlpha(unsigned char _a, unsigned char _b, float &a, float &b)
+static inline void getAlpha(unsigned char _a, unsigned char _b,
+ float &a, float &b)
{
- a = _a / 255.0;
- b = _b / 255.0;
- b *= (1-a);
+ a = _a / 255.0;
+ b = _b / 255.0;
+ b *= (1 - a);
}
-void GUI::PixelBufferAlpha::addPixel(size_t x, size_t y,
- unsigned char red,
- unsigned char green,
- unsigned char blue,
- unsigned char alpha)
+void PixelBufferAlpha::addPixel(size_t x, size_t y,
+ unsigned char red,
+ unsigned char green,
+ unsigned char blue,
+ unsigned char alpha)
{
- if(x >= width || y >= height) return;
+ assert(x < width);
+ assert(y < height);
- if(alpha == 0) return;
+ if(alpha == 0)
+ {
+ return;
+ }
- float a,b;
- getAlpha(alpha, buf[PX(3)], a, b);
+ float a, b;
+ getAlpha(alpha, buf[PX(3)], a, b);
- buf[PX(0)] = (unsigned char)((float)red * a + (float)buf[PX(0)] * b);
- buf[PX(0)] /= (a + b);
- buf[PX(1)] = (unsigned char)((float)green * a + (float)buf[PX(1)] * b);
- buf[PX(1)] /= (a + b);
- buf[PX(2)] = (unsigned char)((float)blue * a + (float)buf[PX(2)] * b);
- buf[PX(2)] /= (a + b);
+ buf[PX(0)] = (unsigned char)((float)red * a + (float)buf[PX(0)] * b);
+ buf[PX(0)] /= (a + b);
+ buf[PX(1)] = (unsigned char)((float)green * a + (float)buf[PX(1)] * b);
+ buf[PX(1)] /= (a + b);
+ buf[PX(2)] = (unsigned char)((float)blue * a + (float)buf[PX(2)] * b);
+ buf[PX(2)] /= (a + b);
- buf[PX(3)] = (a + b) * 255;
+ buf[PX(3)] = (a + b) * 255;
}
-void GUI::PixelBufferAlpha::addPixel(size_t x, size_t y, GUI::Colour c)
+void PixelBufferAlpha::addPixel(size_t x, size_t y, Colour c)
{
- addPixel(x, y, c.red * 255, c.green * 255, c.blue * 255, c.alpha * 255);
+ addPixel(x, y, c.red * 255, c.green * 255, c.blue * 255, c.alpha * 255);
}
-void GUI::PixelBufferAlpha::pixel(size_t x, size_t y,
- unsigned char *red,
- unsigned char *green,
- unsigned char *blue,
- unsigned char *alpha)
+void PixelBufferAlpha::pixel(size_t x, size_t y,
+ unsigned char* red,
+ unsigned char* green,
+ unsigned char* blue,
+ unsigned char* alpha)
{
- if(x >= width || y >= height) return;
- *red = buf[PX(0)];
- *green = buf[PX(1)];
- *blue = buf[PX(2)];
- *alpha = buf[PX(3)];
-}
-
-#ifdef TEST_PIXELBUFFER
-//Additional dependency files
-//deps:
-//Required cflags (autoconf vars may be used)
-//cflags:
-//Required link options (autoconf vars may be used)
-//libs:
-#include "test.h"
-
-TEST_BEGIN;
+ assert(x < width);
+ assert(y < height);
-// TODO: Put some testcode here (see test.h for usable macros).
-
-TEST_END;
+ *red = buf[PX(0)];
+ *green = buf[PX(1)];
+ *blue = buf[PX(2)];
+ *alpha = buf[PX(3)];
+}
-#endif/*TEST_PIXELBUFFER*/
+} // GUI::
diff --git a/plugingui/pixelbuffer.h b/plugingui/pixelbuffer.h
index 2785eb1..d955c1a 100644
--- a/plugingui/pixelbuffer.h
+++ b/plugingui/pixelbuffer.h
@@ -24,68 +24,64 @@
* along with DrumGizmo; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-#ifndef __DRUMGIZMO_PIXELBUFFER_H__
-#define __DRUMGIZMO_PIXELBUFFER_H__
-
-#include <stdlib.h>
+#pragma once
#include "colour.h"
+#include <stdlib.h>
+
namespace GUI {
class PixelBuffer {
public:
- PixelBuffer(size_t width, size_t height);
- ~PixelBuffer();
+ PixelBuffer(size_t width, size_t height);
+ ~PixelBuffer();
- void realloc(size_t width, size_t height);
+ void realloc(size_t width, size_t height);
- void setPixel(size_t x, size_t y,
- unsigned char red,
- unsigned char green,
- unsigned char blue,
- unsigned char alpha);
+ void setPixel(size_t x, size_t y,
+ unsigned char red,
+ unsigned char green,
+ unsigned char blue,
+ unsigned char alpha);
- unsigned char *buf;
- size_t width;
- size_t height;
+ unsigned char* buf;
+ size_t width;
+ size_t height;
};
class PixelBufferAlpha {
public:
- PixelBufferAlpha(size_t width, size_t height);
- ~PixelBufferAlpha();
-
- int idx;
- size_t x, y;
-
- void realloc(size_t width, size_t height);
-
- void setPixel(size_t x, size_t y,
- unsigned char red,
- unsigned char green,
- unsigned char blue,
- unsigned char alpha);
-
- void addPixel(size_t x, size_t y,
- unsigned char red,
- unsigned char green,
- unsigned char blue,
- unsigned char alpha);
-
- void addPixel(size_t x, size_t y, Colour c);
-
- void pixel(size_t x, size_t y,
- unsigned char *red,
- unsigned char *green,
- unsigned char *blue,
- unsigned char *alpha);
-
- unsigned char *buf;
- size_t width;
- size_t height;
-};
-
+ PixelBufferAlpha(size_t width, size_t height);
+ ~PixelBufferAlpha();
+
+ void realloc(size_t width, size_t height);
+
+ void setPixel(size_t x, size_t y,
+ unsigned char red,
+ unsigned char green,
+ unsigned char blue,
+ unsigned char alpha);
+
+ void addPixel(size_t x, size_t y,
+ unsigned char red,
+ unsigned char green,
+ unsigned char blue,
+ unsigned char alpha);
+
+ void addPixel(size_t x, size_t y, Colour c);
+
+ void pixel(size_t x, size_t y,
+ unsigned char* red,
+ unsigned char* green,
+ unsigned char* blue,
+ unsigned char* alpha);
+
+ unsigned char* buf;
+ size_t width;
+ size_t height;
+ size_t x;
+ size_t y;
};
-#endif/*__DRUMGIZMO_PIXELBUFFER_H__*/
+} // GUI::
diff --git a/plugingui/window.cc b/plugingui/window.cc
index afbcb21..a7e220e 100644
--- a/plugingui/window.cc
+++ b/plugingui/window.cc
@@ -178,8 +178,20 @@ void GUI::Window::updateBuffer()
std::vector<PixelBufferAlpha *>::iterator pli = pl.begin();
while(pli != pl.end()) {
PixelBufferAlpha *pb = *pli;
- for(size_t x = 0; x < pb->width; x++) {
- for(size_t y = 0; y < pb->height; y++) {
+ size_t updateWidth = pb->width;
+ size_t updateHeight = pb->height;
+ if(updateWidth > (wpixbuf.width - pb->x))
+ {
+ updateWidth = (wpixbuf.width - pb->x);
+ }
+
+ if(updateHeight > (wpixbuf.height - pb->y))
+ {
+ updateHeight = (wpixbuf.height - pb->y);
+ }
+
+ for(size_t x = 0; x < updateWidth; x++) {
+ for(size_t y = 0; y < updateHeight; y++) {
unsigned char r,g,b,a;
pb->pixel(x,y,&r,&g,&b,&a);
wpixbuf.setPixel(x + pb->x, y + pb->y, r, g, b, a);