X-Git-Url: https://git.donarmstrong.com/?p=xournal.git;a=blobdiff_plain;f=src%2Fxo-image.c;fp=src%2Fxo-image.c;h=884bf2301ef2d4fa53f16d0a3bdccf3b8b0f4401;hp=0000000000000000000000000000000000000000;hb=bc1db27c7eef7de6d5097a5e708d2de540d35b88;hpb=dbcc72baab610c58a36586f75b7ce7e17a0d4f41 diff --git a/src/xo-image.c b/src/xo-image.c new file mode 100644 index 0000000..884bf23 --- /dev/null +++ b/src/xo-image.c @@ -0,0 +1,167 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include + +#include "xournal.h" +#include "xo-support.h" +#include "xo-image.h" + +// create pixbuf from buffer, or return NULL on failure +GdkPixbuf *pixbuf_from_buffer(const gchar *buf, gsize buflen) +{ + GInputStream *istream; + GdkPixbuf *pixbuf; + GError *error; + + error = NULL; + + istream = g_memory_input_stream_new_from_data (buf, buflen, NULL); + pixbuf = gdk_pixbuf_new_from_stream(istream, NULL, &error); + g_input_stream_close(istream, NULL, &error); + return pixbuf; +} + +void create_image_from_pixbuf(GdkPixbuf *pixbuf, double *pt) +{ + double scale; + struct Item *item; + + item = g_new(struct Item, 1); + item->type = ITEM_IMAGE; + item->canvas_item = NULL; + item->bbox.left = pt[0]; + item->bbox.top = pt[1]; + item->image = pixbuf; + item->image_png = NULL; + item->image_png_len = 0; + + // Scale at native size, unless that won't fit, in which case we shrink it down. + scale = 1 / ui.zoom; + if ((scale * gdk_pixbuf_get_width(item->image)) > ui.cur_page->width - item->bbox.left) + scale = (ui.cur_page->width - item->bbox.left) / gdk_pixbuf_get_width(item->image); + if ((scale * gdk_pixbuf_get_height(item->image)) > ui.cur_page->height - item->bbox.top) + scale = (ui.cur_page->height - item->bbox.top) / gdk_pixbuf_get_height(item->image); + + item->bbox.right = item->bbox.left + scale * gdk_pixbuf_get_width(item->image); + item->bbox.bottom = item->bbox.top + scale * gdk_pixbuf_get_height(item->image); + ui.cur_layer->items = g_list_append(ui.cur_layer->items, item); + ui.cur_layer->nitems++; + + make_canvas_item_one(ui.cur_layer->group, item); + + // add undo information + prepare_new_undo(); + undo->type = ITEM_IMAGE; + undo->item = item; + undo->layer = ui.cur_layer; + ui.cur_item = NULL; + ui.cur_item_type = ITEM_NONE; + + // select image + reset_selection(); + ui.selection = g_new0(struct Selection, 1); + ui.selection->type = ITEM_SELECTRECT; + ui.selection->layer = ui.cur_layer; + ui.selection->bbox = item->bbox; + ui.selection->items = g_list_append(ui.selection->items, item); + ui.selection->canvas_item = gnome_canvas_item_new(ui.cur_layer->group, + gnome_canvas_rect_get_type(), "width-pixels", 1, + "outline-color-rgba", 0x000000ff, + "fill-color-rgba", 0x80808040, + "x1", ui.selection->bbox.left, "x2", ui.selection->bbox.right, + "y1", ui.selection->bbox.top, "y2", ui.selection->bbox.bottom, NULL); + make_dashed(ui.selection->canvas_item); + update_copy_paste_enabled(); +} + +void insert_image(GdkEvent *event) +{ + GtkTextBuffer *buffer; + GnomeCanvasItem *canvas_item; + GdkColor color; + GtkWidget *dialog; + GtkFileFilter *filt_all; + GtkFileFilter *filt_gdkimage; + char *filename; + GdkPixbuf *pixbuf; + double scale=1; + double pt[2]; + + dialog = gtk_file_chooser_dialog_new(_("Insert Image"), GTK_WINDOW (winMain), + GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL); +#ifdef FILE_DIALOG_SIZE_BUGFIX + gtk_window_set_default_size(GTK_WINDOW(dialog), 500, 400); +#endif + + filt_all = gtk_file_filter_new(); + gtk_file_filter_set_name(filt_all, _("All files")); + gtk_file_filter_add_pattern(filt_all, "*"); + filt_gdkimage = gtk_file_filter_new(); + gtk_file_filter_set_name(filt_gdkimage, _("Image files")); + gtk_file_filter_add_pixbuf_formats(filt_gdkimage); + gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_gdkimage); + gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_all); + + if (ui.default_image != NULL) gtk_file_chooser_set_filename(GTK_FILE_CHOOSER (dialog), ui.default_image); + + if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_OK) { + gtk_widget_destroy(dialog); + return; + } + filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER (dialog)); + gtk_widget_destroy(dialog); + + if (filename == NULL) return; /* nothing selected */ + + if (ui.default_image != NULL) g_free(ui.default_image); + ui.default_image = g_strdup(filename); + + set_cursor_busy(TRUE); + pixbuf=gdk_pixbuf_new_from_file(filename, NULL); + set_cursor_busy(FALSE); + + if(pixbuf==NULL) { /* open failed */ + dialog = gtk_message_dialog_new(GTK_WINDOW (winMain), GTK_DIALOG_MODAL, + GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Error opening image '%s'"), filename); + gtk_dialog_run(GTK_DIALOG(dialog)); + gtk_widget_destroy(dialog); + g_free(filename); + ui.cur_item = NULL; + ui.cur_item_type = ITEM_NONE; + return; + } + + ui.cur_item_type = ITEM_IMAGE; + + get_pointer_coords(event, pt); + set_current_page(pt); + + create_image_from_pixbuf(pixbuf, pt); +} + +void rescale_images(void) +{ + // nothing needed in this implementation +} +