diff options
-rw-r--r-- | data/de.marvinborner.zathura-note.desktop | 10 | ||||
-rw-r--r-- | data/de.marvinborner.zathura-note.metainfo.xml | 10 | ||||
-rw-r--r-- | data/meson.build | 2 | ||||
-rw-r--r-- | meson.build | 68 | ||||
-rw-r--r-- | zathura-note/note.c | 160 | ||||
-rw-r--r-- | zathura-note/plugin.c | 11 | ||||
-rw-r--r-- | zathura-note/plugin.h | 54 |
7 files changed, 315 insertions, 0 deletions
diff --git a/data/de.marvinborner.zathura-note.desktop b/data/de.marvinborner.zathura-note.desktop new file mode 100644 index 0000000..771d991 --- /dev/null +++ b/data/de.marvinborner.zathura-note.desktop @@ -0,0 +1,10 @@ +[Desktop Entry] +Version=1.0 +Type=Application +Name=Zathura +Comment=A minimalistic document viewer +Exec=zathura %U +Terminal=false +NoDisplay=true +Categories=Office;Viewer; +MimeType=application/zip; diff --git a/data/de.marvinborner.zathura-note.metainfo.xml b/data/de.marvinborner.zathura-note.metainfo.xml new file mode 100644 index 0000000..7f56bad --- /dev/null +++ b/data/de.marvinborner.zathura-note.metainfo.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8"?> +<component type="addon"> + <id>de.marvinborner.zathura-note</id> + <metadata_license>CC0-1.0</metadata_license> + <project_license>MIT</project_license> + <extends>org.pwmt.zathura</extends> + <name>Zathura-PDF-MuPDF</name> + <summary>.note plugin for zathura</summary> + <update_contact>zathura@marvinborner.de</update_contact> +</component> diff --git a/data/meson.build b/data/meson.build new file mode 100644 index 0000000..6fdbadc --- /dev/null +++ b/data/meson.build @@ -0,0 +1,2 @@ +install_data('de.marvinborner.zathura-note.metainfo.xml', install_dir: metainfodir) +install_data('de.marvinborner.zathura-note.desktop', install_dir: desktopdir) diff --git a/meson.build b/meson.build new file mode 100644 index 0000000..8f7647f --- /dev/null +++ b/meson.build @@ -0,0 +1,68 @@ +project('zathura-note', 'c', + version: '0.0.1', + meson_version: '>=0.43', + default_options: ['c_std=c99', 'warning_level=3'] +) + +version = meson.project_version() +version_array = version.split('.') + +cc = meson.get_compiler('c') + +prefix = get_option('prefix') +datadir = get_option('datadir') +metainfodir = join_paths(datadir, 'metainfo') +desktopdir = join_paths(datadir, 'applications') + +# required dependencies +zathura = dependency('zathura', version: '>=0.3.9') +girara = dependency('girara-gtk3') +glib = dependency('glib-2.0') +cairo = dependency('cairo') +zip = dependency('libzip') +plist = dependency('libplist') + +build_dependencies = [ + zathura, + girara, + glib, + cairo, + zip, + plist +] + +plugindir = zathura.get_pkgconfig_variable('plugindir') + +# defines +defines = [ + '-DVERSION_MAJOR=@0@'.format(version_array[0]), + '-DVERSION_MINOR=@0@'.format(version_array[1]), + '-DVERSION_REV=@0@'.format(version_array[2]), + '-D_DEFAULT_SOURCE', +] + +# compile flags +flags = [ + '-Wall', + '-Wextra', + '-pedantic', + '-Werror=implicit-function-declaration', + '-Werror=vla', + '-fvisibility=hidden' +] +flags = cc.get_supported_arguments(flags) + +sources = files( + 'zathura-note/plugin.c', + 'zathura-note/note.c' +) + +note = shared_module('note', + sources, + dependencies: build_dependencies, + c_args: defines + flags, + install: true, + install_dir: plugindir +) + +subdir('data') diff --git a/zathura-note/note.c b/zathura-note/note.c new file mode 100644 index 0000000..2d12114 --- /dev/null +++ b/zathura-note/note.c @@ -0,0 +1,160 @@ +#include "plugin.h" + +#include <plist/plist.h> +#include <stdio.h> +#include <zip.h> + +typedef struct { + zip_t *zip; + plist_t session_plist; + plist_t metadata_plist; +} note_document_t; + +static zathura_error_t plist_load(zip_t *zip, plist_t *plist, const char *root_name, + const char *path) +{ + char name[1024] = { 0 }; + snprintf(name, sizeof(name), "%s/%s", root_name, path); + zip_stat_t stat; + zip_stat(zip, name, 0, &stat); + zip_file_t *file = zip_fopen(zip, name, 0); + if (!file) { + zip_error_t *err = zip_get_error(zip); + fprintf(stderr, "Couldn't find '%s' in zip: %s\n", name, zip_error_strerror(err)); + return ZATHURA_ERROR_INVALID_ARGUMENTS; + } + + void *bin = malloc(stat.size); + size_t length = zip_fread(file, bin, stat.size); + if (length < stat.size) + fprintf(stderr, "Unexpected size difference\n"); + + plist_from_bin(bin, stat.size, plist); + free(bin); + return ZATHURA_ERROR_OK; +} + +GIRARA_HIDDEN zathura_error_t note_document_open(zathura_document_t *document) +{ + zathura_error_t error = ZATHURA_ERROR_OK; + + if (!document) { + error = ZATHURA_ERROR_INVALID_ARGUMENTS; + return error; + } + + int zip_err; + zip_t *zip = + zip_open(zathura_document_get_path(document), ZIP_CHECKCONS | ZIP_RDONLY, &zip_err); + if (!zip || zip_err) { + zip_error_t *err = zip_get_error(zip); + fprintf(stderr, "Couldn't open .note zip: (%d): %s\n", zip_err, + zip_error_strerror(err)); + return ZATHURA_ERROR_INVALID_ARGUMENTS; + } + + char *root_name; + zip_stat_t root_stat; + if (!zip_stat_index(zip, 0, ZIP_FL_NODIR, &root_stat)) { + int length = strlen(root_stat.name); + root_name = malloc(length + 1); + strcpy(root_name, root_stat.name); + strtok(root_name, "/"); + root_name[length] = 0; + } else { + // Wtf? No files? + return ZATHURA_ERROR_INVALID_ARGUMENTS; + } + + note_document_t *note_document = malloc(sizeof(*note_document)); + + // Load Session.plist from zip + zathura_error_t session_error = + plist_load(zip, ¬e_document->session_plist, root_name, "Session.plist"); + if (session_error != ZATHURA_ERROR_OK) { + free(note_document); + free(root_name); + return session_error; + } + + // Load metadata.plist from zip + zathura_error_t metadata_error = + plist_load(zip, ¬e_document->metadata_plist, root_name, "metadata.plist"); + if (metadata_error != ZATHURA_ERROR_OK) { + free(note_document); + free(root_name); + return metadata_error; + } + + note_document->zip = zip; + + zathura_document_set_data(document, note_document); + zathura_document_set_number_of_pages(document, 1); // TODO: Get page count + + free(root_name); + return ZATHURA_ERROR_OK; +} + +GIRARA_HIDDEN zathura_error_t note_document_free(zathura_document_t *document, void *data) +{ + note_document_t *note_document = data; + zip_close(note_document->zip); + return ZATHURA_ERROR_OK; +} + +GIRARA_HIDDEN zathura_error_t note_page_init(zathura_page_t *page) +{ + // TODO: Get width dynamagically + int width = 500; + zathura_page_set_width(page, width); + zathura_page_set_height(page, (int)((float)width * 1.41)); + + return ZATHURA_ERROR_OK; +} + +GIRARA_HIDDEN zathura_error_t note_page_clear(zathura_page_t *page, void *data) +{ + return ZATHURA_ERROR_OK; +} + +// For debugging +static void plist_dump(plist_t plist, int depth) +{ + // Debug dump + plist_dict_iter iter; + plist_dict_new_iter(plist, &iter); + char *key = 0; + plist_t val; + while (1) { + plist_dict_next_item(plist, iter, &key, &val); + if (!key || !val) + break; + + printf("%s\n", key); + for (int i = 0; i < depth; i++) + printf(" "); + } +} + +GIRARA_HIDDEN zathura_error_t note_page_render_cairo(zathura_page_t *page, void *data, + cairo_t *cairo, bool printing) +{ + printf("Rendering page %d\n", zathura_page_get_index(page)); + if (printing) + return ZATHURA_ERROR_NOT_IMPLEMENTED; + + note_document_t *note_document = data; + plist_dump(note_document->session_plist, 0); + + /* cairo_set_source_rgba(cairo, 0xff, 0, 0, 1); */ + /* cairo_set_line_width(cairo, 1); */ + /* cairo_move_to(cairo, 0, 0); */ + /* cairo_line_to(cairo, 100, 100); */ + /* cairo_rel_line_to(cairo, 0.25, -0.125); */ + /* cairo_arc(cairo, 0.5, 0.5, 0.25 * sqrt(2), -0.25 * M_PI, 0.25 * M_PI); */ + /* cairo_rel_curve_to(cairo, -0.25, -0.125, -0.25, 0.125, -0.5, 0); */ + /* cairo_close_path(cairo); */ + /* cairo_stroke(cairo); */ + + return ZATHURA_ERROR_OK; +} diff --git a/zathura-note/plugin.c b/zathura-note/plugin.c new file mode 100644 index 0000000..713475e --- /dev/null +++ b/zathura-note/plugin.c @@ -0,0 +1,11 @@ +#include "plugin.h" + +ZATHURA_PLUGIN_REGISTER_WITH_FUNCTIONS("pdf-mupdf", VERSION_MAJOR, VERSION_MINOR, VERSION_REV, + ZATHURA_PLUGIN_FUNCTIONS({ + .document_open = note_document_open, + .document_free = note_document_free, + .page_init = note_page_init, + .page_clear = note_page_clear, + .page_render_cairo = note_page_render_cairo, + }), + ZATHURA_PLUGIN_MIMETYPES({ "application/zip" })) diff --git a/zathura-note/plugin.h b/zathura-note/plugin.h new file mode 100644 index 0000000..e16205a --- /dev/null +++ b/zathura-note/plugin.h @@ -0,0 +1,54 @@ +#ifndef PLUGIN_H +#define PLUGIN_H + +#include <zathura/plugin-api.h> + +/** + * Open a note document + * + * @param document Zathura document + * @return ZATHURA_ERROR_OK when no error occurred, otherwise see + * zathura_error_t + */ +GIRARA_HIDDEN zathura_error_t note_document_open(zathura_document_t *document); + +/** + * Closes and frees the internal document structure + * + * @param document Zathura document + * @return ZATHURA_ERROR_OK when no error occurred, otherwise see + * zathura_error_t + */ +GIRARA_HIDDEN zathura_error_t note_document_free(zathura_document_t *document, void *note_document); + +/** + * Initializes the page + * + * @param page The page object + * @return ZATHURA_ERROR_OK when no error occurred, otherwise see + * zathura_error_t + */ +GIRARA_HIDDEN zathura_error_t note_page_init(zathura_page_t *page); + +/** + * Frees a note page + * + * @param page Page + * @return ZATHURA_ERROR_OK when no error occurred, otherwise see + * zathura_error_t + */ +GIRARA_HIDDEN zathura_error_t note_page_clear(zathura_page_t *page, void *data); + +/** + * Renders a page onto a cairo object + * + * @param page Page + * @param cairo Cairo object + * @param printing Set to true if page should be rendered for printing + * @return ZATHURA_ERROR_OK when no error occurred, otherwise see + * zathura_error_t + */ +GIRARA_HIDDEN zathura_error_t note_page_render_cairo(zathura_page_t *page, void *data, + cairo_t *cairo, bool printing); + +#endif |