diff options
| author | Bent Bisballe Nyeng <deva@aasimon.org> | 2020-03-07 14:22:56 +0100 | 
|---|---|---|
| committer | Bent Bisballe Nyeng <deva@aasimon.org> | 2020-03-07 19:23:26 +0100 | 
| commit | d9d7188ad7b22e8991a9ef685840ac0e88566b39 (patch) | |
| tree | 23ac163bfb60cce4b9aefb658df5322687db1dc6 /plugingui | |
| parent | df71bccf9c4731af9bcca79eee8d95651646bd82 (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.h | 4 | ||||
| -rw-r--r-- | plugingui/layout.cc | 26 | ||||
| -rw-r--r-- | plugingui/painter.cc | 35 | ||||
| -rw-r--r-- | plugingui/pixelbuffer.cc | 69 | ||||
| -rw-r--r-- | plugingui/pixelbuffer.h | 4 | ||||
| -rw-r--r-- | plugingui/widget.cc | 2 | ||||
| -rw-r--r-- | plugingui/widget.h | 2 | 
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; } | 
