aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/de.marvinborner.zathura-note.desktop10
-rw-r--r--data/de.marvinborner.zathura-note.metainfo.xml10
-rw-r--r--data/meson.build2
-rw-r--r--meson.build68
-rw-r--r--zathura-note/note.c160
-rw-r--r--zathura-note/plugin.c11
-rw-r--r--zathura-note/plugin.h54
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, &note_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, &note_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