[cairo-commit] rcairo/packages/cairo/ext rb_cairo_context.c, 1.32, 1.33 rb_cairo_surface.c, 1.30, 1.31

Kouhei Sutou commit at pdx.freedesktop.org
Fri Dec 29 04:37:29 PST 2006


Committed by: kou

Update of /cvs/cairo/rcairo/packages/cairo/ext
In directory kemper:/tmp/cvs-serv15897/packages/cairo/ext

Modified Files:
	rb_cairo_context.c rb_cairo_surface.c 
Log Message:
* packages/cairo/ext/rb_cairo_context.c: keep reference of Ruby
  object for the surface in the context.

* packages/cairo/ext/rb_cairo_surface.c:
  - use file output functions provided by cairo.
  - hold output target reference in surface.


Index: rb_cairo_context.c
===================================================================
RCS file: /cvs/cairo/rcairo/packages/cairo/ext/rb_cairo_context.c,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -d -r1.32 -r1.33
--- rb_cairo_context.c	21 Dec 2006 15:34:36 -0000	1.32
+++ rb_cairo_context.c	29 Dec 2006 12:37:25 -0000	1.33
@@ -17,7 +17,7 @@
 
 VALUE rb_cCairo_Context;
 
-static ID cr_id_source_class;
+static ID cr_id_source, cr_id_source_class;
 
 #define _SELF  (RVAL2CRCONTEXT(self))
 
@@ -93,6 +93,7 @@
 
   cr = cairo_create (RVAL2CRSURFACE (target));
   cr_check_status (cr);
+  rb_ivar_set (self, cr_id_source, target);
   DATA_PTR(self) = cr;
   return Qnil;
 }
@@ -1165,10 +1166,19 @@
 cr_get_target (VALUE self)
 {
   cairo_surface_t *surface;
+  VALUE rb_surface;
 
   surface = cairo_get_target (_SELF);
   rb_cairo_check_status (cairo_surface_status (surface));
-  return CRSURFACE2RVAL (surface);
+
+  rb_surface = rb_ivar_get (self, cr_id_source);
+  if (NIL_P (rb_surface) || RVAL2CRSURFACE (rb_surface) != surface)
+    {
+      rb_surface = CRSURFACE2RVAL (surface);
+      rb_ivar_set (self, cr_id_source, rb_surface);
+    }
+
+  return rb_surface;
 }
 
 static VALUE
@@ -1209,6 +1219,7 @@
 void
 Init_cairo_context (void)
 {
+  cr_id_source = rb_intern ("source");
   cr_id_source_class = rb_intern ("source_class");
 
 #if CAIRO_CHECK_VERSION(1, 3, 0)

Index: rb_cairo_surface.c
===================================================================
RCS file: /cvs/cairo/rcairo/packages/cairo/ext/rb_cairo_surface.c,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -d -r1.30 -r1.31
--- rb_cairo_surface.c	21 Dec 2006 15:34:36 -0000	1.30
+++ rb_cairo_surface.c	29 Dec 2006 12:37:25 -0000	1.31
@@ -30,11 +30,9 @@
 VALUE rb_cCairo_PSSurface;
 VALUE rb_cCairo_SVGSurface;
 
+static ID cr_id_target;
 static ID cr_id_read;
 static ID cr_id_write;
-static ID cr_id_holder;
-static ID cr_id_closed;
-static ID cr_id_closure;
 static cairo_user_data_key_t cr_klass_key;
 static cairo_user_data_key_t cr_closure_key;
 
@@ -92,74 +90,26 @@
 typedef struct cr_io_callback_closure {
   VALUE target;
   VALUE error;
-  VALUE klass;
   unsigned char *data;
   unsigned int length;
-  cairo_bool_t is_file;
 } cr_io_callback_closure_t;
 
 #if HAS_CREATE_CR_CLOSURE_SURFACE
-static VALUE
-cr_closure_target_push (VALUE klass, VALUE obj)
-{
-  VALUE holder, key, objs;
-  
-  holder = rb_ivar_get (klass, cr_id_holder);
-  key = rb_obj_id (obj);
-  objs = rb_hash_aref (holder, key);
-
-  if (NIL_P (objs))
-    {
-      objs = rb_ary_new ();
-      rb_hash_aset (holder, key, objs);
-    }
-
-  rb_ary_push(objs, obj);
-
-  return Qnil;
-}
-
-static VALUE
-cr_closure_target_pop(VALUE klass, VALUE obj)
-{
-  VALUE holder, key, objs;
-  VALUE result = Qnil;
-
-  holder = rb_ivar_get (klass, cr_id_holder);
-  key = rb_obj_id (obj);
-  objs = rb_hash_aref (holder, key);
-
-  if (!NIL_P (objs))
-    {
-      result = rb_ary_pop (objs);
-      if (RARRAY (objs)->len == 0)
-        {
-          rb_hash_delete (holder, key);
-        }
-    }
-
-  return result;
-}
-
 static cr_io_callback_closure_t *
-cr_closure_new (VALUE target, cairo_bool_t is_file)
+cr_closure_new (VALUE target)
 {
   cr_io_callback_closure_t *closure;
   closure = ALLOC (cr_io_callback_closure_t);
 
   closure->target = target;
   closure->error = Qnil;
-  closure->is_file = is_file;
-  
+
   return closure;
 }
 
 static void
 cr_closure_destroy (cr_io_callback_closure_t *closure)
 {
-  if (closure->is_file)
-    cr_closure_target_pop (closure->klass, closure->target);
-
   free (closure);
 }
 
@@ -336,14 +286,6 @@
   
   cairo_surface_finish (_SELF);
 
-  if (closure && closure->is_file)
-    {
-      VALUE file;
-      file = closure->target;
-      if (!RTEST (rb_funcall (file, cr_id_closed, 0)))
-        rb_io_close (file);
-    }
-  
   if (closure && !NIL_P (closure->error))
     rb_exc_raise (closure->error);
   
@@ -373,7 +315,6 @@
 
   closure.target = target;
   closure.error = Qnil;
-  closure.is_file = CR_FALSE;
 
   status = cairo_surface_write_to_png_stream (_SELF, cr_surface_write_func,
                                               (void *)&closure);
@@ -385,21 +326,12 @@
 }
 
 static VALUE
-cr_surface_write_to_png_stream_invoke (VALUE info)
-{
-  return cr_surface_write_to_png_stream (rb_ary_entry (info, 0),
-                                         rb_ary_entry (info, 1));
-}
-
-static VALUE
 cr_surface_write_to_png (VALUE self, VALUE filename)
 {
-  VALUE info, file;
-
-  file = rb_file_open (StringValuePtr (filename), "wb");
-  info = rb_ary_new3 (2, self, file);
-  return rb_ensure (cr_surface_write_to_png_stream_invoke, info,
-                    rb_io_close, file);
+  cairo_status_t status;
+  status = cairo_surface_write_to_png (_SELF, StringValueCStr (filename));
+  rb_cairo_check_status (status);
+  return self;
 }
 
 static VALUE
@@ -493,7 +425,7 @@
 
 /* Image-surface functions */
 #if CAIRO_HAS_PNG_FUNCTIONS
-static VALUE
+static cairo_surface_t *
 cr_image_surface_create_from_png_stream (VALUE target)
 {
   cr_io_callback_closure_t closure;
@@ -501,24 +433,19 @@
 
   closure.target = target;
   closure.error = Qnil;
-  closure.is_file = CR_FALSE;
-  
+
   surface = cairo_image_surface_create_from_png_stream (cr_surface_read_func,
                                                         (void *)&closure);
   if (!NIL_P (closure.error))
     rb_exc_raise (closure.error);
   
-  return (VALUE)surface;
+  return surface;
 }
 
-static VALUE
+static cairo_surface_t *
 cr_image_surface_create_from_png (VALUE filename)
 {
-  VALUE file;
-  file = rb_file_open (StringValuePtr (filename), "rb");
-  
-  return rb_ensure (cr_image_surface_create_from_png_stream, file,
-                    rb_io_close, file);
+  return cairo_image_surface_create_from_png (StringValueCStr (filename));
 }
 
 static VALUE
@@ -526,10 +453,11 @@
 {
   VALUE rb_surface;
   cairo_surface_t *surface;
+
   if (rb_respond_to (target, cr_id_read))
-    surface = (cairo_surface_t *)cr_image_surface_create_from_png_stream (target);
+    surface = cr_image_surface_create_from_png_stream (target);
   else
-    surface = (cairo_surface_t *)cr_image_surface_create_from_png (target);
+    surface = cr_image_surface_create_from_png (target);
 
   cr_surface_check_status (surface);
   cr_surface_set_klass (surface, klass);
@@ -631,46 +559,52 @@
 
 
 /* Printing surfaces */
-#define DEFINE_SURFACE(type)                                              \
-static VALUE                                                              \
-cr_ ## type ## _surface_initialize (VALUE self, VALUE target,             \
-                                    VALUE rb_width_in_points,             \
-                                    VALUE rb_height_in_points)            \
-{                                                                         \
-  cr_io_callback_closure_t *closure;                                      \
-  cairo_surface_t *surface;                                               \
-  double width_in_points, height_in_points;                               \
-                                                                          \
-  if (rb_respond_to (target, cr_id_write))                                \
-    {                                                                     \
-      closure = cr_closure_new (target, CR_FALSE);                        \
-    }                                                                     \
-  else                                                                    \
-    {                                                                     \
-      VALUE file;                                                         \
-      file = rb_file_open (StringValuePtr (target), "wb");                \
-      closure = cr_closure_new (file, CR_TRUE);                           \
-      closure->klass = rb_obj_class (self);                               \
-      cr_closure_target_push (closure->klass, closure->target);           \
-    }                                                                     \
-                                                                          \
-  width_in_points = NUM2DBL (rb_width_in_points);                         \
-  height_in_points = NUM2DBL (rb_height_in_points);                       \
-  surface =                                                               \
-    cairo_ ## type ## _surface_create_for_stream (cr_surface_write_func,  \
-                                                  (void *) closure,       \
-                                                  width_in_points,        \
-                                                  height_in_points);      \
-                                                                          \
-  if (cairo_surface_status (surface))                                     \
-    cr_closure_destroy (closure);                                         \
-  else                                                                    \
-    cairo_surface_set_user_data (surface, &cr_closure_key,                \
-                                 closure, cr_closure_free);               \
-                                                                          \
-  cr_surface_check_status (surface);                                      \
-  DATA_PTR (self) = surface;                                              \
-  return Qnil;                                                            \
+#define DEFINE_SURFACE(type)                                            \
+static VALUE                                                            \
+cr_ ## type ## _surface_initialize (VALUE self, VALUE target,           \
+                                    VALUE rb_width_in_points,           \
+                                    VALUE rb_height_in_points)          \
+{                                                                       \
+  cairo_surface_t *surface;                                             \
+  double width_in_points, height_in_points;                             \
+                                                                        \
+  width_in_points = NUM2DBL (rb_width_in_points);                       \
+  height_in_points = NUM2DBL (rb_height_in_points);                     \
+                                                                        \
+  if (rb_respond_to (target, cr_id_write))                              \
+    {                                                                   \
+      cr_io_callback_closure_t *closure;                                \
+                                                                        \
+      closure = cr_closure_new (target);                                \
+      surface =                                                         \
+        cairo_ ## type ## _surface_create_for_stream (                  \
+          cr_surface_write_func,                                        \
+          (void *) closure,                                             \
+          width_in_points,                                              \
+          height_in_points);                                            \
+                                                                        \
+      if (cairo_surface_status (surface))                               \
+        {                                                               \
+          cr_closure_destroy (closure);                                 \
+        }                                                               \
+      else                                                              \
+        {                                                               \
+          rb_ivar_set (self, cr_id_target, target);                     \
+          cairo_surface_set_user_data (surface, &cr_closure_key,        \
+                                       closure, cr_closure_free);       \
+        }                                                               \
+    }                                                                   \
+  else                                                                  \
+    {                                                                   \
+      surface =                                                         \
+        cairo_ ## type ## _surface_create (StringValueCStr (target),    \
+                                           width_in_points,             \
+                                           height_in_points);           \
+    }                                                                   \
+                                                                        \
+  cr_surface_check_status (surface);                                    \
+  DATA_PTR (self) = surface;                                            \
+  return Qnil;                                                          \
 }
 
 
@@ -782,11 +716,9 @@
 void
 Init_cairo_surface (void)
 {
+  cr_id_target = rb_intern ("target");
   cr_id_read = rb_intern ("read");
   cr_id_write = rb_intern ("write");
-  cr_id_closed = rb_intern ("closed?");
-  cr_id_closure = rb_intern ("closure");
-  cr_id_holder = rb_intern ("holder");
   
   rb_cCairo_Surface =
     rb_define_class_under (rb_mCairo, "Surface", rb_cObject);
@@ -844,9 +776,6 @@
     rb_define_class_under (rb_mCairo, # name "Surface",                 \
                            rb_cCairo_Surface);                          \
                                                                         \
-  rb_ivar_set (rb_cCairo_ ## name ## Surface,                           \
-               cr_id_holder, rb_hash_new ());                           \
-                                                                        \
   rb_define_method (rb_cCairo_ ## name ## Surface, "initialize",        \
                     cr_ ## type ## _surface_initialize, 3);
 



More information about the cairo-commit mailing list