X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=src%2Fxo-print.c;h=029500ecba345d808c4ce4901227b185294dc32e;hb=HEAD;hp=dc14d4ee00a809da2aa2e1bc4c72234f7fc845c8;hpb=e648cece76b671b5b0e165acc6d14178e8de1000;p=xournal.git diff --git a/src/xo-print.c b/src/xo-print.c index dc14d4e..029500e 100644 --- a/src/xo-print.c +++ b/src/xo-print.c @@ -1,3 +1,18 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + #ifdef HAVE_CONFIG_H # include #endif @@ -6,17 +21,20 @@ #include #include -#include -#include #include #include #include #include #include +#include #include #include #include FT_FREETYPE_H -#include "sft.h" /* Sun Font Tools, embedded in libgnomeprint */ + +#define NO_MAPPERS +#define NO_TYPE3 +#define NO_TYPE42 +#include "ttsubset/sft.h" #include "xournal.h" #include "xo-support.h" @@ -725,7 +743,7 @@ int pdf_draw_bitmap_background(struct Page *pg, GString *str, width = (int) (PDFTOPPM_PRINTING_DPI * pgwidth/72.0); height = (int) (PDFTOPPM_PRINTING_DPI * pgheight/72.0); pix = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, width, height); - poppler_page_render_to_pixbuf( + wrapper_poppler_page_render_to_pixbuf( pdfpage, 0, 0, width, height, PDFTOPPM_PRINTING_DPI/72.0, 0, pix); g_object_unref(pdfpage); } @@ -758,7 +776,7 @@ int pdf_draw_bitmap_background(struct Page *pg, GString *str, make_xref(xref, xref->last+1, pdfbuf->len); g_string_append_printf(pdfbuf, - "%d 0 obj\n<< /Length %d /Filter /FlateDecode /Type /Xobject " + "%d 0 obj\n<< /Length %zu /Filter /FlateDecode /Type /Xobject " "/Subtype /Image /Width %d /Height %d /ColorSpace /DeviceRGB " "/BitsPerComponent 8 >> stream\n", xref->last, zpix->len, width, height); @@ -769,6 +787,81 @@ int pdf_draw_bitmap_background(struct Page *pg, GString *str, 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; ypixbuf)+stride*y; + for (x=0; xdata[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; ypixbuf)+stride*y; + for (x=0; xdata[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, @@ -837,10 +930,12 @@ void embed_pdffont(GString *pdfbuf, struct XrefTable *xref, struct PdfFont *font gboolean fallback, is_binary; guchar encoding[256]; gushort glyphs[256]; - int i, j, num, len1, len2; - gsize len; + int i, j, num; + guint32 len1, len2; + guint32 tt_len; + gsize t1_len; TrueTypeFont *ttfnt; - char *tmpfile, *seg1, *seg2; + char *seg1, *seg2; char *fontdata, *p; char prefix[8]; int nobj_fontprog, nobj_descr, lastchar; @@ -859,28 +954,24 @@ void embed_pdffont(GString *pdfbuf, struct XrefTable *xref, struct PdfFont *font } font->num_glyphs_used = num-1; if (OpenTTFont(font->filename, 0, &ttfnt) == SF_OK) { - tmpfile = mktemp(g_strdup(TMPDIR_TEMPLATE)); - CreateTTFromTTGlyphs(ttfnt, tmpfile, glyphs, encoding, num, - 0, NULL, TTCF_AutoName | TTCF_IncludeOS2); - CloseTTFont(ttfnt); - if (g_file_get_contents(tmpfile, &fontdata, &len, NULL) && len>=8) { + if (CreateTTFromTTGlyphs_tomemory(ttfnt, (guint8**)&fontdata, &tt_len, glyphs, encoding, num, + 0, NULL, TTCF_AutoName | TTCF_IncludeOS2) == SF_OK) { make_xref(xref, xref->last+1, pdfbuf->len); nobj_fontprog = xref->last; g_string_append_printf(pdfbuf, - "%d 0 obj\n<< /Length %d /Length1 %d >> stream\n", - nobj_fontprog, (int)len, (int)len); - g_string_append_len(pdfbuf, fontdata, len); + "%d 0 obj\n<< /Length %u /Length1 %u >> stream\n", + nobj_fontprog, tt_len, tt_len); + g_string_append_len(pdfbuf, fontdata, tt_len); g_string_append(pdfbuf, "endstream\nendobj\n"); g_free(fontdata); - } + } else fallback = TRUE; - unlink(tmpfile); - g_free(tmpfile); - } - else fallback = TRUE; + CloseTTFont(ttfnt); + } + else fallback = TRUE; } else { // embed the font file: Type1 case - if (g_file_get_contents(font->filename, &fontdata, &len, NULL) && len>=8) { + if (g_file_get_contents(font->filename, &fontdata, &t1_len, NULL) && t1_len>=8) { if (fontdata[0]==(char)0x80 && fontdata[1]==(char)0x01) { is_binary = TRUE; len1 = pfb_get_length((unsigned char *)fontdata+2); @@ -899,7 +990,7 @@ void embed_pdffont(GString *pdfbuf, struct XrefTable *xref, struct PdfFont *font if (*p=='\n' || *p=='\r') p++; if (*p=='\n' || *p=='\r') p++; len1 = p-fontdata; - p = g_strrstr_len(fontdata, len, T1_SEGMENT_3_END); + p = g_strrstr_len(fontdata, t1_len, T1_SEGMENT_3_END); if (p==NULL) fallback = TRUE; else { // rewind 512 zeros @@ -937,7 +1028,7 @@ void embed_pdffont(GString *pdfbuf, struct XrefTable *xref, struct PdfFont *font make_xref(xref, xref->last+1, pdfbuf->len); nobj_fontprog = xref->last; g_string_append_printf(pdfbuf, - "%d 0 obj\n<< /Length %d /Length1 %d /Length2 %d /Length3 0 >> stream\n", + "%d 0 obj\n<< /Length %u /Length1 %u /Length2 %u /Length3 0 >> stream\n", nobj_fontprog, len1+len2, len1, len2); g_string_append_len(pdfbuf, seg1, len1); g_string_append_len(pdfbuf, seg2, len2); @@ -1007,10 +1098,31 @@ void embed_pdffont(GString *pdfbuf, struct XrefTable *xref, struct PdfFont *font 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) + struct XrefTable *xref, GList **pdffonts, GList **pdfimages) { GList *layerlist, *itemlist, *tmplist; struct Layer *l; @@ -1026,6 +1138,7 @@ void pdf_draw_page(struct Page *pg, GString *str, gboolean *use_hiliter, PangoRectangle logical_rect; PangoLayoutRun *run; PangoFcFont *fcfont; + PangoFontMap *fontmap; FcPattern *pattern; int baseline, advance; int glyph_no, glyph_page, current_page; @@ -1034,6 +1147,7 @@ void pdf_draw_page(struct Page *pg, GString *str, gboolean *use_hiliter, 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 @@ -1042,6 +1156,10 @@ void pdf_draw_page(struct Page *pg, GString *str, gboolean *use_hiliter, cur_font = (struct PdfFont *)tmplist->data; cur_font->used_in_this_page = FALSE; } + for (tmplist = *pdfimages; tmplist!=NULL; tmplist = tmplist->next) { + cur_image = (struct PdfImage *)tmplist->data; + cur_image->used_in_this_page = FALSE; + } for (layerlist = pg->layers; layerlist!=NULL; layerlist = layerlist->next) { l = (struct Layer *)layerlist->data; @@ -1080,8 +1198,12 @@ void pdf_draw_page(struct Page *pg, GString *str, gboolean *use_hiliter, g_string_append_printf(str, "%.2f %.2f %.2f rg ", RGBA_RGB(item->brush.color_rgba)); old_text_rgba = item->brush.color_rgba & ~0xff; - context = gnome_print_pango_create_context(gnome_print_pango_get_default_font_map()); + fontmap = pango_ft2_font_map_new(); + pango_ft2_font_map_set_resolution(PANGO_FT2_FONT_MAP (fontmap), 72, 72); + context = pango_context_new(); + pango_context_set_font_map(context, fontmap); layout = pango_layout_new(context); + g_object_unref(fontmap); g_object_unref(context); font_desc = pango_font_description_from_string(item->font_name); pango_font_description_set_absolute_size(font_desc, @@ -1157,6 +1279,14 @@ void pdf_draw_page(struct Page *pg, GString *str, gboolean *use_hiliter, pango_layout_iter_free(iter); g_object_unref(layout); } + else if (item->type == ITEM_IMAGE) { + cur_image = new_pdfimage(xref, pdfimages, item->image); + cur_image->used_in_this_page = TRUE; + 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, item->bbox.top, // translation + item->bbox.right-item->bbox.left, item->bbox.top-item->bbox.bottom, item->bbox.bottom-item->bbox.top, // scaling + cur_image->n_obj); + } } } } @@ -1183,17 +1313,19 @@ gboolean print_to_pdf(char *filename) gboolean use_hiliter; struct PdfInfo pdfinfo; struct PdfObj *obj; - GList *pdffonts, *list; + GList *pdffonts, *pdfimages, *list; struct PdfFont *font; + struct PdfImage *image; char *tmpbuf; - f = fopen(filename, "w"); + f = fopen(filename, "wb"); if (f == NULL) return FALSE; setlocale(LC_NUMERIC, "C"); annot = FALSE; 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; @@ -1254,7 +1386,7 @@ gboolean print_to_pdf(char *filename) tmpstr = make_pdfprefix(pdfinfo.pages+(pg->bg->file_page_seq-1), pg->width, pg->height); g_string_append_printf(pdfbuf, - "%d 0 obj\n<< /Length %d >> stream\n%s\nendstream\nendobj\n", + "%d 0 obj\n<< /Length %zu >> stream\n%s\nendstream\nendobj\n", n_obj_prefix, tmpstr->len, tmpstr->str); g_string_free(tmpstr, TRUE); g_string_prepend(pgstrm, "Q Q Q "); @@ -1263,7 +1395,7 @@ gboolean print_to_pdf(char *filename) 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); + pdf_draw_page(pg, pgstrm, &use_hiliter, &xref, &pdffonts, &pdfimages); g_string_append_printf(pgstrm, "Q\n"); // deflate pgstrm and write it @@ -1272,7 +1404,7 @@ gboolean print_to_pdf(char *filename) make_xref(&xref, xref.last+1, pdfbuf->len); g_string_append_printf(pdfbuf, - "%d 0 obj\n<< /Length %d /Filter /FlateDecode>> stream\n", + "%d 0 obj\n<< /Length %zu /Filter /FlateDecode>> stream\n", xref.last, zpgstrm->len); g_string_append_len(pdfbuf, zpgstrm->str, zpgstrm->len); g_string_free(zpgstrm, TRUE); @@ -1319,7 +1451,7 @@ gboolean print_to_pdf(char *filename) } add_dict_subentry(pdfbuf, &xref, obj, "/ProcSet", PDFTYPE_ARRAY, NULL, mk_pdfname("/PDF")); - if (n_obj_bgpix>0) + if (n_obj_bgpix>0 || pdfimages!=NULL) add_dict_subentry(pdfbuf, &xref, obj, "/ProcSet", PDFTYPE_ARRAY, NULL, mk_pdfname("/ImageC")); if (use_hiliter) @@ -1339,12 +1471,21 @@ gboolean print_to_pdf(char *filename) g_free(tmpbuf); } } + for (list=pdfimages; list!=NULL; list = list->next) { + image = (struct PdfImage *)list->data; + if (image->used_in_this_page) { + 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 + // after the pages, we insert fonts and images for (list = pdffonts; list!=NULL; list = list->next) { font = (struct PdfFont *)list->data; embed_pdffont(pdfbuf, &xref, font); @@ -1353,6 +1494,14 @@ gboolean print_to_pdf(char *filename) g_free(font); } g_list_free(pdffonts); + 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; @@ -1401,84 +1550,79 @@ gboolean print_to_pdf(char *filename) return TRUE; } -/*********** Printing via libgnomeprint **********/ +/*********** Printing via gtk-print **********/ + +#if GTK_CHECK_VERSION(2, 10, 0) // does the same job as update_canvas_bg(), but to a print context -void print_background(GnomePrintContext *gpc, struct Page *pg, gboolean *abort) +void print_background(cairo_t *cr, struct Page *pg) { double x, y; GdkPixbuf *pix; BgPdfPage *pgpdf; PopplerPage *pdfpage; - int width, height; + cairo_surface_t *cr_pixbuf; double pgwidth, pgheight; 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); - + cairo_set_source_rgb(cr, RGBA_RGB(pg->bg->color_rgba)); + cairo_rectangle(cr, 0, 0, pg->width, pg->height); + cairo_fill(cr); if (!ui.print_ruling) return; if (pg->bg->ruling == RULING_NONE) return; - gnome_print_setrgbcolor(gpc, RGBA_RGB(RULING_COLOR)); - gnome_print_setlinewidth(gpc, RULING_THICKNESS); - + cairo_set_source_rgb(cr, RGBA_RGB(RULING_COLOR)); + cairo_set_line_width(cr, 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); + { cairo_move_to(cr, x, 0); cairo_line_to(cr, x, pg->height); } for (y=RULING_GRAPHSPACING; yheight-1; y+=RULING_GRAPHSPACING) - gnome_print_line_stroked(gpc, 0, -y, pg->width, -y); + { cairo_move_to(cr, 0, y); cairo_line_to(cr, pg->width, y); } + cairo_stroke(cr); return; } for (y=RULING_TOPMARGIN; yheight-1; y+=RULING_SPACING) - gnome_print_line_stroked(gpc, 0, -y, pg->width, -y); + { cairo_move_to(cr, 0, y); cairo_line_to(cr, pg->width, y); } + cairo_stroke(cr); 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); + cairo_set_source_rgb(cr, RGBA_RGB(RULING_MARGIN_COLOR)); + cairo_move_to(cr, RULING_LEFTMARGIN, 0); + cairo_line_to(cr, RULING_LEFTMARGIN, pg->height); + cairo_stroke(cr); } return; } + else + if (pg->bg->type == BG_PDF) { + if (!bgpdf.document) return; + pdfpage = poppler_document_get_page(bgpdf.document, pg->bg->file_page_seq-1); + if (!pdfpage) return; + poppler_page_get_size(pdfpage, &pgwidth, &pgheight); + cairo_save(cr); + cairo_scale(cr, pg->width/pgwidth, pg->height/pgheight); + poppler_page_render(pdfpage, cr); + cairo_restore(cr); + g_object_unref(pdfpage); + } else - if (pg->bg->type == BG_PIXMAP || pg->bg->type == BG_PDF) { - if (pg->bg->type == BG_PDF) { - if (!bgpdf.document) return; - pdfpage = poppler_document_get_page(bgpdf.document, pg->bg->file_page_seq-1); - if (!pdfpage) return; - poppler_page_get_size(pdfpage, &pgwidth, &pgheight); - width = (int) (PDFTOPPM_PRINTING_DPI * pgwidth/72.0); - height = (int) (PDFTOPPM_PRINTING_DPI * pgheight/72.0); - pix = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, width, height); - poppler_page_render_to_pixbuf( - pdfpage, 0, 0, width, height, PDFTOPPM_PRINTING_DPI/72.0, 0, pix); - g_object_unref(pdfpage); - } - else pix = g_object_ref(pg->bg->pixbuf); - - if (gdk_pixbuf_get_bits_per_sample(pix) != 8 || - gdk_pixbuf_get_colorspace(pix) != GDK_COLORSPACE_RGB) - { g_object_unref(pix); 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)); - g_object_unref(pix); - gnome_print_grestore(gpc); - return; + if (pg->bg->type == BG_PIXMAP) { + cairo_save(cr); + cairo_scale(cr, pg->width/gdk_pixbuf_get_width(pg->bg->pixbuf), + pg->height/gdk_pixbuf_get_height(pg->bg->pixbuf)); + gdk_cairo_set_source_pixbuf(cr, pg->bg->pixbuf, 0, 0); + cairo_rectangle(cr, 0, 0, gdk_pixbuf_get_width(pg->bg->pixbuf), gdk_pixbuf_get_height(pg->bg->pixbuf)); + cairo_fill(cr); + cairo_restore(cr); } } -void print_page(GnomePrintContext *gpc, struct Page *pg, int pageno, - double pgwidth, double pgheight, gboolean *abort) +void print_job_render_page(GtkPrintOperation *print, GtkPrintContext *context, gint pageno, gpointer user_data) { - char tmp[10]; - gdouble scale; + cairo_t *cr; + gdouble width, height, scale; + struct Page *pg; guint old_rgba; double old_thickness; GList *layerlist, *itemlist; @@ -1488,128 +1632,79 @@ void print_page(GnomePrintContext *gpc, struct Page *pg, int pageno, double *pt; PangoFontDescription *font_desc; PangoLayout *layout; + + pg = (struct Page *)g_list_nth_data(journal.pages, pageno); + cr = gtk_print_context_get_cairo_context(context); + width = gtk_print_context_get_width(context); + height = gtk_print_context_get_height(context); + scale = MIN(width/pg->width, height/pg->height); - if (pg==NULL) return; + cairo_translate(cr, (width-scale*pg->width)/2, (height-scale*pg->height)/2); + cairo_scale(cr, scale, scale); + cairo_set_line_join(cr, CAIRO_LINE_JOIN_ROUND); + cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND); - 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); + print_background(cr, pg); - old_rgba = 0x12345678; // not any values we use, so we'll reset them + old_rgba = predef_colors_rgba[COLOR_BLACK]; + cairo_set_source_rgb(cr, 0, 0, 0); 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 || item->type == ITEM_TEXT) { - 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.color_rgba != old_rgba) + cairo_set_source_rgba(cr, RGBA_RGB(item->brush.color_rgba), + RGBA_ALPHA(item->brush.color_rgba)); old_rgba = item->brush.color_rgba; } if (item->type == ITEM_STROKE) { if (item->brush.thickness != old_thickness) - gnome_print_setlinewidth(gpc, item->brush.thickness); - gnome_print_newpath(gpc); + cairo_set_line_width(cr, item->brush.thickness); pt = item->path->coords; if (!item->brush.variable_width) { - gnome_print_moveto(gpc, pt[0], -pt[1]); + cairo_move_to(cr, 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); + cairo_line_to(cr, pt[0], pt[1]); + cairo_stroke(cr); old_thickness = item->brush.thickness; } else { for (i=0; ipath->num_points-1; i++, pt+=2) { - gnome_print_moveto(gpc, pt[0], -pt[1]); - gnome_print_setlinewidth(gpc, item->widths[i]); - gnome_print_lineto(gpc, pt[2], -pt[3]); - gnome_print_stroke(gpc); + cairo_move_to(cr, pt[0], pt[1]); + cairo_set_line_width(cr, item->widths[i]); + cairo_line_to(cr, pt[2], pt[3]); + cairo_stroke(cr); } old_thickness = 0.0; } } if (item->type == ITEM_TEXT) { - layout = gnome_print_pango_create_layout(gpc); + layout = gtk_print_context_create_pango_layout(context); font_desc = pango_font_description_from_string(item->font_name); - pango_font_description_set_absolute_size(font_desc, - item->font_size*PANGO_SCALE); + if (item->font_size) + pango_font_description_set_absolute_size(font_desc, + item->font_size*PANGO_SCALE); pango_layout_set_font_description(layout, font_desc); pango_font_description_free(font_desc); pango_layout_set_text(layout, item->text, -1); - gnome_print_moveto(gpc, item->bbox.left, -item->bbox.top); - gnome_print_pango_layout(gpc, layout); + cairo_move_to(cr, item->bbox.left, item->bbox.top); + pango_cairo_show_layout(cr, layout); g_object_unref(layout); } + if (item->type == ITEM_IMAGE) { + double scalex = (item->bbox.right-item->bbox.left)/gdk_pixbuf_get_width(item->image); + double scaley = (item->bbox.bottom-item->bbox.top)/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]; + cairo_set_source_rgb(cr, 0, 0, 0); + } } } - - 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++) { -#if GTK_CHECK_VERSION(2,6,0) - if (!gtk_check_version(2, 6, 0)) - gtk_message_dialog_format_secondary_text( - GTK_MESSAGE_DIALOG(wait_dialog), _("Page %d"), i+1); #endif - 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; - } -#if GTK_CHECK_VERSION(2,6,0) - if (!gtk_check_version(2, 6, 0)) - gtk_message_dialog_format_secondary_text( - GTK_MESSAGE_DIALOG(wait_dialog), _("Finalizing...")); -#endif - 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); -}