X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=blobdiff_plain;f=libview%2Fev-jobs.c;h=3e33886f7f4a761f029544dffe26abd88a803eeb;hb=b0e729d2f6401c7cf6988aa044f47b3ca8e48487;hp=c0aa0b482d5347aa4a63a361ec98c4088caf06fc;hpb=3d3328b2597e9b85afcb552ffc6abdeca1e3e3a7;p=evince.git diff --git a/libview/ev-jobs.c b/libview/ev-jobs.c index c0aa0b48..3e33886f 100644 --- a/libview/ev-jobs.c +++ b/libview/ev-jobs.c @@ -15,13 +15,12 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "ev-jobs.h" -#include "ev-document-thumbnails.h" #include "ev-document-links.h" #include "ev-document-images.h" #include "ev-document-forms.h" @@ -36,6 +35,7 @@ #include "ev-document-print.h" #include "ev-document-annotations.h" #include "ev-document-attachments.h" +#include "ev-document-text.h" #include "ev-debug.h" #include @@ -49,8 +49,12 @@ static void ev_job_links_init (EvJobLinks *job); static void ev_job_links_class_init (EvJobLinksClass *class); static void ev_job_attachments_init (EvJobAttachments *job); static void ev_job_attachments_class_init (EvJobAttachmentsClass *class); +static void ev_job_annots_init (EvJobAnnots *job); +static void ev_job_annots_class_init (EvJobAnnotsClass *class); static void ev_job_render_init (EvJobRender *job); static void ev_job_render_class_init (EvJobRenderClass *class); +static void ev_job_page_data_init (EvJobPageData *job); +static void ev_job_page_data_class_init (EvJobPageDataClass *class); static void ev_job_thumbnail_init (EvJobThumbnail *job); static void ev_job_thumbnail_class_init (EvJobThumbnailClass *class); static void ev_job_load_init (EvJobLoad *job); @@ -72,11 +76,6 @@ enum { LAST_SIGNAL }; -enum { - PAGE_READY, - RENDER_LAST_SIGNAL -}; - enum { FONTS_UPDATED, FONTS_LAST_SIGNAL @@ -88,14 +87,15 @@ enum { }; static guint job_signals[LAST_SIGNAL] = { 0 }; -static guint job_render_signals[RENDER_LAST_SIGNAL] = { 0 }; static guint job_fonts_signals[FONTS_LAST_SIGNAL] = { 0 }; static guint job_find_signals[FIND_LAST_SIGNAL] = { 0 }; G_DEFINE_ABSTRACT_TYPE (EvJob, ev_job, G_TYPE_OBJECT) G_DEFINE_TYPE (EvJobLinks, ev_job_links, EV_TYPE_JOB) G_DEFINE_TYPE (EvJobAttachments, ev_job_attachments, EV_TYPE_JOB) +G_DEFINE_TYPE (EvJobAnnots, ev_job_annots, EV_TYPE_JOB) G_DEFINE_TYPE (EvJobRender, ev_job_render, EV_TYPE_JOB) +G_DEFINE_TYPE (EvJobPageData, ev_job_page_data, EV_TYPE_JOB) G_DEFINE_TYPE (EvJobThumbnail, ev_job_thumbnail, EV_TYPE_JOB) G_DEFINE_TYPE (EvJobFonts, ev_job_fonts, EV_TYPE_JOB) G_DEFINE_TYPE (EvJobLoad, ev_job_load, EV_TYPE_JOB) @@ -437,6 +437,85 @@ ev_job_attachments_new (EvDocument *document) return job; } +/* EvJobAnnots */ +static void +ev_job_annots_init (EvJobAnnots *job) +{ + EV_JOB (job)->run_mode = EV_JOB_RUN_THREAD; +} + +static void +ev_job_annots_dispose (GObject *object) +{ + EvJobAnnots *job; + + ev_debug_message (DEBUG_JOBS, NULL); + + job = EV_JOB_ANNOTS (object); + + if (job->annots) { + g_list_foreach (job->annots, (GFunc)ev_mapping_list_unref, NULL); + g_list_free (job->annots); + job->annots = NULL; + } + + G_OBJECT_CLASS (ev_job_annots_parent_class)->dispose (object); +} + +static gboolean +ev_job_annots_run (EvJob *job) +{ + EvJobAnnots *job_annots = EV_JOB_ANNOTS (job); + gint i; + + ev_debug_message (DEBUG_JOBS, NULL); + ev_profiler_start (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job); + + ev_document_doc_mutex_lock (); + for (i = 0; i < ev_document_get_n_pages (job->document); i++) { + EvMappingList *mapping_list; + EvPage *page; + + page = ev_document_get_page (job->document, i); + mapping_list = ev_document_annotations_get_annotations (EV_DOCUMENT_ANNOTATIONS (job->document), + page); + g_object_unref (page); + + if (mapping_list) + job_annots->annots = g_list_prepend (job_annots->annots, mapping_list); + } + ev_document_doc_mutex_unlock (); + + job_annots->annots = g_list_reverse (job_annots->annots); + + ev_job_succeeded (job); + + return FALSE; +} + +static void +ev_job_annots_class_init (EvJobAnnotsClass *class) +{ + GObjectClass *oclass = G_OBJECT_CLASS (class); + EvJobClass *job_class = EV_JOB_CLASS (class); + + oclass->dispose = ev_job_annots_dispose; + job_class->run = ev_job_annots_run; +} + +EvJob * +ev_job_annots_new (EvDocument *document) +{ + EvJob *job; + + ev_debug_message (DEBUG_JOBS, NULL); + + job = g_object_new (EV_TYPE_JOB_ANNOTS, NULL); + job->document = g_object_ref (document); + + return job; +} + /* EvJobRender */ static void ev_job_render_init (EvJobRender *job) @@ -451,12 +530,8 @@ ev_job_render_dispose (GObject *object) job = EV_JOB_RENDER (object); - if (job->ev_page) { - ev_debug_message (DEBUG_JOBS, "page: %d (%p)", job->ev_page->index, job); - g_object_unref (job->ev_page); - job->ev_page = NULL; - } - + ev_debug_message (DEBUG_JOBS, "page: %d (%p)", job->page, job); + if (job->surface) { cairo_surface_destroy (job->surface); job->surface = NULL; @@ -468,44 +543,18 @@ ev_job_render_dispose (GObject *object) } if (job->selection_region) { - gdk_region_destroy (job->selection_region); + cairo_region_destroy (job->selection_region); job->selection_region = NULL; } (* G_OBJECT_CLASS (ev_job_render_parent_class)->dispose) (object); } -static gboolean -notify_page_ready (EvJobRender *job) -{ - ev_debug_message (DEBUG_JOBS, "%d (%p)", job->ev_page->index, job); - ev_profiler_stop (EV_PROFILE_JOBS, "Rendering page %d", job->ev_page->index); - - if (EV_JOB (job)->cancelled) { - ev_debug_message (DEBUG_JOBS, "%s (%p) job was cancelled, do not emit page_ready", EV_GET_TYPE_NAME (job), job); - } else { - g_signal_emit (job, job_render_signals[PAGE_READY], 0); - } - - return FALSE; -} - -static void -ev_job_render_page_ready (EvJobRender *job) -{ - ev_debug_message (DEBUG_JOBS, "%d (%p)", job->ev_page->index, job); - - job->page_ready = TRUE; - g_idle_add_full (G_PRIORITY_HIGH_IDLE, - (GSourceFunc)notify_page_ready, - g_object_ref (job), - (GDestroyNotify)g_object_unref); -} - static gboolean ev_job_render_run (EvJob *job) { EvJobRender *job_render = EV_JOB_RENDER (job); + EvPage *ev_page; EvRenderContext *rc; ev_debug_message (DEBUG_JOBS, "page: %d (%p)", job_render->page, job); @@ -517,9 +566,10 @@ ev_job_render_run (EvJob *job) ev_document_fc_mutex_lock (); - job_render->ev_page = ev_document_get_page (job->document, job_render->page); - rc = ev_render_context_new (job_render->ev_page, job_render->rotation, job_render->scale); - + ev_page = ev_document_get_page (job->document, job_render->page); + rc = ev_render_context_new (ev_page, job_render->rotation, job_render->scale); + g_object_unref (ev_page); + job_render->surface = ev_document_render (job->document, rc); /* If job was cancelled during the page rendering, * we return now, so that the thread is finished ASAP @@ -531,8 +581,8 @@ ev_job_render_run (EvJob *job) return FALSE; } - - if ((job_render->flags & EV_RENDER_INCLUDE_SELECTION) && EV_IS_SELECTION (job->document)) { + + if (job_render->include_selection && EV_IS_SELECTION (job->document)) { ev_selection_render_selection (EV_SELECTION (job->document), rc, &(job_render->selection), @@ -547,29 +597,9 @@ ev_job_render_run (EvJob *job) &(job_render->selection_points)); } - ev_job_render_page_ready (job_render); - - ev_document_fc_mutex_unlock (); - - if ((job_render->flags & EV_RENDER_INCLUDE_TEXT) && EV_IS_SELECTION (job->document)) - job_render->text_mapping = - ev_selection_get_selection_map (EV_SELECTION (job->document), rc); - if ((job_render->flags & EV_RENDER_INCLUDE_LINKS) && EV_IS_DOCUMENT_LINKS (job->document)) - job_render->link_mapping = - ev_document_links_get_links (EV_DOCUMENT_LINKS (job->document), job_render->page); - if ((job_render->flags & EV_RENDER_INCLUDE_FORMS) && EV_IS_DOCUMENT_FORMS (job->document)) - job_render->form_field_mapping = - ev_document_forms_get_form_fields (EV_DOCUMENT_FORMS (job->document), - job_render->ev_page); - if ((job_render->flags & EV_RENDER_INCLUDE_IMAGES) && EV_IS_DOCUMENT_IMAGES (job->document)) - job_render->image_mapping = - ev_document_images_get_image_mapping (EV_DOCUMENT_IMAGES (job->document), - job_render->page); - if ((job_render->flags & EV_RENDER_INCLUDE_ANNOTS) && EV_IS_DOCUMENT_ANNOTATIONS (job->document)) - job_render->annots_mapping = - ev_document_annotations_get_annotations (EV_DOCUMENT_ANNOTATIONS (job->document), - job_render->ev_page); g_object_unref (rc); + + ev_document_fc_mutex_unlock (); ev_document_doc_mutex_unlock (); ev_job_succeeded (job); @@ -583,15 +613,6 @@ ev_job_render_class_init (EvJobRenderClass *class) GObjectClass *oclass = G_OBJECT_CLASS (class); EvJobClass *job_class = EV_JOB_CLASS (class); - job_render_signals [PAGE_READY] = - g_signal_new ("page-ready", - EV_TYPE_JOB_RENDER, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EvJobRenderClass, page_ready), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - oclass->dispose = ev_job_render_dispose; job_class->run = ev_job_render_run; } @@ -600,10 +621,9 @@ EvJob * ev_job_render_new (EvDocument *document, gint page, gint rotation, - gdouble scale, + gdouble scale, gint width, - gint height, - EvRenderFlags flags) + gint height) { EvJobRender *job; @@ -617,7 +637,6 @@ ev_job_render_new (EvDocument *document, job->scale = scale; job->target_width = width; job->target_height = height; - job->flags = flags; return EV_JOB (job); } @@ -629,14 +648,93 @@ ev_job_render_set_selection_info (EvJobRender *job, GdkColor *text, GdkColor *base) { - job->flags |= EV_RENDER_INCLUDE_SELECTION; - + job->include_selection = TRUE; + job->selection_points = *selection_points; job->selection_style = selection_style; job->text = *text; job->base = *base; } +/* EvJobPageData */ +static void +ev_job_page_data_init (EvJobPageData *job) +{ + EV_JOB (job)->run_mode = EV_JOB_RUN_THREAD; +} + +static gboolean +ev_job_page_data_run (EvJob *job) +{ + EvJobPageData *job_pd = EV_JOB_PAGE_DATA (job); + EvPage *ev_page; + + ev_debug_message (DEBUG_JOBS, "page: %d (%p)", job_pd->page, job); + ev_profiler_start (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job); + + ev_document_doc_mutex_lock (); + ev_page = ev_document_get_page (job->document, job_pd->page); + + if ((job_pd->flags & EV_PAGE_DATA_INCLUDE_TEXT_MAPPING) && EV_IS_DOCUMENT_TEXT (job->document)) + job_pd->text_mapping = + ev_document_text_get_text_mapping (EV_DOCUMENT_TEXT (job->document), ev_page); + if ((job_pd->flags & EV_PAGE_DATA_INCLUDE_TEXT) && EV_IS_DOCUMENT_TEXT (job->document)) + job_pd->text = + ev_document_text_get_text (EV_DOCUMENT_TEXT (job->document), ev_page); + if ((job_pd->flags & EV_PAGE_DATA_INCLUDE_TEXT_LAYOUT) && EV_IS_DOCUMENT_TEXT (job->document)) + ev_document_text_get_text_layout (EV_DOCUMENT_TEXT (job->document), + ev_page, + &(job_pd->text_layout), + &(job_pd->text_layout_length)); + if ((job_pd->flags & EV_PAGE_DATA_INCLUDE_LINKS) && EV_IS_DOCUMENT_LINKS (job->document)) + job_pd->link_mapping = + ev_document_links_get_links (EV_DOCUMENT_LINKS (job->document), ev_page); + if ((job_pd->flags & EV_PAGE_DATA_INCLUDE_FORMS) && EV_IS_DOCUMENT_FORMS (job->document)) + job_pd->form_field_mapping = + ev_document_forms_get_form_fields (EV_DOCUMENT_FORMS (job->document), + ev_page); + if ((job_pd->flags & EV_PAGE_DATA_INCLUDE_IMAGES) && EV_IS_DOCUMENT_IMAGES (job->document)) + job_pd->image_mapping = + ev_document_images_get_image_mapping (EV_DOCUMENT_IMAGES (job->document), + ev_page); + if ((job_pd->flags & EV_PAGE_DATA_INCLUDE_ANNOTS) && EV_IS_DOCUMENT_ANNOTATIONS (job->document)) + job_pd->annot_mapping = + ev_document_annotations_get_annotations (EV_DOCUMENT_ANNOTATIONS (job->document), + ev_page); + g_object_unref (ev_page); + ev_document_doc_mutex_unlock (); + + ev_job_succeeded (job); + + return FALSE; +} + +static void +ev_job_page_data_class_init (EvJobPageDataClass *class) +{ + EvJobClass *job_class = EV_JOB_CLASS (class); + + job_class->run = ev_job_page_data_run; +} + +EvJob * +ev_job_page_data_new (EvDocument *document, + gint page, + EvJobPageDataFlags flags) +{ + EvJobPageData *job; + + ev_debug_message (DEBUG_JOBS, "%d", page); + + job = g_object_new (EV_TYPE_JOB_PAGE_DATA, NULL); + + EV_JOB (job)->document = g_object_ref (document); + job->page = page; + job->flags = flags; + + return EV_JOB (job); +} + /* EvJobThumbnail */ static void ev_job_thumbnail_init (EvJobThumbnail *job) @@ -666,6 +764,7 @@ ev_job_thumbnail_run (EvJob *job) { EvJobThumbnail *job_thumb = EV_JOB_THUMBNAIL (job); EvRenderContext *rc; + GdkPixbuf *pixbuf; EvPage *page; ev_debug_message (DEBUG_JOBS, "%d (%p)", job_thumb->page, job); @@ -677,11 +776,13 @@ ev_job_thumbnail_run (EvJob *job) rc = ev_render_context_new (page, job_thumb->rotation, job_thumb->scale); g_object_unref (page); - job_thumb->thumbnail = ev_document_thumbnails_get_thumbnail (EV_DOCUMENT_THUMBNAILS (job->document), - rc, TRUE); + pixbuf = ev_document_get_thumbnail (job->document, rc); g_object_unref (rc); ev_document_doc_mutex_unlock (); + job_thumb->thumbnail = ev_document_misc_get_thumbnail_frame (-1, -1, pixbuf); + g_object_unref (pixbuf); + ev_job_succeeded (job); return FALSE; @@ -832,6 +933,8 @@ ev_job_load_run (EvJob *job) because, e.g., a password is required - if so, just reload rather than creating a new instance */ if (job->document) { + const gchar *uncompressed_uri; + if (job_load->password) { ev_document_security_set_password (EV_DOCUMENT_SECURITY (job->document), job_load->password); @@ -840,9 +943,11 @@ ev_job_load_run (EvJob *job) job->failed = FALSE; job->finished = FALSE; g_clear_error (&job->error); - + + uncompressed_uri = g_object_get_data (G_OBJECT (job->document), + "uri-uncompressed"); ev_document_load (job->document, - job_load->uri, + uncompressed_uri ? uncompressed_uri : job_load->uri, &error); } else { job->document = ev_document_factory_get_document (job_load->uri, @@ -936,31 +1041,17 @@ ev_job_save_run (EvJob *job) { EvJobSave *job_save = EV_JOB_SAVE (job); gint fd; - gchar *filename; - gchar *tmp_filename; + gchar *tmp_filename = NULL; gchar *local_uri; GError *error = NULL; ev_debug_message (DEBUG_JOBS, "uri: %s, document_uri: %s", job_save->uri, job_save->document_uri); ev_profiler_start (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job); - - filename = ev_tmp_filename ("saveacopy"); - tmp_filename = g_strdup_printf ("%s.XXXXXX", filename); - g_free (filename); - - fd = g_mkstemp (tmp_filename); - if (fd == -1) { - gchar *display_name; - gint save_errno = errno; - display_name = g_filename_display_name (tmp_filename); - ev_job_failed (job, - G_FILE_ERROR, - g_file_error_from_errno (save_errno), - _("Failed to create file “%s”: %s"), - display_name, g_strerror (save_errno)); - g_free (display_name); - g_free (tmp_filename); + fd = ev_mkstemp ("saveacopy.XXXXXX", &tmp_filename, &error); + if (fd == -1) { + ev_job_failed_from_error (job, error); + g_error_free (error); return FALSE; } @@ -968,8 +1059,11 @@ ev_job_save_run (EvJob *job) ev_document_doc_mutex_lock (); /* Save document to temp filename */ - local_uri = g_filename_to_uri (tmp_filename, NULL, NULL); - ev_document_save (job->document, local_uri, &error); + local_uri = g_filename_to_uri (tmp_filename, NULL, &error); + if (local_uri != NULL) { + ev_document_save (job->document, local_uri, &error); + } + close (fd); ev_document_doc_mutex_unlock (); @@ -1000,7 +1094,7 @@ ev_job_save_run (EvJob *job) uri_comp = ev_file_compress (local_uri, ctype, &error); g_free (local_uri); - ev_tmp_filename_unlink (tmp_filename); + g_unlink (tmp_filename); if (!uri_comp || error) { local_uri = NULL; @@ -1010,7 +1104,7 @@ ev_job_save_run (EvJob *job) } g_free (tmp_filename); - + if (error) { g_free (local_uri); ev_job_failed_from_error (job, error); @@ -1086,7 +1180,7 @@ ev_job_find_dispose (GObject *object) gint i; for (i = 0; i < job->n_pages; i++) { - g_list_foreach (job->pages[i], (GFunc)g_free, NULL); + g_list_foreach (job->pages[i], (GFunc)ev_rectangle_free, NULL); g_list_free (job->pages[i]); }