mirror of
https://gitlab.gnome.org/GNOME/evince
synced 2024-07-05 00:59:07 +00:00
[libview] Split EvPixbufCache into dynamic and static data
Dynamic page data (page surfaces and selections) that depend on current scale/rotation, keep in EvPixbufCache with the current cache approach. Static page data (links, annots, images, text and forms) that don't depend on current scale/rotation, have been moved to EvPageCache and they are never removed from the cache. Fixes bgo#602405.
This commit is contained in:
parent
ef00f8a39f
commit
3a8589a7c5
|
@ -13,7 +13,7 @@ ev_job_layers_get_type
|
|||
ev_job_export_get_type
|
||||
ev_view_get_type
|
||||
ev_job_run_mode_get_type
|
||||
ev_render_flags_get_type
|
||||
ev_job_page_data_flags_get_type
|
||||
ev_job_priority_get_type
|
||||
ev_sizing_mode_get_type
|
||||
ev_view_selection_mode_get_type
|
||||
|
|
|
@ -2,6 +2,7 @@ lib_LTLIBRARIES = libevview.la
|
|||
|
||||
NOINST_H_FILES = \
|
||||
ev-annotation-window.h \
|
||||
ev-page-cache.h \
|
||||
ev-pixbuf-cache.h \
|
||||
ev-timeline.h \
|
||||
ev-transition-animation.h \
|
||||
|
@ -25,6 +26,7 @@ libevview_la_SOURCES = \
|
|||
ev-document-model.c \
|
||||
ev-jobs.c \
|
||||
ev-job-scheduler.c \
|
||||
ev-page-cache.c \
|
||||
ev-pixbuf-cache.c \
|
||||
ev-stock-icons.c \
|
||||
ev-timeline.c \
|
||||
|
|
|
@ -51,6 +51,8 @@ static void ev_job_attachments_init (EvJobAttachments *job);
|
|||
static void ev_job_attachments_class_init (EvJobAttachmentsClass *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 +74,6 @@ enum {
|
|||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
enum {
|
||||
PAGE_READY,
|
||||
RENDER_LAST_SIGNAL
|
||||
};
|
||||
|
||||
enum {
|
||||
FONTS_UPDATED,
|
||||
FONTS_LAST_SIGNAL
|
||||
|
@ -88,7 +85,6 @@ 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 };
|
||||
|
||||
|
@ -96,6 +92,7 @@ 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 (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)
|
||||
|
@ -475,33 +472,6 @@ ev_job_render_dispose (GObject *object)
|
|||
(* 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)
|
||||
{
|
||||
|
@ -531,8 +501,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 +517,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), job_render->ev_page);
|
||||
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 +533,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 +541,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 +557,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 +568,85 @@ 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) && EV_IS_SELECTION (job->document))
|
||||
job_pd->text_mapping =
|
||||
ev_selection_get_selection_map (EV_SELECTION (job->document), ev_page);
|
||||
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), job_pd->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),
|
||||
job_pd->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)
|
||||
|
|
|
@ -39,6 +39,9 @@ typedef struct _EvJobClass EvJobClass;
|
|||
typedef struct _EvJobRender EvJobRender;
|
||||
typedef struct _EvJobRenderClass EvJobRenderClass;
|
||||
|
||||
typedef struct _EvJobPageData EvJobPageData;
|
||||
typedef struct _EvJobPageDataClass EvJobPageDataClass;
|
||||
|
||||
typedef struct _EvJobThumbnail EvJobThumbnail;
|
||||
typedef struct _EvJobThumbnailClass EvJobThumbnailClass;
|
||||
|
||||
|
@ -90,6 +93,11 @@ typedef struct _EvJobPrintClass EvJobPrintClass;
|
|||
#define EV_JOB_RENDER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_JOB_RENDER, EvJobRenderClass))
|
||||
#define EV_IS_JOB_RENDER(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_JOB_RENDER))
|
||||
|
||||
#define EV_TYPE_JOB_PAGE_DATA (ev_job_page_data_get_type())
|
||||
#define EV_JOB_PAGE_DATA(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_JOB_PAGE_DATA, EvJobPageData))
|
||||
#define EV_JOB_PAGE_DATA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_JOB_PAGE_DATA, EvJobPageDataClass))
|
||||
#define EV_IS_JOB_PAGE_DATA(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_JOB_PAGE_DATA))
|
||||
|
||||
#define EV_TYPE_JOB_THUMBNAIL (ev_job_thumbnail_get_type())
|
||||
#define EV_JOB_THUMBNAIL(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_JOB_THUMBNAIL, EvJobThumbnail))
|
||||
#define EV_JOB_THUMBNAIL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_JOB_THUMBNAIL, EvJobThumbnailClass))
|
||||
|
@ -189,17 +197,6 @@ struct _EvJobAttachmentsClass
|
|||
EvJobClass parent_class;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
EV_RENDER_INCLUDE_NONE = 0,
|
||||
EV_RENDER_INCLUDE_LINKS = 1 << 0,
|
||||
EV_RENDER_INCLUDE_TEXT = 1 << 1,
|
||||
EV_RENDER_INCLUDE_SELECTION = 1 << 2,
|
||||
EV_RENDER_INCLUDE_IMAGES = 1 << 3,
|
||||
EV_RENDER_INCLUDE_FORMS = 1 << 4,
|
||||
EV_RENDER_INCLUDE_ANNOTS = 1 << 5,
|
||||
EV_RENDER_INCLUDE_ALL = (1 << 6) - 1
|
||||
} EvRenderFlags;
|
||||
|
||||
struct _EvJobRender
|
||||
{
|
||||
EvJob parent;
|
||||
|
@ -214,27 +211,47 @@ struct _EvJobRender
|
|||
gint target_height;
|
||||
cairo_surface_t *surface;
|
||||
|
||||
GList *link_mapping;
|
||||
GdkRegion *text_mapping;
|
||||
GList *image_mapping;
|
||||
GList *form_field_mapping;
|
||||
GList *annots_mapping;
|
||||
|
||||
gboolean include_selection;
|
||||
cairo_surface_t *selection;
|
||||
GdkRegion *selection_region;
|
||||
EvRectangle selection_points;
|
||||
EvSelectionStyle selection_style;
|
||||
GdkColor base;
|
||||
GdkColor text;
|
||||
|
||||
EvRenderFlags flags;
|
||||
GdkColor text;
|
||||
};
|
||||
|
||||
struct _EvJobRenderClass
|
||||
{
|
||||
EvJobClass parent_class;
|
||||
};
|
||||
|
||||
void (* page_ready) (EvJobRender *job);
|
||||
typedef enum {
|
||||
EV_PAGE_DATA_INCLUDE_NONE = 0,
|
||||
EV_PAGE_DATA_INCLUDE_LINKS = 1 << 0,
|
||||
EV_PAGE_DATA_INCLUDE_TEXT = 1 << 1,
|
||||
EV_PAGE_DATA_INCLUDE_IMAGES = 1 << 2,
|
||||
EV_PAGE_DATA_INCLUDE_FORMS = 1 << 3,
|
||||
EV_PAGE_DATA_INCLUDE_ANNOTS = 1 << 4,
|
||||
EV_PAGE_DATA_INCLUDE_ALL = (1 << 5) - 1
|
||||
} EvJobPageDataFlags;
|
||||
|
||||
struct _EvJobPageData
|
||||
{
|
||||
EvJob parent;
|
||||
|
||||
gint page;
|
||||
EvJobPageDataFlags flags;
|
||||
|
||||
GList *link_mapping;
|
||||
GList *image_mapping;
|
||||
GList *form_field_mapping;
|
||||
GList *annot_mapping;
|
||||
GdkRegion *text_mapping;
|
||||
};
|
||||
|
||||
struct _EvJobPageDataClass
|
||||
{
|
||||
EvJobClass parent_class;
|
||||
};
|
||||
|
||||
struct _EvJobThumbnail
|
||||
|
@ -387,13 +404,18 @@ EvJob *ev_job_render_new (EvDocument *document,
|
|||
gint rotation,
|
||||
gdouble scale,
|
||||
gint width,
|
||||
gint height,
|
||||
EvRenderFlags flags);
|
||||
gint height);
|
||||
void ev_job_render_set_selection_info (EvJobRender *job,
|
||||
EvRectangle *selection_points,
|
||||
EvSelectionStyle selection_style,
|
||||
GdkColor *text,
|
||||
GdkColor *base);
|
||||
/* EvJobPageData */
|
||||
GType ev_job_page_data_get_type (void) G_GNUC_CONST;
|
||||
EvJob *ev_job_page_data_new (EvDocument *document,
|
||||
gint page,
|
||||
EvJobPageDataFlags flags);
|
||||
|
||||
/* EvJobThumbnail */
|
||||
GType ev_job_thumbnail_get_type (void) G_GNUC_CONST;
|
||||
EvJob *ev_job_thumbnail_new (EvDocument *document,
|
||||
|
|
330
libview/ev-page-cache.c
Normal file
330
libview/ev-page-cache.c
Normal file
|
@ -0,0 +1,330 @@
|
|||
/* this file is part of evince, a gnome document viewer
|
||||
*
|
||||
* Copyright (C) 2009 Carlos Garcia Campos
|
||||
*
|
||||
* Evince is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Evince 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
|
||||
* General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "ev-jobs.h"
|
||||
#include "ev-job-scheduler.h"
|
||||
#include "ev-mapping.h"
|
||||
#include "ev-selection.h"
|
||||
#include "ev-document-links.h"
|
||||
#include "ev-document-forms.h"
|
||||
#include "ev-document-images.h"
|
||||
#include "ev-document-annotations.h"
|
||||
#include "ev-page-cache.h"
|
||||
|
||||
typedef struct _EvPageCacheData {
|
||||
EvJob *job;
|
||||
gboolean done : 1;
|
||||
|
||||
GList *link_mapping;
|
||||
GList *image_mapping;
|
||||
GList *form_field_mapping;
|
||||
GList *annot_mapping;
|
||||
GdkRegion *text_mapping;
|
||||
} EvPageCacheData;
|
||||
|
||||
struct _EvPageCache {
|
||||
GObject parent;
|
||||
|
||||
EvDocument *document;
|
||||
EvPageCacheData *page_list;
|
||||
gint n_pages;
|
||||
EvJobPageDataFlags flags;
|
||||
};
|
||||
|
||||
struct _EvPageCacheClass {
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
static void job_page_data_finished_cb (EvJob *job,
|
||||
EvPageCache *cache);
|
||||
|
||||
G_DEFINE_TYPE (EvPageCache, ev_page_cache, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
ev_page_cache_data_free (EvPageCacheData *data)
|
||||
{
|
||||
if (data->job) {
|
||||
g_object_unref (data->job);
|
||||
data->job = NULL;
|
||||
}
|
||||
|
||||
if (data->link_mapping) {
|
||||
ev_mapping_list_free (data->link_mapping, g_object_unref);
|
||||
data->link_mapping = NULL;
|
||||
}
|
||||
|
||||
if (data->image_mapping) {
|
||||
ev_mapping_list_free (data->image_mapping, g_object_unref);
|
||||
data->image_mapping = NULL;
|
||||
}
|
||||
|
||||
if (data->form_field_mapping) {
|
||||
ev_mapping_list_free (data->form_field_mapping, g_object_unref);
|
||||
data->form_field_mapping = NULL;
|
||||
}
|
||||
|
||||
if (data->annot_mapping) {
|
||||
ev_mapping_list_free (data->annot_mapping, g_object_unref);
|
||||
data->annot_mapping = NULL;
|
||||
}
|
||||
|
||||
if (data->text_mapping) {
|
||||
gdk_region_destroy (data->text_mapping);
|
||||
data->text_mapping = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ev_page_cache_finalize (GObject *object)
|
||||
{
|
||||
EvPageCache *cache = EV_PAGE_CACHE (object);
|
||||
gint i;
|
||||
|
||||
if (cache->page_list) {
|
||||
for (i = 0; i < cache->n_pages; i++) {
|
||||
EvPageCacheData *data;
|
||||
|
||||
data = &cache->page_list[i];
|
||||
|
||||
if (data->job)
|
||||
g_signal_handlers_disconnect_by_func (data->job,
|
||||
G_CALLBACK (job_page_data_finished_cb),
|
||||
cache);
|
||||
ev_page_cache_data_free (data);
|
||||
}
|
||||
|
||||
g_free (cache->page_list);
|
||||
cache->page_list = NULL;
|
||||
cache->n_pages = 0;
|
||||
}
|
||||
|
||||
if (cache->document) {
|
||||
g_object_unref (cache->document);
|
||||
cache->document = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (ev_page_cache_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
ev_page_cache_init (EvPageCache *cache)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
ev_page_cache_class_init (EvPageCacheClass *klass)
|
||||
{
|
||||
GObjectClass *g_object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
g_object_class->finalize = ev_page_cache_finalize;
|
||||
}
|
||||
|
||||
static EvJobPageDataFlags
|
||||
get_flags_for_document (EvDocument *document)
|
||||
{
|
||||
EvJobPageDataFlags flags = EV_PAGE_DATA_INCLUDE_NONE;
|
||||
|
||||
if (EV_IS_DOCUMENT_LINKS (document))
|
||||
flags |= EV_PAGE_DATA_INCLUDE_LINKS;
|
||||
if (EV_IS_DOCUMENT_IMAGES (document))
|
||||
flags |= EV_PAGE_DATA_INCLUDE_IMAGES;
|
||||
if (EV_IS_DOCUMENT_FORMS (document))
|
||||
flags |= EV_PAGE_DATA_INCLUDE_FORMS;
|
||||
if (EV_IS_DOCUMENT_ANNOTATIONS (document))
|
||||
flags |= EV_PAGE_DATA_INCLUDE_ANNOTS;
|
||||
if (EV_IS_SELECTION (document))
|
||||
flags |= EV_PAGE_DATA_INCLUDE_TEXT;
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
EvPageCache *
|
||||
ev_page_cache_new (EvDocument *document)
|
||||
{
|
||||
EvPageCache *cache;
|
||||
|
||||
g_return_val_if_fail (EV_IS_DOCUMENT (document), NULL);
|
||||
|
||||
cache = EV_PAGE_CACHE (g_object_new (EV_TYPE_PAGE_CACHE, NULL));
|
||||
cache->document = g_object_ref (document);
|
||||
cache->n_pages = ev_document_get_n_pages (document);
|
||||
cache->flags = get_flags_for_document (document);
|
||||
|
||||
if (cache->flags != EV_PAGE_DATA_INCLUDE_NONE) {
|
||||
cache->page_list = g_new0 (EvPageCacheData, cache->n_pages);
|
||||
}
|
||||
|
||||
return cache;
|
||||
}
|
||||
|
||||
static void
|
||||
job_page_data_finished_cb (EvJob *job,
|
||||
EvPageCache *cache)
|
||||
{
|
||||
EvJobPageData *job_data = EV_JOB_PAGE_DATA (job);
|
||||
EvPageCacheData *data;
|
||||
|
||||
data = &cache->page_list[job_data->page];
|
||||
data->link_mapping = job_data->link_mapping;
|
||||
data->image_mapping = job_data->image_mapping;
|
||||
data->form_field_mapping = job_data->form_field_mapping;
|
||||
data->annot_mapping = job_data->annot_mapping;
|
||||
data->text_mapping = job_data->text_mapping;
|
||||
data->done = TRUE;
|
||||
|
||||
g_object_unref (data->job);
|
||||
data->job = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
ev_page_cache_set_page_range (EvPageCache *cache,
|
||||
gint start,
|
||||
gint end)
|
||||
{
|
||||
gint i;
|
||||
|
||||
if (cache->flags == EV_PAGE_DATA_INCLUDE_NONE)
|
||||
return;
|
||||
|
||||
for (i = start; i <= end; i++) {
|
||||
EvPageCacheData *data = &cache->page_list[i];
|
||||
|
||||
if (data->done || data->job)
|
||||
continue;
|
||||
|
||||
data->job = ev_job_page_data_new (cache->document, i, cache->flags);
|
||||
g_signal_connect (data->job, "finished",
|
||||
G_CALLBACK (job_page_data_finished_cb),
|
||||
cache);
|
||||
ev_job_scheduler_push_job (data->job, EV_JOB_PRIORITY_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
GList *
|
||||
ev_page_cache_get_link_mapping (EvPageCache *cache,
|
||||
gint page)
|
||||
{
|
||||
EvPageCacheData *data;
|
||||
|
||||
g_return_val_if_fail (EV_IS_PAGE_CACHE (cache), NULL);
|
||||
g_return_val_if_fail (page >= 0 && page < cache->n_pages, NULL);
|
||||
|
||||
if (!(cache->flags & EV_PAGE_DATA_INCLUDE_LINKS))
|
||||
return NULL;
|
||||
|
||||
data = &cache->page_list[page];
|
||||
if (data->done)
|
||||
return data->link_mapping;
|
||||
|
||||
if (data->job)
|
||||
return EV_JOB_PAGE_DATA (data->job)->link_mapping;
|
||||
|
||||
return data->link_mapping;
|
||||
}
|
||||
|
||||
GList *
|
||||
ev_page_cache_get_image_mapping (EvPageCache *cache,
|
||||
gint page)
|
||||
{
|
||||
EvPageCacheData *data;
|
||||
|
||||
g_return_val_if_fail (EV_IS_PAGE_CACHE (cache), NULL);
|
||||
g_return_val_if_fail (page >= 0 && page < cache->n_pages, NULL);
|
||||
|
||||
if (!(cache->flags & EV_PAGE_DATA_INCLUDE_IMAGES))
|
||||
return NULL;
|
||||
|
||||
data = &cache->page_list[page];
|
||||
if (data->done)
|
||||
return data->image_mapping;
|
||||
|
||||
if (data->job)
|
||||
return EV_JOB_PAGE_DATA (data->job)->image_mapping;
|
||||
|
||||
return data->image_mapping;
|
||||
}
|
||||
|
||||
GList *
|
||||
ev_page_cache_get_form_field_mapping (EvPageCache *cache,
|
||||
gint page)
|
||||
{
|
||||
EvPageCacheData *data;
|
||||
|
||||
g_return_val_if_fail (EV_IS_PAGE_CACHE (cache), NULL);
|
||||
g_return_val_if_fail (page >= 0 && page < cache->n_pages, NULL);
|
||||
|
||||
if (!(cache->flags & EV_PAGE_DATA_INCLUDE_FORMS))
|
||||
return NULL;
|
||||
|
||||
data = &cache->page_list[page];
|
||||
if (data->done)
|
||||
return data->form_field_mapping;
|
||||
|
||||
if (data->job)
|
||||
return EV_JOB_PAGE_DATA (data->job)->form_field_mapping;
|
||||
|
||||
return data->form_field_mapping;
|
||||
}
|
||||
|
||||
GList *
|
||||
ev_page_cache_get_annot_mapping (EvPageCache *cache,
|
||||
gint page)
|
||||
{
|
||||
EvPageCacheData *data;
|
||||
|
||||
g_return_val_if_fail (EV_IS_PAGE_CACHE (cache), NULL);
|
||||
g_return_val_if_fail (page >= 0 && page < cache->n_pages, NULL);
|
||||
|
||||
if (!(cache->flags & EV_PAGE_DATA_INCLUDE_ANNOTS))
|
||||
return NULL;
|
||||
|
||||
data = &cache->page_list[page];
|
||||
if (data->done)
|
||||
return data->annot_mapping;
|
||||
|
||||
if (data->job)
|
||||
return EV_JOB_PAGE_DATA (data->job)->annot_mapping;
|
||||
|
||||
return data->annot_mapping;
|
||||
}
|
||||
|
||||
GdkRegion *
|
||||
ev_page_cache_get_text_mapping (EvPageCache *cache,
|
||||
gint page)
|
||||
{
|
||||
EvPageCacheData *data;
|
||||
|
||||
g_return_val_if_fail (EV_IS_PAGE_CACHE (cache), NULL);
|
||||
g_return_val_if_fail (page >= 0 && page < cache->n_pages, NULL);
|
||||
|
||||
if (!(cache->flags & EV_PAGE_DATA_INCLUDE_TEXT))
|
||||
return NULL;
|
||||
|
||||
data = &cache->page_list[page];
|
||||
if (data->done)
|
||||
return data->text_mapping;
|
||||
|
||||
if (data->job)
|
||||
return EV_JOB_PAGE_DATA (data->job)->text_mapping;
|
||||
|
||||
return data->text_mapping;
|
||||
}
|
||||
|
59
libview/ev-page-cache.h
Normal file
59
libview/ev-page-cache.h
Normal file
|
@ -0,0 +1,59 @@
|
|||
/* this file is part of evince, a gnome document viewer
|
||||
*
|
||||
* Copyright (C) 2009 Carlos Garcia Campos
|
||||
*
|
||||
* Evince is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Evince 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
|
||||
* General Public License for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if !defined (__EV_EVINCE_VIEW_H_INSIDE__) && !defined (EVINCE_COMPILATION)
|
||||
#error "Only <evince-view.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef EV_PAGE_CACHE_H
|
||||
#define EV_PAGE_CACHE_H
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <gdk/gdk.h>
|
||||
#include <evince-document.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define EV_TYPE_PAGE_CACHE (ev_page_cache_get_type ())
|
||||
#define EV_PAGE_CACHE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EV_TYPE_PAGE_CACHE, EvPageCache))
|
||||
#define EV_IS_PAGE_CACHE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EV_TYPE_PAGE_CACHE))
|
||||
|
||||
typedef struct _EvPageCache EvPageCache;
|
||||
typedef struct _EvPageCacheClass EvPageCacheClass;
|
||||
|
||||
GType ev_page_cache_get_type (void) G_GNUC_CONST;
|
||||
EvPageCache *ev_page_cache_new (EvDocument *document);
|
||||
|
||||
void ev_page_cache_set_page_range (EvPageCache *cache,
|
||||
gint start,
|
||||
gint end);
|
||||
GList *ev_page_cache_get_link_mapping (EvPageCache *cache,
|
||||
gint page);
|
||||
GList *ev_page_cache_get_image_mapping (EvPageCache *cache,
|
||||
gint page);
|
||||
GList *ev_page_cache_get_form_field_mapping (EvPageCache *cache,
|
||||
gint page);
|
||||
GList *ev_page_cache_get_annot_mapping (EvPageCache *cache,
|
||||
gint page);
|
||||
GdkRegion *ev_page_cache_get_text_mapping (EvPageCache *cache,
|
||||
gint page);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* EV_PAGE_CACHE_H */
|
|
@ -18,12 +18,7 @@ typedef struct _CacheJobInfo
|
|||
|
||||
/* Data we get from rendering */
|
||||
cairo_surface_t *surface;
|
||||
GList *link_mapping;
|
||||
GList *image_mapping;
|
||||
GList *form_field_mapping;
|
||||
GList *annots_mapping;
|
||||
GdkRegion *text_mapping;
|
||||
|
||||
|
||||
/* Selection data.
|
||||
* Selection_points are the coordinates encapsulated in selection.
|
||||
* target_points is the target selection size. */
|
||||
|
@ -77,18 +72,10 @@ static void ev_pixbuf_cache_init (EvPixbufCache *pixbuf_cach
|
|||
static void ev_pixbuf_cache_class_init (EvPixbufCacheClass *pixbuf_cache);
|
||||
static void ev_pixbuf_cache_finalize (GObject *object);
|
||||
static void ev_pixbuf_cache_dispose (GObject *object);
|
||||
static void job_page_ready_cb (EvJob *job,
|
||||
EvPixbufCache *pixbuf_cache);
|
||||
static void job_finished_cb (EvJob *job,
|
||||
EvPixbufCache *pixbuf_cache);
|
||||
static CacheJobInfo *find_job_cache (EvPixbufCache *pixbuf_cache,
|
||||
int page);
|
||||
static void copy_job_to_job_info (EvJobRender *job_render,
|
||||
CacheJobInfo *job_info,
|
||||
EvPixbufCache *pixbuf_cache);
|
||||
static void copy_job_page_and_selection_to_job_info (EvJobRender *job_render,
|
||||
CacheJobInfo *job_info,
|
||||
EvPixbufCache *pixbuf_cache);
|
||||
static gboolean new_selection_surface_needed(EvPixbufCache *pixbuf_cache,
|
||||
CacheJobInfo *job_info,
|
||||
gint page,
|
||||
|
@ -158,10 +145,8 @@ dispose_cache_job_info (CacheJobInfo *job_info,
|
|||
{
|
||||
if (job_info == NULL)
|
||||
return;
|
||||
|
||||
if (job_info->job) {
|
||||
g_signal_handlers_disconnect_by_func (job_info->job,
|
||||
G_CALLBACK (job_page_ready_cb),
|
||||
data);
|
||||
g_signal_handlers_disconnect_by_func (job_info->job,
|
||||
G_CALLBACK (job_finished_cb),
|
||||
data);
|
||||
|
@ -177,26 +162,6 @@ dispose_cache_job_info (CacheJobInfo *job_info,
|
|||
gdk_region_destroy (job_info->region);
|
||||
job_info->region = NULL;
|
||||
}
|
||||
if (job_info->link_mapping) {
|
||||
ev_mapping_list_free (job_info->link_mapping, g_object_unref);
|
||||
job_info->link_mapping = NULL;
|
||||
}
|
||||
if (job_info->image_mapping) {
|
||||
ev_mapping_list_free (job_info->image_mapping, g_object_unref);
|
||||
job_info->image_mapping = NULL;
|
||||
}
|
||||
if (job_info->form_field_mapping) {
|
||||
ev_mapping_list_free (job_info->form_field_mapping, g_object_unref);
|
||||
job_info->form_field_mapping = NULL;
|
||||
}
|
||||
if (job_info->annots_mapping) {
|
||||
ev_mapping_list_free (job_info->annots_mapping, g_object_unref);
|
||||
job_info->annots_mapping = NULL;
|
||||
}
|
||||
if (job_info->text_mapping) {
|
||||
gdk_region_destroy (job_info->text_mapping);
|
||||
job_info->text_mapping = NULL;
|
||||
}
|
||||
if (job_info->selection) {
|
||||
cairo_surface_destroy (job_info->selection);
|
||||
job_info->selection = NULL;
|
||||
|
@ -249,23 +214,56 @@ ev_pixbuf_cache_new (GtkWidget *view,
|
|||
}
|
||||
|
||||
static void
|
||||
job_page_ready_cb (EvJob *job,
|
||||
EvPixbufCache *pixbuf_cache)
|
||||
copy_job_to_job_info (EvJobRender *job_render,
|
||||
CacheJobInfo *job_info,
|
||||
EvPixbufCache *pixbuf_cache)
|
||||
{
|
||||
CacheJobInfo *job_info;
|
||||
EvJobRender *job_render = EV_JOB_RENDER (job);
|
||||
|
||||
/* If the job is outside of our interest, we silently discard it */
|
||||
if ((job_render->page < (pixbuf_cache->start_page - pixbuf_cache->preload_cache_size)) ||
|
||||
(job_render->page > (pixbuf_cache->end_page + pixbuf_cache->preload_cache_size))) {
|
||||
g_object_unref (job);
|
||||
return;
|
||||
if (job_info->rc == NULL) {
|
||||
job_info->rc = ev_render_context_new (job_render->ev_page,
|
||||
job_render->rotation,
|
||||
job_render->scale);
|
||||
} else {
|
||||
ev_render_context_set_page (job_info->rc, job_render->ev_page);
|
||||
ev_render_context_set_rotation (job_info->rc, job_render->rotation);
|
||||
ev_render_context_set_scale (job_info->rc, job_render->scale);
|
||||
}
|
||||
|
||||
job_info = find_job_cache (pixbuf_cache, job_render->page);
|
||||
if (job_info->surface) {
|
||||
cairo_surface_destroy (job_info->surface);
|
||||
}
|
||||
job_info->surface = cairo_surface_reference (job_render->surface);
|
||||
if (pixbuf_cache->inverted_colors) {
|
||||
ev_document_misc_invert_surface (job_info->surface);
|
||||
}
|
||||
|
||||
copy_job_page_and_selection_to_job_info (job_render, job_info, pixbuf_cache);
|
||||
g_signal_emit (pixbuf_cache, signals[JOB_FINISHED], 0, job_info->region);
|
||||
job_info->points_set = FALSE;
|
||||
if (job_render->include_selection) {
|
||||
if (job_info->selection) {
|
||||
cairo_surface_destroy (job_info->selection);
|
||||
job_info->selection = NULL;
|
||||
}
|
||||
if (job_info->selection_region) {
|
||||
gdk_region_destroy (job_info->selection_region);
|
||||
job_info->selection_region = NULL;
|
||||
}
|
||||
|
||||
job_info->selection_points = job_render->selection_points;
|
||||
job_info->selection_region = gdk_region_copy (job_render->selection_region);
|
||||
job_info->selection = cairo_surface_reference (job_render->selection);
|
||||
g_assert (job_info->selection_points.x1 >= 0);
|
||||
job_info->points_set = TRUE;
|
||||
}
|
||||
|
||||
if (job_info->job) {
|
||||
g_signal_handlers_disconnect_by_func (job_info->job,
|
||||
G_CALLBACK (job_finished_cb),
|
||||
pixbuf_cache);
|
||||
ev_job_cancel (job_info->job);
|
||||
g_object_unref (job_info->job);
|
||||
job_info->job = NULL;
|
||||
}
|
||||
|
||||
job_info->page_ready = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -283,7 +281,9 @@ job_finished_cb (EvJob *job,
|
|||
}
|
||||
|
||||
job_info = find_job_cache (pixbuf_cache, job_render->page);
|
||||
|
||||
copy_job_to_job_info (job_render, job_info, pixbuf_cache);
|
||||
g_signal_emit (pixbuf_cache, signals[JOB_FINISHED], 0, job_info->region);
|
||||
}
|
||||
|
||||
/* This checks a job to see if the job would generate the right sized pixbuf
|
||||
|
@ -310,9 +310,6 @@ check_job_size_and_unref (EvPixbufCache *pixbuf_cache,
|
|||
height == EV_JOB_RENDER (job_info->job)->target_height)
|
||||
return;
|
||||
|
||||
g_signal_handlers_disconnect_by_func (job_info->job,
|
||||
G_CALLBACK (job_page_ready_cb),
|
||||
pixbuf_cache);
|
||||
g_signal_handlers_disconnect_by_func (job_info->job,
|
||||
G_CALLBACK (job_finished_cb),
|
||||
pixbuf_cache);
|
||||
|
@ -372,10 +369,6 @@ move_one_job (CacheJobInfo *job_info,
|
|||
job_info->job = NULL;
|
||||
job_info->region = NULL;
|
||||
job_info->surface = NULL;
|
||||
job_info->link_mapping = NULL;
|
||||
job_info->image_mapping = NULL;
|
||||
job_info->form_field_mapping = NULL;
|
||||
job_info->annots_mapping = NULL;
|
||||
|
||||
if (new_priority != priority && target_page->job) {
|
||||
ev_job_scheduler_update_job (target_page->job, new_priority);
|
||||
|
@ -450,108 +443,6 @@ ev_pixbuf_cache_update_range (EvPixbufCache *pixbuf_cache,
|
|||
pixbuf_cache->end_page = end_page;
|
||||
}
|
||||
|
||||
static void
|
||||
copy_job_page_and_selection_to_job_info (EvJobRender *job_render,
|
||||
CacheJobInfo *job_info,
|
||||
EvPixbufCache *pixbuf_cache)
|
||||
{
|
||||
if (job_info->rc == NULL) {
|
||||
job_info->rc = ev_render_context_new (job_render->ev_page,
|
||||
job_render->rotation,
|
||||
job_render->scale);
|
||||
} else {
|
||||
ev_render_context_set_page (job_info->rc, job_render->ev_page);
|
||||
ev_render_context_set_rotation (job_info->rc, job_render->rotation);
|
||||
ev_render_context_set_scale (job_info->rc, job_render->scale);
|
||||
}
|
||||
|
||||
if (job_info->surface) {
|
||||
cairo_surface_destroy (job_info->surface);
|
||||
}
|
||||
job_info->surface = cairo_surface_reference (job_render->surface);
|
||||
if (pixbuf_cache->inverted_colors) {
|
||||
ev_document_misc_invert_surface (job_info->surface);
|
||||
}
|
||||
|
||||
job_info->points_set = FALSE;
|
||||
if (job_render->flags & EV_RENDER_INCLUDE_SELECTION) {
|
||||
if (job_info->selection) {
|
||||
cairo_surface_destroy (job_info->selection);
|
||||
job_info->selection = NULL;
|
||||
}
|
||||
if (job_info->selection_region) {
|
||||
gdk_region_destroy (job_info->selection_region);
|
||||
job_info->selection_region = NULL;
|
||||
}
|
||||
|
||||
job_info->selection_points = job_render->selection_points;
|
||||
job_info->selection_region = gdk_region_copy (job_render->selection_region);
|
||||
job_info->selection = cairo_surface_reference (job_render->selection);
|
||||
g_assert (job_info->selection_points.x1 >= 0);
|
||||
job_info->points_set = TRUE;
|
||||
}
|
||||
|
||||
if (job_info->job) {
|
||||
g_signal_handlers_disconnect_by_func (job_info->job,
|
||||
G_CALLBACK (job_page_ready_cb),
|
||||
pixbuf_cache);
|
||||
}
|
||||
|
||||
job_info->page_ready = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
copy_job_to_job_info (EvJobRender *job_render,
|
||||
CacheJobInfo *job_info,
|
||||
EvPixbufCache *pixbuf_cache)
|
||||
{
|
||||
if (!job_info->page_ready) {
|
||||
g_signal_emit (pixbuf_cache, signals[JOB_FINISHED], 0, job_info->region);
|
||||
copy_job_page_and_selection_to_job_info (job_render,
|
||||
job_info,
|
||||
pixbuf_cache);
|
||||
}
|
||||
|
||||
if (job_render->flags & EV_RENDER_INCLUDE_LINKS) {
|
||||
if (job_info->link_mapping)
|
||||
ev_mapping_list_free (job_info->link_mapping, g_object_unref);
|
||||
job_info->link_mapping = job_render->link_mapping;
|
||||
}
|
||||
|
||||
if (job_render->flags & EV_RENDER_INCLUDE_IMAGES) {
|
||||
if (job_info->image_mapping)
|
||||
ev_mapping_list_free (job_info->image_mapping, g_object_unref);
|
||||
job_info->image_mapping = job_render->image_mapping;
|
||||
}
|
||||
|
||||
if (job_render->flags & EV_RENDER_INCLUDE_FORMS) {
|
||||
if (job_info->form_field_mapping)
|
||||
ev_mapping_list_free (job_info->form_field_mapping, g_object_unref);
|
||||
job_info->form_field_mapping = job_render->form_field_mapping;
|
||||
}
|
||||
|
||||
if (job_render->flags & EV_RENDER_INCLUDE_ANNOTS) {
|
||||
if (job_info->annots_mapping)
|
||||
ev_mapping_list_free (job_info->annots_mapping, g_object_unref);
|
||||
job_info->annots_mapping = job_render->annots_mapping;
|
||||
}
|
||||
|
||||
if (job_render->flags & EV_RENDER_INCLUDE_TEXT) {
|
||||
if (job_info->text_mapping)
|
||||
gdk_region_destroy (job_info->text_mapping);
|
||||
job_info->text_mapping = job_render->text_mapping;
|
||||
}
|
||||
|
||||
if (job_info->job) {
|
||||
g_signal_handlers_disconnect_by_func (job_info->job,
|
||||
G_CALLBACK (job_finished_cb),
|
||||
pixbuf_cache);
|
||||
ev_job_cancel (job_info->job);
|
||||
g_object_unref (job_info->job);
|
||||
job_info->job = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static CacheJobInfo *
|
||||
find_job_cache (EvPixbufCache *pixbuf_cache,
|
||||
int page)
|
||||
|
@ -623,31 +514,16 @@ add_job (EvPixbufCache *pixbuf_cache,
|
|||
gfloat scale,
|
||||
EvJobPriority priority)
|
||||
{
|
||||
EvRenderFlags flags = 0;
|
||||
|
||||
job_info->page_ready = FALSE;
|
||||
|
||||
|
||||
if (job_info->region)
|
||||
gdk_region_destroy (job_info->region);
|
||||
job_info->region = region ? gdk_region_copy (region) : NULL;
|
||||
|
||||
/* Figure out what else we need for this job */
|
||||
if (job_info->link_mapping == NULL)
|
||||
flags |= EV_RENDER_INCLUDE_LINKS;
|
||||
if (job_info->image_mapping == NULL)
|
||||
flags |= EV_RENDER_INCLUDE_IMAGES;
|
||||
if (job_info->form_field_mapping == NULL)
|
||||
flags |= EV_RENDER_INCLUDE_FORMS;
|
||||
if (job_info->annots_mapping == NULL)
|
||||
flags |= EV_RENDER_INCLUDE_ANNOTS;
|
||||
if (job_info->text_mapping == NULL)
|
||||
flags |= EV_RENDER_INCLUDE_TEXT;
|
||||
|
||||
job_info->job = ev_job_render_new (pixbuf_cache->document,
|
||||
page, rotation, scale,
|
||||
width, height,
|
||||
flags);
|
||||
|
||||
width, height);
|
||||
|
||||
if (new_selection_surface_needed (pixbuf_cache, job_info, page, scale)) {
|
||||
GdkColor *text, *base;
|
||||
|
||||
|
@ -659,9 +535,6 @@ add_job (EvPixbufCache *pixbuf_cache,
|
|||
text, base);
|
||||
}
|
||||
|
||||
g_signal_connect (job_info->job, "page-ready",
|
||||
G_CALLBACK (job_page_ready_cb),
|
||||
pixbuf_cache);
|
||||
g_signal_connect (job_info->job, "finished",
|
||||
G_CALLBACK (job_finished_cb),
|
||||
pixbuf_cache);
|
||||
|
@ -807,102 +680,17 @@ ev_pixbuf_cache_get_surface (EvPixbufCache *pixbuf_cache,
|
|||
|
||||
if (job_info->page_ready)
|
||||
return job_info->surface;
|
||||
|
||||
|
||||
/* We don't need to wait for the idle to handle the callback */
|
||||
if (job_info->job &&
|
||||
EV_JOB_RENDER (job_info->job)->page_ready) {
|
||||
copy_job_page_and_selection_to_job_info (EV_JOB_RENDER (job_info->job), job_info, pixbuf_cache);
|
||||
copy_job_to_job_info (EV_JOB_RENDER (job_info->job), job_info, pixbuf_cache);
|
||||
g_signal_emit (pixbuf_cache, signals[JOB_FINISHED], 0, job_info->region);
|
||||
}
|
||||
|
||||
return job_info->surface;
|
||||
}
|
||||
|
||||
GList *
|
||||
ev_pixbuf_cache_get_link_mapping (EvPixbufCache *pixbuf_cache,
|
||||
gint page)
|
||||
{
|
||||
CacheJobInfo *job_info;
|
||||
|
||||
job_info = find_job_cache (pixbuf_cache, page);
|
||||
if (job_info == NULL)
|
||||
return NULL;
|
||||
|
||||
/* We don't need to wait for the idle to handle the callback */
|
||||
if (job_info->job &&
|
||||
EV_JOB (job_info->job)->finished) {
|
||||
copy_job_to_job_info (EV_JOB_RENDER (job_info->job), job_info, pixbuf_cache);
|
||||
}
|
||||
|
||||
return job_info->link_mapping;
|
||||
}
|
||||
|
||||
GList *
|
||||
ev_pixbuf_cache_get_image_mapping (EvPixbufCache *pixbuf_cache,
|
||||
gint page)
|
||||
{
|
||||
CacheJobInfo *job_info;
|
||||
|
||||
if (!EV_IS_DOCUMENT_IMAGES (pixbuf_cache->document))
|
||||
return NULL;
|
||||
|
||||
job_info = find_job_cache (pixbuf_cache, page);
|
||||
if (job_info == NULL)
|
||||
return NULL;
|
||||
|
||||
/* We don't need to wait for the idle to handle the callback */
|
||||
if (job_info->job &&
|
||||
EV_JOB (job_info->job)->finished) {
|
||||
copy_job_to_job_info (EV_JOB_RENDER (job_info->job), job_info, pixbuf_cache);
|
||||
}
|
||||
|
||||
return job_info->image_mapping;
|
||||
}
|
||||
|
||||
GList *
|
||||
ev_pixbuf_cache_get_form_field_mapping (EvPixbufCache *pixbuf_cache,
|
||||
gint page)
|
||||
{
|
||||
CacheJobInfo *job_info;
|
||||
|
||||
if (!EV_IS_DOCUMENT_FORMS (pixbuf_cache->document))
|
||||
return NULL;
|
||||
|
||||
job_info = find_job_cache (pixbuf_cache, page);
|
||||
if (job_info == NULL)
|
||||
return NULL;
|
||||
|
||||
/* We don't need to wait for the idle to handle the callback */
|
||||
if (job_info->job &&
|
||||
EV_JOB (job_info->job)->finished) {
|
||||
copy_job_to_job_info (EV_JOB_RENDER(job_info->job), job_info, pixbuf_cache);
|
||||
}
|
||||
|
||||
return job_info->form_field_mapping;
|
||||
}
|
||||
|
||||
GList *
|
||||
ev_pixbuf_cache_get_annots_mapping (EvPixbufCache *pixbuf_cache,
|
||||
gint page)
|
||||
{
|
||||
CacheJobInfo *job_info;
|
||||
|
||||
if (!EV_IS_DOCUMENT_ANNOTATIONS (pixbuf_cache->document))
|
||||
return NULL;
|
||||
|
||||
job_info = find_job_cache (pixbuf_cache, page);
|
||||
if (job_info == NULL)
|
||||
return NULL;
|
||||
|
||||
/* We don't need to wait for the idle to handle the callback */
|
||||
if (job_info->job &&
|
||||
EV_JOB (job_info->job)->finished) {
|
||||
copy_job_to_job_info (EV_JOB_RENDER (job_info->job), job_info, pixbuf_cache);
|
||||
}
|
||||
|
||||
return job_info->annots_mapping;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
new_selection_surface_needed (EvPixbufCache *pixbuf_cache,
|
||||
CacheJobInfo *job_info,
|
||||
|
@ -944,25 +732,6 @@ clear_selection_if_needed (EvPixbufCache *pixbuf_cache,
|
|||
}
|
||||
}
|
||||
|
||||
GdkRegion *
|
||||
ev_pixbuf_cache_get_text_mapping (EvPixbufCache *pixbuf_cache,
|
||||
gint page)
|
||||
{
|
||||
CacheJobInfo *job_info;
|
||||
|
||||
job_info = find_job_cache (pixbuf_cache, page);
|
||||
if (job_info == NULL)
|
||||
return NULL;
|
||||
|
||||
/* We don't need to wait for the idle to handle the callback */
|
||||
if (job_info->job &&
|
||||
EV_JOB (job_info->job)->finished) {
|
||||
copy_job_to_job_info (EV_JOB_RENDER (job_info->job), job_info, pixbuf_cache);
|
||||
}
|
||||
|
||||
return job_info->text_mapping;
|
||||
}
|
||||
|
||||
/* Clears the cache of jobs and pixbufs.
|
||||
*/
|
||||
void
|
||||
|
@ -1048,7 +817,7 @@ ev_pixbuf_cache_get_selection_surface (EvPixbufCache *pixbuf_cache,
|
|||
/* If we have a running job, we just return what we have under the
|
||||
* assumption that it'll be updated later and we can scale it as need
|
||||
* be */
|
||||
if (job_info->job && (EV_JOB_RENDER (job_info->job)->flags & EV_RENDER_INCLUDE_SELECTION))
|
||||
if (job_info->job && EV_JOB_RENDER (job_info->job)->include_selection)
|
||||
return job_info->selection;
|
||||
|
||||
/* Now, lets see if we need to resize the image. If we do, we clear the
|
||||
|
|
|
@ -64,16 +64,6 @@ void ev_pixbuf_cache_set_page_range (EvPixbufCache *pixbuf_cache
|
|||
GList *selection_list);
|
||||
cairo_surface_t *ev_pixbuf_cache_get_surface (EvPixbufCache *pixbuf_cache,
|
||||
gint page);
|
||||
GList *ev_pixbuf_cache_get_link_mapping (EvPixbufCache *pixbuf_cache,
|
||||
gint page);
|
||||
GList *ev_pixbuf_cache_get_image_mapping (EvPixbufCache *pixbuf_cache,
|
||||
gint page);
|
||||
GdkRegion *ev_pixbuf_cache_get_text_mapping (EvPixbufCache *pixbuf_cache,
|
||||
gint page);
|
||||
GList *ev_pixbuf_cache_get_form_field_mapping (EvPixbufCache *pixbuf_cache,
|
||||
gint page);
|
||||
GList *ev_pixbuf_cache_get_annots_mapping (EvPixbufCache *pixbuf_cache,
|
||||
gint page);
|
||||
void ev_pixbuf_cache_clear (EvPixbufCache *pixbuf_cache);
|
||||
void ev_pixbuf_cache_style_changed (EvPixbufCache *pixbuf_cache);
|
||||
void ev_pixbuf_cache_reload_page (EvPixbufCache *pixbuf_cache,
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "ev-view.h"
|
||||
#include "ev-document-model.h"
|
||||
#include "ev-pixbuf-cache.h"
|
||||
#include "ev-page-cache.h"
|
||||
#include "ev-jobs.h"
|
||||
#include "ev-image.h"
|
||||
#include "ev-form-field.h"
|
||||
|
@ -136,6 +137,7 @@ struct _EvView {
|
|||
|
||||
EvDocumentModel *model;
|
||||
EvPixbufCache *pixbuf_cache;
|
||||
EvPageCache *page_cache;
|
||||
EvHeightToPageCache *height_to_page_cache;
|
||||
EvViewCursor cursor;
|
||||
EvJobRender *current_job;
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "ev-document-misc.h"
|
||||
#include "ev-document-transition.h"
|
||||
#include "ev-pixbuf-cache.h"
|
||||
#include "ev-page-cache.h"
|
||||
#include "ev-transition-animation.h"
|
||||
#include "ev-view-marshal.h"
|
||||
#include "ev-document-annotations.h"
|
||||
|
@ -734,6 +735,9 @@ view_update_range_and_current_page (EvView *view)
|
|||
}
|
||||
}
|
||||
|
||||
ev_page_cache_set_page_range (view->page_cache,
|
||||
view->start_page,
|
||||
view->end_page);
|
||||
ev_pixbuf_cache_set_page_range (view->pixbuf_cache,
|
||||
view->start_page,
|
||||
view->end_page,
|
||||
|
@ -829,7 +833,7 @@ compute_scroll_increment (EvView *view,
|
|||
|
||||
page = scroll == GTK_SCROLL_PAGE_BACKWARD ? view->start_page : view->end_page;
|
||||
|
||||
text_region = ev_pixbuf_cache_get_text_mapping (view->pixbuf_cache, page);
|
||||
text_region = ev_page_cache_get_text_mapping (view->page_cache, page);
|
||||
if (!text_region || gdk_region_empty (text_region))
|
||||
return adjustment->page_size;
|
||||
|
||||
|
@ -1379,7 +1383,7 @@ location_in_text (EvView *view,
|
|||
if (page == -1)
|
||||
return FALSE;
|
||||
|
||||
region = ev_pixbuf_cache_get_text_mapping (view->pixbuf_cache, page);
|
||||
region = ev_page_cache_get_text_mapping (view->page_cache, page);
|
||||
|
||||
if (region)
|
||||
return gdk_region_point_in (region, x_offset / view->scale, y_offset / view->scale);
|
||||
|
@ -1514,7 +1518,7 @@ ev_view_get_link_at_location (EvView *view,
|
|||
if (!get_doc_point_from_location (view, x, y, &page, &x_new, &y_new))
|
||||
return NULL;
|
||||
|
||||
link_mapping = ev_pixbuf_cache_get_link_mapping (view->pixbuf_cache, page);
|
||||
link_mapping = ev_page_cache_get_link_mapping (view->page_cache, page);
|
||||
|
||||
if (link_mapping)
|
||||
return ev_mapping_list_get_data (link_mapping, x_new, y_new);
|
||||
|
@ -1932,7 +1936,7 @@ ev_view_get_image_at_location (EvView *view,
|
|||
if (!get_doc_point_from_location (view, x, y, &page, &x_new, &y_new))
|
||||
return NULL;
|
||||
|
||||
image_mapping = ev_pixbuf_cache_get_image_mapping (view->pixbuf_cache, page);
|
||||
image_mapping = ev_page_cache_get_image_mapping (view->page_cache, page);
|
||||
|
||||
if (image_mapping)
|
||||
return ev_mapping_list_get_data (image_mapping, x_new, y_new);
|
||||
|
@ -1956,7 +1960,7 @@ ev_view_get_form_field_at_location (EvView *view,
|
|||
if (!get_doc_point_from_location (view, x, y, &page, &x_new, &y_new))
|
||||
return NULL;
|
||||
|
||||
forms_mapping = ev_pixbuf_cache_get_form_field_mapping (view->pixbuf_cache, page);
|
||||
forms_mapping = ev_page_cache_get_form_field_mapping (view->page_cache, page);
|
||||
|
||||
if (forms_mapping)
|
||||
return ev_mapping_list_get_data (forms_mapping, x_new, y_new);
|
||||
|
@ -1971,8 +1975,8 @@ ev_view_form_field_get_region (EvView *view,
|
|||
GdkRectangle view_area;
|
||||
GList *forms_mapping;
|
||||
|
||||
forms_mapping = ev_pixbuf_cache_get_form_field_mapping (view->pixbuf_cache,
|
||||
field->page->index);
|
||||
forms_mapping = ev_page_cache_get_form_field_mapping (view->page_cache,
|
||||
field->page->index);
|
||||
ev_view_get_area_from_mapping (view, field->page->index,
|
||||
forms_mapping,
|
||||
field, &view_area);
|
||||
|
@ -2023,8 +2027,8 @@ ev_view_form_field_button_create_widget (EvView *view,
|
|||
/* For radio buttons and checkbox buttons that are in a set
|
||||
* we need to update also the region for the current selected item
|
||||
*/
|
||||
forms_mapping = ev_pixbuf_cache_get_form_field_mapping (view->pixbuf_cache,
|
||||
field->page->index);
|
||||
forms_mapping = ev_page_cache_get_form_field_mapping (view->page_cache,
|
||||
field->page->index);
|
||||
for (l = forms_mapping; l; l = g_list_next (l)) {
|
||||
EvFormField *button = ((EvMapping *)(l->data))->data;
|
||||
GdkRegion *button_region;
|
||||
|
@ -2407,7 +2411,8 @@ ev_view_handle_form_field (EvView *view,
|
|||
g_object_ref (field),
|
||||
(GDestroyNotify)g_object_unref);
|
||||
|
||||
form_field_mapping = ev_pixbuf_cache_get_form_field_mapping (view->pixbuf_cache, field->page->index);
|
||||
form_field_mapping = ev_page_cache_get_form_field_mapping (view->page_cache,
|
||||
field->page->index);
|
||||
ev_view_get_area_from_mapping (view, field->page->index,
|
||||
form_field_mapping,
|
||||
field, &view_area);
|
||||
|
@ -2631,7 +2636,7 @@ show_annotation_windows (EvView *view,
|
|||
|
||||
parent = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (view)));
|
||||
|
||||
annots = ev_pixbuf_cache_get_annots_mapping (view->pixbuf_cache, page);
|
||||
annots = ev_page_cache_get_annot_mapping (view->page_cache, page);
|
||||
|
||||
for (l = annots; l && l->data; l = g_list_next (l)) {
|
||||
EvAnnotation *annot;
|
||||
|
@ -2696,7 +2701,7 @@ hide_annotation_windows (EvView *view,
|
|||
{
|
||||
GList *annots, *l;
|
||||
|
||||
annots = ev_pixbuf_cache_get_annots_mapping (view->pixbuf_cache, page);
|
||||
annots = ev_page_cache_get_annot_mapping (view->page_cache, page);
|
||||
|
||||
for (l = annots; l && l->data; l = g_list_next (l)) {
|
||||
EvAnnotation *annot;
|
||||
|
@ -2728,7 +2733,7 @@ ev_view_get_annotation_at_location (EvView *view,
|
|||
if (!get_doc_point_from_location (view, x, y, &page, &x_new, &y_new))
|
||||
return NULL;
|
||||
|
||||
annotations_mapping = ev_pixbuf_cache_get_annots_mapping (view->pixbuf_cache, page);
|
||||
annotations_mapping = ev_page_cache_get_annot_mapping (view->page_cache, page);
|
||||
|
||||
if (annotations_mapping)
|
||||
return ev_mapping_list_get_data (annotations_mapping, x_new, y_new);
|
||||
|
@ -2965,8 +2970,8 @@ ev_view_size_allocate (GtkWidget *widget,
|
|||
if (!field)
|
||||
continue;
|
||||
|
||||
form_field_mapping = ev_pixbuf_cache_get_form_field_mapping (view->pixbuf_cache,
|
||||
field->page->index);
|
||||
form_field_mapping = ev_page_cache_get_form_field_mapping (view->page_cache,
|
||||
field->page->index);
|
||||
ev_view_get_area_from_mapping (view, field->page->index,
|
||||
form_field_mapping,
|
||||
field, &view_area);
|
||||
|
@ -3220,7 +3225,7 @@ ev_view_expose_event (GtkWidget *widget,
|
|||
return FALSE;
|
||||
|
||||
cr = gdk_cairo_create (view->layout.bin_window);
|
||||
|
||||
|
||||
for (i = view->start_page; i >= 0 && i <= view->end_page; i++) {
|
||||
GdkRectangle page_area;
|
||||
GtkBorder border;
|
||||
|
@ -3305,7 +3310,7 @@ get_link_area (EvView *view,
|
|||
|
||||
find_page_at_location (view, x, y, &page, &x_offset, &y_offset);
|
||||
|
||||
link_mapping = ev_pixbuf_cache_get_link_mapping (view->pixbuf_cache, page);
|
||||
link_mapping = ev_page_cache_get_link_mapping (view->page_cache, page);
|
||||
ev_view_get_area_from_mapping (view, page,
|
||||
link_mapping,
|
||||
link, area);
|
||||
|
@ -3318,7 +3323,7 @@ get_annot_area (EvView *view,
|
|||
EvAnnotation *annot,
|
||||
GdkRectangle *area)
|
||||
{
|
||||
GList *annots_mapping;
|
||||
GList *annot_mapping;
|
||||
gint page;
|
||||
gint x_offset = 0, y_offset = 0;
|
||||
|
||||
|
@ -3327,9 +3332,9 @@ get_annot_area (EvView *view,
|
|||
|
||||
find_page_at_location (view, x, y, &page, &x_offset, &y_offset);
|
||||
|
||||
annots_mapping = ev_pixbuf_cache_get_annots_mapping (view->pixbuf_cache, page);
|
||||
annot_mapping = ev_page_cache_get_annot_mapping (view->page_cache, page);
|
||||
ev_view_get_area_from_mapping (view, page,
|
||||
annots_mapping,
|
||||
annot_mapping,
|
||||
annot, area);
|
||||
}
|
||||
|
||||
|
@ -4565,6 +4570,11 @@ ev_view_destroy (GtkObject *object)
|
|||
view->pixbuf_cache = NULL;
|
||||
}
|
||||
|
||||
if (view->page_cache) {
|
||||
g_object_unref (view->page_cache);
|
||||
view->page_cache = NULL;
|
||||
}
|
||||
|
||||
if (view->goto_window) {
|
||||
gtk_widget_destroy (view->goto_window);
|
||||
view->goto_window = NULL;
|
||||
|
@ -5107,6 +5117,7 @@ setup_caches (EvView *view)
|
|||
|
||||
view->height_to_page_cache = ev_view_get_height_to_page_cache (view);
|
||||
view->pixbuf_cache = ev_pixbuf_cache_new (GTK_WIDGET (view), view->document);
|
||||
view->page_cache = ev_page_cache_new (view->document);
|
||||
inverted_colors = ev_document_model_get_inverted_colors (view->model);
|
||||
ev_pixbuf_cache_set_inverted_colors (view->pixbuf_cache, inverted_colors);
|
||||
g_signal_connect (view->pixbuf_cache, "job-finished", G_CALLBACK (job_finished_cb), view);
|
||||
|
@ -5119,6 +5130,11 @@ clear_caches (EvView *view)
|
|||
g_object_unref (view->pixbuf_cache);
|
||||
view->pixbuf_cache = NULL;
|
||||
}
|
||||
|
||||
if (view->page_cache) {
|
||||
g_object_unref (view->page_cache);
|
||||
view->page_cache = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
Loading…
Reference in New Issue
Block a user