[cairo-commit] rcairo/packages/cairo/ext rb_cairo_context.c, 1.22,
1.23 rb_cairo_surface.c, 1.18, 1.19
Kouhei Sutou
commit at pdx.freedesktop.org
Sat Oct 15 07:33:48 PDT 2005
- Previous message: [cairo-commit] rcairo ChangeLog,1.70,1.71
- Next message: [cairo-commit] rcairo/samples pdf.rb, 1.3, 1.4 pdf2.rb, NONE,
1.1 png.rb, 1.8, 1.9 ps.rb, 1.2, 1.3 ps2.rb, NONE, 1.1
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Committed by: kou
Update of /cvs/cairo/rcairo/packages/cairo/ext
In directory gabe:/tmp/cvs-serv12660/packages/cairo/ext
Modified Files:
rb_cairo_context.c rb_cairo_surface.c
Log Message:
* packages/cairo/ext/rb_cairo_context.c: Use StringValuePtr
instead of STR2CSTR.
* packages/cairo/ext/rb_cairo_surface.c: Supported PS/PDF surface.
* samples/ps.rb, samples/ps2.rb: Added PS surface sample.
* samples/pdf.rb, samples/pdf2.rb: Added PDF surface sample.
Index: rb_cairo_context.c
===================================================================
RCS file: /cvs/cairo/rcairo/packages/cairo/ext/rb_cairo_context.c,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -d -r1.22 -r1.23
--- rb_cairo_context.c 12 Oct 2005 14:57:44 -0000 1.22
+++ rb_cairo_context.c 15 Oct 2005 14:33:46 -0000 1.23
@@ -757,7 +757,7 @@
static VALUE
cr_select_font_face (VALUE self, VALUE family, VALUE slant, VALUE weight)
{
- cairo_select_font_face (_SELF, STR2CSTR (family),
+ cairo_select_font_face (_SELF, StringValuePtr (family),
RVAL2CRFONTSLANT (slant), RVAL2CRFONTWEIGHT (weight));
cr_check_status (_SELF);
return self;
@@ -808,7 +808,7 @@
static VALUE
cr_show_text (VALUE self, VALUE utf8)
{
- cairo_show_text (_SELF, STR2CSTR (utf8));
+ cairo_show_text (_SELF, StringValuePtr (utf8));
cr_check_status (_SELF);
return self;
}
@@ -880,7 +880,7 @@
static VALUE
cr_text_path (VALUE self, VALUE utf8)
{
- cairo_text_path (_SELF, STR2CSTR (utf8));
+ cairo_text_path (_SELF, StringValuePtr (utf8));
cr_check_status (_SELF);
return self;
}
Index: rb_cairo_surface.c
===================================================================
RCS file: /cvs/cairo/rcairo/packages/cairo/ext/rb_cairo_surface.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -d -r1.18 -r1.19
--- rb_cairo_surface.c 13 Oct 2005 04:45:52 -0000 1.18
+++ rb_cairo_surface.c 15 Oct 2005 14:33:46 -0000 1.19
@@ -31,10 +31,17 @@
static ID cr_id_read;
static ID cr_id_write;
-static cairo_user_data_key_t klass_key;
+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;
#define _SELF (RVAL2CRSURFACE(self))
+#define CR_TRUE 1
+#define CR_FALSE 0
+
static inline void
cr_surface_check_status (cairo_surface_t *surface)
{
@@ -45,7 +52,7 @@
cr_surface_set_klass (cairo_surface_t *surface, VALUE klass)
{
cairo_status_t status;
- status = cairo_surface_set_user_data (surface, &klass_key,
+ status = cairo_surface_set_user_data (surface, &cr_klass_key,
(void *)klass, NULL);
rb_cairo_check_status (status);
}
@@ -53,7 +60,7 @@
static VALUE
cr_surface_get_klass (cairo_surface_t *surface)
{
- VALUE klass = (VALUE)cairo_surface_get_user_data (surface, &klass_key);
+ VALUE klass = (VALUE)cairo_surface_get_user_data (surface, &cr_klass_key);
if (!klass)
{
rb_raise (rb_eArgError, "[BUG] uninitialized surface for Ruby");
@@ -65,11 +72,83 @@
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;
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_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);
+}
+
+static void
+cr_closure_free (void *closure)
+{
+ cr_closure_destroy ((cr_io_callback_closure_t *) closure);
+}
+
+static VALUE
cr_surface_io_func_rescue (VALUE io_closure)
{
cr_io_callback_closure_t *closure;
@@ -230,7 +309,22 @@
static VALUE
cr_surface_finish (VALUE self)
{
+ cr_io_callback_closure_t *closure;
+ closure = cairo_surface_get_user_data (_SELF, &cr_closure_key);
+
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);
+
cr_surface_check_status (_SELF);
return self;
}
@@ -244,6 +338,7 @@
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);
@@ -350,6 +445,7 @@
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);
@@ -448,148 +544,67 @@
return INT2NUM (cairo_image_surface_get_height (_SELF));
}
-#if CAIRO_HAS_PS_SURFACE
-/* PS-surface functions */
-static VALUE
-cr_ps_surface_create_for_stream (VALUE info)
-{
- VALUE self, input, width_in_points, height_in_points;
- cr_io_callback_closure_t closure;
- cairo_surface_t *surface;
-
- self = rb_ary_entry (info, 0);
- input = rb_ary_entry (info, 1);
- width_in_points = rb_ary_entry (info, 2);
- height_in_points = rb_ary_entry (info, 3);
-
- closure.target = input;
- closure.error = Qnil;
-
- surface = cairo_ps_surface_create_for_stream (cr_surface_write_func,
- (void *) &closure,
- NUM2DBL (width_in_points),
- NUM2DBL (height_in_points));
- if (!NIL_P (closure.error))
- rb_exc_raise (closure.error);
-
- return (VALUE)surface;
-}
-
-static VALUE
-cr_ps_surface_create (VALUE self, VALUE filename,
- VALUE width_in_points, VALUE height_in_points)
-{
- VALUE file, info;
-
- file = rb_file_open (StringValuePtr (filename), "rb");
- info = rb_ary_new3 (4, self, file, width_in_points, height_in_points);
- return rb_ensure (cr_ps_surface_create_for_stream, info,
- rb_io_close, file);
-}
-static VALUE
-cr_ps_surface_initialize (VALUE self, VALUE target,
- VALUE width_in_points, VALUE height_in_points)
-{
- cairo_surface_t *surface;
-
- if (rb_respond_to (target, cr_id_read))
- {
- VALUE info;
- info = rb_ary_new3 (4, self, target, width_in_points, height_in_points);
- surface = (cairo_surface_t *)cr_ps_surface_create_for_stream (info);
- }
- else
- {
- surface = (cairo_surface_t *)cr_ps_surface_create (self, target,
- width_in_points,
- height_in_points);
- }
-
- 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) \
+{ \
+ 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; \
+} \
+ \
+static VALUE \
+cr_ ## type ## _surface_set_dpi (VALUE self, VALUE x_dpi, VALUE y_dpi) \
+{ \
+ cairo_ ## type ## _surface_set_dpi (_SELF, \
+ NUM2DBL (x_dpi), \
+ NUM2DBL (y_dpi)); \
+ cr_surface_check_status (_SELF); \
+ return self; \
}
-static VALUE
-cr_ps_surface_set_dpi (VALUE self, VALUE x_dpi, VALUE y_dpi)
-{
- cairo_ps_surface_set_dpi (_SELF, NUM2DBL (x_dpi), NUM2DBL (y_dpi));
- cr_surface_check_status (_SELF);
- return self;
-}
+#if CAIRO_HAS_PS_SURFACE
+/* PS-surface functions */
+DEFINE_SURFACE(ps)
#endif
#if CAIRO_HAS_PDF_SURFACE
/* PDF-surface functions */
-static VALUE
-cr_pdf_surface_create_for_stream (VALUE info)
-{
- VALUE self, input, width_in_points, height_in_points;
- cr_io_callback_closure_t closure;
- cairo_surface_t *surface;
-
- self = rb_ary_entry (info, 0);
- input = rb_ary_entry (info, 1);
- width_in_points = rb_ary_entry (info, 2);
- height_in_points = rb_ary_entry (info, 3);
-
- closure.target = input;
- closure.error = Qnil;
-
- surface = cairo_pdf_surface_create_for_stream (cr_surface_write_func,
- (void *) &closure,
- NUM2DBL (width_in_points),
- NUM2DBL (height_in_points));
- if (!NIL_P (closure.error))
- rb_exc_raise (closure.error);
-
- return (VALUE)surface;
-}
-
-static VALUE
-cr_pdf_surface_create (VALUE self, VALUE filename,
- VALUE width_in_points, VALUE height_in_points)
-{
- VALUE file, info;
-
- file = rb_file_open (StringValuePtr (filename), "rb");
- info = rb_ary_new3 (4, self, file, width_in_points, height_in_points);
- return rb_ensure (cr_pdf_surface_create_for_stream, info,
- rb_io_close, file);
-}
-
-static VALUE
-cr_pdf_surface_initialize (VALUE self, VALUE target,
- VALUE width_in_points, VALUE height_in_points)
-{
- cairo_surface_t *surface;
-
- if (rb_respond_to (target, cr_id_read))
- {
- VALUE info;
- info = rb_ary_new3 (4, self, target, width_in_points, height_in_points);
- surface = (cairo_surface_t *)cr_pdf_surface_create_for_stream (info);
- }
- else
- {
- surface = (cairo_surface_t *)cr_pdf_surface_create (self, target,
- width_in_points,
- height_in_points);
- }
-
- cr_surface_check_status (surface);
- DATA_PTR (self) = surface;
- return Qnil;
-}
-
-static VALUE
-cr_pdf_surface_set_dpi (VALUE self, VALUE x_dpi, VALUE y_dpi)
-{
- cairo_pdf_surface_set_dpi (_SELF, NUM2DBL (x_dpi), NUM2DBL (y_dpi));
- cr_surface_check_status (_SELF);
- return self;
-}
+DEFINE_SURFACE(pdf)
#endif
void
@@ -597,6 +612,9 @@
{
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);
@@ -636,26 +654,31 @@
cr_image_surface_write_to_png_generic, 1);
#endif
-
+
+#define INIT_SURFACE(type, name) \
+ rb_cCairo_ ## name ## Surface = \
+ 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); \
+ rb_define_method (rb_cCairo_ ## name ## Surface, "set_dpi", \
+ cr_ ## type ## _surface_set_dpi, 2);
+
#if CAIRO_HAS_PS_SURFACE
/* PS-surface */
- rb_cCairo_PSSurface =
- rb_define_class_under (rb_mCairo, "PSSurface", rb_cCairo_Surface);
-
- rb_define_method (rb_cCairo_PSSurface, "initialize",
- cr_ps_surface_initialize, 3);
- rb_define_method (rb_cCairo_PSSurface, "set_dpi",
- cr_ps_surface_set_dpi, 2);
+ INIT_SURFACE(ps, PS)
+#else
+ rb_cCairo_PSSurface = Qnil;
#endif
#if CAIRO_HAS_PDF_SURFACE
/* PDF-surface */
- rb_cCairo_PDFSurface =
- rb_define_class_under (rb_mCairo, "PDFSurface", rb_cCairo_Surface);
-
- rb_define_method (rb_cCairo_PDFSurface, "initialize",
- cr_pdf_surface_initialize, 3);
- rb_define_method (rb_cCairo_PDFSurface, "set_dpi",
- cr_pdf_surface_set_dpi, 2);
+ INIT_SURFACE(pdf, PDF)
+#else
+ rb_cCairo_PDFSurface = Qnil;
#endif
}
- Previous message: [cairo-commit] rcairo ChangeLog,1.70,1.71
- Next message: [cairo-commit] rcairo/samples pdf.rb, 1.3, 1.4 pdf2.rb, NONE,
1.1 png.rb, 1.8, 1.9 ps.rb, 1.2, 1.3 ps2.rb, NONE, 1.1
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the cairo-commit
mailing list