static void gnm_soi_write_xml_sax (SheetObject const *so, GsfXMLOut *output, G_GNUC_UNUSED GnmConventions const *convs) { SheetObjectImage *soi; g_return_if_fail (IS_SHEET_OBJECT_IMAGE (so)); soi = SHEET_OBJECT_IMAGE (so); gsf_xml_out_add_float (output, "crop-top", soi->crop_top, 3); gsf_xml_out_add_float (output, "crop-bottom", soi->crop_bottom, 3); gsf_xml_out_add_float (output, "crop-left", soi->crop_left, 3); gsf_xml_out_add_float (output, "crop-right", soi->crop_right, 3); gsf_xml_out_start_element (output, "Content"); if (soi->type != NULL) gsf_xml_out_add_cstr (output, "image-type", soi->type); if (soi->image && go_image_get_name (soi->image)) { gsf_xml_out_add_cstr (output, "name", go_image_get_name (soi->image)); if (sheet_object_get_sheet (so)) go_doc_save_image (GO_DOC (sheet_object_get_sheet (so)->workbook), go_image_get_name (soi->image)); else { /* looks that this may happen when pasting from another process, see #687414 */ gsize length; guint8 const *data = go_image_get_data (soi->image, &length); gsf_xml_out_add_uint (output, "size-bytes", length); gsf_xml_out_add_base64 (output, NULL, data, length); } } else { gsf_xml_out_add_uint (output, "size-bytes", soi->bytes.len); gsf_xml_out_add_base64 (output, NULL, soi->bytes.data, soi->bytes.len); } gsf_xml_out_end_element (output); }
void sheet_object_image_set_crop (SheetObjectImage *soi, double crop_left, double crop_top, double crop_right, double crop_bottom) { g_return_if_fail (IS_SHEET_OBJECT_IMAGE (soi)); soi->crop_left = crop_left; soi->crop_top = crop_top; soi->crop_right = crop_right; soi->crop_bottom = crop_bottom; }
/** * sheet_object_image_set_image : * @so : #SheetObjectImage * @type : * @data : * @data_len * @copy_data : * * Assign raw data and type to @so assuming that it has not been initialized * yet. **/ void sheet_object_image_set_image (SheetObjectImage *soi, char const *type, guint8 *data, unsigned data_len, gboolean copy_data) { g_return_if_fail (IS_SHEET_OBJECT_IMAGE (soi)); g_return_if_fail (soi->bytes.data == NULL && soi->bytes.len == 0); soi->type = g_strdup (type); soi->bytes.len = data_len; soi->bytes.data = copy_data ? g_memdup (data, data_len) : data; }
static void gnm_soi_write_xml_sax (SheetObject const *so, GsfXMLOut *output, GnmConventions const *convs) { SheetObjectImage *soi; g_return_if_fail (IS_SHEET_OBJECT_IMAGE (so)); soi = SHEET_OBJECT_IMAGE (so); gsf_xml_out_add_float (output, "crop-top", soi->crop_top, 3); gsf_xml_out_add_float (output, "crop-bottom", soi->crop_bottom, 3); gsf_xml_out_add_float (output, "crop-left", soi->crop_left, 3); gsf_xml_out_add_float (output, "crop-right", soi->crop_right, 3); gsf_xml_out_start_element (output, "Content"); if (soi->type != NULL) gsf_xml_out_add_cstr (output, "image-type", soi->type); gsf_xml_out_add_uint (output, "size-bytes", soi->bytes.len); gsf_xml_out_add_base64 (output, NULL, soi->bytes.data, soi->bytes.len); gsf_xml_out_end_element (output); }
/** * sheet_object_image_set_image : * @soi: #SheetObjectImage * @type: * @data: * @data_len * @copy_data: * * Assign raw data and type to @so assuming that it has not been initialized * yet. **/ void sheet_object_image_set_image (SheetObjectImage *soi, char const *type, guint8 *data, unsigned data_len, gboolean copy_data) { g_return_if_fail (IS_SHEET_OBJECT_IMAGE (soi)); g_return_if_fail (soi->bytes.data == NULL && soi->bytes.len == 0); soi->type = (type && *type)? g_strdup (type): NULL; soi->bytes.len = data_len; soi->bytes.data = copy_data ? g_memdup (data, data_len) : data; soi->image = go_image_new_from_data (soi->type, soi->bytes.data, soi->bytes.len, ((soi->type == NULL)? &soi->type: NULL), NULL); if (soi->sheet_object.sheet != NULL) { GOImage *image = go_doc_add_image (GO_DOC (soi->sheet_object.sheet->workbook), NULL, soi->image); if (image != soi->image) { g_object_unref (soi->image); soi->image = g_object_ref (image); } } }
/** * be sure to unref the result if it is non-NULL * * TODO : this is really overkill for now. * only wmf/emf will require regenerating the pixbuf for different scale * factors. And even then we should cache them. */ static GdkPixbuf * soi_get_pixbuf (SheetObjectImage *soi, double scale) { GError *err = NULL; guint8 *data; guint32 data_len; GdkPixbufLoader *loader = NULL; GdkPixbuf *pixbuf = NULL; gboolean ret; g_return_val_if_fail (IS_SHEET_OBJECT_IMAGE (soi), NULL); data = soi->bytes.data; data_len = soi->bytes.len; if (data == NULL || data_len == 0) return pixbuf; if (soi->type != NULL && !strcmp (soi->type, "wmf")) loader = gdk_pixbuf_loader_new_with_type (soi->type, &err); else loader = gdk_pixbuf_loader_new (); if (soi->type == NULL || strlen (soi->type) == 0) g_signal_connect (loader, "size-prepared", G_CALLBACK (soi_info_cb), soi); if (loader) { ret = gdk_pixbuf_loader_write (loader, soi->bytes.data, soi->bytes.len, &err); /* Close in any case. But don't let error during closing * shadow error from loader_write. */ gdk_pixbuf_loader_close (loader, ret ? &err : NULL); if (ret) pixbuf = gdk_pixbuf_loader_get_pixbuf (loader); if (pixbuf) { g_object_ref (G_OBJECT (pixbuf)); d (printf ("pixbuf width=%d, height=%d\n", gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf))); if (soi->crop_top != 0.0 || soi->crop_bottom != 0.0 || soi->crop_left != 0.0 || soi->crop_right != 0.0) { d (printf ("crop rect top=%g, bottom=%g, " "left=%g, right=%g\n", soi->crop_top, soi->crop_bottom, soi->crop_left, soi->crop_right)); pixbuf = soi_get_cropped_pixbuf (soi, pixbuf); } } g_object_unref (G_OBJECT (loader)); } if (!pixbuf) { if (!soi->dumped) { static int count = 0; char *filename = g_strdup_printf ("unknown%d.%s", count++, soi->type); #if 0 GsfOutput *file = gsf_output_stdio_new (filename, NULL); if (file) { gsf_output_write (GSF_OUTPUT (file), soi->bytes.len, soi->bytes.data); gsf_output_close (GSF_OUTPUT (file)); g_object_unref (file); } #endif g_free (filename); soi->dumped = TRUE; } if (err != NULL) { g_warning ("%s", err->message); g_error_free (err); err = NULL; } else { g_warning ("Unable to display image"); } } return pixbuf; }