コード例 #1
0
ファイル: utils.c プロジェクト: aroig/zathura
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;
}
コード例 #2
0
ファイル: utils.c プロジェクト: MaximeCheramy/zathura
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;
}
コード例 #3
0
ファイル: page.c プロジェクト: pwmt/zathura-ps
zathura_error_t
ps_page_init(zathura_page_t* page, SpectrePage* spectre_page)
{
  if (page == NULL) {
    return ZATHURA_ERROR_INVALID_ARGUMENTS;
  }

  zathura_document_t* document      = zathura_page_get_document(page);
  SpectreDocument* spectre_document = zathura_document_get_data(document);

  SpectrePage* ps_page = spectre_document_get_page(spectre_document, zathura_page_get_index(page));
  if (ps_page == NULL) {
    return ZATHURA_ERROR_UNKNOWN;
  }

  int page_width;
  int page_height;
  spectre_page_get_size(ps_page, &(page_width), &(page_height));

  zathura_page_set_width(page, page_width);
  zathura_page_set_height(page, page_height);
  zathura_page_set_data(page, ps_page);

  return ZATHURA_ERROR_OK;
}
コード例 #4
0
zathura_error_t
djvu_page_init(zathura_page_t* page, void* UNUSED(data))
{
  if (page == NULL) {
    return ZATHURA_ERROR_INVALID_ARGUMENTS;
  }

  zathura_document_t* document   = zathura_page_get_document(page);
  djvu_document_t* djvu_document = zathura_document_get_data(document);

  ddjvu_status_t status;
  ddjvu_pageinfo_t page_info;

  unsigned int index = zathura_page_get_index(page);
  while ((status = ddjvu_document_get_pageinfo(djvu_document->document, index,
          &page_info)) < DDJVU_JOB_OK) {
    handle_messages(djvu_document, true);
  }

  if (status >= DDJVU_JOB_FAILED) {
    handle_messages(djvu_document, true);
    return ZATHURA_ERROR_UNKNOWN;
  }

  zathura_page_set_width(page,  ZATHURA_DJVU_SCALE * page_info.width);
  zathura_page_set_height(page, ZATHURA_DJVU_SCALE * page_info.height);

  return ZATHURA_ERROR_OK;
}
コード例 #5
0
zathura_error_t
djvu_page_render_cairo(zathura_page_t* page, void* UNUSED(data), cairo_t* cairo,
    bool GIRARA_UNUSED(printing))
{
  if (page == NULL || cairo == NULL) {
    return ZATHURA_ERROR_INVALID_ARGUMENTS;
  }

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

  /* 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) {
    return ZATHURA_ERROR_UNKNOWN;
  }

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

  cairo_surface_t* surface = cairo_get_target(cairo);

  if (surface == NULL ||
      cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS ||
      cairo_surface_get_type(surface) != CAIRO_SURFACE_TYPE_IMAGE) {
    ddjvu_page_release(djvu_page);
    return ZATHURA_ERROR_UNKNOWN;
  }

  unsigned int page_width  = cairo_image_surface_get_width(surface);
  unsigned int page_height = cairo_image_surface_get_height(surface);;

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

  char* surface_data = (char*) cairo_image_surface_get_data(surface);

  if (surface_data == NULL) {
    ddjvu_page_release(djvu_page);
    return ZATHURA_ERROR_UNKNOWN;
  }

  /* render page */
  ddjvu_page_render(djvu_page, DDJVU_RENDER_COLOR, &prect, &rrect,
      djvu_document->format, cairo_image_surface_get_stride(surface), surface_data);

  ddjvu_page_release(djvu_page);

  return ZATHURA_ERROR_OK;
}
コード例 #6
0
ファイル: synctex.c プロジェクト: Louisvh/zathura
void
synctex_edit(const char* editor, zathura_page_t* page, int x, int y)
{
  if (editor == NULL || page == NULL) {
    return;
  }

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

  const char* filename = zathura_document_get_path(document);
  if (filename == NULL) {
    return;
  }

  unsigned int line = 0;
  unsigned int column = 0;
  char* input_file = NULL;

  if (synctex_get_input_line_column(filename, zathura_page_get_index(page), x, y,
        &input_file, &line, &column) == true) {
    char* linestr = g_strdup_printf("%d", line);
    char* columnstr = g_strdup_printf("%d", column);

    gchar** argv = NULL;
    gint    argc = 0;
    if (g_shell_parse_argv(editor, &argc, &argv, NULL) == TRUE) {
      for (gint i = 0; i != argc; ++i) {
        char* temp = girara_replace_substring(argv[i], "%{line}", linestr);
        g_free(argv[i]);
        argv[i] = temp;
        temp = girara_replace_substring(argv[i], "%{column}", columnstr);
        g_free(argv[i]);
        argv[i] = temp;
        temp = girara_replace_substring(argv[i], "%{input}", input_file);
        g_free(argv[i]);
        argv[i] = temp;
      }

      g_spawn_async(NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, NULL);
      g_strfreev(argv);
    }

    g_free(linestr);
    g_free(columnstr);

    g_free(input_file);
  }
}
コード例 #7
0
girara_list_t*
djvu_page_search_text(zathura_page_t* page, void* UNUSED(data), const char* text, zathura_error_t* error)
{
  if (page == NULL || text == NULL || strlen(text) == 0) {
    if (error != NULL) {
      *error = ZATHURA_ERROR_INVALID_ARGUMENTS;
    }
    goto error_ret;
  }

  zathura_document_t* document = zathura_page_get_document(page);
  if (document == NULL) {
    goto error_ret;
  }

  djvu_document_t* djvu_document = zathura_document_get_data(document);

  djvu_page_text_t* page_text = djvu_page_text_new(djvu_document, page);
  if (page_text == NULL) {
    goto error_ret;
  }

  girara_list_t* results = djvu_page_text_search(page_text, text);
  if (results == NULL) {
    goto error_free;
  }

  djvu_page_text_free(page_text);

  return results;

error_free:

  if (page_text != NULL) {
    djvu_page_text_free(page_text);
  }

error_ret:

  if (error != NULL && *error == ZATHURA_ERROR_OK) {
    *error = ZATHURA_ERROR_UNKNOWN;
  }

  return NULL;
}
コード例 #8
0
ファイル: synctex.c プロジェクト: rschatz/zathura-synctex
void
synctex_edit(zathura_t* zathura, zathura_page_t* page, int x, int y)
{
  zathura_document_t* doc = zathura_page_get_document(page);
  const char *filename = zathura_document_get_path(doc);
  int pageIdx = zathura_page_get_index(page);

  char *buffer = g_strdup_printf("%d:%d:%d:%s", pageIdx+1, x, y, filename);
  if (buffer == NULL)
    return;

  if (zathura->synctex.editor) {
    char* argv[] = {"synctex", "edit", "-o", buffer, "-x", zathura->synctex.editor, NULL};
    g_spawn_async(NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, NULL);
  } else {
    char* argv[] = {"synctex", "edit", "-o", buffer, NULL};
    g_spawn_async(NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, NULL);
  }

  g_free(buffer);
}
コード例 #9
0
ファイル: render.c プロジェクト: FSX/zathura-cb
zathura_error_t
cb_page_render_cairo(zathura_page_t* page, cb_page_t* cb_page,
    cairo_t* cairo, bool printing)
{
  if (page == NULL || cb_page == NULL || cairo == NULL) {
    return ZATHURA_ERROR_INVALID_ARGUMENTS;
  }

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

  GdkPixbuf* pixbuf = load_pixbuf_from_archive(zathura_document_get_path(document), cb_page->file);
  if (pixbuf == NULL) {
    return ZATHURA_ERROR_UNKNOWN;
  }

  gdk_cairo_set_source_pixbuf(cairo, pixbuf, 0, 0);
  cairo_paint(cairo);
  g_object_unref(pixbuf);

  return ZATHURA_ERROR_OK;
}
コード例 #10
0
ファイル: select.c プロジェクト: pwmt/zathura-pdf-mupdf
char*
pdf_page_get_text(zathura_page_t* page, void* data, zathura_rectangle_t rectangle, zathura_error_t* error)
{
  mupdf_page_t* mupdf_page = data;

  if (page == NULL || mupdf_page == NULL || mupdf_page->text == NULL) {
    if (error != NULL) {
      *error = ZATHURA_ERROR_INVALID_ARGUMENTS;
    }
    goto error_ret;
  }

  zathura_document_t* document     = zathura_page_get_document(page);
  mupdf_document_t* mupdf_document = zathura_document_get_data(document);

  if (mupdf_page->extracted_text == false) {
    mupdf_page_extract_text(mupdf_document, mupdf_page);
  }

  fz_point a = { rectangle.x1, rectangle.y1 };
  fz_point b = { rectangle.x2, rectangle.y2 };

#ifdef _WIN32
  return fz_copy_selection(mupdf_page->ctx, mupdf_page->text, a, b, 1);
#else
  return fz_copy_selection(mupdf_page->ctx, mupdf_page->text, a, b, 0);
#endif

error_ret:

  if (error != NULL && *error == ZATHURA_ERROR_OK) {
    *error = ZATHURA_ERROR_UNKNOWN;
  }

  return NULL;
}
コード例 #11
0
ファイル: image.c プロジェクト: pwmt/zathura-pdf-mupdf
girara_list_t*
pdf_page_images_get(zathura_page_t* page, void* data, zathura_error_t* error)
{
  mupdf_page_t* mupdf_page = data;

  if (page == NULL) {
    if (error != NULL) {
      *error = ZATHURA_ERROR_INVALID_ARGUMENTS;
    }
    goto error_ret;
  }

  girara_list_t* list = NULL;
  zathura_document_t* document = zathura_page_get_document(page);
  if (document == NULL) {
    goto error_ret;
  }

  mupdf_document_t* mupdf_document = zathura_document_get_data(document);

  /* Setup image list */
  list = girara_list_new();
  if (list == NULL) {
    if (error != NULL) {
      *error = ZATHURA_ERROR_OUT_OF_MEMORY;
    }
    goto error_free;
  }

  girara_list_set_free_function(list, (girara_free_function_t) pdf_zathura_image_free);

  /* Extract images */
  mupdf_page_extract_text(mupdf_document, mupdf_page);

  fz_stext_block* block;
  for (block = mupdf_page->text->first_block; block; block = block->next) {
    if (block->type == FZ_STEXT_BLOCK_IMAGE) {
      zathura_image_t* zathura_image = g_malloc(sizeof(zathura_image_t));

      zathura_image->position.x1 = block->bbox.x0;
      zathura_image->position.y1 = block->bbox.y0;
      zathura_image->position.x2 = block->bbox.x1;
      zathura_image->position.y2 = block->bbox.y1;
      zathura_image->data        = block->u.i.image;

      girara_list_append(list, zathura_image);
    }
  }

  return list;

error_free:

  if (error != NULL && *error == ZATHURA_ERROR_OK) {
    *error = ZATHURA_ERROR_UNKNOWN;
  }

  if (list != NULL) {
    girara_list_free(list);
  }

error_ret:

  return NULL;
}
コード例 #12
0
ファイル: synctex.c プロジェクト: MaximeCheramy/zathura
void
synctex_edit(zathura_t* zathura, zathura_page_t* page, int x, int y)
{
  if (zathura == NULL || page == NULL || zathura->synctex.editor == NULL) {
    return;
  }

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

  const char *filename = zathura_document_get_path(document);
  if (filename == NULL) {
    return;
  }

  synctex_scanner_t scanner = synctex_scanner_new_with_output_file(filename, NULL, 1);
  if (scanner == NULL) {
    girara_debug("Failed to create synctex scanner.");
    return;
  }

  synctex_scanner_t temp = synctex_scanner_parse(scanner);
  if (temp == NULL) {
    girara_debug("Failed to parse synctex file.");
    synctex_scanner_free(scanner);
    return;
  }

  if (synctex_edit_query(scanner, zathura_page_get_index(page) + 1, x, y) > 0) {
    /* Assume that a backward search returns either at most one result. */
    synctex_node_t node = synctex_next_result(scanner);
    if (node != NULL) {
      const char* input_file = synctex_scanner_get_name(scanner, synctex_node_tag(node));
      const int line = synctex_node_line(node);
      const int column = synctex_node_column (node);

      char* linestr = g_strdup_printf("%d", line);
      char* columnstr = g_strdup_printf("%d", column);

      gchar** argv = NULL;
      gint    argc = 0;
      if (g_shell_parse_argv(zathura->synctex.editor, &argc, &argv, NULL) == TRUE) {
        for (gint i = 0; i != argc; ++i) {
          char* temp = girara_replace_substring(argv[i], "%{line}", linestr);
          g_free(argv[i]);
          argv[i] = temp;
          temp = girara_replace_substring(argv[i], "%{column}", columnstr);
          g_free(argv[i]);
          argv[i] = temp;
          temp = girara_replace_substring(argv[i], "%{input}", input_file);
          g_free(argv[i]);
          argv[i] = temp;
        }

        g_spawn_async(NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, NULL);
        g_strfreev(argv);
      }

      g_free(linestr);
      g_free(columnstr);
    }
  }

  synctex_scanner_free(scanner);
}
コード例 #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;
}
コード例 #14
0
girara_list_t*
djvu_page_links_get(zathura_page_t* page, void* UNUSED(data), zathura_error_t* error)
{
  if (page == NULL) {
    if (error != NULL) {
      *error = ZATHURA_ERROR_INVALID_ARGUMENTS;
    }
    goto error_ret;
  }

  zathura_document_t* document = zathura_page_get_document(page);
  if (document == NULL) {
    goto error_ret;
  }

  girara_list_t* list = girara_list_new2((girara_free_function_t) zathura_link_free);
  if (list == NULL) {
    if (error != NULL) {
      *error = ZATHURA_ERROR_OUT_OF_MEMORY;
    }
    goto error_ret;
  }

  djvu_document_t* djvu_document = zathura_document_get_data(document);

  miniexp_t annotations = miniexp_nil;
  while ((annotations = ddjvu_document_get_pageanno(djvu_document->document,
          zathura_page_get_index(page))) == miniexp_dummy) {
    handle_messages(djvu_document, true);
  }

  if (annotations == miniexp_nil) {
    goto error_free;
  }

  miniexp_t* hyperlinks = ddjvu_anno_get_hyperlinks(annotations);
  for (miniexp_t* iter = hyperlinks; *iter != NULL; iter++) {
    if (miniexp_car(*iter) != miniexp_symbol("maparea")) {
      continue;
    }

    miniexp_t inner = miniexp_cdr(*iter);

    /* extract url information */
    const char* target_string = NULL;

    if (miniexp_caar(inner) == miniexp_symbol("url")) {
      if (exp_to_str(miniexp_caddr(miniexp_car(inner)), &target_string) == false) {
        continue;
      }
    } else {
      if (exp_to_str(miniexp_car(inner), &target_string) == false) {
        continue;
      }
    }

    /* skip comment */
    inner = miniexp_cdr(inner);

    /* extract link area */
    inner = miniexp_cdr(inner);

    zathura_rectangle_t rect = { 0, 0, 0, 0 };
    if (exp_to_rect(miniexp_car(inner), &rect) == false) {
      continue;
    }

    /* update rect */
    unsigned int page_height = zathura_page_get_height(page) / ZATHURA_DJVU_SCALE;
    rect.x1 = rect.x1 * ZATHURA_DJVU_SCALE;
    rect.x2 = rect.x2 * ZATHURA_DJVU_SCALE;
    double tmp = rect.y1;
    rect.y1 = (page_height - rect.y2) * ZATHURA_DJVU_SCALE;
    rect.y2 = (page_height - tmp)     * ZATHURA_DJVU_SCALE;

    /* create zathura link */
    zathura_link_type_t type = ZATHURA_LINK_INVALID;
    zathura_link_target_t target = { ZATHURA_LINK_DESTINATION_UNKNOWN, NULL, 0, -1, -1, -1, -1, 0 };;

    /* goto page */
    if (target_string[0] == '#' && target_string[1] == 'p') {
      type = ZATHURA_LINK_GOTO_DEST;
      target.page_number = atoi(target_string + 2) - 1;
    /* url or other? */
    } else if (strstr(target_string, "//") != NULL) {
      type = ZATHURA_LINK_URI;
      target.value = (char*) target_string;
    /* TODO: Parse all different links */
    } else {
      continue;
    }

    zathura_link_t* link = zathura_link_new(type, rect, target);
    if (link != NULL) {
      girara_list_append(list, link);
    }
  }

  return list;

error_free:

  if (list != NULL) {
    girara_list_free(list);
  }

error_ret:

  return NULL;
}
コード例 #15
0
char*
djvu_page_get_text(zathura_page_t* page, void* UNUSED(data), zathura_rectangle_t
    rectangle, zathura_error_t* error)
{
  if (page == NULL) {
    if (error != NULL) {
      *error = ZATHURA_ERROR_INVALID_ARGUMENTS;
    }
    goto error_ret;
  }

  zathura_document_t* document = zathura_page_get_document(page);
  if (document == NULL) {
    goto error_ret;
  }

  djvu_document_t* djvu_document = zathura_document_get_data(document);

  djvu_page_text_t* page_text = djvu_page_text_new(djvu_document, page);
  if (page_text == NULL) {
    goto error_ret;
  }

  double tmp = 0;
  double page_height = zathura_page_get_height(page);
  double page_width  = zathura_page_get_width(page);

  switch (zathura_document_get_rotation(document)) {
    case 90:
      tmp = rectangle.x1;
      rectangle.x1 = rectangle.y1;
      rectangle.y1 = tmp;
      tmp = rectangle.x2;
      rectangle.x2 = rectangle.y2;
      rectangle.y2 = tmp;
      break;
    case 180:
      tmp = rectangle.x1;
      rectangle.x1 = (page_width  - rectangle.x2);
      rectangle.x2 = (page_width  - tmp);
      break;
    case 270:
      tmp = rectangle.y2;
      rectangle.y2 = (page_height - rectangle.x1);
      rectangle.x1 = (page_width  - tmp);
      tmp = rectangle.y1;
      rectangle.y1 = (page_height - rectangle.x2);
      rectangle.x2 = (page_width  - tmp);
      break;
    default:
      tmp = rectangle.y1;
      rectangle.y1 = (page_height - rectangle.y2);
      rectangle.y2 = (page_height - tmp);
      break;
  }

  /* adjust to scale */
  rectangle.x1 /= ZATHURA_DJVU_SCALE;
  rectangle.x2 /= ZATHURA_DJVU_SCALE;
  rectangle.y1 /= ZATHURA_DJVU_SCALE;
  rectangle.y2 /= ZATHURA_DJVU_SCALE;

  char* text = djvu_page_text_select(page_text, rectangle);

  djvu_page_text_free(page_text);

  return text;

error_ret:

  if (error != NULL && *error == ZATHURA_ERROR_OK) {
    *error = ZATHURA_ERROR_UNKNOWN;
  }

  return NULL;
}