From be15d3f5bfe7f68fd5a1d20850f11d8e7bf9dcf9 Mon Sep 17 00:00:00 2001 From: auroux Date: Sat, 28 Jan 2006 22:07:28 +0000 Subject: [PATCH] Initial revision --- src/xo-print.c | 190 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100644 src/xo-print.c diff --git a/src/xo-print.c b/src/xo-print.c new file mode 100644 index 0000000..933868e --- /dev/null +++ b/src/xo-print.c @@ -0,0 +1,190 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#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; xwidth-1; x+=RULING_GRAPHSPACING) + gnome_print_line_stroked(gpc, x, 0, x, pg->height); + for (y=RULING_GRAPHSPACING; yheight-1; y+=RULING_GRAPHSPACING) + gnome_print_line_stroked(gpc, 0, y, pg->width, y); + return; + } + + for (y=RULING_TOPMARGIN; yheight-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; ipath->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); +} -- 2.39.2