X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=blobdiff_plain;f=backend%2Fpdf%2Fev-poppler.cc;h=fb2a5ba5d8399697f08fa231e3692b39477894bc;hb=1535a8e52feeffa1ad445ca4f1b49b8e5f7b40dd;hp=ec2bbc0835b7f01636344c939e2930d2145c09ce;hpb=c561c0a1ff7ff46f1a1cf781b0d9b30a1599d1d7;p=evince.git diff --git a/backend/pdf/ev-poppler.cc b/backend/pdf/ev-poppler.cc index ec2bbc08..fb2a5ba5 100644 --- a/backend/pdf/ev-poppler.cc +++ b/backend/pdf/ev-poppler.cc @@ -52,6 +52,11 @@ #include "ev-attachment.h" #include "ev-image.h" +#include +#include +#include +#include + #if (defined (HAVE_POPPLER_PAGE_RENDER)) && (defined (HAVE_CAIRO_PDF) || defined (HAVE_CAIRO_PS)) #define HAVE_CAIRO_PRINT #endif @@ -573,6 +578,94 @@ pdf_document_set_password (EvDocumentSecurity *document_security, document->password = g_strdup (password); } + +/* reference: +http://www.pdfa.org/lib/exe/fetch.php?id=pdfa%3Aen%3Atechdoc&cache=cache&media=pdfa:techdoc:tn0001_pdfa-1_and_namespaces_2008-03-18.pdf */ +static char * +pdf_document_get_format_from_metadata (const char *metadata) +{ + xmlDocPtr doc; + xmlXPathContextPtr xpathCtx; + xmlXPathObjectPtr xpathObj; + xmlChar *part = NULL; + xmlChar *conf = NULL; + char *result = NULL; + int i; + + doc = xmlParseMemory (metadata, strlen (metadata)); + if (doc == NULL) + return NULL; /* invalid xml metadata */ + + xpathCtx = xmlXPathNewContext (doc); + if (xpathCtx == NULL) { + xmlFreeDoc (doc); + return NULL; /* invalid xpath context */ + } + + /* add pdf/a namespaces */ + xmlXPathRegisterNs (xpathCtx, BAD_CAST "x", BAD_CAST "adobe:ns:meta/"); + xmlXPathRegisterNs (xpathCtx, BAD_CAST "rdf", BAD_CAST "http://www.w3.org/1999/02/22-rdf-syntax-ns#"); + xmlXPathRegisterNs (xpathCtx, BAD_CAST "pdfaid", BAD_CAST "http://www.aiim.org/pdfa/ns/id/"); + + /* reads pdf/a part */ + /* first syntax: child node */ + xpathObj = xmlXPathEvalExpression (BAD_CAST "/x:xmpmeta/rdf:RDF/rdf:Description/pdfaid:part", xpathCtx); + if (xpathObj != NULL) { + if (xpathObj->nodesetval != NULL && xpathObj->nodesetval->nodeNr != 0) + part = xmlNodeGetContent (xpathObj->nodesetval->nodeTab[0]); + + xmlXPathFreeObject (xpathObj); + } + if (part == NULL) { + /* second syntax: attribute */ + xpathObj = xmlXPathEvalExpression (BAD_CAST "/x:xmpmeta/rdf:RDF/rdf:Description/@pdfaid:part", xpathCtx); + if (xpathObj != NULL) { + if (xpathObj->nodesetval != NULL && xpathObj->nodesetval->nodeNr != 0) + part = xmlNodeGetContent (xpathObj->nodesetval->nodeTab[0]); + + xmlXPathFreeObject (xpathObj); + } + } + + /* reads pdf/a conformance */ + /* first syntax: child node */ + xpathObj = xmlXPathEvalExpression (BAD_CAST "/x:xmpmeta/rdf:RDF/rdf:Description/pdfaid:conformance", xpathCtx); + if (xpathObj != NULL) { + if (xpathObj->nodesetval != NULL && xpathObj->nodesetval->nodeNr != 0) + conf = xmlNodeGetContent (xpathObj->nodesetval->nodeTab[0]); + + xmlXPathFreeObject (xpathObj); + } + if (conf == NULL) { + /* second syntax: attribute */ + xpathObj = xmlXPathEvalExpression (BAD_CAST "/x:xmpmeta/rdf:RDF/rdf:Description/@pdfaid:conformance", xpathCtx); + if (xpathObj != NULL) { + if (xpathObj->nodesetval != NULL && xpathObj->nodesetval->nodeNr != 0) + conf = xmlNodeGetContent (xpathObj->nodesetval->nodeTab[0]); + + xmlXPathFreeObject (xpathObj); + } + } + + if (part != NULL && conf != NULL) { + /* makes conf lowercase */ + for (i = 0; conf[i]; i++) + conf[i] = g_ascii_tolower (conf[i]); + + /* return buffer */ + result = g_strdup_printf ("PDF/A - %s%s", part, conf); + } + + /* Cleanup */ + xmlFree (part); + xmlFree (conf); + xmlXPathFreeContext (xpathCtx); + xmlFreeDoc (doc); + + return result; +} + + static EvDocumentInfo * pdf_document_get_info (EvDocument *document) { @@ -582,6 +675,8 @@ pdf_document_get_info (EvDocument *document) PopplerViewerPreferences view_prefs; PopplerPermissions permissions; EvPage *page; + char *metadata; + char *fmt; info = g_new0 (EvDocumentInfo, 1); @@ -618,8 +713,18 @@ pdf_document_get_info (EvDocument *document) "creation-date", &(info->creation_date), "mod-date", &(info->modified_date), "linearized", &(info->linearized), + "metadata", &metadata, NULL); + if (metadata != NULL) { + fmt = pdf_document_get_format_from_metadata(metadata); + if (fmt != NULL) { + g_free (info->format); + info->format = fmt; + } + g_free (metadata); + } + info->n_pages = ev_document_get_n_pages (document); if (info->n_pages > 0) { @@ -910,9 +1015,11 @@ ev_link_dest_from_dest (PdfDocument *pdf_document, g_object_unref (poppler_page); } break; - case POPPLER_DEST_FIT: + case POPPLER_DEST_FITB: + case POPPLER_DEST_FIT: ev_dest = ev_link_dest_new_fit (dest->page_num - 1); break; + case POPPLER_DEST_FITBH: case POPPLER_DEST_FITH: { PopplerPage *poppler_page; double height; @@ -926,6 +1033,7 @@ ev_link_dest_from_dest (PdfDocument *pdf_document, g_object_unref (poppler_page); } break; + case POPPLER_DEST_FITBV: case POPPLER_DEST_FITV: ev_dest = ev_link_dest_new_fitv (dest->page_num - 1, dest->left, @@ -946,15 +1054,6 @@ ev_link_dest_from_dest (PdfDocument *pdf_document, g_object_unref (poppler_page); } break; - case POPPLER_DEST_FITB: - unimplemented_dest = "POPPLER_DEST_FITB"; - break; - case POPPLER_DEST_FITBH: - unimplemented_dest = "POPPLER_DEST_FITBH"; - break; - case POPPLER_DEST_FITBV: - unimplemented_dest = "POPPLER_DEST_FITBV"; - break; case POPPLER_DEST_NAMED: ev_dest = ev_link_dest_new_named (dest->named_dest); break; @@ -1374,9 +1473,9 @@ pdf_document_thumbnails_get_dimensions (EvDocumentThumbnails *document_thumbnail poppler_page_get_size (POPPLER_PAGE (rc->page->backend_page), &page_width, &page_height); - *width = (gint) MAX (page_width * rc->scale, 1); - *height = (gint) MAX (page_height * rc->scale, 1); - + *width = MAX ((gint)(page_width * rc->scale + 0.5), 1); + *height = MAX ((gint)(page_height * rc->scale + 0.5), 1); + if (rc->rotation == 90 || rc->rotation == 270) { gint temp;