]> www.fi.muni.cz Git - evince.git/blobdiff - ps/ps-document.c
Release 0.1.7
[evince.git] / ps / ps-document.c
index 1df82e2643d2e9d70b0a9c924bd36f3fedcc8ab8..958d7687c2a196213d4604ee0c032ebce667616c 100644 (file)
@@ -216,6 +216,7 @@ static gint start_interpreter(PSDocument * gs);
 gboolean computeSize(void);
 static gboolean ps_document_set_page_size(PSDocument * gs, gint new_pagesize, gint pageid);
 static void ps_document_document_iface_init (EvDocumentIface *iface);
+static gboolean ps_document_goto_page(PSDocument * gs, gint page);
 
 static GObjectClass *parent_class = NULL;
 
@@ -226,7 +227,7 @@ ps_document_init(PSDocument * gs)
 {
   gs->bpixmap = NULL;
 
-  gs->current_page = -2;
+  gs->current_page = 0;
   gs->disable_start = FALSE;
   gs->interpreter_pid = -1;
 
@@ -277,14 +278,11 @@ ps_document_init(PSDocument * gs)
   gs->page_y_offset = 0;
 
   /* Set user defined defaults */
-  gs->override_orientation = gtk_gs_defaults_get_override_orientation();
-  gs->fallback_orientation = gtk_gs_defaults_get_orientation();
-  gs->zoom_factor = gtk_gs_defaults_get_zoom_factor();
-  gs->default_size = gtk_gs_defaults_get_size();
-  gs->antialiased = gtk_gs_defaults_get_antialiased();
-  gs->override_size = gtk_gs_defaults_get_override_size();
-  gs->respect_eof = gtk_gs_defaults_get_respect_eof();
-  gs->zoom_mode = gtk_gs_defaults_get_zoom_mode();
+  gs->fallback_orientation = GTK_GS_ORIENTATION_PORTRAIT;
+  gs->zoom_factor = 1.0;
+  gs->default_size = 1;
+  gs->antialiased = TRUE;
+  gs->respect_eof = TRUE;
 
   gs->gs_status = _("No document loaded.");
 }
@@ -343,8 +341,6 @@ ps_document_class_init(PSDocumentClass *klass)
   klass->page_atom = gdk_atom_intern("PAGE", FALSE);
   klass->string_atom = gdk_atom_intern("STRING", FALSE);
 
-  gtk_gs_defaults_load();
-
   g_object_class_override_property (object_class, PROP_TITLE, "title");
 }
 
@@ -379,7 +375,7 @@ ps_document_cleanup(PSDocument * gs)
     g_free(gs->gs_filename_unc);
     gs->gs_filename_unc = NULL;
   }
-  gs->current_page = -1;
+  gs->current_page = 0;
   gs->loaded = FALSE;
   gs->llx = 0;
   gs->lly = 0;
@@ -388,6 +384,63 @@ ps_document_cleanup(PSDocument * gs)
   set_up_page(gs);
 }
 
+static gboolean
+ps_document_widget_event (GtkWidget *widget, GdkEvent *event, gpointer data)
+{
+       PSDocument *gs = (PSDocument *) data;
+
+       if(event->type != GDK_CLIENT_EVENT)
+               return FALSE;
+
+       gs->message_window = event->client.data.l[0];
+
+       if (event->client.message_type == gs_class->page_atom) {
+               LOG ("GS rendered the document");
+               gs->busy = FALSE;
+
+               if (gs->scaling) {
+                       ev_document_scale_changed (EV_DOCUMENT (gs));
+                       gs->scaling = FALSE;
+               } else {
+                       ev_document_page_changed (EV_DOCUMENT (gs));
+               }
+       }
+
+       return TRUE;
+}
+
+static void
+ps_document_set_target (EvDocument  *document,
+                       GdkDrawable *target)
+{
+       PSDocument *gs = PS_DOCUMENT (document);
+       GtkWidget *widget;
+       gpointer data;
+
+       if (gs->pstarget) {
+               gdk_window_get_user_data (gs->pstarget, &data);
+               g_return_if_fail (GTK_IS_WIDGET (data));
+
+               widget = GTK_WIDGET (data);
+               g_signal_handlers_disconnect_by_func
+                       (widget, ps_document_widget_event, document);
+       }
+
+       gs->pstarget = target;
+
+       if (gs->pstarget) {
+               gdk_window_get_user_data (gs->pstarget, &data);
+               g_return_if_fail (GTK_IS_WIDGET (data));
+
+               widget = GTK_WIDGET (data);
+               g_signal_connect (widget, "event",
+                                 G_CALLBACK (ps_document_widget_event),
+                                 document);
+       }
+
+       ps_document_goto_page (gs, gs->current_page);
+}
+
 static void
 ps_document_finalize (GObject * object)
 {
@@ -403,6 +456,8 @@ ps_document_finalize (GObject * object)
        ps_document_cleanup (gs);
        stop_interpreter (gs);
 
+       ps_document_set_target (EV_DOCUMENT (object), NULL);
+
        if(gs->input_buffer) {
                g_free(gs->input_buffer);
                gs->input_buffer = NULL;
@@ -470,8 +525,7 @@ ps_document_get_orientation(PSDocument * gs)
       gs->real_orientation = gs->doc->orientation;
   }
 
-  if(gs->override_orientation ||
-     gs->real_orientation == GTK_GS_ORIENTATION_NONE)
+  if(gs->real_orientation == GTK_GS_ORIENTATION_NONE)
     return gs->fallback_orientation;
   else
     return gs->real_orientation;
@@ -486,13 +540,16 @@ set_up_page(PSDocument * gs)
   GdkGC *fill;
   GdkColor white = { 0, 0xFFFF, 0xFFFF, 0xFFFF };   /* pixel, r, g, b */
   GdkColormap *colormap;
-
-  LOG ("Setup the page");
+  gboolean size_changed;
 
 #ifdef HAVE_LOCALE_H
   char *savelocale;
 #endif
 
+  LOG ("Setup the page");
+
+  size_changed = compute_size (gs);
+
   if (gs->pstarget == NULL)
     return;
 
@@ -502,7 +559,7 @@ set_up_page(PSDocument * gs)
 
   orientation = ps_document_get_orientation(gs);
 
-  if(compute_size(gs)) {
+  if (size_changed || gs->bpixmap == NULL) {
     gdk_flush();
 
     /* clear new pixmap (set to white) */
@@ -720,8 +777,6 @@ start_interpreter(PSDocument * gs)
   int std_out[2];               /* pipe from interp stdout */
   int std_err[2];               /* pipe from interp stderr */
 
-  LOG ("Start the interpreter");
-
 #define NUM_ARGS    100
 #define NUM_GS_ARGS (NUM_ARGS - 20)
 #define NUM_ALPHA_ARGS 10
@@ -730,6 +785,8 @@ start_interpreter(PSDocument * gs)
   char **gs_args, **alpha_args = NULL;
   int argc = 0, i;
 
+  LOG ("Start the interpreter");
+
   if(!gs->gs_filename)
     return 0;
 
@@ -1027,113 +1084,6 @@ check_filecompressed(PSDocument * gs)
   return filename_unc;
 }
 
-/*
- * Check if gs->gs_filename or gs->gs_filename_unc is a pdf file and scan
- * pdf file if necessary.
- * Set gs->filename_dsc to the name of the dsc file or NULL.
- * Error reporting via signal 'interpreter_message'.
- */
-static gchar *
-check_pdf(PSDocument * gs)
-{
-  FILE *file;
-  gchar buf[1024], *filename;
-  int fd;
-
-  /* use uncompressed file as input if necessary */
-  filename = (gs->gs_filename_unc ? gs->gs_filename_unc : gs->gs_filename);
-
-  if((file = fopen(filename, "r"))
-     && (fread(buf, sizeof(char), 5, file) == 5)
-     && (strncmp(buf, "%PDF-", 5) == 0)) {
-    /* we found a PDF file */
-    gchar *fname, *filename_dsc, *filename_err, *cmd, *cmdline;
-    filename_dsc = g_strconcat(g_get_tmp_dir(), "/ggvXXXXXX", NULL);
-    if((fd = mkstemp(filename_dsc)) < 0) {
-      return NULL;
-    }
-    close(fd);
-    filename_err = g_strconcat(g_get_tmp_dir(), "/ggvXXXXXX", NULL);
-    if((fd = mkstemp(filename_err)) < 0) {
-      g_free(filename_dsc);
-      return NULL;
-    }
-    close(fd);
-    fname = g_shell_quote(filename);
-    cmd = g_strdup_printf(gtk_gs_defaults_get_dsc_cmd(), filename_dsc, fname);
-    g_free(fname);
-    /* this command (sometimes?) prints error messages to stdout! */
-    cmdline = g_strdup_printf("%s >%s 2>&1", cmd, filename_err);
-    g_free(cmd);
-
-    if((system(cmdline) == 0) && file_readable(filename_dsc)) {
-
-      /* success */
-      filename = gs->gs_filename_dsc = filename_dsc;
-
-      if(file_length(filename_err) > 0) {
-        gchar *err_msg = " ";
-        GtkWidget *dialog;
-        FILE *err;
-        GdkColor color;
-
-        if((err = fopen(filename_err, "r"))) {
-
-          /* print the content of the file to a message box */
-          while(fgets(buf, 1024, err))
-            err_msg = g_strconcat(err_msg, buf, NULL);
-
-          /* FIXME The dialog is not yet set to modal, difficult to 
-           * get the parent of the dialog box here 
-           */
-
-          dialog = gtk_message_dialog_new(NULL,
-                                          GTK_DIALOG_MODAL,
-                                          GTK_MESSAGE_WARNING,
-                                          GTK_BUTTONS_OK,
-                                          ("There was an error while scaning the file: %s \n%s"),
-                                          gs->gs_filename, err_msg);
-
-          gdk_color_parse("white", &color);
-          gtk_widget_modify_bg(GTK_WIDGET(dialog), GTK_STATE_NORMAL, &color);
-
-          g_signal_connect(G_OBJECT(dialog), "response",
-                           G_CALLBACK(gtk_widget_destroy), NULL);
-
-          gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
-          gtk_widget_show(dialog);
-          g_free(err_msg);
-        }
-      }
-
-    }
-    else {
-      /* report error */
-      g_snprintf(buf, 1024,
-                 _("Error while converting pdf file %s:\n"), filename);
-      ps_document_emit_error_msg(gs, buf);
-
-      if(file_length(filename_err) > 0) {
-        FILE *err;
-        if((err = fopen(filename_err, "r"))) {
-          /* print file to message window */
-          while(fgets(buf, 1024, err))
-            ps_document_emit_error_msg(gs, buf);
-        }
-      }
-      unlink(filename_dsc);
-      g_free(filename_dsc);
-      filename = NULL;
-    }
-    unlink(filename_err);
-    g_free(filename_err);
-    g_free(cmdline);
-  }
-  if(NULL != file)
-    fclose(file);
-  return filename;
-}
-
 #ifdef BROKEN_XINERAMA_PATCH_THAT_SHOULD_NOT_BE_USED
 /* never mind this patch: a properly working X server should take care of
    calculating the proper values. */
@@ -1315,7 +1265,7 @@ document_load(PSDocument * gs, const gchar * fname)
   /* default values: no dsc information available  */
   gs->structured_doc = FALSE;
   gs->send_filename_to_gs = TRUE;
-  gs->current_page = -2;
+  gs->current_page = 0;
   gs->loaded = FALSE;
   if(*fname == '/') {
     /* an absolute path */
@@ -1346,8 +1296,6 @@ document_load(PSDocument * gs, const gchar * fname)
     }
     else {
       filename = check_filecompressed(gs);
-      if(filename)
-        filename = check_pdf(gs);
     }
 
     if(!filename || (gs->gs_psfile = fopen(filename, "r")) == NULL) {
@@ -1377,22 +1325,7 @@ document_load(PSDocument * gs, const gchar * fname)
     }
 
     /* We have to set up the orientation of the document */
-
-
-    /* orientation can only be portrait, and landscape or none.
-       This is the document default. A document can have
-       pages in landscape and some in portrait */
-    if(gs->override_orientation) {
-      /* If the orientation should be override... 
-         then gs->orientation has already the correct
-         value (it was set when the widget was created */
-      /* So do nothing */
-
-    }
-    else {
-      /* Otherwise, set the proper orientation for the doc */
-      gs->real_orientation = gs->doc->orientation;
-    }
+    gs->real_orientation = gs->doc->orientation;
   }
   ps_document_set_page_size(gs, -1, gs->current_page);
   gs->loaded = TRUE;
@@ -1466,7 +1399,6 @@ ps_document_goto_page(PSDocument * gs, gint page)
     gs->current_page = page;
 
     if(gs->doc->pages[page].orientation != NONE &&
-       !gs->override_orientation &&
        gs->doc->pages[page].orientation != gs->real_orientation) {
       gs->real_orientation = gs->doc->pages[page].orientation;
       gs->changed = TRUE;
@@ -1540,7 +1472,7 @@ ps_document_set_page_size(PSDocument * gs, gint new_pagesize, gint pageid)
   if(new_pagesize == -1) {
     if(gs->default_size > 0)
       new_pagesize = gs->default_size;
-    if(!gs->override_size && gs->doc) {
+    if(gs->doc) {
       /* If we have a document:
          We use -- the page size (if specified)
          or the doc. size (if specified)
@@ -1571,7 +1503,7 @@ ps_document_set_page_size(PSDocument * gs, gint new_pagesize, gint pageid)
   }
 
   /* Compute bounding box */
-  if(gs->doc && ((gs->doc->epsf && !gs->override_size) || new_pagesize == -1)) {    /* epsf or bbox */
+  if(gs->doc && (gs->doc->epsf || new_pagesize == -1)) {    /* epsf or bbox */
     if((pageid >= 0) &&
        (gs->doc->pages) &&
        (gs->doc->pages[pageid].boundingbox[URX] >
@@ -1597,7 +1529,7 @@ ps_document_set_page_size(PSDocument * gs, gint new_pagesize, gint pageid)
     if(new_pagesize < 0)
       new_pagesize = gs->default_size;
     new_llx = new_lly = 0;
-    if(gs->doc && !gs->override_size && gs->doc->size &&
+    if(gs->doc && gs->doc->size &&
        (new_pagesize < gs->doc->numsizes)) {
       new_urx = gs->doc->size[new_pagesize].width;
       new_ury = gs->doc->size[new_pagesize].height;
@@ -1632,54 +1564,19 @@ ps_document_set_page_size(PSDocument * gs, gint new_pagesize, gint pageid)
   return FALSE;
 }
 
-static gfloat
-ps_document_zoom_to_fit(PSDocument * gs, gboolean fit_width)
-{
-  gint new_y;
-  gfloat new_zoom;
-  guint avail_w, avail_h;
-
-  g_return_val_if_fail(gs != NULL, 0.0);
-  g_return_val_if_fail(GTK_IS_GS(gs), 0.0);
-
-  avail_w = (gs->avail_w > 0) ? gs->avail_w : gs->width;
-  avail_h = (gs->avail_h > 0) ? gs->avail_h : gs->height;
-
-  new_zoom = ((gfloat) avail_w) / ((gfloat) gs->width) * gs->zoom_factor;
-  if(!fit_width) {
-    new_y = new_zoom * ((gfloat) gs->height) / gs->zoom_factor;
-    if(new_y > avail_h)
-      new_zoom = ((gfloat) avail_h) / ((gfloat) gs->height) * gs->zoom_factor;
-  }
-
-  return new_zoom;
-}
-
 static void
-ps_document_set_zoom(PSDocument * gs, gfloat zoom)
+ps_document_set_zoom (PSDocument * gs, gfloat zoom)
 {
-  g_return_if_fail(gs != NULL);
-  g_return_if_fail(GTK_IS_GS(gs));
+       g_return_if_fail (gs != NULL);
 
-  switch (gs->zoom_mode) {
-  case GTK_GS_ZOOM_FIT_WIDTH:
-    zoom = ps_document_zoom_to_fit(gs, TRUE);
-    break;
-  case GTK_GS_ZOOM_FIT_PAGE:
-    zoom = ps_document_zoom_to_fit(gs, FALSE);
-    break;
-  case GTK_GS_ZOOM_ABSOLUTE:
-  default:
-    break;
-  }
-
-  if(fabs(gs->zoom_factor - zoom) > 0.001) {
-    gs->zoom_factor = zoom;
-    set_up_page(gs);
-    gs->changed = TRUE;
-  }
+       gs->zoom_factor = zoom;
 
-  ps_document_goto_page(gs, gs->current_page);
+       if (gs->pstarget != NULL) {
+               set_up_page(gs);
+               gs->changed = TRUE;
+               gs->scaling = TRUE;
+               ps_document_goto_page (gs, gs->current_page);
+       }
 }
 
 static gboolean
@@ -1747,48 +1644,6 @@ ps_document_get_page (EvDocument  *document)
        return ps->current_page + 1;
 }
 
-static gboolean
-ps_document_widget_event (GtkWidget *widget, GdkEvent *event, gpointer data)
-{
-       PSDocument *gs = (PSDocument *) data;
-
-       if(event->type != GDK_CLIENT_EVENT)
-               return FALSE;
-
-       gs->message_window = event->client.data.l[0];
-
-       if (event->client.message_type == gs_class->page_atom) {
-               LOG ("GS rendered the document");
-               gs->busy = FALSE;
-               ev_document_changed (EV_DOCUMENT (gs));
-       }
-
-       return TRUE;
-}
-
-static void
-ps_document_set_target (EvDocument  *document,
-                       GdkDrawable *target)
-{
-       PSDocument *gs = PS_DOCUMENT (document);
-       GtkWidget *widget;
-       gpointer data;
-
-       gs->pstarget = target;
-
-       if (gs->pstarget) {
-               gdk_window_get_user_data (gs->pstarget, &data);
-               g_return_if_fail (GTK_IS_WIDGET (data));
-
-               widget = GTK_WIDGET (data);
-               g_signal_connect (widget, "event",
-                                 G_CALLBACK (ps_document_widget_event),
-                                 document);
-       }
-
-       ps_document_goto_page (gs, gs->current_page);
-}
-
 static void
 ps_document_set_scale (EvDocument  *document,
                        double       scale)