Example #1
0
static jboolean miniexp_get_text(JNIEnv * env, miniexp_t exp, jobject stringBuilder, jobject positions, int *state,
                        jclass rectFClass, jmethodID ctor, jmethodID addToList, int pageHeight)
{

  miniexp_t type = miniexp_car(exp);
  int typenum = parse_text_type(type);
  miniexp_t r = exp = miniexp_cdr(exp);
  if (! miniexp_symbolp(type))
    return 0;

  jobject rect = miniexp_get_rect(&r, env, rectFClass, ctor, pageHeight);
  if (rect == NULL)
    return 0;

  miniexp_t s = miniexp_car(r);
  *state = qMax(*state, typenum);

  jstring space = (*env)->NewStringUTF(env, " ");
  jstring newLine = (*env)->NewStringUTF(env, "\n");

  if (miniexp_stringp(s) && !miniexp_cdr(r))
    {
      //result += (state >= 2) ? "\n" : (state >= 1) ? " " : "";
      if (*state >= 2) {
        (*env)->CallBooleanMethod(env, positions, addToList, rect);
        (*env)->CallBooleanMethod(env, stringBuilder, addToList, newLine);
      } else if (*state >= 1) {
        (*env)->CallBooleanMethod(env, positions, addToList, rect);
        (*env)->CallBooleanMethod(env, stringBuilder, addToList, newLine);
      } else {
        //add empty?
      }
      *state = -1;

      (*env)->CallBooleanMethod(env, positions, addToList, rect);

      jstring string = (*env)->NewStringUTF(env, miniexp_to_str(s));
      (*env)->CallBooleanMethod(env, stringBuilder, addToList, string);
      (*env)->DeleteLocalRef(env, string);

      r = miniexp_cdr(r);
    }

  (*env)->DeleteLocalRef(env, space);
  (*env)->DeleteLocalRef(env, newLine);
  (*env)->DeleteLocalRef(env, rect);

  while(miniexp_consp(s))
    {
      miniexp_get_text(env, s, stringBuilder, positions, state, rectFClass, ctor, addToList, pageHeight);
      r = miniexp_cdr(r);
      s = miniexp_car(r);
    }

  if (r)
    return 0;

  *state = qMax(*state, typenum);
  return 1;
}
Example #2
0
/**
 * djvu_text_page_sexpr:
 * @page: #DjvuTextPage instance
 * @p: tree to append
 * @start: first s-expression in the selection
 * @end: last s-expression in the selection
 * 
 * Walks the tree in @p and extends the rectangle with 
 * djvu_text_page_process() for all s-expressions between @start and @end.
 * 
 * Returns: whether the end was not reached in this subtree
 */
static gboolean
djvu_text_page_sexpr (DjvuTextPage *page, 
		      miniexp_t p,
		      miniexp_t start, 
		      miniexp_t end)
{
	g_return_val_if_fail (miniexp_consp (p) && miniexp_symbolp
			      (miniexp_car (p)), FALSE);

	miniexp_t deeper = miniexp_cddr (miniexp_cdddr (p));
	while (deeper != miniexp_nil) {
		miniexp_t str = miniexp_car (deeper);
		if (miniexp_stringp (str)) {
			if (!djvu_text_page_sexpr_process
			    (page, p, start, end))
				return FALSE;
		} else {
			if (!djvu_text_page_sexpr
			    (page, str, start, end))
				return FALSE;
		}
		deeper = miniexp_cdr (deeper);
	}
	return TRUE;
}
Example #3
0
/**
 * djvu_text_page_selection:
 * @page: #DjvuTextPage instance
 * @p: tree to append
 * @delimit: character/word/... delimiter
 * 
 * Walks the tree in @p and appends the text with
 * djvu_text_page_selection_process() for all s-expressions 
 * between the start and end fields.
 * 
 * Returns: whether the end was not reached in this subtree
 */
static gboolean
djvu_text_page_selection (DjvuTextPage *page, 
		          miniexp_t     p,
		          int           delimit)
{
	g_return_val_if_fail (miniexp_consp (p) && miniexp_symbolp
			      (miniexp_car (p)), FALSE);

	if (miniexp_car (p) != page->char_symbol) 
		delimit |= miniexp_car (p) == page->word_symbol ? 1 : 2;
		
	miniexp_t deeper = miniexp_cddr (miniexp_cdddr (p));
	while (deeper != miniexp_nil) {
		miniexp_t str = miniexp_car (deeper);
		if (miniexp_stringp (str)) {
			if (!djvu_text_page_selection_process
			    (page, p, delimit))
				return FALSE;
		} else {
			if (!djvu_text_page_selection
			    (page, str, delimit))
				return FALSE;
		}
		delimit = 0;
		deeper = miniexp_cdr (deeper);
	}
	return TRUE;
}
extern "C" jlong Java_org_ebookdroid_droids_djvu_codec_DjvuOutline_getChild(JNIEnv *env, jclass cls, jlong expr)
{
//    DEBUG("DjvuOutline.getChild(%p)",expr);
    miniexp_t s = miniexp_car((miniexp_t) expr);
    if (miniexp_consp(s) && miniexp_consp(miniexp_cdr(s)) && miniexp_stringp(miniexp_car(s))
        && miniexp_stringp(miniexp_cadr(s)))
        return (jlong) miniexp_cddr(s);
    return 0;
}
Example #5
0
static int miniexp_get_int(miniexp_t * r, int * x)
{
  if (! miniexp_numberp(miniexp_car(*r)))
    return 0;

  *x = miniexp_to_int(miniexp_car(*r));
  *r = miniexp_cdr(*r);

  return 1;
}
jint* get_djvu_hyperlink_area(ddjvu_pageinfo_t *page_info, miniexp_t sexp, int &type, int &len)
{
    miniexp_t iter;

    iter = sexp;

    DEBUG("Hyperlink area %s", miniexp_to_name(miniexp_car(sexp)));

    if (miniexp_car(iter) == miniexp_symbol("rect"))
        type = 1;
    else if (miniexp_car(iter) == miniexp_symbol("oval"))
        type = 2;
    else if (miniexp_car(iter) == miniexp_symbol("poly"))
        type = 3;
    else return NULL;

    len = miniexp_length(iter);
    jint* array = new jint[len];

    int x, i = 0;
    iter = miniexp_cdr(iter);
    while (iter != miniexp_nil)
    {
        if (!number_from_miniexp(miniexp_car(iter), &x))
            break;
        iter = miniexp_cdr(iter);
        array[i++] = (jint) x;
        if (i >= len)
            break;
    }

    len = i;
    if ((type == 1 || type == 2) && len == 4)
    {
        int miny, width, height;

        miny = array[1];
        width = array[2];
        height = array[3];
        array[1] = (page_info->height - (miny + height));
        array[2] = array[0] + width;
        array[3] = (page_info->height - miny);
    }
    if (type == 3 && (len % 2) == 0)
    {
        int ccc;
        for (int k = 1; k < len; k += 2)
        {
            ccc = array[k];
            array[k] = (page_info->height - ccc);
        }
    }

    return array;
}
extern "C" jstring Java_org_ebookdroid_droids_djvu_codec_DjvuOutline_getTitle(JNIEnv *env, jclass cls, jlong expr)
{
//        DEBUG("DjvuOutline.getTitle(%p)",expr);
    miniexp_t s = miniexp_car((miniexp_t) expr);
    if (miniexp_consp(s) && miniexp_consp(miniexp_cdr(s)) && miniexp_stringp(miniexp_car(s))
        && miniexp_stringp(miniexp_cadr(s)))
    {
        const char* buf = miniexp_to_str(miniexp_car(s));
        return env->NewStringUTF(buf);
    }
    return NULL;
}
Example #8
0
void declare(llvm::Module* module, minivar_t declare_list) {
    minivar_t name = miniexp_car(declare_list);
    minivar_t object = miniexp_cadr(declare_list);

    minivar_t objecttype = miniexp_car(object);
    if(miniexp_to_stdname(objecttype) == "fun") {
        declare_fun(module, name, miniexp_cadr(declare_list));
    } else {
        std::cerr << "Unknown object type " << miniexp_to_stdname(objecttype) << " to declare " << miniexp_to_stdname(name) << std::endl;
        return;
    }
}
Example #9
0
static int walkTableOfContent(lua_State *L, miniexp_t r, int *count, int depth) {
	depth++;

	miniexp_t lista = miniexp_cdr(r); // go inside bookmars in the list

	int length = miniexp_length(r);
	int counter = 0;
	const char* page_name;
	int page_number;

	while(counter < length-1) {
		lua_pushnumber(L, *count);
		lua_newtable(L);

		lua_pushstring(L, "page");
		page_name = miniexp_to_str(miniexp_car(miniexp_cdr(miniexp_nth(counter, lista))));
		if(page_name != NULL && page_name[0] == '#') {
			errno = 0;
			page_number = strtol(page_name + 1, NULL, 10);
			if(!errno) {
				lua_pushnumber(L, page_number);
			} else {
				/* we can not parse this as a number, TODO: parse page names */
				lua_pushnumber(L, -1);
			}
		} else {
			/* something we did not expect here */
			lua_pushnumber(L, -1);
		}
		lua_settable(L, -3);

		lua_pushstring(L, "depth");
		lua_pushnumber(L, depth);
		lua_settable(L, -3);

		lua_pushstring(L, "title");
		lua_pushstring(L, miniexp_to_str(miniexp_car(miniexp_nth(counter, lista))));
		lua_settable(L, -3);

		lua_settable(L, -3);

		(*count)++;

		if (miniexp_length(miniexp_cdr(miniexp_nth(counter, lista))) > 1) {
			walkTableOfContent(L, miniexp_cdr(miniexp_nth(counter, lista)), count, depth);
		}
		counter++;
	}
	return 0;
}
Example #10
0
girara_tree_node_t*
djvu_document_index_generate(zathura_document_t* document, djvu_document_t*
    djvu_document, zathura_error_t* error)
{
  if (document == NULL || djvu_document == NULL) {
    if (error != NULL) {
      *error = ZATHURA_ERROR_INVALID_ARGUMENTS;
    }
    return NULL;
  }

  miniexp_t outline = miniexp_dummy;
  while ((outline = ddjvu_document_get_outline(djvu_document->document)) ==
      miniexp_dummy) {
    handle_messages(djvu_document, true);
  }

  if (outline == miniexp_dummy) {
    return NULL;
  }

  if (miniexp_consp(outline) == 0 || miniexp_car(outline) != miniexp_symbol("bookmarks")) {
    ddjvu_miniexp_release(djvu_document->document, outline);
    return NULL;
  }

  girara_tree_node_t* root = girara_node_new(zathura_index_element_new("ROOT"));
  build_index(djvu_document, miniexp_cdr(outline), root);

  ddjvu_miniexp_release(djvu_document->document, outline);

  return root;
}
Example #11
0
/**
 * djvu_text_page_append_search:
 * @page: #DjvuTextPage instance
 * @p: tree to append
 * @case_sensitive: do not ignore case
 * @delimit: insert spaces because of higher (sentence/paragraph/...) break
 * 
 * Appends the tree in @p to the internal text string. 
 */
static void
djvu_text_page_append_text (DjvuTextPage *page,
			    miniexp_t     p, 
			    gboolean      case_sensitive, 
			    gboolean      delimit)
{
	char *token_text;
	miniexp_t deeper;
	
	g_return_if_fail (miniexp_consp (p) && 
			  miniexp_symbolp (miniexp_car (p)));

	delimit |= page->char_symbol != miniexp_car (p);
	
	deeper = miniexp_cddr (miniexp_cdddr (p));
	while (deeper != miniexp_nil) {
		miniexp_t data = miniexp_car (deeper);
		if (miniexp_stringp (data)) {
			DjvuTextLink link;
			link.position = page->text == NULL ? 0 :
			    strlen (page->text);
			link.pair = p;
			g_array_append_val (page->links, link);

			token_text = (char *) miniexp_to_str (data);
			if (!case_sensitive)
				token_text = g_utf8_casefold (token_text, -1);
			if (page->text == NULL)
				page->text = g_strdup (token_text);
			else {
				char *new_text =
				    g_strjoin (delimit ? " " : NULL,
					       page->text, token_text,
					       NULL);
				g_free (page->text);
				page->text = new_text;
			}
			if (!case_sensitive)
				g_free (token_text);
		} else
			djvu_text_page_append_text (page, data, 
						    case_sensitive, delimit);
		delimit = FALSE;
		deeper = miniexp_cdr (deeper);
	}
}
Example #12
0
int buildTOC(miniexp_t expr, list * myList, int level, JNIEnv * env, jclass olClass, jmethodID ctor)
{   
  while(miniexp_consp(expr))
    {
      miniexp_t s = miniexp_car(expr);
      expr = miniexp_cdr(expr);
      if (miniexp_consp(s) &&
          miniexp_consp(miniexp_cdr(s)) &&
          miniexp_stringp(miniexp_car(s)) &&
          miniexp_stringp(miniexp_cadr(s)) )
        {
          // fill item
          const char *name = miniexp_to_str(miniexp_car(s));
          const char *page = miniexp_to_str(miniexp_cadr(s));
          //starts with #

          int pageno = -1;
          if (page[0] == '#') {
              pageno = ddjvu_document_search_pageno(doc, &page[1]);
          }

          if (pageno < 0) {
            LOGI("Page %s", page);
          }

          if (name == NULL) {return -1;}

          OutlineItem * element = (OutlineItem *) malloc(sizeof(OutlineItem));
          element->title = name;
          element->page = pageno;
          element->level = level;

          list_item * next = (list_item *) malloc(sizeof(list_item));
          next->item = element;
          next->next = NULL;
          myList->tail->next = next;
          myList->tail = next;
	  	  
          // recursion
          buildTOC(miniexp_cddr(s), myList, level+1, env, olClass, ctor);	  
        }
    }
    return 0;
}
Example #13
0
static void
djvu_text_page_limits (DjvuTextPage *page,
			  miniexp_t     p, 
			  EvRectangle  *rect)
{
	g_return_if_fail (miniexp_consp (p) && 
			  miniexp_symbolp (miniexp_car (p)));

	miniexp_t deeper = miniexp_cddr (miniexp_cdddr (p));
	while (deeper != miniexp_nil) {
		miniexp_t str = miniexp_car (deeper);
		if (miniexp_stringp (str))
			djvu_text_page_limits_process (page, p, rect);
		else
			djvu_text_page_limits (page, str, rect);

		deeper = miniexp_cdr (deeper);
	}
}
Example #14
0
void 
QDjViewOutline::fillItems(QTreeWidgetItem *root, miniexp_t expr)
{
  while(miniexp_consp(expr))
    {
      miniexp_t s = miniexp_car(expr);
      expr = miniexp_cdr(expr);
      if (miniexp_consp(s) &&
          miniexp_consp(miniexp_cdr(s)) &&
          miniexp_stringp(miniexp_car(s)) &&
          miniexp_stringp(miniexp_cadr(s)) )
        {
          // fill item
          const char *name = miniexp_to_str(miniexp_car(s));
          const char *link = miniexp_to_str(miniexp_cadr(s));
          int pageno = pageNumber(link);
          QString pagename = (pageno>=0)?djview->pageName(pageno):QString();
          QTreeWidgetItem *item = new QTreeWidgetItem(root);
          QString text = QString::fromUtf8(name);
          if (name && name[0])
            item->setText(0, text.replace(spaces," "));
          else if (! pagename.isEmpty())
            item->setText(0, tr("Page %1").arg(pagename));
          item->setFlags(0);
          item->setWhatsThis(0, whatsThis());
          if (link && link[0])
            {
              QString slink = QString::fromUtf8(link);
              item->setData(0, Qt::UserRole+1, slink);
              item->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled);
              item->setToolTip(0, tr("Go: %1").arg(slink));
              if (pageno >= 0)
                item->setData(0, Qt::UserRole, pageno);
              if (! pagename.isEmpty())
                item->setToolTip(0, tr("Go: page %1.").arg(pagename));
            }
          // recurse
          fillItems(item, miniexp_cddr(s));
        }
    }
}
Example #15
0
void 
QDjViewOutline::refresh()
{
  QDjVuDocument *doc = djview->getDocument();
  if (doc && !loaded && djview->pageNum()>0)
    {
      miniexp_t outline = doc->getDocumentOutline();
      if (outline == miniexp_dummy)
        return;
      loaded = true;
      if (outline)
        {
          if (!miniexp_consp(outline) ||
              miniexp_car(outline) != miniexp_symbol("bookmarks"))
            {
              QString msg = tr("Outline data is corrupted");
              qWarning("%s", (const char*)msg.toLocal8Bit());
            }
          tree->clear();
          QTreeWidgetItem *root = new QTreeWidgetItem();
          fillItems(root, miniexp_cdr(outline));
          while (root->childCount() > 0)
            tree->insertTopLevelItem(tree->topLevelItemCount(),
                                     root->takeChild(0) );
          if (tree->topLevelItemCount() == 1)
            tree->topLevelItem(0)->setExpanded(true);
          delete root;
        }
      else
        {
          tree->clear();
          QTreeWidgetItem *root = new QTreeWidgetItem(tree);
          root->setText(0, tr("Pages"));
          root->setFlags(Qt::ItemIsEnabled);
          root->setData(0, Qt::UserRole, -1);
          for (int pageno=0; pageno<djview->pageNum(); pageno++)
            {
              QTreeWidgetItem *item = new QTreeWidgetItem(root);
              QString name = djview->pageName(pageno);
              item->setText(0, tr("Page %1").arg(name));
              item->setData(0, Qt::UserRole, pageno);
              item->setData(0, Qt::UserRole+1, pageno);
              item->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled);
              item->setToolTip(0, tr("Go: page %1.").arg(name));
              item->setWhatsThis(0, whatsThis());
            }
          tree->setItemExpanded(root, true);
        }
      pageChanged(djview->getDjVuWidget()->page());
    }
}
extern "C" jstring Java_org_ebookdroid_droids_djvu_codec_DjvuOutline_getLink(JNIEnv *env, jclass cls, jlong expr,
                                                                           jlong docHandle)
{
//        DEBUG("DjvuOutline.getLinkPage(%p)",expr);
    miniexp_t s = miniexp_car((miniexp_t) expr);
    if (miniexp_consp(s) && miniexp_consp(miniexp_cdr(s)) && miniexp_stringp(miniexp_car(s))
        && miniexp_stringp(miniexp_cadr(s)))
    {
        const char *link = miniexp_to_str(miniexp_cadr(s));
        int number = -1;
        if (link && link[0] == '#')
        {
            number = ddjvu_document_search_pageno((ddjvu_document_t*) docHandle, link + 1);
            if (number >= 0)
            {
                char linkbuf[128];
                snprintf(linkbuf, 127, "#%d", number + 1);
                return env->NewStringUTF(linkbuf);
            }
        }
        return env->NewStringUTF(link);
    }
    return NULL;
}
//Outline
extern "C" jlong Java_org_ebookdroid_droids_djvu_codec_DjvuOutline_open(JNIEnv *env, jclass cls, jlong docHandle)
{
//        DEBUG("DjvuOutline.open(%p)",docHandle);
    miniexp_t outline = ddjvu_document_get_outline((ddjvu_document_t*) docHandle);
    if (outline && outline != miniexp_dummy)
    {
        if (!miniexp_consp(outline) || miniexp_car(outline) != miniexp_symbol("bookmarks"))
        {
            ERROR("%s", "Outline data is corrupted");
            return 0;
        }
        else return (jlong) outline;
//	    debug_outline(outline);
    }
    return 0;
}
Example #18
0
static EvMapping *
get_djvu_hyperlink_mapping (DjvuDocument     *djvu_document,
			    int               page,
			    ddjvu_pageinfo_t *page_info,
			    miniexp_t         sexp)
{
	EvMapping *ev_link_mapping = NULL;
	EvLinkAction *ev_action = NULL;
	miniexp_t iter;
	const char *url, *url_target, *comment;

	ev_link_mapping = g_new (EvMapping, 1);

	iter = sexp;

	if (miniexp_car (iter) != miniexp_symbol ("maparea")) goto unknown_mapping;

	iter = miniexp_cdr(iter);

	if (miniexp_caar(iter) == miniexp_symbol("url")) {
		if (!string_from_miniexp (miniexp_cadr (miniexp_car (iter)), &url)) goto unknown_mapping;
		if (!string_from_miniexp (miniexp_caddr (miniexp_car (iter)), &url_target)) goto unknown_mapping;
	} else {
		if (!string_from_miniexp (miniexp_car(iter), &url)) goto unknown_mapping;
		url_target = NULL;
	}

	iter = miniexp_cdr (iter);
	if (!string_from_miniexp (miniexp_car(iter), &comment)) goto unknown_mapping;

	iter = miniexp_cdr (iter);
	if (!get_djvu_hyperlink_area (page_info, miniexp_car(iter), ev_link_mapping)) goto unknown_mapping;

	iter = miniexp_cdr (iter);
	/* FIXME: DjVu hyperlink attributes are ignored */

	ev_action = get_djvu_link_action (djvu_document, url, page);
	if (!ev_action) goto unknown_mapping;

	ev_link_mapping->data = ev_link_new (comment, ev_action);
	g_object_unref (ev_action);

	return ev_link_mapping;

 unknown_mapping:
	if (ev_link_mapping) g_free(ev_link_mapping);
	g_warning("DjvuLibre error: Unknown hyperlink %s", miniexp_to_name(miniexp_car(sexp)));
	return NULL;
}
Example #19
0
static gboolean
get_djvu_hyperlink_area (ddjvu_pageinfo_t *page_info,
			 miniexp_t         sexp,
			 EvMapping        *ev_link_mapping)
{
	miniexp_t iter;

	iter = sexp;
	
	if ((miniexp_car (iter) == miniexp_symbol ("rect") || miniexp_car (iter) == miniexp_symbol ("oval"))
	    && miniexp_length (iter) == 5) {
		/* FIXME: get bounding box for (oval) since Evince doesn't support shaped links */
		int minx, miny, width, height;

		iter = miniexp_cdr (iter);
		if (!number_from_miniexp (miniexp_car (iter), &minx)) goto unknown_link;
		iter = miniexp_cdr (iter);
		if (!number_from_miniexp (miniexp_car (iter), &miny)) goto unknown_link;
		iter = miniexp_cdr (iter);
		if (!number_from_miniexp (miniexp_car (iter), &width)) goto unknown_link;
		iter = miniexp_cdr (iter);
		if (!number_from_miniexp (miniexp_car (iter), &height)) goto unknown_link;

		ev_link_mapping->area.x1 = minx;
		ev_link_mapping->area.x2 = (minx + width);
		ev_link_mapping->area.y1 = (page_info->height - (miny + height));
		ev_link_mapping->area.y2 = (page_info->height - miny);
	} else if (miniexp_car (iter) == miniexp_symbol ("poly")
		   && miniexp_length (iter) >= 5 && miniexp_length (iter) % 2 == 1) {
		
		/* FIXME: get bounding box since Evince doesn't support shaped links */
		int minx = G_MAXINT, miny = G_MAXINT;
		int maxx = G_MININT, maxy = G_MININT;

		iter = miniexp_cdr(iter);
		while (iter != miniexp_nil) {
			int x, y;

			if (!number_from_miniexp (miniexp_car(iter), &x)) goto unknown_link;
			iter = miniexp_cdr (iter);
			if (!number_from_miniexp (miniexp_car(iter), &y)) goto unknown_link;
			iter = miniexp_cdr (iter);

			minx = MIN (minx, x);
			miny = MIN (miny, y);
			maxx = MAX (maxx, x);
			maxy = MAX (maxy, y);
		}

		ev_link_mapping->area.x1 = minx;
		ev_link_mapping->area.x2 = maxx;
		ev_link_mapping->area.y1 = (page_info->height - maxy);
		ev_link_mapping->area.y2 = (page_info->height - miny);
	} else {
		/* unknown */
		goto unknown_link;
	}

	return TRUE;
	
 unknown_link:
	g_warning("DjvuLibre error: Unknown hyperlink area %s", miniexp_to_name(miniexp_car(sexp)));
	return FALSE;
}
Example #20
0
/**
 * Builds the index GtkTreeModel from DjVu s-expr
 *
 * (bookmarks
 *   ("title1" "dest1"
 *     ("title12" "dest12"
 *       ... )
 *     ... )
 *   ("title2" "dest2"
 *     ... )
 *   ... )
 */
static void
build_tree (const DjvuDocument *djvu_document,
	    GtkTreeModel       *model,
	    GtkTreeIter        *parent,
	    miniexp_t           iter)
{
	const char *title, *link_dest;
	char *title_markup;

	EvLinkAction *ev_action = NULL;
	EvLink *ev_link = NULL;
	GtkTreeIter tree_iter;

	if (miniexp_car (iter) == miniexp_symbol ("bookmarks")) {
		/* The (bookmarks) cons */
		iter = miniexp_cdr (iter);
	} else if ( miniexp_length (iter) >= 2 ) {
		gchar *utf8_title = NULL;
		
		/* An entry */
		if (!string_from_miniexp (miniexp_car (iter), &title)) goto unknown_entry;
		if (!string_from_miniexp (miniexp_cadr (iter), &link_dest)) goto unknown_entry;

		
		if (!g_utf8_validate (title, -1, NULL)) {
			utf8_title = str_to_utf8 (title);
			title_markup = g_markup_escape_text (utf8_title, -1);
		} else {
			title_markup = g_markup_escape_text (title, -1);
		}

		ev_action = get_djvu_link_action (djvu_document, link_dest, -1);

		if (ev_action) {
			ev_link = ev_link_new (utf8_title ? utf8_title : title, ev_action);
			gtk_tree_store_append (GTK_TREE_STORE (model), &tree_iter, parent);
			gtk_tree_store_set (GTK_TREE_STORE (model), &tree_iter,
					    EV_DOCUMENT_LINKS_COLUMN_MARKUP, title_markup,
					    EV_DOCUMENT_LINKS_COLUMN_LINK, ev_link,
					    EV_DOCUMENT_LINKS_COLUMN_EXPAND, FALSE,
					    -1);
			g_object_unref (ev_action);
			g_object_unref (ev_link);
		} else {
			gtk_tree_store_append (GTK_TREE_STORE (model), &tree_iter, parent);
			gtk_tree_store_set (GTK_TREE_STORE (model), &tree_iter,
					    EV_DOCUMENT_LINKS_COLUMN_MARKUP, title_markup,
					    EV_DOCUMENT_LINKS_COLUMN_EXPAND, FALSE,
					    -1);
		}

		g_free (title_markup);
		g_free (utf8_title);
		iter = miniexp_cddr (iter);
		parent = &tree_iter;
	} else {
		goto unknown_entry;
	}

	for (; iter != miniexp_nil; iter = miniexp_cdr (iter)) {
		build_tree (djvu_document, model, parent, miniexp_car (iter));
	}
	return;

 unknown_entry:
	g_warning ("DjvuLibre error: Unknown entry in bookmarks");
	return;
}
Example #21
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;
}
Example #22
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);
  }
}
Example #23
0
static bool
exp_to_rect(miniexp_t expression, zathura_rectangle_t* rect)
{
  if ((miniexp_car(expression) == miniexp_symbol("rect")
        || miniexp_car(expression) == miniexp_symbol("oval"))
      && miniexp_length(expression) == 5) {
    int min_x  = 0;
    int min_y  = 0;
    int width  = 0;
    int height = 0;

    miniexp_t iter = miniexp_cdr(expression);
    if (exp_to_int(miniexp_car(iter), &min_x) == false) {
      return false;
    }
    iter = miniexp_cdr(iter);
    if (exp_to_int(miniexp_car(iter), &min_y) == false) {
      return false;
    }
    iter = miniexp_cdr(iter);
    if (exp_to_int(miniexp_car(iter), &width) == false) {
      return false;
    }
    iter = miniexp_cdr(iter);
    if (exp_to_int(miniexp_car(iter), &height) == false) {
      return false;
    }

    rect->x1 = min_x;
    rect->x2 = min_x + width;
    rect->y1 = min_y;
    rect->y2 = min_y + height;
  } else if (miniexp_car(expression) == miniexp_symbol("poly")
      && miniexp_length(expression) >= 5) {
    int min_x = 0;
    int min_y = 0;
    int max_x = 0;
    int max_y = 0;

    miniexp_t iter = miniexp_cdr(expression);
    while (iter != miniexp_nil) {
      int x = 0;
      int y = 0;

      if (exp_to_int(miniexp_car(iter), &x) == false) {
        return false;
      }
      iter = miniexp_cdr(iter);
      if (exp_to_int(miniexp_car(iter), &y) == false) {
        return false;
      }
      iter = miniexp_cdr(iter);

      min_x = MIN(min_x, x);
      min_y = MIN(min_y, y);
      max_x = MAX(max_x, x);
      max_y = MAX(max_y, y);
    }

    rect->x1 = min_x;
    rect->x2 = max_x;
    rect->y1 = min_y;
    rect->y2 = max_y;
  }

  return true;
}
void djvu_get_djvu_words(SearchHelper& h, jobject list, miniexp_t expr, jstring pattern)
{
    int coords[4];

    if (!miniexp_consp(expr))
    {
        return;
    }

    miniexp_t head = miniexp_car(expr);
    expr = miniexp_cdr(expr);
    if (!miniexp_symbolp(head))
    {
        return;
    }

    int i;
    for (i = 0; i < 4 && miniexp_consp(expr); i++)
    {
        head = miniexp_car(expr);
        expr = miniexp_cdr(expr);

        if (!miniexp_numberp(head))
        {
            return;
        }
        coords[i] = miniexp_to_int(head);
    }

    while (miniexp_consp(expr))
    {
        head = miniexp_car(expr);

        if (miniexp_stringp(head))
        {
            const char* text = miniexp_to_str(head);

            // DEBUG("%d, %d, %d, %d: %s", coords[0], coords[1], coords[2], coords[3], text);

            bool add = !pattern;
            jstring txt = h.str.toString(text);
            if (pattern)
            {
                jstring ltxt = h.str.toLowerCase(txt);
                add = h.str.indexOf(ltxt, pattern) >= 0;
                h.str.release(ltxt);
            }
            if (add)
            {
                // add to list
                jobject ptb = h.box.create();
                h.box.setRect(ptb, coords);
                h.box.setText(ptb, txt);
                h.arr.add(list, ptb);
            }
            else
            {
                h.str.release(txt);
            }
        }
        else if (miniexp_consp(head))
        {
            djvu_get_djvu_words(h, list, head, pattern);
        }

        expr = miniexp_cdr(expr);
    }
}
jobject get_djvu_hyperlink_mapping(JNIEnv *jenv, ddjvu_document_t* djvu_document, ddjvu_pageinfo_t *page_info,
                                   miniexp_t sexp)
{
    miniexp_t iter;
    const char *url, *url_target;

    jobject hl = NULL;

    iter = sexp;

    if (miniexp_car(iter) != miniexp_symbol("maparea"))
    {
        ERROR("DjvuLibre error: Unknown hyperlink %s", miniexp_to_name(miniexp_car(sexp)));
        return hl;
    }

    iter = miniexp_cdr(iter);

    if (miniexp_caar(iter) == miniexp_symbol("url"))
    {
        if (!string_from_miniexp(miniexp_cadr(miniexp_car(iter)), &url))
        {
            ERROR("DjvuLibre error: Unknown hyperlink %s", miniexp_to_name(miniexp_car(sexp)));
            return hl;
        }
        if (!string_from_miniexp(miniexp_caddr(miniexp_car(iter)), &url_target))
        {
            ERROR("DjvuLibre error: Unknown hyperlink %s", miniexp_to_name(miniexp_car(sexp)));
            return hl;
        }
    }
    else
    {
        if (!string_from_miniexp(miniexp_car(iter), &url))
        {
            ERROR("DjvuLibre error: Unknown hyperlink %s", miniexp_to_name(miniexp_car(sexp)));
            return hl;
        }
        url_target = NULL;
    }

    iter = miniexp_cdr(iter);
    /* FIXME: DjVu hyperlink comments are ignored */

    int len = 0;
    int type;
    jint* data;
    iter = miniexp_cdr(iter);
    if ((data = get_djvu_hyperlink_area(page_info, miniexp_car(iter), type, len)) == NULL)
    {
        ERROR("DjvuLibre error: Unknown hyperlink %s", miniexp_to_name(miniexp_car(sexp)));
        return hl;
    }

    iter = miniexp_cdr(iter);
    /* FIXME: DjVu hyperlink attributes are ignored */

    DEBUG("DjvuLibre: Hyperlink url: %s url_target: %s", url, url_target);

    if (!url)
    {
        delete[] data;
        return hl;
    }

    jclass pagelinkClass = jenv->FindClass("org/ebookdroid/core/codec/PageLink");
    if (!pagelinkClass)
    {
        delete[] data;
        return hl;
    }

    jmethodID plInitMethodId = jenv->GetMethodID(pagelinkClass, "<init>", "(Ljava/lang/String;I[I)V");
    if (!plInitMethodId)
    {
        delete[] data;
        return hl;
    }

    jintArray points = jenv->NewIntArray(len);
    jenv->SetIntArrayRegion(points, 0, len, data);

    jstring jstr = jenv->NewStringUTF(url);

    hl = jenv->NewObject(pagelinkClass, plInitMethodId, jstr, (jint) type, points);

    jenv->DeleteLocalRef(jstr);
    jenv->DeleteLocalRef(points);

    delete[] data;

//    DEBUG("DjvuLibre: Hyperlink url: %s url_target: %s", url, url_target);

    return hl;

}
Example #26
0
JNIEXPORT jobjectArray JNICALL Java_universe_constellation_orion_viewer_djvu_DjvuDocument_getOutline(JNIEnv * env, jobject thiz) 
{
  miniexp_t outline = ddjvu_document_get_outline(doc);
  
  if (outline == miniexp_dummy || outline == NULL) {    
      return NULL;
  }
    
  if (!miniexp_consp(outline) || miniexp_car(outline) != miniexp_symbol("bookmarks"))
  {
     LOGI("Outlines is empty");
  }
      
  list_item * root = (list_item *) malloc(sizeof(list_item)); 
  root->next = NULL;
  
  list * myList = (list *) malloc(sizeof(list));
  myList->head = root;
  myList->tail = root;
  
  jclass        olClass;
  jmethodID     ctor;

  olClass = (*env)->FindClass(env, "universe/constellation/orion/viewer/outline/OutlineItem");
  if (olClass == NULL) return NULL;
  ctor = (*env)->GetMethodID(env, olClass, "<init>", "(ILjava/lang/String;I)V");
  if (ctor == NULL) return NULL;  
  
  buildTOC(miniexp_cdr(outline), myList, 0, env, olClass, ctor);
  
  list_item * next = myList->head;
  int size = 0;
  while (next->next != NULL) {    
    next = next->next;
    size++;
  }
  
  LOGI("Outline has %i entries", size);
  
  jobjectArray arr = (*env)->NewObjectArray(env, size, olClass, NULL);
  if (arr == NULL) {
    return NULL;
  }
  
  next = root->next;
  int pos = 0;  
    
  while (next != NULL) {    
    OutlineItem * item = next->item;
    jstring title = (*env)->NewStringUTF(env, item->title);
    //shift pageno to zero based
    jobject element = (*env)->NewObject(env, olClass, ctor, item->level, title, item->page - 1);
    (*env)->SetObjectArrayElement(env, arr, pos, element);    
    (*env)->DeleteLocalRef(env, title);    
    (*env)->DeleteLocalRef(env, element);
    
    free(item);    
    list_item * next2 = next->next;
    free(next);
    next = next2;
    pos++;    
  }
  free(root);
  
  return arr;  
}
Example #27
0
//sumatrapdf code
int extractText(miniexp_t item, Arraylist list, fz_bbox * target) {
    miniexp_t type = miniexp_car(item);

    if (!miniexp_symbolp(type))
        return 0;

    item = miniexp_cdr(item);

    if (!miniexp_numberp(miniexp_car(item))) return 0;
    int x0 = miniexp_to_int(miniexp_car(item)); item = miniexp_cdr(item);
    if (!miniexp_numberp(miniexp_car(item))) return 0;
    int y0 = miniexp_to_int(miniexp_car(item)); item = miniexp_cdr(item);
    if (!miniexp_numberp(miniexp_car(item))) return 0;
    int x1 = miniexp_to_int(miniexp_car(item)); item = miniexp_cdr(item);
    if (!miniexp_numberp(miniexp_car(item))) return 0;
    int y1 = miniexp_to_int(miniexp_car(item)); item = miniexp_cdr(item);
    //RectI rect = RectI::FromXY(x0, y0, x1, y1);
    fz_bbox rect = {x0 , y0 , x1 , y1};

    miniexp_t str = miniexp_car(item);

    if (miniexp_stringp(str) && !miniexp_cdr(item)) {
        fz_bbox inters = fz_intersect_bbox(rect, *target);
            //LOGI("Start text extraction: rectangle=[%d,%d,%d,%d] %s", rect.x0, rect.y0, rect.x1, rect.y1, content);
        if (!fz_is_empty_bbox(inters)) {
            const char *content = miniexp_to_str(str);

            while (*content) {
                arraylist_add(list, *content++);
            }

    //        if (value) {
    //            size_t len = str::Len(value);
    //            // TODO: split the rectangle into individual parts per glyph
    //            for (size_t i = 0; i < len; i++)
    //                coords.Append(RectI(rect.x, rect.y, rect.dx, rect.dy));
    //            extracted.AppendAndFree(value);
    //        }
            if (miniexp_symbol("word") == type) {
                arraylist_add(list, ' ');
                //coords.Append(RectI(rect.x + rect.dx, rect.y, 2, rect.dy));
            }
            else if (miniexp_symbol("char") != type) {
                arraylist_add(list, '\n');
    //            extracted.Append(lineSep);
    //            for (size_t i = 0; i < str::Len(lineSep); i++)
    //                coords.Append(RectI());
            }
        }
        item = miniexp_cdr(item);
    }

    while (miniexp_consp(str)) {
        extractText(str, list, target);
        item = miniexp_cdr(item);
        str = miniexp_car(item);
    }

    return !item;
}