Commit 3a8589a7 authored by Carlos Garcia Campos's avatar Carlos Garcia Campos

[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.
parent ef00f8a3
......@@ -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,
......
/* 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;
}
/* 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