Beispiel #1
0
bool
sc_zoom(girara_session_t* session, girara_argument_t* argument, girara_event_t*
        event, unsigned int t)
{
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;
  g_return_val_if_fail(argument != NULL, false);
  g_return_val_if_fail(zathura->document != NULL, false);

  zathura_document_set_adjust_mode(zathura->document, ZATHURA_ADJUST_NONE);

  /* retrieve zoom step value */
  int value = 1;
  girara_setting_get(zathura->ui.session, "zoom-step", &value);

  const int nt = (t == 0) ? 1 : t;
  const double zoom_step = 1.0 + value / 100.0 * nt;
  const double old_zoom = zathura_document_get_scale(zathura->document);

  /* specify new zoom value */
  if (argument->n == ZOOM_IN) {
    girara_debug("Increasing zoom by %f.", zoom_step - 1.0);
    zathura_document_set_scale(zathura->document, old_zoom * zoom_step);
  } else if (argument->n == ZOOM_OUT) {
    girara_debug("Decreasing zoom by %f.", zoom_step - 1.0);
    zathura_document_set_scale(zathura->document, old_zoom / zoom_step);
  } else if (argument->n == ZOOM_SPECIFIC) {
    if (t == 0) {
      girara_debug("Setting zoom to 1.");
      zathura_document_set_scale(zathura->document, 1.0);
    } else {
      girara_debug("Setting zoom to %f.", t / 100.0);
      zathura_document_set_scale(zathura->document, t / 100.0);
    }
  } else if (argument->n == ZOOM_SMOOTH) {
    const double dy = (event != NULL) ? event->y : 1.0;
    girara_debug("Increasing zoom by %f.", zoom_step * dy - 1.0);
    zathura_document_set_scale(zathura->document, old_zoom + zoom_step * dy);
  } else {
    girara_debug("Setting zoom to 1.");
    zathura_document_set_scale(zathura->document, 1.0);
  }

  /* zoom limitations */
  const double scale = zathura_document_get_scale(zathura->document);
  zathura_document_set_scale(zathura->document, zathura_correct_scale_value(session, scale));

  const double new_zoom = zathura_document_get_scale(zathura->document);
  if (fabs(new_zoom - old_zoom) <= DBL_EPSILON) {
    girara_debug("New and old zoom level are too close: %f vs. %f, diff = %f", new_zoom, old_zoom, fabs(new_zoom - old_zoom));
    return false;
  }

  girara_debug("Re-rendering with new zoom level %f.", new_zoom);
  render_all(zathura);
  refresh_view(zathura);

  return false;
}
Beispiel #2
0
bool
sc_zoom(girara_session_t* session, girara_argument_t* argument, girara_event_t*
        UNUSED(event), unsigned int t)
{
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;
  g_return_val_if_fail(argument != NULL, false);
  g_return_val_if_fail(zathura->document != NULL, false);

  zathura_document_set_adjust_mode(zathura->document, ZATHURA_ADJUST_NONE);

  /* retreive zoom step value */
  int value = 1;
  girara_setting_get(zathura->ui.session, "zoom-step", &value);

  int nt = (t == 0) ? 1 : t;
  float zoom_step = value / 100.0f * nt;
  float old_zoom = zathura_document_get_scale(zathura->document);

  /* specify new zoom value */
  if (argument->n == ZOOM_IN) {
    zathura_document_set_scale(zathura->document, old_zoom + zoom_step);
  } else if (argument->n == ZOOM_OUT) {
    zathura_document_set_scale(zathura->document, old_zoom - zoom_step);
  } else if (argument->n == ZOOM_SPECIFIC) {
    if (t == 0) {
      zathura_document_set_scale(zathura->document, 1.0f);
    } else {
      zathura_document_set_scale(zathura->document, t / 100.0f);
    }
  } else {
    zathura_document_set_scale(zathura->document, 1.0f);
  }

  /* zoom limitations */
  int zoom_min_int = 10;
  int zoom_max_int = 1000;
  girara_setting_get(session, "zoom-min", &zoom_min_int);
  girara_setting_get(session, "zoom-max", &zoom_max_int);

  float zoom_min = zoom_min_int * 0.01f;
  float zoom_max = zoom_max_int * 0.01f;

  float scale = zathura_document_get_scale(zathura->document);
  if (scale < zoom_min) {
    zathura_document_set_scale(zathura->document, zoom_min);
  } else if (scale > zoom_max) {
    zathura_document_set_scale(zathura->document, zoom_max);
  }

  /* keep position */
  readjust_view_after_zooming(zathura, old_zoom, true);

  render_all(zathura);

  return false;
}
Beispiel #3
0
bool
sc_jumplist(girara_session_t* session, girara_argument_t* argument, girara_event_t* UNUSED(event), unsigned int UNUSED(t))
{
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;
  g_return_val_if_fail(argument != NULL, false);
  g_return_val_if_fail(zathura->document != NULL, false);

  zathura_jump_t* jump = NULL;
  switch(argument->n) {
    case FORWARD:
      zathura_jumplist_save(zathura);
      zathura_jumplist_forward(zathura);
      jump = zathura_jumplist_current(zathura);
      break;

    case BACKWARD:
      zathura_jumplist_save(zathura);
      zathura_jumplist_backward(zathura);
      jump = zathura_jumplist_current(zathura);
      break;
  }

  if (jump != NULL) {
    page_set(zathura, jump->page);
    const double s = zathura_document_get_scale(zathura->document);
    position_set_delayed(zathura, jump->x * s, jump->y * s);
  }

  return false;
}
Beispiel #4
0
double
page_calc_height_width(zathura_page_t* page, unsigned int* page_height, unsigned int* page_width, bool rotate)
{
  g_return_val_if_fail(page != NULL && page_height != NULL && page_width != NULL, 0.0);

  zathura_document_t* document = zathura_page_get_document(page);
  if (document == NULL) {
    return 0.0;
  }

  double height = zathura_page_get_height(page);
  double width  = zathura_page_get_width(page);
  double scale  = zathura_document_get_scale(document);
  double real_scale;

  if (rotate && zathura_document_get_rotation(document) % 180) {
    *page_width  = ceil(height * scale);
    *page_height = ceil(width  * scale);
    real_scale = MAX(*page_width / height, *page_height / width);
  } else {
    *page_width  = ceil(width  * scale);
    *page_height = ceil(height * scale);
    real_scale = MAX(*page_width / width, *page_height / height);
  }

  return real_scale;
}
Beispiel #5
0
zathura_rectangle_t
recalc_rectangle(zathura_page_t* page, zathura_rectangle_t rectangle)
{
  if (page == NULL) {
    goto error_ret;
  }

  zathura_document_t* document = zathura_page_get_document(page);

  if (document == NULL) {
    goto error_ret;
  }

  double page_height = zathura_page_get_height(page);
  double page_width  = zathura_page_get_width(page);
  double scale       = zathura_document_get_scale(document);

  zathura_rectangle_t tmp = rotate_rectangle(rectangle, zathura_document_get_rotation(document), page_height, page_width);
  tmp.x1 *= scale;
  tmp.x2 *= scale;
  tmp.y1 *= scale;
  tmp.y2 *= scale;

  return tmp;

error_ret:

  return rectangle;
}
Beispiel #6
0
void
cb_view_vadjustment_value_changed(GtkAdjustment* GIRARA_UNUSED(adjustment), gpointer data)
{
  zathura_t* zathura = data;
  if (zathura == NULL || zathura->document == NULL || zathura->ui.page_widget == NULL) {
    return;
  }

  GtkAdjustment* view_vadjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));
  GtkAdjustment* view_hadjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));

  GdkRectangle view_rect;
  /* get current adjustment values */
  view_rect.y      = 0;
  view_rect.height = gtk_adjustment_get_page_size(view_vadjustment);
  view_rect.x      = 0;
  view_rect.width  = gtk_adjustment_get_page_size(view_hadjustment);

  int page_padding = 1;
  girara_setting_get(zathura->ui.session, "page-padding", &page_padding);

  GdkRectangle center;
  center.x = (view_rect.width + 1) / 2;
  center.y = (view_rect.height + 1) / 2;
  center.height = center.width = (2 * page_padding) + 1;

  unsigned int number_of_pages = zathura_document_get_number_of_pages(zathura->document);
  double scale = zathura_document_get_scale(zathura->document);

  bool updated = false;
  /* find page that fits */
  for (unsigned int page_id = 0; page_id < number_of_pages; page_id++) {
    zathura_page_t* page = zathura_document_get_page(zathura->document, page_id);

    GdkRectangle page_rect;
    GtkWidget* page_widget = zathura_page_get_widget(zathura, page);
    gtk_widget_translate_coordinates(page_widget,
        zathura->ui.session->gtk.view, 0, 0, &page_rect.x, &page_rect.y);
    page_rect.width  = zathura_page_get_width(page)  * scale;
    page_rect.height = zathura_page_get_height(page) * scale;

    if (gdk_rectangle_intersect(&view_rect, &page_rect, NULL) == TRUE) {
      zathura_page_set_visibility(page, true);
      if (zathura->global.update_page_number == true && updated == false
          && gdk_rectangle_intersect(&center, &page_rect, NULL) == TRUE) {
        zathura_document_set_current_page_number(zathura->document, page_id);
        updated = true;
      }
    } else {
      zathura_page_set_visibility(page, false);
    }
    zathura_page_widget_update_view_time(ZATHURA_PAGE(page_widget));
  }

  statusbar_page_number_update(zathura);
}
Beispiel #7
0
double
page_calc_height_width(zathura_document_t* document, double height,
                       double width, unsigned int* page_height,
                       unsigned int* page_width, bool rotate)
{
  g_return_val_if_fail(document != NULL && page_height != NULL && page_width != NULL, 0.0);

  double scale = zathura_document_get_scale(document);
  if (rotate && zathura_document_get_rotation(document) % 180) {
    *page_width  = round(height * scale);
    *page_height = round(width  * scale);
    scale = MAX(*page_width / height, *page_height / width);
  } else {
    *page_width  = round(width  * scale);
    *page_height = round(height * scale);
    scale = MAX(*page_width / width, *page_height / height);
  }

  return scale;
}
Beispiel #8
0
void
mark_add(zathura_t* zathura, int key)
{
  if (zathura == NULL || zathura->document == NULL || zathura->global.marks == NULL) {
    return;
  }

  GtkScrolledWindow *window = GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view);
  GtkAdjustment* v_adjustment = gtk_scrolled_window_get_vadjustment(window);
  GtkAdjustment* h_adjustment = gtk_scrolled_window_get_hadjustment(window);

  if (v_adjustment == NULL || h_adjustment == NULL) {
    return;
  }

  double position_x = gtk_adjustment_get_value(h_adjustment);
  double position_y = gtk_adjustment_get_value(v_adjustment);
  float scale       = zathura_document_get_scale(zathura->document);

  /* search for existing mark */
  GIRARA_LIST_FOREACH(zathura->global.marks, zathura_mark_t*, iter, mark)
    if (mark->key == key) {
      mark->position_x = position_x;
      mark->position_y = position_y;
      mark->scale      = scale;
      return;
    }
  GIRARA_LIST_FOREACH_END(zathura->global.marks, zathura_mark_t*, iter, mark);

  /* add new mark */
  zathura_mark_t* mark = g_malloc0(sizeof(zathura_mark_t));

  mark->key        = key;
  mark->position_x = position_x;
  mark->position_y = position_y;
  mark->scale      = scale;

  girara_list_append(zathura->global.marks, mark);
}
Beispiel #9
0
void
mark_evaluate(zathura_t* zathura, int key)
{
  if (zathura == NULL || zathura->global.marks == NULL) {
    return;
  }

  /* search for existing mark */
  GIRARA_LIST_FOREACH(zathura->global.marks, zathura_mark_t*, iter, mark)
    if (mark != NULL && mark->key == key) {
      double old_scale = zathura_document_get_scale(zathura->document);
      zathura_document_set_scale(zathura->document, mark->scale);
      readjust_view_after_zooming(zathura, old_scale, true);
      render_all(zathura);

      position_set_delayed(zathura, mark->position_x, mark->position_y);

      cb_view_vadjustment_value_changed(NULL, zathura);

      zathura->global.update_page_number = true;
      return;
    }
  GIRARA_LIST_FOREACH_END(zathura->global.marks, zathura_mark_t*, iter, mark);
}
Beispiel #10
0
void
zathura_get_document_size(zathura_t* zathura,
                          unsigned int cell_height, unsigned int cell_width,
                          unsigned int* height, unsigned int* width)
{
  g_return_if_fail(zathura != NULL && zathura->document != NULL &&
                   height != NULL && width != NULL);

  unsigned int pages_per_row = 1;
  girara_setting_get(zathura->ui.session, "pages-per-row", &pages_per_row);
  if (pages_per_row == 0)
    pages_per_row = 1;

  unsigned int first_page_column = 1;
  girara_setting_get(zathura->ui.session, "first-page-column", &first_page_column);
  if (first_page_column < 1)
    first_page_column = 1;
  if (first_page_column > pages_per_row)
    first_page_column = (first_page_column - 1) % pages_per_row + 1;

  int padding = 1;
  girara_setting_get(zathura->ui.session, "page-padding", &padding);

  double scale = zathura_document_get_scale(zathura->document);

  cell_height = ceil(cell_height * scale);
  cell_width  = ceil(cell_width * scale);

  *width = pages_per_row * cell_width + (pages_per_row - 1) * padding;
  unsigned int effective_number_of_pages =
    zathura_document_get_number_of_pages(zathura->document) +
    first_page_column - 1;
  unsigned int rows = effective_number_of_pages / pages_per_row +
                     (effective_number_of_pages % pages_per_row ? 1 : 0);
  *height = rows * cell_height + (rows - 1) * padding;
}
Beispiel #11
0
bool
sc_toggle_presentation(girara_session_t* session, girara_argument_t*
                     UNUSED(argument), girara_event_t* UNUSED(event), unsigned int UNUSED(t))
{
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;

  if (zathura->document == NULL) {
    girara_notify(session, GIRARA_WARNING, _("No document opened."));
    return false;
  }

  const girara_mode_t old_mode = girara_mode_get(session);
  if (old_mode == zathura->modes.presentation) {
    /* reset pages per row */
    girara_setting_set(session, "pages-per-row", &zathura->shortcut.toggle_presentation_mode.pages);

    /* reset first page column */
    if (zathura->shortcut.toggle_presentation_mode.first_page_column_list != NULL) {
      girara_setting_set(session, "first-page-column", zathura->shortcut.toggle_presentation_mode.first_page_column_list);
    }

    /* show status bar */
    gtk_widget_show(GTK_WIDGET(session->gtk.statusbar));

    /* set full screen */
    gtk_window_unfullscreen(GTK_WINDOW(session->gtk.window));

    /* reset scale */
    zathura_document_set_scale(zathura->document, zathura->shortcut.toggle_presentation_mode.zoom);
    render_all(zathura);
    refresh_view(zathura);

    /* set mode */
    girara_mode_set(session, zathura->modes.normal);
  } else if (old_mode == zathura->modes.normal) {
    /* backup pages per row */
    girara_setting_get(session, "pages-per-row", &zathura->shortcut.toggle_presentation_mode.pages);

    /* backup first page column */
    g_free(zathura->shortcut.toggle_presentation_mode.first_page_column_list);
    zathura->shortcut.toggle_presentation_mode.first_page_column_list = NULL;
    /* this will leak. we need to move the values somewhere else */
    girara_setting_get(session, "first-page-column", &zathura->shortcut.toggle_presentation_mode.first_page_column_list);

    /* set single view */
    int int_value = 1;
    girara_setting_set(session, "pages-per-row", &int_value);

    /* back up zoom */
    zathura->shortcut.toggle_presentation_mode.zoom = zathura_document_get_scale(zathura->document);

    /* adjust window */
    girara_argument_t argument = { ZATHURA_ADJUST_BESTFIT, NULL };
    sc_adjust_window(session, &argument, NULL, 0);

    /* hide status and inputbar */
    gtk_widget_hide(GTK_WIDGET(session->gtk.inputbar));
    gtk_widget_hide(GTK_WIDGET(session->gtk.statusbar));

    /* set full screen */
    gtk_window_fullscreen(GTK_WINDOW(session->gtk.window));
    refresh_view(zathura);

    /* set mode */
    girara_mode_set(session, zathura->modes.presentation);
  }

  return false;
}
Beispiel #12
0
bool
sc_adjust_window(girara_session_t* session, girara_argument_t* argument,
                 girara_event_t* UNUSED(event), unsigned int UNUSED(t))
{
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;
  g_return_val_if_fail(argument != NULL, false);

  unsigned int pages_per_row = 1;
  girara_setting_get(session, "pages-per-row", &pages_per_row);

  unsigned int first_page_column = 1;
  girara_setting_get(session, "first-page-column", &first_page_column);

  int padding = 1;
  girara_setting_get(zathura->ui.session, "page-padding", &padding);

  if (zathura->ui.page_widget == NULL || zathura->document == NULL) {
    goto error_ret;
  }

  float old_zoom = zathura_document_get_scale(zathura->document);
  zathura_document_set_adjust_mode(zathura->document, argument->n);
  if (argument->n == ZATHURA_ADJUST_NONE) {
    /* there is nothing todo */
    goto error_ret;
  }

  /* get window size */
  GtkAllocation allocation;
  gtk_widget_get_allocation(session->gtk.view, &allocation);
  unsigned int width  = allocation.width;
  unsigned int height = allocation.height;

  /* scrollbar spacing */
  gint spacing;
  gtk_widget_style_get(session->gtk.view, "scrollbar_spacing", &spacing, NULL);
  width -= spacing;

  /* correct view size */
  if (gtk_widget_get_visible(GTK_WIDGET(session->gtk.inputbar)) == true) {
    gtk_widget_get_allocation(session->gtk.inputbar, &allocation);
    height += allocation.height;
  }

  double scale = 1.0;
  unsigned int cell_height = 0, cell_width = 0;
  unsigned int document_height = 0, document_width = 0;

  zathura_document_set_scale(zathura->document, scale);
  zathura_document_get_cell_size(zathura->document, &cell_height, &cell_width);
  zathura_get_document_size(zathura, cell_height, cell_width,
                            &document_height, &document_width);

  double page_ratio   = (double)cell_height / (double)document_width;
  double window_ratio = (double)height / (double)width;

  if (argument->n == ZATHURA_ADJUST_WIDTH ||
      (argument->n == ZATHURA_ADJUST_BESTFIT && page_ratio < window_ratio)) {
    scale = (double)(width - (pages_per_row - 1) * padding) /
            (double)(pages_per_row * cell_width);
    zathura_document_set_scale(zathura->document, scale);

    bool show_scrollbars = false;
    girara_setting_get(session, "show-scrollbars", &show_scrollbars);

    if (show_scrollbars) {
      /* If the document is taller than the view, there's a vertical
       * scrollbar; we need to substract its width from the view's width. */
      zathura_get_document_size(zathura, cell_height, cell_width,
                                &document_height, &document_width);
      if (height < document_height) {
        GtkWidget* vscrollbar = gtk_scrolled_window_get_vscrollbar(
            GTK_SCROLLED_WINDOW(session->gtk.view));

        if (vscrollbar != NULL) {
          GtkRequisition requisition;
          gtk_widget_get_requisition(vscrollbar, &requisition);
          if (0 < requisition.width && (unsigned)requisition.width < width) {
            width -= requisition.width;
            scale = (double)(width - (pages_per_row - 1) * padding) /
                    (double)(pages_per_row * cell_width);
            zathura_document_set_scale(zathura->document, scale);
          }
        }
      }
    }
  }
  else if (argument->n == ZATHURA_ADJUST_BESTFIT) {
    scale = (double)height / (double)cell_height;
    zathura_document_set_scale(zathura->document, scale);
  }
  else {
    goto error_ret;
  }

  /* keep position */
  readjust_view_after_zooming(zathura, old_zoom, false);

  /* re-render all pages */
  render_all(zathura);

error_ret:

  return false;
}
Beispiel #13
0
zathura_image_buffer_t*
djvu_page_render(zathura_page_t* page, void* UNUSED(data), zathura_error_t* error)
{
  if (page == NULL) {
    if (error != NULL) {
      *error = ZATHURA_ERROR_INVALID_ARGUMENTS;
    }
    return NULL;
  }
 
  zathura_document_t* document = zathura_page_get_document(page);
  if (document == NULL) {
    return NULL;
  }

  /* calculate sizes */
  unsigned int page_width  = zathura_document_get_scale(document) * zathura_page_get_width(page);
  unsigned int page_height = zathura_document_get_scale(document) * zathura_page_get_height(page);

  if (page_width == 0 || page_height == 0) {
    if (error != NULL) {
      *error = ZATHURA_ERROR_UNKNOWN;
    }
    goto error_out;
  }

  /* init ddjvu render data */
  djvu_document_t* djvu_document = zathura_document_get_data(document);
  ddjvu_page_t* djvu_page        = ddjvu_page_create_by_pageno(
      djvu_document->document, zathura_page_get_index(page));

  if (djvu_page == NULL) {
    if (error != NULL) {
      *error = ZATHURA_ERROR_UNKNOWN;
    }
    goto error_out;
  }

  while (!ddjvu_page_decoding_done(djvu_page)) {
    handle_messages(djvu_document, true);
  }

  ddjvu_rect_t rrect = { 0, 0, page_width, page_height };
  ddjvu_rect_t prect = { 0, 0, page_width, page_height };

  zathura_image_buffer_t* image_buffer =
    zathura_image_buffer_create(page_width, page_height);

  if (image_buffer == NULL) {
    if (error != NULL) {
      *error = ZATHURA_ERROR_OUT_OF_MEMORY;
    }
    goto error_free;
  }

  /* set rotation */
  ddjvu_page_set_rotation(djvu_page, DDJVU_ROTATE_0);

  /* render page */
  ddjvu_page_render(djvu_page, DDJVU_RENDER_COLOR, &prect, &rrect,
      djvu_document->format, 3 * page_width, (char*) image_buffer->data);

  return image_buffer;

error_free:

    ddjvu_page_release(djvu_page);
    zathura_image_buffer_free(image_buffer);

error_out:

  return NULL;
}
Beispiel #14
0
bool
sc_toggle_fullscreen(girara_session_t* session, girara_argument_t*
                     UNUSED(argument), girara_event_t* UNUSED(event), unsigned int UNUSED(t))
{
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;

  if (zathura->document == NULL) {
    girara_notify(session, GIRARA_WARNING, _("No document opened."));
    return false;
  }

  static bool fullscreen = false;
  static int pages_per_row = 1;
  static int first_page_column = 1;
  static double zoom = 1.0;

  if (fullscreen == true) {
    /* reset pages per row */
    girara_setting_set(session, "pages-per-row", &pages_per_row);

    /* reset first page column */
    girara_setting_set(session, "first-page-column", &first_page_column);

    /* show status bar */
    gtk_widget_show(GTK_WIDGET(session->gtk.statusbar));

    /* set full screen */
    gtk_window_unfullscreen(GTK_WINDOW(session->gtk.window));

    /* reset scale */
    zathura_document_set_scale(zathura->document, zoom);
    render_all(zathura);
    page_set_delayed(zathura, zathura_document_get_current_page_number(zathura->document));

    /* setm ode */
    girara_mode_set(session, zathura->modes.normal);
  } else {
    /* backup pages per row */
    girara_setting_get(session, "pages-per-row", &pages_per_row);

    /* backup first page column */
    girara_setting_get(session, "first-page-column", &first_page_column);

    /* set single view */
    int int_value = 1;
    girara_setting_set(session, "pages-per-row", &int_value);

    /* back up zoom */
    zoom = zathura_document_get_scale(zathura->document);

    /* adjust window */
    girara_argument_t argument = { ZATHURA_ADJUST_BESTFIT, NULL };
    sc_adjust_window(session, &argument, NULL, 0);

    /* hide status and inputbar */
    gtk_widget_hide(GTK_WIDGET(session->gtk.inputbar));
    gtk_widget_hide(GTK_WIDGET(session->gtk.statusbar));

    /* set full screen */
    gtk_window_fullscreen(GTK_WINDOW(session->gtk.window));
    page_set_delayed(zathura, zathura_document_get_current_page_number(zathura->document));

    /* setm ode */
    girara_mode_set(session, zathura->modes.fullscreen);
  }

  fullscreen = fullscreen ? false : true;

  return false;
}
Beispiel #15
0
void
cb_view_vadjustment_value_changed(GtkAdjustment* GIRARA_UNUSED(adjustment), gpointer data)
{
  zathura_t* zathura = data;
  if (zathura == NULL || zathura->document == NULL || zathura->ui.page_widget == NULL) {
    return;
  }

  GtkAdjustment* view_vadjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));
  GtkAdjustment* view_hadjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));

  /* current adjustment values */
  GdkRectangle view_rect = {
    .x      = 0,
    .y      = 0,
    .width  = gtk_adjustment_get_page_size(view_hadjustment),
    .height = gtk_adjustment_get_page_size(view_vadjustment)
  };

  int page_padding = 1;
  girara_setting_get(zathura->ui.session, "page-padding", &page_padding);

  GdkRectangle center = {
    .x      = (view_rect.width  + 1) / 2,
    .y      = (view_rect.height + 1) / 2,
    .width  = (2 * page_padding) + 1,
    .height = (2 * page_padding) + 1
  };

  unsigned int number_of_pages = zathura_document_get_number_of_pages(zathura->document);
  double scale = zathura_document_get_scale(zathura->document);

  bool updated = false;
  /* find page that fits */
  for (unsigned int page_id = 0; page_id < number_of_pages; page_id++) {
    zathura_page_t* page = zathura_document_get_page(zathura->document, page_id);

    GdkRectangle page_rect = {
      .width  = zathura_page_get_width(page)  * scale,
      .height = zathura_page_get_height(page) * scale
    };
    GtkWidget* page_widget = zathura_page_get_widget(zathura, page);
    gtk_widget_translate_coordinates(page_widget,
                                     zathura->ui.session->gtk.view, 0, 0, &page_rect.x, &page_rect.y);

    if (gdk_rectangle_intersect(&view_rect, &page_rect, NULL) == TRUE) {
      zathura_page_set_visibility(page, true);
      if (zathura->global.update_page_number == true && updated == false
          && gdk_rectangle_intersect(&center, &page_rect, NULL) == TRUE) {
        zathura_document_set_current_page_number(zathura->document, page_id);
        updated = true;
      }
    } else {
      zathura_page_set_visibility(page, false);
    }
    zathura_page_widget_update_view_time(ZATHURA_PAGE(page_widget));
  }

  statusbar_page_number_update(zathura);
}

void
cb_pages_per_row_value_changed(girara_session_t* session, const char* UNUSED(name), girara_setting_type_t UNUSED(type), void* value, void* UNUSED(data))
{
  g_return_if_fail(value != NULL);
  g_return_if_fail(session != NULL);
  g_return_if_fail(session->global.data != NULL);
  zathura_t* zathura = session->global.data;

  int pages_per_row = *(int*) value;

  if (pages_per_row < 1) {
    pages_per_row = 1;
  }

  unsigned int first_page_column = 1;
  girara_setting_get(session, "first-page-column", &first_page_column);

  page_widget_set_mode(zathura, pages_per_row, first_page_column);

  if (zathura->document != NULL) {
    unsigned int current_page = zathura_document_get_current_page_number(zathura->document);
    page_set_delayed(zathura, current_page);
  }
}
Beispiel #16
0
bool
sc_scroll(girara_session_t* session, girara_argument_t* argument,
          girara_event_t* UNUSED(event), unsigned int UNUSED(t))
{
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;
  g_return_val_if_fail(argument != NULL, false);
  if (zathura->document == NULL) {
    return false;
  }

  GtkAdjustment* adjustment = NULL;
  if ( (argument->n == LEFT) || (argument->n == FULL_LEFT) || (argument->n == HALF_LEFT) ||
       (argument->n == RIGHT) || (argument->n == FULL_RIGHT) || (argument->n == HALF_RIGHT)) {
    adjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(session->gtk.view));
  } else {
    adjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(session->gtk.view));
  }

  gdouble view_size                  = gtk_adjustment_get_page_size(adjustment);
  gdouble value                      = gtk_adjustment_get_value(adjustment);
  gdouble max                        = gtk_adjustment_get_upper(adjustment) - view_size;
  zathura->global.update_page_number = true;

  float scroll_step = 40;
  girara_setting_get(session, "scroll-step", &scroll_step);
  float scroll_hstep = -1;
  girara_setting_get(session, "scroll-hstep", &scroll_hstep);
  if (scroll_hstep < 0) {
    scroll_hstep = scroll_step;
  }
  float scroll_full_overlap = 0.0;
  girara_setting_get(session, "scroll-full-overlap", &scroll_full_overlap);
  bool scroll_page_aware = false;
  girara_setting_get(session, "scroll-page-aware", &scroll_page_aware);

  bool scroll_wrap = false;
  girara_setting_get(session, "scroll-wrap", &scroll_wrap);

  int padding = 1;
  girara_setting_get(session, "page-padding", &padding);

  gdouble new_value;

  switch(argument->n) {
    case FULL_UP:
    case FULL_LEFT:
      new_value = value - (1.0 - scroll_full_overlap) * view_size - padding;
      break;
    case FULL_DOWN:
    case FULL_RIGHT:
      new_value = value + (1.0 - scroll_full_overlap) * view_size + padding;
      break;
    case HALF_UP:
    case HALF_LEFT:
      new_value = value - ((view_size + padding) / 2);
      break;
    case HALF_DOWN:
    case HALF_RIGHT:
      new_value = value + ((view_size + padding) / 2);
      break;
    case LEFT:
      new_value = value - scroll_hstep;
      break;
    case UP:
      new_value = value - scroll_step;
      break;
    case RIGHT:
      new_value = value + scroll_hstep;
      break;
    case DOWN:
      new_value = value + scroll_step;
      break;
    case TOP:
      new_value = 0;
      break;
    case BOTTOM:
      new_value = max;
      break;
    default:
      new_value = value;
  }

  if (scroll_wrap == true) {
    if (new_value < 0)
      new_value = max;
    else if (new_value > max)
      new_value = 0;
  }

  if (scroll_page_aware == true) {
    int page_offset;
    double page_size;

    {
      unsigned int page_id = zathura_document_get_current_page_number(zathura->document);
      zathura_page_t* page = zathura_document_get_page(zathura->document, page_id);
      page_offset_t offset;
      page_calculate_offset(zathura, page, &offset);

      double scale = zathura_document_get_scale(zathura->document);

      if ((argument->n == LEFT) || (argument->n == FULL_LEFT) || (argument->n == HALF_LEFT) ||
          (argument->n == RIGHT) || (argument->n == FULL_RIGHT) || (argument->n == HALF_RIGHT)) {
        page_offset = offset.x;
        page_size = zathura_page_get_width(page) * scale;
      } else {
        page_offset = offset.y;
        page_size = zathura_page_get_height(page) * scale;
      }

      page_offset -= padding / 2;
      page_size   += padding;
    }

    if ((argument->n == FULL_DOWN) || (argument->n == HALF_DOWN) ||
        (argument->n == FULL_RIGHT) || (argument->n == HALF_RIGHT)) {
      if ((page_offset > value) &&
          (page_offset < value + view_size)) {
        new_value = page_offset;
      } else if ((page_offset <= value) &&
                 (page_offset + page_size < value + view_size)) {
        new_value = page_offset + page_size + 1;
      } else if ((page_offset <= value) &&
                 (page_offset + page_size < new_value + view_size)) {
        new_value = page_offset + page_size - view_size + 1;
      }
    } else if ((argument->n == FULL_UP) || (argument->n == HALF_UP) ||
               (argument->n == FULL_LEFT) || (argument->n == HALF_LEFT)) {
      if ((page_offset + 1 >= value) &&
          (page_offset < value + view_size)) {
        new_value = page_offset - view_size;
      } else if ((page_offset <= value) &&
                 (page_offset + page_size + 1 < value + view_size)) {
        new_value = page_offset + page_size - view_size;
      } else if ((page_offset <= value) &&
                 (page_offset > new_value)) {
        new_value = page_offset;
      }
    }
  }

  set_adjustment(adjustment, new_value);

  return false;
}
Beispiel #17
0
static bool
render(zathura_t* zathura, zathura_page_t* page)
{
  if (zathura == NULL || page == NULL || zathura->sync.render_thread->about_to_close == true) {
    return false;
  }

  /* create cairo surface */
  unsigned int page_width  = 0;
  unsigned int page_height = 0;
  page_calc_height_width(page, &page_height, &page_width, false);

  cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, page_width, page_height);

  if (surface == NULL) {
    return false;
  }

  cairo_t* cairo = cairo_create(surface);

  if (cairo == NULL) {
    cairo_surface_destroy(surface);
    return false;
  }

  cairo_save(cairo);
  cairo_set_source_rgb(cairo, 1, 1, 1);
  cairo_rectangle(cairo, 0, 0, page_width, page_height);
  cairo_fill(cairo);
  cairo_restore(cairo);
  cairo_save(cairo);

  double scale = zathura_document_get_scale(zathura->document);
  if (fabs(scale - 1.0f) > FLT_EPSILON) {
    cairo_scale(cairo, scale, scale);
  }

  render_lock(zathura->sync.render_thread);
  if (zathura_page_render(page, cairo, false) != ZATHURA_ERROR_OK) {
    render_unlock(zathura->sync.render_thread);
    cairo_destroy(cairo);
    cairo_surface_destroy(surface);
    return false;
  }

  render_unlock(zathura->sync.render_thread);
  cairo_restore(cairo);
  cairo_destroy(cairo);

  const int rowstride  = cairo_image_surface_get_stride(surface);
  unsigned char* image = cairo_image_surface_get_data(surface);

  /* recolor */
  /* uses a representation of a rgb color as follows:
     - a lightness scalar (between 0,1), which is a weighted average of r, g, b,
     - a hue vector, which indicates a radian direction from the grey axis, inside the equal lightness plane.
     - a saturation scalar between 0,1. It is 0 when grey, 1 when the color is in the boundary of the rgb cube.
  */
  if (zathura->global.recolor == true) {
    /* RGB weights for computing lightness. Must sum to one */
    double a[] = {0.30, 0.59, 0.11};

    double l1, l2, l, s, u, t;
    double h[3];
    double rgb1[3], rgb2[3], rgb[3];

    color2double(&zathura->ui.colors.recolor_dark_color, rgb1);
    color2double(&zathura->ui.colors.recolor_light_color, rgb2);

    l1 = (a[0]*rgb1[0] + a[1]*rgb1[1] + a[2]*rgb1[2]);
    l2 = (a[0]*rgb2[0] + a[1]*rgb2[1] + a[2]*rgb2[2]);

    for (unsigned int y = 0; y < page_height; y++) {
      unsigned char* data = image + y * rowstride;

      for (unsigned int x = 0; x < page_width; x++) {
        /* Careful. data color components blue, green, red. */
        rgb[0] = (double) data[2] / 256.;
        rgb[1] = (double) data[1] / 256.;
        rgb[2] = (double) data[0] / 256.;

        /* compute h, s, l data   */
        l = a[0]*rgb[0] + a[1]*rgb[1] + a[2]*rgb[2];

        h[0] = rgb[0] - l;
        h[1] = rgb[1] - l;
        h[2] = rgb[2] - l;

        /* u is the maximum possible saturation for given h and l. s is a rescaled saturation between 0 and 1 */
        u = colorumax(h, l, 0, 1);
        if (u == 0) {
          s = 0;
        } else {
          s = 1/u;
        }

        /* Interpolates lightness between light and dark colors. white goes to light, and black goes to dark. */
        t = l;
        l = t * (l2 - l1) + l1;

        if (zathura->global.recolor_keep_hue == true) {
          /* adjusting lightness keeping hue of current color. white and black go to grays of same ligtness
             as light and dark colors. */
          u = colorumax(h, l, l1, l2);
          data[2] = (unsigned char)round(255.*(l + s*u * h[0]));
          data[1] = (unsigned char)round(255.*(l + s*u * h[1]));
          data[0] = (unsigned char)round(255.*(l + s*u * h[2]));
        } else {
          /* Linear interpolation between dark and light with color ligtness as a parameter */
          data[2] = (unsigned char)round(255.*(t * (rgb2[0] - rgb1[0]) + rgb1[0]));
          data[1] = (unsigned char)round(255.*(t * (rgb2[1] - rgb1[1]) + rgb1[1]));
          data[0] = (unsigned char)round(255.*(t * (rgb2[2] - rgb1[2]) + rgb1[2]));
        }

        data += 4;
      }
    }
  }

  if (zathura->sync.render_thread->about_to_close == false) {
    /* update the widget */
    gdk_threads_enter();
    GtkWidget* widget = zathura_page_get_widget(zathura, page);
    zathura_page_widget_update_surface(ZATHURA_PAGE(widget), surface);
    gdk_threads_leave();
  } else {
    cairo_surface_destroy(surface);
  }

  return true;
}