36 #include <gdk-pixbuf/gdk-pixbuf.h>
37 #include <glib/gi18n-lib.h>
68 #define EV_DJVU_ERROR ev_djvu_error_quark ()
75 q = g_quark_from_string (
"ev-djvu-quark");
83 switch (msg->m_any.tag) {
87 if (msg->m_error.filename) {
88 error_str = g_strdup_printf (
"DjvuLibre error: %s:%d",
89 msg->m_error.filename,
92 error_str = g_strdup_printf (
"DjvuLibre error: %s",
93 msg->m_error.message);
99 g_warning (
"%s", error_str);
114 ddjvu_context_t *ctx = djvu_document->
d_context;
115 const ddjvu_message_t *msg;
121 ddjvu_message_wait (ctx);
123 while ((msg = ddjvu_message_peek (ctx))) {
125 ddjvu_message_pop (ctx);
134 ddjvu_context_t *ctx = djvu_document->
d_context;
135 const ddjvu_message_t *msg;
137 ddjvu_message_wait (ctx);
138 while ((msg = ddjvu_message_peek (ctx)) && (msg->m_any.tag != message)) {
140 ddjvu_message_pop (ctx);
144 if (msg && msg->m_any.tag == message)
145 ddjvu_message_pop (ctx);
154 ddjvu_document_t *doc;
156 gboolean missing_files =
FALSE;
157 gboolean check_for_missing_files =
FALSE;
158 GError *djvu_error = NULL;
164 filename = g_filename_from_uri (uri, NULL, error);
169 doc = ddjvu_document_create_by_filename_utf8 (djvu_document->
d_context, filename,
TRUE);
171 doc = ddjvu_document_create_by_filename (djvu_document->
d_context, filename,
TRUE);
176 g_set_error_literal (error,
179 _(
"DjVu document has incorrect format"));
184 ddjvu_document_release (djvu_document->
d_document);
190 g_set_error_literal (error,
193 djvu_error->message);
194 g_error_free (djvu_error);
196 ddjvu_document_release (djvu_document->
d_document);
202 if (ddjvu_document_decoding_error (djvu_document->
d_document))
206 g_set_error_literal (error,
209 djvu_error->message);
210 g_error_free (djvu_error);
212 ddjvu_document_release (djvu_document->
d_document);
218 g_free (djvu_document->
uri);
219 djvu_document->
uri = g_strdup (uri);
223 if (djvu_document->
n_pages > 0) {
225 djvu_document->
file_ids = g_hash_table_new (g_str_hash, g_str_equal);
227 if (ddjvu_document_get_type (djvu_document->
d_document) == DDJVU_DOCTYPE_INDIRECT)
228 check_for_missing_files =
TRUE;
230 base = g_path_get_dirname (filename);
232 n_files = ddjvu_document_get_filenum (djvu_document->
d_document);
233 for (i = 0; i < n_files; i++) {
234 ddjvu_fileinfo_t fileinfo;
237 ddjvu_document_get_fileinfo (djvu_document->
d_document,
240 if (fileinfo.type !=
'P')
243 if (fileinfo.pageno >= 0 && fileinfo.pageno < djvu_document->
n_pages) {
247 g_hash_table_insert (djvu_document->
file_ids,
249 GINT_TO_POINTER(fileinfo.pageno));
251 if (check_for_missing_files && !missing_files) {
252 file = g_build_filename (base, fileinfo.id, NULL);
253 if (!g_file_test (file, G_FILE_TEST_EXISTS)) {
254 missing_files =
TRUE;
263 g_set_error_literal (error,
266 _(
"The document is composed of several files. "
267 "One or more of these files cannot be accessed."));
291 g_return_val_if_fail (djvu_document->
d_document, 0);
293 return ddjvu_document_get_pagenum (djvu_document->
d_document);
303 ddjvu_pageinfo_t info;
306 while ((r = ddjvu_document_get_pageinfo(djvu_document->
d_document, page, &info)) < DDJVU_JOB_OK)
309 if (r >= DDJVU_JOB_FAILED)
313 *width = info.width * 72.0 / info.dpi;
315 *height = info.height * 72.0 / info.dpi;
331 width, height, NULL);
334 static cairo_surface_t *
339 cairo_surface_t *surface;
344 ddjvu_page_t *d_page;
345 ddjvu_page_rotation_t rotation;
346 gint buffer_modified;
347 double page_width, page_height;
348 gint transformed_width, transformed_height;
350 d_page = ddjvu_page_create_by_pageno (djvu_document->
d_document, rc->page->index);
352 while (!ddjvu_page_decoding_done (d_page))
356 rotation = ddjvu_page_get_initial_rotation (d_page);
359 &transformed_width, &transformed_height);
365 switch (rc->rotation) {
367 rotation += DDJVU_ROTATE_270;
371 rotation += DDJVU_ROTATE_180;
375 rotation += DDJVU_ROTATE_90;
379 rotation += DDJVU_ROTATE_0;
381 rotation = rotation % 4;
383 surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24,
384 transformed_width, transformed_height);
386 rowstride = cairo_image_surface_get_stride (surface);
387 pixels = (gchar *)cairo_image_surface_get_data (surface);
391 prect.w = transformed_width;
392 prect.h = transformed_height;
395 ddjvu_page_set_rotation (d_page, rotation);
397 buffer_modified = ddjvu_page_render (d_page, DDJVU_RENDER_COLOR,
404 if (!buffer_modified) {
405 cairo_t *cr = cairo_create (surface);
407 cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
411 cairo_surface_mark_dirty (surface);
422 const gchar *title = NULL;
432 if (!g_str_has_suffix (title,
".djvu"))
433 label = g_strdup (title);
443 GdkPixbuf *pixbuf, *rotated_pixbuf;
444 gdouble page_width, page_height;
445 gint thumb_width, thumb_height;
448 g_return_val_if_fail (djvu_document->
d_document, NULL);
451 &page_width, &page_height);
454 &thumb_width, &thumb_height);
456 pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
FALSE, 8,
457 thumb_width, thumb_height);
458 gdk_pixbuf_fill (pixbuf, 0xffffffff);
459 pixels = gdk_pixbuf_get_pixels (pixbuf);
461 while (ddjvu_thumbnail_status (djvu_document->
d_document, rc->page->index, 1) < DDJVU_JOB_OK)
464 ddjvu_thumbnail_render (djvu_document->
d_document, rc->page->index,
465 &thumb_width, &thumb_height,
467 gdk_pixbuf_get_rowstride (pixbuf),
470 rotated_pixbuf = gdk_pixbuf_rotate_simple (pixbuf, 360 - rc->rotation);
471 g_object_unref (pixbuf);
473 return rotated_pixbuf;
476 static cairo_surface_t *
481 cairo_surface_t *surface, *rotated_surface;
482 gdouble page_width, page_height;
483 gint thumb_width, thumb_height;
485 gint thumbnail_rendered;
487 g_return_val_if_fail (djvu_document->
d_document, NULL);
490 &page_width, &page_height);
493 &thumb_width, &thumb_height);
495 surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24,
496 thumb_width, thumb_height);
497 pixels = (gchar *)cairo_image_surface_get_data (surface);
499 while (ddjvu_thumbnail_status (djvu_document->
d_document, rc->page->index, 1) < DDJVU_JOB_OK)
502 thumbnail_rendered = ddjvu_thumbnail_render (djvu_document->
d_document,
504 &thumb_width, &thumb_height,
506 cairo_image_surface_get_stride (surface),
509 if (!thumbnail_rendered) {
510 cairo_surface_destroy (surface);
513 cairo_surface_mark_dirty (surface);
518 cairo_surface_destroy (surface);
519 surface = rotated_surface;
531 ddjvu_document_release (djvu_document->
d_document);
533 if (djvu_document->
opts)
534 g_string_free (djvu_document->
opts,
TRUE);
543 g_hash_table_destroy (djvu_document->
file_ids);
545 ddjvu_context_release (djvu_document->
d_context);
546 ddjvu_format_release (djvu_document->
d_format);
548 g_free (djvu_document->
uri);
550 G_OBJECT_CLASS (djvu_document_parent_class)->finalize (
object);
556 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
580 ddjvu_document_get_pagetext (djvu_document->
d_document,
581 page_num,
"char")) == miniexp_dummy)
584 if (page_text != miniexp_nil) {
589 ddjvu_miniexp_release (djvu_document->
d_document, page_text);
601 dest->
x1 = source->
x1 * dpi / 72;
602 dest->
x2 = source->
x2 * dpi / 72;
603 dest->
y1 = (height - source->
y2) * dpi / 72;
604 dest->
y2 = (height - source->
y1) * dpi / 72;
620 while ((page_text = ddjvu_document_get_pagetext (djvu_document->
d_document,
621 page,
"char")) == miniexp_dummy)
624 if (page_text != miniexp_nil) {
629 ddjvu_miniexp_release (djvu_document->
d_document, page_text);
635 static cairo_region_t *
643 GList *rects = NULL, *l;
644 cairo_region_t *region;
649 region = cairo_region_create ();
650 for (l = rects; l && l->data; l = g_list_next (l)) {
651 cairo_rectangle_int_t rect;
658 r->
y1 = height - r->
y2 * 72 / dpi;
659 r->
y2 = height - tmp * 72 / dpi;
661 rect.x = (gint) ((r->
x1 * scale_x) + 0.5);
662 rect.y = (gint) ((r->
y1 * scale_y) + 0.5);
663 rect.width = (gint) ((r->
x2 * scale_x) + 0.5) - rect.x;
664 rect.height = (gint) ((r->
y2 * scale_y) + 0.5) - rect.y;
665 cairo_region_union_rectangle (region, &rect);
673 static cairo_region_t *
680 gdouble page_width, page_height;
681 gdouble scale_x, scale_y;
687 scale_x, scale_y, points);
706 text = g_strdup (
"");
718 static cairo_region_t *
729 &points.
x2, &points.
y2, NULL);
743 while ((page_text = ddjvu_document_get_pagetext (djvu_document->
d_document,
745 "char")) == miniexp_dummy)
748 if (page_text != miniexp_nil) {
755 ddjvu_miniexp_release (djvu_document->
d_document, page_text);
778 g_string_assign (djvu_document->
opts,
"-page=");
787 g_string_append_printf (djvu_document->
opts,
"%d,", (rc->page->index) + 1);
794 const char *d_optv[d_optc];
799 FILE *fn = fopen (djvu_document->
ps_filename,
"w");
801 g_warning (
"Cannot open file ā%sā.", djvu_document->
ps_filename);
805 d_optv[0] = djvu_document->
opts->str;
807 job = ddjvu_document_print(djvu_document->
d_document, fn, d_optc, d_optv);
808 while (!ddjvu_job_done(job)) {
837 guint masks[4] = { 0xff0000, 0xff00, 0xff, 0xff000000 };
839 djvu_document->
d_context = ddjvu_context_create (
"Evince");
840 djvu_document->
d_format = ddjvu_format_create (DDJVU_FORMAT_RGBMASK32, 4, masks);
841 ddjvu_format_set_row_order (djvu_document->
d_format, 1);
843 djvu_document->
thumbs_format = ddjvu_format_create (DDJVU_FORMAT_RGB24, 0, 0);
844 ddjvu_format_set_row_order (djvu_document->
thumbs_format, 1);
847 djvu_document->
opts = g_string_new (
"");
856 gboolean case_sensitive)
860 gdouble width, height, dpi;
861 GList *matches = NULL, *l;
863 g_return_val_if_fail (text != NULL, NULL);
865 while ((page_text = ddjvu_document_get_pagetext (djvu_document->
d_document,
867 "char")) == miniexp_dummy)
870 if (page_text != miniexp_nil) {
874 if (tpage->
links->len > 0) {
879 ddjvu_miniexp_release (djvu_document->
d_document, page_text);
885 for (l = matches; l && l->data; l = g_list_next (l)) {
892 r->
y1 = height - r->
y2 * 72.0 / dpi;
893 r->
y2 = height - tmp * 72.0 / dpi;