[gimp] Issue #526: Import/Export Windows cursor files (.CUR).
- From: Jehan <jehanp src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] Issue #526: Import/Export Windows cursor files (.CUR).
- Date: Thu, 10 Feb 2022 17:45:37 +0000 (UTC)
commit b301dbee783d6855f72159310af48e0f32ca6731
Author: Jehan <jehan girinstud io>
Date: Thu Feb 10 18:20:41 2022 +0100
Issue #526: Import/Export Windows cursor files (.CUR).
MR !565 was only a partial implementation as it was assuming all cursors
had the same hot spot coordinates in the file, which is false more often
than not (since usually it's several sizes for the same image, hence
coordinates move). I should have realized this before merging.
With this new commit, we actually loads the hot spot coordinates per
cursor, stores them as per-layer parasites, then exports with per-cursor
coordinates.
Also it makes the procedure API use int32 array (should be int16 but we
removed the support, now I think it may have been a mistake) which shows
the ugliness of our array support once again with additional size args
per array (even if it's the same size). Also I realize that our support
of arrays with config object is not good. This is also something we'll
have to look at.
plug-ins/file-ico/ico-dialog.c | 83 ++++++++--------
plug-ins/file-ico/ico-load.c | 31 +++---
plug-ins/file-ico/ico-save.c | 211 +++++++++++++++++++++++++++++++----------
plug-ins/file-ico/ico-save.h | 12 +--
plug-ins/file-ico/ico.c | 61 +++++++++---
plug-ins/file-ico/ico.h | 10 +-
6 files changed, 275 insertions(+), 133 deletions(-)
---
diff --git a/plug-ins/file-ico/ico-dialog.c b/plug-ins/file-ico/ico-dialog.c
index 6172149aa7..625000e929 100644
--- a/plug-ins/file-ico/ico-dialog.c
+++ b/plug-ins/file-ico/ico-dialog.c
@@ -49,9 +49,6 @@ ico_dialog_new (IcoSaveInfo *info)
GtkWidget *frame;
GtkWidget *scrolled_window;
GtkWidget *viewport;
- GtkWidget *grid;
- GtkAdjustment *adj;
- GtkWidget *spinbutton;
GtkWidget *warning;
dialog = gimp_export_dialog_new (_("Windows Icon"),
@@ -74,46 +71,6 @@ ico_dialog_new (IcoSaveInfo *info)
main_vbox, TRUE, TRUE, 0);
gtk_widget_show (main_vbox);
- /* Cursor */
- if (info->is_cursor)
- {
- frame = gimp_frame_new (_("Cursor Hot spot"));
- gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 4);
- gtk_widget_show (frame);
-
- grid = gtk_grid_new ();
- gtk_grid_set_row_spacing (GTK_GRID (grid), 6);
- gtk_grid_set_column_spacing (GTK_GRID (grid), 6);
- gtk_container_add (GTK_CONTAINER (frame), grid);
- gtk_widget_show (grid);
-
- adj = (GtkAdjustment *)
- gtk_adjustment_new (info->hot_spot_x, 0,
- G_MAXUINT16, 1, 10, 0);
- spinbutton = gimp_spin_button_new (adj, 1.0, 0);
- gtk_spin_button_set_range (GTK_SPIN_BUTTON (spinbutton),
- 0, G_MAXUINT16);
- gimp_grid_attach_aligned (GTK_GRID (grid), 0, 0,
- _("Hot spot _X:"), 0.0, 0.5,
- spinbutton, 1);
- g_signal_connect (adj, "value-changed",
- G_CALLBACK (gimp_int_adjustment_update),
- &info->hot_spot_x);
-
- adj = (GtkAdjustment *)
- gtk_adjustment_new (info->hot_spot_y, 0,
- G_MAXUINT16, 1, 10, 0);
- spinbutton = gimp_spin_button_new (adj, 1.0, 0);
- gtk_spin_button_set_range (GTK_SPIN_BUTTON (spinbutton),
- 0, G_MAXUINT16);
- gimp_grid_attach_aligned (GTK_GRID (grid), 0, 1,
- _("Hot spot _Y:"), 0.0, 0.5,
- spinbutton, 1);
- g_signal_connect (adj, "value-changed",
- G_CALLBACK (gimp_int_adjustment_update),
- &info->hot_spot_y);
- }
-
/* Cursor */
frame = gimp_frame_new (_("Icon Details"));
gtk_box_pack_start (GTK_BOX (main_vbox), frame, TRUE, TRUE, 4);
@@ -501,6 +458,46 @@ ico_dialog_add_icon (GtkWidget *dialog,
ico_dialog_update_icon_preview (dialog, layer, info->depths[layer_num]);
ico_dialog_check_compat (dialog, info);
+
+ /* Cursor */
+ if (info->is_cursor)
+ {
+ GtkWidget *grid;
+ GtkAdjustment *adj;
+ GtkWidget *spinbutton;
+
+ grid = gtk_grid_new ();
+ gtk_grid_set_row_spacing (GTK_GRID (grid), 6);
+ gtk_grid_set_column_spacing (GTK_GRID (grid), 6);
+ gtk_box_pack_start (GTK_BOX (hbox), grid, FALSE, FALSE, 0);
+ gtk_widget_show (grid);
+
+ adj = (GtkAdjustment *)
+ gtk_adjustment_new (info->hot_spot_x[layer_num], 0,
+ G_MAXUINT16, 1, 10, 0);
+ spinbutton = gimp_spin_button_new (adj, 1.0, 0);
+ gtk_spin_button_set_range (GTK_SPIN_BUTTON (spinbutton),
+ 0, G_MAXUINT16);
+ gimp_grid_attach_aligned (GTK_GRID (grid), 0, 0,
+ _("Hot spot _X:"), 0.0, 0.5,
+ spinbutton, 1);
+ g_signal_connect (adj, "value-changed",
+ G_CALLBACK (gimp_int_adjustment_update),
+ &info->hot_spot_x[layer_num]);
+
+ adj = (GtkAdjustment *)
+ gtk_adjustment_new (info->hot_spot_y[layer_num], 0,
+ G_MAXUINT16, 1, 10, 0);
+ spinbutton = gimp_spin_button_new (adj, 1.0, 0);
+ gtk_spin_button_set_range (GTK_SPIN_BUTTON (spinbutton),
+ 0, G_MAXUINT16);
+ gimp_grid_attach_aligned (GTK_GRID (grid), 0, 1,
+ _("Hot spot _Y:"), 0.0, 0.5,
+ spinbutton, 1);
+ g_signal_connect (adj, "value-changed",
+ G_CALLBACK (gimp_int_adjustment_update),
+ &info->hot_spot_y[layer_num]);
+ }
}
static void
diff --git a/plug-ins/file-ico/ico-load.c b/plug-ins/file-ico/ico-load.c
index abe4f2a915..36c3b402bb 100644
--- a/plug-ins/file-ico/ico-load.c
+++ b/plug-ins/file-ico/ico-load.c
@@ -664,7 +664,6 @@ ico_load_image (GFile *file,
guchar *buf;
guint icon_count;
gint maxsize;
- GimpParasite *parasite;
gchar *str;
gimp_progress_init_printf (_("Opening '%s'"),
@@ -716,23 +715,27 @@ ico_load_image (GFile *file,
image = gimp_image_new (max_width, max_height, GIMP_RGB);
gimp_image_set_file (image, file);
- /* Save CUR hot spot information */
- if (header.resource_type == 2)
- {
- str = g_strdup_printf ("%d %d", info[0].planes, info[0].bpp);
- parasite = gimp_parasite_new ("cur-hot-spot",
- GIMP_PARASITE_PERSISTENT,
- strlen (str) + 1, (gpointer) str);
- g_free (str);
- gimp_image_attach_parasite (image, parasite);
- gimp_parasite_free (parasite);
- }
-
maxsize = max_width * max_height * 4;
buf = g_new (guchar, max_width * max_height * 4);
for (i = 0; i < icon_count; i++)
{
- ico_load_layer (fp, image, i, buf, maxsize, info+i);
+ GimpLayer *layer;
+
+ layer = ico_load_layer (fp, image, i, buf, maxsize, info+i);
+
+ /* Save CUR hot spot information */
+ if (header.resource_type == 2)
+ {
+ GimpParasite *parasite;
+
+ str = g_strdup_printf ("%d %d", info[i].planes, info[i].bpp);
+ parasite = gimp_parasite_new ("cur-hot-spot",
+ GIMP_PARASITE_PERSISTENT,
+ strlen (str) + 1, (gpointer) str);
+ g_free (str);
+ gimp_item_attach_parasite (GIMP_ITEM (layer), parasite);
+ gimp_parasite_free (parasite);
+ }
}
g_free (buf);
g_free (info);
diff --git a/plug-ins/file-ico/ico-save.c b/plug-ins/file-ico/ico-save.c
index 3f366e0145..4993166732 100644
--- a/plug-ins/file-ico/ico-save.c
+++ b/plug-ins/file-ico/ico-save.c
@@ -72,6 +72,25 @@ static void ico_image_get_reduced_buf (GimpDrawable *layer,
guchar **cmap_out,
guchar **buf_out);
+static gboolean ico_save_init (GimpImage *image,
+ gint32 run_mode,
+ IcoSaveInfo *info,
+ gint n_hot_spot_x,
+ gint32 *hot_spot_x,
+ gint n_hot_spot_y,
+ gint32 *hot_spot_y,
+ GError **error);
+static GimpPDBStatusType
+ shared_save_image (GFile *file,
+ GimpImage *image,
+ gint32 run_mode,
+ gint *n_hot_spot_x,
+ gint32 **hot_spot_x,
+ gint *n_hot_spot_y,
+ gint32 **hot_spot_y,
+ GError **error,
+ IcoSaveInfo *info);
+
static gint
ico_write_int32 (FILE *fp,
@@ -155,9 +174,15 @@ ico_write_int8 (FILE *fp,
}
-static void
+static gboolean
ico_save_init (GimpImage *image,
- IcoSaveInfo *info)
+ gint32 run_mode,
+ IcoSaveInfo *info,
+ gint n_hot_spot_x,
+ gint32 *hot_spot_x,
+ gint n_hot_spot_y,
+ gint32 *hot_spot_y,
+ GError **error)
{
GList *iter;
gint num_colors;
@@ -169,6 +194,51 @@ ico_save_init (GimpImage *image,
info->depths = g_new (gint, info->num_icons);
info->default_depths = g_new (gint, info->num_icons);
info->compress = g_new (gboolean, info->num_icons);
+ info->hot_spot_x = g_new0 (gint, info->num_icons);
+ info->hot_spot_y = g_new0 (gint, info->num_icons);
+
+ if (run_mode == GIMP_RUN_NONINTERACTIVE &&
+ (n_hot_spot_x != info->num_icons ||
+ n_hot_spot_y != info->num_icons))
+ {
+ /* While it is acceptable for interactive and last values run (in
+ * such case, we just drop the previous values), we expect
+ * non-interactive calls to have exactly the right numbers of
+ * hot-spot values set.
+ */
+ g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
+ _("Called non-interactively with %d and %d hotspot "
+ "coordinates with an image of %d icons."),
+ n_hot_spot_x, n_hot_spot_y, info->num_icons);
+
+ return FALSE;
+ }
+
+ /* Only use existing values if we have exactly the same number of
+ * icons. Drop previous/saved values otherwise.
+ */
+ if (hot_spot_x && n_hot_spot_x == info->num_icons)
+ {
+ /* XXX This is the limit of our array arguments not self-aware of
+ * their length (the separate args may be "lying" with a wrong
+ * call). We may end up with a segfault if the arg array was not
+ * big enough. There is not much we can really do here. I thought
+ * about g_renew() but it won't initialize to 0 if the arg is
+ * smaller. Also we don't want to free the original array.
+ */
+ for (iter = info->layers, i = 0;
+ iter;
+ iter = g_list_next (iter), i++)
+ info->hot_spot_x[i] = hot_spot_x[i];
+ }
+
+ if (hot_spot_y && n_hot_spot_y == info->num_icons)
+ {
+ for (iter = info->layers, i = 0;
+ iter;
+ iter = g_list_next (iter), i++)
+ info->hot_spot_y[i] = hot_spot_y[i];
+ }
/* Limit the color depths to values that don't cause any color loss
* -- the user should pick these anyway, so we can save her some
@@ -225,6 +295,8 @@ ico_save_init (GimpImage *image,
/* set with default values */
memcpy (info->depths, info->default_depths,
sizeof (gint) * info->num_icons);
+
+ return TRUE;
}
@@ -237,37 +309,41 @@ ico_save_dialog (GimpImage *image,
GList *iter;
gint i;
gint response;
- GimpParasite *parasite = NULL;
gimp_ui_init (PLUG_IN_BINARY);
- /* Loading hot spots for cursors if applicable */
- parasite = gimp_image_get_parasite (image, "cur-hot-spot");
-
- if (parasite)
- {
- gchar *parasite_data;
- guint32 parasite_size;
- gint x, y;
-
- parasite_data = (gchar *) gimp_parasite_get_data (parasite, ¶site_size);
- parasite_data = g_strndup (parasite_data, parasite_size);
-
- if (sscanf (parasite_data, "%i %i", &x, &y) == 2)
- {
- info->hot_spot_x = x;
- info->hot_spot_y = y;
- }
-
- gimp_parasite_free (parasite);
- g_free (parasite_data);
- }
-
dialog = ico_dialog_new (info);
for (iter = info->layers, i = 0;
iter;
iter = g_list_next (iter), i++)
{
+ if (info->is_cursor)
+ {
+ GimpParasite *parasite = NULL;
+
+ /* Loading hot spots for cursors if applicable */
+ parasite = gimp_item_get_parasite (GIMP_ITEM (iter->data), "cur-hot-spot");
+
+ if (parasite)
+ {
+ gchar *parasite_data;
+ guint32 parasite_size;
+ gint x, y;
+
+ parasite_data = (gchar *) gimp_parasite_get_data (parasite, ¶site_size);
+ parasite_data = g_strndup (parasite_data, parasite_size);
+
+ if (sscanf (parasite_data, "%i %i", &x, &y) == 2)
+ {
+ info->hot_spot_x[i] = x;
+ info->hot_spot_y[i] = y;
+ }
+
+ gimp_parasite_free (parasite);
+ g_free (parasite_data);
+ }
+ }
+
/* if (gimp_layer_get_visible(layers[i])) */
ico_dialog_add_icon (dialog, iter->data, i);
}
@@ -1080,6 +1156,8 @@ ico_save_info_free (IcoSaveInfo *info)
g_free (info->default_depths);
g_free (info->compress);
g_list_free (info->layers);
+ g_free (info->hot_spot_x);
+ g_free (info->hot_spot_y);
memset (info, 0, sizeof (IcoSaveInfo));
}
@@ -1089,42 +1167,51 @@ ico_save_image (GFile *file,
gint32 run_mode,
GError **error)
{
- IcoSaveInfo info;
+ IcoSaveInfo info;
D(("*** Exporting Microsoft icon file %s\n",
gimp_file_get_utf8_name (file)));
info.is_cursor = FALSE;
- return shared_save_image (file, image, run_mode, error, &info);
+ return shared_save_image (file, image, run_mode,
+ 0, NULL, 0, NULL,
+ error, &info);
}
GimpPDBStatusType
cur_save_image (GFile *file,
GimpImage *image,
gint32 run_mode,
- gint32 hot_spot_x,
- gint32 hot_spot_y,
+ gint *n_hot_spot_x,
+ gint32 **hot_spot_x,
+ gint *n_hot_spot_y,
+ gint32 **hot_spot_y,
GError **error)
{
- IcoSaveInfo info;
+ IcoSaveInfo info;
D(("*** Exporting Microsoft cursor file %s\n",
gimp_file_get_utf8_name (file)));
info.is_cursor = TRUE;
- info.hot_spot_x = hot_spot_x;
- info.hot_spot_y = hot_spot_y;
- return shared_save_image (file, image, run_mode, error, &info);
+ return shared_save_image (file, image, run_mode,
+ n_hot_spot_x, hot_spot_x,
+ n_hot_spot_y, hot_spot_y,
+ error, &info);
}
GimpPDBStatusType
-shared_save_image (GFile *file,
- GimpImage *image,
- gint32 run_mode,
- GError **error,
- IcoSaveInfo *info)
+shared_save_image (GFile *file,
+ GimpImage *image,
+ gint32 run_mode,
+ gint *n_hot_spot_x,
+ gint32 **hot_spot_x,
+ gint *n_hot_spot_y,
+ gint32 **hot_spot_y,
+ GError **error,
+ IcoSaveInfo *info)
{
FILE *fp;
GList *iter;
@@ -1137,7 +1224,15 @@ shared_save_image (GFile *file,
GimpParasite *parasite = NULL;
gchar *str;
- ico_save_init (image, info);
+ if (! ico_save_init (image, run_mode, info,
+ n_hot_spot_x ? *n_hot_spot_x : 0,
+ hot_spot_x ? *hot_spot_x : NULL,
+ n_hot_spot_y ? *n_hot_spot_y : 0,
+ hot_spot_y ? *hot_spot_y : NULL,
+ error))
+ {
+ return GIMP_PDB_EXECUTION_ERROR;
+ }
if (run_mode == GIMP_RUN_INTERACTIVE)
{
@@ -1210,8 +1305,8 @@ shared_save_image (GFile *file,
/* .cur file reuses these fields for cursor offsets */
if (info->is_cursor)
{
- entries[i].planes = info->hot_spot_x;
- entries[i].bpp = info->hot_spot_y;
+ entries[i].planes = info->hot_spot_x[i];
+ entries[i].bpp = info->hot_spot_y[i];
}
entries[i].offset = ftell (fp);
@@ -1251,14 +1346,34 @@ shared_save_image (GFile *file,
/* Updating parasite hot spots if needed */
if (info->is_cursor)
{
- str = g_strdup_printf ("%d %d", info->hot_spot_x, info->hot_spot_y);
- parasite = gimp_parasite_new ("cur-hot-spot",
- GIMP_PARASITE_PERSISTENT,
- strlen (str) + 1, (gpointer) str);
- g_free (str);
- gimp_image_attach_parasite (image, parasite);
- gimp_parasite_free (parasite);
+ for (iter = info->layers, i = 0;
+ iter;
+ iter = g_list_next (iter), i++)
+ {
+ str = g_strdup_printf ("%d %d", info->hot_spot_x[i], info->hot_spot_y[i]);
+ parasite = gimp_parasite_new ("cur-hot-spot",
+ GIMP_PARASITE_PERSISTENT,
+ strlen (str) + 1, (gpointer) str);
+ g_free (str);
+ gimp_item_attach_parasite (GIMP_ITEM (iter->data), parasite);
+ gimp_parasite_free (parasite);
+ }
+ }
+
+ if (hot_spot_x)
+ {
+ *hot_spot_x = info->hot_spot_x;
+ info->hot_spot_x = NULL;
+ }
+ if (hot_spot_y)
+ {
+ *hot_spot_y = info->hot_spot_y;
+ info->hot_spot_y = NULL;
}
+ if (n_hot_spot_x)
+ *n_hot_spot_x = info->num_icons;
+ if (n_hot_spot_y)
+ *n_hot_spot_y = info->num_icons;
ico_save_info_free (info);
fclose (fp);
diff --git a/plug-ins/file-ico/ico-save.h b/plug-ins/file-ico/ico-save.h
index 920feb05d5..1e1ed82dc9 100644
--- a/plug-ins/file-ico/ico-save.h
+++ b/plug-ins/file-ico/ico-save.h
@@ -30,16 +30,12 @@ GimpPDBStatusType ico_save_image (GFile *file,
GimpPDBStatusType cur_save_image (GFile *file,
GimpImage *image,
gint32 run_mode,
- gint32 hot_spot_x,
- gint32 hot_spot_y,
+ gint *n_hot_spot_x,
+ gint32 **hot_spot_x,
+ gint *n_hot_spot_y,
+ gint32 **hot_spot_y,
GError **error);
-GimpPDBStatusType shared_save_image (GFile *file,
- GimpImage *image,
- gint32 run_mode,
- GError **error,
- IcoSaveInfo *info);
-
gboolean ico_cmap_contains_black (const guchar *cmap,
gint num_colors);
diff --git a/plug-ins/file-ico/ico.c b/plug-ins/file-ico/ico.c
index 728c70bed9..4a63aedad7 100644
--- a/plug-ins/file-ico/ico.c
+++ b/plug-ins/file-ico/ico.c
@@ -255,17 +255,25 @@ ico_create_procedure (GimpPlugIn *plug_in,
gimp_file_procedure_set_extensions (GIMP_FILE_PROCEDURE (procedure),
"cur");
- GIMP_PROC_ARG_INT (procedure, "hot-spot-x",
- "Hot spot X",
- "X coordinate of hot spot",
- 0, G_MAXUINT16, 0,
+ GIMP_PROC_ARG_INT (procedure, "n-hot-spot-x",
+ "Number of hot spot's X coordinates",
+ "Number of hot spot's X coordinates",
+ 0, G_MAXINT, 0,
G_PARAM_READWRITE);
-
- GIMP_PROC_ARG_INT (procedure, "hot-spot-y",
- "Hot spot Y",
- "Y coordinate of hot spot",
- 0, G_MAXUINT16, 0,
+ GIMP_PROC_ARG_INT32_ARRAY (procedure, "hot-spot-x",
+ "Hot spot X",
+ "X coordinates of hot spot (one per layer)",
+ G_PARAM_READWRITE);
+
+ GIMP_PROC_ARG_INT (procedure, "n-hot-spot-y",
+ "Number of hot spot's Y coordinates",
+ "Number of hot spot's Y coordinates",
+ 0, G_MAXINT, 0,
G_PARAM_READWRITE);
+ GIMP_PROC_ARG_INT32_ARRAY (procedure, "hot-spot-y",
+ "Hot spot Y",
+ "Y coordinates of hot spot (one per layer)",
+ G_PARAM_READWRITE);
}
return procedure;
@@ -374,9 +382,11 @@ cur_save (GimpProcedure *procedure,
{
GimpProcedureConfig *config;
GimpPDBStatusType status;
- GError *error = NULL;
- gint hot_spot_x = 0;
- gint hot_spot_y = 0;
+ GError *error = NULL;
+ gint32 *hot_spot_x = NULL;
+ gint32 *hot_spot_y = NULL;
+ gint n_hot_spot_x = 0;
+ gint n_hot_spot_y = 0;
INIT_I18N ();
gegl_init (NULL, NULL);
@@ -385,11 +395,32 @@ cur_save (GimpProcedure *procedure,
gimp_procedure_config_begin_run (config, image, run_mode, args);
g_object_get (config,
- "hot-spot-x", &hot_spot_x,
- "hot-spot-y", &hot_spot_y,
+ "n-hot-spot-x", &n_hot_spot_x,
+ "n-hot-spot-y", &n_hot_spot_y,
+ "hot-spot-x", &hot_spot_x,
+ "hot-spot-y", &hot_spot_y,
NULL);
- status = cur_save_image (file, image, run_mode, hot_spot_x, hot_spot_y, &error);
+ status = cur_save_image (file, image, run_mode,
+ &n_hot_spot_x, &hot_spot_x,
+ &n_hot_spot_y, &hot_spot_y,
+ &error);
+
+ if (status == GIMP_PDB_SUCCESS)
+ {
+ /* XXX: seems libgimpconfig is not able to serialize
+ * GimpInt32Array args yet anyway. Still leave this here for now,
+ * as reminder of missing feature when we see the warnings.
+ */
+ g_object_set (config,
+ "n-hot-spot-x", n_hot_spot_x,
+ "n-hot-spot-y", n_hot_spot_y,
+ /*"hot-spot-x", hot_spot_x,*/
+ /*"hot-spot-y", hot_spot_y,*/
+ NULL);
+ g_free (hot_spot_x);
+ g_free (hot_spot_y);
+ }
gimp_procedure_config_end_run (config, status);
g_object_unref (config);
diff --git a/plug-ins/file-ico/ico.h b/plug-ins/file-ico/ico.h
index 972dd19ceb..07465d853b 100644
--- a/plug-ins/file-ico/ico.h
+++ b/plug-ins/file-ico/ico.h
@@ -50,11 +50,11 @@ typedef struct _IcoFileHeader
typedef struct _IcoFileEntry
{
guint8 width; /* Width of icon in pixels */
- guint8 height; /* Height of icon in pixels */
+ guint8 height; /* Height of icon in pixels */
guint8 num_colors; /* Number of colors of paletted image */
guint8 reserved; /* Must be 0 */
- guint16 planes; /* Must be 1 */
- guint16 bpp; /* 1, 4, 8, 24 or 32 bits per pixel */
+ guint16 planes; /* Must be 1 for ICO, x position of hot spot for CUR */
+ guint16 bpp; /* 1, 4, 8, 24 or 32 bits per pixel for ICO, y position of hot spot for CUR */
guint32 size; /* Size of icon (including data header) */
guint32 offset; /* Absolute offset of data in a file */
} IcoFileEntry;
@@ -93,8 +93,8 @@ typedef struct _IcoSaveInfo
GList *layers;
gint num_icons;
gboolean is_cursor;
- gint hot_spot_x;
- gint hot_spot_y;
+ gint *hot_spot_x;
+ gint *hot_spot_y;
} IcoSaveInfo;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]