Commit 753fe464af1021ec7183e5550a0cbc198959c1e1

Thomas de Grivel 2023-12-04T20:11:58

revert to cairo_image_surface_create_from_png

diff --git a/libc3/window/cairo/cairo_sprite.c b/libc3/window/cairo/cairo_sprite.c
index 8b2063e..0284863 100644
--- a/libc3/window/cairo/cairo_sprite.c
+++ b/libc3/window/cairo/cairo_sprite.c
@@ -15,28 +15,6 @@
 #include <libc3/c3.h>
 #include "cairo_sprite.h"
 
-bool g_il_is_loaded = false;
-
-static void ilEnsureInit (void)
-{
-  if (! g_il_is_loaded) {
-    ilInit();
-    iluInit();
-    g_il_is_loaded = true;
-  }
-}
-
-void ilClean (void)
-{
-  /*
-  if (g_il_is_loaded) {
-    iluDestroy();
-    ilDestroy();
-    g_il_is_loaded = false;
-  }
-  */
-}
-
 void cairo_sprite_blit (const s_cairo_sprite *sprite, uw frame,
                         cairo_t *cr, uw x, uw y)
 {
@@ -69,9 +47,14 @@ s_cairo_sprite * cairo_sprite_init (s_cairo_sprite *sprite,
   assert(sprite);
   assert(dim_x);
   assert(dim_y);
-    ILubyte *data;
+  u8 *dest_data;
+  uw  dest_stride;
   uw i;
-  ILuint il_image[2];
+  cairo_surface_t *src;
+  u8              *src_data;
+  uw               src_stride;
+  uw u;
+  uw v;
   uw x;
   uw y;
   assert(sprite);
@@ -84,18 +67,16 @@ s_cairo_sprite * cairo_sprite_init (s_cairo_sprite *sprite,
     str_clean(&sprite->path);
     return NULL;
   }
-  ilEnsureInit();
-  ilGenImages(2, il_image);
-  ilBindImage(il_image[0]);
-  if (! ilLoadImage(sprite->path.ptr.ps8)) {
+  src = cairo_image_surface_create_from_png(sprite->real_path.ptr.ps8);
+  if (! src) {
     warnx("cairo_sprite_init: error loading image: %s",
-          iluErrorString(ilGetError()));
+          sprite->real_path.ptr.ps8);
     str_clean(&sprite->path);
     str_clean(&sprite->real_path);
     return NULL;
   }
-  sprite->total_w = ilGetInteger(IL_IMAGE_WIDTH);
-  sprite->total_h = ilGetInteger(IL_IMAGE_HEIGHT);
+  sprite->total_w = cairo_image_surface_get_width(src);
+  sprite->total_h = cairo_image_surface_get_height(src);
   sprite->dim_x = dim_x;
   sprite->dim_y = dim_y;
   sprite->w = sprite->total_w / dim_x;
@@ -104,7 +85,7 @@ s_cairo_sprite * cairo_sprite_init (s_cairo_sprite *sprite,
   sprite->surface = calloc(frame_count, sizeof(cairo_surface_t *));
   if (! sprite->surface) {
     warn("cairo_sprite_init: sprite->surface");
-    ilDeleteImages(2, il_image);
+    cairo_surface_destroy(src);
     str_clean(&sprite->path);
     str_clean(&sprite->real_path);
     return NULL;
@@ -114,21 +95,39 @@ s_cairo_sprite * cairo_sprite_init (s_cairo_sprite *sprite,
   while (i < sprite->frame_count && y < dim_y) {
     x = 0;
     while (i < sprite->frame_count && x < dim_x) {
-      ilBindImage(il_image[1]);
-      ilTexImage(sprite->w, sprite->h, 1, 32, IL_RGBA, IL_UNSIGNED_BYTE,
-                 NULL);
-      data = ilGetData();
-      ilBindImage(il_image[0]);
-      ilCopyPixels(x * sprite->w, y * sprite->h, 0,
-                   sprite->w, sprite->h, 1, IL_RGBA, IL_UNSIGNED_BYTE,
-                   data);
-      sprite->surface[i] = cairo_image_surface_create_for_data
-        (data, CAIRO_FORMAT_ARGB32, sprite->w, sprite->h, sprite->w * 4);
+      src_data = cairo_image_surface_get_data(src);
+      src_stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32,
+                                                 sprite->total_w);
+      dest_stride =
+        cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, sprite->w);
+      dest_data = malloc(sprite->h * dest_stride);
+      sprite->surface[i] =
+        cairo_image_surface_create_for_data(dest_data,
+                                            CAIRO_FORMAT_ARGB32,
+                                            sprite->w, sprite->h,
+                                            dest_stride);
+      v = 0;
+      while (v < sprite->h) {
+        u = 0;
+        while (u < sprite->w) {
+          u8 *dest_pixel = dest_data + v * dest_stride +
+            u * 4;
+          u8 *src_pixel = src_data +
+            (y * sprite->h + v) * src_stride +
+            (x * sprite->w + u) * 4;
+          dest_pixel[0] = src_pixel[0];
+          dest_pixel[1] = src_pixel[1];
+          dest_pixel[2] = src_pixel[2];
+          dest_pixel[3] = src_pixel[3];
+          u++;
+        }
+        v++;
+      }
       i++;
       x++;
     }
     y++;
   }
-  ilDeleteImages(2, il_image);
+  cairo_surface_destroy(src);
   return sprite;
 }
diff --git a/libc3/window/cairo/configure b/libc3/window/cairo/configure
index d79f71b..4f6c3ca 100755
--- a/libc3/window/cairo/configure
+++ b/libc3/window/cairo/configure
@@ -44,7 +44,8 @@ config_asan
 config_gnu
 pkg_config cairo
 pkg_config freetype2
-config_lib IL -lIL -lILU
+#config_lib IL -lIL -lILU
+config_lib FREEIMAGE -lfreeimage
 pkg_config libbsd-overlay
 pkg_config xkbcommon
 config_lib_have COCOA -framework Cocoa
diff --git a/libc3/window/cairo/quartz/demo/window_cairo_quartz_demo.c b/libc3/window/cairo/quartz/demo/window_cairo_quartz_demo.c
index bc66a73..a13f851 100644
--- a/libc3/window/cairo/quartz/demo/window_cairo_quartz_demo.c
+++ b/libc3/window/cairo/quartz/demo/window_cairo_quartz_demo.c
@@ -24,6 +24,7 @@ int main (int argc, s8 **argv)
   s_window_cairo window;
   if (! c3_init(NULL, argc, argv))
     return 1;
+  c3_window_cairo_init();
   window_cairo_init(&window, 0, 0, 800, 600,
                     "C3.Window.Cairo.Quartz demo",
                     WINDOW_CAIRO_DEMO_SEQUENCE_COUNT);
@@ -34,6 +35,7 @@ int main (int argc, s8 **argv)
   window.resize = window_cairo_demo_resize;
   if (! window_cairo_quartz_run(&window))
     r = g_c3_exit_code;
+  c3_window_cairo_clean();
   c3_clean(NULL);
   return r;
 }
diff --git a/libc3/window/cairo/types.h b/libc3/window/cairo/types.h
index e8674b2..7a1afdd 100644
--- a/libc3/window/cairo/types.h
+++ b/libc3/window/cairo/types.h
@@ -22,8 +22,7 @@
 #include <cairo-ft.h>
 #include <ft2build.h>
 #include FT_FREETYPE_H
-#include <IL/il.h>
-#include <IL/ilu.h>
+#include <png.h>
 #include <libc3/types.h>
 #include "../types.h"
 
@@ -79,6 +78,7 @@ struct cairo_sprite {
   uw frame_count;
   uw w;
   uw h;
+  //ILuint *il_image;
   cairo_surface_t **surface;
 };
 
diff --git a/libc3/window/cairo/win32/demo/window_cairo_win32_demo.c b/libc3/window/cairo/win32/demo/window_cairo_win32_demo.c
index 192a49e..57ddb0c 100644
--- a/libc3/window/cairo/win32/demo/window_cairo_win32_demo.c
+++ b/libc3/window/cairo/win32/demo/window_cairo_win32_demo.c
@@ -18,9 +18,12 @@
 #include "../../c3_window_cairo_demo.h"
 #include "../window_cairo_win32.h"
 
-int main (void)
+int main (int argc, char **argv)
 {
   s_window_cairo window;
+  if (! c3_init(NULL, argc, argv))
+    return 1;
+  c3_window_cairo_init();
   window_cairo_init(&window, 0, 0, 800, 600,
                     "C3.Window.Cairo.Win32 demo",
                     LIBC3_WINDOW_CAIRO_DEMO_SEQUENCE_COUNT);
@@ -31,5 +34,7 @@ int main (void)
   window.resize = c3_window_cairo_demo_resize;
   if (! window_cairo_win32_run(&window))
     return g_c3_exit_code;
+  c3_window_cairo_clean();
+  c3_clean(NULL);
   return 0;
 }
diff --git a/libc3/window/cairo/window_cairo.c b/libc3/window/cairo/window_cairo.c
index 6e725c5..67dd84d 100644
--- a/libc3/window/cairo/window_cairo.c
+++ b/libc3/window/cairo/window_cairo.c
@@ -16,6 +16,14 @@
 #include <libc3/tag.h>
 #include "window_cairo.h"
 
+void c3_window_cairo_clean (void)
+{
+}
+
+void c3_window_cairo_init (void)
+{
+}
+
 s_window_cairo * window_cairo_init (s_window_cairo *window,
                                     sw x, sw y, uw w, uw h,
                                     const s8 *title,
diff --git a/libc3/window/cairo/window_cairo.h b/libc3/window/cairo/window_cairo.h
index 9030c6a..76e03fe 100644
--- a/libc3/window/cairo/window_cairo.h
+++ b/libc3/window/cairo/window_cairo.h
@@ -15,6 +15,11 @@
 
 #include "types.h"
 
+/* Library functions, call c3_window_cairo_init at program start,
+   and c3_window_cairo_clean at program end. */
+void c3_window_cairo_clean (void);
+void c3_window_cairo_init (void);
+
 s_window_cairo * window_cairo_init (s_window_cairo *window,
                                     sw x, sw y, uw w, uw h,
                                     const s8 *title,
diff --git a/libc3/window/cairo/xcb/demo/window_cairo_xcb_demo.c b/libc3/window/cairo/xcb/demo/window_cairo_xcb_demo.c
index d38c4d1..9cf1feb 100644
--- a/libc3/window/cairo/xcb/demo/window_cairo_xcb_demo.c
+++ b/libc3/window/cairo/xcb/demo/window_cairo_xcb_demo.c
@@ -24,6 +24,7 @@ int main (int argc, char **argv)
     err_puts("c3_init");
     return 1;
   }
+  c3_window_cairo_init();
   window_cairo_init(&window, 0, 0, 800, 600,
                     "C3.Window.Cairo.XCB demo",
                     WINDOW_CAIRO_DEMO_SEQUENCE_COUNT);
@@ -37,6 +38,7 @@ int main (int argc, char **argv)
     c3_clean(NULL);
     return g_c3_exit_code;
   }
+  c3_window_cairo_clean();
   c3_clean(NULL);
   return 0;
 }