]> git.donarmstrong.com Git - xournal.git/blobdiff - src/xo-print.c
Add internationalization support.
[xournal.git] / src / xo-print.c
index cfd61e1f0b3ce53207c2a17d49e61f1a1c874e32..dc14d4ee00a809da2aa2e1bc4c72234f7fc845c8 100644 (file)
@@ -19,6 +19,7 @@
 #include "sft.h" /* Sun Font Tools, embedded in libgnomeprint */
 
 #include "xournal.h"
+#include "xo-support.h"
 #include "xo-misc.h"
 #include "xo-paint.h"
 #include "xo-print.h"
@@ -342,7 +343,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 +461,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 +712,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 +754,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 +772,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 +837,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 +863,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 +880,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 +1029,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 +1060,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; i<item->path->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; i<item->path->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; i<item->path->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 +1099,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 +1179,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 +1200,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 +1410,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 +1440,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 +1468,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;
   }
@@ -1472,7 +1491,7 @@ void print_page(GnomePrintContext *gpc, struct Page *pg, int pageno,
   
   if (pg==NULL) return;
   
-  g_snprintf(tmp, 10, "Page %d", pageno);
+  g_snprintf(tmp, 10, _("Page %d"), pageno);
   gnome_print_beginpage(gpc, (guchar *)tmp);
   gnome_print_gsave(gpc);
   
@@ -1504,13 +1523,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; i<item->path->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; i<item->path->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; i<item->path->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);
@@ -1553,7 +1582,7 @@ void print_job_render(GnomePrintJob *gpj, int fromPage, int toPage)
 
   abort = FALSE;
   wait_dialog = gtk_message_dialog_new(GTK_WINDOW(winMain), GTK_DIALOG_MODAL,
-     GTK_MESSAGE_INFO, GTK_BUTTONS_CANCEL, "Preparing print job");
+     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);
   
@@ -1561,7 +1590,7 @@ void print_job_render(GnomePrintJob *gpj, int fromPage, int toPage)
 #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); 
+             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,
@@ -1571,7 +1600,7 @@ void print_job_render(GnomePrintJob *gpj, int fromPage, int toPage)
 #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...");
+              GTK_MESSAGE_DIALOG(wait_dialog), _("Finalizing..."));
 #endif
   while (gtk_events_pending()) gtk_main_iteration();