diff options
Diffstat (limited to 'plugingui')
-rw-r--r-- | plugingui/painter.cc | 18 | ||||
-rw-r--r-- | plugingui/pixelbuffer.cc | 160 | ||||
-rw-r--r-- | plugingui/pixelbuffer.h | 16 |
3 files changed, 34 insertions, 160 deletions
diff --git a/plugingui/painter.cc b/plugingui/painter.cc index 89d7498..761fe9b 100644 --- a/plugingui/painter.cc +++ b/plugingui/painter.cc @@ -65,7 +65,8 @@ static void plot(PixelBufferAlpha& pixbuf, const Colour& colour, } // plot the pixel at (x, y) with brightness c (where 0 ≤ c ≤ 1) - pixbuf.addPixel(x, y, colour.red(), colour.green(), colour.blue(), colour.alpha() * c); + Colour col(colour.red(), colour.green(), colour.blue(), (std::uint8_t)(colour.alpha() * c)); + pixbuf.addPixel(x, y, col); } static inline double fpart(double x) @@ -202,21 +203,19 @@ void Painter::drawText(int x0, int y0, const Font& font, { for(int x = -1 * std::min(0, x0); x < renderWidth; ++x) { - unsigned char r, g, b, a; - assert(x >= 0); assert(y >= 0); assert(x < (int)textbuf->width); assert(y < (int)textbuf->height); - textbuf->pixel(x, y, &r, &g, &b, &a); + auto c = textbuf->pixel(x, y); assert(x + x0 >= 0); assert(y + y0 >= 0); assert(x + x0 < (int)pixbuf.width); assert(y + y0 < (int)pixbuf.height); - pixbuf.addPixel(x + x0, y + y0, r, g, b, a); + pixbuf.addPixel(x + x0, y + y0, c); } } } @@ -226,22 +225,21 @@ void Painter::drawText(int x0, int y0, const Font& font, { for(int x = -1 * std::min(0, x0); x < renderWidth; ++x) { - unsigned char r,g,b,a; - assert(x >= 0); assert(y >= 0); assert(x < (int)textbuf->width); assert(y < (int)textbuf->height); - textbuf->pixel(x, y, &r, &g, &b, &a); + auto c = textbuf->pixel(x, y); assert(x + x0 >= 0); assert(y + y0 >= 0); assert(x + x0 < (int)pixbuf.width); assert(y + y0 < (int)pixbuf.height); - pixbuf.addPixel(x + x0, y + y0, colour.red(), colour.green(), - colour.blue(), (int)(colour.alpha() * a) / 255); + Colour col(colour.red(), colour.green(), + colour.blue(), (int)(colour.alpha() * c.alpha()) / 255); + pixbuf.addPixel(x + x0, y + y0, col); } } } diff --git a/plugingui/pixelbuffer.cc b/plugingui/pixelbuffer.cc index 827d2fc..fd02703 100644 --- a/plugingui/pixelbuffer.cc +++ b/plugingui/pixelbuffer.cc @@ -53,36 +53,10 @@ void PixelBuffer::realloc(std::size_t width, std::size_t height) this->height = height; } -#define PX(k) ((x + y * width) * 3 + k) -void PixelBuffer::setPixel(std::size_t x, std::size_t y, const Colour& c) -{ - if(c.alpha() == 0) - { - return; - } - - if(c.alpha() < 255) - { - unsigned int a = c.alpha(); - unsigned int b = 255 - a; - - std::uint8_t* pixel = &buf[PX(0)]; - *pixel = (std::uint8_t)(((int)c.red() * a + (int)*pixel * b) / 255); - ++pixel; - *pixel = (std::uint8_t)(((int)c.green() * a + (int)*pixel * b) / 255); - ++pixel; - *pixel = (std::uint8_t)(((int)c.blue() * a + (int)*pixel * b) / 255); - } - else - { - memcpy(&buf[PX(0)], c.data(), 3); - } -} - -void PixelBuffer::writeLine(std::size_t x, std::size_t y, +void PixelBuffer::blendLine(std::size_t x, std::size_t y, const std::uint8_t* line, std::size_t len) { - std::uint8_t* target = &buf[PX(0)]; + std::uint8_t* target = buf + (x + y * width) * 3; while(len) { if(line[3] == 0xff) @@ -94,9 +68,9 @@ void PixelBuffer::writeLine(std::size_t x, std::size_t y, unsigned int a = line[3]; unsigned int b = 255 - a; - target[0] = (std::uint8_t)(((int)line[0] * a + (int)target[0] * b) / 255); - target[1] = (std::uint8_t)(((int)line[1] * a + (int)target[1] * b) / 255); - target[2] = (std::uint8_t)(((int)line[2] * a + (int)target[2] * b) / 255); + target[0] = (std::uint8_t)((line[0] * a + target[0] * b) / 255); + target[1] = (std::uint8_t)((line[1] * a + target[1] * b) / 255); + target[2] = (std::uint8_t)((line[2] * a + target[2] * b) / 255); } target += 3; line += 4; @@ -221,7 +195,7 @@ Rect PixelBuffer::updateBuffer(std::vector<PixelBufferAlpha*>& pixel_buffers) for(int y = from_y; y < to_y; y++) { - writeLine(pixel_buffer->x + from_x, + blendLine(pixel_buffer->x + from_x, pixel_buffer->y + y, pixel_buffer->getLine(from_x, y), to_x - from_x); @@ -278,35 +252,10 @@ void PixelBufferAlpha::clear() #undef PX #define PX(k) ((x + y * width) * 4 + k) -//void PixelBufferAlpha::setPixel(std::size_t x, std::size_t y, -// std::uint8_t red, -// std::uint8_t green, -// std::uint8_t blue, -// std::uint8_t alpha) -//{ -// //assert(x < width); -// //assert(y < height); -// -// std::uint8_t* pixel = &buf[PX(0)]; -// *pixel = red; -// ++pixel; -// *pixel = green; -// ++pixel; -// *pixel = blue; -// ++pixel; -// *pixel = alpha; -//} - void PixelBufferAlpha::setPixel(std::size_t x, std::size_t y, const Colour& c) { std::uint8_t* pixel = &buf[PX(0)]; - *pixel = c.red(); - ++pixel; - *pixel = c.green(); - ++pixel; - *pixel = c.blue(); - ++pixel; - *pixel = c.alpha(); + memcpy(pixel, c.data(), 4); } void PixelBufferAlpha::writeLine(std::size_t x, std::size_t y, @@ -325,45 +274,23 @@ void PixelBufferAlpha::writeLine(std::size_t x, std::size_t y, void PixelBufferAlpha::blendLine(std::size_t x, std::size_t y, const std::uint8_t* line, std::size_t len) { - auto offset = &buf[PX(0)]; if(x + y * width + len > width * height) { return; // out of bounds } - std::uint32_t* foreground = (std::uint32_t*)line; - std::uint32_t* background = (std::uint32_t*)offset; + std::uint8_t* target = &buf[PX(0)]; for(std::size_t x = 0; x < len; ++x) { - auto Rf = *foreground & 0xff; - auto Gf = (*foreground >> 8) & 0xff; - auto Bf = (*foreground >> 16) & 0xff; - auto Af = (*foreground >> 24) & 0xff; - - auto Rb = *background & 0xff; - auto Gb = (*background >> 8) & 0xff; - auto Bb = (*background >> 16) & 0xff; - auto Ab = (*background >> 24) & 0xff; - - auto R = (Rf * Af)/256 + Rb; - auto G = (Gf * Af)/256 + Gb; - auto B = (Bf * Af)/256 + Bb; - - if (R > 255) R = 255; - if (G > 255) G = 255; - if (B > 255) B = 255; - -// auto a = Ab / 255.0; -// auto b = Af / 255.0; -// b *= (1 - a); - -// (Af / 255.0 * (1 - Ab / 255.0)) * 255 - auto b = Ab * (255 - Af); - - *background = R | (G << 8) | (B << 16) | b << 24; + unsigned int a = line[3]; + unsigned int b = 255 - a; - ++foreground; - ++background; + target[0] = (std::uint8_t)((line[0] * a + target[0] * b) / 255); + target[1] = (std::uint8_t)((line[1] * a + target[1] * b) / 255); + target[2] = (std::uint8_t)((line[2] * a + target[2] * b) / 255); + target[3] = a * b / 255; + line += 4; + target += 4; } } @@ -377,75 +304,38 @@ static inline void getAlpha(std::uint8_t _a, std::uint8_t _b, b *= (1 - a); } -void PixelBufferAlpha::addPixel(std::size_t x, std::size_t y, - std::uint8_t red, - std::uint8_t green, - std::uint8_t blue, - std::uint8_t alpha) +void PixelBufferAlpha::addPixel(std::size_t x, std::size_t y, const Colour& c) { - //assert(x < width); - //assert(y < height); - - if(alpha == 0) + if(c.alpha() == 0) { return; } std::uint8_t* pixel = &buf[PX(0)]; - if(alpha < 255) + if(c.alpha() < 255) { float a, b; - getAlpha(alpha, buf[PX(3)], a, b); + getAlpha(c.alpha(), buf[PX(3)], a, b); - *pixel = (std::uint8_t)((red * a + *pixel * b) / (a + b)); + *pixel = (std::uint8_t)((c.red() * a + *pixel * b) / (a + b)); ++pixel; - *pixel = (std::uint8_t)((green * a + *pixel * b) / (a + b)); + *pixel = (std::uint8_t)((c.green() * a + *pixel * b) / (a + b)); ++pixel; - *pixel = (std::uint8_t)((blue * a + *pixel * b) / (a + b)); + *pixel = (std::uint8_t)((c.blue() * a + *pixel * b) / (a + b)); ++pixel; *pixel = (a + b) * 255; } else { - *pixel = red; - ++pixel; - *pixel = green; - ++pixel; - *pixel = blue; - ++pixel; - *pixel = alpha; + memcpy(pixel, c.data(), 4); } } -void PixelBufferAlpha::addPixel(std::size_t x, std::size_t y, const Colour& c) -{ - addPixel(x, y, c.red(), c.green(), c.blue(), c.alpha()); -} - -void PixelBufferAlpha::pixel(std::size_t x, std::size_t y, - std::uint8_t* red, - std::uint8_t* green, - std::uint8_t* blue, - std::uint8_t* alpha) const -{ - //assert(x < width); - //assert(y < height); - - std::uint8_t* pixel = &buf[PX(0)]; - *red = *pixel; - ++pixel; - *green = *pixel; - ++pixel; - *blue = *pixel; - ++pixel; - *alpha = *pixel; -} - const Colour& PixelBufferAlpha::pixel(std::size_t x, std::size_t y) const { static Colour c; - c = Colour(buf[PX(0)], buf[PX(1)], buf[PX(2)], buf[PX(3)]); + memcpy(c.data(), &buf[PX(0)], 4); return c; } diff --git a/plugingui/pixelbuffer.h b/plugingui/pixelbuffer.h index 81921e5..5078ed6 100644 --- a/plugingui/pixelbuffer.h +++ b/plugingui/pixelbuffer.h @@ -44,9 +44,7 @@ public: void realloc(std::size_t width, std::size_t height); - void setPixel(std::size_t x, std::size_t y, const Colour& c); - - void writeLine(std::size_t x, std::size_t y, + void blendLine(std::size_t x, std::size_t y, const std::uint8_t* line, std::size_t len); Rect updateBuffer(std::vector<class PixelBufferAlpha*>& pixel_buffers); @@ -74,20 +72,8 @@ public: void blendLine(std::size_t x, std::size_t y, const std::uint8_t* line, std::size_t len); - void addPixel(std::size_t x, std::size_t y, - std::uint8_t red, - std::uint8_t green, - std::uint8_t blue, - std::uint8_t alpha); - void addPixel(std::size_t x, std::size_t y, const Colour& c); - void pixel(std::size_t x, std::size_t y, - std::uint8_t* red, - std::uint8_t* green, - std::uint8_t* blue, - std::uint8_t* alpha) const; - const Colour& pixel(std::size_t x, std::size_t y) const; const std::uint8_t* getLine(std::size_t x, std::size_t y) const; |