]> git.donarmstrong.com Git - xournal.git/commitdiff
Initial revision
authorauroux <auroux>
Sat, 28 Jan 2006 22:07:28 +0000 (22:07 +0000)
committerauroux <auroux>
Sat, 28 Jan 2006 22:07:28 +0000 (22:07 +0000)
src/xo-print.c [new file with mode: 0644]

diff --git a/src/xo-print.c b/src/xo-print.c
new file mode 100644 (file)
index 0000000..933868e
--- /dev/null
@@ -0,0 +1,190 @@
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <gtk/gtk.h>
+#include <libgnomecanvas/libgnomecanvas.h>
+#include <libgnomeprint/gnome-print-job.h>
+
+#include "xournal.h"
+#include "xo-misc.h"
+#include "xo-paint.h"
+#include "xo-print.h"
+#include "xo-file.h"
+
+#define RGBA_RED(rgba) (((rgba>>24)&0xff)/255.0)
+#define RGBA_GREEN(rgba) (((rgba>>16)&0xff)/255.0)
+#define RGBA_BLUE(rgba) (((rgba>>8)&0xff)/255.0)
+#define RGBA_ALPHA(rgba) (((rgba>>0)&0xff)/255.0)
+#define RGBA_RGB(rgba) RGBA_RED(rgba), RGBA_GREEN(rgba), RGBA_BLUE(rgba)
+
+// does the same job as update_canvas_bg(), but to a print context
+
+void print_background(GnomePrintContext *gpc, struct Page *pg, gboolean *abort)
+{
+  double x, y;
+  GdkPixbuf *pix;
+  BgPdfPage *pgpdf;
+
+  if (pg->bg->type == BG_SOLID) {
+    gnome_print_setopacity(gpc, 1.0);
+    gnome_print_setrgbcolor(gpc, RGBA_RGB(pg->bg->color_rgba));
+    gnome_print_rect_filled(gpc, 0, 0, pg->width, pg->height);
+
+    if (pg->bg->ruling == RULING_NONE) return;
+    gnome_print_setrgbcolor(gpc, RGBA_RGB(RULING_COLOR));
+    gnome_print_setlinewidth(gpc, RULING_THICKNESS);
+    
+    if (pg->bg->ruling == RULING_GRAPH) {
+      for (x=RULING_GRAPHSPACING; x<pg->width-1; x+=RULING_GRAPHSPACING)
+        gnome_print_line_stroked(gpc, x, 0, x, pg->height);
+      for (y=RULING_GRAPHSPACING; y<pg->height-1; y+=RULING_GRAPHSPACING)
+        gnome_print_line_stroked(gpc, 0, y, pg->width, y);
+      return;
+    }
+    
+    for (y=RULING_TOPMARGIN; y<pg->height-1; y+=RULING_SPACING)
+      gnome_print_line_stroked(gpc, 0, y, pg->width, y);
+    if (pg->bg->ruling == RULING_LINED) {
+      gnome_print_setrgbcolor(gpc, RGBA_RGB(RULING_MARGIN_COLOR));
+      gnome_print_line_stroked(gpc, RULING_LEFTMARGIN, 0, RULING_LEFTMARGIN, pg->height);
+    }
+    return;
+  }
+  else if (pg->bg->type == BG_PIXMAP || pg->bg->type == BG_PDF) {
+    if (pg->bg->type == BG_PDF) {
+      pgpdf = (struct BgPdfPage *)g_list_nth_data(bgpdf.pages, pg->bg->file_page_seq-1);
+      if (pgpdf == NULL) return;
+      if (pgpdf->dpi != PDFTOPPM_PRINTING_DPI) {
+        add_bgpdf_request(pg->bg->file_page_seq, 0, TRUE);
+        while (pgpdf->dpi != PDFTOPPM_PRINTING_DPI && bgpdf.status == STATUS_RUNNING) {
+          gtk_main_iteration();
+          if (*abort) return;
+        }
+      }
+      pix = pgpdf->pixbuf;
+    }
+    else pix = pg->bg->pixbuf;
+    if (gdk_pixbuf_get_bits_per_sample(pix) != 8) return;
+    if (gdk_pixbuf_get_colorspace(pix) != GDK_COLORSPACE_RGB) return;
+    gnome_print_gsave(gpc);
+    gnome_print_scale(gpc, pg->width, -pg->height);
+    gnome_print_translate(gpc, 0., -1.);
+    if (gdk_pixbuf_get_n_channels(pix) == 3)
+       gnome_print_rgbimage(gpc, gdk_pixbuf_get_pixels(pix),
+         gdk_pixbuf_get_width(pix), gdk_pixbuf_get_height(pix), gdk_pixbuf_get_rowstride(pix));
+    else if (gdk_pixbuf_get_n_channels(pix) == 4)
+       gnome_print_rgbaimage(gpc, gdk_pixbuf_get_pixels(pix),
+         gdk_pixbuf_get_width(pix), gdk_pixbuf_get_height(pix), gdk_pixbuf_get_rowstride(pix));
+    gnome_print_grestore(gpc);
+    return;
+  }
+}
+
+void print_page(GnomePrintContext *gpc, struct Page *pg, int pageno,
+                double pgwidth, double pgheight, gboolean *abort)
+{
+  char tmp[10];
+  gdouble scale;
+  guint old_rgba;
+  double old_thickness;
+  GList *layerlist, *itemlist;
+  struct Layer *l;
+  struct Item *item;
+  int i;
+  double *pt;
+  
+  if (pg==NULL) return;
+  
+  g_snprintf(tmp, 10, "Page %d", pageno);
+  gnome_print_beginpage(gpc, (guchar *)tmp);
+  gnome_print_gsave(gpc);
+  
+  scale = MIN(pgwidth/pg->width, pgheight/pg->height)*0.95;
+  gnome_print_translate(gpc,
+     (pgwidth - scale*pg->width)/2, (pgheight + scale*pg->height)/2);
+  gnome_print_scale(gpc, scale, -scale);
+  gnome_print_setlinejoin(gpc, 1); // round
+  gnome_print_setlinecap(gpc, 1); // round
+
+  print_background(gpc, pg, abort);
+
+  old_rgba = 0x12345678;    // not any values we use, so we'll reset them
+  old_thickness = 0.0;
+
+  for (layerlist = pg->layers; layerlist!=NULL; layerlist = layerlist->next) {
+    if (*abort) break;
+    l = (struct Layer *)layerlist->data;
+    for (itemlist = l->items; itemlist!=NULL; itemlist = itemlist->next) {
+      if (*abort) break;
+      item = (struct Item *)itemlist->data;
+      if (item->type == ITEM_STROKE) {
+        if ((item->brush.color_rgba & ~0xff) != (old_rgba & ~0xff))
+          gnome_print_setrgbcolor(gpc, RGBA_RGB(item->brush.color_rgba));
+        if ((item->brush.color_rgba & 0xff) != (old_rgba & 0xff))
+          gnome_print_setopacity(gpc, RGBA_ALPHA(item->brush.color_rgba));
+        if (item->brush.thickness != old_thickness)
+          gnome_print_setlinewidth(gpc, item->brush.thickness);
+        old_rgba = item->brush.color_rgba;
+        old_thickness = item->brush.thickness;
+        gnome_print_newpath(gpc);
+        pt = item->path->coords;
+        gnome_print_moveto(gpc, pt[0], pt[1]);
+        for (i=1, pt+=2; i<item->path->num_points; i++, pt+=2)
+          gnome_print_lineto(gpc, pt[0], pt[1]);
+        gnome_print_stroke(gpc);
+      }
+    }
+  }
+  
+  gnome_print_grestore(gpc);
+  gnome_print_showpage(gpc);
+}
+
+void cb_print_abort(GtkDialog *dialog, gint response, gboolean *abort)
+{
+  *abort = TRUE;
+}
+
+void print_job_render(GnomePrintJob *gpj, int fromPage, int toPage)
+{
+  GnomePrintConfig *config;
+  GnomePrintContext *gpc;
+  GtkWidget *wait_dialog;
+  double pgwidth, pgheight;
+  int i;
+  gboolean abort;
+  
+  config = gnome_print_job_get_config(gpj);
+  gnome_print_config_get_page_size(config, &pgwidth, &pgheight);
+  g_object_unref(G_OBJECT(config));
+
+  gpc = gnome_print_job_get_context(gpj);
+
+  abort = FALSE;
+  wait_dialog = gtk_message_dialog_new(GTK_WINDOW(winMain), GTK_DIALOG_MODAL,
+     GTK_MESSAGE_INFO, GTK_BUTTONS_CANCEL, "Preparing print job");
+  gtk_widget_show(wait_dialog);
+  g_signal_connect(wait_dialog, "response", G_CALLBACK (cb_print_abort), &abort);
+  
+  for (i = fromPage; i <= toPage; i++) {
+    gtk_message_dialog_format_secondary_text(
+              GTK_MESSAGE_DIALOG(wait_dialog), "Page %d", i+1); 
+    while (gtk_events_pending()) gtk_main_iteration();
+    print_page(gpc, (struct Page *)g_list_nth_data(journal.pages, i), i+1,
+                                             pgwidth, pgheight, &abort);
+    if (abort) break;
+  }
+  gtk_message_dialog_format_secondary_text(
+              GTK_MESSAGE_DIALOG(wait_dialog), "Finalizing...");
+  while (gtk_events_pending()) gtk_main_iteration();
+
+  gnome_print_context_close(gpc);  
+  g_object_unref(G_OBJECT(gpc));  
+
+  gnome_print_job_close(gpj);
+  if (!abort) gnome_print_job_print(gpj);
+  g_object_unref(G_OBJECT(gpj));
+
+  gtk_widget_destroy(wait_dialog);
+}