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 {
38 EvMappingList *link_mapping;
39 EvMappingList *image_mapping;
40 EvMappingList *form_field_mapping;
41 EvMappingList *annot_mapping;
42 cairo_region_t *text_mapping;
43 EvRectangle *text_layout;
44 guint text_layout_length;
52 EvPageCacheData *page_list;
54 EvJobPageDataFlags flags;
57 struct _EvPageCacheClass {
58 GObjectClass parent_class;
61 static void job_page_data_finished_cb (EvJob *job,
64 G_DEFINE_TYPE (EvPageCache, ev_page_cache, G_TYPE_OBJECT)
67 ev_page_cache_data_free (EvPageCacheData *data)
70 g_object_unref (data->job);
74 if (data->link_mapping) {
75 ev_mapping_list_unref (data->link_mapping);
76 data->link_mapping = NULL;
79 if (data->image_mapping) {
80 ev_mapping_list_unref (data->image_mapping);
81 data->image_mapping = NULL;
84 if (data->form_field_mapping) {
85 ev_mapping_list_unref (data->form_field_mapping);
86 data->form_field_mapping = NULL;
89 if (data->annot_mapping) {
90 ev_mapping_list_unref (data->annot_mapping);
91 data->annot_mapping = NULL;
94 if (data->text_mapping) {
95 cairo_region_destroy (data->text_mapping);
96 data->text_mapping = NULL;
99 if (data->text_layout) {
100 g_free (data->text_layout);
101 data->text_layout = NULL;
102 data->text_layout_length = 0;
112 ev_page_cache_finalize (GObject *object)
114 EvPageCache *cache = EV_PAGE_CACHE (object);
117 if (cache->page_list) {
118 for (i = 0; i < cache->n_pages; i++) {
119 EvPageCacheData *data;
121 data = &cache->page_list[i];
124 g_signal_handlers_disconnect_by_func (data->job,
125 G_CALLBACK (job_page_data_finished_cb),
127 ev_page_cache_data_free (data);
130 g_free (cache->page_list);
131 cache->page_list = NULL;
135 if (cache->document) {
136 g_object_unref (cache->document);
137 cache->document = NULL;
140 G_OBJECT_CLASS (ev_page_cache_parent_class)->finalize (object);
144 ev_page_cache_init (EvPageCache *cache)
149 ev_page_cache_class_init (EvPageCacheClass *klass)
151 GObjectClass *g_object_class = G_OBJECT_CLASS (klass);
153 g_object_class->finalize = ev_page_cache_finalize;
156 static EvJobPageDataFlags
157 get_flags_for_document (EvDocument *document)
159 EvJobPageDataFlags flags = EV_PAGE_DATA_INCLUDE_NONE;
161 if (EV_IS_DOCUMENT_LINKS (document))
162 flags |= EV_PAGE_DATA_INCLUDE_LINKS;
163 if (EV_IS_DOCUMENT_IMAGES (document))
164 flags |= EV_PAGE_DATA_INCLUDE_IMAGES;
165 if (EV_IS_DOCUMENT_FORMS (document))
166 flags |= EV_PAGE_DATA_INCLUDE_FORMS;
167 if (EV_IS_DOCUMENT_ANNOTATIONS (document))
168 flags |= EV_PAGE_DATA_INCLUDE_ANNOTS;
169 if (EV_IS_SELECTION (document) && EV_IS_DOCUMENT_TEXT (document))
170 flags |= EV_PAGE_DATA_INCLUDE_TEXT_MAPPING;
171 if (EV_IS_DOCUMENT_TEXT (document))
172 flags |= EV_PAGE_DATA_INCLUDE_TEXT | EV_PAGE_DATA_INCLUDE_TEXT_LAYOUT;
178 ev_page_cache_new (EvDocument *document)
182 g_return_val_if_fail (EV_IS_DOCUMENT (document), NULL);
184 cache = EV_PAGE_CACHE (g_object_new (EV_TYPE_PAGE_CACHE, NULL));
185 cache->document = g_object_ref (document);
186 cache->n_pages = ev_document_get_n_pages (document);
187 cache->flags = get_flags_for_document (document);
189 if (cache->flags != EV_PAGE_DATA_INCLUDE_NONE) {
190 cache->page_list = g_new0 (EvPageCacheData, cache->n_pages);
197 job_page_data_finished_cb (EvJob *job,
200 EvJobPageData *job_data = EV_JOB_PAGE_DATA (job);
201 EvPageCacheData *data;
203 data = &cache->page_list[job_data->page];
204 data->link_mapping = job_data->link_mapping;
205 data->image_mapping = job_data->image_mapping;
206 data->form_field_mapping = job_data->form_field_mapping;
207 data->annot_mapping = job_data->annot_mapping;
208 data->text_mapping = job_data->text_mapping;
209 data->text_layout = job_data->text_layout;
210 data->text_layout_length = job_data->text_layout_length;
211 data->text = job_data->text;
214 g_object_unref (data->job);
219 ev_page_cache_set_page_range (EvPageCache *cache,
225 if (cache->flags == EV_PAGE_DATA_INCLUDE_NONE)
228 for (i = start; i <= end; i++) {
229 EvPageCacheData *data = &cache->page_list[i];
231 if (data->done || data->job)
234 data->job = ev_job_page_data_new (cache->document, i, cache->flags);
235 g_signal_connect (data->job, "finished",
236 G_CALLBACK (job_page_data_finished_cb),
238 ev_job_scheduler_push_job (data->job, EV_JOB_PRIORITY_NONE);
243 ev_page_cache_get_flags (EvPageCache *cache)
249 ev_page_cache_set_flags (EvPageCache *cache,
250 EvJobPageDataFlags flags)
252 cache->flags = flags;
256 ev_page_cache_get_link_mapping (EvPageCache *cache,
259 EvPageCacheData *data;
261 g_return_val_if_fail (EV_IS_PAGE_CACHE (cache), NULL);
262 g_return_val_if_fail (page >= 0 && page < cache->n_pages, NULL);
264 if (!(cache->flags & EV_PAGE_DATA_INCLUDE_LINKS))
267 data = &cache->page_list[page];
269 return data->link_mapping;
272 return EV_JOB_PAGE_DATA (data->job)->link_mapping;
274 return data->link_mapping;
278 ev_page_cache_get_image_mapping (EvPageCache *cache,
281 EvPageCacheData *data;
283 g_return_val_if_fail (EV_IS_PAGE_CACHE (cache), NULL);
284 g_return_val_if_fail (page >= 0 && page < cache->n_pages, NULL);
286 if (!(cache->flags & EV_PAGE_DATA_INCLUDE_IMAGES))
289 data = &cache->page_list[page];
291 return data->image_mapping;
294 return EV_JOB_PAGE_DATA (data->job)->image_mapping;
296 return data->image_mapping;
300 ev_page_cache_get_form_field_mapping (EvPageCache *cache,
303 EvPageCacheData *data;
305 g_return_val_if_fail (EV_IS_PAGE_CACHE (cache), NULL);
306 g_return_val_if_fail (page >= 0 && page < cache->n_pages, NULL);
308 if (!(cache->flags & EV_PAGE_DATA_INCLUDE_FORMS))
311 data = &cache->page_list[page];
313 return data->form_field_mapping;
316 return EV_JOB_PAGE_DATA (data->job)->form_field_mapping;
318 return data->form_field_mapping;
322 ev_page_cache_get_annot_mapping (EvPageCache *cache,
325 EvPageCacheData *data;
327 g_return_val_if_fail (EV_IS_PAGE_CACHE (cache), NULL);
328 g_return_val_if_fail (page >= 0 && page < cache->n_pages, NULL);
330 if (!(cache->flags & EV_PAGE_DATA_INCLUDE_ANNOTS))
333 data = &cache->page_list[page];
335 return data->annot_mapping;
338 return EV_JOB_PAGE_DATA (data->job)->annot_mapping;
340 return data->annot_mapping;
344 ev_page_cache_get_text_mapping (EvPageCache *cache,
347 EvPageCacheData *data;
349 g_return_val_if_fail (EV_IS_PAGE_CACHE (cache), NULL);
350 g_return_val_if_fail (page >= 0 && page < cache->n_pages, NULL);
352 if (!(cache->flags & EV_PAGE_DATA_INCLUDE_TEXT_MAPPING))
355 data = &cache->page_list[page];
357 return data->text_mapping;
360 return EV_JOB_PAGE_DATA (data->job)->text_mapping;
362 return data->text_mapping;
366 ev_page_cache_get_text (EvPageCache *cache,
369 EvPageCacheData *data;
371 g_return_val_if_fail (EV_IS_PAGE_CACHE (cache), NULL);
372 g_return_val_if_fail (page >= 0 && page < cache->n_pages, NULL);
374 if (!(cache->flags & EV_PAGE_DATA_INCLUDE_TEXT))
377 data = &cache->page_list[page];
382 return EV_JOB_PAGE_DATA (data->job)->text;
388 ev_page_cache_get_text_layout (EvPageCache *cache,
393 EvPageCacheData *data;
395 g_return_val_if_fail (EV_IS_PAGE_CACHE (cache), FALSE);
396 g_return_val_if_fail (page >= 0 && page < cache->n_pages, FALSE);
398 if (!(cache->flags & EV_PAGE_DATA_INCLUDE_TEXT_LAYOUT))
401 data = &cache->page_list[page];
403 *areas = data->text_layout;
404 *n_areas = data->text_layout_length;
410 *areas = EV_JOB_PAGE_DATA (data->job)->text_layout;
411 *n_areas = EV_JOB_PAGE_DATA (data->job)->text_layout_length;