Blame c++/iir_blur/surface.h

bw 249abc
/*
bw 249abc
    ......... 2016 Ivan Mahonin
bw 249abc
bw 249abc
    This program is free software: you can redistribute it and/or modify
bw 249abc
    it under the terms of the GNU General Public License as published by
bw 249abc
    the Free Software Foundation, either version 3 of the License, or
bw 249abc
    (at your option) any later version.
bw 249abc
bw 249abc
    This program is distributed in the hope that it will be useful,
bw 249abc
    but WITHOUT ANY WARRANTY; without even the implied warranty of
bw 249abc
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
bw 249abc
    GNU General Public License for more details.
bw 249abc
bw 249abc
    You should have received a copy of the GNU General Public License
bw 249abc
    along with this program.  If not, see <http: licenses="" www.gnu.org="">.</http:>
bw 249abc
*/
bw 249abc
bw 249abc
#ifndef _SURFACE_H_
bw 249abc
#define _SURFACE_H_
bw 249abc
bw 249abc
#include <cassert></cassert>
bw 249abc
bw 249abc
#include <string></string>
bw 249abc
bw 249abc
class Surface {
bw 249abc
public:
bw 249abc
	typedef unsigned int Color;
bw 249abc
bw 249abc
	Color* const buffer;
bw 249abc
	const int width;
bw 249abc
	const int height;
bw 249abc
bw 249abc
	Color color;
bw 249abc
	int x, y;
bw 249abc
	bool blending;
bw 249abc
bw 249abc
	Surface(int width, int height);
bw 249abc
	~Surface();
bw 249abc
bw 249abc
	static unsigned int convert_channel(double c);
bw 249abc
	static unsigned int blend_channel(unsigned int a, unsigned int dest, unsigned int src);
bw 249abc
	static Color convert_color(double r, double g, double b, double a = 1.0);
bw 249abc
	static Color blend(Color dest, Color src);
bw 249abc
bw 249abc
	bool is_inside(int x, int y) const
bw 249abc
		{ return x >= 0 && x < width && y >= 0 && y < height; }
bw 249abc
bw 249abc
	Color& point(int x, int y)
bw 249abc
		{ assert(is_inside(x, y)); return buffer[y*width + x]; }
bw 249abc
	const Color& point(int x, int y) const
bw 249abc
		{ assert(is_inside(x, y)); return buffer[y*width + x]; }
bw 249abc
bw 249abc
	void set_color(Color color)
bw 249abc
		{ this->color = color; }
bw 249abc
	void set_color(double r, double g, double b, double a = 1.0)
bw 249abc
		{ set_color(convert_color(r, g, b, a)); }
bw 249abc
	void set_blending(bool blending) { this->blending = blending; }
bw 249abc
bw 249abc
	void line(Color color, int x0, int y0, int x1, int y1, bool blending = true);
bw 249abc
	void rect(Color color, int x0, int y0, int x1, int y1, bool blending = true);
bw 249abc
bw 249abc
	void move_to(int x, int y) { this->x = x; this->y = y; }
bw 249abc
	void line_to(int x, int y) { line(color, this->x, this->y, x, y, blending); move_to(x, y); };
bw 249abc
	void rect_to(int x, int y) { rect(color, this->x, this->y, x, y, blending); move_to(x, y); };
bw 249abc
bw 249abc
	void move_by(int x, int y) { move_to(this->x + x, this->y + y); }
bw 249abc
	void line_by(int x, int y) { line_to(this->x + x, this->y + y); }
bw 249abc
	void rect_by(int x, int y) { rect_to(this->x + x, this->y + y); }
bw 249abc
bw 249abc
	void clear(Color color = 0) { rect(color, 0, 0, width, height, false); }
bw 249abc
	void clear(double r, double g, double b, double a) { clear(convert_color(r, g, b, a)); }
bw 249abc
bw 249abc
	void set_point(int x, int y, unsigned int color)
bw 249abc
		{ if (is_inside(x, y)) point(x, y) = color; }
bw 249abc
	void blend_point(int x, int y, unsigned int color) {
bw 249abc
		if (is_inside(x, y)) {
bw 249abc
			Color& p = point(x, y);
bw 249abc
			p = blend(p, color);
bw 249abc
		}
bw 249abc
	}
bw 249abc
bw 249abc
	void save(const std::string &filename) const;
bw 249abc
};
bw 249abc
bw 249abc
#endif