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; | 
