com gtk/php-gtk: Ported pixbufdemo from c sources to php-gtk. Unfortunately, php segfaults when trying to execute it. It does not segfault when disabling the draw_rgb_image_dithalign me thod in line #72, e.g. by adding a (false &&) to line #71: demos/apple-r ed.png demos/background.jpg demos/gnome-applets.png demos/gnome-calendar.png demos/gnome-foot.png demos/ gnome-gimp.png demos/gnome-gmush.png demos/gnome-gsame .png demos/gnu-keys.png demos/pixbu

[email protected] (David Soria Parra) Sun, 05 Feb 2006 08:07:39 +0000
Newsgroups php.gtk.cvs
Message-ID <[email protected]>
Commit:    80b3c121ca776d616f31d1f1420ec15ad55f00f9
Author:    Christian Weiske <[email protected]>         Sun, 5 Feb 2006 08:07:39 +0000
Parents:   37a437df96d4ada065e62e2f4f013d86423b95f3
Branches:  master

Link:       http://git.php.net/?p=gtk/php-gtk.git;a=commitdiff;h=80b3c121ca776d616f31d1f1420ec15ad55f00f9

Log:
Ported pixbufdemo from c sources to php-gtk.
Unfortunately, php segfaults when trying to execute it.
It does not segfault when disabling the draw_rgb_image_dithalign
method in line #72, e.g. by adding a (false &&) to line #71

Andrei, could you have a look into it or tell me how to debug correctly
- I compiled php and php-gtk2 with debugging support, but a
"gdb php pixbuf-demo.php" gives me the message that it's not a core dump
and can't be read (file format not recognized)

Bugs:
https://bugs.php.net/72
https://bugs.php.net/71

Changed paths:
  A  demos/apple-red.png
  A  demos/background.jpg
  A  demos/gnome-applets.png
  A  demos/gnome-calendar.png
  A  demos/gnome-foot.png
  A  demos/gnome-gimp.png
  A  demos/gnome-gmush.png
  A  demos/gnome-gsame.png
  A  demos/gnu-keys.png
  A  demos/pixbuf-demo.php
  M  ext/gtk+/gdk.overrides


Diff:
80b3c121ca776d616f31d1f1420ec15ad55f00f9
diff --git a/demos/apple-red.png b/demos/apple-red.png
new file mode 100644
index 0000000..b0a24e9
Binary files /dev/null and b/demos/apple-red.png differ
diff --git a/demos/background.jpg b/demos/background.jpg
new file mode 100644
index 0000000..86c006a
Binary files /dev/null and b/demos/background.jpg differ
diff --git a/demos/gnome-applets.png b/demos/gnome-applets.png
new file mode 100644
index 0000000..8d3549e
Binary files /dev/null and b/demos/gnome-applets.png differ
diff --git a/demos/gnome-calendar.png b/demos/gnome-calendar.png
new file mode 100644
index 0000000..889f329
Binary files /dev/null and b/demos/gnome-calendar.png differ
diff --git a/demos/gnome-foot.png b/demos/gnome-foot.png
new file mode 100644
index 0000000..0476658
Binary files /dev/null and b/demos/gnome-foot.png differ
diff --git a/demos/gnome-gimp.png b/demos/gnome-gimp.png
new file mode 100644
index 0000000..f6bbc6d
Binary files /dev/null and b/demos/gnome-gimp.png differ
diff --git a/demos/gnome-gmush.png b/demos/gnome-gmush.png
new file mode 100644
index 0000000..0a4b0d0
Binary files /dev/null and b/demos/gnome-gmush.png differ
diff --git a/demos/gnome-gsame.png b/demos/gnome-gsame.png
new file mode 100644
index 0000000..01c0611
Binary files /dev/null and b/demos/gnome-gsame.png differ
diff --git a/demos/gnu-keys.png b/demos/gnu-keys.png
new file mode 100644
index 0000000..58a3377
Binary files /dev/null and b/demos/gnu-keys.png differ
diff --git a/demos/pixbuf-demo.php b/demos/pixbuf-demo.php
new file mode 100644
index 0000000..bb890b1
--- /dev/null
+++ b/demos/pixbuf-demo.php
@@ -0,0 +1,160 @@
+<?php
+define('FRAME_DELAY', 50);
+define('BACKGROUND_NAME', "background.jpg");
+
+$image_names = array(
+"apple-red.png",
+"gnome-applets.png",
+"gnome-calendar.png",
+"gnome-foot.png",
+"gnome-gmush.png",
+"gnome-gimp.png",
+"gnome-gsame.png",
+"gnu-keys.png"
+);
+
+define('N_IMAGES', count($image_names));
+define('CYCLE_LEN', 60);
+
+//Drawing area
+$da = null;
+
+//GdkPixbuf
+$frame;
+
+/* Background image */
+//GdkPixbuf
+$background;
+
+//int
+$back_width; $back_height;
+
+/* Images */
+//GdkPixbuf
+$images = array();
+
+function load_pixbufs()
+{
+    global $background, $back_width, $back_height, $images, $image_names;
+
+    $i = 0;
+    /* We pass NULL for the error return location, we don't care
+     * about the error message.
+     */
+    $background = GdkPixbuf::new_from_file(BACKGROUND_NAME);
+    if (!$background) {
+        return false;
+    }
+
+    $back_width = $background->get_width();
+    $back_height = $background->get_height();
+
+    for ($i = 0; $i < N_IMAGES; $i++) {
+        $images[$i] = GdkPixbuf::new_from_file($image_names[$i]);
+        if (!$images[$i])
+            return false;
+    }
+
+    return true;
+}
+
+/* Expose callback for the drawing area */
+function expose_cb(GtkWidget $widget, $event, $data = null)
+{
+    global $frame, $window;
+
+    $rowstride = $frame->get_rowstride();
+
+    //area.x area.y
+    $pixels = $frame->get_pixels() + $rowstride * $event->area->y + $event->area->x * 3;
+
+    if ($window->window !== null) {
+        $window->window->draw_rgb_image_dithalign(
+        $widget->style->black_gc,
+        $event->area->x, $event->area->y,
+        $event->area->width, $event->area->height,
+        Gdk::RGB_DITHER_NORMAL,
+        $pixels, $rowstride,
+        $event->area->x, $event->area->y);
+    }
+
+    return true;
+}
+
+
+/* Timeout handler to regenerate the frame */
+function timeout()
+{
+    global $da, $background, $back_width, $back_height, $frame, $images, $frame_num;
+
+    $background->copy_area(0, 0, $back_width, $back_height, $frame, 0, 0);
+
+    $f = ($frame_num % CYCLE_LEN) / CYCLE_LEN;
+
+    $xmid = $back_width / 2.0;
+    $ymid = $back_height / 2.0;
+
+    $radius = min($xmid, $ymid) / 2.0;
+
+    for ($i = 0; $i < N_IMAGES; $i++) {
+        $ang = 2.0 * pi() * $i / N_IMAGES - $f * 2.0 * pi();
+
+        $iw = $images[$i]->get_width();
+        $ih = $images[$i]->get_height();
+
+        $r = $radius + ($radius / 3.0) * sin($f * 2.0 * pi());
+
+        $xpos = floor ($xmid + $r * cos($ang) - $iw / 2.0 + 0.5);
+        $ypos = floor ($ymid + $r * sin($ang) - $ih / 2.0 + 0.5);
+
+        $k = ($i & 1) ? sin($f * 2.0 * pi()) : cos($f * 2.0 * pi());
+        $k = 2.0 * $k * $k;
+        $k = max(0.25, $k);
+
+        $r1 = new GdkRectangle($xpos, $ypos, $iw * $k, $ih * $k);
+        $r2 = new GdkRectangle(0, 0, $back_width, $back_height);
+
+        $dest = $r1->intersect($r2);
+        $images[$i]->composite(
+            $frame,
+            $dest->x, $dest->y,
+            $dest->width, $dest->height,
+            $xpos, $ypos,
+            $k, $k,
+            Gdk::INTERP_NEAREST,
+            (($i & 1)
+            ? max(127, abs(255 * sin($f * 2.0 * pi())))
+            : max(127, abs(255 * cos($f * 2.0 * pi())))));
+    }
+
+    $da->queue_draw();
+
+    $frame_num++;
+    return true;
+}
+
+$timeout_id = 0;
+
+//pixbuf_init ();
+
+if (!load_pixbufs()) {
+    die("main(): Could not load all the pixbufs!");
+}
+
+$frame = new GdkPixbuf(Gdk::COLORSPACE_RGB, false, 8, $back_width, $back_height);
+$window = new GtkWindow(Gtk::WINDOW_TOPLEVEL);
+
+$window->set_size_request($back_width, $back_height);
+$window->set_resizable(false);
+$window->connect_simple('destroy', array('gtk', 'main_quit'));
+
+$da = new GtkDrawingArea();
+$da->connect('expose_event', 'expose_cb');
+
+$window->add($da);
+
+Gtk::timeout_add(FRAME_DELAY, 'timeout');
+
+$window->show_all();
+Gtk::main();
+?>
\ No newline at end of file
diff --git a/ext/gtk+/gdk.overrides b/ext/gtk+/gdk.overrides
index 732b82d..677b2a8 100644
--- a/ext/gtk+/gdk.overrides
+++ b/ext/gtk+/gdk.overrides
@@ -948,6 +948,43 @@ PHP_METHOD
 
 %% {{{ GdkPixbuf
 
+
+%%
+add-arginfo GdkPixbuf __construct
+static
+ZEND_BEGIN_ARG_INFO(ARGINFO_NAME, 0)
+    ZEND_ARG_INFO(0, colorspace)
+    ZEND_ARG_INFO(0, has_alpha)
+    ZEND_ARG_INFO(0, bits_per_sample)
+    ZEND_ARG_INFO(0, width)
+    ZEND_ARG_INFO(0, height)
+ZEND_END_ARG_INFO();
+
+%% override gdk_pixbuf_new
+PHP_METHOD
+{
+    zend_bool has_alpha;
+    long bits_per_sample, width, height;
+    GObject *wrapped_obj;
+    zval *php_colorspace;
+    GdkColorspace colorspace;
+
+    if (!php_gtk_parse_args(ZEND_NUM_ARGS(), "ibiii", &php_colorspace, &has_alpha, &bits_per_sample, &width, &height)) {
+        PHPG_THROW_CONSTRUCT_EXCEPTION(GdkPixbuf);
+    }
+
+    if (phpg_gvalue_get_enum(GDK_TYPE_COLORSPACE, php_colorspace, (gint *) &colorspace) == FAILURE)
+        return;
+
+    wrapped_obj = (GObject *) gdk_pixbuf_new(colorspace, (gboolean)has_alpha, (int)bits_per_sample, (int)width, (int)height);
+
+    if (!wrapped_obj) {
+        PHPG_THROW_CONSTRUCT_EXCEPTION(GdkPixbuf);
+    }
+    phpg_gobject_set_wrapper(this_ptr, wrapped_obj TSRMLS_CC);
+}
+
+
 %%
 add-arginfo GdkPixbuf render_pixmap_and_mask
 static
@@ -973,7 +1010,7 @@ PHP_METHOD
     if (pixmap) {
         phpg_gobject_new(&php_pixmap, (GObject*)pixmap TSRMLS_CC);
         gdk_pixmap_unref(pixmap);
-    } else {                            
+    } else {
         MAKE_STD_ZVAL(php_pixmap);
     }