Exemplo n.º 1
0
girara_tree_node_t*
cb_document_index_generate(zathura_document_t* document,
                           cb_document_t* cb_document, zathura_error_t* error)
{
  if (document == NULL || cb_document == NULL) {
    if (error != NULL) {
      *error = ZATHURA_ERROR_INVALID_ARGUMENTS;
    }
    return NULL;
  }

  girara_tree_node_t* root = girara_node_new(zathura_index_element_new("ROOT"));
  unsigned int page_number = 0;
  GIRARA_LIST_FOREACH(cb_document->pages, cb_document_page_meta_t*, iter, page)
  {
    gchar* markup = g_markup_escape_text(page->file, -1);
    zathura_index_element_t* index_element = zathura_index_element_new(markup);
    g_free(markup);

    if (index_element != NULL) {
      zathura_rectangle_t rect = { 0, 0, 0, 0 };
      zathura_link_target_t target = { ZATHURA_LINK_DESTINATION_XYZ, NULL,
        page_number, -1, -1, -1, -1, 0 };

      index_element->link = zathura_link_new(ZATHURA_LINK_GOTO_DEST, rect,
          target);
      girara_node_append_data(root, index_element);
    }
    ++page_number;
  }
  GIRARA_LIST_FOREACH_END(cb_document->pages, cb_document_page_meta_t*, iter, page);

  return root;
}
Exemplo n.º 2
0
static void
build_index(fz_context* ctx, fz_document* document, fz_outline* outline, girara_tree_node_t* root)
{
  if (outline == NULL || root == NULL) {
    return;
  }

  while (outline != NULL) {
    zathura_index_element_t* index_element = zathura_index_element_new(outline->title);
    zathura_link_target_t target           = { ZATHURA_LINK_DESTINATION_UNKNOWN, NULL, 0, -1, -1, -1, -1, 0 };
    zathura_link_type_t type               = ZATHURA_LINK_INVALID;
    zathura_rectangle_t rect               = { .x1 = 0, .y1 = 0, .x2 = 0, .y2 = 0 };

    if (outline->uri == NULL) {
      type = ZATHURA_LINK_NONE;
    } else if (fz_is_external_link(ctx, outline->uri) == 1) {
      if (strstr(outline->uri, "file://") == outline->uri) {
        type         = ZATHURA_LINK_GOTO_REMOTE;
        target.value = outline->uri;
      } else {
        type         = ZATHURA_LINK_URI;
        target.value = outline->uri;
      }
    } else {
      float x = 0;
      float y = 0;

      type                    = ZATHURA_LINK_GOTO_DEST;
      target.destination_type = ZATHURA_LINK_DESTINATION_XYZ;
      target.page_number      = fz_resolve_link(ctx, document, outline->uri, &x, &y);
      target.left  = x;
      target.top   = y;
      target.zoom  = 0.0;
    }

    index_element->link = zathura_link_new(type, rect, target);
    if (index_element->link == NULL) {
      outline = outline->next;
      continue;
    }

    girara_tree_node_t* node = girara_node_append_data(root, index_element);

    if (outline->down != NULL) {
      build_index(ctx, document, outline->down, node);
    }

    outline = outline->next;
  }
}
Exemplo n.º 3
0
static void
build_index(djvu_document_t *djvu_document, miniexp_t expression, girara_tree_node_t* root)
{
  if (expression == miniexp_nil || root == NULL) {
    return;
  }

  int fileno = ddjvu_document_get_filenum(djvu_document->document);
  int curfile = 0;

  while (miniexp_consp(expression) != 0) {
    miniexp_t inner = miniexp_car(expression);

    if (miniexp_consp(inner)
        && miniexp_consp(miniexp_cdr(inner))
        && miniexp_stringp(miniexp_car(inner))
        && miniexp_stringp(miniexp_car(inner))
       ) {
      const char* name = miniexp_to_str(miniexp_car(inner));
      const char* link = miniexp_to_str(miniexp_cadr(inner));

      /* TODO: handle other links? */
      if (link == NULL || link[0] != '#') {
        expression = miniexp_cdr(expression);
        continue;
      }

      zathura_link_type_t type = ZATHURA_LINK_GOTO_DEST;
      zathura_rectangle_t rect;
      zathura_link_target_t target = { 0 };
      target.destination_type = ZATHURA_LINK_DESTINATION_XYZ;

      /* Check if link+1 contains a number */
      bool number = true;
      const size_t linklen = strlen(link);
      for (unsigned int k = 1; k < linklen; k++) {
	      if (!isdigit(link[k])) {
	        number = false;
	        break;
	      }
      }

      /* if link starts with a number assume it is a number */
      if (number == true) {
	      target.page_number = atoi(link + 1) - 1;
      } else {
        /* otherwise assume it is an id for a page */
        ddjvu_fileinfo_t info;
        int f, i;
        for (i=0; i < fileno; i++) {
          f = (curfile + i) % fileno;
          ddjvu_document_get_fileinfo(djvu_document->document, f, &info);
          if (info.id != NULL && !strcmp(link+1, info.id)) {
            break;
	        }
	      }

        /* got a page */
        if (i < fileno && info.pageno >= 0) {
          curfile = (f+1) % fileno;
          target.page_number = info.pageno;
        } else {
          /* give up */
          expression = miniexp_cdr(expression);
          continue;
        }
      }

      zathura_index_element_t* index_element = zathura_index_element_new(name);
      if (index_element == NULL) {
        continue;
      }

      index_element->link = zathura_link_new(type, rect, target);
      if (index_element->link == NULL) {
        zathura_index_element_free(index_element);
        continue;
      }

      girara_tree_node_t* node = girara_node_append_data(root, index_element);

      /* search recursive */
      build_index(djvu_document, miniexp_cddr(inner), node);
    }

    expression = miniexp_cdr(expression);
  }
}
Exemplo n.º 4
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;
}