[cairo-commit] rcairo/src cairo.c,NONE,1.1 extconf.rb,NONE,1.1 image.c,NONE,1.1 shared.h,NONE,1.1 xlib.c,NONE,1.1
Evan Martin
commit at pdx.freedesktop.org
Tue Oct 28 10:27:24 PST 2003
- Previous message: [cairo-commit] rcairo/gen gen.rb,NONE,1.1 gen_api_sig.rb,NONE,1.1 load_api.rb,NONE,1.1
- Next message: [cairo-commit] rcairo/tests spline,NONE,1.1 test-nox,NONE,1.1 text,NONE,1.1
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Committed by: martine
Update of /cvs/cairo/rcairo/src
In directory pdx:/tmp/cvs-serv31046/src
Added Files:
cairo.c extconf.rb image.c shared.h xlib.c
Log Message:
Initial import of Ruby/Cairo.
I just moved the code around a bit in anticipation of wanting to do it later,
and I haven't tested if it broke anything yet, so don't be surprised if it
doesn't quite build yet.
--- NEW FILE: cairo.c ---
/* ruby-cairo - Ruby bindings for Cairo.
* Copyright (C) 2003 Evan Martin <martine at danga.com>
*
* vim: tabstop=4 shiftwidth=4 noexpandtab :
*/
#include "shared.h"
VALUE mCairo, cCairo, cCairoSurface, cCairoMatrix;
cairo_t*
rcairo_get_cairo(VALUE vcairo) {
cairo_t *cr;
Data_Get_Struct(vcairo, cairo_t, cr);
return cr;
}
VALUE
rcairo_new() {
cairo_t *cr = cairo_create();
cairo_reference(cr);
return Data_Wrap_Struct(cCairo, NULL, cairo_destroy, cr);
}
static VALUE
rcairo_rcairo_new(VALUE class) {
return rcairo_new();
}
static VALUE
rcairo_dup(VALUE vself) {
VALUE vdest = rcairo_new();
cairo_copy(rcairo_get_cairo(vdest), rcairo_get_cairo(vself));
rb_iv_set(vdest, "@target_image", rb_iv_get(vself, "@target_image"));
return vdest;
}
static VALUE
rcairo_set_target_image(VALUE vself, VALUE vimage) {
RCairoImage *img;
img = rcairo_image_get_image(vimage);
rb_iv_set(vself, "@target_image", vimage);
cairo_set_target_image(rcairo_get_cairo(vself), img->data, img->format,
img->width, img->height, img->stride);
return Qnil;
}
static VALUE
rcairo_set_dash(VALUE vself, VALUE vdashes, VALUE offset) {
rb_notimplement();
return Qnil;
}
static VALUE
rcairo_run_pt_func(VALUE vself, VALUE pt, void (*f)(cairo_t*,double*,double*)) {
double x = NUM2DBL(rb_ary_entry(pt, 0));
double y = NUM2DBL(rb_ary_entry(pt, 1));
f(rcairo_get_cairo(vself), &x, &y);
return rb_ary_new3(2, rb_float_new(x), rb_float_new(y));
}
static VALUE
rcairo_transform_point(VALUE vself, VALUE pt) {
return rcairo_run_pt_func(vself, pt, cairo_transform_point);
}
static VALUE
rcairo_transform_distance(VALUE vself, VALUE pt) {
return rcairo_run_pt_func(vself, pt, cairo_transform_distance);
}
static VALUE
rcairo_inverse_transform_point(VALUE vself, VALUE pt) {
return rcairo_run_pt_func(vself, pt, cairo_inverse_transform_point);
}
static VALUE
rcairo_inverse_transform_distance(VALUE vself, VALUE pt) {
return rcairo_run_pt_func(vself, pt, cairo_inverse_transform_distance);
}
static VALUE
rcairo_text_extents(VALUE vself, VALUE text) {
double x, y, w, h, dx, dy;
cairo_text_extents(rcairo_get_cairo(vself), STR2CSTR(text),
&x, &y, &w, &h, &dx, &dy);
return rb_ary_new3(6, rb_float_new(x), rb_float_new(y),
rb_float_new(w), rb_float_new(h),
rb_float_new(dx), rb_float_new(dy));
}
/* Ruby-style functions. */
static VALUE
rcairo_stack(VALUE vself) {
cairo_t *cr = rcairo_get_cairo(vself);
cairo_save(cr);
rb_yield(Qnil);
cairo_restore(cr);
return Qnil;
}
static VALUE
rcairo_run_path_func(VALUE vself, void (*f)(cairo_t *cr)) {
cairo_t *cr = rcairo_get_cairo(vself);
if (rb_block_given_p()) {
cairo_new_path(cr);
rb_yield(Qnil);
}
f(cr);
return Qnil;
}
static VALUE
rcairo_stroke(VALUE vself) {
return rcairo_run_path_func(vself, cairo_stroke);
}
static VALUE
rcairo_fill(VALUE vself) {
return rcairo_run_path_func(vself, cairo_fill);
}
cairo_matrix_t*
rmatrix_get_matrix(VALUE vmatrix) {
cairo_matrix_t *cr;
Data_Get_Struct(vmatrix, cairo_matrix_t, cr);
return cr;
}
VALUE
rmatrix_new() {
cairo_matrix_t *cr = cairo_matrix_create();
//cairo_matrix_reference(cr);
return Data_Wrap_Struct(cCairoMatrix, NULL, cairo_matrix_destroy, cr);
}
static VALUE
rmatrix_rmatrix_new(VALUE class) {
return rmatrix_new();
}
cairo_surface_t*
rsurface_get_surface(VALUE vsurface) {
cairo_surface_t *cr;
Data_Get_Struct(vsurface, cairo_surface_t, cr);
return cr;
}
VALUE
rsurface_new_from(cairo_surface_t *surf) {
cairo_surface_reference(surf);
return Data_Wrap_Struct(cCairoSurface, NULL, cairo_surface_destroy, surf);
}
/*static VALUE
rcairo_surface_new_for_image(VALUE class, VALUE image) {
cairo_surface_t *surface;
rcairoImage *img;
Data_Get_Struct(image, rcairoImage, img);
surface = cairo_surface_create_for_image(img->data, img->format,
img->width, img->height, img->stride);
return Data_Wrap_Struct(cCairoSurface, NULL, cairo_surface_destroy, surface);
}*/
void
Init_cairo() {
mCairo = rb_define_module("Cairo");
cCairo = gen_Cairo();
rb_define_singleton_method(cCairo, "new", rcairo_rcairo_new, 0);
rb_define_method(cCairo, "dup", rcairo_dup, 0);
rb_define_method(cCairo, "target_image=", rcairo_set_target_image, 1);
rb_define_method(cCairo, "set_dash", rcairo_set_dash, 2);
rb_define_method(cCairo, "transform_point", rcairo_transform_point, 1);
rb_define_method(cCairo, "transform_distance", rcairo_transform_distance, 1);
rb_define_method(cCairo, "inverse_transform_point", rcairo_inverse_transform_point, 1);
rb_define_method(cCairo, "inverse_transform_distance", rcairo_inverse_transform_distance, 1);
rb_define_method(cCairo, "text_extents", rcairo_text_extents, 1);
rb_define_method(cCairo, "stack", rcairo_stack, 0);
rb_define_method(cCairo, "stroke", rcairo_stroke, 0);
rb_define_method(cCairo, "fill", rcairo_fill, 0);
cCairoMatrix = gen_CairoMatrix();
cCairoSurface = gen_CairoSurface();
xlib_init();
rcairo_image_init();
cCairoSurface = rb_define_class_under(mCairo, "Surface", rb_cObject);
//rb_define_singleton_method(cCairoSurface, "new_for_image", rcairo_surface_new_for_image, 1);
}
--- NEW FILE: extconf.rb ---
#!/usr/bin/env ruby
require 'mkmf'
$CFLAGS << " -g -Wall `pkg-config --cflags cairo`"
$LDFLAGS << " `pkg-config --libs cairo`"
create_makefile("cairo")
--- NEW FILE: image.c ---
/* vim: set ts=4 sw=4 noet : */
#include "shared.h"
VALUE cCairoImage;
VALUE eCairoImageFormat;
static void
rcairo_image_free(RCairoImage *img) {
free(img->data); free(img);
}
RCairoImage*
rcairo_image_get_image(VALUE vimage) {
RCairoImage *img;
Data_Get_Struct(vimage, RCairoImage, img);
return img;
}
static VALUE
rcairo_image_new(VALUE class, VALUE vformat, VALUE vwidth, VALUE vheight, VALUE vstride) {
int format = FIX2INT(vformat);
int bpp = 0;
int datasize;
RCairoImage *img;
/* XXX only supports one format. */
format = CAIRO_FORMAT_ARGB32;
switch (format) {
case CAIRO_FORMAT_ARGB32:
bpp = 32;
break;
default:
rb_raise(eCairoImageFormat, "unimplemented image format %d\n", format);
return Qnil;
}
img = malloc(sizeof(RCairoImage));
img->format = format;
img->width = FIX2INT(vwidth);
img->height = FIX2INT(vheight);
img->stride = FIX2INT(vstride);
datasize = img->stride * img->height * bpp/8;
img->data = malloc(datasize);
memset(img->data, 0, datasize);
return Data_Wrap_Struct(cCairoImage, NULL, rcairo_image_free, img);
}
static VALUE
rcairo_image_each_pixel(VALUE self) {
RCairoImage *img = rcairo_image_get_image(self);
unsigned int *data;
int x, y;
/* XXX assumes 32bpp format and stride == width. */
data = (unsigned int*)img->data;
for (y = 0; y < img->height; y++) {
for (x = 0; x < img->width; x++) {
rb_yield(rb_ary_new3(4, INT2FIX(x), INT2FIX(y), UINT2NUM(*data)));
data++;
}
}
return Qnil;
}
void
rcairo_image_init(void) {
cCairoImage = rb_define_class_under(mCairo, "Image", rb_cObject);
rb_define_singleton_method(cCairoImage, "new", rcairo_image_new, 4);
rb_define_method(cCairoImage, "each_pixel", rcairo_image_each_pixel, 0);
eCairoImageFormat = rb_define_class_under(mCairo, "ImageFormat", rb_eException);
}
--- NEW FILE: shared.h ---
/* ruby-cairo - Ruby bindings for Cairo.
* Copyright (C) 2003 Evan Martin <martine at danga.com>
*
* vim: tabstop=4 shiftwidth=4 noexpandtab :
*/
#include <ruby.h>
#include <cairo.h>
void xlib_init();
void cairo_xlib_init(void);
extern VALUE mCairo, cCairo, cCairoSurface, cCairoMatrix, cCairoImage;
extern VALUE cDisplay, eXlib;
typedef struct {
char *data;
cairo_format_t format;
int width, height, stride;
} RCairoImage;
VALUE gen_Cairo(void);
VALUE gen_CairoMatrix(void);
VALUE gen_CairoSurface(void);
VALUE rcairo_display_new();
Display* rcairo_display_get_display(VALUE rdpy);
VALUE rcairo_new();
cairo_t* rcairo_get_cairo(VALUE rcairo);
void rcairo_image_init(void);
RCairoImage* rcairo_image_get_image(VALUE vimage);
VALUE rmatrix_new();
cairo_matrix_t* rmatrix_get_matrix(VALUE vmatrix);
VALUE rsurface_new_from();
cairo_surface_t* rsurface_get_surface(VALUE rcairo);
--- NEW FILE: xlib.c ---
/* ruby-cairo - Ruby bindings for Cairo.
* Copyright (C) 2003 Evan Martin <martine at danga.com>
*
* vim: tabstop=4 shiftwidth=4 noexpandtab :
*/
#include "shared.h"
#include "cairo-xlib.h"
VALUE mXlib, eXlib, cDisplay, cWindow;
VALUE
rcairo_display_new() {
Display *dpy;
VALUE obj;
dpy = XOpenDisplay(NULL);
if (dpy == NULL) {
rb_raise(eXlib, "XOpenDisplay: Unable to open display");
return Qnil;
}
obj = Data_Wrap_Struct(cDisplay, 0, 0, dpy);
rb_iv_set(obj, "@windows", rb_hash_new());
rb_iv_set(obj, "@quit", Qfalse);
return obj;
}
Display*
rcairo_display_get_display(VALUE rdpy) {
Display *dpy;
Data_Get_Struct(rdpy, Display, dpy);
return dpy;
}
static VALUE
display_new(VALUE class) {
return rcairo_display_new();
}
static VALUE
display_xconnection(VALUE self) {
Display *dpy;
Data_Get_Struct(self, Display, dpy);
return INT2FIX(ConnectionNumber(dpy));
}
static VALUE
display_width(VALUE self) {
Display *dpy;
Data_Get_Struct(self, Display, dpy);
return INT2FIX(DisplayWidth(dpy, 0));
}
static VALUE
display_height(VALUE self) {
Display *dpy;
Data_Get_Struct(self, Display, dpy);
return INT2FIX(DisplayHeight(dpy, 0));
}
static void
redraw(VALUE vwin, Display *dpy, Window win) {
XClearWindow(dpy, win);
rb_funcall(vwin, rb_intern("draw"), 0);
}
static VALUE
display_loop(VALUE vself) {
Display *dpy = rcairo_display_get_display(vself);
XEvent xev;
VALUE vwindows, vwin;
vwindows = rb_iv_get(vself, "@windows");
while (rb_iv_get(vself, "@quit") == Qfalse) {
XNextEvent(dpy, &xev);
switch(xev.type) {
case KeyPress: {
XKeyEvent *kev = &xev.xkey;
unsigned int sym = XKeycodeToKeysym(dpy, kev->keycode, 0);
vwin = rb_hash_aref(vwindows, INT2FIX(kev->window));
if (vwin == Qnil)
continue;
if (sym > 255) sym = 0;
rb_funcall(vwin, rb_intern("keypress"), 1, INT2FIX(sym));
redraw(vwin, dpy, kev->window);
} break;
case ConfigureNotify: {
XConfigureEvent *cev = &xev.xconfigure;
vwin = rb_hash_aref(vwindows, INT2FIX(cev->window));
if (vwin == Qnil)
continue;
rb_iv_set(vwin, "@width", INT2FIX(cev->width));
rb_iv_set(vwin, "@height", INT2FIX(cev->height));
rb_funcall(vwin, rb_intern("resize"), 0);
} break;
case Expose: {
XExposeEvent *eev = &xev.xexpose;
vwin = rb_hash_aref(vwindows, INT2FIX(eev->window));
if (vwin == Qnil)
continue;
if (eev->count == 0)
redraw(vwin, dpy, eev->window);
} break;
}
}
XCloseDisplay(dpy);
return Qnil;
}
static VALUE
display_quit(VALUE vself) {
rb_iv_set(vself, "@quit", Qtrue);
return Qnil;
}
void
xlib_set_size_hints(Display *dpy, Window win, int width, int height) {
XSizeHints hnt = {0};
hnt.flags = USSize | PSize | PMinSize | PMaxSize;
hnt.width = width;
hnt.min_width = width;
hnt.max_width = width;
hnt.height = height;
hnt.min_height = height;
hnt.max_height = height;
XSetWMNormalHints(dpy, win, &hnt);
}
static VALUE
window_create(VALUE vdpy, VALUE vwidth, VALUE vheight, VALUE vbg) {
Display *dpy;
Window root, win;
int scr;
int width, height;
unsigned long color;
dpy = rcairo_display_get_display(vdpy);
XSynchronize(dpy, 1);
root = DefaultRootWindow(dpy);
scr = DefaultScreen(dpy);
width = FIX2INT(vwidth);
height = FIX2INT(vheight);
if (vbg == Qtrue)
color = WhitePixel(dpy, scr);
else
color = BlackPixel(dpy, scr);
win = XCreateSimpleWindow(dpy, root, 0, 0,
width, height, 0,
color, color);
XSelectInput(dpy, win,
KeyPressMask
|StructureNotifyMask
|ExposureMask);
XMapWindow(dpy, win);
return INT2FIX(win);
}
static VALUE
window_init(VALUE vself, VALUE vdpy, VALUE vwidth, VALUE vheight, VALUE vbg) {
VALUE vwin, vcairo;
rb_iv_set(vself, "@dpy", vdpy);
vwin = window_create(vdpy, vwidth, vheight, vbg);
rb_hash_aset(rb_iv_get(vdpy, "@windows"), vwin, vself);
rb_iv_set(vself, "@win", vwin);
vcairo = rcairo_new();
rb_iv_set(vself, "@cairo", vcairo);
cairo_set_target_drawable(rcairo_get_cairo(vcairo),
rcairo_display_get_display(vdpy),
FIX2INT(vwin));
return vself;
}
static VALUE
window_nop(VALUE vself) {
return Qnil;
}
void
xlib_init() {
VALUE mXlib = rb_define_module_under(mCairo, "Xlib");
eXlib = rb_define_class_under(mXlib, "Exception", rb_eException);
cDisplay = rb_define_class_under(mXlib, "Display", rb_cObject);
rb_define_singleton_method(cDisplay, "new", display_new, 0);
rb_define_method(cDisplay, "xconnection", display_xconnection, 0);
rb_define_method(cDisplay, "width", display_width, 0);
rb_define_method(cDisplay, "height", display_height, 0);
rb_define_method(cDisplay, "mainloop", display_loop, 0);
rb_define_method(cDisplay, "quit", display_quit, 0);
cWindow = rb_define_class_under(mXlib, "Window", rb_cObject);
rb_define_method(cWindow, "initialize", window_init, 4);
rb_define_method(cWindow, "draw", window_nop, -1);
rb_define_method(cWindow, "resize", window_nop, -1);
rb_define_method(cWindow, "keypress", window_nop, -1);
}
Display*
xlib_dpy_from_rb(VALUE display) {
Display *dpy;
Data_Get_Struct(display, Display, dpy);
return dpy;
}
- Previous message: [cairo-commit] rcairo/gen gen.rb,NONE,1.1 gen_api_sig.rb,NONE,1.1 load_api.rb,NONE,1.1
- Next message: [cairo-commit] rcairo/tests spline,NONE,1.1 test-nox,NONE,1.1 text,NONE,1.1
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the cairo-commit
mailing list