summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlivier Andrieu <oandrieu@gmail.com>2005-12-13 22:42:02 +0000
committerHezekiah M. Carty <hcarty@atmos.umd.edu>2009-06-18 14:01:08 -0400
commit567f826e1bff5834092632a179bfded62e78037d (patch)
treed32959d5166a29c6efed1e901f5065094e279862
parent7c75f949a874e37c0725e22973228bf6b3ecb4ab (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--ChangeLog4
-rw-r--r--configure.ac3
-rw-r--r--src/cairo_lablgtk.ml15
-rw-r--r--src/cairo_lablgtk.mli20
-rw-r--r--src/ml_cairo_lablgtk.c281
-rw-r--r--test/demo.ml4
-rw-r--r--test/knockout.ml2
-rw-r--r--test/spline.ml2
-rw-r--r--test/text.ml5
9 files changed, 197 insertions, 139 deletions
diff --git a/ChangeLog b/ChangeLog
index 562562f..fa59f49 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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 () ;