diff options
Diffstat (limited to 'plugingui/pixelbuffer.cc')
-rw-r--r-- | plugingui/pixelbuffer.cc | 160 |
1 files changed, 25 insertions, 135 deletions
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; } |