From 6af4a5522670f351ea1b265332c1b722c2322903 Mon Sep 17 00:00:00 2001 From: B. Watson Date: Mon, 11 May 2015 20:41:46 -0400 Subject: office/zathura-pdf-mupdf: Updated for version 0.2.7. --- office/zathura-pdf-mupdf/README | 12 +- ...-correct-free-function-for-search-results.patch | 25 ++ ...itional-and-missing-link-types-in-outline.patch | 51 +++ .../patches/0003-Update-for-1.7-API-changes.patch | 352 +++++++++++++++++++++ .../0004-Enable-EPUB-support.patch.disabled | 45 +++ ...0005-Locate-and-extract-images-from-pages.patch | 311 ++++++++++++++++++ ...es-in-the-document-information-dictionary.patch | 147 +++++++++ office/zathura-pdf-mupdf/upstream.README | 23 ++ .../zathura-pdf-mupdf/zathura-pdf-mupdf.SlackBuild | 26 +- office/zathura-pdf-mupdf/zathura-pdf-mupdf.info | 8 +- 10 files changed, 986 insertions(+), 14 deletions(-) create mode 100644 office/zathura-pdf-mupdf/patches/0001-Use-correct-free-function-for-search-results.patch create mode 100644 office/zathura-pdf-mupdf/patches/0002-Handle-additional-and-missing-link-types-in-outline.patch create mode 100644 office/zathura-pdf-mupdf/patches/0003-Update-for-1.7-API-changes.patch create mode 100644 office/zathura-pdf-mupdf/patches/0004-Enable-EPUB-support.patch.disabled create mode 100644 office/zathura-pdf-mupdf/patches/0005-Locate-and-extract-images-from-pages.patch create mode 100644 office/zathura-pdf-mupdf/patches/0006-Parse-entries-in-the-document-information-dictionary.patch create mode 100644 office/zathura-pdf-mupdf/upstream.README (limited to 'office') diff --git a/office/zathura-pdf-mupdf/README b/office/zathura-pdf-mupdf/README index 707c63c1af..02740305b2 100644 --- a/office/zathura-pdf-mupdf/README +++ b/office/zathura-pdf-mupdf/README @@ -4,9 +4,9 @@ The zathura-pdf-mupdf plugin adds PDF support to zathura by using the mupdf rendering library (replacing the poppler-based PDF support from the zathura package). -Note: This overwrites /usr/lib/zathura/pdf.so from the zathura -package (replace lib with lib64 for 64-bit systems). zathura doesn't -support having multiple plugins per filetype, so after installing -zathura-pdf-mupdf, zathura will always use the mupdf backend. To switch -back to the poppler backend, remove both zathura and zathura-pdf-mupdf, -then reinstall zathura. +To switch between the mupdf and poppler backends without reinstalling +packages, adjust the symlink at /usr/lib(64)/zathura/pdf.so. It +should point to either pdf-mupdf/pdf.so or pdf-poppler/pdf.so. You can +also reinstall zathura to switch to the poppler backend, or reinstall +zathura-pdf-mupdf to switch to the mupdf backend (whichever was installed +last "wins"). diff --git a/office/zathura-pdf-mupdf/patches/0001-Use-correct-free-function-for-search-results.patch b/office/zathura-pdf-mupdf/patches/0001-Use-correct-free-function-for-search-results.patch new file mode 100644 index 0000000000..6eaa0775ad --- /dev/null +++ b/office/zathura-pdf-mupdf/patches/0001-Use-correct-free-function-for-search-results.patch @@ -0,0 +1,25 @@ +From e2dbf4be4709c54d3e3859eba4ceb9cdab8e6b43 Mon Sep 17 00:00:00 2001 +From: Moritz Lipp +Date: Thu, 20 Nov 2014 13:58:42 +0100 +Subject: [PATCH 1/6] Use correct free function for search results + +--- + search.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/search.c b/search.c +index d0a148f..3a9fad4 100644 +--- a/search.c ++++ b/search.c +@@ -26,7 +26,7 @@ pdf_page_search_text(zathura_page_t* page, mupdf_page_t* mupdf_page, const char* + + mupdf_document_t* mupdf_document = zathura_document_get_data(document);; + +- girara_list_t* list = girara_list_new2((girara_free_function_t) zathura_link_free); ++ girara_list_t* list = girara_list_new2(g_free); + if (list == NULL) { + if (error != NULL) { + *error = ZATHURA_ERROR_OUT_OF_MEMORY; +-- +1.8.4 + diff --git a/office/zathura-pdf-mupdf/patches/0002-Handle-additional-and-missing-link-types-in-outline.patch b/office/zathura-pdf-mupdf/patches/0002-Handle-additional-and-missing-link-types-in-outline.patch new file mode 100644 index 0000000000..fa62463d31 --- /dev/null +++ b/office/zathura-pdf-mupdf/patches/0002-Handle-additional-and-missing-link-types-in-outline.patch @@ -0,0 +1,51 @@ +From 23b5d6f2822bb27ec97de0701aefeed2a539f06a Mon Sep 17 00:00:00 2001 +From: Moritz Lipp +Date: Sat, 7 Feb 2015 15:56:59 +0100 +Subject: [PATCH 2/6] Handle additional and missing link types in outline + +--- + index.c | 20 +++++++++++++++++--- + 1 file changed, 17 insertions(+), 3 deletions(-) + +diff --git a/index.c b/index.c +index 023944f..80c1068 100644 +--- a/index.c ++++ b/index.c +@@ -73,17 +73,31 @@ build_index(fz_outline* outline, girara_tree_node_t* root) + if (gflags & fz_link_flag_t_valid) { + target.top = outline->dest.ld.gotor.lt.y; + } +- if (gflags & fz_link_flag_r_is_zoom) { +- target.scale = outline->dest.ld.gotor.rb.x; +- } ++ /* if (gflags & fz_link_flag_r_is_zoom) { */ ++ /* target.scale = outline->dest.ld.gotor.rb.x; */ ++ /* } */ + } + break; ++ case FZ_LINK_LAUNCH: ++ type = ZATHURA_LINK_LAUNCH; ++ target.value = outline->dest.ld.launch.file_spec; ++ break; ++ case FZ_LINK_NAMED: ++ type = ZATHURA_LINK_NAMED; ++ target.value = outline->dest.ld.named.named; ++ break; ++ case FZ_LINK_GOTOR: ++ type = ZATHURA_LINK_GOTO_REMOTE; ++ target.value = outline->dest.ld.gotor.file_spec; ++ break; + default: ++ outline = outline->next; // TODO: Don't skip unknown type + continue; + } + + index_element->link = zathura_link_new(type, rect, target); + if (index_element->link == NULL) { ++ outline = outline->next; + continue; + } + +-- +1.8.4 + diff --git a/office/zathura-pdf-mupdf/patches/0003-Update-for-1.7-API-changes.patch b/office/zathura-pdf-mupdf/patches/0003-Update-for-1.7-API-changes.patch new file mode 100644 index 0000000000..ecb78e0fbf --- /dev/null +++ b/office/zathura-pdf-mupdf/patches/0003-Update-for-1.7-API-changes.patch @@ -0,0 +1,352 @@ +From f96dd48825c049bbccb2e25a814c49d03fedf86c Mon Sep 17 00:00:00 2001 +From: Moritz Lipp +Date: Sun, 19 Apr 2015 10:39:02 +0200 +Subject: [PATCH 3/6] Update for 1.7 API changes + +Thanks to Leonardo Taccari +--- + README | 2 +- + document.c | 16 +++++++------- + image.c | 70 +++++++++++++++++++++++++++++++++++++++++--------------------- + index.c | 4 ++-- + links.c | 2 +- + page.c | 10 ++++----- + render.c | 8 +++---- + utils.c | 4 ++-- + 8 files changed, 70 insertions(+), 46 deletions(-) + +diff --git a/README b/README +index 9773daf..34db54a 100644 +--- a/README ++++ b/README +@@ -7,7 +7,7 @@ Requirements + ------------ + zathura (>= 0.2.0) + girara +-mupdf (>= 1.3) ++mupdf (>= 1.7) + openjpeg (>= 2.0) + + Installation +diff --git a/document.c b/document.c +index ec26e9d..38e70b5 100644 +--- a/document.c ++++ b/document.c +@@ -51,14 +51,14 @@ pdf_document_open(zathura_document_t* document) + } + + /* authenticate if password is required and given */ +- if (fz_needs_password(mupdf_document->document) != 0) { +- if (password == NULL || fz_authenticate_password(mupdf_document->document, (char*) password) == 0) { ++ if (fz_needs_password(mupdf_document->ctx, mupdf_document->document) != 0) { ++ if (password == NULL || fz_authenticate_password(mupdf_document->ctx, mupdf_document->document, (char*) password) == 0) { + error = ZATHURA_ERROR_INVALID_PASSWORD; + goto error_free; + } + } + +- zathura_document_set_number_of_pages(document, fz_count_pages(mupdf_document->document)); ++ zathura_document_set_number_of_pages(document, fz_count_pages(mupdf_document->ctx, mupdf_document->document)); + zathura_document_set_data(document, mupdf_document); + + return error; +@@ -67,10 +67,10 @@ error_free: + + if (mupdf_document != NULL) { + if (mupdf_document->document != NULL) { +- fz_close_document(mupdf_document->document); ++ fz_drop_document(mupdf_document->ctx, mupdf_document->document); + } + if (mupdf_document->ctx != NULL) { +- fz_free_context(mupdf_document->ctx); ++ fz_drop_context(mupdf_document->ctx); + } + + free(mupdf_document); +@@ -90,8 +90,8 @@ pdf_document_free(zathura_document_t* document, mupdf_document_t* mupdf_document + return ZATHURA_ERROR_INVALID_ARGUMENTS; + } + +- fz_close_document(mupdf_document->document); +- fz_free_context(mupdf_document->ctx); ++ fz_drop_document(mupdf_document->ctx, mupdf_document->document); ++ fz_drop_context(mupdf_document->ctx); + free(mupdf_document); + zathura_document_set_data(document, NULL); + +@@ -112,7 +112,7 @@ pdf_document_save_as(zathura_document_t* document, mupdf_document_t* + * options. */ + + fz_write_options opts = { 0 }; /* just use the default options */ +- fz_write_document(mupdf_document->document, (char*) path, &opts); ++ fz_write_document(mupdf_document->ctx, mupdf_document->document, (char*) path, &opts); + } fz_catch (mupdf_document->ctx) { + return ZATHURA_ERROR_UNKNOWN; + } +diff --git a/image.c b/image.c +index 90d6899..ef2f67b 100644 +--- a/image.c ++++ b/image.c +@@ -9,8 +9,8 @@ + #include "plugin.h" + + static void pdf_zathura_image_free(zathura_image_t* image); +-static void get_images(pdf_obj* dict, girara_list_t* list); +-static void get_resources(pdf_obj* resource, girara_list_t* list); ++static void get_images(zathura_page_t* page, pdf_obj* dict, girara_list_t* list); ++static void get_resources(zathura_page_t* page, pdf_obj* resource, girara_list_t* list); + + girara_list_t* + pdf_page_images_get(zathura_page_t* page, mupdf_page_t* mupdf_page, zathura_error_t* error) +@@ -30,12 +30,12 @@ pdf_page_images_get(zathura_page_t* page, mupdf_page_t* mupdf_page, zathura_erro + + mupdf_document_t* mupdf_document = zathura_document_get_data(document); + +- pdf_obj* page_object = pdf_load_object((pdf_document*) mupdf_document->document, zathura_page_get_index(page), 0); ++ pdf_obj* page_object = pdf_load_object(mupdf_document->ctx, (pdf_document*) mupdf_document->document, zathura_page_get_index(page), 0); + if (page_object == NULL) { + goto error_free; + } + +- pdf_obj* resource = pdf_dict_gets(page_object, "Resources"); ++ pdf_obj* resource = pdf_dict_gets(mupdf_document->ctx, page_object, "Resources"); + if (resource == NULL) { + goto error_free; + } +@@ -50,7 +50,7 @@ pdf_page_images_get(zathura_page_t* page, mupdf_page_t* mupdf_page, zathura_erro + + girara_list_set_free_function(list, (girara_free_function_t) pdf_zathura_image_free); + +- get_resources(resource, list); ++ get_resources(page, resource, list); + + return list; + +@@ -81,20 +81,32 @@ pdf_zathura_image_free(zathura_image_t* image) + } + + static void +-get_images(pdf_obj* dict, girara_list_t* list) ++get_images(zathura_page_t* page, pdf_obj* dict, girara_list_t* list) + { + if (dict == NULL || list == NULL) { + return; + } + +- for (int i = 0; i < pdf_dict_len(dict); i++) { +- pdf_obj* image_dict = pdf_dict_get_val(dict, i); +- if (pdf_is_dict(image_dict) == 0) { ++ if (page == NULL) { ++ return; ++ } ++ ++ zathura_document_t* document = zathura_page_get_document(page); ++ ++ if (document == NULL) { ++ return; ++ } ++ ++ mupdf_document_t* mupdf_document = zathura_document_get_data(document); ++ ++ for (int i = 0; i < pdf_dict_len(mupdf_document->ctx, dict); i++) { ++ pdf_obj* image_dict = pdf_dict_get_val(mupdf_document->ctx, dict, i); ++ if (pdf_is_dict(mupdf_document->ctx, image_dict) == 0) { + continue; + } + +- pdf_obj* type = pdf_dict_gets(image_dict, "Subtype"); +- if (strcmp(pdf_to_name(type), "Image") != 0) { ++ pdf_obj* type = pdf_dict_gets(mupdf_document->ctx, image_dict, "Subtype"); ++ if (strcmp(pdf_to_name(mupdf_document->ctx, type), "Image") != 0) { + continue; + } + +@@ -110,8 +122,8 @@ get_images(pdf_obj* dict, girara_list_t* list) + continue; + } + +- pdf_obj* width = pdf_dict_gets(image_dict, "Width"); +- pdf_obj* height = pdf_dict_gets(image_dict, "Height"); ++ pdf_obj* width = pdf_dict_gets(mupdf_document->ctx, image_dict, "Width"); ++ pdf_obj* height = pdf_dict_gets(mupdf_document->ctx, image_dict, "Height"); + + zathura_image_t* zathura_image = g_malloc(sizeof(zathura_image_t)); + +@@ -120,33 +132,45 @@ get_images(pdf_obj* dict, girara_list_t* list) + // FIXME: Get correct image coordinates + zathura_image->data = image_dict; + zathura_image->position.x1 = 0; +- zathura_image->position.x2 = pdf_to_int(width); ++ zathura_image->position.x2 = pdf_to_int(mupdf_document->ctx, width); + zathura_image->position.y1 = 0; +- zathura_image->position.y2 = pdf_to_int(height); ++ zathura_image->position.y2 = pdf_to_int(mupdf_document->ctx, height); + + girara_list_append(list, zathura_image); + } + } + + static void +-get_resources(pdf_obj* resource, girara_list_t* list) ++get_resources(zathura_page_t* page, pdf_obj* resource, girara_list_t* list) + { + if (resource == NULL || list == NULL) { + return; + } + +- pdf_obj* x_object = pdf_dict_gets(resource, "XObject"); ++ if (page == NULL) { ++ return; ++ } ++ ++ zathura_document_t* document = zathura_page_get_document(page); ++ ++ if (document == NULL) { ++ return; ++ } ++ ++ mupdf_document_t* mupdf_document = zathura_document_get_data(document); ++ ++ pdf_obj* x_object = pdf_dict_gets(mupdf_document->ctx, resource, "XObject"); + if (x_object == NULL) { + return; + } + +- get_images(x_object, list); ++ get_images(page, x_object, list); + +- for (int i = 0; i < pdf_dict_len(x_object); i++) { +- pdf_obj* obj = pdf_dict_get_val(x_object, i); +- pdf_obj* subsrc = pdf_dict_gets(obj, "Resources"); +- if (subsrc != NULL && pdf_objcmp(resource, subsrc)) { +- get_resources(subsrc, list); ++ for (int i = 0; i < pdf_dict_len(mupdf_document->ctx, x_object); i++) { ++ pdf_obj* obj = pdf_dict_get_val(mupdf_document->ctx, x_object, i); ++ pdf_obj* subsrc = pdf_dict_gets(mupdf_document->ctx, obj, "Resources"); ++ if (subsrc != NULL && pdf_objcmp(mupdf_document->ctx, resource, subsrc)) { ++ get_resources(page, subsrc, list); + } + } + } +diff --git a/index.c b/index.c +index 80c1068..8b8f8a5 100644 +--- a/index.c ++++ b/index.c +@@ -19,7 +19,7 @@ pdf_document_index_generate(zathura_document_t* document, mupdf_document_t* mupd + } + + /* get outline */ +- fz_outline* outline = fz_load_outline(mupdf_document->document); ++ fz_outline* outline = fz_load_outline(mupdf_document->ctx, mupdf_document->document); + if (outline == NULL) { + if (error != NULL) { + *error = ZATHURA_ERROR_UNKNOWN; +@@ -32,7 +32,7 @@ pdf_document_index_generate(zathura_document_t* document, mupdf_document_t* mupd + build_index(outline, root); + + /* free outline */ +- fz_free_outline(mupdf_document->ctx, outline); ++ fz_drop_outline(mupdf_document->ctx, outline); + + return root; + } +diff --git a/links.c b/links.c +index 21be39d..a947802 100644 +--- a/links.c ++++ b/links.c +@@ -31,7 +31,7 @@ pdf_page_links_get(zathura_page_t* page, mupdf_page_t* mupdf_page, zathura_error + goto error_free; + } + +- fz_link* link = fz_load_links(mupdf_document->document, mupdf_page->page); ++ fz_link* link = fz_load_links(mupdf_document->ctx, mupdf_page->page); + for (; link != NULL; link = link->next) { + /* extract position */ + zathura_rectangle_t position; +diff --git a/page.c b/page.c +index 9032622..beb0351 100644 +--- a/page.c ++++ b/page.c +@@ -29,12 +29,12 @@ pdf_page_init(zathura_page_t* page) + + /* load page */ + fz_try (mupdf_page->ctx) { +- mupdf_page->page = fz_load_page(mupdf_document->document, index); ++ mupdf_page->page = fz_load_page(mupdf_document->ctx, mupdf_document->document, index); + } fz_catch (mupdf_page->ctx) { + goto error_free; + } + +- fz_bound_page(mupdf_document->document, (fz_page*) mupdf_page->page, &mupdf_page->bbox); ++ fz_bound_page(mupdf_document->ctx, (fz_page*) mupdf_page->page, &mupdf_page->bbox); + + /* get page dimensions */ + zathura_page_set_width(page, mupdf_page->bbox.x1 - mupdf_page->bbox.x0); +@@ -74,15 +74,15 @@ pdf_page_clear(zathura_page_t* page, mupdf_page_t* mupdf_page) + + if (mupdf_page != NULL) { + if (mupdf_page->text != NULL) { +- fz_free_text_page(mupdf_page->ctx, mupdf_page->text); ++ fz_drop_text_page(mupdf_page->ctx, mupdf_page->text); + } + + if (mupdf_page->sheet != NULL) { +- fz_free_text_sheet(mupdf_page->ctx, mupdf_page->sheet); ++ fz_drop_text_sheet(mupdf_page->ctx, mupdf_page->sheet); + } + + if (mupdf_page->page != NULL) { +- fz_free_page(mupdf_document->document, mupdf_page->page); ++ fz_drop_page(mupdf_document->ctx, mupdf_page->page); + } + + free(mupdf_page); +diff --git a/render.c b/render.c +index 4ec07ae..e0648e1 100644 +--- a/render.c ++++ b/render.c +@@ -26,12 +26,12 @@ pdf_page_render_to_buffer(mupdf_document_t* mupdf_document, mupdf_page_t* mupdf_ + fz_try (mupdf_document->ctx) { + fz_matrix m; + fz_scale(&m, scalex, scaley); +- fz_run_page(mupdf_document->document, mupdf_page->page, device, &m, NULL); ++ fz_run_page(mupdf_document->ctx, mupdf_page->page, device, &m, NULL); + } fz_catch (mupdf_document->ctx) { + return ZATHURA_ERROR_UNKNOWN; + } + +- fz_free_device(device); ++ fz_drop_device(mupdf_page->ctx, device); + + fz_irect irect = { .x1 = page_width, .y1 = page_height }; + fz_rect rect = { .x1 = page_width, .y1 = page_height }; +@@ -41,8 +41,8 @@ pdf_page_render_to_buffer(mupdf_document_t* mupdf_document, mupdf_page_t* mupdf_ + fz_clear_pixmap_with_value(mupdf_page->ctx, pixmap, 0xFF); + + device = fz_new_draw_device(mupdf_page->ctx, pixmap); +- fz_run_display_list(display_list, device, &fz_identity, &rect, NULL); +- fz_free_device(device); ++ fz_run_display_list(mupdf_page->ctx, display_list, device, &fz_identity, &rect, NULL); ++ fz_drop_device(mupdf_page->ctx, device); + + unsigned char* s = fz_pixmap_samples(mupdf_page->ctx, pixmap); + unsigned int n = fz_pixmap_components(mupdf_page->ctx, pixmap); +diff --git a/utils.c b/utils.c +index 13ee788..d45a31d 100644 +--- a/utils.c ++++ b/utils.c +@@ -17,9 +17,9 @@ mupdf_page_extract_text(mupdf_document_t* mupdf_document, mupdf_page_t* mupdf_pa + text_device = fz_new_text_device(mupdf_page->ctx, mupdf_page->sheet, mupdf_page->text); + fz_matrix ctm; + fz_scale(&ctm, 1.0, 1.0); +- fz_run_page(mupdf_document->document, mupdf_page->page, text_device, &ctm, NULL); ++ fz_run_page(mupdf_page->ctx, mupdf_page->page, text_device, &ctm, NULL); + } fz_always (mupdf_document->ctx) { +- fz_free_device(text_device); ++ fz_drop_device(mupdf_page->ctx, text_device); + } fz_catch(mupdf_document->ctx) { + } + +-- +1.8.4 + diff --git a/office/zathura-pdf-mupdf/patches/0004-Enable-EPUB-support.patch.disabled b/office/zathura-pdf-mupdf/patches/0004-Enable-EPUB-support.patch.disabled new file mode 100644 index 0000000000..3c731be781 --- /dev/null +++ b/office/zathura-pdf-mupdf/patches/0004-Enable-EPUB-support.patch.disabled @@ -0,0 +1,45 @@ +From 00792eae08aafb5ba2f429b1cdee0a5fe9c25c61 Mon Sep 17 00:00:00 2001 +From: Moritz Lipp +Date: Sun, 19 Apr 2015 10:49:20 +0200 +Subject: [PATCH 4/6] Enable EPUB support + +--- + document.c | 8 +++----- + plugin.c | 3 ++- + 2 files changed, 5 insertions(+), 6 deletions(-) + +diff --git a/document.c b/document.c +index 38e70b5..de805bb 100644 +--- a/document.c ++++ b/document.c +@@ -34,11 +34,9 @@ pdf_document_open(zathura_document_t* document) + const char* password = zathura_document_get_password(document); + + fz_try(mupdf_document->ctx){ +- if (strstr(path, ".xps") != 0 || strstr(path, ".XPS") != 0 || strstr(path, ".rels") != 0) { +- mupdf_document->document = (fz_document*) xps_open_document(mupdf_document->ctx, (char*) path); +- } else { +- mupdf_document->document = (fz_document*) pdf_open_document(mupdf_document->ctx, (char*) path); +- } ++ fz_register_document_handlers(mupdf_document->ctx); ++ ++ mupdf_document->document = fz_open_document(mupdf_document->ctx, path); + } + fz_catch(mupdf_document->ctx){ + error = ZATHURA_ERROR_UNKNOWN; +diff --git a/plugin.c b/plugin.c +index a115db4..86cb8de 100644 +--- a/plugin.c ++++ b/plugin.c +@@ -32,6 +32,7 @@ ZATHURA_PLUGIN_REGISTER( + register_functions, + ZATHURA_PLUGIN_MIMETYPES({ + "application/pdf", +- "application/oxps" ++ "application/oxps", ++ "application/epub+zip" + }) + ) +-- +1.8.4 + diff --git a/office/zathura-pdf-mupdf/patches/0005-Locate-and-extract-images-from-pages.patch b/office/zathura-pdf-mupdf/patches/0005-Locate-and-extract-images-from-pages.patch new file mode 100644 index 0000000000..b59bb9aec3 --- /dev/null +++ b/office/zathura-pdf-mupdf/patches/0005-Locate-and-extract-images-from-pages.patch @@ -0,0 +1,311 @@ +From c3820b67cc2742e531481c7255bfa3bbdbe36a2a Mon Sep 17 00:00:00 2001 +From: Moritz Lipp +Date: Sun, 19 Apr 2015 23:24:39 +0200 +Subject: [PATCH 5/6] Locate and extract images from pages + +--- + image.c | 163 ++++++++++++++++++++++++++++----------------------------------- + plugin.c | 3 +- + plugin.h | 14 ++++++ + select.c | 3 -- + utils.c | 4 ++ + 5 files changed, 92 insertions(+), 95 deletions(-) + +diff --git a/image.c b/image.c +index ef2f67b..97d4143 100644 +--- a/image.c ++++ b/image.c +@@ -7,10 +7,9 @@ + #include + + #include "plugin.h" ++#include "utils.h" + + static void pdf_zathura_image_free(zathura_image_t* image); +-static void get_images(zathura_page_t* page, pdf_obj* dict, girara_list_t* list); +-static void get_resources(zathura_page_t* page, pdf_obj* resource, girara_list_t* list); + + girara_list_t* + pdf_page_images_get(zathura_page_t* page, mupdf_page_t* mupdf_page, zathura_error_t* error) +@@ -30,16 +29,7 @@ pdf_page_images_get(zathura_page_t* page, mupdf_page_t* mupdf_page, zathura_erro + + mupdf_document_t* mupdf_document = zathura_document_get_data(document); + +- pdf_obj* page_object = pdf_load_object(mupdf_document->ctx, (pdf_document*) mupdf_document->document, zathura_page_get_index(page), 0); +- if (page_object == NULL) { +- goto error_free; +- } +- +- pdf_obj* resource = pdf_dict_gets(mupdf_document->ctx, page_object, "Resources"); +- if (resource == NULL) { +- goto error_free; +- } +- ++ /* Setup image list */ + list = girara_list_new(); + if (list == NULL) { + if (error != NULL) { +@@ -50,7 +40,25 @@ pdf_page_images_get(zathura_page_t* page, mupdf_page_t* mupdf_page, zathura_erro + + girara_list_set_free_function(list, (girara_free_function_t) pdf_zathura_image_free); + +- get_resources(page, resource, list); ++ /* Extract images */ ++ mupdf_page_extract_text(mupdf_document, mupdf_page); ++ ++ fz_page_block* block; ++ for (block = mupdf_page->text->blocks; block < mupdf_page->text->blocks + mupdf_page->text->len; block++) { ++ if (block->type == FZ_PAGE_BLOCK_IMAGE) { ++ fz_image_block *image_block = block->u.image; ++ ++ zathura_image_t* zathura_image = g_malloc(sizeof(zathura_image_t)); ++ ++ zathura_image->position.x1 = image_block->bbox.x0; ++ zathura_image->position.y1 = image_block->bbox.y0; ++ zathura_image->position.x2 = image_block->bbox.x1; ++ zathura_image->position.y2 = image_block->bbox.y1; ++ zathura_image->data = image_block->image; ++ ++ girara_list_append(list, zathura_image); ++ } ++ } + + return list; + +@@ -69,109 +77,82 @@ error_ret: + return NULL; + } + +- +-static void +-pdf_zathura_image_free(zathura_image_t* image) ++cairo_surface_t* ++pdf_page_image_get_cairo(zathura_page_t* page, mupdf_page_t* mupdf_page, ++ zathura_image_t* image, zathura_error_t* error) + { +- if (image == NULL) { +- return; ++ if (page == NULL || mupdf_page == NULL || image == NULL || image->data == NULL) { ++ if (error != NULL) { ++ *error = ZATHURA_ERROR_INVALID_ARGUMENTS; ++ } ++ goto error_ret; + } + +- g_free(image); +-} ++ fz_image* mupdf_image = (fz_image*) image->data; + +-static void +-get_images(zathura_page_t* page, pdf_obj* dict, girara_list_t* list) +-{ +- if (dict == NULL || list == NULL) { +- return; +- } ++ fz_pixmap* pixmap = NULL; ++ cairo_surface_t* surface = NULL; + +- if (page == NULL) { +- return; ++ pixmap = fz_new_pixmap_from_image(mupdf_page->ctx, mupdf_image, 0, 0); ++ if (pixmap == NULL) { ++ goto error_free; + } + +- zathura_document_t* document = zathura_page_get_document(page); +- +- if (document == NULL) { +- return; ++ surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, mupdf_image->w, mupdf_image->h); ++ if (surface == NULL) { ++ goto error_free; + } + +- mupdf_document_t* mupdf_document = zathura_document_get_data(document); ++ unsigned char* surface_data = cairo_image_surface_get_data(surface); ++ int rowstride = cairo_image_surface_get_stride(surface); + +- for (int i = 0; i < pdf_dict_len(mupdf_document->ctx, dict); i++) { +- pdf_obj* image_dict = pdf_dict_get_val(mupdf_document->ctx, dict, i); +- if (pdf_is_dict(mupdf_document->ctx, image_dict) == 0) { +- continue; +- } ++ unsigned char* s = fz_pixmap_samples(mupdf_page->ctx, pixmap); ++ unsigned int n = fz_pixmap_components(mupdf_page->ctx, pixmap); + +- pdf_obj* type = pdf_dict_gets(mupdf_document->ctx, image_dict, "Subtype"); +- if (strcmp(pdf_to_name(mupdf_document->ctx, type), "Image") != 0) { +- continue; +- } ++ for (unsigned int y = 0; y < fz_pixmap_height(mupdf_page->ctx, pixmap); y++) { ++ for (unsigned int x = 0; x < fz_pixmap_width(mupdf_page->ctx, pixmap); x++) { ++ guchar* p = surface_data + y * rowstride + x * 4; + +- bool duplicate = false; +- GIRARA_LIST_FOREACH(list, zathura_image_t*, iter, image) +- if (image->data == image_dict) { +- duplicate = true; +- break; ++ // RGB ++ if (n == 4) { ++ p[0] = s[2]; ++ p[1] = s[1]; ++ p[2] = s[0]; ++ // Gray-scale or mask ++ } else { ++ p[0] = s[0]; ++ p[1] = s[0]; ++ p[2] = s[0]; + } +- GIRARA_LIST_FOREACH_END(list, zathura_image_t*, iter, image); +- +- if (duplicate == true) { +- continue; ++ s += n; + } ++ } + +- pdf_obj* width = pdf_dict_gets(mupdf_document->ctx, image_dict, "Width"); +- pdf_obj* height = pdf_dict_gets(mupdf_document->ctx, image_dict, "Height"); +- +- zathura_image_t* zathura_image = g_malloc(sizeof(zathura_image_t)); +- +- fprintf(stderr, "image\n"); ++ fz_drop_pixmap(mupdf_page->ctx, pixmap); + +- // FIXME: Get correct image coordinates +- zathura_image->data = image_dict; +- zathura_image->position.x1 = 0; +- zathura_image->position.x2 = pdf_to_int(mupdf_document->ctx, width); +- zathura_image->position.y1 = 0; +- zathura_image->position.y2 = pdf_to_int(mupdf_document->ctx, height); ++ return surface; + +- girara_list_append(list, zathura_image); +- } +-} ++error_free: + +-static void +-get_resources(zathura_page_t* page, pdf_obj* resource, girara_list_t* list) +-{ +- if (resource == NULL || list == NULL) { +- return; ++ if (pixmap != NULL) { ++ fz_drop_pixmap(mupdf_page->ctx, pixmap); + } + +- if (page == NULL) { +- return; ++ if (surface != NULL) { ++ cairo_surface_destroy(surface); + } + +- zathura_document_t* document = zathura_page_get_document(page); +- +- if (document == NULL) { +- return; +- } ++error_ret: + +- mupdf_document_t* mupdf_document = zathura_document_get_data(document); ++ return NULL; ++} + +- pdf_obj* x_object = pdf_dict_gets(mupdf_document->ctx, resource, "XObject"); +- if (x_object == NULL) { ++static void ++pdf_zathura_image_free(zathura_image_t* image) ++{ ++ if (image == NULL) { + return; + } + +- get_images(page, x_object, list); +- +- for (int i = 0; i < pdf_dict_len(mupdf_document->ctx, x_object); i++) { +- pdf_obj* obj = pdf_dict_get_val(mupdf_document->ctx, x_object, i); +- pdf_obj* subsrc = pdf_dict_gets(mupdf_document->ctx, obj, "Resources"); +- if (subsrc != NULL && pdf_objcmp(mupdf_document->ctx, resource, subsrc)) { +- get_resources(page, subsrc, list); +- } +- } ++ g_free(image); + } +- +diff --git a/plugin.c b/plugin.c +index 86cb8de..fef2c6a 100644 +--- a/plugin.c ++++ b/plugin.c +@@ -17,12 +17,13 @@ register_functions(zathura_plugin_functions_t* functions) + functions->page_links_get = (zathura_plugin_page_links_get_t) pdf_page_links_get; + #if 0 + functions->document_get_information = (zathura_plugin_document_get_information_t) pdf_document_get_information; +- functions->page_images_get = (zathura_plugin_page_images_get_t) pdf_page_images_get; + #endif ++ functions->page_images_get = (zathura_plugin_page_images_get_t) pdf_page_images_get; + functions->page_get_text = (zathura_plugin_page_get_text_t) pdf_page_get_text; + functions->page_render = (zathura_plugin_page_render_t) pdf_page_render; + #if HAVE_CAIRO + functions->page_render_cairo = (zathura_plugin_page_render_cairo_t) pdf_page_render_cairo; ++ functions->page_image_get_cairo = (zathura_plugin_page_image_get_cairo_t) pdf_page_image_get_cairo; + #endif + } + +diff --git a/plugin.h b/plugin.h +index a229a74..8b6c74d 100644 +--- a/plugin.h ++++ b/plugin.h +@@ -113,6 +113,20 @@ girara_list_t* pdf_page_links_get(zathura_page_t* page, mupdf_page_t* mupdf_page + */ + girara_list_t* pdf_page_images_get(zathura_page_t* page, mupdf_page_t* mupdf_page, zathura_error_t* error); + ++#if HAVE_CAIRO ++/** ++ * Gets the content of the image in a cairo surface ++ * ++ * @param page Page ++ * @param image Image identifier ++ * @param error Set to an error value (see \ref zathura_error_t) if an ++ * error occured ++ * @return The cairo image surface or NULL if an error occured ++ */ ++cairo_surface_t* pdf_page_image_get_cairo(zathura_page_t* page, mupdf_page_t* ++ mupdf_page, zathura_image_t* image, zathura_error_t* error); ++#endif ++ + /** + * Get text for selection + * @param page Page +diff --git a/select.c b/select.c +index 15f9258..c1e1437 100644 +--- a/select.c ++++ b/select.c +@@ -7,9 +7,6 @@ + #include "plugin.h" + #include "utils.h" + +-void mupdf_page_extract_text(mupdf_document_t* mupdf_document, +- mupdf_page_t* mupdf_page); +- + char* + pdf_page_get_text(zathura_page_t* page, mupdf_page_t* mupdf_page, zathura_rectangle_t rectangle, zathura_error_t* error) + { +diff --git a/utils.c b/utils.c +index d45a31d..4a003b9 100644 +--- a/utils.c ++++ b/utils.c +@@ -15,6 +15,10 @@ mupdf_page_extract_text(mupdf_document_t* mupdf_document, mupdf_page_t* mupdf_pa + + fz_try (mupdf_page->ctx) { + text_device = fz_new_text_device(mupdf_page->ctx, mupdf_page->sheet, mupdf_page->text); ++ ++ /* Disable FZ_IGNORE_IMAGE to collect image blocks */ ++ fz_disable_device_hints(mupdf_page->ctx, text_device, FZ_IGNORE_IMAGE); ++ + fz_matrix ctm; + fz_scale(&ctm, 1.0, 1.0); + fz_run_page(mupdf_page->ctx, mupdf_page->page, text_device, &ctm, NULL); +-- +1.8.4 + diff --git a/office/zathura-pdf-mupdf/patches/0006-Parse-entries-in-the-document-information-dictionary.patch b/office/zathura-pdf-mupdf/patches/0006-Parse-entries-in-the-document-information-dictionary.patch new file mode 100644 index 0000000000..5101a90cde --- /dev/null +++ b/office/zathura-pdf-mupdf/patches/0006-Parse-entries-in-the-document-information-dictionary.patch @@ -0,0 +1,147 @@ +From 99bff723291f5aa2558e5c8b475f496025105f4a Mon Sep 17 00:00:00 2001 +From: Moritz Lipp +Date: Mon, 20 Apr 2015 00:30:54 +0200 +Subject: [PATCH 6/6] Parse entries in the document information dictionary + +--- + document.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + plugin.c | 4 +-- + 2 files changed, 99 insertions(+), 3 deletions(-) + +diff --git a/document.c b/document.c +index de805bb..873866c 100644 +--- a/document.c ++++ b/document.c +@@ -6,8 +6,12 @@ + #include + #include + ++#include ++ + #include "plugin.h" + ++#define LENGTH(x) (sizeof(x)/sizeof((x)[0])) ++ + zathura_error_t + pdf_document_open(zathura_document_t* document) + { +@@ -118,3 +122,97 @@ pdf_document_save_as(zathura_document_t* document, mupdf_document_t* + return ZATHURA_ERROR_OK; + } + ++girara_list_t* ++pdf_document_get_information(zathura_document_t* document, mupdf_document_t* ++ mupdf_document, zathura_error_t* error) ++{ ++ if (document == NULL || mupdf_document == NULL || error == NULL) { ++ if (error != NULL) { ++ *error = ZATHURA_ERROR_INVALID_ARGUMENTS; ++ } ++ } ++ ++ girara_list_t* list = zathura_document_information_entry_list_new(); ++ if (list == NULL) { ++ if (error != NULL) { ++ *error = ZATHURA_ERROR_UNKNOWN; ++ } ++ return NULL; ++ } ++ ++ fz_try (mupdf_document->ctx) { ++ pdf_obj* trailer = pdf_trailer(mupdf_document->ctx, (pdf_document*) mupdf_document->document); ++ pdf_obj* info_dict = pdf_dict_get(mupdf_document->ctx, trailer, PDF_NAME_Info); ++ ++ /* get string values */ ++ typedef struct info_value_s { ++ const char* property; ++ zathura_document_information_type_t type; ++ } info_value_t; ++ ++ static const info_value_t string_values[] = { ++ { "Title", ZATHURA_DOCUMENT_INFORMATION_TITLE }, ++ { "Author", ZATHURA_DOCUMENT_INFORMATION_AUTHOR }, ++ { "Subject", ZATHURA_DOCUMENT_INFORMATION_SUBJECT }, ++ { "Keywords", ZATHURA_DOCUMENT_INFORMATION_KEYWORDS }, ++ { "Creator", ZATHURA_DOCUMENT_INFORMATION_CREATOR }, ++ { "Producer", ZATHURA_DOCUMENT_INFORMATION_PRODUCER } ++ }; ++ ++ for (unsigned int i = 0; i < LENGTH(string_values); i++) { ++ pdf_obj* value = pdf_dict_gets(mupdf_document->ctx, info_dict, string_values[i].property); ++ if (value == NULL) { ++ continue; ++ } ++ ++ char* str_value = pdf_to_str_buf(mupdf_document->ctx, value); ++ if (str_value == NULL || strlen(str_value) == 0) { ++ continue; ++ } ++ ++ zathura_document_information_entry_t* entry = ++ zathura_document_information_entry_new( ++ string_values[i].type, ++ str_value ++ ); ++ ++ if (entry != NULL) { ++ girara_list_append(list, entry); ++ } ++ } ++ ++ static const info_value_t time_values[] = { ++ { "CreationDate", ZATHURA_DOCUMENT_INFORMATION_CREATION_DATE }, ++ { "ModDate", ZATHURA_DOCUMENT_INFORMATION_MODIFICATION_DATE } ++ }; ++ ++ for (unsigned int i = 0; i < LENGTH(time_values); i++) { ++ pdf_obj* value = pdf_dict_gets(mupdf_document->ctx, info_dict, time_values[i].property); ++ if (value == NULL) { ++ continue; ++ } ++ ++ char* str_value = pdf_to_str_buf(mupdf_document->ctx, value); ++ if (str_value == NULL || strlen(str_value) == 0) { ++ continue; ++ } ++ ++ zathura_document_information_entry_t* entry = ++ zathura_document_information_entry_new( ++ time_values[i].type, ++ str_value // FIXME: Convert to common format ++ ); ++ ++ if (entry != NULL) { ++ girara_list_append(list, entry); ++ } ++ } ++ } fz_catch (mupdf_document->ctx) { ++ if (error != NULL) { ++ *error = ZATHURA_ERROR_UNKNOWN; ++ } ++ return NULL; ++ } ++ ++ return list; ++} +diff --git a/plugin.c b/plugin.c +index fef2c6a..2efae6f 100644 +--- a/plugin.c ++++ b/plugin.c +@@ -11,13 +11,11 @@ register_functions(zathura_plugin_functions_t* functions) + functions->document_free = (zathura_plugin_document_free_t) pdf_document_free; + functions->document_save_as = (zathura_plugin_document_save_as_t) pdf_document_save_as; + functions->document_index_generate = (zathura_plugin_document_index_generate_t) pdf_document_index_generate; ++ functions->document_get_information = (zathura_plugin_document_get_information_t) pdf_document_get_information; + functions->page_init = (zathura_plugin_page_init_t) pdf_page_init; + functions->page_clear = (zathura_plugin_page_clear_t) pdf_page_clear; + functions->page_search_text = (zathura_plugin_page_search_text_t) pdf_page_search_text; + functions->page_links_get = (zathura_plugin_page_links_get_t) pdf_page_links_get; +-#if 0 +- functions->document_get_information = (zathura_plugin_document_get_information_t) pdf_document_get_information; +-#endif + functions->page_images_get = (zathura_plugin_page_images_get_t) pdf_page_images_get; + functions->page_get_text = (zathura_plugin_page_get_text_t) pdf_page_get_text; + functions->page_render = (zathura_plugin_page_render_t) pdf_page_render; +-- +1.8.4 + diff --git a/office/zathura-pdf-mupdf/upstream.README b/office/zathura-pdf-mupdf/upstream.README new file mode 100644 index 0000000000..9773daf2ac --- /dev/null +++ b/office/zathura-pdf-mupdf/upstream.README @@ -0,0 +1,23 @@ +zathura-pdf-mupdf +================= +The zathura-pdf-mupdf plugin adds PDF support to zathura by using the mupdf +rendering library. + +Requirements +------------ +zathura (>= 0.2.0) +girara +mupdf (>= 1.3) +openjpeg (>= 2.0) + +Installation +------------ +To build and install the plugin: + + make install + +Uninstall: +---------- +To delete the plugin from your system, just type: + + make uninstall diff --git a/office/zathura-pdf-mupdf/zathura-pdf-mupdf.SlackBuild b/office/zathura-pdf-mupdf/zathura-pdf-mupdf.SlackBuild index 7e7be3cb6a..8ff8cc5af8 100644 --- a/office/zathura-pdf-mupdf/zathura-pdf-mupdf.SlackBuild +++ b/office/zathura-pdf-mupdf/zathura-pdf-mupdf.SlackBuild @@ -7,7 +7,7 @@ # Licensed under the WTFPL. See http://www.wtfpl.net/txt/copying/ for details. PRGNAM=zathura-pdf-mupdf -VERSION=${VERSION:-0.2.6} +VERSION=${VERSION:-0.2.7} BUILD=${BUILD:-1} TAG=${TAG:-_SBo} @@ -40,7 +40,10 @@ fi set -e +rm -rf $PKG +mkdir -p $TMP $PKG $OUTPUT cd $TMP +rm -rf $PRGNAM-$VERSION tar xvf $CWD/$PRGNAM-$VERSION.tar.gz cd $PRGNAM-$VERSION chown -R root:root . @@ -50,6 +53,17 @@ find -L . \ \( -perm 666 -o -perm 664 -o -perm 600 -o -perm 444 -o -perm 440 -o -perm 400 \) \ -exec chmod 644 {} \; +# Upstream left the README out of the release tarball for some reason. +cat $CWD/upstream.README > README + +# Patches from upstream's -develop branch, needed for mupdf-1.7 API. +# Also fix some minor bugs. The patch that enables epub support is +# disabled here, as it doesn't actually work (yet). +for patch in $CWD/patches/*.patch; do + basename $patch + patch -p1 < $patch +done + # mupdf 1.4 and later no longer have libmupdf-js-none (moved to libmupdf). # Anyway it's better to use pkg-config now that mupdf supports it. sed -i \ @@ -57,12 +71,16 @@ sed -i \ -e '/^MUPDF_LIB/s,-.*,$(shell pkg-config --libs mupdf),' \ config.mk -make VERBOSE=1 +PLUGDIR=/usr/lib$LIBDIRSUFFIX/zathura + +make strip *.so -make install DESTDIR=$PKG +make install DESTDIR=$PKG PLUGINDIR="$PLUGDIR/pdf-mupdf" + +ln -s pdf-mupdf/pdf.so $PKG/$PLUGDIR/pdf.so mkdir -p $PKG/usr/doc/$PRGNAM-$VERSION -cp -a AUTHORS LICENSE $PKG/usr/doc/$PRGNAM-$VERSION +cp -a README AUTHORS LICENSE $PKG/usr/doc/$PRGNAM-$VERSION cat $CWD/$PRGNAM.SlackBuild > $PKG/usr/doc/$PRGNAM-$VERSION/$PRGNAM.SlackBuild mkdir -p $PKG/install diff --git a/office/zathura-pdf-mupdf/zathura-pdf-mupdf.info b/office/zathura-pdf-mupdf/zathura-pdf-mupdf.info index d7cbe64fd6..7ef8d074f6 100644 --- a/office/zathura-pdf-mupdf/zathura-pdf-mupdf.info +++ b/office/zathura-pdf-mupdf/zathura-pdf-mupdf.info @@ -1,8 +1,8 @@ PRGNAM="zathura-pdf-mupdf" -VERSION="0.2.6" -HOMEPAGE="http://www.pwmt.org/projects/zathura/plugins/zathura-pdf-mupdf/" -DOWNLOAD="http://www.pwmt.org/projects/zathura/plugins/download/zathura-pdf-mupdf-0.2.6.tar.gz" -MD5SUM="5102e416aecc2a14d78cc9c83d529b39" +VERSION="0.2.7" +HOMEPAGE="https://www.pwmt.org/projects/zathura-pdf-mupdf/" +DOWNLOAD="http://www.pwmt.org/projects/zathura/plugins/download/zathura-pdf-mupdf-0.2.7.tar.gz" +MD5SUM="b89b45289c8ec77854de4afc149cd1a4" DOWNLOAD_x86_64="" MD5SUM_x86_64="" REQUIRES="mupdf zathura" -- cgit v1.2.3