[xournal] #827922 - image insertion patch

Jaromír Cápík jcapik at fedoraproject.org
Mon Jul 9 17:22:59 UTC 2012


commit 9b61d4357ee6ad84d17ea21189af1eb1e1a9786a
Author: Jaromir Capik <jcapik at redhat.com>
Date:   Mon Jul 9 19:22:47 2012 +0200

    #827922 - image insertion patch

 xournal-0.4.5-sjg-image-rev7.patch | 3110 ++++++++++++++++++++++++++++++++++++
 xournal.spec                       |    8 +-
 2 files changed, 3117 insertions(+), 1 deletions(-)
---
diff --git a/xournal-0.4.5-sjg-image-rev7.patch b/xournal-0.4.5-sjg-image-rev7.patch
new file mode 100644
index 0000000..a3be178
--- /dev/null
+++ b/xournal-0.4.5-sjg-image-rev7.patch
@@ -0,0 +1,3110 @@
+# This is a patch for xournal-0.4.5 to update it to xournal
+# 
+# To apply this patch:
+# STEP 1: Chdir to the source directory.
+# STEP 2: Run the 'applypatch' program with this patch file as input.
+#
+# If you do not have 'applypatch', it is part of the 'makepatch' package
+# that you can fetch from the Comprehensive Perl Archive Network:
+# http://www.perl.com/CPAN/authors/Johan_Vromans/makepatch-x.y.tar.gz
+# In the above URL, 'x' should be 2 or higher.
+#
+# To apply this patch without the use of 'applypatch':
+# STEP 1: Chdir to the source directory.
+# If you have a decent Bourne-type shell:
+# STEP 2: Run the shell with this file as input.
+# If you don't have such a shell, you may need to manually create
+# the files as shown below.
+# STEP 3: Run the 'patch' program with this file as input.
+#
+# These are the commands needed to create/delete files/directories:
+#
+touch './README.image'
+chmod 0644 './README.image'
+touch './src/xo-clipboard.c'
+chmod 0644 './src/xo-clipboard.c'
+touch './src/xo-clipboard.h'
+chmod 0644 './src/xo-clipboard.h'
+touch './src/xo-image.c'
+chmod 0644 './src/xo-image.c'
+touch './src/xo-image.h'
+chmod 0644 './src/xo-image.h'
+#
+# This command terminates the shell and need not be executed manually.
+exit
+#
+#### End of Preamble ####
+
+#### Patch data follows ####
+diff -c /dev/null 'xournal/README.image'
+Index: ./README.image
+*** ./README.image	Thu Jan  1 12:00:00 1970
+--- ./README.image	Thu Apr 15 17:16:44 2010
+***************
+*** 0 ****
+--- 1,19 ----
++ This paste image patch is based on Victor Saase's insert image patch,
++ with grateful thanks to Victor for making a good start.
++ 
++ This patch is to be applied to a vanilla xournal-0.4.5.
++ 
++ This patch therefore contains Victor's changes, and also:
++ 
++ + images are now stored in the journal file, inline in the XML, as 
++   base64 encoded PNGs.
++ + images can be pasted in from the clipboard
++ + copy and paste of images works within the application
++ + export of image with PDF now works
++ 
++ I also fixed this bug:
++ 
++ + free pixbufs using g_object_unref not g_free.
++ 
++ 
++ Simon Guest 14/4/10
+diff -c 'xournal-0.4.5/src/Makefile.am' 'xournal/src/Makefile.am'
+Index: ./src/Makefile.am
+*** ./src/Makefile.am	Tue Sep 22 03:24:32 2009
+--- ./src/Makefile.am	Thu Apr 15 17:22:24 2010
+***************
+*** 12,17 ****
+--- 12,19 ----
+  xournal_SOURCES = \
+  	main.c xournal.h \
+  	xo-misc.c xo-misc.h \
++ 	xo-clipboard.c xo-clipboard.h \
++ 	xo-image.c xo-image.h \
+  	xo-file.c xo-file.h \
+  	xo-paint.c xo-paint.h \
+  	xo-print.c xo-print.h \
+diff -c 'xournal-0.4.5/src/Makefile.in' 'xournal/src/Makefile.in'
+Index: ./src/Makefile.in
+*** ./src/Makefile.in	Fri Oct  2 19:42:14 2009
+--- ./src/Makefile.in	Thu Apr 15 17:27:17 2010
+***************
+*** 1,4 ****
+! # Makefile.in generated by automake 1.11 from Makefile.am.
+  # @configure_input@
+  
+  # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+--- 1,4 ----
+! # Makefile.in generated by automake 1.11.1 from Makefile.am.
+  # @configure_input@
+  
+  # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+***************
+*** 46,54 ****
+  am__installdirs = "$(DESTDIR)$(bindir)"
+  PROGRAMS = $(bin_PROGRAMS)
+  am_xournal_OBJECTS = main.$(OBJEXT) xo-misc.$(OBJEXT) \
+! 	xo-file.$(OBJEXT) xo-paint.$(OBJEXT) xo-print.$(OBJEXT) \
+! 	xo-support.$(OBJEXT) xo-interface.$(OBJEXT) \
+! 	xo-callbacks.$(OBJEXT) xo-shapes.$(OBJEXT)
+  xournal_OBJECTS = $(am_xournal_OBJECTS)
+  am__DEPENDENCIES_1 =
+  xournal_DEPENDENCIES = ttsubset/libttsubset.a $(am__DEPENDENCIES_1)
+--- 46,55 ----
+  am__installdirs = "$(DESTDIR)$(bindir)"
+  PROGRAMS = $(bin_PROGRAMS)
+  am_xournal_OBJECTS = main.$(OBJEXT) xo-misc.$(OBJEXT) \
+! 	xo-clipboard.$(OBJEXT) xo-image.$(OBJEXT) xo-file.$(OBJEXT) \
+! 	xo-paint.$(OBJEXT) xo-print.$(OBJEXT) xo-support.$(OBJEXT) \
+! 	xo-interface.$(OBJEXT) xo-callbacks.$(OBJEXT) \
+! 	xo-shapes.$(OBJEXT)
+  xournal_OBJECTS = $(am_xournal_OBJECTS)
+  am__DEPENDENCIES_1 =
+  xournal_DEPENDENCIES = ttsubset/libttsubset.a $(am__DEPENDENCIES_1)
+***************
+*** 154,159 ****
+--- 155,161 ----
+  PACKAGE_NAME = @PACKAGE_NAME@
+  PACKAGE_STRING = @PACKAGE_STRING@
+  PACKAGE_TARNAME = @PACKAGE_TARNAME@
++ PACKAGE_URL = @PACKAGE_URL@
+  PACKAGE_VERSION = @PACKAGE_VERSION@
+  PATH_SEPARATOR = @PATH_SEPARATOR@
+  PKG_CONFIG = @PKG_CONFIG@
+***************
+*** 219,224 ****
+--- 221,228 ----
+  xournal_SOURCES = \
+  	main.c xournal.h \
+  	xo-misc.c xo-misc.h \
++ 	xo-clipboard.c xo-clipboard.h \
++ 	xo-image.c xo-image.h \
+  	xo-file.c xo-file.h \
+  	xo-paint.c xo-paint.h \
+  	xo-print.c xo-print.h \
+***************
+*** 311,317 ****
+--- 315,323 ----
+  
+  @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/main.Po at am__quote@
+  @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/xo-callbacks.Po at am__quote@
++ @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/xo-clipboard.Po at am__quote@
+  @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/xo-file.Po at am__quote@
++ @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/xo-image.Po at am__quote@
+  @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/xo-interface.Po at am__quote@
+  @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/xo-misc.Po at am__quote@
+  @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/xo-paint.Po at am__quote@
+***************
+*** 340,346 ****
+  #     (which will cause the Makefiles to be regenerated when you run `make');
+  # (2) otherwise, pass the desired values on the `make' command line.
+  $(RECURSIVE_TARGETS):
+! 	@failcom='exit 1'; \
+  	for f in x $$MAKEFLAGS; do \
+  	  case $$f in \
+  	    *=* | --[!k]*);; \
+--- 346,352 ----
+  #     (which will cause the Makefiles to be regenerated when you run `make');
+  # (2) otherwise, pass the desired values on the `make' command line.
+  $(RECURSIVE_TARGETS):
+! 	@fail= failcom='exit 1'; \
+  	for f in x $$MAKEFLAGS; do \
+  	  case $$f in \
+  	    *=* | --[!k]*);; \
+***************
+*** 365,371 ****
+  	fi; test -z "$$fail"
+  
+  $(RECURSIVE_CLEAN_TARGETS):
+! 	@failcom='exit 1'; \
+  	for f in x $$MAKEFLAGS; do \
+  	  case $$f in \
+  	    *=* | --[!k]*);; \
+--- 371,377 ----
+  	fi; test -z "$$fail"
+  
+  $(RECURSIVE_CLEAN_TARGETS):
+! 	@fail= failcom='exit 1'; \
+  	for f in x $$MAKEFLAGS; do \
+  	  case $$f in \
+  	    *=* | --[!k]*);; \
+diff -c 'xournal-0.4.5/src/TODO' 'xournal/src/TODO'
+Index: ./src/TODO
+*** ./src/TODO	Sat Oct  3 12:20:35 2009
+--- ./src/TODO	Fri May 14 17:59:39 2010
+***************
+*** 138,145 ****
+  - copy/paste of an entire page (beware if PDF bg is not compatible!)
+  - rewrite printing using GtkPrint + Cairo as GnomePrint replacement
+     (keep GnomePrint option for compatibility with GTK+ <2.10)
+- - insert images (screen capture or from file or from clipboard), 
+-   not as full-page backgrounds (new ITEM type)
+  
+  - convert to/from Jarnal format; to/from MS Journal format???
+  - export as SVG, as bitmap (use Cairo for this)
+--- 138,143 ----
+diff -c 'xournal-0.4.5/src/main.c' 'xournal/src/main.c'
+Index: ./src/main.c
+*** ./src/main.c	Mon Sep 28 11:08:34 2009
+--- ./src/main.c	Sun Jun 27 16:22:44 2010
+***************
+*** 287,292 ****
+--- 287,295 ----
+    g_free(tmpfn);
+    set_cursor_busy(FALSE);
+    if (!success) {
++ 	  #ifdef IMAGE_DEBUG
++ 	  printf("error opening file '%s'\n",argv[1]);
++ 	  #endif
+      w = gtk_message_dialog_new(GTK_WINDOW (winMain), GTK_DIALOG_DESTROY_WITH_PARENT,
+         GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Error opening file '%s'"), argv[1]);
+      gtk_dialog_run(GTK_DIALOG(w));
+diff -c 'xournal-0.4.5/src/xo-callbacks.c' 'xournal/src/xo-callbacks.c'
+Index: ./src/xo-callbacks.c
+*** ./src/xo-callbacks.c	Tue Sep 29 12:42:49 2009
+--- ./src/xo-callbacks.c	Thu Jun 24 20:32:09 2010
+***************
+*** 452,458 ****
+    if (undo == NULL) return; // nothing to undo!
+    reset_selection(); // safer
+    reset_recognizer(); // safer
+!   if (undo->type == ITEM_STROKE || undo->type == ITEM_TEXT) {
+      // we're keeping the stroke info, but deleting the canvas item
+      gtk_object_destroy(GTK_OBJECT(undo->item->canvas_item));
+      undo->item->canvas_item = NULL;
+--- 452,458 ----
+    if (undo == NULL) return; // nothing to undo!
+    reset_selection(); // safer
+    reset_recognizer(); // safer
+!   if (undo->type == ITEM_STROKE || undo->type == ITEM_TEXT || undo->type == ITEM_IMAGE) {
+      // we're keeping the stroke info, but deleting the canvas item
+      gtk_object_destroy(GTK_OBJECT(undo->item->canvas_item));
+      undo->item->canvas_item = NULL;
+***************
+*** 666,672 ****
+    if (redo == NULL) return; // nothing to redo!
+    reset_selection(); // safer
+    reset_recognizer(); // safer
+!   if (redo->type == ITEM_STROKE || redo->type == ITEM_TEXT) {
+      // re-create the canvas_item
+      make_canvas_item_one(redo->layer->group, redo->item);
+      // reinsert the item on its layer
+--- 666,672 ----
+    if (redo == NULL) return; // nothing to redo!
+    reset_selection(); // safer
+    reset_recognizer(); // safer
+!   if (redo->type == ITEM_STROKE || redo->type == ITEM_TEXT || redo->type == ITEM_IMAGE) {
+      // re-create the canvas_item
+      make_canvas_item_one(redo->layer->group, redo->item);
+      // reinsert the item on its layer
+***************
+*** 824,829 ****
+--- 824,835 ----
+        if (it->type == ITEM_TEXT && it->canvas_item != NULL)
+          gnome_canvas_item_set(it->canvas_item, 
+            "fill-color-rgba", it->brush.color_rgba, NULL);
++       if (it->type == ITEM_IMAGE && it->canvas_item != NULL) {
++         // remark: a variable-width item might have lost its variable-width
++         group = (GnomeCanvasGroup *) it->canvas_item->parent;
++         gtk_object_destroy(GTK_OBJECT(it->canvas_item));
++         make_canvas_item_one(group, it);
++       }
+      }
+    }
+    else if (redo->type == ITEM_TEXT_EDIT) {
+***************
+*** 946,951 ****
+--- 952,958 ----
+    gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
+    rescale_text_items();
+    rescale_bg_pixmaps();
++   rescale_images();
+  }
+  
+  
+***************
+*** 958,963 ****
+--- 965,971 ----
+    gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
+    rescale_text_items();
+    rescale_bg_pixmaps();
++   rescale_images();
+  }
+  
+  
+***************
+*** 969,974 ****
+--- 977,983 ----
+    gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
+    rescale_text_items();
+    rescale_bg_pixmaps();
++   rescale_images();
+  }
+  
+  
+***************
+*** 980,985 ****
+--- 989,995 ----
+    gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
+    rescale_text_items();
+    rescale_bg_pixmaps();
++   rescale_images();
+  }
+  
+  
+***************
+*** 1539,1544 ****
+--- 1549,1555 ----
+      gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
+      rescale_text_items();
+      rescale_bg_pixmaps();
++     rescale_images();
+    }
+    do_switch_page(ui.pageno, TRUE, TRUE);
+  }
+***************
+*** 1585,1590 ****
+--- 1596,1602 ----
+      gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
+      rescale_text_items();
+      rescale_bg_pixmaps();
++     rescale_images();
+    }
+    do_switch_page(ui.pageno, TRUE, TRUE);
+  }
+***************
+*** 1747,1752 ****
+--- 1759,1790 ----
+    update_cursor();
+  }
+  
++ void
++ on_toolsImage_activate                  (GtkMenuItem     *menuitem,
++                                         gpointer         user_data)
++ {
++   if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
++     if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
++       return;
++   } else {
++     if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
++       return;
++   }
++   
++   if (ui.cur_mapping != 0 && !ui.button_switch_mapping) return; // not user-generated
++   if (ui.toolno[ui.cur_mapping] == TOOL_IMAGE) return;
++   
++   ui.cur_mapping = 0; // don't use switch_mapping() (refreshes buttons too soon)
++   reset_selection();
++   ui.toolno[ui.cur_mapping] = TOOL_IMAGE;
++   ui.cur_brush = &(ui.brushes[ui.cur_mapping][TOOL_PEN]);
++   update_mapping_linkings(-1);
++   update_tool_buttons();
++   update_tool_menu();
++   update_color_menu();
++   update_cursor();
++ }
++ 
+  
+  void
+  on_toolsSelectRegion_activate          (GtkMenuItem     *menuitem,
+***************
+*** 2321,2328 ****
+                                          gpointer         user_data)
+  {
+    double pt[2];
+-   gboolean page_change;
+-   struct Page *tmppage;
+    GtkWidget *dialog;
+    int mapping;
+    gboolean is_core;
+--- 2359,2364 ----
+***************
+*** 2407,2430 ****
+    else mapping = event->button-1;
+  
+    // check whether we're in a page
+-   page_change = FALSE;
+-   tmppage = ui.cur_page;
+    get_pointer_coords((GdkEvent *)event, pt);
+!   while (ui.view_continuous && (pt[1] < - VIEW_CONTINUOUS_SKIP)) {
+!     if (ui.pageno == 0) break;
+!     page_change = TRUE;
+!     ui.pageno--;
+!     tmppage = g_list_nth_data(journal.pages, ui.pageno);
+!     pt[1] += tmppage->height + VIEW_CONTINUOUS_SKIP;
+!   }
+!   while (ui.view_continuous && (pt[1] > tmppage->height + VIEW_CONTINUOUS_SKIP)) {
+!     if (ui.pageno == journal.npages-1) break;
+!     pt[1] -= tmppage->height + VIEW_CONTINUOUS_SKIP;
+!     page_change = TRUE;
+!     ui.pageno++;
+!     tmppage = g_list_nth_data(journal.pages, ui.pageno);
+!   }
+!   if (page_change) do_switch_page(ui.pageno, FALSE, FALSE);
+    
+    // can't paint on the background...
+  
+--- 2443,2450 ----
+    else mapping = event->button-1;
+  
+    // check whether we're in a page
+    get_pointer_coords((GdkEvent *)event, pt);
+!   set_current_page(pt);
+    
+    // can't paint on the background...
+  
+***************
+*** 2487,2492 ****
+--- 2507,2515 ----
+    else if (ui.toolno[mapping] == TOOL_TEXT) {
+      start_text((GdkEvent *)event, NULL);
+    }
++   else if (ui.toolno[mapping] == TOOL_IMAGE) {
++     insert_image((GdkEvent *)event, NULL);
++   }
+    return FALSE;
+  }
+  
+***************
+*** 2665,2671 ****
+       or if there's a selection (then we might want to change the mouse
+       cursor to indicate the possibility of resizing) */  
+    if (ui.cur_item_type == ITEM_NONE && ui.selection==NULL) return FALSE;
+!   if (ui.cur_item_type == ITEM_TEXT) return FALSE;
+  
+    is_core = (event->device == gdk_device_get_core_pointer());
+    if (!ui.use_xinput && !is_core) return FALSE;
+--- 2688,2694 ----
+       or if there's a selection (then we might want to change the mouse
+       cursor to indicate the possibility of resizing) */  
+    if (ui.cur_item_type == ITEM_NONE && ui.selection==NULL) return FALSE;
+!   if (ui.cur_item_type == ITEM_TEXT || ui.cur_item_type == ITEM_IMAGE) return FALSE;
+  
+    is_core = (event->device == gdk_device_get_core_pointer());
+    if (!ui.use_xinput && !is_core) return FALSE;
+***************
+*** 3340,3345 ****
+--- 3363,3369 ----
+        gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
+        rescale_text_items();
+        rescale_bg_pixmaps();
++       rescale_images();
+      }
+    } while (response == GTK_RESPONSE_APPLY);
+    
+diff -c 'xournal-0.4.5/src/xo-callbacks.h' 'xournal/src/xo-callbacks.h'
+Index: ./src/xo-callbacks.h
+*** ./src/xo-callbacks.h	Tue Sep 29 12:43:34 2009
+--- ./src/xo-callbacks.h	Mon Mar 22 11:39:25 2010
+***************
+*** 211,216 ****
+--- 211,220 ----
+  void
+  on_toolsText_activate                  (GtkMenuItem     *menuitem,
+                                          gpointer         user_data);
++ 					
++ void
++ on_toolsImage_activate                  (GtkMenuItem     *menuitem,
++                                         gpointer         user_data);
+  
+  void
+  on_toolsSelectRegion_activate          (GtkMenuItem     *menuitem,
+diff -c /dev/null 'xournal/src/xo-clipboard.c'
+Index: ./src/xo-clipboard.c
+*** ./src/xo-clipboard.c	Thu Jan  1 12:00:00 1970
+--- ./src/xo-clipboard.c	Thu Jul 29 19:56:43 2010
+***************
+*** 0 ****
+--- 1,304 ----
++ #ifdef HAVE_CONFIG_H
++ #  include <config.h>
++ #endif
++ 
++ #include <string.h>
++ #include <gtk/gtk.h>
++ 
++ #include "xournal.h"
++ #include "xo-callbacks.h"
++ #include "xo-interface.h"
++ #include "xo-support.h"
++ #include "xo-misc.h"
++ #include "xo-paint.h"
++ #include "xo-image.h"
++ 
++ 
++ void callback_clipboard_get(GtkClipboard *clipboard,
++                             GtkSelectionData *selection_data,
++                             guint info, gpointer user_data)
++ {
++   int length;
++   
++   g_memmove(&length, user_data, sizeof(int));
++   gtk_selection_data_set(selection_data,
++      gdk_atom_intern("_XOURNAL", FALSE), 8, user_data, length);
++ }
++ 
++ void callback_clipboard_clear(GtkClipboard *clipboard, gpointer user_data)
++ {
++   g_free(user_data);
++ }
++ 
++ void callback_clipboard_targets_received(GtkClipboard *clipboard,
++                                          GdkAtom *atoms,
++                                          gint n_atoms,
++                                          gpointer data)
++ {
++   gint i;
++   printf("clipboard targets:\n");
++   for (i = 0; i < n_atoms; i++) {
++     printf("%s\n", gdk_atom_name(atoms[i]));
++   }
++ }
++ 
++ void selection_to_clip(void)
++ {
++   int bufsz, nitems, val;
++   char *buf, *p;
++   GList *list;
++   struct Item *item;
++   GtkTargetEntry target;
++   
++   if (ui.selection == NULL) return;
++   bufsz = 2*sizeof(int) // bufsz, nitems
++         + sizeof(struct BBox); // bbox
++   nitems = 0;
++   for (list = ui.selection->items; list != NULL; list = list->next) {
++     item = (struct Item *)list->data;
++     nitems++;
++     if (item->type == ITEM_STROKE) {
++       bufsz+= sizeof(int) // type
++             + sizeof(struct Brush) // brush
++             + sizeof(int) // num_points
++             + 2*item->path->num_points*sizeof(double); // the points
++       if (item->brush.variable_width)
++         bufsz += (item->path->num_points-1)*sizeof(double); // the widths
++     }
++     else if (item->type == ITEM_TEXT) {
++       bufsz+= sizeof(int) // type
++             + sizeof(struct Brush) // brush
++             + 2*sizeof(double) // bbox upper-left
++             + sizeof(int) // text len
++             + strlen(item->text)+1 // text
++             + sizeof(int) // font_name len
++             + strlen(item->font_name)+1 // font_name
++             + sizeof(double); // font_size
++     }
++     else if (item->type == ITEM_IMAGE) {
++       if (item->image_png == NULL) {
++         if (!pixbuf_to_buffer(item->image, &item->image_png, &item->image_png_len, "png")) {
++           item->image_png_len = 0;       // failed for some reason, so forget it
++         }
++       }
++       bufsz+= sizeof(int) // type
++         + sizeof(struct BBox)
++         + sizeof(gsize) // png_buflen
++         + item->image_png_len;
++     }
++     else bufsz+= sizeof(int); // type
++   }
++   p = buf = g_malloc(bufsz);
++   g_memmove(p, &bufsz, sizeof(int)); p+= sizeof(int);
++   g_memmove(p, &nitems, sizeof(int)); p+= sizeof(int);
++   g_memmove(p, &ui.selection->bbox, sizeof(struct BBox)); p+= sizeof(struct BBox);
++   for (list = ui.selection->items; list != NULL; list = list->next) {
++     item = (struct Item *)list->data;
++     g_memmove(p, &item->type, sizeof(int)); p+= sizeof(int);
++     if (item->type == ITEM_STROKE) {
++       g_memmove(p, &item->brush, sizeof(struct Brush)); p+= sizeof(struct Brush);
++       g_memmove(p, &item->path->num_points, sizeof(int)); p+= sizeof(int);
++       g_memmove(p, item->path->coords, 2*item->path->num_points*sizeof(double));
++       p+= 2*item->path->num_points*sizeof(double);
++       if (item->brush.variable_width) {
++         g_memmove(p, item->widths, (item->path->num_points-1)*sizeof(double));
++         p+= (item->path->num_points-1)*sizeof(double);
++       }
++     }
++     if (item->type == ITEM_TEXT) {
++       g_memmove(p, &item->brush, sizeof(struct Brush)); p+= sizeof(struct Brush);
++       g_memmove(p, &item->bbox.left, sizeof(double)); p+= sizeof(double);
++       g_memmove(p, &item->bbox.top, sizeof(double)); p+= sizeof(double);
++       val = strlen(item->text);
++       g_memmove(p, &val, sizeof(int)); p+= sizeof(int);
++       g_memmove(p, item->text, val+1); p+= val+1;
++       val = strlen(item->font_name);
++       g_memmove(p, &val, sizeof(int)); p+= sizeof(int);
++       g_memmove(p, item->font_name, val+1); p+= val+1;
++       g_memmove(p, &item->font_size, sizeof(double)); p+= sizeof(double);
++     }
++     if (item->type == ITEM_IMAGE) {
++       g_memmove(p, &item->bbox, sizeof(struct BBox)); p+= sizeof(struct BBox);
++       g_memmove(p, &item->image_png_len, sizeof(gsize)); p+= sizeof(gsize);
++       if (item->image_png_len > 0) {
++         g_memmove(p, item->image_png, item->image_png_len); p+= item->image_png_len;
++       }
++     }
++   }
++   
++   target.target = "_XOURNAL";
++   target.flags = 0;
++   target.info = 0;
++   
++   gtk_clipboard_set_with_data(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD), 
++        &target, 1,
++        callback_clipboard_get, callback_clipboard_clear, buf);
++ }
++ 
++ // local paste within the application
++ void clipboard_paste_from_xournal(GtkSelectionData *sel_data)
++ {
++   unsigned char *p;
++   int nitems, npts, i, len;
++   struct Item *item;
++   double hoffset, voffset, cx, cy;
++   double *pf;
++   int sx, sy, wx, wy;
++   
++   reset_selection();
++ 
++   ui.selection = g_new(struct Selection, 1);
++   p = sel_data->data + sizeof(int);
++   g_memmove(&nitems, p, sizeof(int)); p+= sizeof(int);
++   ui.selection->type = ITEM_SELECTRECT;
++   ui.selection->layer = ui.cur_layer;
++   g_memmove(&ui.selection->bbox, p, sizeof(struct BBox)); p+= sizeof(struct BBox);
++   ui.selection->items = NULL;
++   
++   // find by how much we translate the pasted selection
++   gnome_canvas_get_scroll_offsets(canvas, &sx, &sy);
++   gdk_window_get_geometry(GTK_WIDGET(canvas)->window, NULL, NULL, &wx, &wy, NULL);
++   gnome_canvas_window_to_world(canvas, sx + wx/2, sy + wy/2, &cx, &cy);
++   cx -= ui.cur_page->hoffset;
++   cy -= ui.cur_page->voffset;
++   if (cx + (ui.selection->bbox.right-ui.selection->bbox.left)/2 > ui.cur_page->width)
++     cx = ui.cur_page->width - (ui.selection->bbox.right-ui.selection->bbox.left)/2;
++   if (cx - (ui.selection->bbox.right-ui.selection->bbox.left)/2 < 0)
++     cx = (ui.selection->bbox.right-ui.selection->bbox.left)/2;
++   if (cy + (ui.selection->bbox.bottom-ui.selection->bbox.top)/2 > ui.cur_page->height)
++     cy = ui.cur_page->height - (ui.selection->bbox.bottom-ui.selection->bbox.top)/2;
++   if (cy - (ui.selection->bbox.bottom-ui.selection->bbox.top)/2 < 0)
++     cy = (ui.selection->bbox.bottom-ui.selection->bbox.top)/2;
++   hoffset = cx - (ui.selection->bbox.right+ui.selection->bbox.left)/2;
++   voffset = cy - (ui.selection->bbox.top+ui.selection->bbox.bottom)/2;
++   ui.selection->bbox.left += hoffset;
++   ui.selection->bbox.right += hoffset;
++   ui.selection->bbox.top += voffset;
++   ui.selection->bbox.bottom += voffset;
++ 
++   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);
++ 
++   while (nitems-- > 0) {
++     item = g_new(struct Item, 1);
++     ui.selection->items = g_list_append(ui.selection->items, item);
++     ui.cur_layer->items = g_list_append(ui.cur_layer->items, item);
++     ui.cur_layer->nitems++;
++     g_memmove(&item->type, p, sizeof(int)); p+= sizeof(int);
++     if (item->type == ITEM_STROKE) {
++       g_memmove(&item->brush, p, sizeof(struct Brush)); p+= sizeof(struct Brush);
++       g_memmove(&npts, p, sizeof(int)); p+= sizeof(int);
++       item->path = gnome_canvas_points_new(npts);
++       pf = (double *)p;
++       for (i=0; i<npts; i++) {
++         item->path->coords[2*i] = pf[2*i] + hoffset;
++         item->path->coords[2*i+1] = pf[2*i+1] + voffset;
++       }
++       p+= 2*item->path->num_points*sizeof(double);
++       if (item->brush.variable_width) {
++         item->widths = g_memdup(p, (item->path->num_points-1)*sizeof(double));
++         p+= (item->path->num_points-1)*sizeof(double);
++       }
++       else item->widths = NULL;
++       update_item_bbox(item);
++       make_canvas_item_one(ui.cur_layer->group, item);
++     }
++     if (item->type == ITEM_TEXT) {
++       g_memmove(&item->brush, p, sizeof(struct Brush)); p+= sizeof(struct Brush);
++       g_memmove(&item->bbox.left, p, sizeof(double)); p+= sizeof(double);
++       g_memmove(&item->bbox.top, p, sizeof(double)); p+= sizeof(double);
++       item->bbox.left += hoffset;
++       item->bbox.top += voffset;
++       g_memmove(&len, p, sizeof(int)); p+= sizeof(int);
++       item->text = g_malloc(len+1);
++       g_memmove(item->text, p, len+1); p+= len+1;
++       g_memmove(&len, p, sizeof(int)); p+= sizeof(int);
++       item->font_name = g_malloc(len+1);
++       g_memmove(item->font_name, p, len+1); p+= len+1;
++       g_memmove(&item->font_size, p, sizeof(double)); p+= sizeof(double);
++       make_canvas_item_one(ui.cur_layer->group, item);
++     }
++     if (item->type == ITEM_IMAGE) {
++       item->canvas_item = NULL;
++       item->image_scaled = NULL;
++       item->image_png = NULL;
++       item->image_png_len = 0;
++       g_memmove(&item->bbox, p, sizeof(struct BBox)); p+= sizeof(struct BBox);
++       item->bbox.left += hoffset;
++       item->bbox.right += hoffset;
++       item->bbox.top += voffset;
++       item->bbox.bottom += voffset;
++       g_memmove(&item->image_png_len, p, sizeof(gsize)); p+= sizeof(gsize);
++       if (item->image_png_len > 0) {
++         item->image_png = g_memdup(p, item->image_png_len);
++         item->image = pixbuf_from_buffer(item->image_png, item->image_png_len);
++         p+= item->image_png_len;
++       } else {
++         item->image = NULL;
++       }
++       make_canvas_item_one(ui.cur_layer->group, item);
++     }
++   }
++ 
++   prepare_new_undo();
++   undo->type = ITEM_PASTE;
++   undo->layer = ui.cur_layer;
++   undo->itemlist = g_list_copy(ui.selection->items);  
++   
++   gtk_selection_data_free(sel_data);
++   update_copy_paste_enabled();
++   update_color_menu();
++   update_thickness_buttons();
++   update_color_buttons();
++   update_font_button();  
++   update_cursor(); // FIXME: can't know if pointer is within selection!
++ }
++ 
++ // paste an external image
++ void clipboard_paste_image(GdkPixbuf *pixbuf)
++ {
++   double pt[2];
++ 
++   reset_selection();
++ 
++   get_current_pointer_coords(pt);
++   set_current_page(pt);  
++ 
++   create_image_from_pixbuf(pixbuf, NULL, pt);
++ }
++ 
++ // work out what format the clipboard data is in, and paste accordingly
++ void clipboard_paste(void)
++ {
++   GtkSelectionData *sel_data;
++   GdkPixbuf *pixbuf;
++   GtkClipboard *clipboard;
++   unsigned char *p;
++   int nitems, npts, i, len;
++   struct Item *item;
++   double hoffset, voffset, cx, cy;
++   double *pf;
++   int sx, sy, wx, wy;
++ 
++   if (ui.cur_layer == NULL) return;
++ 
++   ui.cur_item_type = ITEM_PASTE;
++   clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
++   sel_data = gtk_clipboard_wait_for_contents(
++       clipboard,
++       gdk_atom_intern("_XOURNAL", FALSE));
++   ui.cur_item_type = ITEM_NONE;
++   if (sel_data != NULL) {
++     clipboard_paste_from_xournal(sel_data);
++   } else {
++     pixbuf = gtk_clipboard_wait_for_image(clipboard);
++     if (pixbuf != NULL) {
++       clipboard_paste_image(pixbuf);
++     }
++   }
++ }
+diff -c /dev/null 'xournal/src/xo-clipboard.h'
+Index: ./src/xo-clipboard.h
+*** ./src/xo-clipboard.h	Thu Jan  1 12:00:00 1970
+--- ./src/xo-clipboard.h	Thu Mar 25 15:09:53 2010
+***************
+*** 0 ****
+--- 1,2 ----
++ void selection_to_clip(void);
++ void clipboard_paste(void);
+diff -c 'xournal-0.4.5/src/xo-file.c' 'xournal/src/xo-file.c'
+Index: ./src/xo-file.c
+*** ./src/xo-file.c	Tue Sep 29 12:36:05 2009
+--- ./src/xo-file.c	Thu Jul 29 16:59:47 2010
+***************
+*** 25,30 ****
+--- 25,31 ----
+  #include "xo-misc.h"
+  #include "xo-file.h"
+  #include "xo-paint.h"
++ #include "xo-image.h"
+  
+  const char *tool_names[NUM_TOOLS] = {"pen", "eraser", "highlighter", "text", "", "selectrect", "vertspace", "hand"};
+  const char *color_names[COLOR_MAX] = {"black", "blue", "red", "green",
+***************
+*** 68,73 ****
+--- 69,122 ----
+    }
+  }
+  
++ 
++ // Write image to file: returns true on success, false on error.
++ // The image is written as a base64 encoded PNG.
++ gboolean write_image(gzFile f, Item *item)
++ {
++   gchar *base64_str;
++   GError **error;
++ 
++   error = NULL;
++ 
++   if (item->image_png == NULL) {
++     if (!pixbuf_to_buffer(item->image, &item->image_png, &item->image_png_len, "png")) {
++       item->image_png_len = 0;       // failed for some reason, so forget it
++       return FALSE;
++     }
++   }
++ 
++   base64_str = g_base64_encode(item->image_png, item->image_png_len);
++ 
++   gzputs(f, base64_str);
++ 
++   g_free(base64_str);
++ 
++   return TRUE;
++ }
++ 
++ // create pixbuf from base64 encoded PNG, or return NULL on failure
++ GdkPixbuf *read_pixbuf(const gchar *base64_str, gsize base64_strlen)
++ {
++   gchar *base64_str2;
++   gchar *png_buf;
++   gsize png_buflen;
++   GdkPixbuf *pixbuf;
++ 
++   // We have to copy the string in order to null terminate it, sigh.
++   base64_str2 = g_memdup(base64_str, base64_strlen + 1);
++   base64_str2[ base64_strlen ] = '\0';
++   
++   png_buf = g_base64_decode(base64_str2, &png_buflen);
++ 
++   pixbuf = pixbuf_from_buffer(png_buf, png_buflen);
++ 
++   g_free(png_buf);
++   g_free(base64_str2);
++ 
++   return pixbuf;
++ }
++ 
+  // saves the journal to a file: returns true on success, false on error
+  
+  gboolean save_journal(const char *filename)
+***************
+*** 199,204 ****
+--- 248,261 ----
+            gzprintf(f, "\">%s</text>\n", tmpstr);
+            g_free(tmpstr);
+          }
++ 	if (item->type == ITEM_IMAGE) {
++           gzprintf(f, "<image left=\"%.2f\" top=\"%.2f\" right=\"%.2f\" bottom=\"%.2f\">", item->bbox.left, item->bbox.top, item->bbox.right, item->bbox.bottom);
++ 
++           if (!write_image(f, item)) {
++             success = FALSE;
++           }
++           gzprintf(f, "</image>\n");
++         }
+        }
+        gzprintf(f, "</layer>\n");
+      }
+***************
+*** 575,580 ****
+--- 632,688 ----
+      }
+      if (has_attr!=31) *error = xoj_invalid();
+    }
++   else if (!strcmp(element_name, "image")) { // start of a image item
++     if (tmpLayer == NULL || tmpItem != NULL) {
++       *error = xoj_invalid();
++       return;
++     }
++     tmpItem = (struct Item *)g_malloc0(sizeof(struct Item));
++     tmpItem->type = ITEM_IMAGE;
++     tmpItem->canvas_item = NULL;
++     tmpItem->image=NULL;
++     tmpItem->image_scaled=NULL;
++     tmpItem->image_png = NULL;
++     tmpItem->image_png_len = 0;
++     tmpLayer->items = g_list_append(tmpLayer->items, tmpItem);
++     tmpLayer->nitems++;
++     // scan for x, y
++     has_attr = 0;
++     while (*attribute_names!=NULL) {
++       if (!strcmp(*attribute_names, "left")) {
++         if (has_attr & 1) *error = xoj_invalid();
++         cleanup_numeric((gchar *)*attribute_values);
++         tmpItem->bbox.left = g_ascii_strtod(*attribute_values, &ptr);
++         if (ptr == *attribute_values) *error = xoj_invalid();
++         has_attr |= 1;
++       }
++       else if (!strcmp(*attribute_names, "top")) {
++         if (has_attr & 2) *error = xoj_invalid();
++         cleanup_numeric((gchar *)*attribute_values);
++         tmpItem->bbox.top = g_ascii_strtod(*attribute_values, &ptr);
++         if (ptr == *attribute_values) *error = xoj_invalid();
++         has_attr |= 2;
++       }
++       else if (!strcmp(*attribute_names, "right")) {
++         if (has_attr & 4) *error = xoj_invalid();
++         cleanup_numeric((gchar *)*attribute_values);
++         tmpItem->bbox.right = g_ascii_strtod(*attribute_values, &ptr);
++         if (ptr == *attribute_values) *error = xoj_invalid();
++         has_attr |= 4;
++       }
++       else if (!strcmp(*attribute_names, "bottom")) {
++         if (has_attr & 8) *error = xoj_invalid();
++         cleanup_numeric((gchar *)*attribute_values);
++         tmpItem->bbox.bottom = g_ascii_strtod(*attribute_values, &ptr);
++         if (ptr == *attribute_values) *error = xoj_invalid();
++         has_attr |= 8;
++       }
++       else *error = xoj_invalid();
++       attribute_names++;
++       attribute_values++;
++     }
++     if (has_attr!=15) *error = xoj_invalid();
++   }
+  }
+  
+  void xoj_parser_end_element(GMarkupParseContext *context,
+***************
+*** 610,615 ****
+--- 718,730 ----
+      }
+      tmpItem = NULL;
+    }
++   if (!strcmp(element_name, "image")) {
++     if (tmpItem == NULL) {
++       *error = xoj_invalid();
++       return;
++     }
++     tmpItem = NULL;
++   }
+  }
+  
+  void xoj_parser_text(GMarkupParseContext *context,
+***************
+*** 647,652 ****
+--- 762,770 ----
+      g_memmove(tmpItem->text, text, text_len);
+      tmpItem->text[text_len]=0;
+    }
++   if (!strcmp(element_name, "image")) {
++     tmpItem->image = read_pixbuf(text, text_len);
++   }
+  }
+  
+  gboolean user_wants_second_chance(char **filename)
+***************
+*** 716,722 ****
+    g_free(tmpfn);
+  
+    f = gzopen(filename, "r");
+!   if (f==NULL) return FALSE;
+    if (filename[0]=='/') {
+      if (ui.default_path != NULL) g_free(ui.default_path);
+      ui.default_path = g_path_get_dirname(filename);
+--- 834,845 ----
+    g_free(tmpfn);
+  
+    f = gzopen(filename, "r");
+!   if (f==NULL) {
+! 	  #ifdef IMAGE_DEBUG
+! 	  printf("gzopen failed\n");
+! 	  #endif
+! 	  return FALSE;
+!   }
+    if (filename[0]=='/') {
+      if (ui.default_path != NULL) g_free(ui.default_path);
+      ui.default_path = g_path_get_dirname(filename);
+***************
+*** 737,752 ****
+  
+    while (valid && !gzeof(f)) {
+      len = gzread(f, buffer, 1000);
+!     if (len<0) valid = FALSE;
+      if (maybe_pdf && len>=4 && !strncmp(buffer, "%PDF", 4))
+        { valid = FALSE; break; } // most likely pdf
+      else maybe_pdf = FALSE;
+      if (len<=0) break;
+      valid = g_markup_parse_context_parse(context, buffer, len, &error);
+    }
+    gzclose(f);
+!   if (valid) valid = g_markup_parse_context_end_parse(context, &error);
+!   if (tmpJournal.npages == 0) valid = FALSE;
+    g_markup_parse_context_free(context);
+    
+    if (!valid) {
+--- 860,893 ----
+  
+    while (valid && !gzeof(f)) {
+      len = gzread(f, buffer, 1000);
+!     if (len<0){
+! 	    valid = FALSE;
+!     }
+      if (maybe_pdf && len>=4 && !strncmp(buffer, "%PDF", 4))
+        { valid = FALSE; break; } // most likely pdf
+      else maybe_pdf = FALSE;
+      if (len<=0) break;
+      valid = g_markup_parse_context_parse(context, buffer, len, &error);
++ 	      
++ #ifdef IMAGE_DEBUG
++     if(!valid) printf("parsing failed\n");
++ #endif
+    }
+    gzclose(f);
+!   
+!   if (valid) {
+! 	  valid = g_markup_parse_context_end_parse(context, &error);
+! 	  
+! 	  #ifdef IMAGE_DEBUG
+! 	  if(!valid) printf("end parsing failed\n");
+! 	  #endif
+!   }
+!   if (tmpJournal.npages == 0){
+! 	   #ifdef IMAGE_DEBUG
+! 	  printf("found no pages\n");
+! 	  #endif
+! 	  valid = FALSE;
+!   }
+    g_markup_parse_context_free(context);
+    
+    if (!valid) {
+***************
+*** 823,828 ****
+--- 964,970 ----
+    update_page_stuff();
+    rescale_bg_pixmaps(); // this requests the PDF pages if need be
+    gtk_adjustment_set_value(gtk_layout_get_vadjustment(GTK_LAYOUT(canvas)), 0);
++   
+    return TRUE;
+  }
+  
+***************
+*** 1338,1343 ****
+--- 1480,1486 ----
+    ui.print_ruling = TRUE;
+    ui.default_unit = UNIT_CM;
+    ui.default_path = NULL;
++   ui.default_image = NULL;
+    ui.default_font_name = g_strdup(DEFAULT_FONT);
+    ui.default_font_size = DEFAULT_FONT_SIZE;
+    ui.pressure_sensitivity = FALSE;
+diff -c /dev/null 'xournal/src/xo-image.c'
+Index: ./src/xo-image.c
+*** ./src/xo-image.c	Thu Jan  1 12:00:00 1970
+--- ./src/xo-image.c	Thu Jul 29 16:54:52 2010
+***************
+*** 0 ****
+--- 1,238 ----
++ #ifdef HAVE_CONFIG_H
++ #  include <config.h>
++ #endif
++ 
++ #include <math.h>
++ #include <string.h>
++ #include <gtk/gtk.h>
++ #include <gio/gio.h>
++ 
++ #include "xournal.h"
++ #include "xo-support.h"
++ #include "xo-image.h"
++ 
++ 
++ // Write pixmap to buffer: returns true on success, false on error.
++ gboolean pixbuf_to_buffer(GdkPixbuf *pixbuf, gchar **buf, gsize *buflen, const char *type)
++ {
++   GError *error;
++ 
++   error = NULL;
++ 
++   if (!gdk_pixbuf_save_to_buffer(pixbuf,
++                                  buf,
++                                  buflen,
++                                  type,
++                                  &error,
++                                  NULL)) {
++     return FALSE;
++   }
++ 
++   return TRUE;
++ }
++ 
++ // 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, struct Item *item, double *pt)
++ {
++   GtkTextBuffer *buffer;
++   GnomeCanvasItem *canvas_item;
++   GdkColor color;
++   GtkWidget *dialog;
++   GtkFileFilter *filt_all;
++   GtkFileFilter *filt_gdkimage;
++   double scale;
++ 
++   if (item==NULL) {
++     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_scaled = NULL;
++     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 ) {
++       //set scale so that it does not extend too far to the right
++       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 ) {
++       //set scale so that it does not extend too far to the bottom
++       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);
++     g_memmove(&(item->brush), ui.cur_brush, sizeof(struct Brush));
++     ui.cur_layer->items = g_list_append(ui.cur_layer->items, item);
++     ui.cur_layer->nitems++;
++   }
++   
++   item->type = ITEM_IMAGE;
++   ui.cur_item = item;
++   
++   if (item->canvas_item!=NULL) {
++     lower_canvas_item_to(ui.cur_layer->group, canvas_item, item->canvas_item);
++     gtk_object_destroy(GTK_OBJECT(item->canvas_item));
++   }
++ 
++   make_canvas_item_one(ui.cur_layer->group, item);
++ 
++   // 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);
++ 
++   // add undo information
++   prepare_new_undo();
++   undo->type = ITEM_IMAGE;
++   undo->item = ui.cur_item;
++   undo->layer = ui.cur_layer;
++   
++   ui.cur_item = NULL;
++   ui.cur_item_type = ITEM_NONE;
++ }
++ 
++ void insert_image(GdkEvent *event, struct Item *item)
++ {
++   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, _("supported 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) {
++     /* nothing selected */
++     return;
++   }
++ 
++   if (ui.default_image != NULL) g_free(ui.default_image);
++   ui.default_image = g_strdup(filename);
++   
++   pixbuf=gdk_pixbuf_new_from_file(filename, NULL);
++   if(pixbuf==NULL){
++ 	  /* open failed */
++ 	  dialog = gtk_message_dialog_new(GTK_WINDOW (winMain), GTK_DIALOG_DESTROY_WITH_PARENT,
++ 	    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, item, pt);
++ }
++ 
++ void update_scaled_image(struct Item *item)
++ {
++   gboolean use_native = is_native_image_usable( item );
++   if ( is_native_image_usable( item ) != (item->image_scaled == NULL) ) {
++     // we are currently using a scaled image, and should switch to native,
++     // or vice versa
++ 
++     adjust_or_make_canvas_item_image(ui.cur_layer->group, item);
++   }
++ }
++ 
++ void rescale_images(void)
++ {
++   GList *pagelist, *layerlist, *itemlist;
++   struct Item *item;
++   
++   for (pagelist = journal.pages; pagelist!=NULL; pagelist = pagelist->next)
++     for (layerlist = ((struct Page *)pagelist->data)->layers; layerlist!=NULL; layerlist = layerlist->next)
++       for (itemlist = ((struct Layer *)layerlist->data)->items; itemlist!=NULL; itemlist = itemlist->next) {
++         item = (struct Item *)itemlist->data;
++         if ( item->type == ITEM_IMAGE ) {
++           update_scaled_image( item );
++         }
++       }
++ }
++ 
++ gboolean is_native_image_usable(struct Item *item)
++ {
++   double native_width;
++   double native_height;
++   double required_width;
++   double required_height;
++   gboolean usable;
++ 
++   // use the original image at native resolution if it's close enough to what we need
++   native_width  = gdk_pixbuf_get_width(item->image) / ui.zoom;
++   native_height = gdk_pixbuf_get_height(item->image) / ui.zoom;
++   required_width = item->bbox.right - item->bbox.left;
++   required_height = item->bbox.bottom - item->bbox.top;
++     
++   usable = ( fabs( native_width - required_width ) < 1 && 
++              fabs( native_height - required_height ) < 1 );
++ 
++   return usable;
++ }
+diff -c /dev/null 'xournal/src/xo-image.h'
+Index: ./src/xo-image.h
+*** ./src/xo-image.h	Thu Jan  1 12:00:00 1970
+--- ./src/xo-image.h	Thu Jun 24 20:42:02 2010
+***************
+*** 0 ****
+--- 1,7 ----
++ extern gboolean pixbuf_to_buffer(GdkPixbuf *pixbuf, gchar **buf, gsize *buflen, const char *type);
++ extern GdkPixbuf *pixbuf_from_buffer(const gchar *buf, gsize buflen);
++ 
++ void create_image_from_pixbuf(GdkPixbuf *pixbuf, struct Item *item, double *pt);
++ void insert_image(GdkEvent *event, struct Item *item);
++ void rescale_images(void);
++ gboolean is_native_image_usable(struct Item *item);
+diff -c 'xournal-0.4.5/src/xo-interface.c' 'xournal/src/xo-interface.c'
+Index: ./src/xo-interface.c
+*** ./src/xo-interface.c	Fri Oct  2 19:03:32 2009
+--- ./src/xo-interface.c	Mon Mar 22 11:39:25 2010
+***************
+*** 36,42 ****
+    GtkWidget *menuFile_menu;
+    GtkWidget *fileNew;
+    GtkWidget *fileNewBackground;
+-   GtkWidget *image623;
+    GtkWidget *fileOpen;
+    GtkWidget *fileSave;
+    GtkWidget *fileSaveAs;
+--- 36,41 ----
+***************
+*** 53,59 ****
+    GtkWidget *mru7;
+    GtkWidget *separator22;
+    GtkWidget *filePrintOptions;
+-   GtkWidget *image624;
+    GtkWidget *filePrint;
+    GtkWidget *filePrintPDF;
+    GtkWidget *separator2;
+--- 52,57 ----
+***************
+*** 81,102 ****
+    GtkWidget *viewZoomOut;
+    GtkWidget *viewNormalSize;
+    GtkWidget *viewPageWidth;
+-   GtkWidget *image625;
+    GtkWidget *viewSetZoom;
+    GtkWidget *separator5;
+    GtkWidget *viewFirstPage;
+-   GtkWidget *image626;
+    GtkWidget *viewPreviousPage;
+-   GtkWidget *image627;
+    GtkWidget *viewNextPage;
+-   GtkWidget *image628;
+    GtkWidget *viewLastPage;
+-   GtkWidget *image629;
+    GtkWidget *separator6;
+    GtkWidget *viewShowLayer;
+-   GtkWidget *image630;
+    GtkWidget *viewHideLayer;
+-   GtkWidget *image631;
+    GtkWidget *menuJournal;
+    GtkWidget *menuJournal_menu;
+    GtkWidget *journalNewPageBefore;
+--- 79,93 ----
+***************
+*** 131,137 ****
+    GtkWidget *journalApplyAllPages;
+    GtkWidget *separator23;
+    GtkWidget *journalLoadBackground;
+-   GtkWidget *image632;
+    GtkWidget *journalScreenshot;
+    GtkWidget *separator19;
+    GtkWidget *journalDefaultBackground;
+--- 122,127 ----
+***************
+*** 153,159 ****
+    GtkWidget *toolsHand;
+    GtkWidget *separator16;
+    GtkWidget *toolsColor;
+-   GtkWidget *image633;
+    GtkWidget *toolsColor_menu;
+    GSList *colorBlack_group = NULL;
+    GtkWidget *colorBlack;
+--- 143,148 ----
+***************
+*** 196,202 ****
+    GtkWidget *highlighterMedium;
+    GtkWidget *highlighterThick;
+    GtkWidget *toolsTextFont;
+-   GtkWidget *image634;
+    GtkWidget *separator10;
+    GtkWidget *toolsDefaultPen;
+    GtkWidget *toolsDefaultEraser;
+--- 185,190 ----
+***************
+*** 289,294 ****
+--- 277,283 ----
+    GtkWidget *buttonEraser;
+    GtkWidget *buttonHighlighter;
+    GtkWidget *buttonText;
++   GtkWidget *buttonImage;
+    GtkWidget *buttonReco;
+    GtkWidget *buttonRuler;
+    GtkWidget *toolitem15;
+***************
+*** 368,381 ****
+    gtk_widget_show (fileNew);
+    gtk_container_add (GTK_CONTAINER (menuFile_menu), fileNew);
+  
+!   fileNewBackground = gtk_image_menu_item_new_with_mnemonic (_("Annotate PD_F"));
+    gtk_widget_show (fileNewBackground);
+    gtk_container_add (GTK_CONTAINER (menuFile_menu), fileNewBackground);
+  
+-   image623 = gtk_image_new_from_stock ("gtk-open", GTK_ICON_SIZE_MENU);
+-   gtk_widget_show (image623);
+-   gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (fileNewBackground), image623);
+- 
+    fileOpen = gtk_image_menu_item_new_from_stock ("gtk-open", accel_group);
+    gtk_widget_show (fileOpen);
+    gtk_container_add (GTK_CONTAINER (menuFile_menu), fileOpen);
+--- 357,366 ----
+    gtk_widget_show (fileNew);
+    gtk_container_add (GTK_CONTAINER (menuFile_menu), fileNew);
+  
+!   fileNewBackground = gtk_image_menu_item_new_with_mnemonic ("Annotate PD_F");
+    gtk_widget_show (fileNewBackground);
+    gtk_container_add (GTK_CONTAINER (menuFile_menu), fileNewBackground);
+  
+    fileOpen = gtk_image_menu_item_new_from_stock ("gtk-open", accel_group);
+    gtk_widget_show (fileOpen);
+    gtk_container_add (GTK_CONTAINER (menuFile_menu), fileOpen);
+***************
+*** 437,450 ****
+    gtk_container_add (GTK_CONTAINER (menuFile_menu), separator22);
+    gtk_widget_set_sensitive (separator22, FALSE);
+  
+!   filePrintOptions = gtk_image_menu_item_new_with_mnemonic (_("Print Options"));
+    gtk_widget_show (filePrintOptions);
+    gtk_container_add (GTK_CONTAINER (menuFile_menu), filePrintOptions);
+  
+-   image624 = gtk_image_new_from_stock ("gtk-preferences", GTK_ICON_SIZE_MENU);
+-   gtk_widget_show (image624);
+-   gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (filePrintOptions), image624);
+- 
+    filePrint = gtk_image_menu_item_new_from_stock ("gtk-print", accel_group);
+    gtk_widget_show (filePrint);
+    gtk_container_add (GTK_CONTAINER (menuFile_menu), filePrint);
+--- 422,431 ----
+    gtk_container_add (GTK_CONTAINER (menuFile_menu), separator22);
+    gtk_widget_set_sensitive (separator22, FALSE);
+  
+!   filePrintOptions = gtk_image_menu_item_new_with_mnemonic ("Print Options");
+    gtk_widget_show (filePrintOptions);
+    gtk_container_add (GTK_CONTAINER (menuFile_menu), filePrintOptions);
+  
+    filePrint = gtk_image_menu_item_new_from_stock ("gtk-print", accel_group);
+    gtk_widget_show (filePrint);
+    gtk_container_add (GTK_CONTAINER (menuFile_menu), filePrint);
+***************
+*** 577,593 ****
+                                GDK_0, (GdkModifierType) GDK_CONTROL_MASK,
+                                GTK_ACCEL_VISIBLE);
+  
+!   viewPageWidth = gtk_image_menu_item_new_with_mnemonic (_("Page _Width"));
+    gtk_widget_show (viewPageWidth);
+    gtk_container_add (GTK_CONTAINER (menuViewZoom_menu), viewPageWidth);
+    gtk_widget_add_accelerator (viewPageWidth, "activate", accel_group,
+                                GDK_equal, (GdkModifierType) GDK_CONTROL_MASK,
+                                GTK_ACCEL_VISIBLE);
+  
+-   image625 = gtk_image_new_from_stock ("gtk-zoom-fit", GTK_ICON_SIZE_MENU);
+-   gtk_widget_show (image625);
+-   gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (viewPageWidth), image625);
+- 
+    viewSetZoom = gtk_menu_item_new_with_mnemonic (_("_Set Zoom"));
+    gtk_widget_show (viewSetZoom);
+    gtk_container_add (GTK_CONTAINER (menuViewZoom_menu), viewSetZoom);
+--- 558,570 ----
+                                GDK_0, (GdkModifierType) GDK_CONTROL_MASK,
+                                GTK_ACCEL_VISIBLE);
+  
+!   viewPageWidth = gtk_image_menu_item_new_with_mnemonic ("Page _Width");
+    gtk_widget_show (viewPageWidth);
+    gtk_container_add (GTK_CONTAINER (menuViewZoom_menu), viewPageWidth);
+    gtk_widget_add_accelerator (viewPageWidth, "activate", accel_group,
+                                GDK_equal, (GdkModifierType) GDK_CONTROL_MASK,
+                                GTK_ACCEL_VISIBLE);
+  
+    viewSetZoom = gtk_menu_item_new_with_mnemonic (_("_Set Zoom"));
+    gtk_widget_show (viewSetZoom);
+    gtk_container_add (GTK_CONTAINER (menuViewZoom_menu), viewSetZoom);
+***************
+*** 597,667 ****
+    gtk_container_add (GTK_CONTAINER (menuView_menu), separator5);
+    gtk_widget_set_sensitive (separator5, FALSE);
+  
+!   viewFirstPage = gtk_image_menu_item_new_with_mnemonic (_("_First Page"));
+    gtk_widget_show (viewFirstPage);
+    gtk_container_add (GTK_CONTAINER (menuView_menu), viewFirstPage);
+    gtk_widget_add_accelerator (viewFirstPage, "activate", accel_group,
+                                GDK_Home, (GdkModifierType) GDK_CONTROL_MASK,
+                                GTK_ACCEL_VISIBLE);
+  
+!   image626 = gtk_image_new_from_stock ("gtk-goto-first", GTK_ICON_SIZE_MENU);
+!   gtk_widget_show (image626);
+!   gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (viewFirstPage), image626);
+! 
+!   viewPreviousPage = gtk_image_menu_item_new_with_mnemonic (_("_Previous Page"));
+    gtk_widget_show (viewPreviousPage);
+    gtk_container_add (GTK_CONTAINER (menuView_menu), viewPreviousPage);
+    gtk_widget_add_accelerator (viewPreviousPage, "activate", accel_group,
+                                GDK_Left, (GdkModifierType) GDK_CONTROL_MASK,
+                                GTK_ACCEL_VISIBLE);
+  
+!   image627 = gtk_image_new_from_stock ("gtk-go-back", GTK_ICON_SIZE_MENU);
+!   gtk_widget_show (image627);
+!   gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (viewPreviousPage), image627);
+! 
+!   viewNextPage = gtk_image_menu_item_new_with_mnemonic (_("_Next Page"));
+    gtk_widget_show (viewNextPage);
+    gtk_container_add (GTK_CONTAINER (menuView_menu), viewNextPage);
+    gtk_widget_add_accelerator (viewNextPage, "activate", accel_group,
+                                GDK_Right, (GdkModifierType) GDK_CONTROL_MASK,
+                                GTK_ACCEL_VISIBLE);
+  
+!   image628 = gtk_image_new_from_stock ("gtk-go-forward", GTK_ICON_SIZE_MENU);
+!   gtk_widget_show (image628);
+!   gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (viewNextPage), image628);
+! 
+!   viewLastPage = gtk_image_menu_item_new_with_mnemonic (_("_Last Page"));
+    gtk_widget_show (viewLastPage);
+    gtk_container_add (GTK_CONTAINER (menuView_menu), viewLastPage);
+    gtk_widget_add_accelerator (viewLastPage, "activate", accel_group,
+                                GDK_End, (GdkModifierType) GDK_CONTROL_MASK,
+                                GTK_ACCEL_VISIBLE);
+  
+-   image629 = gtk_image_new_from_stock ("gtk-goto-last", GTK_ICON_SIZE_MENU);
+-   gtk_widget_show (image629);
+-   gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (viewLastPage), image629);
+- 
+    separator6 = gtk_separator_menu_item_new ();
+    gtk_widget_show (separator6);
+    gtk_container_add (GTK_CONTAINER (menuView_menu), separator6);
+    gtk_widget_set_sensitive (separator6, FALSE);
+  
+!   viewShowLayer = gtk_image_menu_item_new_with_mnemonic (_("_Show Layer"));
+    gtk_widget_show (viewShowLayer);
+    gtk_container_add (GTK_CONTAINER (menuView_menu), viewShowLayer);
+  
+!   image630 = gtk_image_new_from_stock ("gtk-add", GTK_ICON_SIZE_MENU);
+!   gtk_widget_show (image630);
+!   gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (viewShowLayer), image630);
+! 
+!   viewHideLayer = gtk_image_menu_item_new_with_mnemonic (_("_Hide Layer"));
+    gtk_widget_show (viewHideLayer);
+    gtk_container_add (GTK_CONTAINER (menuView_menu), viewHideLayer);
+  
+-   image631 = gtk_image_new_from_stock ("gtk-remove", GTK_ICON_SIZE_MENU);
+-   gtk_widget_show (image631);
+-   gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (viewHideLayer), image631);
+- 
+    menuJournal = gtk_menu_item_new_with_mnemonic (_("_Journal"));
+    gtk_widget_show (menuJournal);
+    gtk_container_add (GTK_CONTAINER (menubar), menuJournal);
+--- 574,620 ----
+    gtk_container_add (GTK_CONTAINER (menuView_menu), separator5);
+    gtk_widget_set_sensitive (separator5, FALSE);
+  
+!   viewFirstPage = gtk_image_menu_item_new_with_mnemonic ("_First Page");
+    gtk_widget_show (viewFirstPage);
+    gtk_container_add (GTK_CONTAINER (menuView_menu), viewFirstPage);
+    gtk_widget_add_accelerator (viewFirstPage, "activate", accel_group,
+                                GDK_Home, (GdkModifierType) GDK_CONTROL_MASK,
+                                GTK_ACCEL_VISIBLE);
+  
+!   viewPreviousPage = gtk_image_menu_item_new_with_mnemonic ("_Previous Page");
+    gtk_widget_show (viewPreviousPage);
+    gtk_container_add (GTK_CONTAINER (menuView_menu), viewPreviousPage);
+    gtk_widget_add_accelerator (viewPreviousPage, "activate", accel_group,
+                                GDK_Left, (GdkModifierType) GDK_CONTROL_MASK,
+                                GTK_ACCEL_VISIBLE);
+  
+!   viewNextPage = gtk_image_menu_item_new_with_mnemonic ("_Next Page");
+    gtk_widget_show (viewNextPage);
+    gtk_container_add (GTK_CONTAINER (menuView_menu), viewNextPage);
+    gtk_widget_add_accelerator (viewNextPage, "activate", accel_group,
+                                GDK_Right, (GdkModifierType) GDK_CONTROL_MASK,
+                                GTK_ACCEL_VISIBLE);
+  
+!   viewLastPage = gtk_image_menu_item_new_with_mnemonic ("_Last Page");
+    gtk_widget_show (viewLastPage);
+    gtk_container_add (GTK_CONTAINER (menuView_menu), viewLastPage);
+    gtk_widget_add_accelerator (viewLastPage, "activate", accel_group,
+                                GDK_End, (GdkModifierType) GDK_CONTROL_MASK,
+                                GTK_ACCEL_VISIBLE);
+  
+    separator6 = gtk_separator_menu_item_new ();
+    gtk_widget_show (separator6);
+    gtk_container_add (GTK_CONTAINER (menuView_menu), separator6);
+    gtk_widget_set_sensitive (separator6, FALSE);
+  
+!   viewShowLayer = gtk_image_menu_item_new_with_mnemonic ("_Show Layer");
+    gtk_widget_show (viewShowLayer);
+    gtk_container_add (GTK_CONTAINER (menuView_menu), viewShowLayer);
+  
+!   viewHideLayer = gtk_image_menu_item_new_with_mnemonic ("_Hide Layer");
+    gtk_widget_show (viewHideLayer);
+    gtk_container_add (GTK_CONTAINER (menuView_menu), viewHideLayer);
+  
+    menuJournal = gtk_menu_item_new_with_mnemonic (_("_Journal"));
+    gtk_widget_show (menuJournal);
+    gtk_container_add (GTK_CONTAINER (menubar), menuJournal);
+***************
+*** 808,821 ****
+    gtk_container_add (GTK_CONTAINER (menuJournal_menu), separator23);
+    gtk_widget_set_sensitive (separator23, FALSE);
+  
+!   journalLoadBackground = gtk_image_menu_item_new_with_mnemonic (_("_Load Background"));
+    gtk_widget_show (journalLoadBackground);
+    gtk_container_add (GTK_CONTAINER (menuJournal_menu), journalLoadBackground);
+  
+-   image632 = gtk_image_new_from_stock ("gtk-open", GTK_ICON_SIZE_MENU);
+-   gtk_widget_show (image632);
+-   gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (journalLoadBackground), image632);
+- 
+    journalScreenshot = gtk_menu_item_new_with_mnemonic (_("Background Screens_hot"));
+    gtk_widget_show (journalScreenshot);
+    gtk_container_add (GTK_CONTAINER (menuJournal_menu), journalScreenshot);
+--- 761,770 ----
+    gtk_container_add (GTK_CONTAINER (menuJournal_menu), separator23);
+    gtk_widget_set_sensitive (separator23, FALSE);
+  
+!   journalLoadBackground = gtk_image_menu_item_new_with_mnemonic ("_Load Background");
+    gtk_widget_show (journalLoadBackground);
+    gtk_container_add (GTK_CONTAINER (menuJournal_menu), journalLoadBackground);
+  
+    journalScreenshot = gtk_menu_item_new_with_mnemonic (_("Background Screens_hot"));
+    gtk_widget_show (journalScreenshot);
+    gtk_container_add (GTK_CONTAINER (menuJournal_menu), journalScreenshot);
+***************
+*** 940,953 ****
+    gtk_container_add (GTK_CONTAINER (menuTools_menu), separator16);
+    gtk_widget_set_sensitive (separator16, FALSE);
+  
+!   toolsColor = gtk_image_menu_item_new_with_mnemonic (_("_Color"));
+    gtk_widget_show (toolsColor);
+    gtk_container_add (GTK_CONTAINER (menuTools_menu), toolsColor);
+  
+-   image633 = gtk_image_new_from_stock ("gtk-select-color", GTK_ICON_SIZE_MENU);
+-   gtk_widget_show (image633);
+-   gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (toolsColor), image633);
+- 
+    toolsColor_menu = gtk_menu_new ();
+    gtk_menu_item_set_submenu (GTK_MENU_ITEM (toolsColor), toolsColor_menu);
+  
+--- 889,898 ----
+    gtk_container_add (GTK_CONTAINER (menuTools_menu), separator16);
+    gtk_widget_set_sensitive (separator16, FALSE);
+  
+!   toolsColor = gtk_image_menu_item_new_with_mnemonic ("_Color");
+    gtk_widget_show (toolsColor);
+    gtk_container_add (GTK_CONTAINER (menuTools_menu), toolsColor);
+  
+    toolsColor_menu = gtk_menu_new ();
+    gtk_menu_item_set_submenu (GTK_MENU_ITEM (toolsColor), toolsColor_menu);
+  
+***************
+*** 1141,1157 ****
+    gtk_container_add (GTK_CONTAINER (toolsHighlighterOptions_menu), highlighterThick);
+    gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (highlighterThick), TRUE);
+  
+!   toolsTextFont = gtk_image_menu_item_new_with_mnemonic (_("Text _Font..."));
+    gtk_widget_show (toolsTextFont);
+    gtk_container_add (GTK_CONTAINER (menuTools_menu), toolsTextFont);
+    gtk_widget_add_accelerator (toolsTextFont, "activate", accel_group,
+                                GDK_F, (GdkModifierType) GDK_CONTROL_MASK | GDK_SHIFT_MASK,
+                                GTK_ACCEL_VISIBLE);
+  
+-   image634 = gtk_image_new_from_stock ("gtk-select-font", GTK_ICON_SIZE_MENU);
+-   gtk_widget_show (image634);
+-   gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (toolsTextFont), image634);
+- 
+    separator10 = gtk_separator_menu_item_new ();
+    gtk_widget_show (separator10);
+    gtk_container_add (GTK_CONTAINER (menuTools_menu), separator10);
+--- 1086,1098 ----
+    gtk_container_add (GTK_CONTAINER (toolsHighlighterOptions_menu), highlighterThick);
+    gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (highlighterThick), TRUE);
+  
+!   toolsTextFont = gtk_image_menu_item_new_with_mnemonic ("Text _Font...");
+    gtk_widget_show (toolsTextFont);
+    gtk_container_add (GTK_CONTAINER (menuTools_menu), toolsTextFont);
+    gtk_widget_add_accelerator (toolsTextFont, "activate", accel_group,
+                                GDK_F, (GdkModifierType) GDK_CONTROL_MASK | GDK_SHIFT_MASK,
+                                GTK_ACCEL_VISIBLE);
+  
+    separator10 = gtk_separator_menu_item_new ();
+    gtk_widget_show (separator10);
+    gtk_container_add (GTK_CONTAINER (menuTools_menu), separator10);
+***************
+*** 1588,1593 ****
+--- 1529,1545 ----
+    gtk_radio_tool_button_set_group (GTK_RADIO_TOOL_BUTTON (buttonText), buttonPen_group);
+    buttonPen_group = gtk_radio_tool_button_get_group (GTK_RADIO_TOOL_BUTTON (buttonText));
+  
++   buttonImage = (GtkWidget*) gtk_radio_tool_button_new (NULL);
++   gtk_tool_button_set_label (GTK_TOOL_BUTTON (buttonImage), _("Image"));
++   tmp_image = gtk_image_new_from_stock ("gtk-orientation-portrait", tmp_toolbar_icon_size);
++   gtk_widget_show (tmp_image);
++   gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (buttonImage), tmp_image);
++   gtk_widget_show (buttonImage);
++   gtk_container_add (GTK_CONTAINER (toolbarPen), buttonImage);
++   gtk_tool_item_set_tooltip (GTK_TOOL_ITEM (buttonImage), tooltips, _("Image"), NULL);
++   gtk_radio_tool_button_set_group (GTK_RADIO_TOOL_BUTTON (buttonImage), buttonPen_group);
++   buttonPen_group = gtk_radio_tool_button_get_group (GTK_RADIO_TOOL_BUTTON (buttonImage));
++ 
+    buttonReco = (GtkWidget*) gtk_toggle_tool_button_new ();
+    gtk_tool_button_set_label (GTK_TOOL_BUTTON (buttonReco), _("Shape Recognizer"));
+    tmp_image = create_pixmap (winMain, "shapes.png");
+***************
+*** 1669,1675 ****
+    gtk_widget_show (tmp_image);
+    buttonToolDefault = (GtkWidget*) gtk_tool_button_new (tmp_image, _("Default"));
+    gtk_widget_show (buttonToolDefault);
+-   gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (buttonToolDefault), FALSE);
+    gtk_container_add (GTK_CONTAINER (toolbarPen), buttonToolDefault);
+    gtk_tool_item_set_tooltip (GTK_TOOL_ITEM (buttonToolDefault), tooltips, _("Default"), NULL);
+  
+--- 1621,1626 ----
+***************
+*** 1694,1700 ****
+    gtk_widget_show (tmp_image);
+    gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (buttonFine), tmp_image);
+    gtk_widget_show (buttonFine);
+-   gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (buttonFine), FALSE);
+    gtk_container_add (GTK_CONTAINER (toolbarPen), buttonFine);
+    gtk_widget_set_size_request (buttonFine, 24, -1);
+    gtk_tool_item_set_tooltip (GTK_TOOL_ITEM (buttonFine), tooltips, _("Fine"), NULL);
+--- 1645,1650 ----
+***************
+*** 1707,1713 ****
+    gtk_widget_show (tmp_image);
+    gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (buttonMedium), tmp_image);
+    gtk_widget_show (buttonMedium);
+-   gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (buttonMedium), FALSE);
+    gtk_container_add (GTK_CONTAINER (toolbarPen), buttonMedium);
+    gtk_widget_set_size_request (buttonMedium, 24, -1);
+    gtk_tool_item_set_tooltip (GTK_TOOL_ITEM (buttonMedium), tooltips, _("Medium"), NULL);
+--- 1657,1662 ----
+***************
+*** 1720,1726 ****
+    gtk_widget_show (tmp_image);
+    gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (buttonThick), tmp_image);
+    gtk_widget_show (buttonThick);
+-   gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (buttonThick), FALSE);
+    gtk_container_add (GTK_CONTAINER (toolbarPen), buttonThick);
+    gtk_widget_set_size_request (buttonThick, 24, -1);
+    gtk_tool_item_set_tooltip (GTK_TOOL_ITEM (buttonThick), tooltips, _("Thick"), NULL);
+--- 1669,1674 ----
+***************
+*** 1747,1753 ****
+    gtk_widget_show (tmp_image);
+    gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (buttonBlack), tmp_image);
+    gtk_widget_show (buttonBlack);
+-   gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (buttonBlack), FALSE);
+    gtk_container_add (GTK_CONTAINER (toolbarPen), buttonBlack);
+    gtk_tool_item_set_tooltip (GTK_TOOL_ITEM (buttonBlack), tooltips, _("Black"), NULL);
+    gtk_radio_tool_button_set_group (GTK_RADIO_TOOL_BUTTON (buttonBlack), buttonBlack_group);
+--- 1695,1700 ----
+***************
+*** 1759,1765 ****
+    gtk_widget_show (tmp_image);
+    gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (buttonBlue), tmp_image);
+    gtk_widget_show (buttonBlue);
+-   gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (buttonBlue), FALSE);
+    gtk_container_add (GTK_CONTAINER (toolbarPen), buttonBlue);
+    gtk_tool_item_set_tooltip (GTK_TOOL_ITEM (buttonBlue), tooltips, _("Blue"), NULL);
+    gtk_radio_tool_button_set_group (GTK_RADIO_TOOL_BUTTON (buttonBlue), buttonBlack_group);
+--- 1706,1711 ----
+***************
+*** 1771,1777 ****
+    gtk_widget_show (tmp_image);
+    gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (buttonRed), tmp_image);
+    gtk_widget_show (buttonRed);
+-   gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (buttonRed), FALSE);
+    gtk_container_add (GTK_CONTAINER (toolbarPen), buttonRed);
+    gtk_tool_item_set_tooltip (GTK_TOOL_ITEM (buttonRed), tooltips, _("Red"), NULL);
+    gtk_radio_tool_button_set_group (GTK_RADIO_TOOL_BUTTON (buttonRed), buttonBlack_group);
+--- 1717,1722 ----
+***************
+*** 1783,1789 ****
+    gtk_widget_show (tmp_image);
+    gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (buttonGreen), tmp_image);
+    gtk_widget_show (buttonGreen);
+-   gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (buttonGreen), FALSE);
+    gtk_container_add (GTK_CONTAINER (toolbarPen), buttonGreen);
+    gtk_tool_item_set_tooltip (GTK_TOOL_ITEM (buttonGreen), tooltips, _("Green"), NULL);
+    gtk_radio_tool_button_set_group (GTK_RADIO_TOOL_BUTTON (buttonGreen), buttonBlack_group);
+--- 1728,1733 ----
+***************
+*** 1795,1801 ****
+    gtk_widget_show (tmp_image);
+    gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (buttonGray), tmp_image);
+    gtk_widget_show (buttonGray);
+-   gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (buttonGray), FALSE);
+    gtk_container_add (GTK_CONTAINER (toolbarPen), buttonGray);
+    gtk_tool_item_set_tooltip (GTK_TOOL_ITEM (buttonGray), tooltips, _("Gray"), NULL);
+    gtk_radio_tool_button_set_group (GTK_RADIO_TOOL_BUTTON (buttonGray), buttonBlack_group);
+--- 1739,1744 ----
+***************
+*** 1807,1813 ****
+    gtk_widget_show (tmp_image);
+    gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (buttonLightBlue), tmp_image);
+    gtk_widget_show (buttonLightBlue);
+-   gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (buttonLightBlue), FALSE);
+    gtk_container_add (GTK_CONTAINER (toolbarPen), buttonLightBlue);
+    gtk_tool_item_set_tooltip (GTK_TOOL_ITEM (buttonLightBlue), tooltips, _("Light Blue"), NULL);
+    gtk_radio_tool_button_set_group (GTK_RADIO_TOOL_BUTTON (buttonLightBlue), buttonBlack_group);
+--- 1750,1755 ----
+***************
+*** 1819,1825 ****
+    gtk_widget_show (tmp_image);
+    gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (buttonLightGreen), tmp_image);
+    gtk_widget_show (buttonLightGreen);
+-   gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (buttonLightGreen), FALSE);
+    gtk_container_add (GTK_CONTAINER (toolbarPen), buttonLightGreen);
+    gtk_tool_item_set_tooltip (GTK_TOOL_ITEM (buttonLightGreen), tooltips, _("Light Green"), NULL);
+    gtk_radio_tool_button_set_group (GTK_RADIO_TOOL_BUTTON (buttonLightGreen), buttonBlack_group);
+--- 1761,1766 ----
+***************
+*** 1831,1837 ****
+    gtk_widget_show (tmp_image);
+    gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (buttonMagenta), tmp_image);
+    gtk_widget_show (buttonMagenta);
+-   gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (buttonMagenta), FALSE);
+    gtk_container_add (GTK_CONTAINER (toolbarPen), buttonMagenta);
+    gtk_tool_item_set_tooltip (GTK_TOOL_ITEM (buttonMagenta), tooltips, _("Magenta"), NULL);
+    gtk_radio_tool_button_set_group (GTK_RADIO_TOOL_BUTTON (buttonMagenta), buttonBlack_group);
+--- 1772,1777 ----
+***************
+*** 1843,1849 ****
+    gtk_widget_show (tmp_image);
+    gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (buttonOrange), tmp_image);
+    gtk_widget_show (buttonOrange);
+-   gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (buttonOrange), FALSE);
+    gtk_container_add (GTK_CONTAINER (toolbarPen), buttonOrange);
+    gtk_tool_item_set_tooltip (GTK_TOOL_ITEM (buttonOrange), tooltips, _("Orange"), NULL);
+    gtk_radio_tool_button_set_group (GTK_RADIO_TOOL_BUTTON (buttonOrange), buttonBlack_group);
+--- 1783,1788 ----
+***************
+*** 1855,1861 ****
+    gtk_widget_show (tmp_image);
+    gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (buttonYellow), tmp_image);
+    gtk_widget_show (buttonYellow);
+-   gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (buttonYellow), FALSE);
+    gtk_container_add (GTK_CONTAINER (toolbarPen), buttonYellow);
+    gtk_tool_item_set_tooltip (GTK_TOOL_ITEM (buttonYellow), tooltips, _("Yellow"), NULL);
+    gtk_radio_tool_button_set_group (GTK_RADIO_TOOL_BUTTON (buttonYellow), buttonBlack_group);
+--- 1794,1799 ----
+***************
+*** 1867,1873 ****
+    gtk_widget_show (tmp_image);
+    gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (buttonWhite), tmp_image);
+    gtk_widget_show (buttonWhite);
+-   gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (buttonWhite), FALSE);
+    gtk_container_add (GTK_CONTAINER (toolbarPen), buttonWhite);
+    gtk_tool_item_set_tooltip (GTK_TOOL_ITEM (buttonWhite), tooltips, _("White"), NULL);
+    gtk_radio_tool_button_set_group (GTK_RADIO_TOOL_BUTTON (buttonWhite), buttonBlack_group);
+--- 1805,1810 ----
+***************
+*** 2426,2431 ****
+--- 2363,2371 ----
+    g_signal_connect ((gpointer) buttonText, "toggled",
+                      G_CALLBACK (on_toolsText_activate),
+                      NULL);
++   g_signal_connect ((gpointer) buttonImage, "toggled",
++                     G_CALLBACK (on_toolsImage_activate),
++                     NULL);
+    g_signal_connect ((gpointer) buttonReco, "toggled",
+                      G_CALLBACK (on_toolsReco_activate),
+                      NULL);
+***************
+*** 2513,2519 ****
+    GLADE_HOOKUP_OBJECT (winMain, menuFile_menu, "menuFile_menu");
+    GLADE_HOOKUP_OBJECT (winMain, fileNew, "fileNew");
+    GLADE_HOOKUP_OBJECT (winMain, fileNewBackground, "fileNewBackground");
+-   GLADE_HOOKUP_OBJECT (winMain, image623, "image623");
+    GLADE_HOOKUP_OBJECT (winMain, fileOpen, "fileOpen");
+    GLADE_HOOKUP_OBJECT (winMain, fileSave, "fileSave");
+    GLADE_HOOKUP_OBJECT (winMain, fileSaveAs, "fileSaveAs");
+--- 2453,2458 ----
+***************
+*** 2530,2536 ****
+    GLADE_HOOKUP_OBJECT (winMain, mru7, "mru7");
+    GLADE_HOOKUP_OBJECT (winMain, separator22, "separator22");
+    GLADE_HOOKUP_OBJECT (winMain, filePrintOptions, "filePrintOptions");
+-   GLADE_HOOKUP_OBJECT (winMain, image624, "image624");
+    GLADE_HOOKUP_OBJECT (winMain, filePrint, "filePrint");
+    GLADE_HOOKUP_OBJECT (winMain, filePrintPDF, "filePrintPDF");
+    GLADE_HOOKUP_OBJECT (winMain, separator2, "separator2");
+--- 2469,2474 ----
+***************
+*** 2557,2578 ****
+    GLADE_HOOKUP_OBJECT (winMain, viewZoomOut, "viewZoomOut");
+    GLADE_HOOKUP_OBJECT (winMain, viewNormalSize, "viewNormalSize");
+    GLADE_HOOKUP_OBJECT (winMain, viewPageWidth, "viewPageWidth");
+-   GLADE_HOOKUP_OBJECT (winMain, image625, "image625");
+    GLADE_HOOKUP_OBJECT (winMain, viewSetZoom, "viewSetZoom");
+    GLADE_HOOKUP_OBJECT (winMain, separator5, "separator5");
+    GLADE_HOOKUP_OBJECT (winMain, viewFirstPage, "viewFirstPage");
+-   GLADE_HOOKUP_OBJECT (winMain, image626, "image626");
+    GLADE_HOOKUP_OBJECT (winMain, viewPreviousPage, "viewPreviousPage");
+-   GLADE_HOOKUP_OBJECT (winMain, image627, "image627");
+    GLADE_HOOKUP_OBJECT (winMain, viewNextPage, "viewNextPage");
+-   GLADE_HOOKUP_OBJECT (winMain, image628, "image628");
+    GLADE_HOOKUP_OBJECT (winMain, viewLastPage, "viewLastPage");
+-   GLADE_HOOKUP_OBJECT (winMain, image629, "image629");
+    GLADE_HOOKUP_OBJECT (winMain, separator6, "separator6");
+    GLADE_HOOKUP_OBJECT (winMain, viewShowLayer, "viewShowLayer");
+-   GLADE_HOOKUP_OBJECT (winMain, image630, "image630");
+    GLADE_HOOKUP_OBJECT (winMain, viewHideLayer, "viewHideLayer");
+-   GLADE_HOOKUP_OBJECT (winMain, image631, "image631");
+    GLADE_HOOKUP_OBJECT (winMain, menuJournal, "menuJournal");
+    GLADE_HOOKUP_OBJECT (winMain, menuJournal_menu, "menuJournal_menu");
+    GLADE_HOOKUP_OBJECT (winMain, journalNewPageBefore, "journalNewPageBefore");
+--- 2495,2509 ----
+***************
+*** 2605,2611 ****
+    GLADE_HOOKUP_OBJECT (winMain, journalApplyAllPages, "journalApplyAllPages");
+    GLADE_HOOKUP_OBJECT (winMain, separator23, "separator23");
+    GLADE_HOOKUP_OBJECT (winMain, journalLoadBackground, "journalLoadBackground");
+-   GLADE_HOOKUP_OBJECT (winMain, image632, "image632");
+    GLADE_HOOKUP_OBJECT (winMain, journalScreenshot, "journalScreenshot");
+    GLADE_HOOKUP_OBJECT (winMain, separator19, "separator19");
+    GLADE_HOOKUP_OBJECT (winMain, journalDefaultBackground, "journalDefaultBackground");
+--- 2536,2541 ----
+***************
+*** 2626,2632 ****
+    GLADE_HOOKUP_OBJECT (winMain, toolsHand, "toolsHand");
+    GLADE_HOOKUP_OBJECT (winMain, separator16, "separator16");
+    GLADE_HOOKUP_OBJECT (winMain, toolsColor, "toolsColor");
+-   GLADE_HOOKUP_OBJECT (winMain, image633, "image633");
+    GLADE_HOOKUP_OBJECT (winMain, toolsColor_menu, "toolsColor_menu");
+    GLADE_HOOKUP_OBJECT (winMain, colorBlack, "colorBlack");
+    GLADE_HOOKUP_OBJECT (winMain, colorBlue, "colorBlue");
+--- 2556,2561 ----
+***************
+*** 2664,2670 ****
+    GLADE_HOOKUP_OBJECT (winMain, highlighterMedium, "highlighterMedium");
+    GLADE_HOOKUP_OBJECT (winMain, highlighterThick, "highlighterThick");
+    GLADE_HOOKUP_OBJECT (winMain, toolsTextFont, "toolsTextFont");
+-   GLADE_HOOKUP_OBJECT (winMain, image634, "image634");
+    GLADE_HOOKUP_OBJECT (winMain, separator10, "separator10");
+    GLADE_HOOKUP_OBJECT (winMain, toolsDefaultPen, "toolsDefaultPen");
+    GLADE_HOOKUP_OBJECT (winMain, toolsDefaultEraser, "toolsDefaultEraser");
+--- 2593,2598 ----
+***************
+*** 2750,2755 ****
+--- 2678,2684 ----
+    GLADE_HOOKUP_OBJECT (winMain, buttonEraser, "buttonEraser");
+    GLADE_HOOKUP_OBJECT (winMain, buttonHighlighter, "buttonHighlighter");
+    GLADE_HOOKUP_OBJECT (winMain, buttonText, "buttonText");
++   GLADE_HOOKUP_OBJECT (winMain, buttonImage, "buttonImage");
+    GLADE_HOOKUP_OBJECT (winMain, buttonReco, "buttonReco");
+    GLADE_HOOKUP_OBJECT (winMain, buttonRuler, "buttonRuler");
+    GLADE_HOOKUP_OBJECT (winMain, toolitem15, "toolitem15");
+***************
+*** 2860,2865 ****
+--- 2789,2795 ----
+    entryWidth = gtk_entry_new ();
+    gtk_widget_show (entryWidth);
+    gtk_box_pack_start (GTK_BOX (hbox3), entryWidth, TRUE, TRUE, 0);
++   gtk_entry_set_invisible_char (GTK_ENTRY (entryWidth), 9679);
+    gtk_entry_set_width_chars (GTK_ENTRY (entryWidth), 5);
+  
+    labelHeight = gtk_label_new (_("Height:"));
+***************
+*** 2869,2874 ****
+--- 2799,2805 ----
+    entryHeight = gtk_entry_new ();
+    gtk_widget_show (entryHeight);
+    gtk_box_pack_start (GTK_BOX (hbox3), entryHeight, TRUE, TRUE, 0);
++   gtk_entry_set_invisible_char (GTK_ENTRY (entryHeight), 9679);
+    gtk_entry_set_width_chars (GTK_ENTRY (entryHeight), 5);
+  
+    comboUnit = gtk_combo_box_new_text ();
+***************
+*** 2951,2962 ****
+    labelTitle = gtk_label_new (_("Xournal"));
+    gtk_widget_show (labelTitle);
+    gtk_box_pack_start (GTK_BOX (dialog_vbox2), labelTitle, FALSE, FALSE, 3);
+-   gtk_label_set_justify (GTK_LABEL (labelTitle), GTK_JUSTIFY_CENTER);
+  
+    labelInfo = gtk_label_new (_("Written by Denis Auroux\nand other contributors\n       http://xournal.sourceforge.net/       "));
+    gtk_widget_show (labelInfo);
+    gtk_box_pack_start (GTK_BOX (dialog_vbox2), labelInfo, FALSE, FALSE, 0);
+-   gtk_label_set_justify (GTK_LABEL (labelInfo), GTK_JUSTIFY_CENTER);
+    gtk_misc_set_padding (GTK_MISC (labelInfo), 20, 10);
+  
+    dialog_action_area2 = GTK_DIALOG (aboutDialog)->action_area;
+--- 2882,2891 ----
+diff -c 'xournal-0.4.5/src/xo-misc.c' 'xournal/src/xo-misc.c'
+Index: ./src/xo-misc.c
+*** ./src/xo-misc.c	Fri Oct  2 20:20:30 2009
+--- ./src/xo-misc.c	Thu Jul 29 16:11:24 2010
+***************
+*** 17,22 ****
+--- 17,23 ----
+  #include "xo-file.h"
+  #include "xo-paint.h"
+  #include "xo-shapes.h"
++ #include "xo-image.h"
+  
+  // some global constants
+  
+***************
+*** 90,95 ****
+--- 91,121 ----
+    return pg;
+  }
+  
++ // change the current page if necessary for pointer at pt
++ void set_current_page(gdouble *pt)
++ {
++   gboolean page_change;
++   struct Page *tmppage;
++ 
++   page_change = FALSE;
++   tmppage = ui.cur_page;
++   while (ui.view_continuous && (pt[1] < - VIEW_CONTINUOUS_SKIP)) {
++     if (ui.pageno == 0) break;
++     page_change = TRUE;
++     ui.pageno--;
++     tmppage = g_list_nth_data(journal.pages, ui.pageno);
++     pt[1] += tmppage->height + VIEW_CONTINUOUS_SKIP;
++   }
++   while (ui.view_continuous && (pt[1] > tmppage->height + VIEW_CONTINUOUS_SKIP)) {
++     if (ui.pageno == journal.npages-1) break;
++     pt[1] -= tmppage->height + VIEW_CONTINUOUS_SKIP;
++     page_change = TRUE;
++     ui.pageno++;
++     tmppage = g_list_nth_data(journal.pages, ui.pageno);
++   }
++   if (page_change) do_switch_page(ui.pageno, FALSE, FALSE);
++ }
++ 
+  void realloc_cur_path(int n)
+  {
+    if (n <= ui.cur_path_storage_alloc) return;
+***************
+*** 142,147 ****
+--- 168,179 ----
+        g_free(redo->item->font_name);
+        g_free(redo->item);
+      }
++     else if (redo->type == ITEM_IMAGE) {
++       g_object_unref(redo->item->image);
++       if (redo->item->image_scaled != NULL) g_object_unref(redo->item->image_scaled);
++       g_free(redo->item->image_png);
++       g_free(redo->item);
++     }
+      else if (redo->type == ITEM_ERASURE || redo->type == ITEM_RECOGNIZER) {
+        for (list = redo->erasurelist; list!=NULL; list=list->next) {
+          erasure = (struct UndoErasureData *)list->data;
+***************
+*** 218,223 ****
+--- 250,260 ----
+          }
+          if (erasure->item->type == ITEM_TEXT)
+            { g_free(erasure->item->text); g_free(erasure->item->font_name); }
++ 	if (erasure->item->type == ITEM_IMAGE) {
++           g_object_unref(erasure->item->image);
++           if (erasure->item->image_scaled != NULL) g_object_unref(erasure->item->image_scaled);
++           g_free(erasure->item->image_png);
++         }
+          g_free(erasure->item);
+          g_list_free(erasure->replacement_items);
+          g_free(erasure);
+***************
+*** 302,307 ****
+--- 339,349 ----
+      if (item->type == ITEM_TEXT) {
+        g_free(item->font_name); g_free(item->text);
+      }
++     if (item->type == ITEM_IMAGE) {
++       g_object_unref(item->image);
++       if (item->image_scaled != NULL) g_object_unref(item->image_scaled);
++       g_free(item->image_png);
++     }
+      // don't need to delete the canvas_item, as it's part of the group destroyed below
+      g_free(item);
+      l->items = g_list_delete_link(l->items, l->items);
+***************
+*** 350,355 ****
+--- 392,409 ----
+    ret[1] -= ui.cur_page->voffset;
+  }
+  
++ // get the current pointer position in canvas world coordinates
++ void get_current_pointer_coords(gdouble *ret)
++ {
++   gint wx, wy, sx, sy;
++ 
++   gtk_widget_get_pointer((GtkWidget *)canvas, &wx, &wy);
++   gnome_canvas_get_scroll_offsets(canvas, &sx, &sy);
++   gnome_canvas_window_to_world(canvas, (double)(wx + sx), (double)(wy + sy), ret, ret+1);
++   ret[0] -= ui.cur_page->hoffset;
++   ret[1] -= ui.cur_page->voffset;
++ }
++ 
+  void fix_xinput_coords(GdkEvent *event)
+  {
+    double *axes, *px, *py, axis_width;
+***************
+*** 440,446 ****
+  {
+    int i;
+    gdouble *p, h, w;
+!   
+    if (item->type == ITEM_STROKE) {
+      item->bbox.left = item->bbox.right = item->path->coords[0];
+      item->bbox.top = item->bbox.bottom = item->path->coords[1];
+--- 494,501 ----
+  {
+    int i;
+    gdouble *p, h, w;
+!   gboolean width_in_pixels, height_in_pixels;
+! 
+    if (item->type == ITEM_STROKE) {
+      item->bbox.left = item->bbox.right = item->path->coords[0];
+      item->bbox.top = item->bbox.bottom = item->path->coords[1];
+***************
+*** 458,463 ****
+--- 513,534 ----
+      item->bbox.right = item->bbox.left + w;
+      item->bbox.bottom = item->bbox.top + h;
+    }
++   if (item->type == ITEM_IMAGE && item->canvas_item!=NULL) {
++     // be careful in case canvas item size in pixels
++     h=0.; w=0.;
++     g_object_get(item->canvas_item, "width", &w, "height", &h, 
++                  "width-in-pixels", &width_in_pixels,
++                  "height-in-pixels", &height_in_pixels,
++                  NULL);
++     if (width_in_pixels) {
++       w /= ui.zoom;
++     }
++     if (height_in_pixels) {
++       h /= ui.zoom;
++     }
++     item->bbox.right = item->bbox.left + w;
++     item->bbox.bottom = item->bbox.top + h;
++   }
+  }
+  
+  void make_page_clipbox(struct Page *pg)
+***************
+*** 474,483 ****
+--- 545,640 ----
+    gnome_canvas_path_def_unref(pg_clip);
+  }
+  
++ void adjust_or_make_canvas_item_image(GnomeCanvasGroup *group, struct Item *item)
++ {
++   double required_width;
++   double required_height;
++ 
++   // discard previous scaled image, if any
++   if ( item->image_scaled != NULL ) {
++     g_object_unref(item->image_scaled);
++     item->image_scaled = NULL;
++   }
++ 
++   if ( is_native_image_usable( item ) ) {
++     // use native resolution, for sharper image
++     if (item->canvas_item == NULL) {
++       // first time, create new canvas item
++       item->canvas_item = gnome_canvas_item_new(group,
++                                                 GNOME_TYPE_CANVAS_PIXBUF,
++                                                 "anchor", GTK_ANCHOR_NW,
++                                                 "height-in-pixels", TRUE, 
++                                                 "width-in-pixels", TRUE,
++                                                 "x-in-pixels", FALSE,
++                                                 "y-in-pixels", FALSE,
++                                                 "pixbuf", item->image,
++                                                 "x", item->bbox.left, 
++                                                 "y", item->bbox.top,
++                                                 "height", (double)gdk_pixbuf_get_height(item->image),
++                                                 "width", (double)gdk_pixbuf_get_width(item->image),
++                                                 NULL);
++     } else {
++       // update the existing one, which may have been for a scaled image
++       gnome_canvas_item_set(item->canvas_item,
++                             "height-in-pixels", TRUE, 
++                             "width-in-pixels", TRUE,
++                             "pixbuf", item->image,
++                             "height", (double)gdk_pixbuf_get_height(item->image),
++                             "width", (double)gdk_pixbuf_get_width(item->image),
++                             NULL);
++     }
++   } else {
++     // settle for scaled (and blurry) image
++     required_width = item->bbox.right - item->bbox.left;
++     required_height = item->bbox.bottom - item->bbox.top;
++ 
++     item->image_scaled = gdk_pixbuf_scale_simple(item->image,
++                                                  required_width,
++                                                  required_height,
++                                                  GDK_INTERP_HYPER);
++     if (item->canvas_item == NULL) {
++       // first time, create new canvas item
++       item->canvas_item = gnome_canvas_item_new(group,
++                                                 GNOME_TYPE_CANVAS_PIXBUF,
++                                                 "anchor", GTK_ANCHOR_NW,
++                                                 "height-in-pixels", FALSE,
++                                                 "width-in-pixels", FALSE,
++                                                 "x-in-pixels", FALSE,
++                                                 "y-in-pixels", FALSE,
++                                                 "pixbuf", item->image_scaled,
++                                                 "x", item->bbox.left, 
++                                                 "y", item->bbox.top,
++                                                 "height", required_height,
++                                                 "width", required_width,  
++                                                 NULL);
++     } else {
++       // update the existing one, which may have been for a scaled image
++       gnome_canvas_item_set(item->canvas_item,
++                             "height-in-pixels", FALSE,
++                             "width-in-pixels", FALSE,
++                             "pixbuf", item->image_scaled,
++                             "height", required_height,
++                             "width", required_width,  
++                             NULL);
++     }
++   }
++ 
++   // reposition the canvas item absolutely, and reset the affine transformation
++   gnome_canvas_item_affine_absolute(item->canvas_item, NULL);
++   gnome_canvas_item_set(item->canvas_item,
++                         "x", item->bbox.left, 
++                         "y", item->bbox.top,
++                         NULL);
++ }
++ 
+  void make_canvas_item_one(GnomeCanvasGroup *group, struct Item *item)
+  {
+    PangoFontDescription *font_desc;
+    GnomeCanvasPoints points;
++   GtkFileFilter *filt_all;
++   GtkFileFilter *filt_gdkimage;
++   GtkWidget *dialog;
++   char *tmp_filename;
+    int j;
+  
+    if (item->type == ITEM_STROKE) {
+***************
+*** 513,518 ****
+--- 670,678 ----
+            "text", item->text, NULL);
+      update_item_bbox(item);
+    }
++   if (item->type == ITEM_IMAGE) {
++     adjust_or_make_canvas_item_image(group, item);
++   }
+  }
+  
+  void make_canvas_items(void)
+***************
+*** 861,866 ****
+--- 1021,1031 ----
+        gtk_toggle_tool_button_set_active(
+          GTK_TOGGLE_TOOL_BUTTON(GET_COMPONENT("buttonText")), TRUE);
+        break;
++     
++     case TOOL_IMAGE:
++       gtk_toggle_tool_button_set_active(
++         GTK_TOGGLE_TOOL_BUTTON(GET_COMPONENT("buttonImage")), TRUE);
++       break;
+      case TOOL_SELECTREGION:
+        gtk_toggle_tool_button_set_active(
+          GTK_TOGGLE_TOOL_BUTTON(GET_COMPONENT("buttonSelectRegion")), TRUE);
+***************
+*** 1377,1383 ****
+    gtk_widget_set_sensitive(GET_COMPONENT("viewHideLayer"), ui.layerno>=0);
+  
+    gtk_widget_set_sensitive(GET_COMPONENT("editPaste"), ui.cur_layer!=NULL);
+!   gtk_widget_set_sensitive(GET_COMPONENT("buttonPaste"), ui.cur_layer!=NULL);
+  }
+  
+  void update_toolbar_and_menu(void)
+--- 1542,1549 ----
+    gtk_widget_set_sensitive(GET_COMPONENT("viewHideLayer"), ui.layerno>=0);
+  
+    gtk_widget_set_sensitive(GET_COMPONENT("editPaste"), ui.cur_layer!=NULL);
+! 
+! gtk_widget_set_sensitive(GET_COMPONENT("buttonPaste"), ui.cur_layer!=NULL);
+  }
+  
+  void update_toolbar_and_menu(void)
+***************
+*** 1716,1722 ****
+      if (item->type == ITEM_STROKE)
+        for (pt=item->path->coords, i=0; i<item->path->num_points; i++, pt+=2)
+          { pt[0] += dx; pt[1] += dy; }
+!     if (item->type == ITEM_STROKE || item->type == ITEM_TEXT || item->type == ITEM_TEMP_TEXT) {
+        item->bbox.left += dx;
+        item->bbox.right += dx;
+        item->bbox.top += dy;
+--- 1882,1888 ----
+      if (item->type == ITEM_STROKE)
+        for (pt=item->path->coords, i=0; i<item->path->num_points; i++, pt+=2)
+          { pt[0] += dx; pt[1] += dy; }
+!     if (item->type == ITEM_STROKE || item->type == ITEM_TEXT || item->type == ITEM_TEMP_TEXT || item->type==ITEM_IMAGE) {
+        item->bbox.left += dx;
+        item->bbox.right += dx;
+        item->bbox.top += dy;
+***************
+*** 1799,1809 ****
+        item->bbox.left = item->bbox.left*scaling_x + offset_x;
+        item->bbox.top = item->bbox.top*scaling_y + offset_y;
+      }
+      // redraw the item
+      if (item->canvas_item!=NULL) {
+        group = (GnomeCanvasGroup *) item->canvas_item->parent;
+!       gtk_object_destroy(GTK_OBJECT(item->canvas_item));
+!       make_canvas_item_one(group, item);
+      }
+    }
+  }
+--- 1965,1995 ----
+        item->bbox.left = item->bbox.left*scaling_x + offset_x;
+        item->bbox.top = item->bbox.top*scaling_y + offset_y;
+      }
++     if (item->type == ITEM_IMAGE) {
++       item->bbox.left = item->bbox.left*scaling_x + offset_x;
++       item->bbox.right = item->bbox.right*scaling_x + offset_x;
++       item->bbox.top = item->bbox.top*scaling_y + offset_y;
++       item->bbox.bottom = item->bbox.bottom*scaling_y + offset_y;
++       if (item->bbox.left > item->bbox.right) {
++         temp = item->bbox.left;
++         item->bbox.left = item->bbox.right;
++         item->bbox.right = temp;
++       }
++       if (item->bbox.top > item->bbox.bottom) {
++         temp = item->bbox.top;
++         item->bbox.top = item->bbox.bottom;
++         item->bbox.bottom = temp;
++       }
++     }
+      // redraw the item
+      if (item->canvas_item!=NULL) {
+        group = (GnomeCanvasGroup *) item->canvas_item->parent;
+!       if (item->type == ITEM_IMAGE) {
+!         adjust_or_make_canvas_item_image(group, item);
+!       } else {
+!         gtk_object_destroy(GTK_OBJECT(item->canvas_item));
+!         make_canvas_item_one(group, item);
+!       }
+      }
+    }
+  }
+diff -c 'xournal-0.4.5/src/xo-misc.h' 'xournal/src/xo-misc.h'
+Index: ./src/xo-misc.h
+*** ./src/xo-misc.h	Mon Sep 28 16:45:56 2009
+--- ./src/xo-misc.h	Sun Jun 27 16:18:01 2010
+***************
+*** 2,7 ****
+--- 2,8 ----
+  
+  struct Page *new_page(struct Page *template);
+  struct Page *new_page_with_bg(struct Background *bg, double width, double height);
++ void set_current_page(gdouble *pt);
+  void realloc_cur_path(int n);
+  void realloc_cur_widths(int n);
+  void clear_redo_stack(void);
+***************
+*** 20,30 ****
+--- 21,33 ----
+  // helper functions
+  
+  void get_pointer_coords(GdkEvent *event, double *ret);
++ void get_current_pointer_coords(double *ret);
+  double get_pressure_multiplier(GdkEvent *event);
+  void fix_xinput_coords(GdkEvent *event);
+  void update_item_bbox(struct Item *item);
+  void make_page_clipbox(struct Page *pg);
+  void make_canvas_items(void);
++ void adjust_or_make_canvas_item_image(GnomeCanvasGroup *group, struct Item *item);
+  void make_canvas_item_one(GnomeCanvasGroup *group, struct Item *item);
+  void update_canvas_bg(struct Page *pg);
+  gboolean is_visible(struct Page *pg);
+diff -c 'xournal-0.4.5/src/xo-paint.c' 'xournal/src/xo-paint.c'
+Index: ./src/xo-paint.c
+*** ./src/xo-paint.c	Mon Sep 28 09:54:18 2009
+--- ./src/xo-paint.c	Thu Jul 29 16:01:42 2010
+***************
+*** 879,1089 ****
+       the forward direction */
+  }
+  
+- void callback_clipboard_get(GtkClipboard *clipboard,
+-                             GtkSelectionData *selection_data,
+-                             guint info, gpointer user_data)
+- {
+-   int length;
+-   
+-   g_memmove(&length, user_data, sizeof(int));
+-   gtk_selection_data_set(selection_data,
+-      gdk_atom_intern("_XOURNAL", FALSE), 8, user_data, length);
+- }
+- 
+- void callback_clipboard_clear(GtkClipboard *clipboard, gpointer user_data)
+- {
+-   g_free(user_data);
+- }
+- 
+- void selection_to_clip(void)
+- {
+-   int bufsz, nitems, val;
+-   char *buf, *p;
+-   GList *list;
+-   struct Item *item;
+-   GtkTargetEntry target;
+-   
+-   if (ui.selection == NULL) return;
+-   bufsz = 2*sizeof(int) // bufsz, nitems
+-         + sizeof(struct BBox); // bbox
+-   nitems = 0;
+-   for (list = ui.selection->items; list != NULL; list = list->next) {
+-     item = (struct Item *)list->data;
+-     nitems++;
+-     if (item->type == ITEM_STROKE) {
+-       bufsz+= sizeof(int) // type
+-             + sizeof(struct Brush) // brush
+-             + sizeof(int) // num_points
+-             + 2*item->path->num_points*sizeof(double); // the points
+-       if (item->brush.variable_width)
+-         bufsz += (item->path->num_points-1)*sizeof(double); // the widths
+-     }
+-     else if (item->type == ITEM_TEXT) {
+-       bufsz+= sizeof(int) // type
+-             + sizeof(struct Brush) // brush
+-             + 2*sizeof(double) // bbox upper-left
+-             + sizeof(int) // text len
+-             + strlen(item->text)+1 // text
+-             + sizeof(int) // font_name len
+-             + strlen(item->font_name)+1 // font_name
+-             + sizeof(double); // font_size
+-     }
+-     else bufsz+= sizeof(int); // type
+-   }
+-   p = buf = g_malloc(bufsz);
+-   g_memmove(p, &bufsz, sizeof(int)); p+= sizeof(int);
+-   g_memmove(p, &nitems, sizeof(int)); p+= sizeof(int);
+-   g_memmove(p, &ui.selection->bbox, sizeof(struct BBox)); p+= sizeof(struct BBox);
+-   for (list = ui.selection->items; list != NULL; list = list->next) {
+-     item = (struct Item *)list->data;
+-     g_memmove(p, &item->type, sizeof(int)); p+= sizeof(int);
+-     if (item->type == ITEM_STROKE) {
+-       g_memmove(p, &item->brush, sizeof(struct Brush)); p+= sizeof(struct Brush);
+-       g_memmove(p, &item->path->num_points, sizeof(int)); p+= sizeof(int);
+-       g_memmove(p, item->path->coords, 2*item->path->num_points*sizeof(double));
+-       p+= 2*item->path->num_points*sizeof(double);
+-       if (item->brush.variable_width) {
+-         g_memmove(p, item->widths, (item->path->num_points-1)*sizeof(double));
+-         p+= (item->path->num_points-1)*sizeof(double);
+-       }
+-     }
+-     if (item->type == ITEM_TEXT) {
+-       g_memmove(p, &item->brush, sizeof(struct Brush)); p+= sizeof(struct Brush);
+-       g_memmove(p, &item->bbox.left, sizeof(double)); p+= sizeof(double);
+-       g_memmove(p, &item->bbox.top, sizeof(double)); p+= sizeof(double);
+-       val = strlen(item->text);
+-       g_memmove(p, &val, sizeof(int)); p+= sizeof(int);
+-       g_memmove(p, item->text, val+1); p+= val+1;
+-       val = strlen(item->font_name);
+-       g_memmove(p, &val, sizeof(int)); p+= sizeof(int);
+-       g_memmove(p, item->font_name, val+1); p+= val+1;
+-       g_memmove(p, &item->font_size, sizeof(double)); p+= sizeof(double);
+-     }
+-   }
+-   
+-   target.target = "_XOURNAL";
+-   target.flags = 0;
+-   target.info = 0;
+-   
+-   gtk_clipboard_set_with_data(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD), 
+-        &target, 1,
+-        callback_clipboard_get, callback_clipboard_clear, buf);
+- }
+- 
+- 
+- void clipboard_paste(void)
+- {
+-   GtkSelectionData *sel_data;
+-   unsigned char *p;
+-   int nitems, npts, i, len;
+-   struct Item *item;
+-   double hoffset, voffset, cx, cy;
+-   double *pf;
+-   int sx, sy, wx, wy;
+-   
+-   if (ui.cur_layer == NULL) return;
+-   
+-   ui.cur_item_type = ITEM_PASTE;
+-   sel_data = gtk_clipboard_wait_for_contents(
+-       gtk_clipboard_get(GDK_SELECTION_CLIPBOARD),
+-       gdk_atom_intern("_XOURNAL", FALSE));
+-   ui.cur_item_type = ITEM_NONE;
+-   if (sel_data == NULL) return; // paste failed
+-   
+-   reset_selection();
+-   
+-   ui.selection = g_new(struct Selection, 1);
+-   p = sel_data->data + sizeof(int);
+-   g_memmove(&nitems, p, sizeof(int)); p+= sizeof(int);
+-   ui.selection->type = ITEM_SELECTRECT;
+-   ui.selection->layer = ui.cur_layer;
+-   g_memmove(&ui.selection->bbox, p, sizeof(struct BBox)); p+= sizeof(struct BBox);
+-   ui.selection->items = NULL;
+-   
+-   // find by how much we translate the pasted selection
+-   gnome_canvas_get_scroll_offsets(canvas, &sx, &sy);
+-   gdk_window_get_geometry(GTK_WIDGET(canvas)->window, NULL, NULL, &wx, &wy, NULL);
+-   gnome_canvas_window_to_world(canvas, sx + wx/2, sy + wy/2, &cx, &cy);
+-   cx -= ui.cur_page->hoffset;
+-   cy -= ui.cur_page->voffset;
+-   if (cx + (ui.selection->bbox.right-ui.selection->bbox.left)/2 > ui.cur_page->width)
+-     cx = ui.cur_page->width - (ui.selection->bbox.right-ui.selection->bbox.left)/2;
+-   if (cx - (ui.selection->bbox.right-ui.selection->bbox.left)/2 < 0)
+-     cx = (ui.selection->bbox.right-ui.selection->bbox.left)/2;
+-   if (cy + (ui.selection->bbox.bottom-ui.selection->bbox.top)/2 > ui.cur_page->height)
+-     cy = ui.cur_page->height - (ui.selection->bbox.bottom-ui.selection->bbox.top)/2;
+-   if (cy - (ui.selection->bbox.bottom-ui.selection->bbox.top)/2 < 0)
+-     cy = (ui.selection->bbox.bottom-ui.selection->bbox.top)/2;
+-   hoffset = cx - (ui.selection->bbox.right+ui.selection->bbox.left)/2;
+-   voffset = cy - (ui.selection->bbox.top+ui.selection->bbox.bottom)/2;
+-   ui.selection->bbox.left += hoffset;
+-   ui.selection->bbox.right += hoffset;
+-   ui.selection->bbox.top += voffset;
+-   ui.selection->bbox.bottom += voffset;
+- 
+-   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);
+- 
+-   while (nitems-- > 0) {
+-     item = g_new(struct Item, 1);
+-     ui.selection->items = g_list_append(ui.selection->items, item);
+-     ui.cur_layer->items = g_list_append(ui.cur_layer->items, item);
+-     ui.cur_layer->nitems++;
+-     g_memmove(&item->type, p, sizeof(int)); p+= sizeof(int);
+-     if (item->type == ITEM_STROKE) {
+-       g_memmove(&item->brush, p, sizeof(struct Brush)); p+= sizeof(struct Brush);
+-       g_memmove(&npts, p, sizeof(int)); p+= sizeof(int);
+-       item->path = gnome_canvas_points_new(npts);
+-       pf = (double *)p;
+-       for (i=0; i<npts; i++) {
+-         item->path->coords[2*i] = pf[2*i] + hoffset;
+-         item->path->coords[2*i+1] = pf[2*i+1] + voffset;
+-       }
+-       p+= 2*item->path->num_points*sizeof(double);
+-       if (item->brush.variable_width) {
+-         item->widths = g_memdup(p, (item->path->num_points-1)*sizeof(double));
+-         p+= (item->path->num_points-1)*sizeof(double);
+-       }
+-       else item->widths = NULL;
+-       update_item_bbox(item);
+-       make_canvas_item_one(ui.cur_layer->group, item);
+-     }
+-     if (item->type == ITEM_TEXT) {
+-       g_memmove(&item->brush, p, sizeof(struct Brush)); p+= sizeof(struct Brush);
+-       g_memmove(&item->bbox.left, p, sizeof(double)); p+= sizeof(double);
+-       g_memmove(&item->bbox.top, p, sizeof(double)); p+= sizeof(double);
+-       item->bbox.left += hoffset;
+-       item->bbox.top += voffset;
+-       g_memmove(&len, p, sizeof(int)); p+= sizeof(int);
+-       item->text = g_malloc(len+1);
+-       g_memmove(item->text, p, len+1); p+= len+1;
+-       g_memmove(&len, p, sizeof(int)); p+= sizeof(int);
+-       item->font_name = g_malloc(len+1);
+-       g_memmove(item->font_name, p, len+1); p+= len+1;
+-       g_memmove(&item->font_size, p, sizeof(double)); p+= sizeof(double);
+-       make_canvas_item_one(ui.cur_layer->group, item);
+-     }
+-   }
+- 
+-   prepare_new_undo();
+-   undo->type = ITEM_PASTE;
+-   undo->layer = ui.cur_layer;
+-   undo->itemlist = g_list_copy(ui.selection->items);  
+-   
+-   gtk_selection_data_free(sel_data);
+-   update_copy_paste_enabled();
+-   update_color_menu();
+-   update_thickness_buttons();
+-   update_color_buttons();
+-   update_font_button();  
+-   update_cursor(); // FIXME: can't know if pointer is within selection!
+- }
+- 
+  // modify the color or thickness of pen strokes in a selection
+  
+  void recolor_selection(int color_no, guint color_rgba)
+--- 879,884 ----
+diff -c 'xournal-0.4.5/src/xo-paint.h' 'xournal/src/xo-paint.h'
+Index: ./src/xo-paint.h
+*** ./src/xo-paint.h	Thu Sep 17 16:49:04 2009
+--- ./src/xo-paint.h	Thu Apr 15 16:25:13 2010
+***************
+*** 22,29 ****
+  void finalize_resizesel(void);
+  
+  void selection_delete(void);
+- void selection_to_clip(void);
+- void clipboard_paste(void);
+  
+  void recolor_selection(int color_no, guint color_rgba);
+  void rethicken_selection(int val);
+--- 22,27 ----
+diff -c 'xournal-0.4.5/src/xo-print.c' 'xournal/src/xo-print.c'
+Index: ./src/xo-print.c
+*** ./src/xo-print.c	Tue Sep 29 10:36:54 2009
+--- ./src/xo-print.c	Thu Jul 29 16:31:20 2010
+***************
+*** 772,777 ****
+--- 772,851 ----
+    return xref->last;
+  }
+  
++ gboolean pdf_draw_image(PdfImage *image, struct XrefTable *xref, GString *pdfbuf)
++ {
++   char *buf, *p1, *p2;
++   int height, width, stride, x, y, chan;
++   GString *zpix;
++ 
++   if (gdk_pixbuf_get_bits_per_sample(image->pixbuf) != 8 ||
++       gdk_pixbuf_get_colorspace(image->pixbuf) != GDK_COLORSPACE_RGB) {
++     return FALSE;
++   }
++ 
++   width = gdk_pixbuf_get_width(image->pixbuf);
++   height = gdk_pixbuf_get_height(image->pixbuf);
++   stride = gdk_pixbuf_get_rowstride(image->pixbuf);
++   chan = gdk_pixbuf_get_n_channels(image->pixbuf);
++   if (!((chan==3 && !image->has_alpha) || (chan==4 && image->has_alpha))) {
++     return FALSE;
++   }
++ 
++   p2 = buf = (char *)g_malloc(3*width*height);
++   for (y=0; y<height; y++) {
++     p1 = (char *)gdk_pixbuf_get_pixels(image->pixbuf)+stride*y;
++     for (x=0; x<width; x++) {
++       *(p2++)=*(p1++); *(p2++)=*(p1++); *(p2++)=*(p1++);
++       if (chan==4) p1++;
++     }
++   }
++   zpix = do_deflate(buf, 3*width*height);
++   g_free(buf);
++ 
++   xref->data[image->n_obj] = pdfbuf->len;
++   g_string_append_printf(pdfbuf, 
++     "%d 0 obj\n<< /Length %d /Filter /FlateDecode /Type /Xobject "
++     "/Subtype /Image /Width %d /Height %d /ColorSpace /DeviceRGB "
++     "/BitsPerComponent 8 ",
++     image->n_obj, zpix->len, width, height);
++   if (image->has_alpha) {
++     g_string_append_printf(pdfbuf, 
++       "/SMask %d 0 R ",
++       image->n_obj_smask);
++   }
++   g_string_append_printf(pdfbuf, " >> stream\n");
++ 
++   g_string_append_len(pdfbuf, zpix->str, zpix->len);
++   g_string_free(zpix, TRUE);
++   g_string_append(pdfbuf, "endstream\nendobj\n");
++ 
++   if (image->has_alpha) {
++     p2 = buf = (char *)g_malloc(width*height);
++     for (y=0; y<height; y++) {
++       p1 = (char *)gdk_pixbuf_get_pixels(image->pixbuf)+stride*y;
++       for (x=0; x<width; x++) {
++         p1+=3;                  /* skip the RGB */
++         *(p2++)=*(p1++);        /* just copy the alpha */
++       }
++     }
++     zpix = do_deflate(buf, width*height);
++     g_free(buf);
++     
++     xref->data[image->n_obj_smask] = pdfbuf->len;
++     g_string_append_printf(pdfbuf, 
++       "%d 0 obj\n<< /Length %d /Filter /FlateDecode /Type /Xobject "
++       "/Subtype /Image /Width %d /Height %d /ColorSpace /DeviceGray "
++       "/BitsPerComponent 8 >> stream\n",
++       image->n_obj_smask, zpix->len, width, height);
++ 
++     g_string_append_len(pdfbuf, zpix->str, zpix->len);
++     g_string_free(zpix, TRUE);
++     g_string_append(pdfbuf, "endstream\nendobj\n");
++   }
++ 
++   return TRUE;
++ }
++ 
+  // manipulate Pdf fonts
+  
+  struct PdfFont *new_pdffont(struct XrefTable *xref, GList **fonts,
+***************
+*** 1006,1015 ****
+    g_string_append(pdfbuf, ">> endobj\n");
+  }
+  
+  // draw a page's graphics
+  
+  void pdf_draw_page(struct Page *pg, GString *str, gboolean *use_hiliter, 
+!                   struct XrefTable *xref, GList **pdffonts)
+  {
+    GList *layerlist, *itemlist, *tmplist;
+    struct Layer *l;
+--- 1080,1110 ----
+    g_string_append(pdfbuf, ">> endobj\n");
+  }
+  
++ // Pdf images
++ 
++ struct PdfImage *new_pdfimage(struct XrefTable *xref, GList **images, GdkPixbuf *pixbuf)
++ {
++   GList *list;
++   struct PdfImage *image;
++   
++   image = g_malloc(sizeof(struct PdfImage));
++   *images = g_list_append(*images, image);
++   image->n_obj = xref->last+1;
++   make_xref(xref, xref->last+1, 0); // will give it a value later
++   image->has_alpha = gdk_pixbuf_get_has_alpha(pixbuf);
++   if (image->has_alpha) {
++     image->n_obj_smask = xref->last+1;
++     make_xref(xref, xref->last+1, 0); // will give it a value later
++   }
++   image->pixbuf = pixbuf;
++ 
++   return image;
++ }
++ 
+  // draw a page's graphics
+  
+  void pdf_draw_page(struct Page *pg, GString *str, gboolean *use_hiliter, 
+!                    struct XrefTable *xref, GList **pdffonts, GList **pdfimages)
+  {
+    GList *layerlist, *itemlist, *tmplist;
+    struct Layer *l;
+***************
+*** 1034,1039 ****
+--- 1129,1135 ----
+    int font_id;
+    FT_Face ftface;
+    struct PdfFont *cur_font;
++   struct PdfImage *cur_image;
+    gboolean in_string;
+    
+    old_rgba = old_text_rgba = 0x12345678;    // not any values we use, so we'll reset them
+***************
+*** 1161,1166 ****
+--- 1257,1272 ----
+          pango_layout_iter_free(iter);
+          g_object_unref(layout);
+        }
++       else if  (item->type == ITEM_IMAGE) {
++         cur_image = new_pdfimage(xref, pdfimages, item->image);
++         g_string_append_printf(str, "\nq 1 0 0 1 %.2f %.2f cm %.2f 0 0 %.2f 0 %.2f cm /Im%d Do Q ",
++                                item->bbox.left, // translation
++                                item->bbox.top,
++                                item->bbox.right - item->bbox.left, // scaling
++                                item->bbox.top - item->bbox.bottom,
++                                item->bbox.bottom - item->bbox.top,
++                                cur_image->n_obj);
++       }
+      }
+    }
+  }
+***************
+*** 1187,1194 ****
+    gboolean use_hiliter;
+    struct PdfInfo pdfinfo;
+    struct PdfObj *obj;
+!   GList *pdffonts, *list;
+    struct PdfFont *font;
+    char *tmpbuf;
+    
+    f = fopen(filename, "w");
+--- 1293,1301 ----
+    gboolean use_hiliter;
+    struct PdfInfo pdfinfo;
+    struct PdfObj *obj;
+!   GList *pdffonts, *pdfimages, *list;
+    struct PdfFont *font;
++   struct PdfImage *image;
+    char *tmpbuf;
+    
+    f = fopen(filename, "w");
+***************
+*** 1198,1203 ****
+--- 1305,1311 ----
+    xref.data = NULL;
+    uses_pdf = FALSE;
+    pdffonts = NULL;
++   pdfimages = NULL;
+    for (pglist = journal.pages; pglist!=NULL; pglist = pglist->next) {
+      pg = (struct Page *)pglist->data;
+      if (pg->bg->type == BG_PDF) uses_pdf = TRUE;
+***************
+*** 1267,1273 ****
+        n_obj_bgpix = pdf_draw_bitmap_background(pg, pgstrm, &xref, pdfbuf);
+      // draw the page contents
+      use_hiliter = FALSE;
+!     pdf_draw_page(pg, pgstrm, &use_hiliter, &xref, &pdffonts);
+      g_string_append_printf(pgstrm, "Q\n");
+      
+      // deflate pgstrm and write it
+--- 1375,1381 ----
+        n_obj_bgpix = pdf_draw_bitmap_background(pg, pgstrm, &xref, pdfbuf);
+      // draw the page contents
+      use_hiliter = FALSE;
+!     pdf_draw_page(pg, pgstrm, &use_hiliter, &xref, &pdffonts, &pdfimages);
+      g_string_append_printf(pgstrm, "Q\n");
+      
+      // deflate pgstrm and write it
+***************
+*** 1323,1329 ****
+      }
+      add_dict_subentry(pdfbuf, &xref,
+          obj, "/ProcSet", PDFTYPE_ARRAY, NULL, mk_pdfname("/PDF"));
+!     if (n_obj_bgpix>0)
+        add_dict_subentry(pdfbuf, &xref,
+          obj, "/ProcSet", PDFTYPE_ARRAY, NULL, mk_pdfname("/ImageC"));
+      if (use_hiliter)
+--- 1431,1437 ----
+      }
+      add_dict_subentry(pdfbuf, &xref,
+          obj, "/ProcSet", PDFTYPE_ARRAY, NULL, mk_pdfname("/PDF"));
+!     if (n_obj_bgpix>0 || pdfimages!=NULL)
+        add_dict_subentry(pdfbuf, &xref,
+          obj, "/ProcSet", PDFTYPE_ARRAY, NULL, mk_pdfname("/ImageC"));
+      if (use_hiliter)
+***************
+*** 1343,1353 ****
+          g_free(tmpbuf);
+        }
+      }
+      show_pdfobj(obj, pdfbuf);
+      free_pdfobj(obj);
+      g_string_append(pdfbuf, " >> endobj\n");
+    }
+!   
+    // after the pages, we insert fonts
+    for (list = pdffonts; list!=NULL; list = list->next) {
+      font = (struct PdfFont *)list->data;
+--- 1451,1468 ----
+          g_free(tmpbuf);
+        }
+      }
++     for (list=pdfimages; list!=NULL; list = list->next) {
++       image = (struct PdfImage *)list->data;
++       tmpbuf = g_strdup_printf("/Im%d", image->n_obj);
++       add_dict_subentry(pdfbuf, &xref,
++         obj, "/XObject", PDFTYPE_DICT, tmpbuf, mk_pdfref(image->n_obj));
++       g_free(tmpbuf);
++     }
+      show_pdfobj(obj, pdfbuf);
+      free_pdfobj(obj);
+      g_string_append(pdfbuf, " >> endobj\n");
+    }
+! 
+    // after the pages, we insert fonts
+    for (list = pdffonts; list!=NULL; list = list->next) {
+      font = (struct PdfFont *)list->data;
+***************
+*** 1357,1362 ****
+--- 1472,1489 ----
+      g_free(font);
+    }
+    g_list_free(pdffonts);
++ 
++   // after the fonts, we insert images
++   if (pdfimages!=NULL) {
++     for (list = pdfimages; list!=NULL; list = list->next) {
++       image = (struct PdfImage *)list->data;
++       if (!pdf_draw_image(image, &xref, pdfbuf)) {
++         return FALSE;
++       }
++       g_free(image);
++     }
++     g_list_free(pdfimages);
++   }
+    
+    // PDF trailer
+    startxref = pdfbuf->len;
+***************
+*** 1476,1481 ****
+--- 1603,1609 ----
+  void print_job_render_page(GtkPrintOperation *print, GtkPrintContext *context, gint pageno, gpointer user_data)
+  {
+    cairo_t *cr;
++   cairo_t *tempcr;
+    gdouble width, height, scale;
+    struct Page *pg;
+    guint old_rgba;
+***************
+*** 1487,1492 ****
+--- 1615,1621 ----
+    double *pt;
+    PangoFontDescription *font_desc;
+    PangoLayout *layout;
++   cairo_surface_t *surf;
+          
+    pg = (struct Page *)g_list_nth_data(journal.pages, pageno);
+    cr = gtk_print_context_get_cairo_context(context);
+***************
+*** 1509,1515 ****
+      l = (struct Layer *)layerlist->data;
+      for (itemlist = l->items; itemlist!=NULL; itemlist = itemlist->next) {
+        item = (struct Item *)itemlist->data;
+!       if (item->type == ITEM_STROKE || item->type == ITEM_TEXT) {
+          if (item->brush.color_rgba != old_rgba)
+            cairo_set_source_rgba(cr, RGBA_RGB(item->brush.color_rgba),
+                                      RGBA_ALPHA(item->brush.color_rgba));
+--- 1638,1644 ----
+      l = (struct Layer *)layerlist->data;
+      for (itemlist = l->items; itemlist!=NULL; itemlist = itemlist->next) {
+        item = (struct Item *)itemlist->data;
+!       if (item->type == ITEM_STROKE || item->type == ITEM_TEXT || item->type==ITEM_IMAGE) {
+          if (item->brush.color_rgba != old_rgba)
+            cairo_set_source_rgba(cr, RGBA_RGB(item->brush.color_rgba),
+                                      RGBA_ALPHA(item->brush.color_rgba));
+***************
+*** 1548,1553 ****
+--- 1677,1694 ----
+          pango_cairo_show_layout(cr, layout);
+          g_object_unref(layout);
+        }
++       if (item->type == ITEM_IMAGE) {
++         double required_width = item->bbox.right - item->bbox.left;
++         double required_height = item->bbox.bottom - item->bbox.top;
++ 	double scalex = required_width / gdk_pixbuf_get_width(item->image);
++ 	double scaley = required_height / gdk_pixbuf_get_height(item->image);
++ 	cairo_scale(cr,scalex,scaley);
++ 	gdk_cairo_set_source_pixbuf(cr,item->image,item->bbox.left/scalex,item->bbox.top/scaley);
++ 	cairo_scale(cr,1/scalex,1/scaley);
++ 	cairo_paint (cr);
++ 	old_rgba = predef_colors_rgba[COLOR_BLACK]; //this is an ugly fix, I (victor) don't understand cairo enough
++ 	cairo_set_source_rgb(cr, 0, 0, 0);
++       }
+      }
+    }
+  }
+diff -c 'xournal-0.4.5/src/xo-print.h' 'xournal/src/xo-print.h'
+Index: ./src/xo-print.h
+*** ./src/xo-print.h	Tue Sep 15 09:26:26 2009
+--- ./src/xo-print.h	Fri May 28 20:43:50 2010
+***************
+*** 45,50 ****
+--- 45,57 ----
+    int flags;
+  } PdfFont;
+  
++ typedef struct PdfImage {
++   int n_obj;
++   gboolean has_alpha;
++   int n_obj_smask;              /* only if has_alpha */
++   GdkPixbuf *pixbuf;
++ } PdfImage;
++ 
+  #define PDFTYPE_CST 0    // intval: true=1, false=0, null=-1
+  #define PDFTYPE_INT 1    // intval
+  #define PDFTYPE_REAL 2   // realval
+diff -c 'xournal-0.4.5/src/xournal.h' 'xournal/src/xournal.h'
+Index: ./src/xournal.h
+*** ./src/xournal.h	Sat Oct  3 12:42:28 2009
+--- ./src/xournal.h	Thu Jul 29 17:02:19 2010
+***************
+*** 17,22 ****
+--- 17,24 ----
+     "tiny file dialog" syndrome, without hurting those with well-behaved
+     versions of GTK+. Comment out if you'd prefer not to include this fix. */
+  
++ //#define IMAGE_DEBUG  //this is for debugging of the "insert image" patch
++ 
+  // PREF FILES INFO
+  
+  #define CONFIG_DIR ".xournal"
+***************
+*** 120,125 ****
+--- 122,128 ----
+  #define TOOL_SELECTRECT   5
+  #define TOOL_VERTSPACE    6
+  #define TOOL_HAND         7
++ #define TOOL_IMAGE	8
+  #define NUM_STROKE_TOOLS  3
+  #define NUM_TOOLS         8
+  #define NUM_BUTTONS       3
+***************
+*** 150,155 ****
+--- 153,163 ----
+    gchar *font_name;
+    gdouble font_size;
+    GtkWidget *widget; // the widget while text is being edited (ITEM_TEMP_TEXT)
++   // the following fields for ITEM_IMAGE:
++   GdkPixbuf* image;  // original image for print and resizing quality
++   GdkPixbuf* image_scaled; // scaled pixbuf for display
++   gchar *image_png;  // PNG of original image, for save and clipboard
++   gsize image_png_len;
+  } Item;
+  
+  // item type values for Item.type, UndoItem.type, ui.cur_item_type ...
+***************
+*** 178,183 ****
+--- 186,192 ----
+  #define ITEM_TEXT_ATTRIB 21
+  #define ITEM_RESIZESEL 22
+  #define ITEM_RECOGNIZER 23
++ #define ITEM_IMAGE 24
+  
+  typedef struct Layer {
+    GList *items; // the items on the layer, from bottom to top
+***************
+*** 251,256 ****
+--- 260,266 ----
+    gboolean hand_scrollto_pending;
+    char *filename;
+    gchar *default_path; // default path for new notes
++   gchar *default_image; // path for previous image
+    gboolean view_continuous, fullscreen, maximize_at_start;
+    gboolean in_update_page_stuff; // semaphore to avoid scrollbar retroaction
+    struct Selection *selection;
+***************
+*** 300,307 ****
+  
+  typedef struct UndoItem {
+    int type;
+!   struct Item *item; // for ITEM_STROKE, ITEM_TEXT, ITEM_TEXT_EDIT, ITEM_TEXT_ATTRIB
+!   struct Layer *layer; // for ITEM_STROKE, ITEM_ERASURE, ITEM_PASTE, ITEM_NEW_LAYER, ITEM_DELETE_LAYER, ITEM_MOVESEL, ITEM_TEXT, ITEM_TEXT_EDIT, ITEM_RECOGNIZER
+    struct Layer *layer2; // for ITEM_DELETE_LAYER with val=-1, ITEM_MOVESEL
+    struct Page *page;  // for ITEM_NEW_BG_ONE/RESIZE, ITEM_NEW_PAGE, ITEM_NEW_LAYER, ITEM_DELETE_LAYER, ITEM_DELETE_PAGE
+    GList *erasurelist; // for ITEM_ERASURE, ITEM_RECOGNIZER
+--- 310,317 ----
+  
+  typedef struct UndoItem {
+    int type;
+!   struct Item *item; // for ITEM_STROKE, ITEM_TEXT, ITEM_TEXT_EDIT, ITEM_TEXT_ATTRIB, ITEM_IMAGE
+!   struct Layer *layer; // for ITEM_STROKE, ITEM_ERASURE, ITEM_PASTE, ITEM_NEW_LAYER, ITEM_DELETE_LAYER, ITEM_MOVESEL, ITEM_TEXT, ITEM_TEXT_EDIT, ITEM_RECOGNIZER, ITEM_IMAGE
+    struct Layer *layer2; // for ITEM_DELETE_LAYER with val=-1, ITEM_MOVESEL
+    struct Page *page;  // for ITEM_NEW_BG_ONE/RESIZE, ITEM_NEW_PAGE, ITEM_NEW_LAYER, ITEM_DELETE_LAYER, ITEM_DELETE_PAGE
+    GList *erasurelist; // for ITEM_ERASURE, ITEM_RECOGNIZER
+#### End of Patch data ####
+
+#### ApplyPatch data follows ####
+# Data version        : 1.0
+# Date generated      : Thu Jul 29 20:05:54 2010
+# Generated by        : makepatch 2.03
+# Recurse directories : Yes
+# Excluded files      : (\A|/).*\~\Z
+#                       (\A|/).*\.a\Z
+#                       (\A|/).*\.bak\Z
+#                       (\A|/).*\.BAK\Z
+#                       (\A|/).*\.elc\Z
+#                       (\A|/).*\.exe\Z
+#                       (\A|/).*\.gz\Z
+#                       (\A|/).*\.ln\Z
+#                       (\A|/).*\.o\Z
+#                       (\A|/).*\.obj\Z
+#                       (\A|/).*\.olb\Z
+#                       (\A|/).*\.old\Z
+#                       (\A|/).*\.orig\Z
+#                       (\A|/).*\.rej\Z
+#                       (\A|/).*\.so\Z
+#                       (\A|/).*\.Z\Z
+#                       (\A|/)\.del\-.*\Z
+#                       (\A|/)\.make\.state\Z
+#                       (\A|/)\.nse_depinfo\Z
+#                       (\A|/)core\Z
+#                       (\A|/)tags\Z
+#                       (\A|/)TAGS\Z
+# c './README.image' 0 1271308604 0100644
+# p './src/Makefile.am' 560 1271308944 0100644
+# p './src/Makefile.in' 21256 1271309237 0100644
+# p './src/TODO' 12113 1273816779 0100644
+# p './src/main.c' 11751 1277612564 0100644
+# p './src/xo-callbacks.c' 115621 1277368329 0100644
+# p './src/xo-callbacks.h' 22740 1269211165 0100644
+# c './src/xo-clipboard.c' 0 1280390203 0100644
+# c './src/xo-clipboard.h' 0 1269482993 0100644
+# p './src/xo-file.c' 72283 1280379587 0100644
+# c './src/xo-image.c' 0 1280379292 0100644
+# c './src/xo-image.h' 0 1277368922 0100644
+# p './src/xo-interface.c' 154893 1269211165 0100644
+# p './src/xo-misc.c' 75933 1280376684 0100644
+# p './src/xo-misc.h' 4155 1277612281 0100644
+# p './src/xo-paint.c' 51578 1280376102 0100644
+# p './src/xo-paint.h' 1292 1271305513 0100644
+# p './src/xo-print.c' 51697 1280377880 0100644
+# p './src/xo-print.h' 1872 1275036230 0100644
+# p './src/xournal.h' 12910 1280379739 0100644
+#### End of ApplyPatch data ####
+
+#### End of Patch kit [created: Thu Jul 29 20:05:54 2010] ####
+#### Patch checksum: 3071 115300 31326 ####
+#### Checksum: 3109 116607 9177 ####
diff --git a/xournal.spec b/xournal.spec
index 5ac6b4e..635f9b8 100644
--- a/xournal.spec
+++ b/xournal.spec
@@ -1,6 +1,6 @@
 Name:		xournal
 Version:	0.4.5
-Release:	18%{?dist}
+Release:	19%{?dist}
 Summary:	Notetaking, sketching, PDF annotation and general journal
 
 Group:		Applications/Editors
@@ -10,6 +10,8 @@ Source0:	http://downloads.sourceforge.net/xournal/%{name}-%{version}.tar.gz
 Patch0:		xournal-configure.in.patch
 Patch1:		xournal-0.4.5-xoprint-len.patch
 Patch2:		xournal-poppler-api.patch
+Patch3:		xournal-0.4.5-sjg-image-rev7.patch
+
 BuildRoot:	%{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 
 BuildRequires:	gtk2-devel >= 2.10.0 
@@ -41,6 +43,7 @@ resolution) and overall functionality.
 %patch0 -p1
 %patch1 -p1
 %patch2 -p0
+%patch3 -p0
 
 %build
 NOCONFIGURE=1 ./autogen.sh
@@ -112,6 +115,9 @@ update-desktop-database %{_datadir}/applications > /dev/null 2>&1 || :
 
 
 %changelog
+* Mon Jul 09 2012 Jaromir Capik <jcapik at redhat.com> - 0.4.5-19
+- #827922 - image insertion patch
+
 * Wed May 16 2012 Marek Kasik <mkasik at redhat.com> - 0.4.5-18
 - Rebuild (poppler-0.20.0)
 


More information about the scm-commits mailing list