diff options
Diffstat (limited to 'src/ml_cairo_lablgtk.c')
-rw-r--r-- | src/ml_cairo_lablgtk.c | 121 |
1 files changed, 58 insertions, 63 deletions
diff --git a/src/ml_cairo_lablgtk.c b/src/ml_cairo_lablgtk.c index 7a87d9a..9d3521b 100644 --- a/src/ml_cairo_lablgtk.c +++ b/src/ml_cairo_lablgtk.c @@ -6,52 +6,50 @@ /* GNU Lesser General Public License version 2.1 (the "LGPL"). */ /**************************************************************************/ -#include <gdk-pixbuf/gdk-pixbuf.h> -#include <gdk/gdkx.h> - -#include <cairo.h> -#ifdef CAIRO_HAS_XLIB_SURFACE +#include "ml_cairo.h" +#if CAIRO_HAS_XLIB_SURFACE # include <cairo-xlib.h> #endif -#include <caml/mlvalues.h> -#include <caml/alloc.h> +#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" -#include "ml_cairo.h" -#include "ml_cairo_status.h" - CAMLprim value -cairo_lablgtk_of_pixbuf(value pb) +ml_cairo_lablgtk_of_pixbuf (value pb) { - value v; + static const cairo_user_data_key_t pixbuf_key; + 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 - failwith("bad GdkPixbuf format"); + caml_invalid_argument ("bad GdkPixbuf format"); - v = alloc_small(5, 0); - Field(v, 0) = Val_bp(gdk_pixbuf_get_pixels(pixbuf)); - Field(v, 1) = Val_cairo_format_t(format); - Field(v, 2) = Val_int(gdk_pixbuf_get_width(pixbuf)); - Field(v, 3) = Val_int(gdk_pixbuf_get_height(pixbuf)); - Field(v, 4) = Val_int(gdk_pixbuf_get_rowstride(pixbuf)); + 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)); - return v; + ml_cairo_surface_set_user_data (surf, &pixbuf_key, ml_cairo_make_root (pb)); + + return Val_cairo_surface_t (surf); } CAMLprim value -cairo_lablgtk_shuffle_pixels(value pb) +ml_cairo_lablgtk_shuffle_pixels (value pb) { GdkPixbuf *pixbuf = GdkPixbuf_val(pb); guint w, h, s, i, j; @@ -61,10 +59,10 @@ cairo_lablgtk_shuffle_pixels(value pb) (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); + 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; @@ -81,53 +79,50 @@ cairo_lablgtk_shuffle_pixels(value pb) } -#ifdef CAIRO_HAS_XLIB_SURFACE +#if CAIRO_HAS_XLIB_SURFACE CAMLprim value -cairo_lablgtk_surface_create_for_drawable(value d, value fmt) +ml_cairo_xlib_surface_create (value d) { - GdkDrawable *draw = GdkDrawable_val(d); - cairo_surface_t *s; - - s = cairo_xlib_surface_create ( - GDK_DRAWABLE_XDISPLAY(draw), - GDK_DRAWABLE_XID(draw), - GDK_VISUAL_XVISUAL(gdk_drawable_get_visual(draw)), - cairo_format_t_val(fmt), - GDK_COLORMAP_XCOLORMAP(gdk_drawable_get_colormap(draw))); - return Val_cairo_surface_t(s); -} + static const cairo_user_data_key_t drawable_key; -CAMLprim value -cairo_lablgtk_set_target_drawable(value cr, value d) -{ - cairo_t *c = cairo_t_val(cr); - GdkDrawable *draw = GdkDrawable_val(d); - GdkDrawable *real_drawable; - gint x_offset, y_offset; - - if (GDK_IS_WINDOW(draw)) - gdk_window_get_internal_paint_info(GDK_WINDOW(draw), - &real_drawable, - &x_offset, &y_offset); + cairo_surface_t *surface; + gint width, height; + GdkDrawable *drawable = GdkDrawable_val(d); + GdkVisual *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), + width, height); else { - real_drawable = draw; - x_offset = 0; - y_offset = 0; + 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"); + surface = NULL; } - - cairo_set_target_drawable(c, - GDK_DRAWABLE_XDISPLAY(real_drawable), - GDK_DRAWABLE_XID(real_drawable)); - check_cairo_status(cr); - cairo_translate(c, -x_offset, -y_offset); - check_cairo_status(cr); - return Val_unit; + if (surface != NULL) + ml_cairo_surface_set_user_data (surface, &drawable_key, ml_cairo_make_root (d)); + + return Val_cairo_surface_t (surface); } +ML_3 (cairo_xlib_surface_set_size, cairo_surface_t_val, Int_val, Int_val, Unit) + #else -Unsupported(cairo_lablgtk_surface_create_for_drawable) -Unsupported(cairo_lablgtk_set_target_drawable) +Cairo_Unsupported(cairo_xlib_surface_create, "Xlib backend not supported"); +Cairo_Unsupported(cairo_xlib_surface_set_size, "Xlib backend not supported"); #endif /* CAIRO_HAS_XLIB_SURFACE */ |