pax_global_header00006660000000000000000000000064122374425570014525gustar00rootroot0000000000000052 comment=cd05c5dfad504fcd748541881cb19ee87a8717af zathura-cb-0.1.2/000075500000000000000000000000001223744255700135635ustar00rootroot00000000000000zathura-cb-0.1.2/.gitignore000064400000000000000000000001421223744255700155500ustar00rootroot00000000000000*.o *.do *~ .depend *.so *.swp zathura-version-check tags compile_commands.json .ycm_extra_conf.* zathura-cb-0.1.2/AUTHORS000064400000000000000000000002561223744255700146360ustar00rootroot00000000000000zathura-cb is written by: Moritz Lipp Sebastian Ramacher Other contributors are (in no particular order): Frank Smit zathura-cb-0.1.2/Doxyfile000064400000000000000000000011621223744255700152710ustar00rootroot00000000000000# See LICENSE file for license and copyright information # General information PROJECT_NAME = zathura-cb OUTPUT_DIRECTORY = ./doc/ OUTPUT_LANGUAGE = English TAB_SIZE = 2 EXTRACT_ALL = YES OPTIMIZE_OUTPUT_FOR_C = YES DOXYFILE_ENCODING = UTF-8 TYPEDEF_HIDES_STRUCT = YES # Warning and progress messages QUIET = YES WARNINGS = YES WARN_IF_UNDOCUMENTED = YES # Input files INPUT = FILE_PATTERNS = *.h *.c RECURSIVE = YES # Output files GENERATE_HTML = YES GENERATE_LATEX = NO GENERATE_RTF = NO GENERATE_XML = NO SOURCE_BROWSER = YES zathura-cb-0.1.2/LICENSE000064400000000000000000000015421223744255700145720ustar00rootroot00000000000000Copyright (c) 2012-2013 pwmt.org This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. zathura-cb-0.1.2/Makefile000064400000000000000000000052111223744255700152220ustar00rootroot00000000000000# See LICENSE file for license and copyright information include config.mk include common.mk PROJECT = zathura-cb PLUGIN = cb SOURCE = $(wildcard *.c) HEADER = $(wildcard *.h) OBJECTS = ${SOURCE:.c=.o} DOBJECTS = ${SOURCE:.c=.do} ifneq "$(WITH_CAIRO)" "0" CPPFLAGS += -DHAVE_CAIRO INCS += $(CAIRO_INC) LIBS += $(CAIRO_LIB) endif CPPFLAGS += "-DVERSION_MAJOR=${VERSION_MAJOR}" CPPFLAGS += "-DVERSION_MINOR=${VERSION_MINOR}" CPPFLAGS += "-DVERSION_REV=${VERSION_REV}" all: options ${PLUGIN}.so zathura-version-check: ifneq ($(ZATHURA_VERSION_CHECK), 0) $(error "The minimum required version of zathura is ${ZATHURA_MIN_VERSION}") endif $(QUIET)touch zathura-version-check options: $(ECHO) ${PLUGIN} build options: $(ECHO) "CFLAGS = ${CFLAGS}" $(ECHO) "LDFLAGS = ${LDFLAGS}" $(ECHO) "DFLAGS = ${DFLAGS}" $(ECHO) "CC = ${CC}" %.o: %.c $(ECHO) CC $< @mkdir -p .depend $(QUIET)${CC} -c ${CPPFLAGS} ${CFLAGS} -o $@ $< -MMD -MF .depend/$@.dep %.do: %.c $(ECHO) CC $< @mkdir -p .depend $(QUIET)${CC} -c ${CPPFLAGS} ${CFLAGS} ${DFLAGS} -o $@ $< -MMD -MF .depend/$@.dep ${OBJECTS}: config.mk zathura-version-check ${DOBJECTS}: config.mk zathura-version-check ${PLUGIN}.so: ${OBJECTS} $(ECHO) LD $@ $(QUIET)${CC} -shared ${LDFLAGS} -o $@ $(OBJECTS) ${LIBS} ${PLUGIN}-debug.so: ${DOBJECTS} $(ECHO) LD $@ $(QUIET)${CC} -shared ${LDFLAGS} -o $@ $(DOBJECTS) ${LIBS} clean: $(QUIET)rm -rf ${OBJECTS} ${DOBJECTS} $(PLUGIN).so $(PLUGIN)-debug.so \ doc .depend ${PROJECT}-${VERSION}.tar.gz zathura-version-check debug: options ${PLUGIN}-debug.so dist: clean $(QUIET)mkdir -p ${PROJECT}-${VERSION} $(QUIET)cp -R LICENSE Makefile config.mk common.mk Doxyfile \ ${HEADER} ${SOURCE} AUTHORS ${PROJECT}.desktop \ ${PROJECT}-${VERSION} $(QUIET)tar -cf ${PROJECT}-${VERSION}.tar ${PROJECT}-${VERSION} $(QUIET)gzip ${PROJECT}-${VERSION}.tar $(QUIET)rm -rf ${PROJECT}-${VERSION} doc: clean $(QUIET)doxygen Doxyfile install: all $(ECHO) installing ${PLUGIN} plugin $(QUIET)mkdir -p ${DESTDIR}${PLUGINDIR} $(QUIET)cp -f ${PLUGIN}.so ${DESTDIR}${PLUGINDIR} $(QUIET)mkdir -m 755 -p ${DESTDIR}${DESKTOPPREFIX} $(ECHO) installing desktop file $(QUIET)install -m 644 ${PROJECT}.desktop ${DESTDIR}${DESKTOPPREFIX} uninstall: $(ECHO) uninstalling ${PLUGIN} plugin $(QUIET)rm -f ${DESTDIR}${PLUGINDIR}/${PLUGIN}.so $(QUIET)rmdir --ignore-fail-on-non-empty ${DESTDIR}${PLUGINDIR} 2> /dev/null $(ECHO) removing desktop file $(QUIET)rm -f ${DESTDIR}${DESKTOPPREFIX}/${PROJECT}.desktop $(QUIET)rmdir --ignore-fail-on-non-empty ${DESTDIR}${DESKTOPPREFIX} 2> /dev/null -include $(wildcard .depend/*.dep) .PHONY: all options clean debug doc dist install uninstall zathura-cb-0.1.2/README000064400000000000000000000005031223744255700144410ustar00rootroot00000000000000zathura-cb ================= The zathura-b plugin adds comic book support to zathura. Requirements ------------ zathura (>= 0.2.0) libarchive girara cairo Installation ------------ To build and install the plugin: make install Uninstall: ---------- To delete the plugin from your system, just type: make uninstall zathura-cb-0.1.2/common.mk000064400000000000000000000001761223744255700154100ustar00rootroot00000000000000# See LICENSE file for license and copyright information ifeq "$(VERBOSE)" "0" ECHO=@echo QUIET=@ else ECHO=@\# QUIET= endif zathura-cb-0.1.2/config.mk000064400000000000000000000027701223744255700153670ustar00rootroot00000000000000# See LICENSE file for license and copyright information VERSION_MAJOR = 0 VERSION_MINOR = 1 VERSION_REV = 2 VERSION = ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_REV} # minimum required zathura version ZATHURA_MIN_VERSION = 0.2.0 ZATHURA_VERSION_CHECK ?= $(shell pkg-config --atleast-version=$(ZATHURA_MIN_VERSION) zathura; echo $$?) ZATHURA_GTK_VERSION ?= $(shell pkg-config --variable=GTK_VERSION zathura) # paths PREFIX ?= /usr LIBDIR ?= ${PREFIX}/lib DESKTOPPREFIX ?= ${PREFIX}/share/applications # libs CAIRO_INC ?= $(shell pkg-config --cflags cairo) CAIRO_LIB ?= $(shell pkg-config --libs cairo) LIBARCHIVE_INC ?= $(shell pkg-config --cflags libarchive) LIBARCHIVE_LIB ?= $(shell pkg-config --libs libarchive) GLIB_INC ?= $(shell pkg-config --cflags glib-2.0) GLIB_LIB ?= $(shell pkg-config --libs glib-2.0) GIRARA_INC ?= $(shell pkg-config --cflags girara-gtk${ZATHURA_GTK_VERSION}) GIRARA_LIB ?= $(shell pkg-config --libs girara-gtk${ZATHURA_GTK_VERSION}) ZATHURA_INC ?= $(shell pkg-config --cflags zathura) INCS = ${GIRARA_INC} ${GLIB_INC} ${ZATHURA_INC} ${LIBARCHIVE_INC} LIBS = ${GIRARA_LIB} ${GLIB_LIB} ${LIBARCHIVE_LIB} # plugindir PLUGINDIR ?= $(shell pkg-config --variable=plugindir zathura) ifeq (,${PLUGINDIR}) PLUGINDIR = ${LIBDIR}/zathura endif # flags CFLAGS += -std=c99 -fPIC -pedantic -Wall -Wno-format-zero-length $(INCS) # debug DFLAGS ?= -g # build with cairo support? WITH_CAIRO ?= 1 # compiler CC ?= gcc LD ?= ld # set to something != 0 if you want verbose build output VERBOSE ?= 0 zathura-cb-0.1.2/document.c000064400000000000000000000127711223744255700155550ustar00rootroot00000000000000/* See LICENSE file for license and copyright information */ #include #include #include #include #include #include #include #include #include #include "plugin.h" #include "internal.h" #include "utils.h" static int compare_pages(const cb_document_page_meta_t* page1, const cb_document_page_meta_t* page2); static bool read_archive(cb_document_t* cb_document, const char* archive, girara_list_t* supported_extensions); static const char* get_extension(const char* path); static void cb_document_page_meta_free(cb_document_page_meta_t* meta); zathura_error_t cb_document_open(zathura_document_t* document) { if (document == NULL) { return ZATHURA_ERROR_INVALID_ARGUMENTS; } cb_document_t* cb_document = g_malloc0(sizeof(cb_document)); /* archive path */ const char* path = zathura_document_get_path(document); /* create list of supported formats */ girara_list_t* supported_extensions = girara_list_new2(g_free); if (supported_extensions == NULL) { goto error_free; } GSList* formats = gdk_pixbuf_get_formats(); for (GSList* list = formats; list != NULL; list = list->next) { GdkPixbufFormat* format = (GdkPixbufFormat*) list->data; char** extensions = gdk_pixbuf_format_get_extensions(format); for (unsigned int i = 0; extensions[i] != NULL; i++) { girara_list_append(supported_extensions, g_strdup(extensions[i])); } g_strfreev(extensions); } g_slist_free(formats); /* create list of supported files (pages) */ cb_document->pages = girara_sorted_list_new2((girara_compare_function_t) compare_pages, (girara_free_function_t) cb_document_page_meta_free); if (cb_document->pages == NULL) { goto error_free; } /* read files recursively */ if (read_archive(cb_document, path, supported_extensions) == false) { goto error_free; } girara_list_free(supported_extensions); /* set document information */ zathura_document_set_number_of_pages(document, girara_list_size(cb_document->pages)); zathura_document_set_data(document, cb_document); return ZATHURA_ERROR_OK; error_free: girara_list_free(supported_extensions); cb_document_free(document, cb_document); return ZATHURA_ERROR_UNKNOWN; } zathura_error_t cb_document_free(zathura_document_t* document, cb_document_t* cb_document) { if (cb_document == NULL) { return ZATHURA_ERROR_INVALID_ARGUMENTS; } /* remove page list */ if (cb_document->pages != NULL) { girara_list_free(cb_document->pages); } g_free(cb_document); return ZATHURA_ERROR_OK; } static void cb_document_page_meta_free(cb_document_page_meta_t* meta) { if (meta == NULL) { return; } if (meta->file != NULL) { g_free(meta->file); } g_free(meta); } static void get_pixbuf_size(GdkPixbufLoader* loader, int width, int height, gpointer data) { cb_document_page_meta_t* meta = (cb_document_page_meta_t*)data; meta->width = width; meta->height = height; gdk_pixbuf_loader_set_size(loader, 0, 0); } static bool read_archive(cb_document_t* cb_document, const char* archive, girara_list_t* supported_extensions) { struct archive* a = archive_read_new(); if (a == NULL) { return false; } archive_read_support_filter_all(a); archive_read_support_format_all(a); int r = archive_read_open_filename(a, archive, (size_t) LIBARCHIVE_BUFFER_SIZE); if (r != ARCHIVE_OK) { archive_read_free(a); return false; } struct archive_entry *entry = NULL; while ((r = archive_read_next_header(a, &entry)) != ARCHIVE_EOF) { if (r < ARCHIVE_WARN) { // let's ignore warnings ... they are non-fatal errors archive_read_close(a); archive_read_free(a); return false; } if (archive_entry_filetype(entry) != AE_IFREG) { // we only care about regular files continue; } const char* path = archive_entry_pathname(entry); const char* extension = get_extension(path); GIRARA_LIST_FOREACH(supported_extensions, char*, iter, ext) if (g_strcmp0(extension, ext) == 0) { cb_document_page_meta_t* meta = g_malloc0(sizeof(cb_document_page_meta_t)); meta->file = g_strdup(path); GdkPixbufLoader* loader = gdk_pixbuf_loader_new(); g_signal_connect(loader, "size-prepared", G_CALLBACK(get_pixbuf_size), meta); size_t size = 0; const void* buf = NULL; off_t offset = 0; while ((r = archive_read_data_block(a, &buf, &size, &offset)) != ARCHIVE_EOF) { if (size <= 0) { continue; } if (gdk_pixbuf_loader_write(loader, buf, size, NULL) == false) { break; } if (meta->width > 0 || meta->height > 0) { break; } } gdk_pixbuf_loader_close(loader, NULL); g_object_unref(loader); if (meta->width > 0 && meta->height > 0) { girara_list_append(cb_document->pages, meta); } else { cb_document_page_meta_free(meta); } break; } GIRARA_LIST_FOREACH_END(supported_extensions, char*, iter, ext); } archive_read_close(a); archive_read_free(a); return true; } static int compare_pages(const cb_document_page_meta_t* page1, const cb_document_page_meta_t* page2) { return compare_path(page1->file, page2->file); } static const char* get_extension(const char* path) { if (path == NULL) { return NULL; } const char* res = strrchr(path, '.'); if (res == NULL) { return NULL; } return res + 1; } zathura-cb-0.1.2/internal.h000064400000000000000000000010501223744255700155440ustar00rootroot00000000000000/* See LICENSE file for license and copyright information */ #ifndef INTERNAL_H #define INTERNAL_H #define LIBARCHIVE_BUFFER_SIZE 8192 struct cb_document_s { girara_list_t* pages; /**< List of metadata structs */ }; struct cb_page_s { char* file; /**< Image associated to the page */ }; /** Image meta-data read during the document initialization */ typedef struct cb_document_page_meta_s { char* file; /**< Image file */ int width; /**< Image width */ int height; /**< Image height */ } cb_document_page_meta_t; #endif // INTERNAL_H zathura-cb-0.1.2/page.c000064400000000000000000000022731223744255700146470ustar00rootroot00000000000000/* See LICENSE file for license and copyright information */ #include #include #include "plugin.h" #include "internal.h" zathura_error_t cb_page_init(zathura_page_t* page) { if (page == NULL) { return ZATHURA_ERROR_INVALID_ARGUMENTS; } zathura_document_t* document = zathura_page_get_document(page); cb_document_t* cb_document = zathura_document_get_data(document); if (document == NULL || cb_document == NULL) { return ZATHURA_ERROR_UNKNOWN; } cb_document_page_meta_t* meta = girara_list_nth(cb_document->pages, zathura_page_get_index(page)); if (meta == NULL || meta->file == NULL) { return ZATHURA_ERROR_UNKNOWN; } cb_page_t* cb_page = g_malloc0(sizeof(cb_page_t)); if (cb_page == NULL) { return ZATHURA_ERROR_OUT_OF_MEMORY; } cb_page->file = g_strdup(meta->file); zathura_page_set_width(page, meta->width); zathura_page_set_height(page, meta->height); zathura_page_set_data(page, cb_page); return ZATHURA_ERROR_OK; } zathura_error_t cb_page_clear(zathura_page_t* page, cb_page_t* cb_page) { if (cb_page == NULL) { return ZATHURA_ERROR_OK; } g_free(cb_page->file); g_free(cb_page); return ZATHURA_ERROR_OK; } zathura-cb-0.1.2/plugin.c000064400000000000000000000016451223744255700152330ustar00rootroot00000000000000/* See LICENSE file for license and copyright information */ #include "plugin.h" void register_functions(zathura_plugin_functions_t* functions) { functions->document_open = (zathura_plugin_document_open_t) cb_document_open; functions->document_free = (zathura_plugin_document_free_t) cb_document_free; functions->page_init = (zathura_plugin_page_init_t) cb_page_init; functions->page_clear = (zathura_plugin_page_clear_t) cb_page_clear; #ifdef HAVE_CAIRO functions->page_render_cairo = (zathura_plugin_page_render_cairo_t) cb_page_render_cairo; #endif } ZATHURA_PLUGIN_REGISTER( "cb", VERSION_MAJOR, VERSION_MINOR, VERSION_REV, register_functions, ZATHURA_PLUGIN_MIMETYPES({ "application/x-cbr", "application/x-rar", "application/x-cbz", "application/zip", "application/x-cb7", "application/x-7z-compressed", "application/x-cbt", "application/x-tar" }) ) zathura-cb-0.1.2/plugin.h000064400000000000000000000025731223744255700152410ustar00rootroot00000000000000/* See LICENSE file for license and copyright information */ #ifndef CB_H #define CB_H #include #if HAVE_CAIRO #include #endif #include typedef struct cb_document_s cb_document_t; typedef struct cb_page_s cb_page_t; /** * Opens a new document * * @param document The document * @return ZATHURA_ERROR_OK if no error occured */ zathura_error_t cb_document_open(zathura_document_t* document); /** * Frees the document * * @param document The document * @param data Custom data * @return ZATHURA_ERROR_OK if no error occured */ zathura_error_t cb_document_free(zathura_document_t* document, cb_document_t* cb_document); /** * Initializes a page * * @param page The page * @return ZATHURA_ERROR_OK if no error occured */ zathura_error_t cb_page_init(zathura_page_t* page); /** * Clear page * * @param page The page * @param cb_page cb Page * @return ZATHURA_ERROR_OK if no error occured */ zathura_error_t cb_page_clear(zathura_page_t* page, cb_page_t* cb_page); #if HAVE_CAIRO /** * Renders the page to a cairo object * * @param page The page * @param cb_page cb Page * @param cairo Cairo object * @param printing Render for printing * @return ZATHURA_ERROR_OK if no error occured */ zathura_error_t cb_page_render_cairo(zathura_page_t* page, cb_page_t* cb_page, cairo_t* cairo, bool printing); #endif #endif // CB_H zathura-cb-0.1.2/render.c000064400000000000000000000057431223744255700152170ustar00rootroot00000000000000/* See LICENSE file for license and copyright information */ #include #include #include #include #include #include "plugin.h" #include "internal.h" #include "utils.h" #if !defined(HAVE_CAIRO) #error "Cannot render without cairo" #endif static GdkPixbuf* load_pixbuf_from_archive(const char* archive, const char* file); #if HAVE_CAIRO zathura_error_t cb_page_render_cairo(zathura_page_t* page, cb_page_t* cb_page, cairo_t* cairo, bool printing) { if (page == NULL || cb_page == NULL || cairo == NULL) { return ZATHURA_ERROR_INVALID_ARGUMENTS; } zathura_document_t* document = zathura_page_get_document(page); if (document == NULL) { return ZATHURA_ERROR_UNKNOWN; } GdkPixbuf* pixbuf = load_pixbuf_from_archive(zathura_document_get_path(document), cb_page->file); if (pixbuf == NULL) { return ZATHURA_ERROR_UNKNOWN; } gdk_cairo_set_source_pixbuf(cairo, pixbuf, 0, 0); cairo_paint(cairo); g_object_unref(pixbuf); return ZATHURA_ERROR_OK; } #endif static GdkPixbuf* load_pixbuf_from_archive(const char* archive, const char* file) { if (archive == NULL || file == NULL) { return NULL; } struct archive* a = archive_read_new(); if (a == NULL) { return NULL; } archive_read_support_filter_all(a); archive_read_support_format_all(a); int r = archive_read_open_filename(a, archive, LIBARCHIVE_BUFFER_SIZE); if (r != ARCHIVE_OK) { return NULL; } struct archive_entry* entry = NULL; while ((r = archive_read_next_header(a, &entry)) != ARCHIVE_EOF) { if (r < ARCHIVE_WARN) { archive_read_close(a); archive_read_free(a); return NULL; } const char* path = archive_entry_pathname(entry); if (compare_path(path, file) != 0) { continue; } GInputStream* is = g_memory_input_stream_new(); if (is == NULL) { archive_read_close(a); archive_read_free(a); return NULL; } GMemoryInputStream* mis = G_MEMORY_INPUT_STREAM(is); size_t size = 0; const void* buf = NULL; off_t offset = 0; while ((r = archive_read_data_block(a, &buf, &size, &offset)) != ARCHIVE_EOF) { if (r < ARCHIVE_WARN) { archive_read_close(a); archive_read_free(a); g_object_unref(mis); return NULL; } if (size == 0) { continue; } void* tmp = g_malloc0(size); if (tmp == NULL) { archive_read_close(a); archive_read_free(a); g_object_unref(mis); return NULL; } memcpy(tmp, buf, size); g_memory_input_stream_add_data(mis, tmp, size, g_free); } GdkPixbuf* pixbuf = gdk_pixbuf_new_from_stream(is, NULL, NULL); if (pixbuf == NULL) { archive_read_close(a); archive_read_free(a); g_object_unref(mis); return NULL; } archive_read_close(a); archive_read_free(a); g_object_unref(mis); return pixbuf; } archive_read_close(a); archive_read_free(a); return NULL; } zathura-cb-0.1.2/utils.c000064400000000000000000000005261223744255700150720ustar00rootroot00000000000000/* See LICENSE file for license and copyright information */ #include #include "utils.h" int compare_path(const char* str1, const char* str2) { char* ustr1 = g_utf8_casefold(str1, -1); char* ustr2 = g_utf8_casefold(str2, -1); int result = g_utf8_collate(ustr1, ustr2); g_free(ustr1); g_free(ustr2); return result; } zathura-cb-0.1.2/utils.h000064400000000000000000000004371223744255700151000ustar00rootroot00000000000000/* See LICENSE file for license and copyright information */ #ifndef UTILS_H #define UTILS_H /** * Compares two paths with each other * * @param str1 First path * @param str2 Second path * * @return */ int compare_path(const char* str1, const char* str2); #endif // UTILS_H zathura-cb-0.1.2/zathura-cb.desktop000064400000000000000000000021431223744255700172160ustar00rootroot00000000000000[Desktop Entry] Version=1.0 Type=Application Name=Zathura Comment=A minimalistic document viewer Comment[ca]=Un visualitzador de documents minimalista Comment[de]=Ein minimalistischer Dokumenten-Betrachter Comment[el]=Ένας ελαφρύς προβολέας κειμένων Comment[eo]=Malpeza dokumento spektanto Comment[es_CL]=Un visor de documentos minimalista Comment[fr]=Un visionneur de document minimaliste Comment[he]=מציג מסמכים מינימליסטי Comment[id_ID]=Pembaca dokumen minimalis Comment[it]=Un visualizzatore di documenti minimalista Comment[pl]=Minimalistyczna przeglądarka dokumentów Comment[pt_BR]=Um visualizador de documentos minimalista Comment[ru]=Минималистичный просмотрщик документов Comment[tr]=Minimalist bir belge görüntüleyicisi Comment[uk_UA]=Легкий переглядач документів Exec=zathura %f Terminal=false NoDisplay=true Categories=Office;Viewer; MimeType=application/x-cbr;application/x-rar;application/x-cbz;application/zip;application/x-cb7;application/x-7z-compressed;application/x-cbt;application/x-tar;