static void export_shape(DiagramData *data, const gchar *filename, const gchar *diafilename, void* user_data) { DiaSvgRenderer *renderer; int i; gchar *point; gchar *png_filename = NULL; DiaExportFilter *exportfilter; gfloat old_scaling; Rectangle *ext = &data->extents; gfloat scaling_x, scaling_y; /* create the png preview shown in the toolbox */ point = strrchr(filename, '.'); if (point == NULL || strcmp(point, ".shape")) { message_warning(_("Shape files must end in .shape, or they cannot be loaded by Dia")); return; } i = (int)(point-filename); point = g_strndup(filename, i); png_filename = g_strdup_printf("%s.png",point); g_free(point); /* we are especially requesting the libart/png cause it is the only one with the size-hack */ exportfilter = filter_get_by_name ("png-libart"); /* ... but the code below does not use the size-hack anymore ... */ if (!exportfilter) exportfilter = filter_guess_export_filter(png_filename); if (!exportfilter) { message_warning(_("Can't export png icon without export plug-in!")); } else { /* get the scaling right */ old_scaling = data->paper.scaling; scaling_x = 22/((ext->right - ext->left) * 20); scaling_y = 22/((ext->bottom - ext->top) * 20); data->paper.scaling = MIN(scaling_x, scaling_y); exportfilter->export_func(data, png_filename, diafilename, exportfilter->user_data); data->paper.scaling = old_scaling; } /* create the shape */ if((renderer = new_shape_renderer(data, filename))) { data_render(data, DIA_RENDERER(renderer), NULL, NULL, NULL); g_object_unref (renderer); } /* Create a sheet entry if applicable (../../sheets exists) */ g_free(png_filename); }
static gint properties_apply(GtkWidget *canvas, gpointer data) { ObjectChange *obj_change = NULL; if ( (current_obj == NULL) || (current_dia == NULL) ) return 0; object_add_updates(current_obj, current_dia); obj_change = current_obj->ops->apply_properties(current_obj); object_add_updates(current_obj, current_dia); diagram_update_connections_object(current_dia, current_obj, TRUE); if (obj_change != NULL) { undo_object_change(current_dia, current_obj, obj_change); } diagram_modified(current_dia); diagram_update_extents(current_dia); if (obj_change != NULL) { undo_set_transactionpoint(current_dia->undo); } else { message_warning(_("This object doesn't support Undo/Redo.\n" "Undo information erased.")); undo_clear(current_dia->undo); } diagram_flush(current_dia); return 0; }
/** * Kind of dirty way to initialize an anti-aliased renderer, maybe there * should be some plug-in interface to do this. * With the Libart renderer being a deprecated plug-in and the cairo renderer * offering a lot of features including proper highlighting it seems reasonable * to have default at cairo, although you loose a lot when it is switched off ;) */ static DiaRenderer * new_aa_renderer (DDisplay *ddisp) { GType renderer_type; renderer_type = g_type_from_name ("DiaCairoInteractiveRenderer"); if (renderer_type) { DiaRenderer *renderer = g_object_new(renderer_type, NULL); g_object_set (renderer, "zoom", &ddisp->zoom_factor, "rect", &ddisp->visible, NULL); return renderer; } renderer_type = g_type_from_name ("DiaLibartRenderer"); if (renderer_type) { DiaRenderer *renderer = g_object_new(renderer_type, NULL); g_object_set (renderer, "transform", dia_transform_new (&ddisp->visible, &ddisp->zoom_factor), NULL); return renderer; } /* we really should not come here but instead disable the menu command earlier */ message_warning (_("No antialiased renderer found")); /* fallback: built-in libart renderer */ return new_gdk_renderer (ddisp); }
/// This message is needed in multiple places in compressed_name(), /// so the message has been put into its own function. static void msg_suffix(const char *src_name, const char *suffix) { message_warning(_("%s: File already has `%s' suffix, skipping"), src_name, suffix); return; }
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); }
static gint properties_respond(GtkWidget *widget, gint response_id, gpointer data) { ObjectChange *obj_change = NULL; gboolean set_tp = TRUE; GList *tmp; if ( response_id == GTK_RESPONSE_APPLY || response_id == GTK_RESPONSE_OK) { if ((current_objects != NULL) && (current_dia != NULL)) { object_add_updates_list(current_objects, current_dia); for (tmp = current_objects; tmp != NULL; tmp = tmp->next) { DiaObject *current_obj = (DiaObject*)tmp->data; obj_change = current_obj->ops->apply_properties_from_dialog(current_obj, object_part); object_add_updates(current_obj, current_dia); diagram_update_connections_object(current_dia, current_obj, TRUE); if (obj_change != NULL) { undo_object_change(current_dia, current_obj, obj_change); set_tp = set_tp && TRUE; } else set_tp = FALSE; diagram_object_modified(current_dia, current_obj); } diagram_modified(current_dia); diagram_update_extents(current_dia); if (set_tp) { undo_set_transactionpoint(current_dia->undo); } else { message_warning(_("This object doesn't support Undo/Redo.\n" "Undo information erased.")); undo_clear(current_dia->undo); } diagram_flush(current_dia); } } if (response_id != GTK_RESPONSE_APPLY) { #ifdef G_OS_WIN32 /* on windows we are not hiding the dialog, because shrinking when hidden does * not work (the dialog shows up with the same size as before, bug #333751) */ gtk_widget_destroy (dialog); #else properties_dialog_hide(); #endif } return 0; }
/// \brief Removes the filename suffix of the compressed file /// /// \return Name of the uncompressed file, or NULL if file has unknown /// suffix. static char * uncompressed_name(const char *src_name, const size_t src_len) { static const struct { const char *compressed; const char *uncompressed; } suffixes[] = { { ".xz", "" }, { ".txz", ".tar" }, // .txz abbreviation for .txt.gz is rare. { ".lzma", "" }, { ".tlz", ".tar" }, // { ".gz", "" }, // { ".tgz", ".tar" }, }; const char *new_suffix = ""; size_t new_len = 0; if (opt_format == FORMAT_RAW) { // Don't check for known suffixes when --format=raw was used. if (custom_suffix == NULL) { message_error(_("%s: With --format=raw, " "--suffix=.SUF is required unless " "writing to stdout"), src_name); return NULL; } } else { for (size_t i = 0; i < ARRAY_SIZE(suffixes); ++i) { new_len = test_suffix(suffixes[i].compressed, src_name, src_len); if (new_len != 0) { new_suffix = suffixes[i].uncompressed; break; } } } if (new_len == 0 && custom_suffix != NULL) new_len = test_suffix(custom_suffix, src_name, src_len); if (new_len == 0) { message_warning(_("%s: Filename has an unknown suffix, " "skipping"), src_name); return NULL; } const size_t new_suffix_len = strlen(new_suffix); char *dest_name = xmalloc(new_len + new_suffix_len + 1); memcpy(dest_name, src_name, new_len); memcpy(dest_name + new_len, new_suffix, new_suffix_len); dest_name[new_len + new_suffix_len] = '\0'; return dest_name; }
void dia_context_release (DiaContext *context) { /* FIXME: this should vanish */ if (context->messages) message_warning ("%s:\n%s", context->desc ? context->desc : "<no context>", context->messages->data); g_object_unref (G_OBJECT (context)); }
void sheet_append_sheet_obj(Sheet *sheet, SheetObject *obj) { ObjectType *type; type = object_get_type(obj->object_type); if (type == NULL) { message_warning("Object '%s' needed in sheet '%s' was not found.\n" "It will not be availible for use.", obj->object_type, sheet->name); } else { sheet->objects = g_slist_append( sheet->objects, (gpointer) obj); } }
/** Convert Base64 to pixbuf * @param b64 Base64 encoded data */ GdkPixbuf * pixbuf_decode_base64 (const gchar *b64) { /* see lib/prop_pixbuf.c(data_pixbuf) for a very similar implementation */ GdkPixbuf *pixbuf = NULL; GdkPixbufLoader *loader; GError *error = NULL; loader = gdk_pixbuf_loader_new (); if (loader) { gint state = 0; guint save = 0; # define BUF_SIZE 4096 guchar buf[BUF_SIZE]; gchar *in = (gchar *)b64; /* direct access, not involving another xmlStrDup/xmlFree */ gssize len = strlen (b64); do { gsize step = g_base64_decode_step (in, len > BUF_SIZE ? BUF_SIZE : len, buf, &state, &save); if (!gdk_pixbuf_loader_write (loader, buf, step, &error)) break; in += BUF_SIZE; len -= BUF_SIZE; } while (len > 0); if (gdk_pixbuf_loader_close (loader, error ? NULL : &error)) { GdkPixbufFormat *format = gdk_pixbuf_loader_get_format (loader); gchar *format_name = gdk_pixbuf_format_get_name (format); gchar **mime_types = gdk_pixbuf_format_get_mime_types (format); dia_log_message ("Loaded pixbuf from '%s' with '%s'\n", format_name, mime_types[0]); pixbuf = g_object_ref (gdk_pixbuf_loader_get_pixbuf (loader)); /* attach the mime-type to the pixbuf */ g_object_set_data_full (G_OBJECT (pixbuf), "mime-type", g_strdup (mime_types[0]), (GDestroyNotify)g_free); g_strfreev (mime_types); g_free (format_name); } else { message_warning (_("Failed to load image form diagram:\n%s"), error->message); g_error_free (error); } g_object_unref (loader); } return pixbuf; # undef BUF_SIZE }
static void parse_path(ShapeInfo *info, const char *path_str, DiaSvgStyle *s, const char* filename) { GArray *points; gchar *pathdata = (gchar *)path_str, *unparsed; gboolean closed = FALSE; Point current_point = {0.0, 0.0}; points = g_array_new(FALSE, FALSE, sizeof(BezPoint)); g_array_set_size(points, 0); do { if (!dia_svg_parse_path (points, pathdata, &unparsed, &closed, ¤t_point)) break; if (points->len > 0) { if (g_array_index(points, BezPoint, 0).type != BEZ_MOVE_TO) { message_warning (_("The file '%s' has invalid path data.\n" "svg:path data must start with moveto."), dia_message_filename(filename)); } else if (closed) { /* if there is some unclosed commands, add them as a GE_SHAPE */ GraphicElementPath *el = g_malloc(sizeof(GraphicElementPath) + points->len * sizeof(BezPoint)); el->type = GE_SHAPE; dia_svg_style_init (&el->s, s); el->npoints = points->len; memcpy((char *)el->points, points->data, points->len*sizeof(BezPoint)); info->display_list = g_list_append(info->display_list, el); } else { /* if there is some unclosed commands, add them as a GE_PATH */ GraphicElementPath *el = g_malloc(sizeof(GraphicElementPath) + points->len * sizeof(BezPoint)); el->type = GE_PATH; dia_svg_style_init (&el->s, s); el->npoints = points->len; memcpy((char *)el->points, points->data, points->len*sizeof(BezPoint)); info->display_list = g_list_append(info->display_list, el); } g_array_set_size (points, 0); } pathdata = unparsed; unparsed = NULL; } while (pathdata); g_array_free (points, TRUE); }
GdkPixbuf * data_pixbuf (DataNode data) { GdkPixbuf *pixbuf = NULL; GdkPixbufLoader *loader; GError *error = NULL; AttributeNode attr = composite_find_attribute(data, "data"); loader = gdk_pixbuf_loader_new (); if (loader) { xmlNode *node = attribute_first_data (attr); gint state = 0; guint save = 0; # define BUF_SIZE 4096 guchar buf[BUF_SIZE]; gchar *in = NULL; /* direct access, not involving another xmlStrDup/xmlFree */ gssize len = 0; if (node->children && xmlStrcmp (node->children->name, (const xmlChar*)"text") == 0) { in = (gchar *)node->children->content; len = strlen ((char *)in); } do { gsize step = g_base64_decode_step (in, len > BUF_SIZE ? BUF_SIZE : len, buf, &state, &save); if (!gdk_pixbuf_loader_write (loader, buf, step, &error)) break; in += BUF_SIZE; len -= BUF_SIZE; } while (len > 0); if (gdk_pixbuf_loader_close (loader, error ? NULL : &error)) { pixbuf = g_object_ref (gdk_pixbuf_loader_get_pixbuf (loader)); } else { message_warning (_("Failed to load image form diagram:\n%s"), error->message); g_error_free (error); } g_object_unref (loader); } # undef BUF_SIZE return pixbuf; }
/** Return an absolute filename from an absolute or relative filename. * @param filename A relative or absolute filename. * @return Absolute and canonicalized filename as a newly allocated string. */ gchar * dia_get_absolute_filename (const gchar *filename) { gchar *current_dir; gchar *fullname; gchar *canonical; if (filename == NULL) return NULL; if (g_path_is_absolute(filename)) return dia_get_canonical_path(filename); current_dir = g_get_current_dir(); fullname = g_build_filename(current_dir, filename, NULL); g_free(current_dir); if (strchr(fullname, '.') == NULL) return fullname; canonical = dia_get_canonical_path(fullname); if (canonical == NULL) { message_warning(_("Too many \"..\"s in filename %s\n"), dia_message_filename(filename)); return g_strdup(filename); } g_free(fullname); return canonical; }
static ObjectChange * image_apply_properties(Image *image) { gchar *new_file; ObjectState *old_state; if (image != image_properties_dialog->image) { message_warning("Image dialog problem: %p != %p\n", image, image_properties_dialog->image); image = image_properties_dialog->image; } old_state = (ObjectState *)image_get_state(image); image->border_width = gtk_spin_button_get_value_as_float(image_properties_dialog->border_width); dia_color_selector_get_color(image_properties_dialog->fg_color, &image->border_color); dia_line_style_selector_get_linestyle(image_properties_dialog->line_style, &image->line_style, NULL); image->draw_border = gtk_toggle_button_get_active(image_properties_dialog->draw_border); image->keep_aspect = gtk_toggle_button_get_active(image_properties_dialog->keep_aspect); new_file = dia_file_selector_get_file(image_properties_dialog->file); if (image->file) g_free(image->file); if (image->image) { dia_image_release(image->image); } image->image = dia_image_load(new_file); if ((image->image != NULL) && (image->keep_aspect)) { /* Must... keep... aspect... ratio... */ float ratio = (float)dia_image_height(image->image)/ (float)dia_image_width(image->image); image->element.height = image->element.width * ratio; } image->file = g_strdup(new_file); image_update_data(image); return new_object_state_change((Object *)image, old_state, (GetStateFunc)image_get_state, (SetStateFunc)image_set_state); }
/** Convert Base64 to pixbuf * @param b64 Base64 encoded data */ GdkPixbuf * pixbuf_decode_base64 (const gchar *b64) { /* see lib/prop_pixbuf.c(data_pixbuf) for a very similiar implementation */ GdkPixbuf *pixbuf = NULL; GdkPixbufLoader *loader; GError *error = NULL; loader = gdk_pixbuf_loader_new (); if (loader) { gint state = 0; guint save = 0; # define BUF_SIZE 4096 guchar buf[BUF_SIZE]; gchar *in = (gchar *)b64; /* direct access, not involving another xmlStrDup/xmlFree */ gssize len = strlen (b64); do { gsize step = g_base64_decode_step (in, len > BUF_SIZE ? BUF_SIZE : len, buf, &state, &save); if (!gdk_pixbuf_loader_write (loader, buf, step, &error)) break; in += BUF_SIZE; len -= BUF_SIZE; } while (len > 0); if (gdk_pixbuf_loader_close (loader, error ? NULL : &error)) { pixbuf = g_object_ref (gdk_pixbuf_loader_get_pixbuf (loader)); } else { message_warning (_("Failed to load image form diagram:\n%s"), error->message); g_error_free (error); } g_object_unref (loader); } return pixbuf; # undef BUF_SIZE }
void dia_cell_renderer_property_clicked (DiaCellRendererProperty *cell, const gchar *path, GdkModifierType state) { GdkEvent *event; g_return_if_fail (DIA_IS_CELL_RENDERER_PROPERTY (cell)); g_return_if_fail (path != NULL); g_signal_emit (cell, property_cell_signals[CLICKED], 0, path, state); event = gtk_get_current_event (); if (event) { GdkEventButton *bevent = (GdkEventButton *) event; if (bevent->type == GDK_BUTTON_PRESS && (bevent->button == 1 || bevent->button == 2)) { #if 0 dia_view_popup_show (gtk_get_event_widget (event), bevent, cell->renderer->context, cell->renderer->property, cell->renderer->width, cell->renderer->height, cell->renderer->dot_for_dot); #else /* either edit the property itself _or_ if it is a list open another property list */ message_warning ("Clicked!"); #endif } gdk_event_free (event); } }
static void enumprop_load(EnumProperty *prop, AttributeNode attr, DataNode data) { DataType dt = data_type (data); if (DATATYPE_ENUM == dt) prop->enum_data = data_enum(data); else if (DATATYPE_INT == dt) { gboolean cast_ok = FALSE; PropEnumData *enumdata = prop->common.extra_data; guint i, v = data_int(data); for (i = 0; enumdata[i].name != NULL; ++i) { if (v == enumdata[i].enumv) { prop->enum_data = v; cast_ok = TRUE; break; } } if (!cast_ok) { prop->enum_data = enumdata[0].enumv; message_warning (_("Property cast from int to enum out of range")); } } }
void create_object_pixmap(SheetObject *so, GtkWidget *parent, GdkPixmap **pixmap, GdkBitmap **mask) { GtkStyle *style; g_assert(so); g_assert(pixmap); g_assert(mask); style = gtk_widget_get_style(parent); if (so->pixmap != NULL) { *pixmap = gdk_pixmap_colormap_create_from_xpm_d(NULL, gtk_widget_get_colormap(parent), mask, &style->bg[GTK_STATE_NORMAL], (gchar **)so->pixmap); } else { if (so->pixmap_file != NULL) { GdkPixbuf *pixbuf; GError *error = NULL; pixbuf = gdk_pixbuf_new_from_file(so->pixmap_file, &error); if (pixbuf != NULL) { int width = gdk_pixbuf_get_width (pixbuf); int height = gdk_pixbuf_get_height (pixbuf); if (width > 22 && prefs.fixed_icon_size) { GdkPixbuf *cropped; g_warning ("Shape icon '%s' size wrong, cropped.", so->pixmap_file); cropped = gdk_pixbuf_new_subpixbuf (pixbuf, (width - 22) / 2, height > 22 ? (height - 22) / 2 : 0, 22, height > 22 ? 22 : height); g_object_unref (pixbuf); pixbuf = cropped; } gdk_pixbuf_render_pixmap_and_mask(pixbuf, pixmap, mask, 1.0); g_object_unref(pixbuf); } else { message_warning ("%s", error->message); g_error_free (error); *pixmap = gdk_pixmap_colormap_create_from_xpm_d (NULL, gtk_widget_get_colormap(parent), mask, &style->bg[GTK_STATE_NORMAL], (gchar **)missing); } } else { *pixmap = NULL; *mask = NULL; } } }
/** * Respond to a button press (also destroy) in the save as dialog. */ static void file_save_as_response_callback(GtkWidget *fs, gint response, gpointer user_data) { char *filename; Diagram *dia; struct stat stat_struct; if (response == GTK_RESPONSE_ACCEPT) { dia = g_object_get_data (G_OBJECT(fs), "user_data"); filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fs)); if (!filename) { /* Not getting a filename looks like a contract violation in Gtk+ to me. * Still Dia would be crashing (bug #651949) - instead simply go back to the dialog. */ gtk_window_present (GTK_WINDOW (fs)); return; } if (g_stat(filename, &stat_struct) == 0) { GtkWidget *dialog = NULL; char *utf8filename = NULL; if (!g_utf8_validate(filename, -1, NULL)) { utf8filename = g_filename_to_utf8(filename, -1, NULL, NULL, NULL); if (utf8filename == NULL) { message_warning(_("Some characters in the filename are neither UTF-8\n" "nor your local encoding.\nSome things will break.")); } } if (utf8filename == NULL) utf8filename = g_strdup(filename); dialog = gtk_message_dialog_new (GTK_WINDOW(fs), GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, _("File already exists")); gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog), _("The file '%s' already exists.\n" "Do you want to overwrite it?"), utf8filename); g_free(utf8filename); gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_YES); if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_YES) { /* don't hide/destroy the dialog, but simply go back to it */ gtk_window_present (GTK_WINDOW (fs)); gtk_widget_destroy(dialog); g_free (filename); return; } gtk_widget_destroy(dialog); } dia->data->is_compressed = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(user_data)); diagram_update_extents(dia); { DiaContext *ctx = dia_context_new (_("Save as")); diagram_set_filename(dia, filename); dia_context_set_filename (ctx, filename); if (diagram_save(dia, filename, ctx)) recent_file_history_add(filename); dia_context_release (ctx); } g_free (filename); } /* if we have our own reference, drop it before destroy */ if ((dia = g_object_get_data (G_OBJECT(fs), "user_data")) != NULL) { g_object_set_data (G_OBJECT(fs), "user_data", NULL); g_object_unref (dia); } /* if we destroy it gtk_dialog_run wont give the response */ if (!g_object_get_data (G_OBJECT(fs), "dont-destroy")) gtk_widget_destroy(GTK_WIDGET(fs)); }
static ObjectChange* image_move_handle(EImage *image, Handle *handle, Point *to, ConnectionPoint *cp, HandleMoveReason reason, ModifierKeys modifiers) { Element *elem = &image->element; assert(image!=NULL); assert(handle!=NULL); assert(to!=NULL); if (image->keep_aspect) { float width, height; float new_width, new_height; width = image->element.width; height = image->element.height; switch (handle->id) { case HANDLE_RESIZE_NW: new_width = -(to->x-image->element.corner.x)+width; new_height = -(to->y-image->element.corner.y)+height; if (new_height == 0 || new_width/new_height > width/height) { new_height = new_width*height/width; } else { new_width = new_height*width/height; } to->x = image->element.corner.x+(image->element.width-new_width); to->y = image->element.corner.y+(image->element.height-new_height); element_move_handle(elem, HANDLE_RESIZE_NW, to, cp, reason, modifiers); break; case HANDLE_RESIZE_N: new_width = (-(to->y-image->element.corner.y)+height)*width/height; to->x = image->element.corner.x+new_width; element_move_handle(elem, HANDLE_RESIZE_NE, to, cp, reason, modifiers); break; case HANDLE_RESIZE_NE: new_width = to->x-image->element.corner.x; new_height = -(to->y-image->element.corner.y)+height; if (new_height == 0 || new_width/new_height > width/height) { new_height = new_width*height/width; } else { new_width = new_height*width/height; } to->x = image->element.corner.x+new_width; to->y = image->element.corner.y+(image->element.height-new_height); element_move_handle(elem, HANDLE_RESIZE_NE, to, cp, reason, modifiers); break; case HANDLE_RESIZE_E: new_height = (to->x-image->element.corner.x)*height/width; to->y = image->element.corner.y+new_height; element_move_handle(elem, HANDLE_RESIZE_SE, to, cp, reason, modifiers); break; case HANDLE_RESIZE_SE: new_width = to->x-image->element.corner.x; new_height = to->y-image->element.corner.y; if (new_height == 0 || new_width/new_height > width/height) { new_height = new_width*height/width; } else { new_width = new_height*width/height; } to->x = image->element.corner.x+new_width; to->y = image->element.corner.y+new_height; element_move_handle(elem, HANDLE_RESIZE_SE, to, cp, reason, modifiers); break; case HANDLE_RESIZE_S: new_width = (to->y-image->element.corner.y)*width/height; to->x = image->element.corner.x+new_width; element_move_handle(elem, HANDLE_RESIZE_SE, to, cp, reason, modifiers); break; case HANDLE_RESIZE_SW: new_width = -(to->x-image->element.corner.x)+width; new_height = to->y-image->element.corner.y; if (new_height == 0 || new_width/new_height > width/height) { new_height = new_width*height/width; } else { new_width = new_height*width/height; } to->x = image->element.corner.x+(image->element.width-new_width); to->y = image->element.corner.y+new_height; element_move_handle(elem, HANDLE_RESIZE_SW, to, cp, reason, modifiers); break; case HANDLE_RESIZE_W: new_height = (-(to->x-image->element.corner.x)+width)*height/width; to->y = image->element.corner.y+new_height; element_move_handle(elem, HANDLE_RESIZE_SW, to, cp, reason, modifiers); break; default: message_warning("Unforeseen handle in image_move_handle: %d\n", handle->id); } } else { element_move_handle(elem, handle->id, to, cp, reason, modifiers); } image_update_data(image); return NULL; }
static DiaObject * image_load(ObjectNode obj_node, int version, const char *filename) { EImage *image; Element *elem; DiaObject *obj; int i; AttributeNode attr; char *diafile_dir; Diagram *dia; GList *list; image = g_malloc0(sizeof(EImage)); elem = &image->element; obj = &elem->object; obj->type = &eimage_type; obj->ops = &eimage_ops; element_load(elem, obj_node); image->border_width = 0.1; attr = object_find_attribute(obj_node, "border_width"); if (attr != NULL) image->border_width = data_real( attribute_first_data(attr) ); image->border_color = color_black; attr = object_find_attribute(obj_node, "border_color"); if (attr != NULL) data_color(attribute_first_data(attr), &image->border_color); image->line_style = LINESTYLE_SOLID; attr = object_find_attribute(obj_node, "line_style"); if (attr != NULL) image->line_style = data_enum( attribute_first_data(attr) ); image->dashlength = DEFAULT_LINESTYLE_DASHLEN; attr = object_find_attribute(obj_node, "dashlength"); if (attr != NULL) image->dashlength = data_real(attribute_first_data(attr)); image->draw_border = TRUE; attr = object_find_attribute(obj_node, "draw_border"); if (attr != NULL) image->draw_border = data_boolean( attribute_first_data(attr) ); image->keep_aspect = TRUE; attr = object_find_attribute(obj_node, "keep_aspect"); if (attr != NULL) image->keep_aspect = data_boolean( attribute_first_data(attr) ); image->keep_orig_aspect = TRUE; attr = object_find_attribute(obj_node, "keep_orig_aspect"); if (attr != NULL) image->keep_orig_aspect = data_boolean( attribute_first_data(attr) ); attr = object_find_attribute(obj_node, "file"); if (attr != NULL) { image->file = data_filename( attribute_first_data(attr) ); } else { image->file = g_strdup(""); } attr = object_find_attribute(obj_node, "embed_id"); if (attr) { image->embed_id = dtree_conv_longname_from_xml(data_string(attribute_first_data(attr))); } else { image->embed_id = get_default_embed_id("embed_image"); } register_embed_id(image->embed_id); element_init(elem, 8, NUM_CONNECTIONS); for (i=0;i<NUM_CONNECTIONS;i++) { obj->connections[i] = &image->connections[i]; image->connections[i].object = obj; image->connections[i].connected = NULL; } image->connections[8].flags = CP_FLAGS_MAIN; image->image = NULL; if (strcmp(image->file, "")!=0) { diafile_dir = get_directory(filename); if (g_path_is_absolute(image->file)) { /* Absolute pathname */ image->image = dia_image_load(image->file); if (image->image == NULL) { /* Not found as abs path, try in same dir as diagram. */ char *temp_string; const char *image_file_name = image->file; const char *psep; psep = strrchr(image->file, G_DIR_SEPARATOR); /* try the other G_OS as well */ if (!psep) psep = strrchr(image->file, G_DIR_SEPARATOR == '/' ? '\\' : '/'); if (psep) image_file_name = psep + 1; temp_string = g_build_filename(diafile_dir, image_file_name, NULL); image->image = dia_image_load(temp_string); if (image->image != NULL) { /* Found file in same dir as diagram. */ message_warning(_("The image file '%s' was not found in that directory.\n" "Using the file '%s' instead\n"), image->file, temp_string); g_free(image->file); image->file = temp_string; } else { g_free(temp_string); image->image = dia_image_load((char *)image_file_name); if (image->image != NULL) { char *tmp; /* Found file in current dir. */ message_warning(_("The image file '%s' was not found in that directory.\n" "Using the file '%s' instead\n"), image->file, image_file_name); tmp = image->file; image->file = g_strdup(image_file_name); g_free(tmp); } else { message_warning(_("The image file '%s' was not found.\n"), image_file_name); } } } } else { /* Relative pathname: */ char *temp_string; temp_string = g_build_filename (diafile_dir, image->file, NULL); image->image = dia_image_load(temp_string); if (image->image != NULL) { /* Found file in same dir as diagram. */ g_free(image->file); image->file = temp_string; } else { g_free(temp_string); image->image = dia_image_load(image->file); if (image->image == NULL) { /* Didn't find file in current dir. */ message_warning(_("The image file '%s' was not found.\n"), image->file); } } } g_free(diafile_dir); } /* update mtime */ { struct stat st; if (g_stat (image->file, &st) != 0) st.st_mtime = 0; image->mtime = st.st_mtime; } image_update_data(image); obj->node = NULL; list = dia_open_diagrams(); while (list != NULL) { dia = (Diagram *)list->data; if (!g_strcmp0(dia->filename,filename)) { obj->node = dtree_set_data_by_longname(DIA_DIAGRAM_DATA(dia)->dtree, image->embed_id,&image->element.object); } list = g_list_next(list); } return &image->element.object; }
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); } }
static void set_font(DiaRenderer *self, DiaFont *font, real height) { WmfRenderer *renderer = WMF_RENDERER (self); W32::LPCTSTR sFace; W32::DWORD dwItalic = 0; W32::DWORD dwWeight = FW_DONTCARE; DiaFontStyle style = dia_font_get_style(font); real font_size = dia_font_get_size (font) * (height / dia_font_get_height (font)); DIAG_NOTE(renderer, "set_font %s %f\n", dia_font_get_family (font), height); if (renderer->hFont) { W32::DeleteObject(renderer->hFont); renderer->hFont = NULL; } if (renderer->pango_context) { g_object_unref (renderer->pango_context); renderer->pango_context = NULL; } if (renderer->use_pango) { #ifdef __PANGOWIN32_H__ /* with the pangowin32 backend there is a better way */ if (!renderer->pango_context) renderer->pango_context = pango_win32_get_context (); PangoFont* pf = pango_context_load_font (renderer->pango_context, dia_font_get_description (font)); if (pf) { W32::LOGFONT* lf = pango_win32_font_logfont (pf); /* .93 : sligthly smaller looks much better */ lf->lfHeight = -SC(height*.93); lf->lfHeight = -SC(font_size); renderer->hFont = (W32::HFONT)W32::CreateFontIndirect (lf); g_free (lf); g_object_unref (pf); } else { gchar *desc = pango_font_description_to_string (dia_font_get_description (font)); message_warning (_("Can not render unknown font:\n%s"), desc); g_free (desc); } #else g_assert_not_reached(); #endif } else { sFace = dia_font_get_family (font); dwItalic = DIA_FONT_STYLE_GET_SLANT(style) != DIA_FONT_NORMAL; /* although there is a known algorithm avoid it for cleanness */ switch (DIA_FONT_STYLE_GET_WEIGHT(style)) { case DIA_FONT_ULTRALIGHT : dwWeight = FW_ULTRALIGHT; break; case DIA_FONT_LIGHT : dwWeight = FW_LIGHT; break; case DIA_FONT_MEDIUM : dwWeight = FW_MEDIUM; break; case DIA_FONT_DEMIBOLD : dwWeight = FW_DEMIBOLD; break; case DIA_FONT_BOLD : dwWeight = FW_BOLD; break; case DIA_FONT_ULTRABOLD : dwWeight = FW_ULTRABOLD; break; case DIA_FONT_HEAVY : dwWeight = FW_HEAVY; break; default : dwWeight = FW_NORMAL; break; } //Hack to get BYTE out of namespace W32 # ifndef BYTE # define BYTE unsigned char # endif renderer->hFont = (W32::HFONT)W32::CreateFont( - SC (font_size), // logical height of font 0, // logical average character width 0, // angle of escapement 0, // base-line orientation angle dwWeight, // font weight dwItalic, // italic attribute flag 0, // underline attribute flag 0, // strikeout attribute flag DEFAULT_CHARSET, // character set identifier OUT_TT_PRECIS, // output precision CLIP_DEFAULT_PRECIS, // clipping precision PROOF_QUALITY, // output quality DEFAULT_PITCH, // pitch and family sFace); // pointer to typeface name string } }
/// \brief Appends suffix to src_name /// /// In contrast to uncompressed_name(), we check only suffixes that are valid /// for the specified file format. static char * compressed_name(const char *src_name, const size_t src_len) { // The order of these must match the order in args.h. static const char *const all_suffixes[][3] = { { ".xz", ".txz", NULL }, { ".lzma", ".tlz", NULL /* }, { ".gz", ".tgz", NULL */ }, { // --format=raw requires specifying the suffix // manually or using stdout. NULL } }; // args.c ensures this. assert(opt_format != FORMAT_AUTO); const size_t format = opt_format - 1; const char *const *suffixes = all_suffixes[format]; for (size_t i = 0; suffixes[i] != NULL; ++i) { if (test_suffix(suffixes[i], src_name, src_len) != 0) { message_warning(_("%s: File already has `%s' " "suffix, skipping"), src_name, suffixes[i]); return NULL; } } if (custom_suffix != NULL) { if (test_suffix(custom_suffix, src_name, src_len) != 0) { message_warning(_("%s: File already has `%s' " "suffix, skipping"), src_name, custom_suffix); return NULL; } } // TODO: Hmm, maybe it would be better to validate this in args.c, // since the suffix handling when decoding is weird now. if (opt_format == FORMAT_RAW && custom_suffix == NULL) { message_error(_("%s: With --format=raw, " "--suffix=.SUF is required unless " "writing to stdout"), src_name); return NULL; } const char *suffix = custom_suffix != NULL ? custom_suffix : suffixes[0]; const size_t suffix_len = strlen(suffix); char *dest_name = xmalloc(src_len + suffix_len + 1); memcpy(dest_name, src_name, src_len); memcpy(dest_name + src_len, suffix, suffix_len); dest_name[src_len + suffix_len] = '\0'; return dest_name; }
static DiaObject * image_load(ObjectNode obj_node, int version, DiaContext *ctx) { Image *image; Element *elem; DiaObject *obj; int i; AttributeNode attr; char *diafile_dir; image = g_malloc0(sizeof(Image)); elem = &image->element; obj = &elem->object; obj->type = &image_type; obj->ops = &image_ops; element_load(elem, obj_node, ctx); image->border_width = 0.1; attr = object_find_attribute(obj_node, "border_width"); if (attr != NULL) image->border_width = data_real(attribute_first_data(attr), ctx); image->border_color = color_black; attr = object_find_attribute(obj_node, "border_color"); if (attr != NULL) data_color(attribute_first_data(attr), &image->border_color, ctx); image->line_style = LINESTYLE_SOLID; attr = object_find_attribute(obj_node, "line_style"); if (attr != NULL) image->line_style = data_enum(attribute_first_data(attr), ctx); image->dashlength = DEFAULT_LINESTYLE_DASHLEN; attr = object_find_attribute(obj_node, "dashlength"); if (attr != NULL) image->dashlength = data_real(attribute_first_data(attr), ctx); image->draw_border = TRUE; attr = object_find_attribute(obj_node, "draw_border"); if (attr != NULL) image->draw_border = data_boolean(attribute_first_data(attr), ctx); image->keep_aspect = TRUE; attr = object_find_attribute(obj_node, "keep_aspect"); if (attr != NULL) image->keep_aspect = data_boolean(attribute_first_data(attr), ctx); attr = object_find_attribute(obj_node, "file"); if (attr != NULL) { image->file = data_filename(attribute_first_data(attr), ctx); } else { image->file = g_strdup(""); } element_init(elem, 8, NUM_CONNECTIONS); for (i=0;i<NUM_CONNECTIONS;i++) { obj->connections[i] = &image->connections[i]; image->connections[i].object = obj; image->connections[i].connected = NULL; } image->connections[8].flags = CP_FLAGS_MAIN; image->image = NULL; if (strcmp(image->file, "")!=0) { diafile_dir = get_directory(dia_context_get_filename(ctx)); if (g_path_is_absolute(image->file)) { /* Absolute pathname */ image->image = dia_image_load(image->file); if (image->image == NULL) { /* Not found as abs path, try in same dir as diagram. */ char *temp_string; const char *image_file_name = image->file; const char *psep; psep = strrchr(image->file, G_DIR_SEPARATOR); /* try the other G_OS as well */ if (!psep) psep = strrchr(image->file, G_DIR_SEPARATOR == '/' ? '\\' : '/'); if (psep) image_file_name = psep + 1; temp_string = g_build_filename(diafile_dir, image_file_name, NULL); image->image = dia_image_load(temp_string); if (image->image != NULL) { /* Found file in same dir as diagram. */ message_warning(_("The image file '%s' was not found in the specified directory.\n" "Using the file '%s' instead.\n"), image->file, temp_string); g_free(image->file); image->file = temp_string; } else { g_free(temp_string); image->image = dia_image_load((char *)image_file_name); if (image->image != NULL) { char *tmp; /* Found file in current dir. */ message_warning(_("The image file '%s' was not found in the specified directory.\n" "Using the file '%s' instead.\n"), image->file, image_file_name); tmp = image->file; image->file = g_strdup(image_file_name); g_free(tmp); } else { message_warning(_("The image file '%s' was not found.\n"), image_file_name); } } } } else { /* Relative pathname: */ char *temp_string; temp_string = g_build_filename (diafile_dir, image->file, NULL); image->image = dia_image_load(temp_string); if (image->image != NULL) { /* Found file in same dir as diagram. */ g_free(image->file); image->file = temp_string; } else { g_free(temp_string); image->image = dia_image_load(image->file); if (image->image == NULL) { /* Didn't find file in current dir. */ message_warning(_("The image file '%s' was not found.\n"), image->file); } } } g_free(diafile_dir); } /* if we don't have an image yet try to recover it from inlined data */ if (!image->image) { attr = object_find_attribute(obj_node, "pixbuf"); if (attr != NULL) { GdkPixbuf *pixbuf = data_pixbuf (attribute_first_data(attr)); if (pixbuf) { image->image = dia_image_new_from_pixbuf (pixbuf); image->inline_data = TRUE; /* avoid loosing it */ /* FIXME: should we reset the filename? */ g_object_unref (pixbuf); } } } /* update mtime */ { struct stat st; if (g_stat (image->file, &st) != 0) st.st_mtime = 0; image->mtime = st.st_mtime; } image_update_data(image); return &image->element.object; }
/*! * \brief Contructor for ShapeInfo from file * * Load the full shape info from file potentially reusing the preloaded * ShapeInfo loaded by shape_typeinfo_load() * * \extends _ShapeInfo */ static ShapeInfo * load_shape_info(const gchar *filename, ShapeInfo *preload) { xmlErrorPtr error_xml = NULL; xmlDocPtr doc = xmlDoParseFile(filename, &error_xml); xmlNsPtr shape_ns, svg_ns; xmlNodePtr node, root, ext_node = NULL; ShapeInfo *info; gchar *tmp; int i; if (!doc) { g_warning("Custom shape parser error for %s\n%s", filename, error_xml ? error_xml->message : ""); return NULL; } /* skip (emacs) comments */ root = doc->xmlRootNode; while (root && (root->type != XML_ELEMENT_NODE)) root = root->next; if (!root) return NULL; if (xmlIsBlankNode(root)) return NULL; if (!(shape_ns = xmlSearchNsByHref(doc, root, (const xmlChar *)"http://www.daa.com.au/~james/dia-shape-ns"))) { xmlFreeDoc(doc); g_warning("could not find shape namespace"); return NULL; } if (!(svg_ns = xmlSearchNsByHref(doc, root, (const xmlChar *)"http://www.w3.org/2000/svg"))) { xmlFreeDoc(doc); g_warning("could not find svg namespace"); return NULL; } if (root->ns != shape_ns || xmlStrcmp(root->name, (const xmlChar *)"shape")) { g_warning("root element was %s -- expecting shape", root->name); xmlFreeDoc(doc); return NULL; } if (preload) info = preload; else info = g_new0(ShapeInfo, 1); info->loaded = TRUE; info->shape_bounds.top = DBL_MAX; info->shape_bounds.left = DBL_MAX; info->shape_bounds.bottom = -DBL_MAX; info->shape_bounds.right = -DBL_MAX; info->aspect_type = SHAPE_ASPECT_FREE; info->default_width = 0.0; info->default_height = 0.0; info->main_cp = -1; info->object_flags = 0; i = 0; for (node = root->xmlChildrenNode; node != NULL; node = node->next) { if (xmlIsBlankNode(node)) continue; if (node->type != XML_ELEMENT_NODE) continue; if (node->ns == shape_ns && !xmlStrcmp(node->name, (const xmlChar *)"name")) { tmp = (gchar *) xmlNodeGetContent(node); if (preload) { if (strcmp (tmp, info->name) != 0) g_warning ("Shape(preload) '%s' can't change name '%s'", info->name, tmp); /* the key name is already used as key in name_to_info */ } else { g_free(info->name); info->name = g_strdup(tmp); } xmlFree(tmp); } else if (node->ns == shape_ns && !xmlStrcmp(node->name, (const xmlChar *)"icon")) { tmp = (gchar *) xmlNodeGetContent(node); if (preload) { if (strstr (info->icon, tmp) == NULL) /* the left including the absolute path */ g_warning ("Shape(preload) '%s' can't change icon '%s'", info->icon, tmp); /* the key name is already used as key in name_to_info */ } else { g_free(info->icon); info->icon = custom_get_relative_filename(filename, tmp); } xmlFree(tmp); } else if (node->ns == shape_ns && !xmlStrcmp(node->name, (const xmlChar *)"connections")) { GArray *arr = g_array_new(FALSE, FALSE, sizeof(Point)); xmlNodePtr pt_node; for (pt_node = node->xmlChildrenNode; pt_node != NULL; pt_node = pt_node->next) { if (xmlIsBlankNode(pt_node)) continue; if (pt_node->ns == shape_ns && !xmlStrcmp(pt_node->name, (const xmlChar *)"point")) { Point pt = { 0.0, 0.0 }; xmlChar *str; str = xmlGetProp(pt_node, (const xmlChar *)"x"); if (str) { pt.x = g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } str = xmlGetProp(pt_node, (const xmlChar *)"y"); if (str) { pt.y = g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } g_array_append_val(arr, pt); str = xmlGetProp(pt_node, (const xmlChar *)"main"); if (str && str[0] != '\0') { if (info->main_cp != -1) { message_warning("More than one main connection point in %s. Only the first one will be used.\n", info->name); } else { info->main_cp = i; } xmlFree(str); } } i++; } info->nconnections = arr->len; info->connections = (Point *)arr->data; g_array_free(arr, FALSE); } else if (node->ns == shape_ns && !xmlStrcmp(node->name, (const xmlChar *)"can-parent")) { info->object_flags |= DIA_OBJECT_CAN_PARENT; } else if (node->ns == shape_ns && !xmlStrcmp(node->name, (const xmlChar *)"textbox")) { xmlChar *str; str = xmlGetProp(node, (const xmlChar *)"x1"); if (str) { info->text_bounds.left = g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } str = xmlGetProp(node, (const xmlChar *)"y1"); if (str) { info->text_bounds.top = g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } str = xmlGetProp(node, (const xmlChar *)"x2"); if (str) { info->text_bounds.right = g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } str = xmlGetProp(node, (const xmlChar *)"y2"); if (str) { info->text_bounds.bottom = g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } info->resize_with_text = TRUE; str = xmlGetProp(node, (const xmlChar *)"resize"); if (str) { info->resize_with_text = TRUE; if (!xmlStrcmp(str,(const xmlChar *)"no")) info->resize_with_text = FALSE; xmlFree(str); } info->text_align = ALIGN_CENTER; str = xmlGetProp(node, (const xmlChar *)"align"); if (str) { if (!xmlStrcmp(str, (const xmlChar *)"left")) info->text_align = ALIGN_LEFT; else if (!xmlStrcmp(str, (const xmlChar *)"right")) info->text_align = ALIGN_RIGHT; xmlFree(str); } info->has_text = TRUE; } else if (node->ns == shape_ns && !xmlStrcmp(node->name, (const xmlChar *)"aspectratio")) { tmp = (gchar *) xmlGetProp(node, (const xmlChar *)"type"); if (tmp) { if (!strcmp(tmp, "free")) info->aspect_type = SHAPE_ASPECT_FREE; else if (!strcmp(tmp, "fixed")) info->aspect_type = SHAPE_ASPECT_FIXED; else if (!strcmp(tmp, "range")) { xmlChar *str; info->aspect_type = SHAPE_ASPECT_RANGE; info->aspect_min = 0.0; info->aspect_max = G_MAXFLOAT; str = xmlGetProp(node, (const xmlChar *)"min"); if (str) { info->aspect_min = g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } str = xmlGetProp(node, (const xmlChar *)"max"); if (str) { info->aspect_max = g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } if (info->aspect_max < info->aspect_min) { real asp = info->aspect_max; info->aspect_max = info->aspect_min; info->aspect_min = asp; } } xmlFree(tmp); } } else if (node->ns == shape_ns && (!xmlStrcmp(node->name, (const xmlChar *)"default-width") || !xmlStrcmp(node->name, (const xmlChar *)"default-height"))) { int j = 0; DiaUnitDef ud; gdouble val = 0.0; int unit_ssize = 0; int ssize = 0; tmp = (gchar *) xmlNodeGetContent(node); ssize = strlen(tmp); val = g_ascii_strtod(tmp, NULL); for (ud = units[j]; ud.name; ud = units[++j]) { unit_ssize = strlen(ud.unit); if (ssize > unit_ssize && !strcmp(tmp+(ssize-unit_ssize), ud.unit)) { val *= (ud.factor / 28.346457); break; } } if (!xmlStrcmp(node->name, (const xmlChar *)"default-width")) { info->default_width = val; } else { info->default_height = val; } xmlFree(tmp); } else if (node->ns == svg_ns && !xmlStrcmp(node->name, (const xmlChar *)"svg")) { DiaSvgStyle s = { 1.0, DIA_SVG_COLOUR_FOREGROUND, 1.0, DIA_SVG_COLOUR_NONE, 1.0, DIA_SVG_LINECAPS_DEFAULT, DIA_SVG_LINEJOIN_DEFAULT, DIA_SVG_LINESTYLE_DEFAULT, 1.0 }; dia_svg_parse_style(node, &s, -1); parse_svg_node(info, node, svg_ns, &s, filename); update_bounds(info); } else if (!xmlStrcmp(node->name, (const xmlChar *)"ext_attributes")) { ext_node = node; } } /*MC 11/03 parse ext attributes if any & prepare prop tables */ custom_setup_properties (info, ext_node); xmlFreeDoc(doc); return info; }
static Object * image_load(ObjectNode obj_node, int version, const char *filename) { Image *image; Element *elem; Object *obj; int i; AttributeNode attr; char *diafile_dir; image = g_malloc(sizeof(Image)); elem = (Element *)image; obj = (Object *)image; obj->type = &image_type; obj->ops = &image_ops; element_load(elem, obj_node); image->border_width = 0.1; attr = object_find_attribute(obj_node, "border_width"); if (attr != NULL) image->border_width = data_real( attribute_first_data(attr) ); image->border_color = color_black; attr = object_find_attribute(obj_node, "border_color"); if (attr != NULL) data_color(attribute_first_data(attr), &image->border_color); image->line_style = LINESTYLE_SOLID; attr = object_find_attribute(obj_node, "line_style"); if (attr != NULL) image->line_style = data_enum( attribute_first_data(attr) ); image->draw_border = TRUE; attr = object_find_attribute(obj_node, "draw_border"); if (attr != NULL) image->draw_border = data_boolean( attribute_first_data(attr) ); image->keep_aspect = TRUE; attr = object_find_attribute(obj_node, "keep_aspect"); if (attr != NULL) image->keep_aspect = data_boolean( attribute_first_data(attr) ); attr = object_find_attribute(obj_node, "file"); if (attr != NULL) { image->file = data_string( attribute_first_data(attr) ); } else { image->file = g_strdup(""); } element_init(elem, 8, 8); for (i=0;i<8;i++) { obj->connections[i] = &image->connections[i]; image->connections[i].object = obj; image->connections[i].connected = NULL; } image->image = NULL; if (strcmp(image->file, "")!=0) { diafile_dir = get_directory(filename); if (g_path_is_absolute(image->file)) { /* Absolute pathname */ image->image = dia_image_load(image->file); if (image->image == NULL) { /* Not found as abs path, try in same dir as diagram. */ char *temp_string; const char *image_file_name; image_file_name = strrchr(image->file, G_DIR_SEPARATOR) + 1; temp_string = g_malloc(strlen(diafile_dir) + strlen(image_file_name) +1); strcpy(temp_string, diafile_dir); strcat(temp_string, image_file_name); image->image = dia_image_load(temp_string); if (image->image != NULL) { /* Found file in same dir as diagram. */ message_warning(_("The image file '%s' was not found in that directory.\n" "Using the file '%s' instead\n"), image->file, temp_string); g_free(image->file); image->file = temp_string; } else { g_free(temp_string); image->image = dia_image_load((char *)image_file_name); if (image->image != NULL) { char *tmp; /* Found file in current dir. */ message_warning(_("The image file '%s' was not found in that directory.\n" "Using the file '%s' instead\n"), image->file, image_file_name); tmp = image->file; image->file = strdup(image_file_name); g_free(tmp); } else { message_warning(_("The image file '%s' was not found.\n"), image_file_name); } } } } else { /* Relative pathname: */ char *temp_string; temp_string = g_malloc(strlen(diafile_dir) + strlen(image->file) +1); strcpy(temp_string, diafile_dir); strcat(temp_string, image->file); image->image = dia_image_load(temp_string); if (image->image != NULL) { /* Found file in same dir as diagram. */ g_free(image->file); image->file = temp_string; } else { g_free(temp_string); image->image = dia_image_load(image->file); if (image->image == NULL) { /* Didn't find file in current dir. */ message_warning(_("The image file '%s' was not found.\n"), image->file); } } } g_free(diafile_dir); } image_update_data(image); return (Object *)image; }
/** If all files produced by dia were good XML files, we wouldn't have to do * this little gymnastic. Alas, during the libxml1 days, we were outputting * files with no encoding specification (which means UTF-8 if we're in an * asciish encoding) and strings encoded in local charset (so, we wrote * broken files). * * The following logic finds if we have a broken file, and attempts to fix * it if it's possible. If the file is correct or is unrecognisable, we pass * it untouched to libxml2. * @param filename The name of the file to check. * @param default_enc The default encoding to use if none is given. * @return The filename given if it seems ok, or the name of a new file * with fixed contents, or NULL if we couldn't read the file. The * caller should free this string and unlink the file if it is not * the same as `filename'. * @bug The many gzclose-g_free-return sequences should be refactored into * an "exception handle" (goto+label). At least for people who think goto is * better than this. I dont. --hb */ static const gchar * xml_file_check_encoding(const gchar *filename, const gchar *default_enc) { int fd = g_open (filename, O_RDONLY, 0); gzFile zf = gzdopen(fd,"rb"); gchar *buf; gchar *p,*pmax; int len; gchar *tmp,*res; int uf; gboolean well_formed_utf8; static char magic_xml[] = {0x3c,0x3f,0x78,0x6d,0x6c,0x00}; /* "<?xml" in ASCII */ if (!zf) { dia_log_message("%s can not be opened for encoding check (%s)", filename, fd > 0 ? "gzdopen" : "g_open"); /* XXX perhaps we can just chicken out to libxml ? -- CC */ return filename; } p = buf = g_malloc0(BUFLEN); len = gzread(zf,buf,BUFLEN); pmax = p + len; /* first, we expect the magic <?xml string */ if ((0 != strncmp(p,magic_xml,5)) || (len < 5)) { gzclose(zf); g_free(buf); return filename; /* let libxml figure out what this is. */ } /* now, we're sure we have some asciish XML file. */ p += 5; while (((*p == 0x20)||(*p == 0x09)||(*p == 0x0d)||(*p == 0x0a)) && (p<pmax)) p++; if (p>=pmax) { /* whoops ? */ gzclose(zf); g_free(buf); return filename; } if (0 != strncmp(p,"version=\"",9)) { gzclose(zf); /* chicken out. */ g_free(buf); return filename; } p += 9; /* The header is rather well formed. */ if (p>=pmax) { /* whoops ? */ gzclose(zf); g_free(buf); return filename; } while ((*p != '"') && (p < pmax)) p++; p++; while (((*p == 0x20)||(*p == 0x09)||(*p == 0x0d)||(*p == 0x0a)) && (p<pmax)) p++; if (p>=pmax) { /* whoops ? */ gzclose(zf); g_free(buf); return filename; } if (0 == strncmp(p,"encoding=\"",10)) { gzclose(zf); /* this file has an encoding string. Good. */ g_free(buf); return filename; } /* now let's read the whole file, to see if there are offending bits. * We can call it well formed UTF-8 if the highest isn't used */ well_formed_utf8 = TRUE; do { int i; for (i = 0; i < len; i++) if (buf[i] & 0x80 || buf[i] == '&') well_formed_utf8 = FALSE; len = gzread(zf,buf,BUFLEN); } while (len > 0 && well_formed_utf8); if (well_formed_utf8) { gzclose(zf); /* this file is utf-8 compatible */ g_free(buf); return filename; } else { gzclose(zf); /* poor man's fseek */ fd = g_open (filename, O_RDONLY, 0); zf = gzdopen(fd,"rb"); len = gzread(zf,buf,BUFLEN); } if (0 != strcmp(default_enc,"UTF-8")) { message_warning(_("The file %s has no encoding specification;\n" "assuming it is encoded in %s"), dia_message_filename(filename), default_enc); } else { gzclose(zf); /* we apply the standard here. */ g_free(buf); return filename; } tmp = getenv("TMP"); if (!tmp) tmp = getenv("TEMP"); if (!tmp) tmp = "/tmp"; res = g_strconcat(tmp,G_DIR_SEPARATOR_S,"dia-xml-fix-encodingXXXXXX",NULL); uf = g_mkstemp(res); write(uf,buf,p-buf); write(uf," encoding=\"",11); write(uf,default_enc,strlen(default_enc)); write(uf,"\" ",2); write(uf,p,pmax - p); while (1) { len = gzread(zf,buf,BUFLEN); if (len <= 0) break; write(uf,buf,len); } gzclose(zf); close(uf); g_free(buf); return res; /* caller frees the name and unlinks the file. */ }
/// \brief Removes the filename suffix of the compressed file /// /// \return Name of the uncompressed file, or NULL if file has unknown /// suffix. static char * uncompressed_name(const char *src_name, const size_t src_len) { static const struct { const char *compressed; const char *uncompressed; } suffixes[] = { { ".xz", "" }, { ".txz", ".tar" }, // .txz abbreviation for .txt.gz is rare. { ".lzma", "" }, #ifdef __DJGPP__ { ".lzm", "" }, #endif { ".tlz", ".tar" }, // { ".gz", "" }, // { ".tgz", ".tar" }, }; const char *new_suffix = ""; size_t new_len = 0; if (opt_format == FORMAT_RAW) { // Don't check for known suffixes when --format=raw was used. if (custom_suffix == NULL) { message_error(_("%s: With --format=raw, " "--suffix=.SUF is required unless " "writing to stdout"), src_name); return NULL; } } else { for (size_t i = 0; i < ARRAY_SIZE(suffixes); ++i) { new_len = test_suffix(suffixes[i].compressed, src_name, src_len); if (new_len != 0) { new_suffix = suffixes[i].uncompressed; break; } } #ifdef __DJGPP__ // Support also *.?- -> *.? and *.??- -> *.?? on DOS. // This is done also when long filenames are available // to keep it easy to decompress files created when // long filename support wasn't available. if (new_len == 0 && has_sfn_suffix(src_name, src_len)) { new_suffix = ""; new_len = src_len - 1; } #endif } if (new_len == 0 && custom_suffix != NULL) new_len = test_suffix(custom_suffix, src_name, src_len); if (new_len == 0) { message_warning(_("%s: Filename has an unknown suffix, " "skipping"), src_name); return NULL; } const size_t new_suffix_len = strlen(new_suffix); char *dest_name = xmalloc(new_len + new_suffix_len + 1); memcpy(dest_name, src_name, new_len); memcpy(dest_name + new_len, new_suffix, new_suffix_len); dest_name[new_len + new_suffix_len] = '\0'; return dest_name; }
static CLEventList * parse_clevent(const gchar *events, real rise, real fall) { real t = -1E10; double dt; const gchar *p,*p1,*np; gunichar uc; CLEventType et = CLE_UNKNOWN; CLEventType oet = CLE_UNKNOWN; CLEventList *clel = NULL; enum {EVENT,LENGTH} waitfor = EVENT; p1 = p = events; /* if we don't cheat like this, g_slist_insert_sorted won't insert the right way. */ if (rise <= 0.0) rise = 0.0; rise += CHEAT_CST; if (fall <= 0.0) fall = 0.0; fall += CHEAT_CST; while (*p) { uc = g_utf8_get_char(p); np = g_utf8_next_char(p); switch (uc) { /* skip spaces */ case ' ': case '\t': case '\n': p = np; continue; default: break; } if (waitfor == EVENT) { switch(uc) { case 'u': case 'U': et = CLE_UNKNOWN; waitfor = LENGTH; p = np; break; case 'x': case 'X': et = CLE_TWISTED; waitfor = LENGTH; p = np; break; case '@': et = CLE_START; waitfor = LENGTH; p = np ; break; case '(': et = CLE_ON; waitfor = LENGTH; p = np; break; case ')': et = CLE_OFF; waitfor = LENGTH; p = np; break; default: message_warning("Syntax error in event string; waiting one of " "\"()@ux\". string=%s",p); return clel; } } else { /* waitfor == LENGTH */ dt = g_ascii_strtod(p,(char **)&p1); if (p1 == p) { /* We were ready for a length argument, we got nothing. Maybe the user entered a zero-length argument ? */ switch(uc) { case 'u': case 'U': case 'x': case 'X': case '@': case '(': case ')': dt = 0.0; break; default: message_warning("Syntax error in event string; waiting a floating " "point value. string=%s",p); return clel; } } /* dt contains a duration value. p1 points to the rest of the string. */ p = p1; add_event(&clel,&t,&dt,&oet,&et,rise,fall); waitfor=EVENT; } } if (waitfor == LENGTH) { /* late fix */ if (oet == CLE_START) oet = et; dt = 0.0; add_event(&clel,&t,&dt,&oet,&et,rise,fall); } #if DUMP_PARSED_CLELIST dump_parsed_clelist(clel); #endif return clel; }