~ubuntu-branches/ubuntu/oneiric/evince/oneiric-updates

« back to all changes in this revision

Viewing changes to libview/ev-page-cache.c

  • Committer: Bazaar Package Importer
  • Author(s): Frederic Peters
  • Date: 2011-04-14 16:20:57 UTC
  • mfrom: (1.6.4 upstream)
  • mto: (1.3.5 experimental)
  • mto: This revision was merged to the branch mainline in revision 138.
  • Revision ID: james.westby@ubuntu.com-20110414162057-0ofhbd139zs6ev6y
ImportĀ upstreamĀ versionĀ 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
 *
15
15
 * You should have received a copy of the GNU General Public License
16
16
 * along with this program; if not, write to the Free Software
17
 
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
 
17
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18
18
 */
19
19
 
20
20
#include <config.h>
21
21
 
 
22
#include <glib.h>
22
23
#include "ev-jobs.h"
23
24
#include "ev-job-scheduler.h"
24
 
#include "ev-mapping.h"
 
25
#include "ev-mapping-list.h"
25
26
#include "ev-selection.h"
26
27
#include "ev-document-links.h"
27
28
#include "ev-document-forms.h"
28
29
#include "ev-document-images.h"
29
30
#include "ev-document-annotations.h"
 
31
#include "ev-document-text.h"
30
32
#include "ev-page-cache.h"
31
33
 
32
34
typedef struct _EvPageCacheData {
33
 
        EvJob     *job;
34
 
        gboolean   done : 1;
 
35
        EvJob             *job;
 
36
        gboolean           done : 1;
 
37
        gboolean           dirty : 1;
 
38
        EvJobPageDataFlags flags;
35
39
 
36
 
        GList     *link_mapping;
37
 
        GList     *image_mapping;
38
 
        GList     *form_field_mapping;
39
 
        GList     *annot_mapping;
40
 
        GdkRegion *text_mapping;
 
40
        EvMappingList     *link_mapping;
 
41
        EvMappingList     *image_mapping;
 
42
        EvMappingList     *form_field_mapping;
 
43
        EvMappingList     *annot_mapping;
 
44
        cairo_region_t    *text_mapping;
 
45
        EvRectangle       *text_layout;
 
46
        guint              text_layout_length;
 
47
        gchar             *text;
41
48
} EvPageCacheData;
42
49
 
43
50
struct _EvPageCache {
46
53
        EvDocument        *document;
47
54
        EvPageCacheData   *page_list;
48
55
        gint               n_pages;
 
56
 
 
57
        /* Current range */
 
58
        gint               start_page;
 
59
        gint               end_page;
 
60
 
49
61
        EvJobPageDataFlags flags;
50
62
};
51
63
 
53
65
        GObjectClass parent_class;
54
66
};
55
67
 
 
68
#define EV_PAGE_DATA_FLAGS_DEFAULT (        \
 
69
        EV_PAGE_DATA_INCLUDE_LINKS        | \
 
70
        EV_PAGE_DATA_INCLUDE_TEXT_MAPPING | \
 
71
        EV_PAGE_DATA_INCLUDE_IMAGES       | \
 
72
        EV_PAGE_DATA_INCLUDE_FORMS        | \
 
73
        EV_PAGE_DATA_INCLUDE_ANNOTS)
 
74
 
 
75
 
56
76
static void job_page_data_finished_cb (EvJob       *job,
57
77
                                       EvPageCache *cache);
 
78
static void job_page_data_cancelled_cb (EvJob       *job,
 
79
                                        EvPageCacheData *data);
58
80
 
59
81
G_DEFINE_TYPE (EvPageCache, ev_page_cache, G_TYPE_OBJECT)
60
82
 
67
89
        }
68
90
 
69
91
        if (data->link_mapping) {
70
 
                ev_mapping_list_free (data->link_mapping, g_object_unref);
 
92
                ev_mapping_list_unref (data->link_mapping);
71
93
                data->link_mapping = NULL;
72
94
        }
73
95
 
74
96
        if (data->image_mapping) {
75
 
                ev_mapping_list_free (data->image_mapping, g_object_unref);
 
97
                ev_mapping_list_unref (data->image_mapping);
76
98
                data->image_mapping = NULL;
77
99
        }
78
100
 
79
101
        if (data->form_field_mapping) {
80
 
                ev_mapping_list_free (data->form_field_mapping, g_object_unref);
 
102
                ev_mapping_list_unref (data->form_field_mapping);
81
103
                data->form_field_mapping = NULL;
82
104
        }
83
105
 
84
106
        if (data->annot_mapping) {
85
 
                ev_mapping_list_free (data->annot_mapping, g_object_unref);
 
107
                ev_mapping_list_unref (data->annot_mapping);
86
108
                data->annot_mapping = NULL;
87
109
        }
88
110
 
89
111
        if (data->text_mapping) {
90
 
                gdk_region_destroy (data->text_mapping);
 
112
                cairo_region_destroy (data->text_mapping);
91
113
                data->text_mapping = NULL;
92
114
        }
 
115
 
 
116
        if (data->text_layout) {
 
117
                g_free (data->text_layout);
 
118
                data->text_layout = NULL;
 
119
                data->text_layout_length = 0;
 
120
        }
 
121
 
 
122
        if (data->text) {
 
123
                g_free (data->text);
 
124
                data->text = NULL;
 
125
        }
93
126
}
94
127
 
95
128
static void
104
137
 
105
138
                        data = &cache->page_list[i];
106
139
 
107
 
                        if (data->job)
 
140
                        if (data->job) {
108
141
                                g_signal_handlers_disconnect_by_func (data->job,
109
142
                                                                      G_CALLBACK (job_page_data_finished_cb),
110
143
                                                                      cache);
 
144
                                g_signal_handlers_disconnect_by_func (data->job,
 
145
                                                                      G_CALLBACK (job_page_data_cancelled_cb),
 
146
                                                                      data);
 
147
                        }
111
148
                        ev_page_cache_data_free (data);
112
149
                }
113
150
 
138
175
}
139
176
 
140
177
static EvJobPageDataFlags
141
 
get_flags_for_document (EvDocument *document)
 
178
ev_page_cache_get_flags_for_data (EvPageCache     *cache,
 
179
                                  EvPageCacheData *data)
142
180
{
143
181
        EvJobPageDataFlags flags = EV_PAGE_DATA_INCLUDE_NONE;
144
182
 
145
 
        if (EV_IS_DOCUMENT_LINKS (document))
146
 
                flags |= EV_PAGE_DATA_INCLUDE_LINKS;
147
 
        if (EV_IS_DOCUMENT_IMAGES (document))
148
 
                flags |= EV_PAGE_DATA_INCLUDE_IMAGES;
149
 
        if (EV_IS_DOCUMENT_FORMS (document))
150
 
                flags |= EV_PAGE_DATA_INCLUDE_FORMS;
151
 
        if (EV_IS_DOCUMENT_ANNOTATIONS (document))
152
 
                flags |= EV_PAGE_DATA_INCLUDE_ANNOTS;
153
 
        if (EV_IS_SELECTION (document))
154
 
                flags |= EV_PAGE_DATA_INCLUDE_TEXT;
 
183
        if (data->flags == cache->flags && !data->dirty)
 
184
                return cache->flags;
 
185
 
 
186
        /* Flags changed or data is dirty */
 
187
        if (cache->flags & EV_PAGE_DATA_INCLUDE_LINKS) {
 
188
                flags = (data->link_mapping) ?
 
189
                        flags & ~EV_PAGE_DATA_INCLUDE_LINKS :
 
190
                        flags | EV_PAGE_DATA_INCLUDE_LINKS;
 
191
        }
 
192
 
 
193
        if (cache->flags & EV_PAGE_DATA_INCLUDE_IMAGES) {
 
194
                flags = (data->image_mapping) ?
 
195
                        flags & ~EV_PAGE_DATA_INCLUDE_IMAGES :
 
196
                        flags | EV_PAGE_DATA_INCLUDE_IMAGES;
 
197
        }
 
198
 
 
199
        if (cache->flags & EV_PAGE_DATA_INCLUDE_FORMS) {
 
200
                flags = (data->form_field_mapping) ?
 
201
                        flags & ~EV_PAGE_DATA_INCLUDE_FORMS :
 
202
                        flags | EV_PAGE_DATA_INCLUDE_FORMS;
 
203
        }
 
204
 
 
205
        if (cache->flags & EV_PAGE_DATA_INCLUDE_ANNOTS) {
 
206
                flags = (data->annot_mapping) ?
 
207
                        flags & ~EV_PAGE_DATA_INCLUDE_ANNOTS :
 
208
                        flags | EV_PAGE_DATA_INCLUDE_ANNOTS;
 
209
        }
 
210
 
 
211
        if (cache->flags & EV_PAGE_DATA_INCLUDE_TEXT_MAPPING) {
 
212
                flags = (data->text_mapping) ?
 
213
                        flags & ~EV_PAGE_DATA_INCLUDE_TEXT_MAPPING :
 
214
                        flags | EV_PAGE_DATA_INCLUDE_TEXT_MAPPING;
 
215
        }
 
216
 
 
217
        if (cache->flags & EV_PAGE_DATA_INCLUDE_TEXT) {
 
218
                flags = (data->text) ?
 
219
                        flags & ~EV_PAGE_DATA_INCLUDE_TEXT :
 
220
                        flags | EV_PAGE_DATA_INCLUDE_TEXT;
 
221
        }
 
222
 
 
223
        if (cache->flags & EV_PAGE_DATA_INCLUDE_TEXT_LAYOUT) {
 
224
                flags = (data->text_layout_length > 0) ?
 
225
                        flags & ~EV_PAGE_DATA_INCLUDE_TEXT_LAYOUT :
 
226
                        flags | EV_PAGE_DATA_INCLUDE_TEXT_LAYOUT;
 
227
        }
155
228
 
156
229
        return flags;
157
230
}
166
239
        cache = EV_PAGE_CACHE (g_object_new (EV_TYPE_PAGE_CACHE, NULL));
167
240
        cache->document = g_object_ref (document);
168
241
        cache->n_pages = ev_document_get_n_pages (document);
169
 
        cache->flags = get_flags_for_document (document);
170
 
 
171
 
        if (cache->flags != EV_PAGE_DATA_INCLUDE_NONE) {
172
 
                cache->page_list = g_new0 (EvPageCacheData, cache->n_pages);
173
 
        }
 
242
        cache->flags = EV_PAGE_DATA_FLAGS_DEFAULT;
 
243
        cache->page_list = g_new0 (EvPageCacheData, cache->n_pages);
174
244
 
175
245
        return cache;
176
246
}
183
253
        EvPageCacheData *data;
184
254
 
185
255
        data = &cache->page_list[job_data->page];
186
 
        data->link_mapping = job_data->link_mapping;
187
 
        data->image_mapping = job_data->image_mapping;
188
 
        data->form_field_mapping = job_data->form_field_mapping;
189
 
        data->annot_mapping = job_data->annot_mapping;
190
 
        data->text_mapping = job_data->text_mapping;
 
256
 
 
257
        if (job_data->flags & EV_PAGE_DATA_INCLUDE_LINKS)
 
258
                data->link_mapping = job_data->link_mapping;
 
259
        if (job_data->flags & EV_PAGE_DATA_INCLUDE_IMAGES)
 
260
                data->image_mapping = job_data->image_mapping;
 
261
        if (job_data->flags & EV_PAGE_DATA_INCLUDE_FORMS)
 
262
                data->form_field_mapping = job_data->form_field_mapping;
 
263
        if (job_data->flags & EV_PAGE_DATA_INCLUDE_ANNOTS)
 
264
                data->annot_mapping = job_data->annot_mapping;
 
265
        if (job_data->flags & EV_PAGE_DATA_INCLUDE_TEXT_MAPPING)
 
266
                data->text_mapping = job_data->text_mapping;
 
267
        if (job_data->flags & EV_PAGE_DATA_INCLUDE_TEXT_LAYOUT) {
 
268
                data->text_layout = job_data->text_layout;
 
269
                data->text_layout_length = job_data->text_layout_length;
 
270
        }
 
271
        if (job_data->flags & EV_PAGE_DATA_INCLUDE_TEXT)
 
272
                data->text = job_data->text;
191
273
        data->done = TRUE;
192
 
 
 
274
        data->dirty = FALSE;
 
275
 
 
276
        g_object_unref (data->job);
 
277
        data->job = NULL;
 
278
}
 
279
 
 
280
static void
 
281
job_page_data_cancelled_cb (EvJob           *job,
 
282
                            EvPageCacheData *data)
 
283
{
193
284
        g_object_unref (data->job);
194
285
        data->job = NULL;
195
286
}
204
295
        if (cache->flags == EV_PAGE_DATA_INCLUDE_NONE)
205
296
                return;
206
297
 
 
298
        cache->start_page = start;
 
299
        cache->end_page = end;
 
300
 
207
301
        for (i = start; i <= end; i++) {
208
 
                EvPageCacheData *data = &cache->page_list[i];
 
302
                EvPageCacheData   *data = &cache->page_list[i];
 
303
                EvJobPageDataFlags flags;
209
304
 
210
 
                if (data->done || data->job)
 
305
                if (data->flags == cache->flags && !data->dirty && (data->done || data->job))
211
306
                        continue;
212
307
 
213
 
                data->job = ev_job_page_data_new (cache->document, i, cache->flags);
 
308
                if (data->job)
 
309
                        ev_job_cancel (data->job);
 
310
 
 
311
                flags = ev_page_cache_get_flags_for_data (cache, data);
 
312
 
 
313
                data->flags = cache->flags;
 
314
                data->job = ev_job_page_data_new (cache->document, i, flags);
214
315
                g_signal_connect (data->job, "finished",
215
316
                                  G_CALLBACK (job_page_data_finished_cb),
216
317
                                  cache);
 
318
                g_signal_connect (data->job, "cancelled",
 
319
                                  G_CALLBACK (job_page_data_cancelled_cb),
 
320
                                  data);
217
321
                ev_job_scheduler_push_job (data->job, EV_JOB_PRIORITY_NONE);
218
322
        }
219
323
}
228
332
ev_page_cache_set_flags (EvPageCache       *cache,
229
333
                         EvJobPageDataFlags flags)
230
334
{
 
335
        if (cache->flags == flags)
 
336
                return;
 
337
 
231
338
        cache->flags = flags;
232
 
}
233
 
 
234
 
GList *
 
339
 
 
340
        /* Update the current range for new flags */
 
341
        ev_page_cache_set_page_range (cache, cache->start_page, cache->end_page);
 
342
}
 
343
 
 
344
void
 
345
ev_page_cache_mark_dirty (EvPageCache *cache,
 
346
                          gint         page)
 
347
{
 
348
        EvPageCacheData *data;
 
349
 
 
350
        g_return_if_fail (EV_IS_PAGE_CACHE (cache));
 
351
 
 
352
        data = &cache->page_list[page];
 
353
        data->dirty = TRUE;
 
354
 
 
355
        /* Update the current range */
 
356
        ev_page_cache_set_page_range (cache, cache->start_page, cache->end_page);
 
357
}
 
358
 
 
359
EvMappingList *
235
360
ev_page_cache_get_link_mapping (EvPageCache *cache,
236
361
                                gint         page)
237
362
{
253
378
        return data->link_mapping;
254
379
}
255
380
 
256
 
GList *
 
381
EvMappingList *
257
382
ev_page_cache_get_image_mapping (EvPageCache *cache,
258
383
                                 gint         page)
259
384
{
275
400
        return data->image_mapping;
276
401
}
277
402
 
278
 
GList *
 
403
EvMappingList *
279
404
ev_page_cache_get_form_field_mapping (EvPageCache *cache,
280
405
                                      gint         page)
281
406
{
297
422
        return data->form_field_mapping;
298
423
}
299
424
 
300
 
GList *
 
425
EvMappingList *
301
426
ev_page_cache_get_annot_mapping (EvPageCache *cache,
302
427
                                 gint         page)
303
428
{
319
444
        return data->annot_mapping;
320
445
}
321
446
 
322
 
GdkRegion *
 
447
cairo_region_t *
323
448
ev_page_cache_get_text_mapping (EvPageCache *cache,
324
449
                                gint         page)
325
450
{
328
453
        g_return_val_if_fail (EV_IS_PAGE_CACHE (cache), NULL);
329
454
        g_return_val_if_fail (page >= 0 && page < cache->n_pages, NULL);
330
455
 
331
 
        if (!(cache->flags & EV_PAGE_DATA_INCLUDE_TEXT))
 
456
        if (!(cache->flags & EV_PAGE_DATA_INCLUDE_TEXT_MAPPING))
332
457
                return NULL;
333
458
 
334
459
        data = &cache->page_list[page];
341
466
        return data->text_mapping;
342
467
}
343
468
 
 
469
const gchar *
 
470
ev_page_cache_get_text (EvPageCache *cache,
 
471
                             gint         page)
 
472
{
 
473
        EvPageCacheData *data;
 
474
 
 
475
        g_return_val_if_fail (EV_IS_PAGE_CACHE (cache), NULL);
 
476
        g_return_val_if_fail (page >= 0 && page < cache->n_pages, NULL);
 
477
 
 
478
        if (!(cache->flags & EV_PAGE_DATA_INCLUDE_TEXT))
 
479
                return NULL;
 
480
 
 
481
        data = &cache->page_list[page];
 
482
        if (data->done)
 
483
                return data->text;
 
484
 
 
485
        if (data->job)
 
486
                return EV_JOB_PAGE_DATA (data->job)->text;
 
487
 
 
488
        return data->text;
 
489
}
 
490
 
 
491
gboolean
 
492
ev_page_cache_get_text_layout (EvPageCache  *cache,
 
493
                               gint          page,
 
494
                               EvRectangle **areas,
 
495
                               guint        *n_areas)
 
496
{
 
497
        EvPageCacheData *data;
 
498
 
 
499
        g_return_val_if_fail (EV_IS_PAGE_CACHE (cache), FALSE);
 
500
        g_return_val_if_fail (page >= 0 && page < cache->n_pages, FALSE);
 
501
 
 
502
        if (!(cache->flags & EV_PAGE_DATA_INCLUDE_TEXT_LAYOUT))
 
503
                return FALSE;
 
504
 
 
505
        data = &cache->page_list[page];
 
506
        if (data->done) {
 
507
                *areas = data->text_layout;
 
508
                *n_areas = data->text_layout_length;
 
509
 
 
510
                return TRUE;
 
511
        }
 
512
 
 
513
        if (data->job) {
 
514
                *areas = EV_JOB_PAGE_DATA (data->job)->text_layout;
 
515
                *n_areas = EV_JOB_PAGE_DATA (data->job)->text_layout_length;
 
516
 
 
517
                return TRUE;
 
518
        }
 
519
 
 
520
        return FALSE;
 
521
}