[cairo-commit] cairo-ocaml/src ml_cairo_lablgtk.c, 1.13,
1.14 cairo_lablgtk.mli, 1.6, 1.7 cairo_lablgtk.ml, 1.4, 1.5
Olivier Andrieu
commit at pdx.freedesktop.org
Tue Dec 13 14:42:04 PST 2005
- Previous message: [cairo-commit] cairo-ocaml config.make.in,1.5,1.6
- Next message: [cairo-commit] cairo-ocaml/test text.ml, 1.3, 1.4 spline.ml, 1.5,
1.6 knockout.ml, 1.5, 1.6 demo.ml, 1.3, 1.4
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Committed by: oandrieu
Update of /cvs/cairo/cairo-ocaml/src
In directory gabe:/tmp/cvs-serv6245/src
Modified Files:
ml_cairo_lablgtk.c cairo_lablgtk.mli cairo_lablgtk.ml
Log Message:
* src/*lablgtk*: sync cairo_lablgtk module with the gdk_cairo_* API of GTK+ 2.8.
* test/*: adapt
Index: ml_cairo_lablgtk.c
===================================================================
RCS file: /cvs/cairo/cairo-ocaml/src/ml_cairo_lablgtk.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- ml_cairo_lablgtk.c 10 Aug 2005 23:45:15 -0000 1.13
+++ ml_cairo_lablgtk.c 13 Dec 2005 22:42:02 -0000 1.14
@@ -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");
- 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));
-
- ml_cairo_surface_set_image_data (surf, pb);
-
- return Val_cairo_surface_t (surf);
-}
+#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
-CAMLprim value
-ml_cairo_lablgtk_shuffle_pixels (value pb)
+static cairo_t *
+gdk_cairo_create (GdkDrawable *target)
{
- GdkPixbuf *pixbuf = GdkPixbuf_val(pb);
- guint w, h, s, i, j;
- guchar *pixels, *p;
+ 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_pixbuf_get_has_alpha(pixbuf) &&
- (gdk_pixbuf_get_n_channels(pixbuf) == 4) &&
- (gdk_pixbuf_get_bits_per_sample(pixbuf) == 8), Val_unit);
+ g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
- w = gdk_pixbuf_get_width (pixbuf);
- h = gdk_pixbuf_get_height (pixbuf);
- s = gdk_pixbuf_get_rowstride (pixbuf);
- pixels = gdk_pixbuf_get_pixels (pixbuf);
+ 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);
- 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;
+ 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 Val_unit;
-}
+ cr = cairo_create (surface);
+ cairo_surface_destroy (surface);
+ return cr;
+}
-#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_set_source_color (cairo_t *cr,
+ GdkColor *color)
{
- int width, height;
- int x_off=0, y_off=0;
- cairo_surface_t *surface;
- GdkDrawable *drawable = target;
- GdkVisual *visual;
+ 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 (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);
+static void
+gdk_cairo_rectangle (cairo_t *cr,
+ GdkRectangle *rectangle)
+{
+ g_return_if_fail (cr != NULL);
+ g_return_if_fail (rectangle != NULL);
- 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;
+ 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_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");
+ 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);
-#endif /* CAIRO_HAS_XLIB_SURFACE */
+ 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);
+}
+
+#endif /* GTK_CHECK_VERSION(2,8,0) */
+
+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)
Index: cairo_lablgtk.mli
===================================================================
RCS file: /cvs/cairo/cairo-ocaml/src/cairo_lablgtk.mli,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- cairo_lablgtk.mli 10 Aug 2005 23:45:15 -0000 1.6
+++ cairo_lablgtk.mli 13 Dec 2005 22:42:02 -0000 1.7
@@ -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"
Index: cairo_lablgtk.ml
===================================================================
RCS file: /cvs/cairo/cairo-ocaml/src/cairo_lablgtk.ml,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- cairo_lablgtk.ml 10 Aug 2005 23:45:15 -0000 1.4
+++ cairo_lablgtk.ml 13 Dec 2005 22:42:02 -0000 1.5
@@ -6,14 +6,9 @@
(* GNU Lesser General Public License version 2.1 (the "LGPL"). *)
(**************************************************************************)
-type surface = [`Any|`Xlib] Cairo.surface
-
-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 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 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"
- Previous message: [cairo-commit] cairo-ocaml config.make.in,1.5,1.6
- Next message: [cairo-commit] cairo-ocaml/test text.ml, 1.3, 1.4 spline.ml, 1.5,
1.6 knockout.ml, 1.5, 1.6 demo.ml, 1.3, 1.4
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the cairo-commit
mailing list