#include "gpdf-g-switch.h"
#include "ev-document-links.h"
#include "ev-document-misc.h"
+#include "ev-document-security.h"
#include "ev-document-thumbnails.h"
#include "GlobalParams.h"
#include "SplashBitmap.h"
#include "PDFDoc.h"
#include "Outline.h"
+#include "ErrorCodes.h"
#include "UnicodeMap.h"
#include "GlobalParams.h"
#include "GfxState.h"
GDKSplashOutputDev *out;
PSOutputDev *ps_out;
PDFDoc *doc;
+ Links *links;
UnicodeMap *umap;
+ gchar *password;
gboolean page_valid;
PdfDocumentSearch *search;
};
-static void pdf_document_document_links_iface_init (EvDocumentLinksIface *iface);
+static void pdf_document_document_links_iface_init (EvDocumentLinksIface *iface);
static void pdf_document_document_thumbnails_iface_init (EvDocumentThumbnailsIface *iface);
static void pdf_document_document_iface_init (EvDocumentIface *iface);
-static void pdf_document_ps_exporter_iface_init (EvPSExporterIface *iface);
-static void pdf_document_find_iface_init (EvDocumentFindIface *iface);
-static void pdf_document_search_free (PdfDocumentSearch *search);
-static void pdf_document_search_page_changed (PdfDocumentSearch *search);
+static void pdf_document_ps_exporter_iface_init (EvPSExporterIface *iface);
+static void pdf_document_find_iface_init (EvDocumentFindIface *iface);
+static void pdf_document_security_iface_init (EvDocumentSecurityIface *iface);
+static void pdf_document_search_free (PdfDocumentSearch *search);
+static void pdf_document_search_page_changed (PdfDocumentSearch *search);
+
G_DEFINE_TYPE_WITH_CODE (PdfDocument, pdf_document, G_TYPE_OBJECT,
{
pdf_document_ps_exporter_iface_init);
G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_FIND,
pdf_document_find_iface_init);
+ G_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_SECURITY,
+ pdf_document_security_iface_init);
});
+static void
+document_init_links (PdfDocument *pdf_document)
+{
+ Page *page;
+ Object obj;
+
+ if (pdf_document->links) {
+ delete pdf_document->links;
+ }
+ page = pdf_document->doc->getCatalog ()->getPage (pdf_document->page);
+ pdf_document->links = new Links (page->getAnnots (&obj),
+ pdf_document->doc->getCatalog ()->getBaseURI ());
+ obj.free ();
+}
+
static gboolean
document_validate_page (PdfDocument *pdf_document)
{
72 * pdf_document->scale,
0, gTrue, gTrue);
+ document_init_links (pdf_document);
+
pdf_document->page_valid = TRUE;
+ ev_document_changed (EV_DOCUMENT (pdf_document));
+
/* Update the search results available to the app since
* we only provide full results on the current page
*/
g_free (filename);
// open the PDF file, assumes ownership of filename_g
- newDoc = new PDFDoc(filename_g, 0, 0);
+ GString *password = NULL;
+ if (pdf_document->password)
+ password = new GString (pdf_document->password);
+ newDoc = new PDFDoc(filename_g, password, password);
+ if (password)
+ delete password;
if (!newDoc->isOk()) {
err = newDoc->getErrorCode();
delete newDoc;
-
- /* FIXME: Add a real error enum to EvDocument */
- g_set_error (error, G_FILE_ERROR,
- G_FILE_ERROR_FAILED,
- "Failed to load document (error %d) '%s'\n",
- err,
- uri);
+ if (err == errEncrypted) {
+ g_set_error (error, EV_DOCUMENT_ERROR,
+ EV_DOCUMENT_ERROR_ENCRYPTED,
+ "Document is encrypted.");
+ } else {
+ g_set_error (error, G_FILE_ERROR,
+ G_FILE_ERROR_FAILED,
+ "Failed to load document (error %d) '%s'\n",
+ err,
+ uri);
+ }
return FALSE;
}
pdf_document->page = page;
pdf_document->page_valid = FALSE;
}
-
- ev_document_changed (document);
}
static int
g_free (search);
}
+static gboolean
+pdf_document_has_document_security (EvDocumentSecurity *document_security)
+{
+ /* FIXME: do we really need to have this? */
+ return FALSE;
+}
+
+static void
+pdf_document_set_password (EvDocumentSecurity *document_security,
+ const char *password)
+{
+ PdfDocument *document = PDF_DOCUMENT (document_security);
+
+ if (document->password)
+ g_free (document->password);
+
+ document->password = g_strdup (password);
+}
+
static void
pdf_document_ps_export_begin (EvPSExporter *exporter, const char *filename)
{
return (EvDocumentLinksIter *) iter;
}
-/* FIXME This returns a new object every time, probably we should cache it
- in the iter */
static EvLink *
-pdf_document_links_get_link (EvDocumentLinks *document_links,
- EvDocumentLinksIter *links_iter)
+build_link_from_action (PdfDocument *pdf_document,
+ LinkAction *link_action,
+ const char *title)
{
- PdfDocument *pdf_document = PDF_DOCUMENT (document_links);
EvLink *link = NULL;
- LinksIter *iter = (LinksIter *)links_iter;
- OutlineItem *anItem;
- LinkAction *link_action;
- Unicode *link_title;
- const char *title;
-
- g_return_val_if_fail (PDF_IS_DOCUMENT (document_links), FALSE);
- g_return_val_if_fail (iter != NULL, FALSE);
-
- anItem = (OutlineItem *)iter->items->get(iter->index);
- link_action = anItem->getAction ();
- link_title = anItem->getTitle ();
- title = unicode_to_char (anItem, pdf_document->umap);
if (link_action == NULL) {
link = ev_link_new_title (title);
return link;
}
+/* FIXME This returns a new object every time, probably we should cache it
+ in the iter */
+static EvLink *
+pdf_document_links_get_link (EvDocumentLinks *document_links,
+ EvDocumentLinksIter *links_iter)
+{
+ PdfDocument *pdf_document = PDF_DOCUMENT (document_links);
+ LinksIter *iter = (LinksIter *)links_iter;
+ OutlineItem *anItem;
+ LinkAction *link_action;
+ Unicode *link_title;
+ const char *title;
+
+ g_return_val_if_fail (PDF_IS_DOCUMENT (document_links), FALSE);
+ g_return_val_if_fail (iter != NULL, FALSE);
+
+ anItem = (OutlineItem *)iter->items->get(iter->index);
+ link_action = anItem->getAction ();
+ link_title = anItem->getTitle ();
+ title = unicode_to_char (anItem, pdf_document->umap);
+
+ return build_link_from_action (pdf_document, link_action, title);
+}
+
static EvDocumentLinksIter *
pdf_document_links_get_child (EvDocumentLinks *document_links,
- EvDocumentLinksIter *links_iter)
+ EvDocumentLinksIter *links_iter)
{
LinksIter *iter = (LinksIter *)links_iter;
LinksIter *child_iter;
static gboolean
pdf_document_links_next (EvDocumentLinks *document_links,
- EvDocumentLinksIter *links_iter)
+ EvDocumentLinksIter *links_iter)
{
LinksIter *iter = (LinksIter *) links_iter;
static void
pdf_document_links_free_iter (EvDocumentLinks *document_links,
- EvDocumentLinksIter *iter)
+ EvDocumentLinksIter *iter)
{
g_return_if_fail (PDF_IS_DOCUMENT (document_links));
g_return_if_fail (iter != NULL);
{
PdfDocument *pdf_document = PDF_DOCUMENT (object);
+ if (pdf_document->links) {
+ delete pdf_document->links;
+ }
+
if (pdf_document->umap) {
pdf_document->umap->decRefCnt ();
pdf_document->umap = NULL;
char *title = NULL;
Object info;
+ if (pdf_document->doc == NULL)
+ return NULL;
pdf_document->doc->getDocInfo (&info);
if (info.isDict ()) {
const char *text;
int x1, y1, x2, y2;
- x1 = rect->x;
- y1 = rect->y;
- x2 = x1 + rect->width;
- y2 = y1 + rect->height;
+ x1 = rect->x + pdf_document->page_x_offset;
+ y1 = rect->y + pdf_document->page_y_offset;
+ x2 = x1 + rect->width + pdf_document->page_x_offset;
+ y2 = y1 + rect->height + pdf_document->page_y_offset;
sel_text = pdf_document->out->getText (x1, y1, x2, y2);
text = sel_text->getCString ();
return text ? g_strdup (text) : NULL;
}
+static EvLink *
+pdf_document_get_link (EvDocument *document, int x, int y)
+{
+ PdfDocument *pdf_document = PDF_DOCUMENT (document);
+ LinkAction *action;
+ double link_x, link_y;
+
+ if (pdf_document->links == NULL) {
+ return NULL;
+ }
+
+ /* Offset */
+ link_x = x - pdf_document->page_x_offset;
+ link_y = y - pdf_document->page_y_offset;
+
+ /* Inverse y */
+ link_y = pdf_document->out->getBitmapHeight() - link_y;
+
+ /* Zoom */
+ link_x = link_x / pdf_document->scale;
+ link_y = link_y / pdf_document->scale;
+
+ action = pdf_document->links->find (link_x, link_y);
+
+ if (action) {
+ return build_link_from_action (pdf_document, action, "");
+ } else {
+ return NULL;
+ }
+}
+
static void
pdf_document_get_property (GObject *object,
guint prop_id,
iface->load = pdf_document_load;
iface->save = pdf_document_save;
iface->get_text = pdf_document_get_text;
+ iface->get_link = pdf_document_get_link;
iface->get_n_pages = pdf_document_get_n_pages;
iface->set_page = pdf_document_set_page;
iface->get_page = pdf_document_get_page;
iface->cancel = pdf_document_find_cancel;
}
+static void
+pdf_document_security_iface_init (EvDocumentSecurityIface *iface)
+{
+ iface->has_document_security = pdf_document_has_document_security;
+ iface->set_password = pdf_document_set_password;
+}
+
static void
pdf_document_document_links_iface_init (EvDocumentLinksIface *iface)
{
the_page = pdf_document->doc->getCatalog ()->getPage (page + 1);
the_page->getThumb (&the_thumb);
-
-
if (!(the_thumb.isNull () || the_thumb.isNone())) {
/* Build the thumbnail object */
thumb = new Thumb(pdf_document->doc->getXRef (),
pdf_document->scale = 1.;
pdf_document->page_valid = FALSE;
+ pdf_document->password = NULL;
}