From 3e747d769f63fde60f6095bd1ae7c651d4237f39 Mon Sep 17 00:00:00 2001 From: Bent Bisballe Nyeng Date: Sat, 4 Jun 2016 18:36:00 +0200 Subject: Make Colour movabl;e and make Image contain a vector of Colour instead of raw char data. --- plugingui/colour.cc | 70 ++++++++++++++++++++++++++++++++++++++----- plugingui/colour.h | 22 ++++++++------ plugingui/font.cc | 14 ++++----- plugingui/font.h | 2 +- plugingui/image.cc | 78 +++++++++++++++++++++++++++--------------------- plugingui/image.h | 6 ++-- plugingui/painter.cc | 30 +++++++++---------- plugingui/pixelbuffer.cc | 5 ++-- plugingui/pixelbuffer.h | 2 +- 9 files changed, 151 insertions(+), 78 deletions(-) (limited to 'plugingui') diff --git a/plugingui/colour.cc b/plugingui/colour.cc index 88bd75a..d8cd8e9 100644 --- a/plugingui/colour.cc +++ b/plugingui/colour.cc @@ -26,25 +26,81 @@ */ #include "colour.h" +#include + namespace GUI { Colour::Colour() { - red = blue = green = alpha = 1.0; + data = new float[4]; + data[0] = data[1] = data[2] = data[3] = 1.0f; } Colour::Colour(float grey, float a) { - red = green = blue = grey; - alpha = a; + data = new float[4]; + + data[0] = data[1] = data[2] = grey; + data[3] = a; } Colour::Colour(float r, float g, float b, float a) { - red = r; - green = g; - blue = b; - alpha = a; + data = new float[4]; + + data[0] = r; + data[1] = g; + data[2] = b; + data[3] = a; +} + +Colour::Colour(Colour&& other) +{ + if(data) + { + delete[] data; + } + + data = other.data; + other.data = nullptr; +} + +Colour::Colour(const Colour& other) +{ + if(data) + { + delete[] data; + } + + data = new float[4]; + + std::memcpy(data, other.data, 4 * sizeof(float)); +} + +Colour::~Colour() +{ + if(data) + { + delete[] data; + } +} + +Colour& Colour::operator=(const Colour& other) +{ + std::memcpy(data, other.data, 4 * sizeof(float)); + return *this; +} + +Colour& Colour::operator=(Colour&& other) +{ + if(data) + { + delete[] data; + } + + data = other.data; + other.data = nullptr; + return *this; } } // GUI:: diff --git a/plugingui/colour.h b/plugingui/colour.h index a02a6b0..0e85bc6 100644 --- a/plugingui/colour.h +++ b/plugingui/colour.h @@ -31,18 +31,22 @@ namespace GUI { class Colour { public: Colour(); + Colour(float grey, float alpha = 1.0f); + Colour(float red, float green, float blue, float alpha = 1.0f); + Colour(Colour&& other); + Colour(const Colour& other); + ~Colour(); - Colour(float grey, float alpha = 1.0); + Colour& operator=(const Colour& other); + Colour& operator=(Colour&& other); - Colour(float red, - float green, - float blue, - float alpha = 1.0); + inline float red() const { return data[0]; } + inline float green() const { return data[1]; } + inline float blue() const { return data[2]; } + inline float alpha() const { return data[3]; } - float red; - float green; - float blue; - float alpha; +private: + float *data{nullptr}; }; } // GUI:: diff --git a/plugingui/font.cc b/plugingui/font.cc index 4671f86..3be7dd5 100644 --- a/plugingui/font.cc +++ b/plugingui/font.cc @@ -34,7 +34,7 @@ Font::Font(const std::string& fontfile) size_t px = 0; size_t c; - for(c = 0; c < characters.size() && px < img_font.width(); ++c) + for(c = 0; c < (characters.size() - 1) && px < img_font.width(); ++c) { auto& character = characters[c]; character.offset = px + 1; @@ -47,14 +47,13 @@ Font::Font(const std::string& fontfile) ++px; - Colour pixel; while(px < img_font.width()) { - pixel = img_font.getPixel(px, 0); + auto& pixel = img_font.getPixel(px, 0); // Find next purple pixel in top row: - if((pixel.red == 1) && (pixel.green == 0) && - (pixel.blue == 1) && (pixel.alpha == 1)) + if((pixel.red() == 1.0f) && (pixel.green() == 0.0f) && + (pixel.blue() == 1.0f) && (pixel.alpha() == 1.0f)) { break; } @@ -111,9 +110,10 @@ PixelBufferAlpha *Font::render(const std::string& text) const { for(size_t y = 0; y < img_font.height(); ++y) { - Colour c = img_font.getPixel(x + character.offset, y); + auto& c = img_font.getPixel(x + character.offset, y); pb->setPixel(x + x_offset + character.pre_bias, y, - c.red * 255, c.green * 255, c.blue * 255, c.alpha * 255); + c.red() * 255, c.green() * 255, + c.blue() * 255, c.alpha() * 255); } } x_offset += character.width + spacing + character.post_bias; diff --git a/plugingui/font.h b/plugingui/font.h index 4e4c7ba..e18f1bd 100644 --- a/plugingui/font.h +++ b/plugingui/font.h @@ -57,7 +57,7 @@ private: int post_bias{0}; }; - std::array characters; + std::array characters; int spacing{1}; }; diff --git a/plugingui/image.cc b/plugingui/image.cc index 63f708d..a85f752 100644 --- a/plugingui/image.cc +++ b/plugingui/image.cc @@ -29,13 +29,15 @@ #include #include #include +#include #include #include "resource.h" #include "lodepng/lodepng.h" -namespace GUI { +namespace GUI +{ Image::Image(const char* data, size_t size) { @@ -51,32 +53,23 @@ Image::Image(const std::string& filename) Image::Image(Image&& other) : _width(other._width) , _height(other._height) - , image_data(other.image_data) + , image_data(std::move(other.image_data)) { - other.image_data = nullptr; other._width = 0; other._height = 0; } Image::~Image() { - if(image_data) - { - std::free(image_data); - } } Image& Image::operator=(Image&& other) { - if(image_data) - { - std::free(image_data); - } - image_data = other.image_data; + image_data.clear(); + image_data = std::move(other.image_data); _width = other._width; _height = other._height; - other.image_data = nullptr; other._width = 0; other._height = 0; @@ -87,34 +80,60 @@ void Image::setError() { Resource rc(":png_error"); - const unsigned char* p = (const unsigned char*)rc.data(); + const unsigned char* ptr = (const unsigned char*)rc.data(); std::uint32_t iw, ih; - std::memcpy(&iw, p, sizeof(uint32_t)); - p += sizeof(uint32_t); + std::memcpy(&iw, ptr, sizeof(uint32_t)); + ptr += sizeof(uint32_t); - std::memcpy(&ih, p, sizeof(uint32_t)); - p += sizeof(uint32_t); + std::memcpy(&ih, ptr, sizeof(uint32_t)); + ptr += sizeof(uint32_t); _width = iw; _height = ih; - size_t image_size = rc.size() - (sizeof(iw) + sizeof(ih)); - image_data = (unsigned char*)std::malloc(image_size); - memcpy(image_data, p, image_size); + image_data.clear(); + image_data.reserve(_width * _height); + for(std::size_t y = 0; y < _height; ++y) + { + for(std::size_t x = 0; x < _width; ++x) + { + image_data.emplace_back(Colour{ptr[0] / 255.0f, ptr[1] / 255.0f, + ptr[2] / 255.0f, ptr[3] / 255.0f}); + } + } + + assert(image_data.size() == (_width * _height)); } void Image::load(const char* data, size_t size) { unsigned int iw, ih; - unsigned int res = lodepng_decode32((unsigned char**)&image_data, + unsigned char* char_image_data{nullptr}; + unsigned int res = lodepng_decode32((unsigned char**)&char_image_data, &iw, &ih, (const unsigned char*)data, size); _width = iw; _height = ih; + image_data.clear(); + image_data.reserve(_width * _height); + for(std::size_t y = 0; y < _height; ++y) + { + for(std::size_t x = 0; x < _width; ++x) + { + unsigned char* ptr = &char_image_data[(x + y * _width) * 4]; + image_data.emplace_back(Colour{ptr[0] / 255.0f, ptr[1] / 255.0f, + ptr[2] / 255.0f, ptr[3] / 255.0f}); + } + } + + assert(image_data.size() == (_width * _height)); + + std::free(char_image_data); + if(res != 0) { ERR(image, "Error in lodepng_decode32: %d", res); @@ -133,23 +152,14 @@ size_t Image::height() const return _height; } -Colour Image::getPixel(size_t x, size_t y) const +const Colour& Image::getPixel(size_t x, size_t y) const { if(x > _width || y > _height) { - return Colour(0,0,0,0); + return out_of_range; } - unsigned char* ptr = &image_data[(x + y * width()) * 4]; - - float r = ptr[0]; - float g = ptr[1]; - float b = ptr[2]; - float a = ptr[3]; - - Colour c(r / 255.0, g / 255.0, b / 255.0, a / 255.0); - - return c; + return image_data[x + y * _width]; } } // GUI:: diff --git a/plugingui/image.h b/plugingui/image.h index 8d1fd59..4f591aa 100644 --- a/plugingui/image.h +++ b/plugingui/image.h @@ -27,6 +27,7 @@ #pragma once #include +#include #include "colour.h" #include "resource.h" @@ -46,7 +47,7 @@ public: size_t width() const; size_t height() const; - Colour getPixel(size_t x, size_t y) const; + const Colour& getPixel(size_t x, size_t y) const; private: void setError(); @@ -55,7 +56,8 @@ private: std::size_t _width{0}; std::size_t _height{0}; - unsigned char* image_data{nullptr}; + std::vector image_data; + Colour out_of_range{0.0f, 0.0f, 0.0f, 0.0f}; }; } // GUI:: diff --git a/plugingui/painter.cc b/plugingui/painter.cc index 2128c4e..71e4b33 100644 --- a/plugingui/painter.cc +++ b/plugingui/painter.cc @@ -41,7 +41,7 @@ Painter::Painter(Widget& widget) } pixbuf = &widget.pixbuf; - colour = Colour(0, 0, 0, 0.5); + colour = Colour(0.0f, 0.0f, 0.0f, 0.5f); } Painter::~Painter() @@ -69,10 +69,10 @@ 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, - (unsigned char)(colour.red * 255.0), - (unsigned char)(colour.green * 255.0), - (unsigned char)(colour.blue * 255.0), - (unsigned char)(colour.alpha * 255 * c)); + (unsigned char)(colour.red() * 255.0), + (unsigned char)(colour.green() * 255.0), + (unsigned char)(colour.blue() * 255.0), + (unsigned char)(colour.alpha() * 255 * c)); } @@ -231,10 +231,10 @@ void Painter::drawText(int x0, int y0, const Font& font, unsigned char r,g,b,a; textbuf->pixel(x, y, &r, &g, &b, &a); pixbuf->addPixel(x + x0, y + y0, - colour.red * 255, - colour.green * 255, - colour.blue * 255, - colour.alpha * a); + colour.red() * 255, + colour.green() * 255, + colour.blue() * 255, + colour.alpha() * a); } } } @@ -245,10 +245,10 @@ void Painter::drawText(int x0, int y0, const Font& font, void Painter::drawPoint(int x, int y) { 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)); + (unsigned char)(colour.red() * 255.0), + (unsigned char)(colour.green() * 255.0), + (unsigned char)(colour.blue() * 255.0), + (unsigned char)(colour.alpha() * 255.0)); } static void plot4points(Painter *p, int cx, int cy, int x, int y) @@ -365,7 +365,7 @@ void Painter::drawImage(int x0, int y0, const Image& image) { for(size_t x = 0; x < fw; ++x) { - Colour c = image.getPixel(x, y); + auto& c = image.getPixel(x, y); pixbuf->addPixel(x0 + x, y0 + y, c); } } @@ -399,7 +399,7 @@ void Painter::drawImageStretched(int x0, int y0, const Image& image, { int lx = ((float)x / (float)width) * fw; int ly = ((float)y / (float)height) * fh; - Colour c = image.getPixel(lx, ly); + auto& c = image.getPixel(lx, ly); pixbuf->addPixel(x0 + x, y0 + y, c); } } diff --git a/plugingui/pixelbuffer.cc b/plugingui/pixelbuffer.cc index f2fdf62..906e4d6 100644 --- a/plugingui/pixelbuffer.cc +++ b/plugingui/pixelbuffer.cc @@ -142,9 +142,10 @@ void PixelBufferAlpha::addPixel(size_t x, size_t y, buf[PX(3)] = (a + b) * 255; } -void PixelBufferAlpha::addPixel(size_t x, size_t y, Colour c) +void PixelBufferAlpha::addPixel(size_t x, size_t y, const 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 PixelBufferAlpha::pixel(size_t x, size_t y, diff --git a/plugingui/pixelbuffer.h b/plugingui/pixelbuffer.h index f07f9a8..8e7618d 100644 --- a/plugingui/pixelbuffer.h +++ b/plugingui/pixelbuffer.h @@ -69,7 +69,7 @@ public: unsigned char blue, unsigned char alpha); - void addPixel(size_t x, size_t y, Colour c); + void addPixel(size_t x, size_t y, const Colour& c); void pixel(size_t x, size_t y, unsigned char* red, -- cgit v1.2.3