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;
}
Esempio n. 2
0
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);
}
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;
}
Esempio 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;
}