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; }
QString Model::DjVuPage::text(const QRectF& rect) 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; } } const QString text = loadText(pageTextExp, QTransform::fromScale(m_resolution / 72.0, m_resolution / 72.0).mapRect(rect).toRect(), m_size.height()); ddjvu_miniexp_release(m_parent->m_document, pageTextExp); return text.trimmed(); }
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); }
jobject djvu_links_get_links(JNIEnv *jenv, ddjvu_document_t* djvu_document, int page) { DEBUG("djvu_links_get_links %d", page); miniexp_t page_annotations = miniexp_nil; miniexp_t *hyperlinks = NULL, *iter = NULL; ddjvu_pageinfo_t page_info; jobject arrayList = NULL; page_annotations = ddjvu_document_get_pageanno(djvu_document, page); ddjvu_document_get_pageinfo(djvu_document, page, &page_info); if (page_annotations) { hyperlinks = ddjvu_anno_get_hyperlinks(page_annotations); if (hyperlinks) { jclass arrayListClass = jenv->FindClass("java/util/ArrayList"); if (!arrayListClass) return arrayList; jmethodID alInitMethodId = jenv->GetMethodID(arrayListClass, "<init>", "()V"); if (!alInitMethodId) return arrayList; jmethodID alAddMethodId = jenv->GetMethodID(arrayListClass, "add", "(Ljava/lang/Object;)Z"); if (!alAddMethodId) return arrayList; arrayList = jenv->NewObject(arrayListClass, alInitMethodId); if (!arrayList) return arrayList; for (iter = hyperlinks; *iter; ++iter) { jobject hl = get_djvu_hyperlink_mapping(jenv, djvu_document, &page_info, *iter); if (hl) jenv->CallBooleanMethod(arrayList, alAddMethodId, hl); //jenv->DeleteLocalRef(hl); } free(hyperlinks); } ddjvu_miniexp_release(djvu_document, page_annotations); } return arrayList; }
gboolean djvu_links_has_document_links (EvDocumentLinks *document_links) { DjvuDocument *djvu_document = DJVU_DOCUMENT (document_links); miniexp_t outline; while ((outline = ddjvu_document_get_outline (djvu_document->d_document)) == miniexp_dummy) djvu_handle_events (djvu_document, TRUE, NULL); if (outline) { ddjvu_miniexp_release (djvu_document->d_document, outline); return TRUE; } return FALSE; }
EvMappingList * djvu_links_get_links (EvDocumentLinks *document_links, gint page, double scale_factor) { DjvuDocument *djvu_document = DJVU_DOCUMENT (document_links); GList *retval = NULL; miniexp_t page_annotations = miniexp_nil; miniexp_t *hyperlinks = NULL, *iter = NULL; EvMapping *ev_link_mapping; ddjvu_pageinfo_t page_info; while ((page_annotations = ddjvu_document_get_pageanno (djvu_document->d_document, page)) == miniexp_dummy) djvu_handle_events (djvu_document, TRUE, NULL); while (ddjvu_document_get_pageinfo (djvu_document->d_document, page, &page_info) < DDJVU_JOB_OK) djvu_handle_events(djvu_document, TRUE, NULL); if (page_annotations) { hyperlinks = ddjvu_anno_get_hyperlinks (page_annotations); if (hyperlinks) { for (iter = hyperlinks; *iter; ++iter) { ev_link_mapping = get_djvu_hyperlink_mapping (djvu_document, page, &page_info, *iter); if (ev_link_mapping) { ev_link_mapping->area.x1 *= scale_factor; ev_link_mapping->area.x2 *= scale_factor; ev_link_mapping->area.y1 *= scale_factor; ev_link_mapping->area.y2 *= scale_factor; retval = g_list_prepend (retval, ev_link_mapping); } } free (hyperlinks); } ddjvu_miniexp_release (djvu_document->d_document, page_annotations); } return ev_mapping_list_new (page, retval, (GDestroyNotify)g_object_unref); }
GtkTreeModel * djvu_links_get_links_model (EvDocumentLinks *document_links) { DjvuDocument *djvu_document = DJVU_DOCUMENT (document_links); GtkTreeModel *model = NULL; miniexp_t outline = miniexp_nil; while ((outline = ddjvu_document_get_outline (djvu_document->d_document)) == miniexp_dummy) djvu_handle_events (djvu_document, TRUE, NULL); if (outline) { model = (GtkTreeModel *) gtk_tree_store_new (EV_DOCUMENT_LINKS_COLUMN_NUM_COLUMNS, G_TYPE_STRING, G_TYPE_OBJECT, G_TYPE_BOOLEAN, G_TYPE_STRING); build_tree (djvu_document, model, NULL, outline); ddjvu_miniexp_release (djvu_document->d_document, outline); } return model; }
QList< QRectF > DjVuPage::search(const QString& text, bool matchCase, bool wholeWords) const { LOCK_PAGE miniexp_t pageTextExp = miniexp_nil; { LOCK_PAGE_GLOBAL 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; } } } const QTransform transform = QTransform::fromScale(72.0 / m_resolution, 72.0 / m_resolution); const QStringList words = text.split(QRegExp(QLatin1String("\\W+")), QString::SkipEmptyParts); const QList< QRectF > results = findText(pageTextExp, m_size, transform, words, matchCase, wholeWords); { LOCK_PAGE_GLOBAL ddjvu_miniexp_release(m_parent->m_document, pageTextExp); } return results; }
void Model::DjVuDocument::loadOutline(QStandardItemModel* outlineModel) const { Document::loadOutline(outlineModel); QMutexLocker mutexLocker(&m_mutex); miniexp_t outlineExp; while(true) { outlineExp = ddjvu_document_get_outline(m_document); if(outlineExp == miniexp_dummy) { clearMessageQueue(m_context, true); } else { break; } } if(miniexp_length(outlineExp) <= 1) { return; } if(qstrncmp(miniexp_to_name(miniexp_nth(0, outlineExp)), "bookmarks", 9) != 0) { return; } ::loadOutline(outlineExp, 1, outlineModel->invisibleRootItem(), m_indexByName); ddjvu_miniexp_release(m_document, outlineExp); }
QString DjVuPage::text(const QRectF& rect) const { LOCK_PAGE miniexp_t pageTextExp = miniexp_nil; { LOCK_PAGE_GLOBAL 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; } } } const QTransform transform = QTransform::fromScale(m_resolution / 72.0, m_resolution / 72.0); const QString text = loadText(pageTextExp, m_size, transform.mapRect(rect)).simplified(); { LOCK_PAGE_GLOBAL ddjvu_miniexp_release(m_parent->m_document, pageTextExp); } return text.simplified(); }
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; }
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; }