summaryrefslogtreecommitdiff
path: root/plugingui
diff options
context:
space:
mode:
authorBent Bisballe Nyeng <deva@aasimon.org>2020-03-07 14:22:56 +0100
committerBent Bisballe Nyeng <deva@aasimon.org>2020-03-07 19:23:26 +0100
commitd9d7188ad7b22e8991a9ef685840ac0e88566b39 (patch)
tree23ac163bfb60cce4b9aefb658df5322687db1dc6 /plugingui
parentdf71bccf9c4731af9bcca79eee8d95651646bd82 (diff)
Use vector for PixelBuffer memory allocation. Use optimized render routines in some more painter algorithms. Fix capitalization of Canvas::getPixelBuffer method.
Diffstat (limited to 'plugingui')
-rw-r--r--plugingui/canvas.h4
-rw-r--r--plugingui/layout.cc26
-rw-r--r--plugingui/painter.cc35
-rw-r--r--plugingui/pixelbuffer.cc69
-rw-r--r--plugingui/pixelbuffer.h4
-rw-r--r--plugingui/widget.cc2
-rw-r--r--plugingui/widget.h2
7 files changed, 77 insertions, 65 deletions
diff --git a/plugingui/canvas.h b/plugingui/canvas.h
index 2326f0e..d6e8f99 100644
--- a/plugingui/canvas.h
+++ b/plugingui/canvas.h
@@ -31,14 +31,14 @@
namespace GUI
{
-//! Abstract class that can be used by the Paiter to draw on.
+//! Abstract class that can be used by the Painter to draw on.
class Canvas
{
public:
virtual ~Canvas() = default;
//! @returns a reference to the pixel buffer.
- virtual PixelBufferAlpha& GetPixelBuffer() = 0;
+ virtual PixelBufferAlpha& getPixelBuffer() = 0;
};
} // GUI::
diff --git a/plugingui/layout.cc b/plugingui/layout.cc
index f38bc20..61e4f77 100644
--- a/plugingui/layout.cc
+++ b/plugingui/layout.cc
@@ -33,7 +33,8 @@
namespace GUI
{
-LayoutItem::LayoutItem() : parent(nullptr)
+LayoutItem::LayoutItem()
+ : parent(nullptr)
{
}
@@ -170,7 +171,8 @@ void VBoxLayout::setHAlignment(HAlignment alignment)
//
HBoxLayout::HBoxLayout(LayoutItem* parent)
- : BoxLayout(parent), align(VAlignment::center)
+ : BoxLayout(parent)
+ , align(VAlignment::center)
{
}
@@ -242,10 +244,10 @@ void HBoxLayout::setVAlignment(VAlignment alignment)
//
GridLayout::GridLayout(LayoutItem* parent, std::size_t number_of_columns,
- std::size_t number_of_rows)
- : BoxLayout(parent)
- , number_of_columns(number_of_columns)
- , number_of_rows(number_of_rows)
+ std::size_t number_of_rows)
+ : BoxLayout(parent)
+ , number_of_columns(number_of_columns)
+ , number_of_rows(number_of_rows)
{
}
@@ -297,9 +299,11 @@ int GridLayout::lastUsedRow(int column) const
{
int last_row = -1;
- for (auto const& grid_range : grid_ranges) {
+ for (auto const& grid_range : grid_ranges)
+ {
auto const& range = grid_range.second;
- if (column >= range.column_begin && column < range.column_end) {
+ if (column >= range.column_begin && column < range.column_end)
+ {
last_row = std::max(last_row, range.row_end - 1);
}
}
@@ -311,9 +315,11 @@ int GridLayout::lastUsedColumn(int row) const
{
int last_column = -1;
- for (auto const& grid_range : grid_ranges) {
+ for (auto const& grid_range : grid_ranges)
+ {
auto const& range = grid_range.second;
- if (row >= range.row_begin && row < range.row_end) {
+ if (row >= range.row_begin && row < range.row_end)
+ {
last_column = std::max(last_column, range.column_end - 1);
}
}
diff --git a/plugingui/painter.cc b/plugingui/painter.cc
index 7f8acba..d3f28ff 100644
--- a/plugingui/painter.cc
+++ b/plugingui/painter.cc
@@ -39,7 +39,7 @@ namespace GUI
{
Painter::Painter(Canvas& canvas)
- : pixbuf(canvas.GetPixelBuffer())
+ : pixbuf(canvas.getPixelBuffer())
{
colour = Colour(0.0f, 0.0f, 0.0f, 0.5f);
}
@@ -111,11 +111,11 @@ void Painter::drawLine(int x0, int y0, int x1, int y1)
if(steep)
{
- plot(pixbuf, colour, ypxl1, xpxl1, 1);
+ pixbuf.addPixel(ypxl1, xpxl1, colour);
}
else
{
- plot(pixbuf, colour, xpxl1, ypxl1, 1);
+ pixbuf.addPixel(xpxl1, ypxl1, colour);
}
double intery = yend + gradient; // first y-intersection for the main loop
@@ -129,11 +129,11 @@ void Painter::drawLine(int x0, int y0, int x1, int y1)
if(steep)
{
- plot(pixbuf, colour, ypxl2, xpxl2, 1);
+ pixbuf.addPixel(ypxl2, xpxl2, colour);
}
else
{
- plot(pixbuf, colour, xpxl2, ypxl2, 1);
+ pixbuf.addPixel(xpxl2, ypxl2, colour);
}
// main loop
@@ -205,22 +205,21 @@ void Painter::drawText(int x0, int y0, const Font& font,
{
for(int y = -1 * std::min(0, y0); y < renderHeight; ++y)
{
- for(int x = -1 * std::min(0, x0); x < renderWidth; ++x)
- {
- assert(x >= 0);
- assert(y >= 0);
- assert(x < (int)textbuf->width);
- assert(y < (int)textbuf->height);
+ int x = -1 * std::min(0, x0);
- auto c = textbuf->pixel(x, y);
+ assert(x >= 0);
+ assert(y >= 0);
+ assert(x < (int)textbuf->width);
+ assert(y < (int)textbuf->height);
- assert(x + x0 >= 0);
- assert(y + y0 >= 0);
- assert(x + x0 < (int)pixbuf.width);
- assert(y + y0 < (int)pixbuf.height);
+ auto c = textbuf->getLine(x, y);
- pixbuf.addPixel(x + x0, y + y0, c);
- }
+ assert(x + x0 >= 0);
+ assert(y + y0 >= 0);
+ assert(x + x0 < (int)pixbuf.width);
+ assert(y + y0 < (int)pixbuf.height);
+
+ pixbuf.blendLine(x + x0, y + y0, c, renderWidth - x);
}
}
else
diff --git a/plugingui/pixelbuffer.cc b/plugingui/pixelbuffer.cc
index 918298b..c73e663 100644
--- a/plugingui/pixelbuffer.cc
+++ b/plugingui/pixelbuffer.cc
@@ -35,20 +35,18 @@ namespace GUI
{
PixelBuffer::PixelBuffer(std::size_t width, std::size_t height)
- : buf(nullptr)
{
realloc(width, height);
}
PixelBuffer::~PixelBuffer()
{
- free(buf);
}
void PixelBuffer::realloc(std::size_t width, std::size_t height)
{
- free(buf);
- buf = (std::uint8_t *)calloc(width * height, 3);
+ buf_data.resize(width * height * 3);
+ buf = buf_data.data();
this->width = width;
this->height = height;
}
@@ -61,7 +59,7 @@ void PixelBuffer::blendLine(std::size_t x, std::size_t y,
{
if(line[3] == 0xff)
{
- memcpy(target, line, 3);
+ std::memcpy(target, line, 3);
}
else
{
@@ -219,53 +217,50 @@ Rect PixelBuffer::updateBuffer(std::vector<PixelBufferAlpha*>& pixel_buffers)
return dirty_rect;
}
-
PixelBufferAlpha::PixelBufferAlpha(std::size_t width, std::size_t height)
- : managed(true)
- , buf(nullptr)
- , x(0)
- , y(0)
{
realloc(width, height);
}
PixelBufferAlpha::~PixelBufferAlpha()
{
- if(managed)
- {
- free(buf);
- }
}
void PixelBufferAlpha::realloc(std::size_t width, std::size_t height)
{
- free(buf);
- buf = (std::uint8_t *)calloc(width * height, 4);
+ buf_data.resize(width * height * 4);
+ buf = buf_data.data();
this->width = width;
this->height = height;
+ clear();
}
void PixelBufferAlpha::clear()
{
- memset(buf, 0, width * height * 4);
+ std::memset(buf, 0, width * height * 4);
}
-#undef PX
-#define PX(k) ((x + y * width) * 4 + k)
void PixelBufferAlpha::setPixel(std::size_t x, std::size_t y, const Colour& c)
{
- std::uint8_t* pixel = &buf[PX(0)];
- memcpy(pixel, c.data(), 4);
+ std::uint8_t* pixel = buf + (x + y * width) * 4;
+ std::memcpy(pixel, c.data(), 4);
}
void PixelBufferAlpha::writeLine(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)
+ if(x >= width || y >= height)
{
- return; // out of bounds
+ return;
}
+
+ if(x + len > width)
+ {
+ len = width - x;
+ }
+
+ auto offset = buf + (x + y * width) * 4;
+
std::memcpy(offset, line, len * 4);
}
@@ -276,13 +271,18 @@ 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)
{
- if(x + y * width + len > width * height)
+ if(x >= width || y >= height)
{
- return; // out of bounds
+ return;
+ }
+
+ if(x + len > width)
+ {
+ len = width - x;
}
int a, b;
- std::uint8_t* target = &buf[PX(0)];
+ std::uint8_t* target = buf + (x + y * width) * 4;
while(len)
{
if(line[3] == 0xff)
@@ -293,7 +293,7 @@ void PixelBufferAlpha::blendLine(std::size_t x, std::size_t y,
end += 4;
}
auto chunk_len = end - line;
- memcpy(target, line, chunk_len);
+ std::memcpy(target, line, chunk_len);
line += chunk_len;
target += chunk_len;
len -= chunk_len / 4;
@@ -322,6 +322,11 @@ void PixelBufferAlpha::blendLine(std::size_t x, std::size_t y,
void PixelBufferAlpha::addPixel(std::size_t x, std::size_t y, const Colour& c)
{
+ if(x >= width || y >= height)
+ {
+ return; // out of bounds
+ }
+
const std::uint8_t* colour = c.data();
if(colour[3] == 0)
@@ -330,11 +335,11 @@ void PixelBufferAlpha::addPixel(std::size_t x, std::size_t y, const Colour& c)
}
int a, b;
- std::uint8_t* target = &buf[PX(0)];
+ std::uint8_t* target = buf + (x + y * width) * 4;
if(colour[3] == 0xff)
{
- memcpy(target, colour, 4);
+ std::memcpy(target, colour, 4);
}
else
{
@@ -351,13 +356,13 @@ void PixelBufferAlpha::addPixel(std::size_t x, std::size_t y, const Colour& c)
const Colour& PixelBufferAlpha::pixel(std::size_t x, std::size_t y) const
{
static Colour c;
- memcpy(c.data(), &buf[PX(0)], 4);
+ std::memcpy(c.data(), buf + (x + y * width) * 4, 4);
return c;
}
const std::uint8_t* PixelBufferAlpha::getLine(std::size_t x, std::size_t y) const
{
- return &buf[PX(0)];
+ return buf + (x + y * width) * 4;
}
} // GUI::
diff --git a/plugingui/pixelbuffer.h b/plugingui/pixelbuffer.h
index 5078ed6..5c11d14 100644
--- a/plugingui/pixelbuffer.h
+++ b/plugingui/pixelbuffer.h
@@ -29,6 +29,7 @@
#include "colour.h"
#include <cstddef>
+#include <cstdint>
#include <vector>
#include "guievent.h"
@@ -49,6 +50,7 @@ public:
Rect updateBuffer(std::vector<class PixelBufferAlpha*>& pixel_buffers);
+ std::vector<std::uint8_t> buf_data;
std::uint8_t* buf{nullptr};
std::size_t width{0};
std::size_t height{0};
@@ -78,7 +80,7 @@ public:
const std::uint8_t* getLine(std::size_t x, std::size_t y) const;
- bool managed{false};
+ std::vector<std::uint8_t> buf_data;
std::uint8_t* buf{nullptr};
std::size_t width{0};
std::size_t height{0};
diff --git a/plugingui/widget.cc b/plugingui/widget.cc
index 5a76af9..da6b1e2 100644
--- a/plugingui/widget.cc
+++ b/plugingui/widget.cc
@@ -201,7 +201,7 @@ Point Widget::position() const
return { _x, _y };
}
-PixelBufferAlpha& Widget::GetPixelBuffer()
+PixelBufferAlpha& Widget::getPixelBuffer()
{
return pixbuf;
}
diff --git a/plugingui/widget.h b/plugingui/widget.h
index fbf3f5b..b9436b7 100644
--- a/plugingui/widget.h
+++ b/plugingui/widget.h
@@ -81,7 +81,7 @@ public:
Point position() const;
// From Canvas
- PixelBufferAlpha& GetPixelBuffer() override;
+ PixelBufferAlpha& getPixelBuffer() override;
virtual bool isFocusable() { return false; }
virtual bool catchMouse() { return false; }