Hello community, here is the log from the commit of package libgepub for openSUSE:Factory checked in at 2016-09-01 14:03:49 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/libgepub (Old) and /work/SRC/openSUSE:Factory/.libgepub.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libgepub" Changes: -------- --- /work/SRC/openSUSE:Factory/libgepub/libgepub.changes 2016-08-25 09:56:51.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.libgepub.new/libgepub.changes 2016-09-01 14:03:51.000000000 +0200 @@ -1,0 +2,41 @@ +Wed Aug 31 10:13:52 UTC 2016 - dims...@opensuse.org + +- Update to version 0.4: + + go_next and go_prev returns TRUE if success. + + Added functions to get the current doc mime and path. + + Fixed resource path for relative and doc paths. + + Remove libarchive from the public API. + + Simplify pkg-config file. + + Don't link the library against GTK+. + + Function to replace relative resources by epub://. + + utils: replace epub:// URIs for crosslinks too. + + utils: correctly terminate base URI. + + doc: fix wrong path when looking for resources. + + doc: make API to get resources consistent. + + Added GepubWidget class to show the content with webkit. + + Don't NULL-terminate document content. + + utils: remove unused variable. + + build: highlight introspection warnings. + + build: fix introspection warnings. + + Fixes in gepub-widget to work with the last merge. + + widget: make it a WebKitWebView. + + widget: simplify code. + + Fix gtk-doc annotations. + + widget: make the GepubDoc a property. + + doc: remove unneeded API. + + doc: use htmlReadMemory(). + + widget: plug a memory leak. + + Rework API to be based on GBytes. + + doc: trivial indentation fix. + + Const-ify API methods that take strings. + + doc: don't call g_list_append(). + + doc: rework page API. + + widget: automatically reload chapter when current page changes. + + Ignore HTML entities parse error when loading xml. + + New release 0.4. +- Add pkgconfig(libsoup-2.4) and pkgconfig(webkit2gtk-4.0) + BuildRequires: new dependencies. +- Rename typelib-1_0-Gepub-0_3 subpackage to typelib-1_0-Gepub-0_4, + following upstreams rename of the typelib file. + +------------------------------------------------------------------- Old: ---- libgepub-0.3.tar.xz New: ---- libgepub-0.4.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libgepub.spec ++++++ --- /var/tmp/diff_new_pack.RCYg3g/_old 2016-09-01 14:03:52.000000000 +0200 +++ /var/tmp/diff_new_pack.RCYg3g/_new 2016-09-01 14:03:52.000000000 +0200 @@ -18,7 +18,7 @@ %global sover 0 Name: libgepub -Version: 0.3 +Version: 0.4 Release: 0 Summary: Epub Documents library License: LGPL-2.1+ @@ -33,7 +33,9 @@ BuildRequires: pkgconfig(gobject-introspection-1.0) >= 1.30.0 BuildRequires: pkgconfig(gtk+-3.0) BuildRequires: pkgconfig(libarchive) +BuildRequires: pkgconfig(libsoup-2.4) BuildRequires: pkgconfig(libxml-2.0) +BuildRequires: pkgconfig(webkit2gtk-4.0) BuildRoot: %{_tmppath}/%{name}-%{version}-build %description @@ -46,18 +48,18 @@ %description -n %{name}%{sover} A GObject based library for handling and rendering epub documents. -%package -n typelib-1_0-Gepub-0_3 +%package -n typelib-1_0-Gepub-0_4 Summary: Epub Documents library -- Introspection bindings Group: System/Libraries -%description -n typelib-1_0-Gepub-0_3 +%description -n typelib-1_0-Gepub-0_4 A GObject based library for handling and rendering epub documents. %package devel Summary: Epub Documents library -- Development files Group: Development/Languages/C and C++ Requires: %{name}%{sover} = %{version} -Requires: typelib-1_0-Gepub-0_3 = %{version} +Requires: typelib-1_0-Gepub-0_4 = %{version} %description devel A GObject based library for handling and rendering epub documents. @@ -83,15 +85,15 @@ %doc README COPYING %{_libdir}/%{name}.so.* -%files -n typelib-1_0-Gepub-0_3 +%files -n typelib-1_0-Gepub-0_4 %defattr(-,root,root) -%{_libdir}/girepository-1.0/Gepub-0.3.typelib +%{_libdir}/girepository-1.0/Gepub-0.4.typelib %files devel %defattr(-,root,root) %{_includedir}/%{name}/ %{_libdir}/%{name}.so %{_libdir}/pkgconfig/%{name}.pc -%{_datadir}/gir-1.0/Gepub-0.3.gir +%{_datadir}/gir-1.0/Gepub-0.4.gir %changelog ++++++ _service ++++++ --- /var/tmp/diff_new_pack.RCYg3g/_old 2016-09-01 14:03:52.000000000 +0200 +++ /var/tmp/diff_new_pack.RCYg3g/_new 2016-09-01 14:03:52.000000000 +0200 @@ -4,7 +4,7 @@ <param name="scm">git</param> <param name="versionformat">@PARENT_TAG@</param> <param name="changesgenerate">enable</param> - <param name="revision">refs/tags/0.3</param> + <param name="revision">refs/tags/0.4</param> </service> <service mode="disabled" name="recompress"> <param name="file">*.tar</param> ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.RCYg3g/_old 2016-09-01 14:03:52.000000000 +0200 +++ /var/tmp/diff_new_pack.RCYg3g/_new 2016-09-01 14:03:52.000000000 +0200 @@ -1,4 +1,4 @@ <servicedata> <service name="tar_scm"> <param name="url">git://git.gnome.org/libgepub</param> - <param name="changesrevision">f1c9898c40762d89e0fa7e9094c00265e183adbb</param></service></servicedata> \ No newline at end of file + <param name="changesrevision">37b240c7877eafaa8ca2df76a779444f0235e5a3</param></service></servicedata> \ No newline at end of file ++++++ libgepub-0.3.tar.xz -> libgepub-0.4.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgepub-0.3/TODO new/libgepub-0.4/TODO --- old/libgepub-0.3/TODO 2016-05-23 09:29:03.000000000 +0200 +++ new/libgepub-0.4/TODO 2016-08-31 09:39:20.000000000 +0200 @@ -0,0 +1,2 @@ + - support for multi-page display: get_current_next() or get_current_nth() + to the the page nth diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgepub-0.3/configure.ac new/libgepub-0.4/configure.ac --- old/libgepub-0.3/configure.ac 2016-05-23 09:29:03.000000000 +0200 +++ new/libgepub-0.4/configure.ac 2016-08-31 09:39:20.000000000 +0200 @@ -1,5 +1,5 @@ AC_PREREQ(2.60) -AC_INIT([libgepub],[0.3],[dan...@wadobo.com]) +AC_INIT([libgepub],[0.4],[dan...@wadobo.com]) AC_CONFIG_AUX_DIR([build]) AM_INIT_AUTOMAKE([1.10 -Wall -Werror dist-bzip2]) AM_SILENT_RULES([yes]) @@ -17,9 +17,10 @@ AC_PROG_LIBTOOL PKG_CHECK_MODULES(GEPUB, + webkit2gtk-4.0 + libsoup-2.4 glib-2.0 gobject-2.0 - gtk+-3.0 gio-2.0 libxml-2.0 libarchive) @@ -27,6 +28,19 @@ AC_SUBST(GEPUB_CFLAGS) AC_SUBST(GEPUB_LIBS) +PKG_CHECK_MODULES(GEPUB_TESTS, + webkit2gtk-4.0 + libsoup-2.4 + glib-2.0 + gobject-2.0 + gtk+-3.0 + gio-2.0 + libxml-2.0 + libarchive) + +AC_SUBST(GEPUB_TESTS_CFLAGS) +AC_SUBST(GEPUB_TESTS_LIBS) + AC_CONFIG_HEADERS([config.h]) AC_CONFIG_FILES([ Makefile diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgepub-0.3/libgepub/Makefile.am new/libgepub-0.4/libgepub/Makefile.am --- old/libgepub-0.3/libgepub/Makefile.am 2016-05-23 09:29:03.000000000 +0200 +++ new/libgepub-0.4/libgepub/Makefile.am 2016-08-31 09:39:20.000000000 +0200 @@ -4,6 +4,7 @@ gepub-utils.h INST_H_FILES = \ + gepub-widget.h \ gepub-archive.h \ gepub-text-chunk.h \ gepub-doc.h \ @@ -13,6 +14,7 @@ libgepubinclude_HEADERS = $(INST_H_FILES) libgepub_la_SOURCES = \ + gepub-widget.c \ gepub-archive.c \ gepub-text-chunk.c \ gepub-doc.c \ @@ -47,12 +49,13 @@ if HAVE_INTROSPECTION introspection_sources = $(libgepub_la_SOURCES) -Gepub-0.3.gir: libgepub.la -Gepub_0_3_gir_INCLUDES = GObject-2.0 libxml2-2.0 -Gepub_0_3_gir_CFLAGS = $(INCLUDES) -Gepub_0_3_gir_LIBS = libgepub.la -Gepub_0_3_gir_FILES = $(introspection_sources) -INTROSPECTION_GIRS += Gepub-0.3.gir +Gepub-0.4.gir: libgepub.la +Gepub_0_4_gir_INCLUDES = GObject-2.0 libxml2-2.0 WebKit2-4.0 +Gepub_0_4_gir_CFLAGS = $(INCLUDES) +Gepub_0_4_gir_LIBS = libgepub.la +Gepub_0_4_gir_FILES = $(introspection_sources) +Gepub_0_4_gir_SCANNERFLAGS = --warn-all +INTROSPECTION_GIRS += Gepub-0.4.gir girdir = $(datadir)/gir-1.0 gir_DATA = $(INTROSPECTION_GIRS) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgepub-0.3/libgepub/gepub-archive.c new/libgepub-0.4/libgepub/gepub-archive.c --- old/libgepub-0.3/libgepub/gepub-archive.c 2016-05-23 09:29:03.000000000 +0200 +++ new/libgepub-0.4/libgepub/gepub-archive.c 2016-08-31 09:39:20.000000000 +0200 @@ -20,6 +20,8 @@ #include <config.h> #include <libxml/parser.h> #include <libxml/tree.h> +#include <archive.h> +#include <archive_entry.h> #include "gepub-archive.h" #include "gepub-utils.h" @@ -103,6 +105,12 @@ return archive; } +/** + * gepub_archive_list_files: + * @archive: a #GepubArchive + * + * Returns: (element-type utf8) (transfer full): list of files in the archive + */ GList * gepub_archive_list_files (GepubArchive *archive) { @@ -120,17 +128,16 @@ return file_list; } -gboolean +GBytes * gepub_archive_read_entry (GepubArchive *archive, - const gchar *path, - guchar **buffer, - gsize *bufsize) + const gchar *path) { struct archive_entry *entry; + guchar *buffer; gint size; if (!gepub_archive_open (archive)) - return FALSE; + return NULL; while (archive_read_next_header (archive->archive, &entry) == ARCHIVE_OK) { if (g_ascii_strcasecmp (path, archive_entry_pathname (entry)) == 0) @@ -138,14 +145,12 @@ archive_read_data_skip (archive->archive); } - *bufsize = archive_entry_size (entry) + 1; - size = (*bufsize) - 1; - *buffer = g_malloc (*bufsize); - archive_read_data (archive->archive, *buffer, size); - (*buffer)[size] = '\0'; + size = archive_entry_size (entry); + buffer = g_malloc0 (size); + archive_read_data (archive->archive, buffer, size); gepub_archive_close (archive); - return TRUE; + return g_bytes_new_take (buffer, size); } gchar * @@ -154,21 +159,24 @@ xmlDoc *doc = NULL; xmlNode *root_element = NULL; xmlNode *root_node = NULL; - guchar *buffer; + GBytes *bytes; + const guchar *buffer; gsize bufsize; gchar *root_file = NULL; // root file is in META-INF/container.xml - if (!gepub_archive_read_entry (archive, "META-INF/container.xml", &buffer, &bufsize)) + bytes = gepub_archive_read_entry (archive, "META-INF/container.xml"); + if (!bytes) return NULL; - doc = xmlRecoverDoc (buffer); + buffer = g_bytes_get_data (bytes, &bufsize); + doc = xmlRecoverMemory (buffer, bufsize); root_element = xmlDocGetRootElement (doc); root_node = gepub_utils_get_element_by_tag (root_element, "rootfile"); root_file = xmlGetProp (root_node, "full-path"); xmlFreeDoc (doc); - g_free (buffer); + g_bytes_unref (bytes); return root_file; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgepub-0.3/libgepub/gepub-archive.h new/libgepub-0.4/libgepub/gepub-archive.h --- old/libgepub-0.3/libgepub/gepub-archive.h 2016-05-23 09:29:03.000000000 +0200 +++ new/libgepub-0.4/libgepub/gepub-archive.h 2016-08-31 09:39:20.000000000 +0200 @@ -23,8 +23,6 @@ #include <glib-object.h> #include <gio/gio.h> #include <glib.h> -#include <archive.h> -#include <archive_entry.h> G_BEGIN_DECLS @@ -42,10 +40,8 @@ GepubArchive *gepub_archive_new (const gchar *path); GList *gepub_archive_list_files (GepubArchive *archive); -gboolean gepub_archive_read_entry (GepubArchive *archive, - const gchar *path, - guchar **buffer, - gsize *bufsize); +GBytes *gepub_archive_read_entry (GepubArchive *archive, + const gchar *path); gchar *gepub_archive_get_root_file (GepubArchive *archive); G_END_DECLS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgepub-0.3/libgepub/gepub-doc.c new/libgepub-0.4/libgepub/gepub-doc.c --- old/libgepub-0.3/libgepub/gepub-doc.c 2016-05-23 09:29:03.000000000 +0200 +++ new/libgepub-0.4/libgepub/gepub-doc.c 2016-08-31 09:39:20.000000000 +0200 @@ -35,11 +35,13 @@ GObject parent; GepubArchive *archive; - guchar *content; + GBytes *content; gchar *content_base; gchar *path; GHashTable *resources; + GList *spine; + GList *page; }; struct _GepubDocClass { @@ -49,6 +51,7 @@ enum { PROP_0, PROP_PATH, + PROP_PAGE, NUM_PROPS }; @@ -71,8 +74,7 @@ GepubDoc *doc = GEPUB_DOC (object); g_clear_object (&doc->archive); - g_clear_pointer (&doc->content, g_free); - g_clear_pointer (&doc->content_base, g_free); + g_clear_pointer (&doc->content, g_bytes_unref); g_clear_pointer (&doc->path, g_free); g_clear_pointer (&doc->resources, g_hash_table_destroy); @@ -96,6 +98,9 @@ case PROP_PATH: doc->path = g_value_dup_string (value); break; + case PROP_PAGE: + gepub_doc_set_page (doc, g_value_get_int (value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -114,6 +119,9 @@ case PROP_PATH: g_value_set_string (value, doc->path); break; + case PROP_PAGE: + g_value_set_int (value, gepub_doc_get_page (doc)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -149,6 +157,13 @@ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + properties[PROP_PAGE] = + g_param_spec_int ("page", + "Current page", + "The current page index", + -1, G_MAXINT, 0, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS); g_object_class_install_properties (object_class, NUM_PROPS, properties); } @@ -169,12 +184,19 @@ file = gepub_archive_get_root_file (doc->archive); if (!file) return FALSE; - if (!gepub_archive_read_entry (doc->archive, file, &(doc->content), &bufsize)) + doc->content = gepub_archive_read_entry (doc->archive, file); + if (!doc->content) return FALSE; len = strlen (file); - while (file[i++] != '/' && i < len); - doc->content_base = g_strndup (file, i); + doc->content_base = g_strdup (""); + for (i=0; i<len; i++) { + if (file[i] == '/') { + g_free (doc->content_base); + doc->content_base = g_strndup (file, i+1); + break; + } + } gepub_doc_fill_resources (doc); gepub_doc_fill_spine (doc); @@ -193,7 +215,6 @@ /** * gepub_doc_new: * @path: the epub doc path - * @error: location to store a #GError, or %NULL * * Returns: (transfer full): the new GepubDoc created */ @@ -215,8 +236,11 @@ xmlNode *item = NULL; gchar *id, *tmpuri, *uri; GepubResource *res; + const char *data; + gsize size; - xdoc = xmlRecoverDoc (doc->content); + data = g_bytes_get_data (doc->content, &size); + xdoc = xmlRecoverMemory (data, size); root_element = xmlDocGetRootElement (xdoc); mnode = gepub_utils_get_element_by_tag (root_element, "manifest"); @@ -250,8 +274,12 @@ xmlNode *snode = NULL; xmlNode *item = NULL; gchar *id; + const char *data; + gsize size; + GList *spine = NULL; - xdoc = xmlRecoverDoc (doc->content); + data = g_bytes_get_data (doc->content, &size); + xdoc = xmlRecoverMemory (data, size); root_element = xmlDocGetRootElement (xdoc); snode = gepub_utils_get_element_by_tag (root_element, "spine"); @@ -264,10 +292,13 @@ id = xmlGetProp (item, "idref"); - doc->spine = g_list_append (doc->spine, id); + spine = g_list_prepend (spine, id); item = item->next; } + doc->spine = g_list_reverse (spine); + doc->page = doc->spine; + xmlFreeDoc (xdoc); } @@ -277,7 +308,7 @@ * * Returns: (transfer none): the document content */ -gchar * +GBytes * gepub_doc_get_content (GepubDoc *doc) { return doc->content; @@ -291,7 +322,7 @@ * Returns: (transfer full): metadata string */ gchar * -gepub_doc_get_metadata (GepubDoc *doc, gchar *mdata) +gepub_doc_get_metadata (GepubDoc *doc, const gchar *mdata) { xmlDoc *xdoc = NULL; xmlNode *root_element = NULL; @@ -299,8 +330,11 @@ xmlNode *mdata_node = NULL; gchar *ret; xmlChar *text; + const char *data; + gsize size; - xdoc = xmlRecoverDoc (doc->content); + data = g_bytes_get_data (doc->content, &size); + xdoc = xmlRecoverMemory (data, size); root_element = xmlDocGetRootElement (xdoc); mnode = gepub_utils_get_element_by_tag (root_element, "metadata"); mdata_node = gepub_utils_get_element_by_tag (mnode, mdata); @@ -327,50 +361,35 @@ } /** - * gepub_doc_get_resource: + * gepub_doc_get_resource_by_id: * @doc: a #GepubDoc * @id: the resource id - * @bufsize: (out): location to store the length in bytes of the contents * - * Returns: (array length=bufsize) (transfer full): the resource content + * Returns: (transfer full): the resource content */ -guchar * -gepub_doc_get_resource (GepubDoc *doc, gchar *id, gsize *bufsize) +GBytes * +gepub_doc_get_resource_by_id (GepubDoc *doc, const gchar *id) { - guchar *res = NULL; GepubResource *gres = g_hash_table_lookup (doc->resources, id); if (!gres) { // not found return NULL; } - if (!gepub_archive_read_entry (doc->archive, gres->uri, &res, bufsize)) - return NULL; - return res; + return gepub_archive_read_entry (doc->archive, gres->uri); } /** - * gepub_doc_get_resource_v: + * gepub_doc_get_resource: * @doc: a #GepubDoc - * @v: the resource path - * @bufsize: (out): location to store length in bytes of the contents + * @path: the resource path * - * Returns: (array length=bufsize) (transfer full): the resource content + * Returns: (transfer full): the resource content */ -guchar * -gepub_doc_get_resource_v (GepubDoc *doc, gchar *v, gsize *bufsize) +GBytes * +gepub_doc_get_resource (GepubDoc *doc, const gchar *path) { - guchar *res = NULL; - gchar *path = NULL; - - path = g_strdup_printf ("%s%s", doc->content_base, v); - if (!gepub_archive_read_entry (doc->archive, path, &res, bufsize)) { - g_free (path); - return NULL; - } - g_free (path); - - return res; + return gepub_archive_read_entry (doc->archive, path); } /** @@ -381,7 +400,7 @@ * Returns: (transfer full): the resource content */ gchar * -gepub_doc_get_resource_mime_by_id (GepubDoc *doc, gchar *id) +gepub_doc_get_resource_mime_by_id (GepubDoc *doc, const gchar *id) { GepubResource *gres; @@ -399,19 +418,16 @@ /** * gepub_doc_get_resource_mime: * @doc: a #GepubDoc - * @v: the resource path + * @path: the resource path * * Returns: (transfer full): the resource mime */ gchar * -gepub_doc_get_resource_mime (GepubDoc *doc, gchar *v) +gepub_doc_get_resource_mime (GepubDoc *doc, const gchar *path) { - gchar *path = NULL; GepubResource *gres; GList *keys = g_hash_table_get_keys (doc->resources); - path = g_strdup_printf ("%s%s", doc->content_base, v); - while (keys) { gres = ((GepubResource*)g_hash_table_lookup (doc->resources, keys->data)); if (!strcmp (gres->uri, path)) @@ -419,8 +435,6 @@ keys = keys->next; } - g_free(path); - if (keys) return g_strdup (gres->mime); else @@ -428,55 +442,80 @@ } /** - * gepub_doc_get_spine: + * gepub_doc_get_current_mime: * @doc: a #GepubDoc * - * Returns: (element-type utf8) (transfer none): the document spine + * Returns: (transfer full): the current resource mime */ -GList * -gepub_doc_get_spine (GepubDoc *doc) +gchar * +gepub_doc_get_current_mime (GepubDoc *doc) { - return doc->spine; + return gepub_doc_get_resource_mime_by_id (doc, doc->page->data); } /** * gepub_doc_get_current: * @doc: a #GepubDoc - * @bufsize: (out): location to store the length in bytes of the contents * - * Returns: (array length=bufsize) (transfer full): the current chapter data + * Returns: (transfer full): the current chapter data */ -guchar * -gepub_doc_get_current (GepubDoc *doc, gsize *bufsize) +GBytes * +gepub_doc_get_current (GepubDoc *doc) { - return gepub_doc_get_resource (doc, doc->spine->data, bufsize); + return gepub_doc_get_resource_by_id (doc, doc->page->data); +} + +/** + * gepub_doc_get_current_with_epub_uris: + * @doc: a #GepubDoc + * + * Returns: (transfer full): the current chapter + * data, with resource uris renamed so they have the epub:// prefix and all + * are relative to the root file + */ +GBytes * +gepub_doc_get_current_with_epub_uris (GepubDoc *doc) +{ + GBytes *content = gepub_doc_get_current (doc); + gchar *path = gepub_doc_get_current_path (doc); + // getting the basepath of the current xhtml loaded + gchar *base = g_path_get_dirname (path); + + GBytes *replaced = gepub_utils_replace_resources (content, base); + + g_free (path); + g_bytes_unref (content); + + return replaced; } /** * gepub_doc_get_text: * @doc: a #GepubDoc * - * Returns: (element-type Gepub.TextChunk) (transfer full): the list of text in the current chapter, Free with gepub_doc_free_text(). + * Returns: (element-type Gepub.TextChunk) (transfer full): the list of text in the current chapter. */ GList * gepub_doc_get_text (GepubDoc *doc) { xmlDoc *xdoc = NULL; xmlNode *root_element = NULL; - guchar *res = NULL; - gsize size = 0; + GBytes *current; + const guchar *data; + gsize size; GList *texts = NULL; - res = gepub_doc_get_current (doc, &size); - if (!res) { + current = gepub_doc_get_current (doc); + if (!current) { return NULL; } - xdoc = htmlReadDoc (res, "", NULL, HTML_PARSE_NOWARNING | HTML_PARSE_NOERROR); + data = g_bytes_get_data (current, &size); + xdoc = htmlReadMemory (data, size, "", NULL, HTML_PARSE_NOWARNING | HTML_PARSE_NOERROR); root_element = xmlDocGetRootElement (xdoc); texts = gepub_utils_get_text_elements (root_element); - g_free (res); + g_bytes_unref (current); xmlFreeDoc (xdoc); return texts; @@ -487,63 +526,114 @@ * @doc: a #GepubDoc * @id: the resource id * - * Returns: (element-type Gepub.TextChunk) (transfer full): the list of text in the current chapter, Free with gepub_doc_free_text(). + * Returns: (element-type Gepub.TextChunk) (transfer full): the list of text in the current chapter. */ GList * -gepub_doc_get_text_by_id (GepubDoc *doc, gchar *id) +gepub_doc_get_text_by_id (GepubDoc *doc, const gchar *id) { xmlDoc *xdoc = NULL; xmlNode *root_element = NULL; - gsize size = 0; - guchar *res = NULL; + gsize size; + const guchar *res; + GBytes *contents; GList *texts = NULL; - res = gepub_doc_get_resource (doc, id, &size); + contents = gepub_doc_get_resource_by_id (doc, id); if (!res) { return NULL; } - xdoc = htmlReadDoc (res, "", NULL, HTML_PARSE_NOWARNING | HTML_PARSE_NOERROR); + res = g_bytes_get_data (contents, &size); + xdoc = htmlReadMemory (res, size, "", NULL, HTML_PARSE_NOWARNING | HTML_PARSE_NOERROR); root_element = xmlDocGetRootElement (xdoc); texts = gepub_utils_get_text_elements (root_element); - g_free (res); + g_bytes_unref (contents); xmlFreeDoc (xdoc); return texts; } +static gboolean +gepub_doc_set_page_internal (GepubDoc *doc, + GList *page) +{ + if (!page || doc->page == page) + return FALSE; + + doc->page = page; + g_object_notify_by_pspec (G_OBJECT (doc), properties[PROP_PAGE]); + + return TRUE; +} + /** - * gepub_doc_free_text: - * @doc: a #GList + * gepub_doc_go_next: + * @doc: a #GepubDoc + * + * Returns: TRUE on success, FALSE if there's no next pages */ -void -gepub_doc_free_text (GList *tlist) +gboolean +gepub_doc_go_next (GepubDoc *doc) { - g_list_free_full (tlist, (GDestroyNotify)g_object_unref); + return gepub_doc_set_page_internal (doc, doc->page->next); } /** - * gepub_doc_go_next: + * gepub_doc_go_prev: * @doc: a #GepubDoc + * + * Returns: TRUE on success, FALSE if there's no prev pages */ -void gepub_doc_go_next (GepubDoc *doc) +gboolean +gepub_doc_go_prev (GepubDoc *doc) { - if (doc->spine->next) - doc->spine = doc->spine->next; + return gepub_doc_set_page_internal (doc, doc->page->prev); } /** - * gepub_doc_go_next: + * gepub_doc_get_n_pages: * @doc: a #GepubDoc + * + * Returns: the number of pages in the document */ -void gepub_doc_go_prev (GepubDoc *doc) +int +gepub_doc_get_n_pages (GepubDoc *doc) { - if (doc->spine->prev) - doc->spine = doc->spine->prev; + return g_list_length (doc->spine); } +/** + * gepub_doc_get_page: + * @doc: a #GepubDoc + * + * Returns: the current page index, starting from 0 + */ +int +gepub_doc_get_page (GepubDoc *doc) +{ + return g_list_position (doc->spine, doc->page); +} + +/** + * gepub_doc_set_page: + * @doc: a #GepubDoc + * @index: the index of the new page + * + * Sets the document current page to @index. + */ +void +gepub_doc_set_page (GepubDoc *doc, + gint index) +{ + GList *page; + + g_return_if_fail (index >= 0 && index <= gepub_doc_get_n_pages (doc)); + + page = g_list_nth (doc->spine, index); + gepub_doc_set_page_internal (doc, page); +} /** * gepub_doc_get_cover: @@ -560,8 +650,11 @@ xmlNode *mnode = NULL; gchar *ret; xmlChar *text; + const char *data; + gsize size; - xdoc = xmlRecoverDoc (doc->content); + data = g_bytes_get_data (doc->content, &size); + xdoc = xmlRecoverMemory (data, size); root_element = xmlDocGetRootElement (xdoc); mnode = gepub_utils_get_element_by_attr (root_element, "name", "cover"); text = xmlGetProp(mnode, "content"); @@ -581,7 +674,8 @@ * * Returns: (transfer full): the resource path */ -gchar *gepub_doc_get_resource_path (GepubDoc *doc, gchar *id) +gchar * +gepub_doc_get_resource_path (GepubDoc *doc, const gchar *id) { GepubResource *gres = g_hash_table_lookup (doc->resources, id); if (!gres) { @@ -589,5 +683,30 @@ return NULL; } - return gres->uri; + return g_strdup (gres->uri); +} + +/** + * gepub_doc_get_current_path: + * @doc: a #GepubDoc + * + * Returns: (transfer full): the current resource path + */ +gchar * +gepub_doc_get_current_path (GepubDoc *doc) +{ + return gepub_doc_get_resource_path (doc, doc->page->data); +} + +/** + * gepub_doc_get_current_id: + * @doc: a #GepubDoc + * + + * Returns: (transfer none): the current resource id + */ +const gchar * +gepub_doc_get_current_id (GepubDoc *doc) +{ + return doc->page->data; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgepub-0.3/libgepub/gepub-doc.h new/libgepub-0.4/libgepub/gepub-doc.h --- old/libgepub-0.3/libgepub/gepub-doc.h 2016-05-23 09:29:03.000000000 +0200 +++ new/libgepub-0.4/libgepub/gepub-doc.h 2016-08-31 09:39:20.000000000 +0200 @@ -42,65 +42,62 @@ typedef struct _GepubResource GepubResource; -GType gepub_doc_get_type (void) G_GNUC_CONST; +GType gepub_doc_get_type (void) G_GNUC_CONST; -GepubDoc *gepub_doc_new (const gchar *path); -gchar *gepub_doc_get_content (GepubDoc *doc); -gchar *gepub_doc_get_metadata (GepubDoc *doc, gchar *mdata); -guchar *gepub_doc_get_resource (GepubDoc *doc, gchar *id, gsize *bufsize); -guchar *gepub_doc_get_resource_v (GepubDoc *doc, gchar *v, gsize *bufsize); -GHashTable *gepub_doc_get_resources (GepubDoc *doc); -gchar *gepub_doc_get_resource_mime (GepubDoc *doc, gchar *v); -gchar *gepub_doc_get_resource_mime_by_id (GepubDoc *doc, gchar *id); -GList *gepub_doc_get_spine (GepubDoc *doc); -GList *gepub_doc_get_text (GepubDoc *doc); -GList *gepub_doc_get_text_by_id (GepubDoc *doc, gchar *id); -void gepub_doc_free_text (GList *tlist); -guchar *gepub_doc_get_current (GepubDoc *doc, gsize *bufsize); -void gepub_doc_go_next (GepubDoc *doc); -void gepub_doc_go_prev (GepubDoc *doc); -gchar *gepub_doc_get_cover (GepubDoc *doc); -gchar *gepub_doc_get_resource_path (GepubDoc *doc, gchar *id); +GepubDoc *gepub_doc_new (const gchar *path); +GBytes *gepub_doc_get_content (GepubDoc *doc); +gchar *gepub_doc_get_metadata (GepubDoc *doc, const gchar *mdata); +GBytes *gepub_doc_get_resource (GepubDoc *doc, const gchar *path); +GBytes *gepub_doc_get_resource_by_id (GepubDoc *doc, const gchar *id); +GHashTable *gepub_doc_get_resources (GepubDoc *doc); +gchar *gepub_doc_get_resource_mime (GepubDoc *doc, const gchar *path); +gchar *gepub_doc_get_resource_mime_by_id (GepubDoc *doc, const gchar *id); +gchar *gepub_doc_get_current_mime (GepubDoc *doc); +GList *gepub_doc_get_text (GepubDoc *doc); +GList *gepub_doc_get_text_by_id (GepubDoc *doc, const gchar *id); +GBytes *gepub_doc_get_current (GepubDoc *doc); +GBytes *gepub_doc_get_current_with_epub_uris (GepubDoc *doc); +gchar *gepub_doc_get_cover (GepubDoc *doc); +gchar *gepub_doc_get_resource_path (GepubDoc *doc, const gchar *id); +gchar *gepub_doc_get_current_path (GepubDoc *doc); +const gchar *gepub_doc_get_current_id (GepubDoc *doc); + +gboolean gepub_doc_go_next (GepubDoc *doc); +gboolean gepub_doc_go_prev (GepubDoc *doc); +gint gepub_doc_get_n_pages (GepubDoc *doc); +gint gepub_doc_get_page (GepubDoc *doc); +void gepub_doc_set_page (GepubDoc *doc, + gint index); G_END_DECLS /** * GEPUB_META_TITLE: * The book title. - * - * Value: title */ #define GEPUB_META_TITLE "title" /** * GEPUB_META_LANG: * The book lang. - * - * Value: language */ #define GEPUB_META_LANG "language" /** * GEPUB_META_ID: * The book id. - * - * Value: identifier */ #define GEPUB_META_ID "identifier" /** * GEPUB_META_AUTHOR: * The book author. - * - * Value: creator */ #define GEPUB_META_AUTHOR "creator" /** * GEPUB_META_DESC: * The book description. - * - * Value: description */ #define GEPUB_META_DESC "description" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgepub-0.3/libgepub/gepub-text-chunk.h new/libgepub-0.4/libgepub/gepub-text-chunk.h --- old/libgepub-0.3/libgepub/gepub-text-chunk.h 2016-05-23 09:29:03.000000000 +0200 +++ new/libgepub-0.4/libgepub/gepub-text-chunk.h 2016-08-31 09:39:20.000000000 +0200 @@ -54,7 +54,7 @@ typedef struct _GepubTextChunkClass GepubTextChunkClass; GType gepub_text_chunk_get_type (void) G_GNUC_CONST; -GepubTextChunk *gepub_text_chunk_new (GepubTextChunkType type, const guchar *path); +GepubTextChunk *gepub_text_chunk_new (GepubTextChunkType type, const guchar *text); gchar *gepub_text_chunk_type_str (GepubTextChunk *chunk); gchar *gepub_text_chunk_text (GepubTextChunk *chunk); GepubTextChunkType gepub_text_chunk_type (GepubTextChunk *chunk); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgepub-0.3/libgepub/gepub-utils.c new/libgepub-0.4/libgepub/gepub-utils.c --- old/libgepub-0.3/libgepub/gepub-utils.c 2016-05-23 09:29:03.000000000 +0200 +++ new/libgepub-0.4/libgepub/gepub-utils.c 2016-08-31 09:39:20.000000000 +0200 @@ -16,13 +16,57 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include <libsoup/soup.h> + #include <libxml/tree.h> +#include <libxml/parser.h> #include <stdarg.h> #include <string.h> #include "gepub-utils.h" #include "gepub-text-chunk.h" + +/* Replaces the attr value with epub:// prefix for the tagname. This + * function also makes the resource absolute based on the epub root + */ +static void +set_epub_uri (xmlNode *node, const gchar *path, const gchar *tagname, const gchar *attr) +{ + xmlNode *cur_node = NULL; + xmlChar *text = NULL; + + SoupURI *baseURI; + gchar *basepath = g_strdup_printf ("epub://%s/", path); + + baseURI = soup_uri_new (basepath); + g_free (basepath); + + for (cur_node = node; cur_node; cur_node = cur_node->next) { + if (cur_node->type == XML_ELEMENT_NODE ) { + text = xmlGetProp (cur_node, attr); + if (!strcmp (cur_node->name, tagname) && text) { + SoupURI *uri = soup_uri_new_with_base (baseURI, text); + gchar *value = soup_uri_to_string (uri, FALSE); + + xmlSetProp (cur_node, attr, value); + + soup_uri_free (uri); + g_free (value); + } + if (text) { + xmlFree (text); + text = NULL; + } + } + + if (cur_node->children) + set_epub_uri (cur_node->children, path, tagname, attr); + } + + soup_uri_free (baseURI); +} + gboolean gepub_utils_has_parent_tag (xmlNode *node, gchar *name, ...) { @@ -56,8 +100,15 @@ return FALSE; } +/** + * gepub_utils_get_element_by_tag: (skip): + * @node: an #xmlNode + * @name: the tag name + * + * Returns: the tag matching @name. + */ xmlNode * -gepub_utils_get_element_by_tag (xmlNode *node, gchar *name) +gepub_utils_get_element_by_tag (xmlNode *node, const gchar *name) { xmlNode *cur_node = NULL; xmlNode *ret = NULL; @@ -75,8 +126,16 @@ return ret; } +/** + * gepub_utils_get_element_by_attr: (skip): + * @node: an #xmlNode + * @attr: the attribute + * @value: the value + * + * Returns: the element matching @attr and @value. + */ xmlNode * -gepub_utils_get_element_by_attr (xmlNode *node, gchar *attr, gchar *value) +gepub_utils_get_element_by_attr (xmlNode *node, const gchar *attr, const gchar *value) { xmlNode *cur_node = NULL; xmlNode *ret = NULL; @@ -103,6 +162,13 @@ return ret; } +/** + * gepub_utils_get_text_elements: + * @node: an #xmlNode + * + * Returns: (element-type Gepub.TextChunk) (transfer full): the text elements + * of @node. + */ GList * gepub_utils_get_text_elements (xmlNode *node) { @@ -150,3 +216,34 @@ return text_list; } + +/* Replacing epub media paths, for css, image and svg files, to be + * able to provide these files to webkit from the epub file + */ +GBytes * +gepub_utils_replace_resources (GBytes *content, const gchar *path) +{ + xmlDoc *doc = NULL; + xmlNode *root_element = NULL; + guchar *buffer; + const guchar *data; + gsize bufsize; + + data = g_bytes_get_data (content, &bufsize); + doc = xmlReadMemory (data, bufsize, "", NULL, XML_PARSE_NOWARNING | XML_PARSE_NOERROR); + root_element = xmlDocGetRootElement (doc); + + // replacing css resources + set_epub_uri (root_element, path, "link", "href"); + // replacing images resources + set_epub_uri (root_element, path, "img", "src"); + // replacing svg images resources + set_epub_uri (root_element, path, "image", "xlink:href"); + // replacing crosslinks + set_epub_uri (root_element, path, "a", "href"); + + xmlDocDumpFormatMemory (doc, (xmlChar**)&buffer, (int*)&bufsize, 1); + xmlFreeDoc (doc); + + return g_bytes_new_take (buffer, bufsize); +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgepub-0.3/libgepub/gepub-utils.h new/libgepub-0.4/libgepub/gepub-utils.h --- old/libgepub-0.3/libgepub/gepub-utils.h 2016-05-23 09:29:03.000000000 +0200 +++ new/libgepub-0.4/libgepub/gepub-utils.h 2016-08-31 09:39:20.000000000 +0200 @@ -22,8 +22,9 @@ #include <glib.h> #include <libxml/tree.h> -xmlNode * gepub_utils_get_element_by_tag (xmlNode *node, gchar *name); -xmlNode * gepub_utils_get_element_by_attr (xmlNode *node, gchar *attr, gchar *value); -GList * gepub_utils_get_text_elements (xmlNode *node); +xmlNode * gepub_utils_get_element_by_tag (xmlNode *node, const gchar *name); +xmlNode * gepub_utils_get_element_by_attr (xmlNode *node, const gchar *attr, const gchar *value); +GList * gepub_utils_get_text_elements (xmlNode *node); +GBytes * gepub_utils_replace_resources (GBytes *content, const gchar *path); #endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgepub-0.3/libgepub/gepub-widget.c new/libgepub-0.4/libgepub/gepub-widget.c --- old/libgepub-0.3/libgepub/gepub-widget.c 1970-01-01 01:00:00.000000000 +0100 +++ new/libgepub-0.4/libgepub/gepub-widget.c 2016-08-31 09:39:20.000000000 +0200 @@ -0,0 +1,230 @@ +/* GepubWidget + * + * Copyright (C) 2016 Daniel Garcia <dan...@wadobo.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <config.h> +#include <gtk/gtk.h> + +#include "gepub-widget.h" + +struct _GepubWidget { + WebKitWebView parent; + + GepubDoc *doc; +}; + +struct _GepubWidgetClass { + WebKitWebViewClass parent_class; +}; + +enum { + PROP_0, + PROP_DOC, + NUM_PROPS +}; + +static GParamSpec *properties[NUM_PROPS] = { NULL, }; + +G_DEFINE_TYPE (GepubWidget, gepub_widget, WEBKIT_TYPE_WEB_VIEW) + +static void +resource_callback (WebKitURISchemeRequest *request, gpointer user_data) +{ + GInputStream *stream; + gchar *path; + gchar *uri; + gchar *mime; + GepubWidget *widget = user_data; + GBytes *contents; + + if (!widget->doc) + return; + + uri = g_strdup (webkit_uri_scheme_request_get_uri (request)); + // removing "epub://" + path = uri + 7; + contents = gepub_doc_get_resource (widget->doc, path); + mime = gepub_doc_get_resource_mime (widget->doc, path); + + if (!mime) { + g_free (uri); + return; + } + + stream = g_memory_input_stream_new_from_bytes (contents); + webkit_uri_scheme_request_finish (request, stream, g_bytes_get_size (contents), mime); + + g_object_unref (stream); + g_bytes_unref (contents); + g_free (mime); + g_free (uri); +} + +static void +gepub_widget_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GepubWidget *widget = GEPUB_WIDGET (object); + + switch (prop_id) { + case PROP_DOC: + gepub_widget_set_doc (widget, g_value_get_object (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gepub_widget_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GepubWidget *widget = GEPUB_WIDGET (object); + + switch (prop_id) { + case PROP_DOC: + g_value_set_object (value, gepub_widget_get_doc (widget)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gepub_widget_finalize (GObject *object) +{ + GepubWidget *widget = GEPUB_WIDGET (object); + + g_clear_object (&widget->doc); + + G_OBJECT_CLASS (gepub_widget_parent_class)->finalize (object); +} + +static void +gepub_widget_init (GepubWidget *widget) +{ +} + +static void +gepub_widget_constructed (GObject *object) +{ + WebKitWebContext *ctx; + GepubWidget *widget = GEPUB_WIDGET (object); + + G_OBJECT_CLASS (gepub_widget_parent_class)->constructed (object); + + ctx = webkit_web_view_get_context (WEBKIT_WEB_VIEW (widget)); + webkit_web_context_register_uri_scheme (ctx, "epub", resource_callback, widget, NULL); +} + +static void +gepub_widget_class_init (GepubWidgetClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->constructed = gepub_widget_constructed; + object_class->finalize = gepub_widget_finalize; + object_class->set_property = gepub_widget_set_property; + object_class->get_property = gepub_widget_get_property; + + properties[PROP_DOC] = + g_param_spec_object ("doc", + "The GepubDoc", + "The GepubDoc for this widget", + GEPUB_TYPE_DOC, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, NUM_PROPS, properties); +} + +/** + * gepub_widget_new: + * + * Returns: (transfer full): the new GepubWidget created + */ +GtkWidget * +gepub_widget_new (void) +{ + return g_object_new (GEPUB_TYPE_WIDGET, + NULL); +} + +/** + * gepub_widget_get_doc: + * @widget: a #GepubWidget + * + * Returns: (transfer none): the #GepubDoc + */ +GepubDoc * +gepub_widget_get_doc (GepubWidget *widget) +{ + return widget->doc; +} + +static void +reload_current_chapter (GepubWidget *widget) +{ + GBytes *current; + + current = gepub_doc_get_current_with_epub_uris (widget->doc); + webkit_web_view_load_bytes (WEBKIT_WEB_VIEW (widget), + current, + gepub_doc_get_current_mime (widget->doc), + "UTF-8", NULL); + + g_bytes_unref (current); +} + +/** + * gepub_widget_set_doc: + * @widget: a #GepubWidget + * @doc: (nullable): a #GepubDoc + * + * Sets @doc as the document displayed by the widget. + */ +void +gepub_widget_set_doc (GepubWidget *widget, + GepubDoc *doc) +{ + if (widget->doc == doc) + return; + + if (widget->doc != NULL) { + g_signal_handlers_disconnect_by_func (widget->doc, + reload_current_chapter, widget); + g_object_unref (widget->doc); + } + + widget->doc = doc; + + if (widget->doc != NULL) { + g_object_ref (widget->doc); + reload_current_chapter (widget); + g_signal_connect_swapped (widget->doc, "notify::page", + G_CALLBACK (reload_current_chapter), widget); + } + + g_object_notify_by_pspec (G_OBJECT (widget), properties[PROP_DOC]); +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgepub-0.3/libgepub/gepub-widget.h new/libgepub-0.4/libgepub/gepub-widget.h --- old/libgepub-0.3/libgepub/gepub-widget.h 1970-01-01 01:00:00.000000000 +0100 +++ new/libgepub-0.4/libgepub/gepub-widget.h 2016-08-31 09:39:20.000000000 +0200 @@ -0,0 +1,52 @@ +/* GepubWidget + * + * Copyright (C) 2016 Daniel Garcia <dan...@wadobo.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __GEPUB_WIDGET_H__ +#define __GEPUB_WIDGET_H__ + +#include <webkit2/webkit2.h> +#include <glib-object.h> +#include <glib.h> + +#include "gepub-doc.h" + +G_BEGIN_DECLS + +#define GEPUB_TYPE_WIDGET (gepub_widget_get_type ()) +#define GEPUB_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, GEPUB_TYPE_WIDGET, GepubWidget)) +#define GEPUB_WIDGET_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST (cls, GEPUB_TYPE_WIDGET, GepubWidgetClass)) +#define GEPUB_IS_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GEPUB_TYPE_WIDGET)) +#define GEPUB_IS_WIDGET_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE (obj, GEPUB_TYPE_WIDGET)) +#define GEPUB_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEPUB_TYPE_WIDGET, GepubWidgetClass)) + +typedef struct _GepubWidget GepubWidget; +typedef struct _GepubWidgetClass GepubWidgetClass; + +GType gepub_widget_get_type (void) G_GNUC_CONST; + +GtkWidget *gepub_widget_new (void); + +GepubDoc *gepub_widget_get_doc (GepubWidget *widget); +void gepub_widget_set_doc (GepubWidget *widget, + GepubDoc *doc); + +G_END_DECLS + +#endif /* __GEPUB_WIDGET_H__ */ + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgepub-0.3/libgepub/gepub.h new/libgepub-0.4/libgepub/gepub.h --- old/libgepub-0.3/libgepub/gepub.h 2016-05-23 09:29:03.000000000 +0200 +++ new/libgepub-0.4/libgepub/gepub.h 2016-08-31 09:39:20.000000000 +0200 @@ -4,5 +4,6 @@ #include "gepub-archive.h" #include "gepub-text-chunk.h" #include "gepub-doc.h" +#include "gepub-widget.h" #endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgepub-0.3/libgepub.doap new/libgepub-0.4/libgepub.doap --- old/libgepub-0.3/libgepub.doap 1970-01-01 01:00:00.000000000 +0100 +++ new/libgepub-0.4/libgepub.doap 2016-08-31 09:39:20.000000000 +0200 @@ -0,0 +1,19 @@ +<Project xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" + xmlns:foaf="http://xmlns.com/foaf/0.1/" + xmlns:gnome="http://api.gnome.org/doap-extensions#" + xmlns="http://usefulinc.com/ns/doap#"> + + <name xml:lang="en">libgepub</name> + <shortdesc xml:lang="en">Simple library to read epub files using glib</shortdesc> + <description>libgepub is a GObject based library for handling and rendering epub +documents.</description> + <programming-language>C</programming-language> + + <maintainer> + <foaf:Person> + <foaf:name>Daniel GarcĂa Moreno</foaf:name> + <gnome:userid>danigm</gnome:userid> + </foaf:Person> + </maintainer> +</Project> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgepub-0.3/libgepub.pc.in new/libgepub-0.4/libgepub.pc.in --- old/libgepub-0.3/libgepub.pc.in 2016-05-23 09:29:03.000000000 +0200 +++ new/libgepub-0.4/libgepub.pc.in 2016-08-31 09:39:20.000000000 +0200 @@ -6,6 +6,7 @@ Name: libgepub Description: epub Documents library Version: @VERSION@ -Requires: glib-2.0 gobject-2.0 gio-2.0 libxml-2.0 libarchive +Requires: gio-2.0 +Requires.private: libxml-2.0 libarchive Libs: -L${libdir} -lgepub Cflags: -I${includedir} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgepub-0.3/tests/Makefile.am new/libgepub-0.4/tests/Makefile.am --- old/libgepub-0.3/tests/Makefile.am 2016-05-23 09:29:03.000000000 +0200 +++ new/libgepub-0.4/tests/Makefile.am 2016-08-31 09:39:20.000000000 +0200 @@ -7,11 +7,11 @@ $(AM_CPPFLAGS) test_gepub_CFLAGS = \ - $(GEPUB_CFLAGS) \ + $(GEPUB_TESTS_CFLAGS) \ $(WARN_CFLAGS) \ $(AM_CFLAGS) test_gepub_LDADD = \ $(top_builddir)/libgepub/libgepub.la \ - $(GEPUB_LIBS) \ + $(GEPUB_TESTS_LIBS) \ $(GTK_LIBS) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgepub-0.3/tests/test-gepub.c new/libgepub-0.4/tests/test-gepub.c --- old/libgepub-0.3/tests/test-gepub.c 2016-05-23 09:29:03.000000000 +0200 +++ new/libgepub-0.4/tests/test-gepub.c 2016-08-31 09:39:20.000000000 +0200 @@ -53,14 +53,30 @@ } void -button_pressed (GtkButton *button, GepubDoc *doc) +print_replaced_text (GepubDoc *doc) { + GBytes *content; + gsize s; + const guchar *data; + content = gepub_doc_get_current_with_epub_uris (doc); + + data = g_bytes_get_data (content, &s); + printf ("\n\nREPLACED:\n%s\n", data); + g_bytes_unref (content); +} + +void +button_pressed (GtkButton *button, GepubWidget *widget) +{ + GepubDoc *doc = gepub_widget_get_doc (widget); + if (!strcmp (gtk_button_get_label (button), "prev")) { gepub_doc_go_prev (doc); } else { gepub_doc_go_next (doc); } update_text (doc); + print_replaced_text (doc); } void @@ -105,9 +121,10 @@ { GepubArchive *a; GList *list_files = NULL; - guchar *buffer; + const guchar *buffer; guchar *file = NULL; gsize bufsize; + GBytes *bytes; a = gepub_archive_new (path); @@ -115,11 +132,15 @@ GHashTable *ht = (GHashTable*)gepub_doc_get_resources (doc); g_hash_table_foreach (ht, (GHFunc)find_xhtml, &file); - gepub_archive_read_entry (a, file, &buffer, &bufsize); - if (bufsize) - PTEST ("doc:%s\n----\n%s\n-----\n", file, buffer); + bytes = gepub_archive_read_entry (a, file); + if (bytes) { + const char *data; + gsize size; - g_free (buffer); + buffer = g_bytes_get_data (bytes, &bufsize); + PTEST ("doc:%s\n----\n%s\n-----\n", file, buffer); + g_bytes_unref (bytes); + } g_list_foreach (list_files, (GFunc)g_free, NULL); g_list_free (list_files); @@ -184,30 +205,27 @@ GepubDoc *doc = gepub_doc_new (path); GHashTable *ht = (GHashTable*)gepub_doc_get_resources (doc); g_hash_table_foreach (ht, (GHFunc)pk, NULL); - guchar *ncx; + GBytes *ncx; + const guchar *data; gsize size; - ncx = gepub_doc_get_resource (doc, "ncx", &size); - PTEST ("ncx:\n%s\n", ncx); - g_free (ncx); + ncx = gepub_doc_get_resource_by_id (doc, "ncx"); + data = g_bytes_get_data (ncx, &size); + PTEST ("ncx:\n%s\n", data); + g_bytes_unref (ncx); g_object_unref (G_OBJECT (doc)); } void -p (gchar *value, gpointer data) -{ - static int id = 0; - PTEST ("%d: %s\n", id++, value); -} - -void test_doc_spine (const char *path) { GepubDoc *doc = gepub_doc_new (path); + int id = 0; - GList *spine = gepub_doc_get_spine (doc); - g_list_foreach (spine, (GFunc)p, NULL); + do { + PTEST ("%d: %s\n", id++, gepub_doc_get_current_id (doc)); + } while (gepub_doc_go_next (doc)); g_object_unref (G_OBJECT (doc)); } @@ -231,6 +249,7 @@ GepubDoc *doc; GtkWidget *textview2; + GtkWidget *widget = gepub_widget_new (); if (argc < 2) { printf ("you should provide an .epub file\n"); @@ -243,12 +262,15 @@ vpaned = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL); gtk_container_add (GTK_CONTAINER (window), vpaned); + // gepub widget doc = gepub_doc_new (argv[1]); if (!doc) { perror ("BAD epub FILE"); return -1; } + gepub_widget_set_doc (GEPUB_WIDGET (widget), doc); + scrolled = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); textview2 = gtk_text_view_new (); @@ -264,22 +286,23 @@ vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5); hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5); b_prev = gtk_button_new_with_label ("prev"); - g_signal_connect (b_prev, "clicked", (GCallback)button_pressed, doc); + g_signal_connect (b_prev, "clicked", (GCallback)button_pressed, GEPUB_WIDGET (widget)); b_next = gtk_button_new_with_label ("next"); - g_signal_connect (b_next, "clicked", (GCallback)button_pressed, doc); + g_signal_connect (b_next, "clicked", (GCallback)button_pressed, GEPUB_WIDGET (widget)); gtk_container_add (GTK_CONTAINER (hbox), b_prev); gtk_container_add (GTK_CONTAINER (hbox), b_next); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 5); gtk_box_pack_start (GTK_BOX (vbox), scrolled, TRUE, TRUE, 5); - gtk_widget_set_size_request (GTK_WIDGET (vbox), 400, 500); - gtk_paned_add1 (GTK_PANED (vpaned), vbox); - textview = gtk_text_view_new (); scrolled = gtk_scrolled_window_new (NULL, NULL); gtk_container_add (GTK_CONTAINER (scrolled), textview); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtk_paned_add2 (GTK_PANED (vpaned), scrolled); + gtk_box_pack_start (GTK_BOX (vbox), scrolled, TRUE, TRUE, 5); + + gtk_widget_set_size_request (GTK_WIDGET (vbox), 400, 500); + gtk_paned_add1 (GTK_PANED (vpaned), vbox); + gtk_paned_add2 (GTK_PANED (vpaned), widget); gtk_widget_show_all (window); @@ -301,5 +324,7 @@ gtk_main (); + g_object_unref (doc); + return 0; }