mirror of
https://git.pwmt.org/pwmt/zathura.git
synced 2025-02-27 23:34:39 +01:00
Began to use mupdf instead of poppler
This commit is contained in:
parent
31027cbaad
commit
f9c51655cf
3 changed files with 101 additions and 143 deletions
|
@ -12,7 +12,7 @@ GTK_INC = $(shell pkg-config --cflags gtk+-2.0 poppler-glib ddjvuapi)
|
||||||
GTK_LIB = $(shell pkg-config --libs gtk+-2.0 gthread-2.0 poppler-glib ddjvuapi)
|
GTK_LIB = $(shell pkg-config --libs gtk+-2.0 gthread-2.0 poppler-glib ddjvuapi)
|
||||||
|
|
||||||
INCS = -I. -I/usr/include ${GTK_INC}
|
INCS = -I. -I/usr/include ${GTK_INC}
|
||||||
LIBS = -lc ${GTK_LIB} -lpthread -lm -lgirara
|
LIBS = -lc ${GTK_LIB} -lpthread -lm -lgirara -lmupdf -ljbig2dec
|
||||||
|
|
||||||
# flags
|
# flags
|
||||||
CFLAGS += -std=c99 -pedantic -Wall -Wno-format-zero-length $(INCS)
|
CFLAGS += -std=c99 -pedantic -Wall -Wno-format-zero-length $(INCS)
|
||||||
|
|
219
ft/pdf/pdf.c
219
ft/pdf/pdf.c
|
@ -1,7 +1,6 @@
|
||||||
/* See LICENSE file for license and copyright information */
|
/* See LICENSE file for license and copyright information */
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <poppler/glib/poppler.h>
|
|
||||||
|
|
||||||
#include "pdf.h"
|
#include "pdf.h"
|
||||||
#include "../../zathura.h"
|
#include "../../zathura.h"
|
||||||
|
@ -10,13 +9,10 @@ bool
|
||||||
pdf_document_open(zathura_document_t* document)
|
pdf_document_open(zathura_document_t* document)
|
||||||
{
|
{
|
||||||
if (!document) {
|
if (!document) {
|
||||||
goto error_out;
|
goto error_ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
document->functions.document_free = pdf_document_free;
|
document->functions.document_free = pdf_document_free;
|
||||||
document->functions.document_index_generate = pdf_document_index_generate;;
|
|
||||||
document->functions.document_save_as = pdf_document_save_as;
|
|
||||||
document->functions.document_attachments_get = pdf_document_attachments_get;
|
|
||||||
document->functions.page_get = pdf_page_get;
|
document->functions.page_get = pdf_page_get;
|
||||||
document->functions.page_search_text = pdf_page_search_text;
|
document->functions.page_search_text = pdf_page_search_text;
|
||||||
document->functions.page_links_get = pdf_page_links_get;
|
document->functions.page_links_get = pdf_page_links_get;
|
||||||
|
@ -26,46 +22,42 @@ pdf_document_open(zathura_document_t* document)
|
||||||
|
|
||||||
document->data = malloc(sizeof(pdf_document_t));
|
document->data = malloc(sizeof(pdf_document_t));
|
||||||
if (!document->data) {
|
if (!document->data) {
|
||||||
goto error_out;
|
goto error_ret;
|
||||||
}
|
|
||||||
|
|
||||||
/* format path */
|
|
||||||
GError* error = NULL;
|
|
||||||
char* file_uri = g_filename_to_uri(document->file_path, NULL, &error);
|
|
||||||
|
|
||||||
if (!file_uri) {
|
|
||||||
fprintf(stderr, "error: could not open file: %s\n", error->message);
|
|
||||||
goto error_free;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pdf_document_t* pdf_document = (pdf_document_t*) document->data;
|
pdf_document_t* pdf_document = (pdf_document_t*) document->data;
|
||||||
pdf_document->document = poppler_document_new_from_file(file_uri, document->password, &error);
|
|
||||||
|
|
||||||
if (!pdf_document->document) {
|
fz_accelerate();
|
||||||
fprintf(stderr, "error: could not open file: %s\n", error->message);
|
pdf_document->glyphcache = fz_newglyphcache();
|
||||||
|
|
||||||
|
if (pdf_openxref(&(pdf_document->document), document->file_path, NULL)) {
|
||||||
|
fprintf(stderr, "error: could not open file\n");
|
||||||
goto error_free;
|
goto error_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
document->number_of_pages = poppler_document_get_n_pages(pdf_document->document);
|
if (pdf_loadpagetree(pdf_document->document)) {
|
||||||
|
fprintf(stderr, "error: could not open file\n");
|
||||||
|
goto error_free;
|
||||||
|
}
|
||||||
|
|
||||||
g_free(file_uri);
|
document->number_of_pages = pdf_getpagecount(pdf_document->document);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
error_free:
|
error_free:
|
||||||
|
|
||||||
if (error) {
|
if (pdf_document->document) {
|
||||||
g_error_free(error);
|
pdf_freexref(pdf_document->document);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file_uri) {
|
if (pdf_document->glyphcache) {
|
||||||
g_free(file_uri);
|
fz_freeglyphcache(pdf_document->glyphcache);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(document->data);
|
free(document->data);
|
||||||
document->data = NULL;
|
document->data = NULL;
|
||||||
|
|
||||||
error_out:
|
error_ret:
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -79,7 +71,8 @@ pdf_document_free(zathura_document_t* document)
|
||||||
|
|
||||||
if (document->data) {
|
if (document->data) {
|
||||||
pdf_document_t* pdf_document = (pdf_document_t*) document->data;
|
pdf_document_t* pdf_document = (pdf_document_t*) document->data;
|
||||||
g_object_unref(pdf_document->document);
|
pdf_freexref(pdf_document->document);
|
||||||
|
fz_freeglyphcache(pdf_document->glyphcache);
|
||||||
free(document->data);
|
free(document->data);
|
||||||
document->data = NULL;
|
document->data = NULL;
|
||||||
}
|
}
|
||||||
|
@ -87,104 +80,6 @@ pdf_document_free(zathura_document_t* document)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
build_index(pdf_document_t* pdf, girara_tree_node_t* root, PopplerIndexIter* iter)
|
|
||||||
{
|
|
||||||
if (!root || !iter) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
PopplerAction* action = poppler_index_iter_get_action(iter);
|
|
||||||
|
|
||||||
if (!action) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
gchar* markup = g_markup_escape_text(action->any.title, -1);
|
|
||||||
zathura_index_element_t* index_element = zathura_index_element_new(markup);
|
|
||||||
|
|
||||||
if (action->type == POPPLER_ACTION_URI) {
|
|
||||||
index_element->type = ZATHURA_LINK_EXTERNAL;
|
|
||||||
index_element->target.uri = g_strdup(action->uri.uri);
|
|
||||||
} else if (action->type == POPPLER_ACTION_GOTO_DEST) {
|
|
||||||
index_element->type = ZATHURA_LINK_TO_PAGE;
|
|
||||||
|
|
||||||
if (action->goto_dest.dest->type == POPPLER_DEST_NAMED) {
|
|
||||||
PopplerDest* dest = poppler_document_find_dest(pdf->document, action->goto_dest.dest->named_dest);
|
|
||||||
if (dest) {
|
|
||||||
index_element->target.page_number = dest->page_num - 1;
|
|
||||||
poppler_dest_free(dest);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
index_element->target.page_number = action->goto_dest.dest->page_num - 1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
poppler_action_free(action);
|
|
||||||
zathura_index_element_free(index_element);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
poppler_action_free(action);
|
|
||||||
|
|
||||||
girara_tree_node_t* node = girara_node_append_data(root, index_element);
|
|
||||||
PopplerIndexIter* child = poppler_index_iter_get_child(iter);
|
|
||||||
|
|
||||||
if (child) {
|
|
||||||
build_index(pdf, node, child);
|
|
||||||
}
|
|
||||||
|
|
||||||
poppler_index_iter_free(child);
|
|
||||||
|
|
||||||
} while (poppler_index_iter_next(iter));
|
|
||||||
}
|
|
||||||
|
|
||||||
girara_tree_node_t*
|
|
||||||
pdf_document_index_generate(zathura_document_t* document)
|
|
||||||
{
|
|
||||||
if (!document || !document->data) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
pdf_document_t* pdf_document = (pdf_document_t*) document->data;
|
|
||||||
PopplerIndexIter* iter = poppler_index_iter_new(pdf_document->document);
|
|
||||||
|
|
||||||
if (!iter) {
|
|
||||||
// XXX: error message?
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
girara_tree_node_t* root = girara_node_new(zathura_index_element_new("ROOT"));
|
|
||||||
girara_node_set_free_function(root, (girara_free_function_t)zathura_index_element_free);
|
|
||||||
build_index(pdf_document, root, iter);
|
|
||||||
|
|
||||||
poppler_index_iter_free(iter);
|
|
||||||
return root;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
pdf_document_save_as(zathura_document_t* document, const char* path)
|
|
||||||
{
|
|
||||||
if (!document || !document->data || !path) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
pdf_document_t* pdf_document = (pdf_document_t*) document->data;
|
|
||||||
|
|
||||||
char* file_path = g_strdup_printf("file://%s", path);
|
|
||||||
poppler_document_save(pdf_document->document, file_path, NULL);
|
|
||||||
g_free(file_path);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
zathura_list_t*
|
|
||||||
pdf_document_attachments_get(zathura_document_t* document)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
zathura_page_t*
|
zathura_page_t*
|
||||||
pdf_page_get(zathura_document_t* document, unsigned int page)
|
pdf_page_get(zathura_document_t* document, unsigned int page)
|
||||||
{
|
{
|
||||||
|
@ -195,21 +90,38 @@ pdf_page_get(zathura_document_t* document, unsigned int page)
|
||||||
pdf_document_t* pdf_document = (pdf_document_t*) document->data;
|
pdf_document_t* pdf_document = (pdf_document_t*) document->data;
|
||||||
zathura_page_t* document_page = malloc(sizeof(zathura_page_t));
|
zathura_page_t* document_page = malloc(sizeof(zathura_page_t));
|
||||||
|
|
||||||
if (!document_page) {
|
if (document_page == NULL) {
|
||||||
return NULL;
|
goto error_ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mupdf_page_t* mupdf_page = malloc(sizeof(mupdf_page_t));
|
||||||
|
|
||||||
|
if (mupdf_page == NULL) {
|
||||||
|
goto error_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
document_page->document = document;
|
document_page->document = document;
|
||||||
document_page->data = poppler_document_get_page(pdf_document->document, page);
|
document_page->data = mupdf_page;
|
||||||
|
|
||||||
if (!document_page->data) {
|
mupdf_page->page_object = pdf_getpageobject(pdf_document->document, page + 1);
|
||||||
free(document_page);
|
|
||||||
return NULL;
|
if (pdf_loadpage(&(mupdf_page->page), pdf_document->document, mupdf_page->page_object)) {
|
||||||
|
goto error_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
poppler_page_get_size(document_page->data, &(document_page->width), &(document_page->height));
|
document_page->width = mupdf_page->page->mediabox.x1 - mupdf_page->page->mediabox.x0;
|
||||||
|
document_page->height = mupdf_page->page->mediabox.y1 - mupdf_page->page->mediabox.y0;
|
||||||
|
|
||||||
return document_page;
|
return document_page;
|
||||||
|
|
||||||
|
error_free:
|
||||||
|
|
||||||
|
free(document_page);
|
||||||
|
free(mupdf_page);
|
||||||
|
|
||||||
|
error_ret:
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -269,8 +181,49 @@ pdf_page_render(zathura_page_t* page)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
poppler_page_render_to_pixbuf(page->data, 0, 0, page_width, page_height, Zathura.document->scale,
|
pdf_document_t* pdf_document = (pdf_document_t*) page->document->data;
|
||||||
Zathura.document->rotate, pixbuf);
|
mupdf_page_t* mupdf_page = (mupdf_page_t*) page->data;
|
||||||
|
|
||||||
|
/* render */
|
||||||
|
fz_displaylist* list = fz_newdisplaylist();
|
||||||
|
fz_device* dev = fz_newlistdevice(list);
|
||||||
|
|
||||||
|
if (pdf_runpage(pdf_document->document, mupdf_page->page, dev, fz_identity)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
fz_freedevice(dev);
|
||||||
|
|
||||||
|
fz_matrix ctm = fz_translate(0, -mupdf_page->page->mediabox.y1);
|
||||||
|
ctm = fz_concat(ctm, fz_scale(Zathura.document->scale, -Zathura.document->scale));
|
||||||
|
|
||||||
|
fz_bbox bbox = fz_roundrect(fz_transformrect(ctm, mupdf_page->page->mediabox));
|
||||||
|
|
||||||
|
guchar* pixels = gdk_pixbuf_get_pixels(pixbuf);
|
||||||
|
int rowstride = gdk_pixbuf_get_rowstride(pixbuf);
|
||||||
|
int n_channels = gdk_pixbuf_get_n_channels(pixbuf);
|
||||||
|
|
||||||
|
fz_pixmap* pix = fz_newpixmapwithrect(fz_devicergb, bbox);
|
||||||
|
fz_clearpixmap(pix, 0xff);
|
||||||
|
|
||||||
|
dev = fz_newdrawdevice(pdf_document->glyphcache, pix);
|
||||||
|
fz_executedisplaylist(list, dev, ctm);
|
||||||
|
fz_freedevice(dev);
|
||||||
|
|
||||||
|
for (unsigned int y = 0; y < pix->h; y++) {
|
||||||
|
for (unsigned int x = 0; x < pix->w; x++) {
|
||||||
|
unsigned char *s = pix->samples + y * pix->w * 4 + x * 4;
|
||||||
|
guchar* p = pixels + y * rowstride + x * n_channels;
|
||||||
|
p[0] = s[0];
|
||||||
|
p[1] = s[1];
|
||||||
|
p[2] = s[2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fz_droppixmap(pix);
|
||||||
|
fz_freedisplaylist(list);
|
||||||
|
pdf_freepage(mupdf_page->page);
|
||||||
|
pdf_agestore(pdf_document->document->store, 3);
|
||||||
|
|
||||||
/* write pixbuf */
|
/* write pixbuf */
|
||||||
GtkWidget* image = gtk_image_new();
|
GtkWidget* image = gtk_image_new();
|
||||||
|
|
15
ft/pdf/pdf.h
15
ft/pdf/pdf.h
|
@ -4,20 +4,25 @@
|
||||||
#define PDF_H
|
#define PDF_H
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <poppler.h>
|
#include <fitz.h>
|
||||||
|
#include <mupdf.h>
|
||||||
|
|
||||||
#include "../document.h"
|
#include "../document.h"
|
||||||
|
|
||||||
typedef struct pdf_document_s
|
typedef struct pdf_document_s
|
||||||
{
|
{
|
||||||
PopplerDocument *document;
|
fz_glyphcache *glyphcache;
|
||||||
|
pdf_xref *document;
|
||||||
} pdf_document_t;
|
} pdf_document_t;
|
||||||
|
|
||||||
|
typedef struct mupdf_page_s
|
||||||
|
{
|
||||||
|
fz_obj* page_object;
|
||||||
|
pdf_page* page;
|
||||||
|
} mupdf_page_t;
|
||||||
|
|
||||||
bool pdf_document_open(zathura_document_t* document);
|
bool pdf_document_open(zathura_document_t* document);
|
||||||
bool pdf_document_free(zathura_document_t* document);
|
bool pdf_document_free(zathura_document_t* document);
|
||||||
girara_tree_node_t* pdf_document_index_generate(zathura_document_t* document);
|
|
||||||
bool pdf_document_save_as(zathura_document_t* document, const char* path);
|
|
||||||
zathura_list_t* pdf_document_attachments_get(zathura_document_t* document);
|
|
||||||
zathura_page_t* pdf_page_get(zathura_document_t* document, unsigned int page);
|
zathura_page_t* pdf_page_get(zathura_document_t* document, unsigned int page);
|
||||||
zathura_list_t* pdf_page_search_text(zathura_page_t* page, const char* text);
|
zathura_list_t* pdf_page_search_text(zathura_page_t* page, const char* text);
|
||||||
zathura_list_t* pdf_page_links_get(zathura_page_t* page);
|
zathura_list_t* pdf_page_links_get(zathura_page_t* page);
|
||||||
|
|
Loading…
Add table
Reference in a new issue