Commit 5e4d5843 authored by Moritz Lipp's avatar Moritz Lipp

Merge branch 'render' into girara

Conflicts:
	Makefile
	config.c
	config.h
	document.c
	ft/djvu/Makefile
	ft/pdf-mupdf/Makefile
	ft/pdf-poppler/Makefile
	render.c
	zathura.c
parents 12793b35 5c5df5bf
......@@ -3,3 +3,4 @@
*~
*.rej
*.swp
.depend
......@@ -19,11 +19,13 @@ options:
%.o: %.c
@echo CC $<
@${CC} -c ${CFLAGS} -o $@ $<
@mkdir -p .depend
@${CC} -c ${CFLAGS} -o $@ $< -MMD -MF .depend/$@.dep
%.do: %.c
@echo CC $<
@${CC} -c ${CFLAGS} ${DFLAGS} -o $@ $<
@mkdir -p .depend
@${CC} -c ${CFLAGS} ${DFLAGS} -o $@ $< -MMD -MF .depend/$@.dep
${OBJECTS}: config.mk
${DOBJECTS}: config.mk
......@@ -34,7 +36,7 @@ ${PROJECT}: ${OBJECTS}
clean:
@rm -rf ${PROJECT} ${OBJECTS} ${PROJECT}-${VERSION}.tar.gz \
${DOBJECTS} ${PROJECT}-debug
${DOBJECTS} ${PROJECT}-debug .depend
@${MAKE} -C ft clean
${PROJECT}-debug: ${DOBJECTS}
......@@ -77,4 +79,6 @@ uninstall:
@rm -f ${DESTDIR}${MANPREFIX}/man1/${PROJECT}.1
@${MAKE} -C ft uninstall
-include $(wildcard .depend/*.dep)
.PHONY: all options clean debug valgrind gdb dist install uninstall
......@@ -8,18 +8,12 @@
#include "zathura.h"
#include "render.h"
#include "document.h"
#include "utils.h"
gboolean
cb_destroy(GtkWidget* widget, gpointer data)
{
if (Zathura.UI.session) {
girara_session_destroy(Zathura.UI.session);
}
document_close();
/* free registered plugins */
zathura_document_plugins_free();
zathura_free(data);
return TRUE;
}
......@@ -28,21 +22,25 @@ void
buffer_changed(girara_session_t* session)
{
g_return_if_fail(session != NULL);
g_return_if_fail(session->global.data != NULL);
zathura_t* zathura = session->global.data;
char* buffer = girara_buffer_get(session);
if (buffer) {
girara_statusbar_item_set_text(session, Zathura.UI.statusbar.buffer, buffer);
girara_statusbar_item_set_text(session, zathura->ui.statusbar.buffer, buffer);
free(buffer);
} else {
girara_statusbar_item_set_text(session, Zathura.UI.statusbar.buffer, "");
girara_statusbar_item_set_text(session, zathura->ui.statusbar.buffer, "");
}
}
void
cb_view_vadjustment_value_changed(GtkAdjustment *adjustment, gpointer data)
{
if (!Zathura.document || !Zathura.document->pages || !Zathura.UI.page_view) {
zathura_t* zathura = data;
if (!zathura || !zathura->document || !zathura->document->pages || !zathura->ui.page_view) {
return;
}
......@@ -51,23 +49,32 @@ cb_view_vadjustment_value_changed(GtkAdjustment *adjustment, gpointer data)
gdouble upper = lower + gtk_adjustment_get_page_size(adjustment);
/* find page that fits */
for (unsigned int page_id = 0; page_id < Zathura.document->number_of_pages; page_id++)
for (unsigned int page_id = 0; page_id < zathura->document->number_of_pages; page_id++)
{
zathura_page_t* page = Zathura.document->pages[page_id];
zathura_page_t* page = zathura->document->pages[page_id];
/* check for rendered attribute */
if (page->rendered) {
page_offset_t* offset = page_calculate_offset(page);
if (offset == NULL) {
continue;
}
double begin = page->offset;
double end = page->offset + page->height;
double begin = offset->y;
double end = offset->y + page->height;
if ( ( (begin >= lower) && (end <= upper) ) /* page is in viewport */
|| ( (begin <= lower) && (end >= lower) && (end <= upper) ) /* end of the page is in viewport */
|| ( (begin >= lower) && (end >= upper) && (begin <= upper) ) /* begin of the page is in viewport */
if ( ( (begin >= lower) && (end <= upper) ) /* [> page is in viewport <]*/
|| ( (begin <= lower) && (end >= lower) && (end <= upper) ) /* [> end of the page is in viewport <] */
|| ( (begin >= lower) && (end >= upper) && (begin <= upper) ) /* [> begin of the page is in viewport <] */
) {
render_page(Zathura.Sync.render_thread, Zathura.document->pages[page_id]);
page->visible = true;
if (page->surface == NULL) {
render_page(zathura->sync.render_thread, page);
}
} else {
page->visible = false;
cairo_surface_destroy(page->surface);
page->surface = NULL;
}
free(offset);
}
}
......@@ -24,7 +24,12 @@ cmd_bookmark_open(girara_session_t* session, girara_list_t* argument_list)
bool
cmd_close(girara_session_t* session, girara_list_t* argument_list)
{
document_close();
g_return_val_if_fail(session != NULL, false);
g_return_val_if_fail(session->global.data != NULL, false);
zathura_t* zathura = session->global.data;
g_return_val_if_fail(zathura->document != NULL, false);
document_close(zathura);
return true;
}
......
This diff is collapsed.
......@@ -5,18 +5,21 @@
#define GLOBAL_RC "/etc/zathurarc"
#define ZATHURA_RC "zathurarc"
#define CONFIG_DIR "~/.config/zathura"
#include "zathura.h"
/**
* This function loads the default values of the configuration
*
* @param zathura the zathura session
*/
void config_load_default(void);
void config_load_default(zathura_t* zathura);
/**
* Loads and evaluates a configuration file
*
* @param path Path to the configuration file
*/
void config_load_file(char* path);
void config_load_file(zathura_t* zathura, char* path);
#endif // CONFIG_H
This diff is collapsed.
......@@ -7,12 +7,12 @@
#include <stdbool.h>
#include <girara-datastructures.h>
#include "zathura.h"
#define PLUGIN_DIR "/usr/lib/zathura"
#define PLUGIN_REGISTER_FUNCTION "plugin_register"
typedef struct zathura_list_s zathura_list_t;
typedef struct zathura_document_s zathura_document_t;
// typedef struct zathura_document_s zathura_document_t;
typedef bool (*zathura_document_open_t)(zathura_document_t* document);
......@@ -24,7 +24,6 @@ typedef struct zathura_document_plugin_s
char* file_extension; /**> File extension */
zathura_document_open_t open_function; /**> Document open function */
void* handle; /**> DLL handle */
struct zathura_document_plugin_s *next; /**> Next plugin */ // TODO: Use list_t
} zathura_document_plugin_t;
/**
......@@ -43,6 +42,33 @@ struct zathura_list_s
struct zathura_list_s* next; /**> Next element in the list */
};
/**
* Image buffer
*/
typedef struct zathura_image_buffer_s
{
unsigned char* data; /**> Image buffer data */
unsigned int height; /**> Height of the image */
unsigned int width; /**> Width of the image */
unsigned int rowstride; /**> Rowstride of the image */
} zathura_image_buffer_t;
/**
* Creates an image buffer
*
* @param width Width of the image stored in the buffer
* @param height Height of the image stored in the buffer
* @return Image buffer or NULL if an error occured
*/
zathura_image_buffer_t* zathura_image_buffer_create(unsigned int width, unsigned int height);
/**
* Frees the image buffer
*
* @param zathura_image_buffer_t
*/
void zathura_image_buffer_free(zathura_image_buffer_t*);
/**
* Rectangle structure
*/
......@@ -112,17 +138,19 @@ typedef struct zathura_form_s
/**
* Page
*/
typedef struct zathura_page_s
struct zathura_page_s
{
double height; /**> Page height */
double width; /**> Page width */
double offset; /**> Page offset */
unsigned int number; /**> Page number */
zathura_document_t* document; /**> Document */
void* data; /**> Custom data */
bool rendered; /**> Page has been rendered */
bool visible; /**> Page is visible */
GtkWidget* event_box; /**> Widget wrapper for mouse events */
GtkWidget* drawing_area; /**> Drawing area */
GStaticMutex lock; /**> Lock */
} zathura_page_t;
cairo_surface_t* surface; /** Cairo surface */
};
/**
* Document
......@@ -136,88 +164,57 @@ struct zathura_document_s
double scale; /**> Scale value */
int rotate; /**> Rotation */
void* data; /**> Custom data */
zathura_t* zathura; /** Zathura object */
struct
{
/**
* Frees the document
*
* @param document The document
*/
bool (*document_free)(zathura_document_t* document);
/**
* Generates the document index
*
* @param document The document
* @return NULL if an error occured or no index exists
*/
girara_tree_node_t* (*document_index_generate)(zathura_document_t* document);
/**
* Save the document
*
* @param document The document
* @param path The new path
* @return true if no error occured
*/
bool (*document_save_as)(zathura_document_t* document, const char* path);
/**
* Get list of attachments
*
* @param document The document
* @return NULL if an error occured, otherwise the attachment list
*/
zathura_list_t* (*document_attachments_get)(zathura_document_t* document);
/**
* Gets the page object
*
* @param document The document
* @param page_id Number of the page
* @return The page object or NULL, if an error occured
*/
zathura_page_t* (*page_get)(zathura_document_t* document, unsigned int page_id);
/**
* Search text
*
* @param page The page
* @param text Search item
* @return List of results
*/
zathura_list_t* (*page_search_text)(zathura_page_t* page, const char* text);
/**
* Get links on a page
*
* @param page
* @return List of links
*/
zathura_list_t* (*page_links_get)(zathura_page_t* page);
/**
* Get form fields
*
* @param page
* @return List of form fields
*/
zathura_list_t* (*page_form_fields_get)(zathura_page_t* page);
/**
* Renders the page
*
* @param page
* @return Rendered page
*/
GtkWidget* (*page_render)(zathura_page_t* page);
zathura_image_buffer_t* (*page_render)(zathura_page_t* page);
/**
* Free page
*
* @param page
* @return true if no error occured, otherwise false
*/
bool (*page_free)(zathura_page_t* page);
} functions;
......@@ -230,18 +227,22 @@ struct zathura_document_s
/**
* Load all document plugins
*
* @param zathura the zathura session
*/
void zathura_document_plugins_load(void);
void zathura_document_plugins_load(zathura_t* zathura);
/**
* Free all document plugins
*
* @param zathura the zathura session
*/
void zathura_document_plugins_free(void);
void zathura_document_plugins_free(zathura_t* zathura);
/**
* Register document plugin
*/
bool zathura_document_plugin_register(zathura_document_plugin_t* new_plugin, void* handle);
bool zathura_document_plugin_register(zathura_t* zathura, zathura_document_plugin_t* new_plugin, void* handle);
/**
* Open the document
......@@ -250,7 +251,7 @@ bool zathura_document_plugin_register(zathura_document_plugin_t* new_plugin, voi
* @param password Password of the document or NULL
* @return The document object
*/
zathura_document_t* zathura_document_open(const char* path, const char* password);
zathura_document_t* zathura_document_open(zathura_t* zathura, const char* path, const char* password);
/**
* Free the document
......@@ -356,9 +357,9 @@ bool zathura_page_form_fields_free(zathura_list_t* list);
* Render page
*
* @param page The page object
* @return Rendered page
* @return Image buffer or NULL if an error occured
*/
GtkWidget* zathura_page_render(zathura_page_t* page);
zathura_image_buffer_t* zathura_page_render(zathura_page_t* page);
/**
* Create new index element
......
......@@ -18,11 +18,13 @@ options:
%.o: %.c
@echo CC $<
@${CC} -c ${CFLAGS} -o $@ $<
@mkdir -p .depend
@${CC} -c ${CFLAGS} -o $@ $< -MMD -MF .depend/$@.dep
%.do: %.c
@echo CC $<
@${CC} -c ${CFLAGS} ${DFLAGS} -o $@ $<
@mkdir -p .depend
@${CC} -c ${CFLAGS} ${DFLAGS} -o $@ $< -MMD -MF .depend/$@.dep
${OBJECTS}: config.mk
${DOBJECTS}: config.mk
......@@ -36,7 +38,7 @@ ${PLUGIN}-debug: ${DOBJECTS}
@${CC} -shared ${LDFLAGS} -o ${PLUGIN}.so $(DOBJECTS) ${LIBS}
clean:
@rm -rf ${OBJECTS} ${DOBJECTS} $(PLUGIN).so
@rm -rf ${OBJECTS} ${DOBJECTS} $(PLUGIN).so .depend
debug: options ${PLUGIN}-debug
......@@ -50,4 +52,6 @@ uninstall:
@rm -f ${DESTDIR}${PREFIX}/lib/zathura/${PLUGIN}.so
@rm -rf ${DESTDIR}${PREFIX}/lib/zathura
-include $(wildcard .depend/*.dep)
.PHONY: all options clean debug install uninstall
......@@ -215,16 +215,16 @@ djvu_page_form_fields_get(zathura_page_t* page)
return NULL;
}
GtkWidget*
zathura_image_buffer_t*
djvu_page_render(zathura_page_t* page)
{
if (!Zathura.document || !page || !page->document) {
if (!page || !page->document) {
return NULL;
}
/* calculate sizes */
unsigned int page_width = Zathura.document->scale * page->width;
unsigned int page_height = Zathura.document->scale * page->height;
unsigned int page_width = page->document->scale * page->width;
unsigned int page_height = page->document->scale * page->height;
if (!page_width || !page_height) {
goto error_out;
......@@ -243,76 +243,25 @@ djvu_page_render(zathura_page_t* page)
ddjvu_rect_t rrect = { 0, 0, page_width, page_height };
ddjvu_rect_t prect = { 0, 0, page_width, page_height };
guchar* buffer = malloc(sizeof(char) * (page_width * page_height * 3));
if (!buffer) {
zathura_image_buffer_t* image_buffer = zathura_image_buffer_create(page_width, page_height);
if (image_buffer == NULL) {
goto error_free;
}
/* set rotation */
GdkPixbufRotation gdk_angle = GDK_PIXBUF_ROTATE_NONE;
ddjvu_page_rotation_t ddjvu_angle = DDJVU_ROTATE_0;
switch(Zathura.document->rotate) {
case 90:
gdk_angle = GDK_PIXBUF_ROTATE_CLOCKWISE;
ddjvu_angle = DDJVU_ROTATE_90;
break;
case 180:
gdk_angle = GDK_PIXBUF_ROTATE_UPSIDEDOWN;
ddjvu_angle = DDJVU_ROTATE_180;
break;
case 270:
gdk_angle = GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE;
ddjvu_angle = DDJVU_ROTATE_270;
break;
default:
gdk_angle = GDK_PIXBUF_ROTATE_NONE;
ddjvu_angle = DDJVU_ROTATE_0;
break;
}
ddjvu_page_set_rotation(djvu_page, ddjvu_angle);
ddjvu_page_set_rotation(djvu_page, DDJVU_ROTATE_0);
/* render page */
ddjvu_page_render(djvu_page, DDJVU_RENDER_COLOR, &prect, &rrect, djvu_document->format,
3 * page_width, (char*) buffer);
/* create pixbuf */
GdkPixbuf* pixbuf = gdk_pixbuf_new_from_data(buffer, GDK_COLORSPACE_RGB, FALSE, 8,
page_width, page_height, 3 * page_width, NULL, NULL);
if (!pixbuf) {
goto error_free;
}
/* rotate page */
if (Zathura.document->rotate != 0) {
GdkPixbuf* pixbuf_temp = gdk_pixbuf_rotate_simple(pixbuf, gdk_angle);
if (!pixbuf_temp) {
goto error_free;
}
pixbuf = pixbuf_temp;
}
GtkWidget* image = gtk_image_new();
if (!image) {
goto error_free;
}
gtk_image_set_from_pixbuf(GTK_IMAGE(image), pixbuf);
gtk_widget_show(image);
ddjvu_page_release(djvu_page);
3 * page_width, (char*) image_buffer->data);
return image;
return image_buffer;
error_free:
ddjvu_page_release(djvu_page);
free(buffer);
g_object_unref(pixbuf);
zathura_image_buffer_free(image_buffer);
error_out:
......
......@@ -24,7 +24,7 @@ zathura_page_t* djvu_page_get(zathura_document_t* document, unsigned int page);
zathura_list_t* djvu_page_search_text(zathura_page_t* page, const char* text);
zathura_list_t* djvu_page_links_get(zathura_page_t* page);
zathura_list_t* djvu_page_form_fields_get(zathura_page_t* page);
GtkWidget* djvu_page_render(zathura_page_t* page);
zathura_image_buffer_t* djvu_page_render(zathura_page_t* page);
bool djvu_page_free(zathura_page_t* page);
#endif // DJVU_H
......@@ -18,11 +18,13 @@ options:
%.o: %.c
@echo CC $<
@${CC} -c ${CFLAGS} -o $@ $<
@mkdir -p .depend
@${CC} -c ${CFLAGS} -o $@ $< -MMD -MF .depend/$@.dep
%.do: %.c
@echo CC $<
@${CC} -c ${CFLAGS} ${DFLAGS} -o $@ $<
@mkdir -p .depend
@${CC} -c ${CFLAGS} ${DFLAGS} -o $@ $< -MMD -MF .depend/$@.dep
${OBJECTS}: config.mk
${DOBJECTS}: config.mk
......@@ -36,7 +38,7 @@ ${PLUGIN}-debug: ${DOBJECTS}
@${CC} -shared ${LDFLAGS} -o ${PLUGIN}.so $(DOBJECTS) ${LIBS}
clean:
@rm -rf ${OBJECTS} ${DOBJECTS} $(PLUGIN).so
@rm -rf ${OBJECTS} ${DOBJECTS} $(PLUGIN).so .depend
debug: options ${PLUGIN}-debug
......@@ -50,4 +52,6 @@ uninstall:
@rm -f ${DESTDIR}${PREFIX}/lib/zathura/${PLUGIN}.so
@rm -rf ${DESTDIR}${PREFIX}/lib/zathura
-include $(wildcard .depend/*.dep)
.PHONY: all options clean debug install uninstall
......@@ -173,29 +173,28 @@ pdf_page_form_fields_get(zathura_page_t* page)
return NULL;
}
GtkWidget*
zathura_image_buffer_t*
pdf_page_render(zathura_page_t* page)
{
if (!Zathura.document || !page || !page->data || !page->document) {
if (!page || !page->data || !page->document) {
return NULL;
}
/* calculate sizes */
unsigned int page_width = Zathura.document->scale * page->width;
unsigned int page_height = Zathura.document->scale * page->height;
unsigned int page_width = page->document->scale * page->width;
unsigned int page_height = page->document->scale * page->height;
if (Zathura.document->rotate == 90 || Zathura.document->rotate == 270) {
if (page->document->rotate == 90 || page->document->rotate == 270) {
unsigned int dim_temp = 0;
dim_temp = page_width;
page_width = page_height;
page_height = dim_temp;
}
/* create pixbuf */
GdkPixbuf* pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8,
page_width, page_height);
/* create image buffer */
zathura_image_buffer_t* image_buffer = zathura_image_buffer_create(page_width, page_height);
if (!pixbuf) {
if (image_buffer == NULL) {
return NULL;
}
......@@ -216,15 +215,11 @@ pdf_page_render(zathura_page_t* page)
fz_matrix ctm = fz_identity;
ctm = fz_concat(ctm, fz_translate(0, -mupdf_page->page->mediabox.y1));
ctm = fz_concat(ctm, fz_scale(Zathura.document->scale, -Zathura.document->scale));
ctm = fz_concat(ctm, fz_scale(page->document->scale, -page->document->scale));
ctm = fz_concat(ctm, fz_rotate(mupdf_page->page->rotate));
ctm = fz_concat(ctm, fz_rotate(Zathura.document->rotate));
ctm = fz_concat(ctm, fz_rotate(page->document->rotate));
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* pixmap = fz_newpixmapwithrect(fz_devicergb, bbox);
fz_clearpixmapwithcolor(pixmap, 0xFF);
......@@ -235,7 +230,7 @@ pdf_page_render(zathura_page_t* page)
for (unsigned int y = 0; y < pixmap->h; y++) {
for (unsigned int x = 0; x < pixmap->w; x++) {
unsigned char *s = pixmap->samples + y * pixmap->w * 4 + x * 4;
guchar* p = pixels + y * rowstride + x * n_channels;
guchar* p = image_buffer->data + y * image_buffer->rowstride + x * 3;
p[0] = s[0];
p[1] = s[1];
p[2] = s[2];
......@@ -245,16 +240,5 @@ pdf_page_render(zathura_page_t* page)
fz_droppixmap(pixmap);
fz_freedisplaylist(display_list);
/* write pixbuf */
GtkWidget* image = gtk_image_new();
if (!image) {
g_object_unref(pixbuf);
return NULL;
}
gtk_image_set_from_pixbuf(GTK_IMAGE(image), pixbuf);
gtk_widget_show(image);
return image;
return image_buffer;
}
......@@ -27,7 +27,7 @@ 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_links_get(zathura_page_t* page);
zathura_list_t* pdf_page_form_fields_get(zathura_page_t* page);
GtkWidget* pdf_page_render(zathura_page_t* page);
zathura_image_buffer_t* pdf_page_render(zathura_page_t* page);
bool pdf_page_free(zathura_page_t* page);
#endif // PDF_H
......@@ -18,11 +18,13 @@ options:
%.o: %.c
@echo CC $<
@${CC} -c ${CFLAGS} -o $@ $<
@mkdir -p .depend
@${CC} -c ${CFLAGS} -o $@ $< -MMD -MF .depend/$@.dep
%.do: %.c
@echo CC $<
@${CC} -c ${CFLAGS} ${DFLAGS} -o $@ $<
@mkdir -p .depend
@${CC} -c ${CFLAGS} ${DFLAGS} -o $@ $< -MMD -MF .depend/$@.dep
${OBJECTS}: config.mk
${DOBJECTS}: config.mk
......@@ -36,7 +38,7 @@ ${PLUGIN}-debug: ${DOBJECTS}
@${CC} -shared ${LDFLAGS} -o ${PLUGIN}.so $(DOBJECTS) ${LIBS}
clean:
@rm -rf ${OBJECTS} ${DOBJECTS} $(PLUGIN).so
@rm -rf ${OBJECTS} ${DOBJECTS} $(PLUGIN).so .depend
debug: options ${PLUGIN}-debug
......@@ -50,4 +52,6 @@ uninstall:
@rm -f ${DESTDIR}${PREFIX}/lib/zathura/${PLUGIN}.so
@rm -rf ${DESTDIR}${PREFIX}/lib/zathura
-include $(wildcard .depend/*.dep)
.PHONY: all options clean debug install uninstall
......@@ -250,45 +250,52 @@ pdf_page_form_fields_get(zathura_page_t* page)
return NULL;
}
GtkWidget*
zathura_image_buffer_t*
pdf_page_render(zathura_page_t* page)
{
if (!Zathura.document || !page || !page->data || !page->document) {
if (!page || !page->data || !page->document) {
return NULL;
}
/* calculate sizes */
unsigned int page_width = Zathura.document->scale * page->width;
unsigned int page_height = Zathura.document->scale * page->height;
if (Zathura.document->rotate == 90 || Zathura.document->rotate == 270) {
unsigned int dim_temp = 0;
dim_temp = page_width;
page_width = page_height;
page_height = dim_temp;
}
unsigned int page_width = page->document->scale * page->width;
unsigned int page_height = page->document->scale * page->height;
/* create pixbuf */
GdkPixbuf* pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8,
page_width, page_height);
if (!pixbuf) {
if (pixbuf == NULL) {
return NULL;
}
poppler_page_render_to_pixbuf(page->data, 0, 0, page_width, page_height, Zathura.document->scale,
Zathura.document->rotate, pixbuf);
poppler_page_render_to_pixbuf(page->data, 0, 0, page->width, page->height,
page->document->scale, 0, pixbuf);
/* write pixbuf */
GtkWidget* image = gtk_image_new();
/* create image buffer */
zathura_image_buffer_t* image_buffer = zathura_image_buffer_create(page_width, page_height);
if (!image) {
if (image_buffer == NULL) {
g_object_unref(pixbuf);
return NULL;
}
gtk_image_set_from_pixbuf(GTK_IMAGE(image), pixbuf);
gtk_widget_show(image);
/* copy buffer */
guchar* pixels = gdk_pixbuf_get_pixels(pixbuf);