diff options
author | Olivier Andrieu <oandrieu@gmail.com> | 2005-12-13 22:42:02 +0000 |
---|---|---|
committer | Hezekiah M. Carty <hcarty@atmos.umd.edu> | 2009-06-18 14:01:08 -0400 |
commit | 567f826e1bff5834092632a179bfded62e78037d (patch) | |
tree | d32959d5166a29c6efed1e901f5065094e279862 | |
parent | 7c75f949a874e37c0725e22973228bf6b3ecb4ab (diff) |
Update for Gtk+ 2.8
* src/*lablgtk*: sync cairo_lablgtk module with the gdk_cairo_* API of GTK+ 2.8.
* test/*: adapt
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | configure.ac | 3 | ||||
-rw-r--r-- | src/cairo_lablgtk.ml | 15 | ||||
-rw-r--r-- | src/cairo_lablgtk.mli | 20 | ||||
-rw-r--r-- | src/ml_cairo_lablgtk.c | 281 | ||||
-rw-r--r-- | test/demo.ml | 4 | ||||
-rw-r--r-- | test/knockout.ml | 2 | ||||
-rw-r--r-- | test/spline.ml | 2 | ||||
-rw-r--r-- | test/text.ml | 5 |
9 files changed, 197 insertions, 139 deletions
@@ -4,6 +4,10 @@ Cairo_ps.set_dpi * src/Makefile, src*gtkcairo*: drop gtkcairo support. + + * src/*lablgtk*: sync cairo_lablgtk module with the gdk_cairo_* + API of GTK+ 2.8. + * test/*: adapt 2005-11-03 Olivier Andrieu <oliv__a@users.sourceforge.net> diff --git a/configure.ac b/configure.ac index f0b9d8b..cadbe62 100644 --- a/configure.ac +++ b/configure.ac @@ -10,8 +10,9 @@ PKG_CHECK_MODULES(CAIRO, cairo >= 1.0.0 freetype2) # Optional GTK support (for the X11 backend) AC_ARG_WITH(gtk, - AS_HELP_STRING([--with-gtk],[X11 backend support via GTK+ and LablGTK]), + AS_HELP_STRING([--with-gtk],[Cairo/GTK+ integration via LablGTK]), use_gtk=$withval, use_gtk=yes) +AC_ARG_VAR(LABLGTKDIR,[Location of the LablGTK library]) if test $use_gtk = yes ; then # Check for LablGTK diff --git a/src/cairo_lablgtk.ml b/src/cairo_lablgtk.ml index 07fd04a..1b29c0c 100644 --- a/src/cairo_lablgtk.ml +++ b/src/cairo_lablgtk.ml @@ -6,14 +6,9 @@ (* GNU Lesser General Public License version 2.1 (the "LGPL"). *) (**************************************************************************) -type surface = [`Any|`Xlib] Cairo.surface +external create : [> `drawable] Gobject.obj -> Cairo.t = "ml_gdk_cairo_create" +external set_source_color : Cairo.t -> Gdk.color -> unit = "ml_gdk_cairo_set_source_color" +external rectangle : Cairo.t -> Gdk.Rectangle.t -> unit = "ml_gdk_cairo_rectangle" +external region : Cairo.t -> Gdk.region -> unit = "ml_gdk_cairo_region" -external image_of_pixbuf : GdkPixbuf.pixbuf -> Cairo.image_surface = "ml_cairo_lablgtk_of_pixbuf" -external shuffle_pixels : GdkPixbuf.pixbuf -> unit = "ml_cairo_lablgtk_shuffle_pixels" - -external surface_create : [> `drawable] Gobject.obj -> surface = "ml_cairo_xlib_surface_create" -external surface_set_size : [> `Xlib] Cairo.surface -> int -> int -> unit = "ml_cairo_xlib_surface_set_size" -external surface_set_drawable : - [> `Xlib] Cairo.surface -> - [> `drawable] Gobject.obj -> - int -> int -> unit = "ml_cairo_xlib_surface_set_drawable" +external set_source_pixbuf : Cairo.t -> GdkPixbuf.pixbuf -> float -> float -> unit = "ml_gdk_cairo_set_source_pixbuf" diff --git a/src/cairo_lablgtk.mli b/src/cairo_lablgtk.mli index be85d38..bf34d6c 100644 --- a/src/cairo_lablgtk.mli +++ b/src/cairo_lablgtk.mli @@ -6,16 +6,16 @@ (* GNU Lesser General Public License version 2.1 (the "LGPL"). *) (**************************************************************************) -(** Xlib backend, via LablGTK *) +(** GTK/Cairo integration *) -type surface = [`Any|`Xlib] Cairo.surface +(** These functions are available with GTK+ 2.8. + For older versions of GTK+, an implementation is provided, except for [region]. -external image_of_pixbuf : GdkPixbuf.pixbuf -> Cairo.image_surface = "ml_cairo_lablgtk_of_pixbuf" -external shuffle_pixels : GdkPixbuf.pixbuf -> unit = "ml_cairo_lablgtk_shuffle_pixels" + cf. {{:"http://developer.gnome.org/doc/API/2.0/gdk/gdk-Cairo-Interaction.html"}Cairo Interaction} in the GDK Reference Manual. *) -external surface_create : [> `drawable] Gobject.obj -> surface = "ml_cairo_xlib_surface_create" -external surface_set_size : [> `Xlib] Cairo.surface -> int -> int -> unit = "ml_cairo_xlib_surface_set_size" -external surface_set_drawable : - [> `Xlib] Cairo.surface -> - [> `drawable] Gobject.obj -> - int -> int -> unit = "ml_cairo_xlib_surface_set_drawable" +external create : [> `drawable] Gobject.obj -> Cairo.t = "ml_gdk_cairo_create" +external set_source_color : Cairo.t -> Gdk.color -> unit = "ml_gdk_cairo_set_source_color" +external rectangle : Cairo.t -> Gdk.Rectangle.t -> unit = "ml_gdk_cairo_rectangle" +external region : Cairo.t -> Gdk.region -> unit = "ml_gdk_cairo_region" + +external set_source_pixbuf : Cairo.t -> GdkPixbuf.pixbuf -> float -> float -> unit = "ml_gdk_cairo_set_source_pixbuf" diff --git a/src/ml_cairo_lablgtk.c b/src/ml_cairo_lablgtk.c index 2d174de..338433f 100644 --- a/src/ml_cairo_lablgtk.c +++ b/src/ml_cairo_lablgtk.c @@ -7,142 +7,201 @@ /**************************************************************************/ #include "ml_cairo.h" -#if CAIRO_HAS_XLIB_SURFACE -# include <cairo-xlib.h> -#endif #include <gdk-pixbuf/gdk-pixbuf.h> #include <gdk/gdk.h> -#include <gdk/gdkx.h> #include "wrappers.h" #include "ml_gobject.h" #include "ml_gdkpixbuf.h" #include "ml_gdk.h" -CAMLprim value -ml_cairo_lablgtk_of_pixbuf (value pb) -{ - GdkPixbuf *pixbuf = GdkPixbuf_val(pb); - cairo_format_t format; - gboolean alpha = gdk_pixbuf_get_has_alpha(pixbuf); - int nchan = gdk_pixbuf_get_n_channels(pixbuf); - int bps = gdk_pixbuf_get_bits_per_sample(pixbuf); - cairo_surface_t *surf; - if ((nchan == 4) && (bps == 8) && alpha) - format = CAIRO_FORMAT_ARGB32; - else - caml_invalid_argument ("bad GdkPixbuf format"); +#if ! GTK_CHECK_VERSION(2,8,0) +/* For "old" versions of GTK+, provide the GTK+/cairo integration, + (stolen from GTK+) +*/ +#include <gdk/gdkx.h> +#ifdef CAIRO_HAS_XLIB_SURFACE +# include <cairo-xlib.h> +#else +# error "Cairo was not compiled with support for the xlib backend" +#endif - surf = cairo_image_surface_create_for_data (gdk_pixbuf_get_pixels (pixbuf), - format, - gdk_pixbuf_get_width(pixbuf), - gdk_pixbuf_get_height(pixbuf), - gdk_pixbuf_get_rowstride(pixbuf)); +static cairo_t * +gdk_cairo_create (GdkDrawable *target) +{ + int width, height; + int x_off=0, y_off=0; + cairo_t *cr; + cairo_surface_t *surface; + GdkDrawable *drawable = target; + GdkVisual *visual; + + g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL); + + if (GDK_IS_WINDOW(target)) { + /* query the window's backbuffer if it has one */ + GdkWindow *window = GDK_WINDOW(target); + gdk_window_get_internal_paint_info (window, + &drawable, &x_off, &y_off); + } + visual = gdk_drawable_get_visual (drawable); + gdk_drawable_get_size (drawable, &width, &height); + + if (visual) { + surface = cairo_xlib_surface_create (GDK_DRAWABLE_XDISPLAY (drawable), + GDK_DRAWABLE_XID (drawable), + GDK_VISUAL_XVISUAL (visual), + width, height); + } else if (gdk_drawable_get_depth (drawable) == 1) { + surface = cairo_xlib_surface_create_for_bitmap + (GDK_PIXMAP_XDISPLAY (drawable), + GDK_PIXMAP_XID (drawable), + GDK_SCREEN_XSCREEN (gdk_drawable_get_screen (drawable)), + width, height); + } else { + g_warning ("Using Cairo rendering requires the drawable argument to\n" + "have a specified colormap. All windows have a colormap,\n" + "however, pixmaps only have colormap by default if they\n" + "were created with a non-NULL window argument. Otherwise\n" + "a colormap must be set on them with " + "gdk_drawable_set_colormap"); + return NULL; + } + cairo_surface_set_device_offset (surface, -x_off, -y_off); - ml_cairo_surface_set_image_data (surf, pb); + cr = cairo_create (surface); + cairo_surface_destroy (surface); - return Val_cairo_surface_t (surf); + return cr; } -CAMLprim value -ml_cairo_lablgtk_shuffle_pixels (value pb) +static void +gdk_cairo_set_source_color (cairo_t *cr, + GdkColor *color) { - GdkPixbuf *pixbuf = GdkPixbuf_val(pb); - guint w, h, s, i, j; - guchar *pixels, *p; - - g_return_val_if_fail (gdk_pixbuf_get_has_alpha(pixbuf) && - (gdk_pixbuf_get_n_channels(pixbuf) == 4) && - (gdk_pixbuf_get_bits_per_sample(pixbuf) == 8), Val_unit); - - w = gdk_pixbuf_get_width (pixbuf); - h = gdk_pixbuf_get_height (pixbuf); - s = gdk_pixbuf_get_rowstride (pixbuf); - pixels = gdk_pixbuf_get_pixels (pixbuf); - - for (i=0; i<h; i++) { - p = pixels; - for (j=0; j<w; j++) { - guchar red = p[0]; - p[0] = p[2]; - p[2] = red; - p += 4; - } - pixels += s; - } - - return Val_unit; + g_return_if_fail (cr != NULL); + g_return_if_fail (color != NULL); + + cairo_set_source_rgb (cr, + color->red / 65535., + color->green / 65535., + color->blue / 65535.); } - -#if CAIRO_HAS_XLIB_SURFACE -/* copied from pycairo, who got it from GTK+ */ -static cairo_surface_t * -ml_gdk_cairo_surface_create (GdkDrawable *target) +static void +gdk_cairo_rectangle (cairo_t *cr, + GdkRectangle *rectangle) { - int width, height; - int x_off=0, y_off=0; - cairo_surface_t *surface; - GdkDrawable *drawable = target; - GdkVisual *visual; - - if (GDK_IS_WINDOW(target)) { - /* query the window's backbuffer if it has one */ - GdkWindow *window = GDK_WINDOW(target); - gdk_window_get_internal_paint_info (window, - &drawable, &x_off, &y_off); - } - visual = gdk_drawable_get_visual (drawable); - gdk_drawable_get_size (drawable, &width, &height); - - if (visual) { - surface = cairo_xlib_surface_create (GDK_DRAWABLE_XDISPLAY (drawable), - GDK_DRAWABLE_XID (drawable), - GDK_VISUAL_XVISUAL (visual), - width, height); - } else if (gdk_drawable_get_depth (drawable) == 1) { - surface = cairo_xlib_surface_create_for_bitmap - (GDK_PIXMAP_XDISPLAY (drawable), - GDK_PIXMAP_XID (drawable), - GDK_SCREEN_XSCREEN (gdk_drawable_get_screen (drawable)), - width, height); - } else { - g_warning ("Using Cairo rendering requires the drawable argument to\n" - "have a specified colormap. All windows have a colormap,\n" - "however, pixmaps only have colormap by default if they\n" - "were created with a non-NULL window argument. Otherwise\n" - "a colormap must be set on them with " - "gdk_drawable_set_colormap"); - return NULL; - } - cairo_surface_set_device_offset (surface, -x_off, -y_off); - return surface; + g_return_if_fail (cr != NULL); + g_return_if_fail (rectangle != NULL); + + cairo_rectangle (cr, + rectangle->x, rectangle->y, + rectangle->width, rectangle->height); } -CAMLprim value -ml_cairo_xlib_surface_create (value d) +static void +gdk_cairo_region (cairo_t *cr, + GdkRegion *region) { - return Val_cairo_surface_t (ml_gdk_cairo_surface_create (GdkDrawable_val(d))); + caml_failwith("Cairo_lablgtk.region is unsupported with this version of GTK+"); } -ML_3 (cairo_xlib_surface_set_size, cairo_surface_t_val, Int_val, Int_val, Unit) - -CAMLprim value -ml_cairo_xlib_surface_set_drawable (value s, value d, value w, value h) +static void +gdk_cairo_set_source_pixbuf (cairo_t *cr, + GdkPixbuf *pixbuf, + double pixbuf_x, + double pixbuf_y) { - cairo_xlib_surface_set_drawable (cairo_surface_t_val (s), - GDK_DRAWABLE_XID (GdkDrawable_val (d)), - Int_val (w), - Int_val (h)); - return Val_unit; -} + gint width = gdk_pixbuf_get_width (pixbuf); + gint height = gdk_pixbuf_get_height (pixbuf); + guchar *gdk_pixels = gdk_pixbuf_get_pixels (pixbuf); + int gdk_rowstride = gdk_pixbuf_get_rowstride (pixbuf); + int n_channels = gdk_pixbuf_get_n_channels (pixbuf); + guchar *cairo_pixels; + cairo_format_t format; + cairo_surface_t *surface; + static const cairo_user_data_key_t key; + int j; -#else + if (n_channels == 3) + format = CAIRO_FORMAT_RGB24; + else + format = CAIRO_FORMAT_ARGB32; + + cairo_pixels = g_malloc (4 * width * height); + surface = cairo_image_surface_create_for_data ((unsigned char *)cairo_pixels, + format, + width, height, 4 * width); + cairo_surface_set_user_data (surface, &key, + cairo_pixels, (cairo_destroy_func_t)g_free); + + for (j = height; j; j--) + { + guchar *p = gdk_pixels; + guchar *q = cairo_pixels; + + if (n_channels == 3) + { + guchar *end = p + 3 * width; + + while (p < end) + { +#if G_BYTE_ORDER == G_LITTLE_ENDIAN + q[0] = p[2]; + q[1] = p[1]; + q[2] = p[0]; +#else + q[1] = p[0]; + q[2] = p[1]; + q[3] = p[2]; +#endif + p += 3; + q += 4; + } + } + else + { + guchar *end = p + 4 * width; + guint t1,t2,t3; + +#define MULT(d,c,a,t) G_STMT_START { t = c * a; d = ((t >> 8) + t) >> 8; } G_STMT_END + + while (p < end) + { +#if G_BYTE_ORDER == G_LITTLE_ENDIAN + MULT(q[0], p[2], p[3], t1); + MULT(q[1], p[1], p[3], t2); + MULT(q[2], p[0], p[3], t3); + q[3] = p[3]; +#else + q[0] = p[3]; + MULT(q[1], p[0], p[3], t1); + MULT(q[2], p[1], p[3], t2); + MULT(q[3], p[2], p[3], t3); +#endif + + p += 4; + q += 4; + } + +#undef MULT + } + + gdk_pixels += gdk_rowstride; + cairo_pixels += 4 * width; + } + + cairo_set_source_surface (cr, surface, pixbuf_x, pixbuf_y); + cairo_surface_destroy (surface); +} -Cairo_Unsupported(cairo_xlib_surface_create, "Xlib backend not supported"); -Cairo_Unsupported(cairo_xlib_surface_set_size, "Xlib backend not supported"); -Cairo_Unsupported(cairo_xlib_surface_set_drawable, "Xlib backend not supported"); +#endif /* GTK_CHECK_VERSION(2,8,0) */ -#endif /* CAIRO_HAS_XLIB_SURFACE */ +wML_1(gdk_cairo_create, GdkDrawable_val, Val_cairo_t) +wML_2(gdk_cairo_set_source_color, cairo_t_val, GdkColor_val, Unit) +wML_2(gdk_cairo_rectangle, cairo_t_val, GdkRectangle_val, Unit) +wML_2(gdk_cairo_region, cairo_t_val, GdkRegion_val, Unit) +wML_4(gdk_cairo_set_source_pixbuf, cairo_t_val, GdkPixbuf_val, Double_val, Double_val, Unit) diff --git a/test/demo.ml b/test/demo.ml index f04e982..656cfba 100644 --- a/test/demo.ml +++ b/test/demo.ml @@ -64,7 +64,7 @@ let redraw (px : GDraw.pixmap) = let width, height = px#size in px#rectangle ~x:0 ~y:0 ~width ~height ~filled:true () end ; - let cr = Cairo.create (Cairo_lablgtk.surface_create px#pixmap) in + let cr = Cairo_lablgtk.create px#pixmap in Cairo.set_source_rgb cr 1. 1. 1. ; Cairo.save cr ; begin @@ -112,7 +112,7 @@ let main () = let px = GDraw.pixmap ~width:400 ~height:500 ~window:w () in begin try redraw px with Cairo.Error _ -> prerr_endline "Cairo is unhappy" end ; - let img = GMisc.pixmap px ~packing:w#add () in + ignore (GMisc.pixmap px ~packing:w#add ()) ; w#show () ; GMain.main () diff --git a/test/knockout.ml b/test/knockout.ml index 88e7c43..fa6d15d 100644 --- a/test/knockout.ml +++ b/test/knockout.ml @@ -103,7 +103,7 @@ let draw c width height = Cairo.paint c let expose d_area ev = - let c = Cairo.create (Cairo_lablgtk.surface_create d_area#misc#window) in + let c = Cairo_lablgtk.create d_area#misc#window in let allocation = d_area#misc#allocation in draw c allocation.Gtk.width allocation.Gtk.height ; true diff --git a/test/spline.ml b/test/spline.ml index 8f3fcd1..c5b7c84 100644 --- a/test/spline.ml +++ b/test/spline.ml @@ -115,7 +115,7 @@ let draw_spline cr spl = let paint spl = - let cr = Cairo.create (Cairo_lablgtk.surface_create spl.pm#pixmap) in + let cr = Cairo_lablgtk.create spl.pm#pixmap in spl.pm#rectangle ~x:0 ~y:0 ~width:spl.width ~height:spl.height ~filled:true () ; Cairo.set_source_rgb cr 0. 0. 0. ; diff --git a/test/text.ml b/test/text.ml index 80f5c5e..0e74220 100644 --- a/test/text.ml +++ b/test/text.ml @@ -66,7 +66,7 @@ let draw cr w h = Cairo.select_font_face cr "serif" Cairo.FONT_SLANT_NORMAL Cairo.FONT_WEIGHT_NORMAL ; Cairo.set_font_size cr 40. ; - let { Cairo.font_height = height } as f_ext = + let { Cairo.font_height = height } = Cairo.font_extents cr in let glyphs = @@ -125,8 +125,7 @@ let main () = w#connect#destroy GMain.quit ; let p = GDraw.pixmap ~width ~height ~window:w () in - let s = Cairo_lablgtk.surface_create p#pixmap in - let cr = Cairo.create s in + let cr = Cairo_lablgtk.create p#pixmap in draw cr (float width) (float height) ; GMisc.pixmap p ~packing:w#add () ; |