static void image_set_props(Image *image, GPtrArray *props) { struct stat st; time_t mtime = 0; char *old_file = image->file ? g_strdup(image->file) : NULL; const GdkPixbuf *old_pixbuf = dia_image_pixbuf (image->image); gboolean was_inline = image->inline_data; object_set_props_from_offsets(&image->element.object, image_offsets, props); if (old_pixbuf != image->pixbuf) { if (!image->file || *image->file == '\0') { GdkPixbuf *pixbuf = NULL; image->inline_data = TRUE; /* otherwise we'll loose it */ /* somebody deleting the filename? */ if (!image->pixbuf && image->image) pixbuf = g_object_ref ((GdkPixbuf *)dia_image_pixbuf (image->image)); if (image->image) g_object_unref (image->image); image->image = dia_image_new_from_pixbuf (image->pixbuf ? image->pixbuf : pixbuf); image->pixbuf = (GdkPixbuf *)dia_image_pixbuf (image->image); if (pixbuf) g_object_unref (pixbuf); } else { if (image->pixbuf) message_warning ("FIXME: handle pixbuf change!"); } } /* use old value on error */ if (!image->file || g_stat (image->file, &st) != 0) mtime = image->mtime; else mtime = st.st_mtime; /* handle changing the image. */ if (image->file && image->pixbuf && was_inline && !image->inline_data) { /* export inline data */ if (was_inline && !image->inline_data) /* if saving fails we keep it inline */ image->inline_data = !dia_image_save (image->image, image->file); } else if (image->file && ((old_file && strcmp(image->file, old_file) != 0) || image->mtime != mtime)) { Element *elem = &image->element; DiaImage *img = NULL; if ((img = dia_image_load(image->file)) != NULL) image->image = img; else if (!image->pixbuf) /* dont overwrite inlined */ image->image = dia_image_get_broken(); elem->height = (elem->width*(float)dia_image_height(image->image))/ (float)dia_image_width(image->image); } g_free(old_file); /* remember it */ image->mtime = mtime; image_update_data(image); }
/*! * \brief Get properties of the _Image * \memberof _Image * Overwites DiaObject::get_props() to initialize pixbuf property */ static void image_get_props(Image *image, GPtrArray *props) { if (image->inline_data) image->pixbuf = (GdkPixbuf *)dia_image_pixbuf (image->image); object_get_props_from_offsets(&image->element.object, image_offsets, props); }
static void _dae_draw(DiagramAsElement *dae, DiaRenderer *renderer) { DiaRendererClass *renderer_ops = DIA_RENDERER_GET_CLASS (renderer); Element *elem = &dae->element; if (!dae->data) { /* just draw the box */ Point lower_right = { elem->corner.x + elem->width, elem->corner.y + elem->height }; renderer_ops->draw_rect(renderer,&elem->corner, &lower_right, &dae->border_color); } else { if (FALSE) { /* if the renderer supports transformations ... */ /* temporary messing with it (not enough) */ dae->data->paper.scaling *= dae->scale; data_render (dae->data, DIA_RENDERER (renderer), NULL, NULL, NULL); dae->data->paper.scaling /= dae->scale; } else { /* we have to render to an image and draw that */ if (!dae->image) { /* lazy creation */ gchar *imgfname = NULL; gint fd = g_file_open_tmp ("diagram-as-elementXXXXXX.png", &imgfname, NULL); if (fd != -1) { DiaExportFilter *ef = filter_export_get_by_name ("cairo-alpha-png"); if (!ef) /* prefer cairo with alpha, but don't require it */ ef = filter_guess_export_filter (imgfname); close(fd); if (ef) { DiaContext *ctx = dia_context_new ("Diagram as Object"); dia_context_set_filename (ctx, imgfname); if (ef->export_func (dae->data, ctx, imgfname, dae->filename, ef->user_data)) { DiaImage *tmp_image = dia_image_load (imgfname); /* some extra gymnastics to create an image w/o filename */ if (tmp_image) { dae->image = dia_image_new_from_pixbuf ((GdkPixbuf *)dia_image_pixbuf (tmp_image)); g_object_unref (tmp_image); } /* FIXME: where to put the message in case of an error? */ dia_context_release (ctx); } } /* found a filter */ g_unlink (imgfname); g_free (imgfname); } /* temporary file created*/ } /* only if we have no image yet */ if (dae->image) renderer_ops->draw_image (renderer, &elem->corner, elem->width, elem->height, dae->image); } } }
static void draw_image(DiaRenderer *self, Point *point, real width, real height, DiaImage *image) { DiaSvgRenderer *renderer = DIA_SVG_RENDERER (self); xmlNodePtr node; gchar d_buf[DTOSTR_BUF_SIZE]; gchar *uri = NULL; node = xmlNewChild(renderer->root, NULL, (const xmlChar *)"image", NULL); dia_svg_dtostr(d_buf, point->x); xmlSetProp(node, (const xmlChar *)"x", (xmlChar *) d_buf); dia_svg_dtostr(d_buf, point->y); xmlSetProp(node, (const xmlChar *)"y", (xmlChar *) d_buf); dia_svg_dtostr(d_buf, width); xmlSetProp(node, (const xmlChar *)"width", (xmlChar *) d_buf); dia_svg_dtostr(d_buf, height); xmlSetProp(node, (const xmlChar *)"height", (xmlChar *) d_buf); /* if the image file location is relative to the SVG file's store * a relative path - if it does not have a path: inline it */ if (strcmp (dia_image_filename(image), "(null)") == 0) { gchar *b64 = pixbuf_encode_base64 (dia_image_pixbuf (image)); gchar *uri; if (b64) uri = g_strdup_printf ("data:image/png;base64,%s", b64); else uri = g_strdup ("(null)"); xmlSetProp(node, (const xmlChar *)"xlink:href", (xmlChar *) uri); g_free (b64); } else if ((uri = dia_relativize_filename (renderer->filename, dia_image_filename(image))) != NULL) xmlSetProp(node, (const xmlChar *)"xlink:href", (xmlChar *) uri); else if ((uri = g_filename_to_uri(dia_image_filename(image), NULL, NULL)) != NULL) xmlSetProp(node, (const xmlChar *)"xlink:href", (xmlChar *) uri); else /* not sure if this fallback is better than nothing */ xmlSetProp(node, (const xmlChar *)"xlink:href", (xmlChar *) dia_image_filename(image)); g_free (uri); }
static void image_save(Image *image, ObjectNode obj_node, const char *filename) { char *diafile_dir; element_save(&image->element, obj_node); if (image->border_width != 0.1) data_add_real(new_attribute(obj_node, "border_width"), image->border_width); if (!color_equals(&image->border_color, &color_black)) data_add_color(new_attribute(obj_node, "border_color"), &image->border_color); if (image->line_style != LINESTYLE_SOLID) data_add_enum(new_attribute(obj_node, "line_style"), image->line_style); if (image->line_style != LINESTYLE_SOLID && image->dashlength != DEFAULT_LINESTYLE_DASHLEN) data_add_real(new_attribute(obj_node, "dashlength"), image->dashlength); data_add_boolean(new_attribute(obj_node, "draw_border"), image->draw_border); data_add_boolean(new_attribute(obj_node, "keep_aspect"), image->keep_aspect); if (image->file != NULL) { if (g_path_is_absolute(image->file)) { /* Absolute pathname */ diafile_dir = get_directory(filename); if (strncmp(diafile_dir, image->file, strlen(diafile_dir))==0) { /* The image pathname has the dia file pathname in the begining */ /* Save the relative path: */ data_add_filename(new_attribute(obj_node, "file"), image->file + strlen(diafile_dir) + 1); } else { /* Save the absolute path: */ data_add_filename(new_attribute(obj_node, "file"), image->file); } g_free(diafile_dir); } else { /* Relative path. Must be an erronous filename... Just save the filename. */ data_add_filename(new_attribute(obj_node, "file"), image->file); } } /* only save image_data inline if told to do so */ if (image->inline_data) { GdkPixbuf *pixbuf; data_add_boolean (new_attribute(obj_node, "inline_data"), image->inline_data); /* just to be sure to get the currently visible */ pixbuf = (GdkPixbuf *)dia_image_pixbuf (image->image); if (pixbuf != image->pixbuf && image->pixbuf != NULL) message_warning (_("Inconsistent pixbuf during image save.")); if (pixbuf) data_add_pixbuf (new_attribute(obj_node, "pixbuf"), pixbuf); } }