X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=src%2Fxo-print.c;h=cb480b1936d0192b7097337fb4a774f0932547e0;hb=8d8f9e44b17ef9737084eea7693072e4777a0609;hp=cfd61e1f0b3ce53207c2a17d49e61f1a1c874e32;hpb=2e5ff0bff41fa53d4941b6f0fe49c8914bf29cbc;p=xournal.git diff --git a/src/xo-print.c b/src/xo-print.c index cfd61e1..cb480b1 100644 --- a/src/xo-print.c +++ b/src/xo-print.c @@ -342,7 +342,7 @@ struct PdfObj *get_pdfobj(GString *pdfbuf, struct XrefTable *xref, struct PdfObj struct PdfObj *parse_xref_table(GString *pdfbuf, struct XrefTable *xref, int offs) { - char *p, *q, *eof; + char *p, *eof; struct PdfObj *trailerdict, *obj; int start, len, i; @@ -460,7 +460,7 @@ int pdf_getpageinfo(GString *pdfbuf, struct XrefTable *xref, gboolean pdf_parse_info(GString *pdfbuf, struct PdfInfo *pdfinfo, struct XrefTable *xref) { char *p; - int i, offs; + int offs; struct PdfObj *obj, *pages; xref->n_alloc = xref->last = 0; @@ -711,29 +711,34 @@ int pdf_draw_bitmap_background(struct Page *pg, GString *str, BgPdfPage *pgpdf; GdkPixbuf *pix; GString *zpix; + PopplerPage *pdfpage; char *buf, *p1, *p2; int height, width, stride, x, y, chan; + double pgheight, pgwidth; 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 -1; - 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(); - } - pix = pgpdf->pixbuf; + if (!bgpdf.document) return -1; + pdfpage = poppler_document_get_page(bgpdf.document, pg->bg->file_page_seq-1); + if (!pdfpage) return -1; + 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 = pg->bg->pixbuf; - - if (gdk_pixbuf_get_bits_per_sample(pix) != 8) return -1; - if (gdk_pixbuf_get_colorspace(pix) != GDK_COLORSPACE_RGB) return -1; + 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 -1; } + width = gdk_pixbuf_get_width(pix); height = gdk_pixbuf_get_height(pix); stride = gdk_pixbuf_get_rowstride(pix); chan = gdk_pixbuf_get_n_channels(pix); - if (chan!=3 && chan!=4) return -1; + if (chan!=3 && chan!=4) { g_object_unref(pix); return -1; } g_string_append_printf(str, "q %.2f 0 0 %.2f 0 %.2f cm /ImBg Do Q ", pg->width, -pg->height, pg->height); @@ -748,6 +753,7 @@ int pdf_draw_bitmap_background(struct Page *pg, GString *str, } zpix = do_deflate(buf, 3*width*height); g_free(buf); + g_object_unref(pix); make_xref(xref, xref->last+1, pdfbuf->len); g_string_append_printf(pdfbuf, @@ -765,7 +771,7 @@ int pdf_draw_bitmap_background(struct Page *pg, GString *str, // manipulate Pdf fonts struct PdfFont *new_pdffont(struct XrefTable *xref, GList **fonts, - unsigned char *filename, int font_id, FT_Face face, int glyph_page) + char *filename, int font_id, FT_Face face, int glyph_page) { GList *list; struct PdfFont *font; @@ -830,10 +836,11 @@ 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, len, len1, len2; + int i, j, num, len1, len2; + gsize len; TrueTypeFont *ttfnt; char *tmpfile, *seg1, *seg2; - unsigned char *fontdata, *p; + char *fontdata, *p; char prefix[8]; int nobj_fontprog, nobj_descr, lastchar; @@ -855,12 +862,12 @@ void embed_pdffont(GString *pdfbuf, struct XrefTable *xref, struct PdfFont *font CreateTTFromTTGlyphs(ttfnt, tmpfile, glyphs, encoding, num, 0, NULL, TTCF_AutoName | TTCF_IncludeOS2); CloseTTFont(ttfnt); - if (g_file_get_contents(tmpfile, (char **)&fontdata, &len, NULL) && len>=8) { + if (g_file_get_contents(tmpfile, &fontdata, &len, NULL) && len>=8) { 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, len, len); + nobj_fontprog, (int)len, (int)len); g_string_append_len(pdfbuf, fontdata, len); g_string_append(pdfbuf, "endstream\nendobj\n"); g_free(fontdata); @@ -872,14 +879,14 @@ void embed_pdffont(GString *pdfbuf, struct XrefTable *xref, struct PdfFont *font else fallback = TRUE; } else { // embed the font file: Type1 case - if (g_file_get_contents(font->filename, (char **)&fontdata, &len, NULL) && len>=8) { - if (fontdata[0]==0x80 && fontdata[1]==0x01) { + if (g_file_get_contents(font->filename, &fontdata, &len, NULL) && len>=8) { + if (fontdata[0]==(char)0x80 && fontdata[1]==(char)0x01) { is_binary = TRUE; - len1 = pfb_get_length(fontdata+2); - if (fontdata[len1+6]!=0x80 || fontdata[len1+7]!=0x02) fallback = TRUE; + len1 = pfb_get_length((unsigned char *)fontdata+2); + if (fontdata[len1+6]!=(char)0x80 || fontdata[len1+7]!=(char)0x02) fallback = TRUE; else { - len2 = pfb_get_length(fontdata+len1+8); - if (fontdata[len1+len2+12]!=0x80 || fontdata[len1+len2+13]!=0x01) + len2 = pfb_get_length((unsigned char *)fontdata+len1+8); + if (fontdata[len1+len2+12]!=(char)0x80 || fontdata[len1+len2+13]!=(char)0x01) fallback = TRUE; } } @@ -1021,7 +1028,7 @@ void pdf_draw_page(struct Page *pg, GString *str, gboolean *use_hiliter, FcPattern *pattern; int baseline, advance; int glyph_no, glyph_page, current_page; - unsigned char *filename; + char *filename; char tmpstr[200]; int font_id; FT_Face ftface; @@ -1052,10 +1059,18 @@ void pdf_draw_page(struct Page *pg, GString *str, gboolean *use_hiliter, old_rgba = item->brush.color_rgba & ~0xff; old_thickness = item->brush.thickness; pt = item->path->coords; - g_string_append_printf(str, "%.2f %.2f m ", pt[0], pt[1]); - for (i=1, pt+=2; ipath->num_points; i++, pt+=2) - g_string_append_printf(str, "%.2f %.2f l ", pt[0], pt[1]); - g_string_append_printf(str,"S\n"); + if (!item->brush.variable_width) { + g_string_append_printf(str, "%.2f %.2f m ", pt[0], pt[1]); + for (i=1, pt+=2; ipath->num_points; i++, pt+=2) + g_string_append_printf(str, "%.2f %.2f l ", pt[0], pt[1]); + g_string_append_printf(str,"S\n"); + old_thickness = item->brush.thickness; + } else { + for (i=0; ipath->num_points-1; i++, pt+=2) + g_string_append_printf(str, "%.2f w %.2f %.2f m %.2f %.2f l S\n", + item->widths[i], pt[0], pt[1], pt[2], pt[3]); + old_thickness = 0.0; + } if ((item->brush.color_rgba & 0xf0) != 0xf0) // undo transparent g_string_append(str, "Q "); } @@ -1083,7 +1098,7 @@ void pdf_draw_page(struct Page *pg, GString *str, gboolean *use_hiliter, if (!PANGO_IS_FC_FONT(run->item->analysis.font)) continue; fcfont = PANGO_FC_FONT(run->item->analysis.font); pattern = fcfont->font_pattern; - if (FcPatternGetString(pattern, FC_FILE, 0, &filename) != FcResultMatch || + if (FcPatternGetString(pattern, FC_FILE, 0, (unsigned char **)&filename) != FcResultMatch || FcPatternGetInteger(pattern, FC_INDEX, 0, &font_id) != FcResultMatch) continue; ftface = pango_fc_font_lock_face(fcfont); @@ -1163,8 +1178,6 @@ gboolean print_to_pdf(char *filename) struct XrefTable xref; GList *pglist; struct Page *pg; - char *buf; - unsigned int len; gboolean annot, uses_pdf; gboolean use_hiliter; struct PdfInfo pdfinfo; @@ -1186,11 +1199,9 @@ gboolean print_to_pdf(char *filename) } if (uses_pdf && bgpdf.status != STATUS_NOT_INIT && - g_file_get_contents(bgpdf.tmpfile_copy, &buf, &len, NULL) && - !strncmp(buf, "%PDF-1.", 7)) { + bgpdf.file_contents!=NULL && !strncmp(bgpdf.file_contents, "%PDF-1.", 7)) { // parse the existing PDF file - pdfbuf = g_string_new_len(buf, len); - g_free(buf); + pdfbuf = g_string_new_len(bgpdf.file_contents, bgpdf.file_length); if (pdfbuf->str[7]<'4') pdfbuf->str[7] = '4'; // upgrade to 1.4 annot = pdf_parse_info(pdfbuf, &pdfinfo, &xref); if (!annot) { @@ -1398,6 +1409,9 @@ void print_background(GnomePrintContext *gpc, struct Page *pg, gboolean *abort) double x, y; GdkPixbuf *pix; BgPdfPage *pgpdf; + PopplerPage *pdfpage; + int width, height; + double pgwidth, pgheight; if (pg->bg->type == BG_SOLID) { gnome_print_setopacity(gpc, 1.0); @@ -1425,22 +1439,25 @@ void print_background(GnomePrintContext *gpc, struct Page *pg, gboolean *abort) } return; } - else if (pg->bg->type == BG_PIXMAP || pg->bg->type == BG_PDF) { + 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; + 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 = pg->bg->pixbuf; - if (gdk_pixbuf_get_bits_per_sample(pix) != 8) return; - if (gdk_pixbuf_get_colorspace(pix) != GDK_COLORSPACE_RGB) return; + 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.); @@ -1450,6 +1467,7 @@ void print_background(GnomePrintContext *gpc, struct Page *pg, gboolean *abort) 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; } @@ -1504,13 +1522,23 @@ void print_page(GnomePrintContext *gpc, struct Page *pg, int pageno, if (item->type == ITEM_STROKE) { if (item->brush.thickness != old_thickness) gnome_print_setlinewidth(gpc, item->brush.thickness); - 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); + if (!item->brush.variable_width) { + 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); + 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); + } + old_thickness = 0.0; + } } if (item->type == ITEM_TEXT) { layout = gnome_print_pango_create_layout(gpc);