mirror of
https://git.pwmt.org/pwmt/zathura.git
synced 2024-12-27 13:56:00 +01:00
Printing, Image and attachment export
Added following functionality: * Save images * Save attachments * Simple printing support Fixes and other changes: * Additional rectangle calculation function * Search and link clicking fix Other: * Added license file
This commit is contained in:
parent
01e613adc0
commit
54149584f1
4 changed files with 204 additions and 57 deletions
21
LICENSE
Normal file
21
LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
Copyright (c) 2009 ML, JY
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
9
README
9
README
|
@ -1,12 +1,11 @@
|
||||||
zathura - pdf viewer
|
zathura - pdf viewer
|
||||||
--------------------
|
--------------------
|
||||||
zathura is an pdf viewer based on the poppler pdf rendering library
|
zathura is a pdf viewer based on the poppler pdf rendering library
|
||||||
|
|
||||||
Requirements
|
Requirements
|
||||||
------------
|
------------
|
||||||
poppler (0.10.7-2)
|
poppler-glib (0.10.7)
|
||||||
poppler-glib (0.10.7-1)
|
gtk2 (2.17.2)
|
||||||
gtk2 (2.16.5-1)
|
|
||||||
|
|
||||||
Configuration
|
Configuration
|
||||||
-------------
|
-------------
|
||||||
|
@ -30,5 +29,3 @@ Use zathura
|
||||||
Just run:
|
Just run:
|
||||||
|
|
||||||
zathura <file>
|
zathura <file>
|
||||||
|
|
||||||
|
|
||||||
|
|
5
config.h
5
config.h
|
@ -6,7 +6,7 @@ static const int SHOW_NOTIFICATION = 5;
|
||||||
static const int DEFAULT_WIDTH = 800;
|
static const int DEFAULT_WIDTH = 800;
|
||||||
static const int DEFAULT_HEIGHT = 600;
|
static const int DEFAULT_HEIGHT = 600;
|
||||||
static const char BROWSER[] = "firefox %s";
|
static const char BROWSER[] = "firefox %s";
|
||||||
|
static const char PRINTER[] = "EPSON_AL-CX11_192.168.88.80";
|
||||||
/* look */
|
/* look */
|
||||||
static const char font[] = "monospace normal 9";
|
static const char font[] = "monospace normal 9";
|
||||||
static const char default_bgcolor[] = "#000000";
|
static const char default_bgcolor[] = "#000000";
|
||||||
|
@ -39,7 +39,7 @@ Shortcut shortcuts[] = {
|
||||||
{GDK_CONTROL_MASK, GDK_0, sc_zoom, { ZOOM_ORIGINAL } },
|
{GDK_CONTROL_MASK, GDK_0, sc_zoom, { ZOOM_ORIGINAL } },
|
||||||
{GDK_CONTROL_MASK, GDK_r, sc_rotate, { RIGHT } },
|
{GDK_CONTROL_MASK, GDK_r, sc_rotate, { RIGHT } },
|
||||||
{GDK_CONTROL_MASK, GDK_e, sc_rotate, { LEFT } },
|
{GDK_CONTROL_MASK, GDK_e, sc_rotate, { LEFT } },
|
||||||
{GDK_CONTROL_MASK, GDK_p, sc_print, {0} },
|
{GDK_CONTROL_MASK, GDK_p, sc_focus_inputbar, { .data = ":print all" } },
|
||||||
{GDK_CONTROL_MASK, GDK_q, sc_quit, {0} },
|
{GDK_CONTROL_MASK, GDK_q, sc_quit, {0} },
|
||||||
{0, GDK_n, sc_search, { FORWARD } },
|
{0, GDK_n, sc_search, { FORWARD } },
|
||||||
{0, GDK_N, sc_search, { BACKWARD } },
|
{0, GDK_N, sc_search, { BACKWARD } },
|
||||||
|
@ -67,6 +67,7 @@ Command commands[] = {
|
||||||
{"info", cmd_info},
|
{"info", cmd_info},
|
||||||
{"links", cmd_links},
|
{"links", cmd_links},
|
||||||
{"open", cmd_open},
|
{"open", cmd_open},
|
||||||
|
{"print", cmd_print},
|
||||||
{"rotate", cmd_rotate},
|
{"rotate", cmd_rotate},
|
||||||
{"quit", cmd_quit},
|
{"quit", cmd_quit},
|
||||||
{"zoom", cmd_zoom},
|
{"zoom", cmd_zoom},
|
||||||
|
|
222
zathura.c
222
zathura.c
|
@ -87,6 +87,8 @@ void set_page(int);
|
||||||
void draw();
|
void draw();
|
||||||
void highlight_result(PopplerRectangle*);
|
void highlight_result(PopplerRectangle*);
|
||||||
void open_link(char*);
|
void open_link(char*);
|
||||||
|
void save_images(int, char*);
|
||||||
|
void save_attachments(char*);
|
||||||
|
|
||||||
gboolean complete(Argument*);
|
gboolean complete(Argument*);
|
||||||
gboolean delete_widget(gpointer);
|
gboolean delete_widget(gpointer);
|
||||||
|
@ -94,6 +96,8 @@ gboolean delete_widget(gpointer);
|
||||||
GtkWidget* notify(int, char*);
|
GtkWidget* notify(int, char*);
|
||||||
GtkWidget* update_notification(GtkWidget*, int, char*);
|
GtkWidget* update_notification(GtkWidget*, int, char*);
|
||||||
|
|
||||||
|
PopplerRectangle* recalcRectangle(PopplerRectangle*);
|
||||||
|
|
||||||
/* shortcut declarations */
|
/* shortcut declarations */
|
||||||
void sc_focus_inputbar(Argument*);
|
void sc_focus_inputbar(Argument*);
|
||||||
void sc_scroll(Argument*);
|
void sc_scroll(Argument*);
|
||||||
|
@ -102,7 +106,6 @@ void sc_zoom(Argument*);
|
||||||
void sc_adjust_window(Argument*);
|
void sc_adjust_window(Argument*);
|
||||||
void sc_rotate(Argument*);
|
void sc_rotate(Argument*);
|
||||||
void sc_search(Argument*);
|
void sc_search(Argument*);
|
||||||
void sc_print(Argument*);
|
|
||||||
void sc_quit(Argument*);
|
void sc_quit(Argument*);
|
||||||
|
|
||||||
/* command declarations */
|
/* command declarations */
|
||||||
|
@ -111,6 +114,7 @@ void cmd_goto(int, char**);
|
||||||
void cmd_info(int, char**);
|
void cmd_info(int, char**);
|
||||||
void cmd_links(int, char**);
|
void cmd_links(int, char**);
|
||||||
void cmd_open(int, char**);
|
void cmd_open(int, char**);
|
||||||
|
void cmd_print(int, char**);
|
||||||
void cmd_rotate(int, char**);
|
void cmd_rotate(int, char**);
|
||||||
void cmd_quit(int, char**);
|
void cmd_quit(int, char**);
|
||||||
void cmd_zoom(int, char**);
|
void cmd_zoom(int, char**);
|
||||||
|
@ -258,7 +262,6 @@ update_notification(GtkWidget* view, int level, char* text)
|
||||||
{
|
{
|
||||||
gtk_widget_modify_fg(GTK_WIDGET(message), GTK_STATE_NORMAL, &(Zathura.Settings.notification_fg));
|
gtk_widget_modify_fg(GTK_WIDGET(message), GTK_STATE_NORMAL, &(Zathura.Settings.notification_fg));
|
||||||
gtk_widget_modify_bg(GTK_WIDGET(view), GTK_STATE_NORMAL, &(Zathura.Settings.notification_bg));
|
gtk_widget_modify_bg(GTK_WIDGET(view), GTK_STATE_NORMAL, &(Zathura.Settings.notification_bg));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(gtk_bin_get_child(GTK_BIN(view)))
|
if(gtk_bin_get_child(GTK_BIN(view)))
|
||||||
|
@ -269,6 +272,47 @@ update_notification(GtkWidget* view, int level, char* text)
|
||||||
return GTK_WIDGET(view);
|
return GTK_WIDGET(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PopplerRectangle*
|
||||||
|
recalcRectangle(PopplerRectangle* rectangle)
|
||||||
|
{
|
||||||
|
double page_width, page_height;
|
||||||
|
double x1 = rectangle->x1;
|
||||||
|
double x2 = rectangle->x2;
|
||||||
|
double y1 = rectangle->y1;
|
||||||
|
double y2 = rectangle->y2;
|
||||||
|
|
||||||
|
poppler_page_get_size(Zathura.PDF.page, &page_width, &page_height);
|
||||||
|
|
||||||
|
switch(Zathura.PDF.rotate)
|
||||||
|
{
|
||||||
|
case 90:
|
||||||
|
rectangle->x1 = (page_height - y2) * Zathura.PDF.scale;
|
||||||
|
rectangle->y1 = x1 * Zathura.PDF.scale;
|
||||||
|
rectangle->x2 = (page_height - y1) * Zathura.PDF.scale;
|
||||||
|
rectangle->y2 = x2 * Zathura.PDF.scale;
|
||||||
|
break;
|
||||||
|
case 180:
|
||||||
|
rectangle->x1 = (page_width - x2) * Zathura.PDF.scale;
|
||||||
|
rectangle->y1 = (page_height - y2) * Zathura.PDF.scale;
|
||||||
|
rectangle->x2 = (page_width - x1) * Zathura.PDF.scale;
|
||||||
|
rectangle->y2 = (page_height - y1) * Zathura.PDF.scale;
|
||||||
|
break;
|
||||||
|
case 270:
|
||||||
|
rectangle->x1 = y1 * Zathura.PDF.scale;
|
||||||
|
rectangle->y1 = (page_width - x2) * Zathura.PDF.scale;
|
||||||
|
rectangle->x2 = y2 * Zathura.PDF.scale;
|
||||||
|
rectangle->y2 = (page_width - x1) * Zathura.PDF.scale;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
rectangle->x1 = x1 * Zathura.PDF.scale;
|
||||||
|
rectangle->y1 = y1 * Zathura.PDF.scale;
|
||||||
|
rectangle->x2 = x2 * Zathura.PDF.scale;
|
||||||
|
rectangle->y2 = y2 * Zathura.PDF.scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rectangle;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
update_status()
|
update_status()
|
||||||
{
|
{
|
||||||
|
@ -361,34 +405,13 @@ draw()
|
||||||
void
|
void
|
||||||
highlight_result(PopplerRectangle* rectangle)
|
highlight_result(PopplerRectangle* rectangle)
|
||||||
{
|
{
|
||||||
double page_height, page_width;
|
|
||||||
double width, height;
|
|
||||||
double scale;
|
|
||||||
|
|
||||||
poppler_page_get_size(Zathura.PDF.page, &page_width, &page_height);
|
|
||||||
scale = Zathura.PDF.scale;
|
|
||||||
width = (rectangle->x2 - rectangle->x1) * scale;
|
|
||||||
height = (rectangle->y2 - rectangle->y1) * scale;
|
|
||||||
|
|
||||||
cairo_t *cairo = cairo_create(Zathura.PDF.surface);
|
cairo_t *cairo = cairo_create(Zathura.PDF.surface);
|
||||||
cairo_set_source_rgba(cairo, Zathura.Settings.search_highlight.red, Zathura.Settings.search_highlight.green,
|
cairo_set_source_rgba(cairo, Zathura.Settings.search_highlight.red, Zathura.Settings.search_highlight.green,
|
||||||
Zathura.Settings.search_highlight.blue, HL_TRANSPARENCY);
|
Zathura.Settings.search_highlight.blue, HL_TRANSPARENCY);
|
||||||
|
|
||||||
switch(Zathura.PDF.rotate)
|
rectangle = recalcRectangle(rectangle);
|
||||||
{
|
|
||||||
case 90:
|
|
||||||
cairo_rectangle(cairo, scale * rectangle->y1, scale * rectangle->x1, height, width);
|
|
||||||
break;
|
|
||||||
case 180:
|
|
||||||
cairo_rectangle(cairo, scale * (page_width - rectangle->x1) - width, scale * rectangle->y1, width, height);
|
|
||||||
break;
|
|
||||||
case 270:
|
|
||||||
cairo_rectangle(cairo, scale * (page_height - rectangle->y1) - height, scale * (page_width - rectangle->x1) - width, height, width);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
cairo_rectangle(cairo, scale * rectangle->x1, scale * (page_height - rectangle->y1) - height, width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
cairo_rectangle(cairo, rectangle->x1, rectangle->y1, (rectangle->x2 - rectangle->x1), (rectangle->y2 - rectangle->y1));
|
||||||
cairo_fill(cairo);
|
cairo_fill(cairo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -399,6 +422,57 @@ open_link(char* link)
|
||||||
system(start_browser);
|
system(start_browser);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
save_images(int page, char* directory)
|
||||||
|
{
|
||||||
|
GList *image_list;
|
||||||
|
GList *images;
|
||||||
|
cairo_surface_t *image;
|
||||||
|
PopplerPage *document_page;
|
||||||
|
|
||||||
|
document_page = poppler_document_get_page(Zathura.PDF.document, page);
|
||||||
|
image_list = poppler_page_get_image_mapping(document_page);
|
||||||
|
|
||||||
|
for(images = image_list; images; images = g_list_next(images))
|
||||||
|
{
|
||||||
|
PopplerImageMapping *image_mapping;
|
||||||
|
PopplerRectangle image_field;
|
||||||
|
gint image_id;
|
||||||
|
char* file;
|
||||||
|
|
||||||
|
image_mapping = (PopplerImageMapping*) images->data;
|
||||||
|
image_field = image_mapping->area;
|
||||||
|
image_id = image_mapping->image_id;
|
||||||
|
|
||||||
|
image = poppler_page_get_image(document_page, image_id);
|
||||||
|
file = g_strdup_printf("%sp%i_i%i.png", directory, page + 1, image_id);
|
||||||
|
|
||||||
|
cairo_surface_write_to_png(image, file);
|
||||||
|
|
||||||
|
g_free(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
save_attachments(char* directory)
|
||||||
|
{
|
||||||
|
GList *attachment_list;
|
||||||
|
GList *attachments;
|
||||||
|
char *file;
|
||||||
|
|
||||||
|
attachment_list = poppler_document_get_attachments(Zathura.PDF.document);
|
||||||
|
|
||||||
|
for(attachments = attachment_list; attachments; attachments = g_list_next(attachments))
|
||||||
|
{
|
||||||
|
PopplerAttachment *attachment = (PopplerAttachment*) attachments->data;
|
||||||
|
file = g_strdup_printf("%s%s", directory, attachment->name);
|
||||||
|
|
||||||
|
poppler_attachment_save(attachment, file, NULL);
|
||||||
|
|
||||||
|
g_free(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
delete_widget(gpointer data)
|
delete_widget(gpointer data)
|
||||||
{
|
{
|
||||||
|
@ -661,6 +735,8 @@ sc_search(Argument *argument)
|
||||||
/* draw results */
|
/* draw results */
|
||||||
if(results)
|
if(results)
|
||||||
{
|
{
|
||||||
|
double page_width, page_height;
|
||||||
|
poppler_page_get_size(Zathura.PDF.page, &page_width, &page_height);
|
||||||
draw();
|
draw();
|
||||||
|
|
||||||
update_notification(GTK_WIDGET(search_status), DEFAULT, g_strdup_printf("%s found on page %i for %i time(s)",
|
update_notification(GTK_WIDGET(search_status), DEFAULT, g_strdup_printf("%s found on page %i for %i time(s)",
|
||||||
|
@ -668,19 +744,16 @@ sc_search(Argument *argument)
|
||||||
|
|
||||||
for(list = results; list && list->data; list = g_list_next(list))
|
for(list = results; list && list->data; list = g_list_next(list))
|
||||||
{
|
{
|
||||||
highlight_result((PopplerRectangle*) list->data);
|
PopplerRectangle* result = (PopplerRectangle*) list->data;
|
||||||
|
result->y1 = page_height - result->y1;
|
||||||
|
result->y2 = page_height - result->y2;
|
||||||
|
highlight_result(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
update_notification(search_status, DEFAULT, g_strdup_printf("No match for %s", search_item));
|
update_notification(search_status, DEFAULT, g_strdup_printf("No match for %s", search_item));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
sc_print(Argument *argument)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
sc_quit(Argument *argument)
|
sc_quit(Argument *argument)
|
||||||
{
|
{
|
||||||
|
@ -725,24 +798,72 @@ cmd_open(int argc, char** argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
cmd_export(int argc, char** argv)
|
cmd_print(int argc, char** argv)
|
||||||
{
|
{
|
||||||
if(argc == 0)
|
if(argc == 0 || !Zathura.PDF.document)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(strcmp(argv[0], "image") == 0)
|
char* print_command;
|
||||||
{
|
char* sites;
|
||||||
|
|
||||||
}
|
if(strcmp(argv[0], "all") == 0)
|
||||||
else if(strcmp(argv[0], "links") == 0)
|
sites = g_strdup_printf("%i", Zathura.PDF.number_of_pages);
|
||||||
{
|
else
|
||||||
|
sites = argv[0];
|
||||||
|
|
||||||
|
print_command = g_strdup_printf("lp -d '%s' -P %s %s", PRINTER, sites, Zathura.PDF.file);
|
||||||
|
|
||||||
|
system(print_command);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cmd_export(int argc, char** argv)
|
||||||
|
{
|
||||||
|
if(argc == 0 || !Zathura.PDF.document)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(argc < 2)
|
||||||
|
{
|
||||||
|
notify(WARNING, "No export path specified");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* export images */
|
||||||
|
if(strcmp(argv[0], "images") == 0)
|
||||||
|
{
|
||||||
|
int page_counter;
|
||||||
|
|
||||||
|
if(argc == 3)
|
||||||
|
{
|
||||||
|
int page_number = atoi(argv[2]) - 1;
|
||||||
|
|
||||||
|
if(page_number < 0 || page_number > Zathura.PDF.number_of_pages)
|
||||||
|
notify(WARNING, "Page does not exist");
|
||||||
|
else
|
||||||
|
save_images(page_number, argv[1]);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(page_counter = 0; page_counter < Zathura.PDF.number_of_pages; page_counter++)
|
||||||
|
{
|
||||||
|
save_images(page_counter, argv[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* export attachments */
|
||||||
else if(strcmp(argv[0], "attachments") == 0)
|
else if(strcmp(argv[0], "attachments") == 0)
|
||||||
{
|
{
|
||||||
|
if(!poppler_document_has_attachments(Zathura.PDF.document))
|
||||||
|
notify(WARNING, "PDF file has no attachments");
|
||||||
|
else
|
||||||
|
save_attachments(argv[1]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
notify(DEFAULT, "export [images|attachments]");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -889,6 +1010,7 @@ cb_draw(GtkWidget *widget, gpointer data)
|
||||||
void
|
void
|
||||||
cb_destroy(GtkWidget *widget, gpointer data)
|
cb_destroy(GtkWidget *widget, gpointer data)
|
||||||
{
|
{
|
||||||
|
pango_font_description_free(Zathura.Settings.font);
|
||||||
gtk_main_quit();
|
gtk_main_quit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -994,18 +1116,24 @@ cb_drawing_area_button_pressed(GtkWidget* widget, GdkEventButton* event, gpointe
|
||||||
{
|
{
|
||||||
double page_width, page_height;
|
double page_width, page_height;
|
||||||
poppler_page_get_size(Zathura.PDF.page, &page_width, &page_height);
|
poppler_page_get_size(Zathura.PDF.page, &page_width, &page_height);
|
||||||
|
PopplerRectangle* link_rectangle = &link_mapping->area;
|
||||||
|
|
||||||
|
if(Zathura.PDF.rotate == 0 || Zathura.PDF.rotate == 180)
|
||||||
|
event->y = page_height - event->y;
|
||||||
|
else if(Zathura.PDF.rotate == 90 || Zathura.PDF.rotate == 270)
|
||||||
|
event->x = page_height - event->x;
|
||||||
|
|
||||||
|
link_rectangle = recalcRectangle(link_rectangle);
|
||||||
|
|
||||||
// check if click is in url area
|
// check if click is in url area
|
||||||
if( (link_mapping->area.x1 <= event->x)
|
if( (link_rectangle->x1 <= event->x)
|
||||||
&& (link_mapping->area.x2 >= event->x)
|
&& (link_rectangle->x2 >= event->x)
|
||||||
&& (link_mapping->area.y1 <= (page_height - event->y))
|
&& (link_rectangle->y1 <= event->y)
|
||||||
&& (link_mapping->area.y2 >= (page_height - event->y))
|
&& (link_rectangle->y2 >= event->y)
|
||||||
)
|
)
|
||||||
{
|
|
||||||
open_link(action->uri.uri);
|
open_link(action->uri.uri);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
poppler_page_free_link_mapping(link_list);
|
poppler_page_free_link_mapping(link_list);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue