Blame c++/perspective/src/surface.h

531f67
#ifndef SURFACE_H
531f67
#define SURFACE_H
531f67
531f67
531f67
#include <cassert></cassert>
531f67
#include <cstddef></cstddef>
531f67
a1942e
#include <gdkmm pixbuf.h=""></gdkmm>
a1942e
#include <cairomm surface.h=""></cairomm>
a1942e
531f67
#include "common.h"
531f67
531f67
531f67
class Surface: public Shared {
531f67
protected:
531f67
	int m_width;
531f67
	int m_height;
531f67
	int m_pitch;
531f67
	Color *m_origin;
531f67
	
531f67
	Surface();
531f67
	Surface(const Surface &);
531f67
	Surface& operator= (const Surface &) { return *this; }
531f67
	void reset();
4dc49c
	
531f67
public:
531f67
	virtual ~Surface() { }
531f67
	
531f67
	inline int width() const { return m_width; }
531f67
	inline int height() const { return m_height; }
531f67
	inline int pitch() const { return m_pitch; }
531f67
	inline int count() const { return m_width*m_height; }
531f67
	inline bool empty() const { return !count(); }
531f67
	
531f67
	inline Color* origin() { return m_origin; }
531f67
	inline const Color* origin() const { return m_origin; }
4dc49c
	
531f67
	inline int data_count()   const { return data_count  (width(), height(), pitch()); }
531f67
	inline size_t data_size() const { return data_size   (width(), height(), pitch()); }
531f67
	inline int begin_offset() const { return begin_offset(width(), height(), pitch()); }
531f67
	inline int end_offset()   const { return end_offset  (width(), height(), pitch()); }
531f67
	
531f67
	inline Color* data_begin() { return m_origin ? m_origin + begin_offset() : NULL; }
531f67
	inline const Color* data_begin() const { return m_origin ? m_origin + begin_offset() : NULL; }
531f67
	inline Color* data_end() { return m_origin ? m_origin + end_offset() : NULL; }
531f67
	inline const Color* data_end() const { return m_origin ? m_origin + end_offset() : NULL; }
531f67
	
531f67
	inline Color* row(int index)
531f67
		{ assert(index >= 0 && index < m_height); return m_origin + index*m_pitch; }
531f67
	inline const Color* row(int index) const
531f67
		{ assert(index >= 0 && index < m_height); return m_origin + index*m_pitch; }
531f67
	
531f67
	inline Color* operator[] (int index) { return row(index); }
531f67
	inline const Color* operator[] (int index) const { return row(index); }
4dc49c
	
43cb04
	inline void put_pixel(int x, int y, const Color &color) {
43cb04
		if (x >= 0 && y >= 0 && x < width() && y < height())
43cb04
			row(y)[x] = color;
43cb04
	}
43cb04
	
4dc49c
	void mult_alpha();
4dc49c
	void demult_alpha();
4dc49c
	Color get_pixel(Real x, Real y) const;
4dc49c
	Color get_pixel_premulted(Real x, Real y) const;
4dc49c
	
531f67
	static inline int data_count(int width, int height, int pitch)
531f67
		{ return width + abs(pitch)*(height - 1); }
531f67
	static inline size_t data_size(int width, int height, int pitch)
531f67
		{ return data_count(width, height, pitch)*sizeof(Color); }
531f67
	static inline int begin_offset(int width, int height, int pitch)
531f67
		{ return pitch > 0 ? 0 : width - data_count(width, height, pitch); }
531f67
	static inline int end_offset(int width, int height, int pitch)
531f67
		{ return pitch > 0 ? data_count(width, height, pitch) : width; }
531f67
531f67
	static void copy(int width, int height, const Color *src_origin, Color *dest_origin, int src_pitch = 0, int dest_pitch = 0);
4dc49c
	
a1942e
	Glib::RefPtr<gdk::pixbuf> to_pixbuf() const;</gdk::pixbuf>
4dc49c
	Cairo::RefPtr<cairo::imagesurface> to_cairo_surface(bool premulted = false) const;</cairo::imagesurface>
531f67
};
531f67
531f67
531f67
class DataSurface: public Surface {
531f67
public:
531f67
	explicit DataSurface(int width = 0, int height = 0, int pitch = 0, const Color *src_origin = NULL, int src_pitch = 0)
531f67
		{ init(width, height, pitch, src_origin, src_pitch); }
531f67
	DataSurface(const Surface &other)
531f67
		{ *this = other; }
531f67
	~DataSurface()
531f67
		{ clear(); }
531f67
	DataSurface& operator= (const Surface &other)
531f67
		{ init(other); return *this; }
531f67
	
531f67
	void clear();
531f67
	void init(int width, int height, int pitch = 0, const Color *src_origin = NULL, int src_pitch = 0);
531f67
	inline void init(const Surface &other)
531f67
		{ init(other.width(), other.height(), other.pitch(), other.origin(), other.pitch()); }
531f67
};
531f67
531f67
531f67
class AliasSurface: public Surface {
531f67
public:
531f67
	AliasSurface() { }
531f67
	AliasSurface(Color *origin, int width, int height, int pitch = 0)
531f67
		{ init(origin, width, height, pitch); }
531f67
	AliasSurface(const AliasSurface &other)
531f67
		{ *this = other; }
531f67
	AliasSurface(Surface &other)
531f67
		{ init(other); }
531f67
	AliasSurface& operator= (const AliasSurface &other)
531f67
		{ init(other); return *this; }
531f67
	
531f67
	inline Color* origin() const { return m_origin; }
531f67
	
531f67
	void init(Color *origin, int width, int height, int pitch = 0);
531f67
531f67
	inline void clear() { reset(); }
531f67
	inline void init(Surface &other)
531f67
		{ init(other.origin(), other.width(), other.height(), other.pitch()); }
531f67
	inline void init(const AliasSurface &other)
531f67
		{ init(other.origin(), other.width(), other.height(), other.pitch()); }
531f67
};
531f67
531f67
531f67
#endif