advise if I got the patch format wrong or anything!
diff --git a/shoes/canvas.c b/shoes/canvas.c
index c47d1b8..fd39447 100644
--- a/shoes/canvas.c
+++ b/shoes/canvas.c
@@ -2264,3 +2264,76 @@ shoes_canvas_dialog_plain(VALUE self)
return shoes_color_new(GetRValue(winc), GetGValue(winc), GetBValue(winc), SHOES_COLOR_OPAQUE);
#endif
}
+
+typedef cairo_public cairo_surface_t * (cairo_surface_function_t) (const char *filename, double width, double height);
+
+static cairo_public cairo_surface_t *
+nada (const char *filename, double width, double height)
+{
+ return NULL;
+}
+
+#include "cairo-svg.h"
+#include "cairo-ps.h"
+#include "cairo-pdf.h"
+
+// TODO can ya turn on -Wall in the compiler?
+
+static cairo_surface_function_t *
+get_snapshot_surface(VALUE _format)
+{
+ ID format = SYM2ID (_format);
+ if (format == rb_intern ("pdf")) return & cairo_pdf_surface_create;
+ if (format == rb_intern ("ps")) return & cairo_ps_surface_create;
+ if (format == rb_intern ("svg")) return & cairo_svg_surface_create;
+ return nada;
+}
+
+VALUE
+shoes_canvas_snapshot(int argc, VALUE *argv, VALUE self)
+{
+ SETUP();
+ ID s_filename = rb_intern ("filename");
+ ID s_format = rb_intern ("format");
+ VALUE block = Qnil;
+ VALUE _filename = Qnil;
+ VALUE _format = Qnil;
+ VALUE hash = Qnil;
+ argc = rb_scan_args (argc, argv, "1&", &hash, &block);
+
+ if (argc == 1 && rb_obj_is_kind_of(hash, rb_cHash))
+ {
+ _filename = ATTR(hash, filename);
+ _format = ATTR(hash, format);
+ }
+ if (NIL_P(block) || NIL_P(_filename) || NIL_P(_format))
+ {
+ rb_raise(rb_eArgError, "wrong arguments for _snapshot({:filename=>'...',"
+ ":format=>:pdf|:ps|:svg}, &block)\n");
+ }
+ else
+ {
+ const char * filename = RSTRING_PTR(_filename);
+ cairo_surface_t * surface = get_snapshot_surface (_format)
+ (filename, canvas->width, canvas->height);
+ if (surface == NULL) {
+ rb_raise(rb_eArgError, "Failed to create %s surface for file %s\n",
+ RSTRING_PTR(rb_inspect(_format)),
+ RSTRING_PTR(rb_inspect(_filename))); // ERGO test this
+ }
+ else
+ {
+ cairo_t * waz_cr = canvas->cr;
+ cairo_t * cr = canvas->cr = cairo_create (surface);
+ DRAW (self, canvas->app, block);
+ shoes_canvas_draw (self, self, Qfalse); // why, _why?
+ shoes_canvas_draw (self, self, Qtrue);
+ canvas->cr = waz_cr;
+ cairo_show_page (cr);
+ cairo_destroy (cr);
+ cairo_surface_destroy (surface);
+ // TODO detect cairo outrages here
+ }
+ }
+ return Qnil; // TODO what to return??
+}
diff --git a/shoes/canvas.h b/shoes/canvas.h
index 488586f..4d49ad7 100644
--- a/shoes/canvas.h
+++ b/shoes/canvas.h
@@ -376,6 +376,7 @@ VALUE shoes_canvas_window(int, VALUE *, VALUE);
VALUE shoes_canvas_dialog(int, VALUE *, VALUE);
VALUE shoes_canvas_window_plain(VALUE);
VALUE shoes_canvas_dialog_plain(VALUE);
+VALUE shoes_canvas_snapshot(int, VALUE *, VALUE);
VALUE shoes_slot_new(VALUE, VALUE, VALUE);
VALUE shoes_flow_new(VALUE, VALUE);
diff --git a/shoes/ruby.h b/shoes/ruby.h
index 8820194..658ecef 100644
--- a/shoes/ruby.h
+++ b/shoes/ruby.h
@@ -207,6 +207,7 @@ void shoes_cairo_rect(cairo_t *, double, double, double, double, double);
f("window", window, -1); \
f("dialog", dialog, -1); \
f("window_plain", window_plain, 0); \
- f("dialog_plain", dialog_plain, 0)
+ f("dialog_plain", dialog_plain, 0); \
+ f("_snapshot", snapshot, -1) /* TODO neg one?? */
#endif
simple-snapshot.rb
Description: application/ruby
