summaryrefslogtreecommitdiff
path: root/gtk2_ardour/luainstance.cc
diff options
context:
space:
mode:
authorRobin Gareus <robin@gareus.org>2016-07-02 18:20:44 +0200
committerRobin Gareus <robin@gareus.org>2016-07-02 23:36:34 +0200
commitd027ce800625d00e4cb96fd27410a575c9b6d895 (patch)
tree6f3fa1937b2302f091b789263a1e5a727f20325c /gtk2_ardour/luainstance.cc
parentb47d7aec2d3aeac0828a22c841636c3074c80fdf (diff)
add Lua bindings for reference counted Cairo::ImageSurface
Diffstat (limited to 'gtk2_ardour/luainstance.cc')
-rw-r--r--gtk2_ardour/luainstance.cc123
1 files changed, 123 insertions, 0 deletions
diff --git a/gtk2_ardour/luainstance.cc b/gtk2_ardour/luainstance.cc
index 369b795251..a1df9c9dd4 100644
--- a/gtk2_ardour/luainstance.cc
+++ b/gtk2_ardour/luainstance.cc
@@ -17,6 +17,7 @@
*/
#include <cairomm/context.h>
+#include <cairomm/surface.h>
#include "gtkmm2ext/gui_thread.h"
@@ -40,6 +41,113 @@
#include "i18n.h"
+namespace LuaCairo {
+/** wrap RefPtr< Cairo::ImageSurface >
+ *
+ * Image surfaces provide the ability to render to memory buffers either
+ * allocated by cairo or by the calling code. The supported image formats are
+ * those defined in Cairo::Format.
+ */
+class ImageSurface {
+ public:
+ /**
+ * Creates an image surface of the specified format and dimensions. Initially
+ * the surface contents are all 0. (Specifically, within each pixel, each
+ * color or alpha channel belonging to format will be 0. The contents of bits
+ * within a pixel, but not belonging to the given format are undefined).
+ *
+ * @param format format of pixels in the surface to create
+ * @param width width of the surface, in pixels
+ * @param height height of the surface, in pixels
+ */
+ ImageSurface (Cairo::Format format, int width, int height)
+ : _surface (Cairo::ImageSurface::create (format, width, height))
+ , _ctx (Cairo::Context::create (_surface))
+ , ctx (_ctx->cobj ()) {}
+
+ ~ImageSurface () {}
+
+ /**
+ * Set this surface as source for another context.
+ * This allows to draw this surface
+ */
+ void set_as_source (Cairo::Context* c, int x, int y) {
+ _surface->flush ();
+ c->set_source (_surface, x, y);
+ }
+
+ /**
+ * Returns a context object to perform operations on the surface
+ */
+ Cairo::Context* context () {
+ return (Cairo::Context *)&ctx;
+ }
+
+ /**
+ * Returns the stride of the image surface in bytes (or 0 if surface is not
+ * an image surface). The stride is the distance in bytes from the beginning
+ * of one row of the image data to the beginning of the next row.
+ */
+ int get_stride () const {
+ return _surface->get_stride ();
+ }
+
+ /** Gets the width of the ImageSurface in pixels */
+ int get_width () const {
+ return _surface->get_width ();
+ }
+
+ /** Gets the height of the ImageSurface in pixels */
+ int get_height () const {
+ return _surface->get_height ();
+ }
+
+ /**
+ * Get a pointer to the data of the image surface, for direct
+ * inspection or modification.
+ *
+ * Return value: a pointer to the image data of this surface or NULL
+ * if @surface is not an image surface.
+ *
+ */
+ unsigned char* get_data () {
+ return _surface->get_data ();
+ }
+
+ /** Tells cairo to consider the data buffer dirty.
+ *
+ * In particular, if you've created an ImageSurface with a data buffer that
+ * you've allocated yourself and you draw to that data buffer using means
+ * other than cairo, you must call mark_dirty() before doing any additional
+ * drawing to that surface with cairo.
+ *
+ * Note that if you do draw to the Surface outside of cairo, you must call
+ * flush() before doing the drawing.
+ */
+ void mark_dirty () {
+ _surface->mark_dirty ();
+ }
+
+ /** Marks a rectangular area of the given surface dirty.
+ *
+ * @param x X coordinate of dirty rectangle
+ * @param y Y coordinate of dirty rectangle
+ * @param width width of dirty rectangle
+ * @param height height of dirty rectangle
+ */
+ void mark_dirty (int x, int y, int width, int height) {
+ _surface->mark_dirty (x, y, width, height);
+ }
+
+ private:
+ Cairo::RefPtr<Cairo::ImageSurface> _surface;
+ Cairo::RefPtr<Cairo::Context> _ctx;
+ Cairo::Context ctx;
+};
+}; // namespace
+
+////////////////////////////////////////////////////////////////////////////////
+
namespace LuaSignal {
#define STATIC(name,c,p) else if (!strcmp(type, #name)) {return name;}
@@ -181,6 +289,21 @@ LuaInstance::bind_cairo (lua_State* L)
.addConst ("Add", CAIRO_OPERATOR_ADD)
.endNamespace ()
+ .beginNamespace ("Format")
+ .addConst ("ARGB32", CAIRO_FORMAT_ARGB32)
+ .addConst ("RGB24", CAIRO_FORMAT_RGB24)
+ .endNamespace ()
+
+ .beginClass <LuaCairo::ImageSurface> ("ImageSurface")
+ .addConstructor <void (*) (Cairo::Format, int, int)> ()
+ .addFunction ("set_as_source", &LuaCairo::ImageSurface::set_as_source)
+ .addFunction ("context", &LuaCairo::ImageSurface::context)
+ .addFunction ("get_stride", &LuaCairo::ImageSurface::get_stride)
+ .addFunction ("get_width", &LuaCairo::ImageSurface::get_width)
+ .addFunction ("get_height", &LuaCairo::ImageSurface::get_height)
+ .addFunction ("get_data", &LuaCairo::ImageSurface::get_data)
+ .endClass ()
+
.endNamespace ();
/* Lua/cairo bindings operate on Cairo::Context, there is no Cairo::RefPtr wrapper [yet].