1 /* this file is part of evince, a gnome document viewer
3 * Copyright (C) 2009 Carlos Garcia Campos
5 * Evince is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * Evince is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24 #include "ev-job-scheduler.h"
25 #include "ev-mapping-list.h"
26 #include "ev-selection.h"
27 #include "ev-document-links.h"
28 #include "ev-document-forms.h"
29 #include "ev-document-images.h"
30 #include "ev-document-annotations.h"
31 #include "ev-document-text.h"
32 #include "ev-page-cache.h"
34 typedef struct _EvPageCacheData {
37 EvJobPageDataFlags flags;
39 EvMappingList *link_mapping;
40 EvMappingList *image_mapping;
41 EvMappingList *form_field_mapping;
42 EvMappingList *annot_mapping;
43 cairo_region_t *text_mapping;
44 EvRectangle *text_layout;
45 guint text_layout_length;
53 EvPageCacheData *page_list;
60 EvJobPageDataFlags flags;
63 struct _EvPageCacheClass {
64 GObjectClass parent_class;
67 #define EV_PAGE_DATA_FLAGS_DEFAULT ( \
68 EV_PAGE_DATA_INCLUDE_LINKS | \
69 EV_PAGE_DATA_INCLUDE_TEXT_MAPPING | \
70 EV_PAGE_DATA_INCLUDE_IMAGES | \
71 EV_PAGE_DATA_INCLUDE_FORMS | \
72 EV_PAGE_DATA_INCLUDE_ANNOTS)
75 static void job_page_data_finished_cb (EvJob *job,
77 static void job_page_data_cancelled_cb (EvJob *job,
78 EvPageCacheData *data);
80 G_DEFINE_TYPE (EvPageCache, ev_page_cache, G_TYPE_OBJECT)
83 ev_page_cache_data_free (EvPageCacheData *data)
86 g_object_unref (data->job);
90 if (data->link_mapping) {
91 ev_mapping_list_unref (data->link_mapping);
92 data->link_mapping = NULL;
95 if (data->image_mapping) {
96 ev_mapping_list_unref (data->image_mapping);
97 data->image_mapping = NULL;
100 if (data->form_field_mapping) {
101 ev_mapping_list_unref (data->form_field_mapping);
102 data->form_field_mapping = NULL;
105 if (data->annot_mapping) {
106 ev_mapping_list_unref (data->annot_mapping);
107 data->annot_mapping = NULL;
110 if (data->text_mapping) {
111 cairo_region_destroy (data->text_mapping);
112 data->text_mapping = NULL;
115 if (data->text_layout) {
116 g_free (data->text_layout);
117 data->text_layout = NULL;
118 data->text_layout_length = 0;
128 ev_page_cache_finalize (GObject *object)
130 EvPageCache *cache = EV_PAGE_CACHE (object);
133 if (cache->page_list) {
134 for (i = 0; i < cache->n_pages; i++) {
135 EvPageCacheData *data;
137 data = &cache->page_list[i];
140 g_signal_handlers_disconnect_by_func (data->job,
141 G_CALLBACK (job_page_data_finished_cb),
143 g_signal_handlers_disconnect_by_func (data->job,
144 G_CALLBACK (job_page_data_cancelled_cb),
147 ev_page_cache_data_free (data);
150 g_free (cache->page_list);
151 cache->page_list = NULL;
155 if (cache->document) {
156 g_object_unref (cache->document);
157 cache->document = NULL;
160 G_OBJECT_CLASS (ev_page_cache_parent_class)->finalize (object);
164 ev_page_cache_init (EvPageCache *cache)
169 ev_page_cache_class_init (EvPageCacheClass *klass)
171 GObjectClass *g_object_class = G_OBJECT_CLASS (klass);
173 g_object_class->finalize = ev_page_cache_finalize;
176 static EvJobPageDataFlags
177 ev_page_cache_get_flags_for_data (EvPageCache *cache,
178 EvPageCacheData *data)
180 EvJobPageDataFlags flags = EV_PAGE_DATA_INCLUDE_NONE;
182 if (data->flags == cache->flags)
186 if (cache->flags & EV_PAGE_DATA_INCLUDE_LINKS) {
187 flags = (data->link_mapping) ?
188 flags & ~EV_PAGE_DATA_INCLUDE_LINKS :
189 flags | EV_PAGE_DATA_INCLUDE_LINKS;
192 if (cache->flags & EV_PAGE_DATA_INCLUDE_IMAGES) {
193 flags = (data->image_mapping) ?
194 flags & ~EV_PAGE_DATA_INCLUDE_IMAGES :
195 flags | EV_PAGE_DATA_INCLUDE_IMAGES;
198 if (cache->flags & EV_PAGE_DATA_INCLUDE_FORMS) {
199 flags = (data->form_field_mapping) ?
200 flags & ~EV_PAGE_DATA_INCLUDE_FORMS :
201 flags | EV_PAGE_DATA_INCLUDE_FORMS;
204 if (cache->flags & EV_PAGE_DATA_INCLUDE_ANNOTS) {
205 flags = (data->annot_mapping) ?
206 flags & ~EV_PAGE_DATA_INCLUDE_ANNOTS :
207 flags | EV_PAGE_DATA_INCLUDE_ANNOTS;
210 if (cache->flags & EV_PAGE_DATA_INCLUDE_TEXT_MAPPING) {
211 flags = (data->text_mapping) ?
212 flags & ~EV_PAGE_DATA_INCLUDE_TEXT_MAPPING :
213 flags | EV_PAGE_DATA_INCLUDE_TEXT_MAPPING;
216 if (cache->flags & EV_PAGE_DATA_INCLUDE_TEXT) {
217 flags = (data->text) ?
218 flags & ~EV_PAGE_DATA_INCLUDE_TEXT :
219 flags | EV_PAGE_DATA_INCLUDE_TEXT;
222 if (cache->flags & EV_PAGE_DATA_INCLUDE_TEXT_LAYOUT) {
223 flags = (data->text_layout_length > 0) ?
224 flags & ~EV_PAGE_DATA_INCLUDE_TEXT_LAYOUT :
225 flags | EV_PAGE_DATA_INCLUDE_TEXT_LAYOUT;
232 ev_page_cache_new (EvDocument *document)
236 g_return_val_if_fail (EV_IS_DOCUMENT (document), NULL);
238 cache = EV_PAGE_CACHE (g_object_new (EV_TYPE_PAGE_CACHE, NULL));
239 cache->document = g_object_ref (document);
240 cache->n_pages = ev_document_get_n_pages (document);
241 cache->flags = EV_PAGE_DATA_FLAGS_DEFAULT;
242 cache->page_list = g_new0 (EvPageCacheData, cache->n_pages);
248 job_page_data_finished_cb (EvJob *job,
251 EvJobPageData *job_data = EV_JOB_PAGE_DATA (job);
252 EvPageCacheData *data;
254 data = &cache->page_list[job_data->page];
256 if (job_data->flags & EV_PAGE_DATA_INCLUDE_LINKS)
257 data->link_mapping = job_data->link_mapping;
258 if (job_data->flags & EV_PAGE_DATA_INCLUDE_IMAGES)
259 data->image_mapping = job_data->image_mapping;
260 if (job_data->flags & EV_PAGE_DATA_INCLUDE_FORMS)
261 data->form_field_mapping = job_data->form_field_mapping;
262 if (job_data->flags & EV_PAGE_DATA_INCLUDE_ANNOTS)
263 data->annot_mapping = job_data->annot_mapping;
264 if (job_data->flags & EV_PAGE_DATA_INCLUDE_TEXT_MAPPING)
265 data->text_mapping = job_data->text_mapping;
266 if (job_data->flags & EV_PAGE_DATA_INCLUDE_TEXT_LAYOUT) {
267 data->text_layout = job_data->text_layout;
268 data->text_layout_length = job_data->text_layout_length;
270 if (job_data->flags & EV_PAGE_DATA_INCLUDE_TEXT)
271 data->text = job_data->text;
274 g_object_unref (data->job);
279 job_page_data_cancelled_cb (EvJob *job,
280 EvPageCacheData *data)
282 g_object_unref (data->job);
287 ev_page_cache_set_page_range (EvPageCache *cache,
293 if (cache->flags == EV_PAGE_DATA_INCLUDE_NONE)
296 cache->start_page = start;
297 cache->end_page = end;
299 for (i = start; i <= end; i++) {
300 EvPageCacheData *data = &cache->page_list[i];
301 EvJobPageDataFlags flags;
303 if (data->flags == cache->flags && (data->done || data->job))
307 ev_job_cancel (data->job);
309 flags = ev_page_cache_get_flags_for_data (cache, data);
311 data->flags = cache->flags;
312 data->job = ev_job_page_data_new (cache->document, i, flags);
313 g_signal_connect (data->job, "finished",
314 G_CALLBACK (job_page_data_finished_cb),
316 g_signal_connect (data->job, "cancelled",
317 G_CALLBACK (job_page_data_cancelled_cb),
319 ev_job_scheduler_push_job (data->job, EV_JOB_PRIORITY_NONE);
324 ev_page_cache_get_flags (EvPageCache *cache)
330 ev_page_cache_set_flags (EvPageCache *cache,
331 EvJobPageDataFlags flags)
333 if (cache->flags == flags)
336 cache->flags = flags;
338 /* Update the current range for new flags */
339 ev_page_cache_set_page_range (cache, cache->start_page, cache->end_page);
343 ev_page_cache_get_link_mapping (EvPageCache *cache,
346 EvPageCacheData *data;
348 g_return_val_if_fail (EV_IS_PAGE_CACHE (cache), NULL);
349 g_return_val_if_fail (page >= 0 && page < cache->n_pages, NULL);
351 if (!(cache->flags & EV_PAGE_DATA_INCLUDE_LINKS))
354 data = &cache->page_list[page];
356 return data->link_mapping;
359 return EV_JOB_PAGE_DATA (data->job)->link_mapping;
361 return data->link_mapping;
365 ev_page_cache_get_image_mapping (EvPageCache *cache,
368 EvPageCacheData *data;
370 g_return_val_if_fail (EV_IS_PAGE_CACHE (cache), NULL);
371 g_return_val_if_fail (page >= 0 && page < cache->n_pages, NULL);
373 if (!(cache->flags & EV_PAGE_DATA_INCLUDE_IMAGES))
376 data = &cache->page_list[page];
378 return data->image_mapping;
381 return EV_JOB_PAGE_DATA (data->job)->image_mapping;
383 return data->image_mapping;
387 ev_page_cache_get_form_field_mapping (EvPageCache *cache,
390 EvPageCacheData *data;
392 g_return_val_if_fail (EV_IS_PAGE_CACHE (cache), NULL);
393 g_return_val_if_fail (page >= 0 && page < cache->n_pages, NULL);
395 if (!(cache->flags & EV_PAGE_DATA_INCLUDE_FORMS))
398 data = &cache->page_list[page];
400 return data->form_field_mapping;
403 return EV_JOB_PAGE_DATA (data->job)->form_field_mapping;
405 return data->form_field_mapping;
409 ev_page_cache_get_annot_mapping (EvPageCache *cache,
412 EvPageCacheData *data;
414 g_return_val_if_fail (EV_IS_PAGE_CACHE (cache), NULL);
415 g_return_val_if_fail (page >= 0 && page < cache->n_pages, NULL);
417 if (!(cache->flags & EV_PAGE_DATA_INCLUDE_ANNOTS))
420 data = &cache->page_list[page];
422 return data->annot_mapping;
425 return EV_JOB_PAGE_DATA (data->job)->annot_mapping;
427 return data->annot_mapping;
431 ev_page_cache_get_text_mapping (EvPageCache *cache,
434 EvPageCacheData *data;
436 g_return_val_if_fail (EV_IS_PAGE_CACHE (cache), NULL);
437 g_return_val_if_fail (page >= 0 && page < cache->n_pages, NULL);
439 if (!(cache->flags & EV_PAGE_DATA_INCLUDE_TEXT_MAPPING))
442 data = &cache->page_list[page];
444 return data->text_mapping;
447 return EV_JOB_PAGE_DATA (data->job)->text_mapping;
449 return data->text_mapping;
453 ev_page_cache_get_text (EvPageCache *cache,
456 EvPageCacheData *data;
458 g_return_val_if_fail (EV_IS_PAGE_CACHE (cache), NULL);
459 g_return_val_if_fail (page >= 0 && page < cache->n_pages, NULL);
461 if (!(cache->flags & EV_PAGE_DATA_INCLUDE_TEXT))
464 data = &cache->page_list[page];
469 return EV_JOB_PAGE_DATA (data->job)->text;
475 ev_page_cache_get_text_layout (EvPageCache *cache,
480 EvPageCacheData *data;
482 g_return_val_if_fail (EV_IS_PAGE_CACHE (cache), FALSE);
483 g_return_val_if_fail (page >= 0 && page < cache->n_pages, FALSE);
485 if (!(cache->flags & EV_PAGE_DATA_INCLUDE_TEXT_LAYOUT))
488 data = &cache->page_list[page];
490 *areas = data->text_layout;
491 *n_areas = data->text_layout_length;
497 *areas = EV_JOB_PAGE_DATA (data->job)->text_layout;
498 *n_areas = EV_JOB_PAGE_DATA (data->job)->text_layout_length;