Пример #1
0
static void loadOutline(miniexp_t outlineExp, int offset, QStandardItem* parent, const QHash< QString, int >& indexByName)
{
    const int outlineLength = miniexp_length(outlineExp);

    for(int outlineN = qMax(0, offset); outlineN < outlineLength; ++outlineN)
    {
        miniexp_t bookmarkExp = miniexp_nth(outlineN, outlineExp);
        const int bookmarkLength = miniexp_length(bookmarkExp);

        if(bookmarkLength <= 1 || !miniexp_stringp(miniexp_nth(0, bookmarkExp)) || !miniexp_stringp(miniexp_nth(1, bookmarkExp)))
        {
            continue;
        }

        const QString title = QString::fromUtf8(miniexp_to_str(miniexp_nth(0, bookmarkExp)));
        QString destination = QString::fromUtf8(miniexp_to_str(miniexp_nth(1, bookmarkExp)));

        if(!title.isEmpty() && !destination.isEmpty())
        {
            if(destination.at(0) == QLatin1Char('#'))
            {
                destination.remove(0,1);

                bool ok = false;
                int destinationPage = destination.toInt(&ok);

                if(!ok)
                {
                    if(indexByName.contains(destination))
                    {
                        destinationPage = indexByName[destination] + 1;
                    }
                    else
                    {
                        continue;
                    }
                }

                QStandardItem* item = new QStandardItem(title);
                item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);

                item->setData(destinationPage, Qt::UserRole + 1);

                QStandardItem* pageItem = item->clone();
                pageItem->setText(QString::number(destinationPage));
                pageItem->setTextAlignment(Qt::AlignRight);

                parent->appendRow(QList< QStandardItem* >() << item << pageItem);

                if(bookmarkLength >= 3)
                {
                    loadOutline(bookmarkExp, 2, item, indexByName);
                }
            }
        }
    }
}
Пример #2
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;
}
Пример #3
0
/**
 * djvu_text_page_selection_process_box:
 * @page: #DjvuTextPage instance
 * @p: s-expression to append bounding box of
 * @delimit: character/word/... delimiter
 *
 * Appends bounding box of the line containing miniexp_t to page->results
 *
 * Returns: whether the end was not reached in this s-expression
 */
static gboolean
djvu_text_page_selection_process_box (DjvuTextPage *page,
				      miniexp_t     p,
				      int           delimit)
{
	if (page->results || p == page->start) {
		EvRectangle box;
		const char *text;

		box.x1 = miniexp_to_int (miniexp_nth (1, p));
		box.y1 = miniexp_to_int (miniexp_nth (2, p));
		box.x2 = miniexp_to_int (miniexp_nth (3, p));
		box.y2 = miniexp_to_int (miniexp_nth (4, p));
		text = miniexp_to_str (miniexp_nth (5, p));

		if (text != NULL && text[0] != '\0') {
			if (!(delimit & 2) && page->results != NULL) {
				EvRectangle *union_box = (EvRectangle *)page->results->data;

                                /* If still on the same line, add box to union */
				djvu_text_page_union (union_box, &box);
			} else {
				/* A new line, a new box */
				page->results = g_list_prepend (page->results, ev_rectangle_copy (&box));
			}
		}

		if (p == page->end)
			return FALSE;
	}
	return TRUE;
}
Пример #4
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;
}
Пример #5
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;
}
Пример #6
0
static gboolean string_from_miniexp(miniexp_t sexp, const char **str)
{
	if (miniexp_stringp (sexp)) {
		*str = miniexp_to_str (sexp);
		return TRUE;
	} else {
		return FALSE;
	}
}
Пример #7
0
void Model::DjVuDocument::loadProperties(QStandardItemModel* propertiesModel) const
{
    Document::loadProperties(propertiesModel);

    QMutexLocker mutexLocker(&m_mutex);

    propertiesModel->setColumnCount(2);

    miniexp_t annoExp;

    while(true)
    {
        annoExp = ddjvu_document_get_anno(m_document, TRUE);

        if(annoExp == miniexp_dummy)
        {
            clearMessageQueue(m_context, true);
        }
        else
        {
            break;
        }
    }

    const int annoLength = miniexp_length(annoExp);

    for(int annoN = 0; annoN < annoLength; ++annoN)
    {
        miniexp_t listExp = miniexp_nth(annoN, annoExp);
        const int listLength = miniexp_length(listExp);

        if(listLength <= 1 || qstrncmp(miniexp_to_name(miniexp_nth(0, listExp)), "metadata", 8) != 0)
        {
            continue;
        }

        for(int listN = 1; listN < listLength; ++listN)
        {
            miniexp_t keyValueExp = miniexp_nth(listN, listExp);

            if(miniexp_length(keyValueExp) != 2)
            {
                continue;
            }

            const QString key = QString::fromUtf8(miniexp_to_name(miniexp_nth(0, keyValueExp)));
            const QString value = QString::fromUtf8(miniexp_to_str(miniexp_nth(1, keyValueExp)));

            if(!key.isEmpty() && !value.isEmpty())
            {
                propertiesModel->appendRow(QList< QStandardItem* >() << new QStandardItem(key) << new QStandardItem(value));
            }
        }
    }

    ddjvu_miniexp_release(m_document, annoExp);
}
Пример #8
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;
}
Пример #9
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));
        }
    }
}
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;
}
Пример #11
0
static bool
exp_to_str(miniexp_t expression, const char** string)
{
  if (string == NULL) {
    return false;
  }

  if (miniexp_stringp(expression)) {
    *string = miniexp_to_str(expression);
    return true;
  }

  return false;
}
Пример #12
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);
	}
}
void guFolderInspector::extractIsbnsFromDjvu(QString fileName, QList<QString> &ISBNList)
{
    ctx = ddjvu_context_create("lgUploader"); //ddjvu_document_create_by_filename
    doc = ddjvu_document_create_by_filename_utf8(ctx, fileName.toUtf8(), 1);
    while (! ddjvu_document_decoding_done(doc));
    int  numOfPages = ddjvu_document_get_pagenum(doc); //количество страниц - строго!
    //QByteArray b = QFile::encodeName(fileName);
    //doc = ddjvu_document_create_by_filename(ctx, b, 1);
    if(!doc)
        qDebug() << "error create doc";
    if(!ctx)
        qDebug() << "error create context";


    const char *lvl = "page";
    //начало перебора по страницам
    isbnMethods find;
    int numOfSearchPages = 15;
    //qDebug() << "num of pages " << numOfPages;
    if(numOfPages < numOfSearchPages)
    {
        numOfSearchPages = numOfPages;
    }
    for (int pageCount = 0 ; pageCount < numOfSearchPages ; pageCount++)
    {

        miniexp_t r = miniexp_nil;
        while ((r = ddjvu_document_get_pagetext(doc, pageCount ,lvl))==miniexp_dummy);
        r = miniexp_nth(5, r);
        //if ( r == miniexp_nil )
        //    qDebug() << "r = null";
        const char *pageDumpArr = miniexp_to_str( r );
        QString pageDump( QString::fromUtf8( pageDumpArr ));

        find.findIsbns(pageDump, ISBNList);

        //qDebug() << fileName << " content: \n" <<  pageDump ;
    }
    //конец перебора по страницам
    if (doc)
        ddjvu_document_release(doc); //освобождаем контекст документа
    if (ctx)
        ddjvu_context_release(ctx); //освобождаем контескт приложени¤ (возможно стоит оставить)

}
Пример #14
0
static void
djvu_text_page_limits_process (DjvuTextPage *page,
			       miniexp_t     p, 
			       EvRectangle  *rect)
{
	EvRectangle current;
	const char *text;
	
	current.x1 = miniexp_to_int (miniexp_nth (1, p));
	current.y1 = miniexp_to_int (miniexp_nth (2, p));
	current.x2 = miniexp_to_int (miniexp_nth (3, p));
	current.y2 = miniexp_to_int (miniexp_nth (4, p));
	text = miniexp_to_str (miniexp_nth (5, p));
	if (current.x2 >= rect->x1 && current.y1 <= rect->y2 &&
	    current.x1 <= rect->x2 && current.y2 >= rect->y1 &&
	    text != NULL && text[0] != '\0') {
	    	if (page->start == miniexp_nil)
	    		page->start = p;
	    	page->end = p;
	}
}
Пример #15
0
static QString loadText(miniexp_t textExp, const QRect& rect, int pageHeight)
{
    const int textLength = miniexp_length(textExp);

    if(textLength >= 6 && miniexp_symbolp(miniexp_nth(0, textExp)))
    {
        const int xmin = miniexp_to_int(miniexp_nth(1, textExp));
        const int ymin = miniexp_to_int(miniexp_nth(2, textExp));
        const int xmax = miniexp_to_int(miniexp_nth(3, textExp));
        const int ymax = miniexp_to_int(miniexp_nth(4, textExp));

        if(rect.intersects(QRect(xmin, pageHeight - ymax, xmax - xmin, ymax - ymin)))
        {
            if(qstrncmp(miniexp_to_name(miniexp_nth(0, textExp)), "word", 4) == 0)
            {
                return QString::fromUtf8(miniexp_to_str(miniexp_nth(5, textExp)));
            }
            else
            {
                QStringList text;

                for(int textN = 5; textN < textLength; ++textN)
                {
                    text.append(loadText(miniexp_nth(textN, textExp), rect, pageHeight));
                }

                if(qstrncmp(miniexp_to_name(miniexp_nth(0, textExp)), "line", 4) == 0)
                {
                    return text.join(" ");
                }
                else
                {
                    return text.join("\n");
                }
            }
        }
    }

    return QString();
}
Пример #16
0
/**
 * djvu_text_page_selection_process:
 * @page: #DjvuTextPage instance
 * @p: s-expression to append
 * @delimit: character/word/... delimiter
 * 
 * Appends the string in @p to the page text.
 * 
 * Returns: whether the end was not reached in this s-expression
 */
static gboolean
djvu_text_page_selection_process (DjvuTextPage *page, 
                                  miniexp_t     p,
                                  int           delimit)
{
	if (page->text || p == page->start) {
		char *token_text = (char *) miniexp_to_str (miniexp_nth (5, p));
		if (page->text) {
			char *new_text =
			    g_strjoin (delimit & 2 ? "\n" : 
			    	       delimit & 1 ? " " : NULL,
				       page->text, token_text,
				       NULL);
			g_free (page->text);
			page->text = new_text;
		} else
			page->text = g_strdup (token_text);
		if (p == page->end) 
			return FALSE;
	}
	return TRUE;
}
Пример #17
0
void
dopage(int pageno)
{
  miniexp_t r = miniexp_nil;
  const char *lvl = (detail) ? detail : "page";
  while ((r = ddjvu_document_get_pagetext(doc,pageno-1,lvl))==miniexp_dummy)
    handle(TRUE);
  if (detail)
    {
      miniexp_io_t io;
      miniexp_io_init(&io);
      io.p_print7bits = &escape;
      miniexp_pprint_r(&io, r, 72);
    }
  else if ((r = miniexp_nth(5, r)) && miniexp_stringp(r))
    {
      const char *s = miniexp_to_str(r); 
      if (! escape)
        fputs(s, stdout);
      else
        {
          unsigned char c;
          while ((c = *(unsigned char*)s++))
            {
              bool esc = false;
              if (c == '\\' || c >= 0x7f)
                esc = true; /* non-ascii */
              if (c < 0x20 && !strchr("\013\035\037\012", c))
                esc = true; /* non-printable other than separators */
              if (esc)
                printf("\\%03o", c);
              else
                putc(c, stdout);
            }
        }
      fputs("\n\f", stdout);
    }
}
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;
}
Пример #19
0
QList< QRectF > Model::DjVuPage::search(const QString& text, bool matchCase) const
{
    QMutexLocker mutexLocker(&m_parent->m_mutex);

    miniexp_t pageTextExp;

    while(true)
    {
        pageTextExp = ddjvu_document_get_pagetext(m_parent->m_document, m_index, "word");

        if(pageTextExp == miniexp_dummy)
        {
            clearMessageQueue(m_parent->m_context, true);
        }
        else
        {
            break;
        }
    }

    QList< miniexp_t > words;
    QList< QRectF > results;

    words.append(pageTextExp);

    QRectF rect;
    int index = 0;

    while(!words.isEmpty())
    {
        miniexp_t textExp = words.takeFirst();

        const int textLength = miniexp_length(textExp);

        if(textLength >= 6 && miniexp_symbolp(miniexp_nth(0, textExp)))
        {
            if(qstrncmp(miniexp_to_name(miniexp_nth(0, textExp)), "word", 4) == 0)
            {
                const QString word = QString::fromUtf8(miniexp_to_str(miniexp_nth(5, textExp)));

                if(text.indexOf(word, index, matchCase ? Qt::CaseSensitive : Qt::CaseInsensitive) == index)
                {
                    const int xmin = miniexp_to_int(miniexp_nth(1, textExp));
                    const int ymin = miniexp_to_int(miniexp_nth(2, textExp));
                    const int xmax = miniexp_to_int(miniexp_nth(3, textExp));
                    const int ymax = miniexp_to_int(miniexp_nth(4, textExp));

                    rect = rect.united(QRectF(xmin, m_size.height() - ymax, xmax - xmin, ymax - ymin));

                    index += word.length();

                    while(text.length() > index && text.at(index).isSpace())
                    {
                        ++index;
                    }

                    if(text.length() == index)
                    {
                        results.append(rect);

                        rect = QRectF();
                        index = 0;
                    }
                }
                else
                {
                    rect = QRectF();
                    index = 0;
                }
            }
            else
            {
                for(int textN = 5; textN < textLength; ++textN)
                {
                    words.append(miniexp_nth(textN, textExp));
                }
            }
        }
    }

    ddjvu_miniexp_release(m_parent->m_document, pageTextExp);

    QTransform transform = QTransform::fromScale(72.0 / m_resolution, 72.0 / m_resolution);

    for(int index = 0; index < results.size(); ++index)
    {
        results[index] = transform.mapRect(results[index]);
    }

    return results;
}
Пример #20
0
QList< Model::Link* > Model::DjVuPage::links() const
{
    QMutexLocker mutexLocker(&m_parent->m_mutex);

    QList< Link* > links;

    miniexp_t pageAnnoExp;

    while(true)
    {
        pageAnnoExp = ddjvu_document_get_pageanno(m_parent->m_document, m_index);

        if(pageAnnoExp == miniexp_dummy)
        {
            clearMessageQueue(m_parent->m_context, true);
        }
        else
        {
            break;
        }
    }

    const int pageAnnoLength = miniexp_length(pageAnnoExp);

    for(int pageAnnoN = 0; pageAnnoN < pageAnnoLength; ++pageAnnoN)
    {
        miniexp_t linkExp = miniexp_nth(pageAnnoN, pageAnnoExp);

        if(miniexp_length(linkExp) <= 3 || qstrncmp(miniexp_to_name(miniexp_nth(0, linkExp)), "maparea", 7 ) != 0 || !miniexp_symbolp(miniexp_nth(0, miniexp_nth(3, linkExp))))
        {
            continue;
        }

        const QString type = QString::fromUtf8(miniexp_to_name(miniexp_nth(0, miniexp_nth(3, linkExp))));

        if(type == QLatin1String("rect") || type == QLatin1String("oval") || type == QLatin1String("poly"))
        {
            // boundary

            QPainterPath boundary;

            miniexp_t areaExp = miniexp_nth(3, linkExp);
            const int areaLength = miniexp_length( areaExp );

            if(areaLength == 5 && (type == QLatin1String("rect") || type == QLatin1String("oval")))
            {
                QPoint p(miniexp_to_int(miniexp_nth(1, areaExp)), miniexp_to_int(miniexp_nth(2, areaExp)));
                QSize s(miniexp_to_int(miniexp_nth(3, areaExp)), miniexp_to_int(miniexp_nth(4, areaExp)));

                p.setY(m_size.height() - s.height() - p.y());

                const QRectF r(p, s);

                if(type == QLatin1String("rect"))
                {
                    boundary.addRect(r);
                }
                else
                {
                    boundary.addEllipse(r);
                }
            }
            else if(areaLength > 0 && areaLength % 2 == 1 && type == QLatin1String("poly"))
            {
                QPolygon polygon;

                for(int areaExpN = 1; areaExpN < areaLength; areaExpN += 2)
                {
                    QPoint p(miniexp_to_int(miniexp_nth(areaExpN, areaExp)), miniexp_to_int(miniexp_nth(areaExpN + 1, areaExp)));

                    p.setY(m_size.height() - p.y());

                    polygon << p;
                }

                boundary.addPolygon(polygon);
            }

            if(boundary.isEmpty())
            {
                continue;
            }

            boundary = QTransform::fromScale(1.0 / m_size.width(), 1.0 / m_size.height()).map(boundary);

            // target

            QString target;

            miniexp_t targetExp = miniexp_nth(1, linkExp);

            if(miniexp_stringp(targetExp))
            {
                target = QString::fromUtf8(miniexp_to_str(miniexp_nth(1, linkExp)));
            }
            else if(miniexp_length(targetExp) == 3 && qstrncmp(miniexp_to_name(miniexp_nth(0, targetExp)), "url", 3) == 0)
            {
                target = QString::fromUtf8(miniexp_to_str(miniexp_nth(1, targetExp)));
            }

            if(target.isEmpty())
            {
                continue;
            }

            if(target.at(0) == QLatin1Char('#'))
            {
                target.remove(0, 1);

                bool ok = false;
                int targetPage = target.toInt(&ok);

                if(!ok)
                {
                    if(m_parent->m_indexByName.contains(target))
                    {
                        targetPage = m_parent->m_indexByName[target] + 1;
                    }
                    else
                    {
                        continue;
                    }
                }
                else
                {
                    targetPage = (target.at(0) == QLatin1Char('+') || target.at(0) == QLatin1Char('-')) ? m_index + targetPage : targetPage;
                }

                links.append(new Link(boundary, targetPage));
            }
            else
            {
                links.append(new Link(boundary, target));
            }
        }
    }

    ddjvu_miniexp_release(m_parent->m_document, pageAnnoExp);

    return links;
}
Пример #21
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);
  }
}
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);
    }
}
Пример #23
0
/*
 * Return a table like following:
 * {
 *    -- a line entry
 *    1 = {
 *       1 = {word="This", x0=377, y0=4857, x1=2427, y1=5089},
 *       2 = {word="is", x0=377, y0=4857, x1=2427, y1=5089},
 *       3 = {word="Word", x0=377, y0=4857, x1=2427, y1=5089},
 *       4 = {word="List", x0=377, y0=4857, x1=2427, y1=5089},
 *       x0 = 377, y0 = 4857, x1 = 2427, y1 = 5089,
 *    },
 *
 *    -- an other line entry
 *    2 = {
 *       1 = {word="This", x0=377, y0=4857, x1=2427, y1=5089},
 *       2 = {word="is", x0=377, y0=4857, x1=2427, y1=5089},
 *       x0 = 377, y0 = 4857, x1 = 2427, y1 = 5089,
 *    },
 * }
 */
static int getPageText(lua_State *L) {
	DjvuDocument *doc = (DjvuDocument*) luaL_checkudata(L, 1, "djvudocument");
	int pageno = luaL_checkint(L, 2);

	/* get page height for coordinates transform */
	ddjvu_pageinfo_t info;
	ddjvu_status_t r;
	while ((r=ddjvu_document_get_pageinfo(
				   doc->doc_ref, pageno-1, &info))<DDJVU_JOB_OK) {
		handle(L, doc->context, TRUE);
	}
	if (r>=DDJVU_JOB_FAILED)
		return luaL_error(L, "cannot get page #%d information", pageno);

	/* start retrieving page text */
	miniexp_t sexp, se_line, se_word;
	int i = 1, j = 1, counter_l = 1, counter_w=1,
		nr_line = 0, nr_word = 0;
	const char *word = NULL;

	while ((sexp = ddjvu_document_get_pagetext(doc->doc_ref, pageno-1, "word"))
				== miniexp_dummy) {
		handle(L, doc->context, True);
	}

	/* throuw page info and obtain lines info, after this, sexp's entries
	 * are lines. */
	sexp = miniexp_cdr(sexp);
	/* get number of lines in a page */
	nr_line = miniexp_length(sexp);
	/* table that contains all the lines */
	lua_newtable(L);

	counter_l = 1;
	for(i = 1; i <= nr_line; i++) {
		/* retrive one line entry */
		se_line = miniexp_nth(i, sexp);
		nr_word = miniexp_length(se_line);
		if (nr_word == 0) {
			continue;
		}

		/* subtable that contains words in a line */
		lua_pushnumber(L, counter_l);
		lua_newtable(L);
		counter_l++;

		/* set line position */
		lua_pushstring(L, "x0");
		lua_pushnumber(L, miniexp_to_int(miniexp_nth(1, se_line)));
		lua_settable(L, -3);

		lua_pushstring(L, "y1");
		lua_pushnumber(L,
				info.height - miniexp_to_int(miniexp_nth(2, se_line)));
		lua_settable(L, -3);

		lua_pushstring(L, "x1");
		lua_pushnumber(L, miniexp_to_int(miniexp_nth(3, se_line)));
		lua_settable(L, -3);

		lua_pushstring(L, "y0");
		lua_pushnumber(L,
				info.height - miniexp_to_int(miniexp_nth(4, se_line)));
		lua_settable(L, -3);

		/* now loop through each word in the line */
		counter_w = 1;
		for(j = 1; j <= nr_word; j++) {
			/* retrive one word entry */
			se_word = miniexp_nth(j, se_line);
			/* check to see whether the entry is empty */
			word = miniexp_to_str(miniexp_nth(5, se_word));
			if (!word) {
				continue;
			}

			/* create table that contains info for a word */
			lua_pushnumber(L, counter_w);
			lua_newtable(L);
			counter_w++;

			/* set word info */
			lua_pushstring(L, "x0");
			lua_pushnumber(L, miniexp_to_int(miniexp_nth(1, se_word)));
			lua_settable(L, -3);

			lua_pushstring(L, "y1");
			lua_pushnumber(L,
					info.height - miniexp_to_int(miniexp_nth(2, se_word)));
			lua_settable(L, -3);

			lua_pushstring(L, "x1");
			lua_pushnumber(L, miniexp_to_int(miniexp_nth(3, se_word)));
			lua_settable(L, -3);

			lua_pushstring(L, "y0");
			lua_pushnumber(L,
					info.height - miniexp_to_int(miniexp_nth(4, se_word)));
			lua_settable(L, -3);

			lua_pushstring(L, "word");
			lua_pushstring(L, word);
			lua_settable(L, -3);

			/* set word entry to line subtable */
			lua_settable(L, -3);
		} /* end of for (j) */

		/* set line entry to page text table */
		lua_settable(L, -3);
	} /* end of for (i) */

	return 1;
}