diff options
| author | Bent Bisballe Nyeng <deva@aasimon.org> | 2020-12-29 16:09:43 +0100 | 
|---|---|---|
| committer | Bent Bisballe Nyeng <deva@aasimon.org> | 2020-12-29 16:39:54 +0100 | 
| commit | 645250e1cd8ce9bc1faea599df7a1b05836bfeb8 (patch) | |
| tree | c6311afab3900d2dd2aecbfbe1ac348d0e48c428 /plugingui/painter.cc | |
| parent | dce64999d3325c5b55499d6ba657066efa48fbff (diff) | |
Split UI code into application/plugin UI and UI library.
Diffstat (limited to 'plugingui/painter.cc')
| -rw-r--r-- | plugingui/painter.cc | 644 | 
1 files changed, 0 insertions, 644 deletions
| diff --git a/plugingui/painter.cc b/plugingui/painter.cc deleted file mode 100644 index f746f83..0000000 --- a/plugingui/painter.cc +++ /dev/null @@ -1,644 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/*************************************************************************** - *            painter.cc - * - *  Wed Oct 12 19:48:45 CEST 2011 - *  Copyright 2011 Bent Bisballe Nyeng - *  deva@aasimon.org - ****************************************************************************/ - -/* - *  This file is part of DrumGizmo. - * - *  DrumGizmo is free software; you can redistribute it and/or modify - *  it under the terms of the GNU Lesser General Public License as published by - *  the Free Software Foundation; either version 3 of the License, or - *  (at your option) any later version. - * - *  DrumGizmo is distributed in the hope that it will be useful, - *  but WITHOUT ANY WARRANTY; without even the implied warranty of - *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - *  GNU Lesser General Public License for more details. - * - *  You should have received a copy of the GNU Lesser General Public License - *  along with DrumGizmo; if not, write to the Free Software - *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA. - */ -#include "painter.h" - -#include <cmath> -#include <cassert> - -#include "pixelbuffer.h" -#include "font.h" -#include "drawable.h" -#include "image.h" -#include "canvas.h" - -namespace GUI -{ - -Painter::Painter(Canvas& canvas) -	: pixbuf(canvas.getPixelBuffer()) -{ -	colour = Colour(0.0f, 0.0f, 0.0f, 0.5f); -} - -Painter::~Painter() -{ -} - -void Painter::setColour(const Colour& colour) -{ -	this->colour = colour; -} - -static void plot(PixelBufferAlpha& pixbuf, const Colour& colour, -                 int x, int y, double c) -{ -	if((x >= (int)pixbuf.width) || -	   (y >= (int)pixbuf.height) || -	   (x < 0) || -	   (y < 0)) -	{ -		return; -	} - -	// plot the pixel at (x, y) with brightness c (where 0 ≤ c ≤ 1) -	Colour col(colour); -	if(c != 1) -	{ -		col.data()[3] *= c; -	} -	pixbuf.addPixel(x, y, col); -} - -static inline double fpart(double x) -{ -	return x - std::floor(x);// fractional part of x -} - -static inline double rfpart(double x) -{ -	return 1 - fpart(x); // reverse fractional part of x -} - -void Painter::drawLine(int x0, int y0, int x1, int y1) -{ -	bool steep = abs(y1 - y0) > abs(x1 - x0); - -	if(steep) -	{ -		std::swap(x0, y0); -		std::swap(x1, y1); -	} -	if(x0 > x1) -	{ -		std::swap(x0, x1); -		std::swap(y0, y1); -	} - -	double dx = x1 - x0; -	double dy = y1 - y0; -	double gradient = dy / dx; - -	// Handle first endpoint: -	double xend = std::round(x0); -	double yend = y0 + gradient * (xend - x0); - -	double xpxl1 = xend;   // this will be used in the main loop -	double ypxl1 = std::floor(yend); - -	if(steep) -	{ -		pixbuf.addPixel(ypxl1, xpxl1, colour); -	} -	else -	{ -		pixbuf.addPixel(xpxl1, ypxl1, colour); -	} - -	double intery = yend + gradient; // first y-intersection for the main loop - -	// Handle second endpoint: -	xend = std::round(x1); -	yend = y1 + gradient * (xend - x1); - -	double xpxl2 = xend; // this will be used in the main loop -	double ypxl2 = std::floor(yend); - -	if(steep) -	{ -		pixbuf.addPixel(ypxl2, xpxl2, colour); -	} -	else -	{ -		pixbuf.addPixel(xpxl2, ypxl2, colour); -	} - -	// main loop -	for(int x = xpxl1 + 1; x <= xpxl2 - 1; ++x) -	{ -		if(steep) -		{ -			plot(pixbuf, colour, std::floor(intery)  , x, rfpart(intery)); -			plot(pixbuf, colour, std::floor(intery)+1, x,  fpart(intery)); -		} -		else -		{ -			plot(pixbuf, colour, x, std::floor(intery),  rfpart(intery)); -			plot(pixbuf, colour, x, std::floor(intery)+1, fpart(intery)); -		} -		intery += gradient; -	} -} - -void Painter::drawRectangle(int x1, int y1, int x2, int y2) -{ -	drawLine(x1, y1, x2 - 1, y1); -	drawLine(x2, y1, x2, y2 - 1); -	drawLine(x1 + 1, y2, x2, y2); -	drawLine(x1, y1 + 1, x1, y2); -} - -void Painter::drawFilledRectangle(int x1, int y1, int x2, int y2) -{ -	for(int y = y1; y <= y2; ++y) -	{ -		drawLine(x1, y, x2, y); -	} -} - -void Painter::clear() -{ -	pixbuf.clear(); -} - -void Painter::drawText(int x0, int y0, const Font& font, -                       const std::string& text, bool nocolour, bool rotate) -{ -	PixelBufferAlpha* textbuf = font.render(text); - -	if(!rotate) -	{ -		y0 -= textbuf->height; // The y0 offset (baseline) is the bottom of the text. -	} - -	// If the text offset is outside the buffer; skip it. -	if((x0 > (int)pixbuf.width) || (y0 > (int)pixbuf.height)) -	{ -		delete textbuf; -		return; -	} - -	// Make sure we don't try to draw outside the pixbuf. -	int renderWidth = textbuf->width; -	if(renderWidth > (int)(pixbuf.width - x0)) -	{ -		renderWidth = pixbuf.width - x0; -	} - -	int renderHeight = textbuf->height; -	if(renderHeight > ((int)pixbuf.height - y0)) -	{ -		renderHeight = ((int)pixbuf.height - y0); -	} - -	if(nocolour) -	{ -		for(int y = -1 * std::min(0, y0); y < renderHeight; ++y) -		{ -			int x = -1 * std::min(0, x0); - -			assert(x >= 0); -			assert(y >= 0); -			assert(x < (int)textbuf->width); -			assert(y < (int)textbuf->height); - -			auto c = textbuf->getLine(x, y); - -			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 if(rotate) -	{ -		int renderWidth = textbuf->height; -		if(renderWidth > (int)(pixbuf.width - x0)) -		{ -			renderWidth = pixbuf.width - x0; -		} - -		int renderHeight = textbuf->width; -		if(renderHeight > ((int)pixbuf.height - y0)) -		{ -			renderHeight = ((int)pixbuf.height - y0); -		} - -		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->height); -				assert(y < (int)textbuf->width); - -				auto c = textbuf->pixel(textbuf->width - y - 1, x); - -				assert(x + x0 >= 0); -				assert(y + y0 >= 0); -				assert(x + x0 < (int)pixbuf.width); -				assert(y + y0 < (int)pixbuf.height); - -				Colour col(colour.red(), colour.green(), -				           colour.blue(), (int)(colour.alpha() * c.alpha()) / 255); -				pixbuf.addPixel(x + x0, y + y0, col); -			} -		} -	} -	else -	{ -		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); - -				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); - -				Colour col(colour.red(), colour.green(), -				           colour.blue(), (int)(colour.alpha() * c.alpha()) / 255); -				pixbuf.addPixel(x + x0, y + y0, col); -			} -		} -	} - -	delete textbuf; -} - -void Painter::drawPoint(int x, int y) -{ -	if(x >= 0 && y >= 0 && (std::size_t)x < pixbuf.width && (std::size_t)y < pixbuf.height) -	{ -		pixbuf.setPixel(x, y, colour); -	} -} - -static void plot4points(Painter *p, int cx, int cy, int x, int y) -{ -	p->drawPoint(cx + x, cy + y); -	if(x != 0) -	{ -		p->drawPoint(cx - x, cy + y); -	} - -	if(y != 0) -	{ -		p->drawPoint(cx + x, cy - y); -	} - -	if(x != 0 && y != 0) -	{ -		p->drawPoint(cx - x, cy - y); -	} -} - -void Painter::drawCircle(int cx, int cy, double radius) -{ -	int error = -radius; -	int x = radius; -	int y = 0; - -	while(x >= y) -	{ -		plot4points(this, cx, cy, x, y); - -		if(x != y) -		{ -			plot4points(this, cx, cy, y, x); -		} - -		error += y; -		++y; -		error += y; - -		if(error >= 0) -		{ -			--x; -			error -= x; -			error -= x; -		} -	} -} - -static void plot4lines(Painter *p, int cx, int cy, int x, int y) -{ -	p->drawLine(cx + x, cy + y, cx - x, cy + y); -	if(x != 0) -	{ -		p->drawLine(cx - x, cy + y, cx + x, cy + y); -	} - -	if(y != 0) -	{ -		p->drawLine(cx + x, cy - y, cx - x, cy - y); -	} - -	if(x != 0 && y != 0) -	{ -		p->drawLine(cx - x, cy - y, cx + x, cy - y); -	} -} - -void Painter::drawFilledCircle(int cx, int cy, int radius) -{ -	int error = -radius; -	int x = radius; -	int y = 0; - -	while(x >= y) -	{ -		plot4lines(this, cx, cy, x, y); - -		if(x != y) -		{ -			plot4lines(this, cx, cy, y, x); -		} - -		error += y; -		++y; -		error += y; - -		if(error >= 0) -		{ -			--x; -			error -= x; -			error -= x; -		} -	} -} - -void Painter::drawImage(int x0, int y0, const Drawable& image) -{ -	int fw = image.width(); -	int fh = image.height(); - -	// Make sure we don't try to draw outside the pixbuf. -	if(fw > (int)(pixbuf.width - x0)) -	{ -		fw = (int)(pixbuf.width - x0); -	} - -	if(fh > (int)(pixbuf.height - y0)) -	{ -		fh = (int)(pixbuf.height - y0); -	} - -	if((fw < 1) || (fh < 1)) -	{ -		return; -	} - -	if(image.hasAlpha()) -	{ -		if(!image.line(0)) -		{ -			for(std::size_t y = -1 * std::min(0, y0); y < (std::size_t)fh; ++y) -			{ -				for(std::size_t x = -1 * std::min(0, x0); x < (std::size_t)fw; ++x) -				{ -					assert(x >= 0); -					assert(y >= 0); -					assert(x < image.width()); -					assert(y < image.height()); -					auto& c = image.getPixel(x, y); - -					assert(x0 + x >= 0); -					assert(y0 + y >= 0); -					assert(x0 + x < pixbuf.width); -					assert(y0 + y < pixbuf.height); - -					pixbuf.addPixel(x0 + x, y0 + y, c); -				} -			} -		} -		else -		{ -			std::size_t x_offset = -1 * std::min(0, x0); -			for(std::size_t y = -1 * std::min(0, y0); y < (std::size_t)fh; ++y) -			{ -				pixbuf.blendLine(x_offset + x0, y + y0, image.line(y, x_offset), -				                 std::min((int)image.width(), fw - (int)x_offset)); -			} -		} -	} -	else -	{ -		std::size_t x_offset = -1 * std::min(0, x0); -		for(std::size_t y = -1 * std::min(0, y0); y < (std::size_t)fh; ++y) -		{ -			pixbuf.writeLine(x_offset + x0, y + y0, image.line(y, x_offset), -			                 std::min((int)image.width(), fw - (int)x_offset)); -		} -	} -} - -void Painter::drawRestrictedImage(int x0, int y0, -                                  const Colour& restriction_colour, -                                  const Drawable& image) -{ -	int fw = image.width(); -	int fh = image.height(); - -	// Make sure we don't try to draw outside the pixbuf. -	if(fw > (int)(pixbuf.width - x0)) -	{ -		fw = (int)(pixbuf.width - x0); -	} - -	if(fh > (int)(pixbuf.height - y0)) -	{ -		fh = (int)(pixbuf.height - y0); -	} - -	if((fw < 1) || (fh < 1)) -	{ -		return; -	} - -	for(std::size_t y = -1 * std::min(0, y0); y < (std::size_t)fh; ++y) -	{ -		for(std::size_t x = -1 * std::min(0, x0); x < (std::size_t)fw; ++x) -		{ -			assert(x >= 0); -			assert(y >= 0); -			assert(x < image.width()); -			assert(y < image.height()); -			auto& c = image.getPixel(x, y); - -			assert(x0 + x >= 0); -			assert(y0 + y >= 0); -			assert(x0 + x < pixbuf.width); -			assert(y0 + y < pixbuf.height); - -			if(c == restriction_colour) -			{ -				pixbuf.setPixel(x0 + x, y0 + y, c); -			} -		} -	} -} - -void Painter::drawImageStretched(int x0, int y0, const Drawable& image, -                                 int width, int height) -{ -	float fw = image.width(); -	float fh = image.height(); - -	// Make sure we don't try to draw outside the pixbuf. -	if(width > (int)(pixbuf.width - x0)) -	{ -		width = pixbuf.width - x0; -	} - -	if(height > (int)(pixbuf.height - y0)) -	{ -		height = pixbuf.height - y0; -	} - -	if((width < 1) || (height < 1)) -	{ -		return; -	} - -	for(int y = -1 * std::min(0, y0); y < height; ++y) -	{ -		for(int x = -1 * std::min(0, x0); x < width; ++x) -		{ -			int lx = ((float)x / (float)width) * fw; -			int ly = ((float)y / (float)height) * fh; -			auto& c = image.getPixel(lx, ly); -			pixbuf.addPixel(x0 + x, y0 + y, c); -		} -	} -} - -void Painter::drawBox(int x, int y, const Box& box, int width, int height) -{ -	int dx = x; -	int dy = y; - -	// Top: -	drawImage(dx, dy, *box.topLeft); - -	dx += box.topLeft->width(); -	if((dx < 0) || (dy < 0)) -	{ -		return; -	} - -	drawImageStretched(dx, dy, *box.top, -	                   width - box.topRight->width() - box.topLeft->width(), -	                   box.top->height()); - -	dx = x + width - box.topRight->width(); -	if((dx < 0) || (dy < 0)) -	{ -		return; -	} - -	drawImage(dx, dy, *box.topRight); - -	// Center: -	dy = y + box.topLeft->height(); -	dx = x + box.left->width(); -	if((dx < 0) || (dy < 0)) -	{ -		return; -	} - -	drawImageStretched(dx, dy, *box.center, -	                   width - box.left->width() - box.right->width(), -	                   height - box.topLeft->height() - box.bottomLeft->height()); - -	// Mid: -	dx = x; -	dy = y + box.topLeft->height(); -	if((dx < 0) || (dy < 0)) -	{ -		return; -	} - -	drawImageStretched(dx, dy, *box.left, box.left->width(), -	                   height - box.topLeft->height() - box.bottomLeft->height()); - -	dx = x + width - box.right->width(); -	dy = y + box.topRight->height(); -	if((dx < 0) || (dy < 0)) -	{ -		return; -	} - -	drawImageStretched(dx, dy, *box.right, -	                   box.right->width(), -	                   height - box.topRight->height() - box.bottomRight->height()); - -	// Bottom: -	dx = x; -	dy = y + height - box.bottomLeft->height(); -	if((dx < 0) || (dy < 0)) -	{ -		return; -	} - -	drawImage(dx, dy, *box.bottomLeft); - -	dx += box.bottomLeft->width(); -	if((dx < 0) || (dy < 0)) -	{ -		return; -	} - -	drawImageStretched(dx, dy, *box.bottom, -	                   width - box.bottomRight->width() - box.bottomLeft->width(), -	                   box.bottom->height()); - -	dx = x + width - box.bottomRight->width(); -	if((dx < 0) || (dy < 0)) -	{ -		return; -	} - -	drawImage(dx, dy, *box.bottomRight); -} - -void Painter::drawBar(int x, int y, const Bar& bar, int width, int height) -{ -	if(width < ((int)bar.left->width() + (int)bar.right->width() + 1)) -	{ -		width = bar.left->width() + bar.right->width() + 1; -	} - -	drawImageStretched(x, y, *bar.left, bar.left->width(), height); - -	drawImageStretched(x + bar.left->width(), y, *bar.center, -	                   width - bar.left->width() - bar.right->width(), height); - -	drawImageStretched(x + width - bar.left->width(), y, *bar.right, -	                   bar.right->width(), height); -} - -} // GUI:: | 
