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.
20
20
#include <config.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"
32
34
typedef struct _EvPageCacheData {
38
EvJobPageDataFlags flags;
38
GList *form_field_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;
43
50
struct _EvPageCache {
53
65
GObjectClass parent_class;
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)
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);
59
81
G_DEFINE_TYPE (EvPageCache, ev_page_cache, G_TYPE_OBJECT)
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;
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;
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;
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;
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;
116
if (data->text_layout) {
117
g_free (data->text_layout);
118
data->text_layout = NULL;
119
data->text_layout_length = 0;
105
138
data = &cache->page_list[i];
108
141
g_signal_handlers_disconnect_by_func (data->job,
109
142
G_CALLBACK (job_page_data_finished_cb),
144
g_signal_handlers_disconnect_by_func (data->job,
145
G_CALLBACK (job_page_data_cancelled_cb),
111
148
ev_page_cache_data_free (data);
140
177
static EvJobPageDataFlags
141
get_flags_for_document (EvDocument *document)
178
ev_page_cache_get_flags_for_data (EvPageCache *cache,
179
EvPageCacheData *data)
143
181
EvJobPageDataFlags flags = EV_PAGE_DATA_INCLUDE_NONE;
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)
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;
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;
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;
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;
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;
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;
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;
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);
171
if (cache->flags != EV_PAGE_DATA_INCLUDE_NONE) {
172
cache->page_list = g_new0 (EvPageCacheData, cache->n_pages);
242
cache->flags = EV_PAGE_DATA_FLAGS_DEFAULT;
243
cache->page_list = g_new0 (EvPageCacheData, cache->n_pages);
183
253
EvPageCacheData *data;
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;
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;
271
if (job_data->flags & EV_PAGE_DATA_INCLUDE_TEXT)
272
data->text = job_data->text;
191
273
data->done = TRUE;
276
g_object_unref (data->job);
281
job_page_data_cancelled_cb (EvJob *job,
282
EvPageCacheData *data)
193
284
g_object_unref (data->job);
194
285
data->job = NULL;
204
295
if (cache->flags == EV_PAGE_DATA_INCLUDE_NONE)
298
cache->start_page = start;
299
cache->end_page = end;
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;
210
if (data->done || data->job)
305
if (data->flags == cache->flags && !data->dirty && (data->done || data->job))
213
data->job = ev_job_page_data_new (cache->document, i, cache->flags);
309
ev_job_cancel (data->job);
311
flags = ev_page_cache_get_flags_for_data (cache, data);
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),
318
g_signal_connect (data->job, "cancelled",
319
G_CALLBACK (job_page_data_cancelled_cb),
217
321
ev_job_scheduler_push_job (data->job, EV_JOB_PRIORITY_NONE);
228
332
ev_page_cache_set_flags (EvPageCache *cache,
229
333
EvJobPageDataFlags flags)
335
if (cache->flags == flags)
231
338
cache->flags = flags;
340
/* Update the current range for new flags */
341
ev_page_cache_set_page_range (cache, cache->start_page, cache->end_page);
345
ev_page_cache_mark_dirty (EvPageCache *cache,
348
EvPageCacheData *data;
350
g_return_if_fail (EV_IS_PAGE_CACHE (cache));
352
data = &cache->page_list[page];
355
/* Update the current range */
356
ev_page_cache_set_page_range (cache, cache->start_page, cache->end_page);
235
360
ev_page_cache_get_link_mapping (EvPageCache *cache,
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);
331
if (!(cache->flags & EV_PAGE_DATA_INCLUDE_TEXT))
456
if (!(cache->flags & EV_PAGE_DATA_INCLUDE_TEXT_MAPPING))
334
459
data = &cache->page_list[page];
341
466
return data->text_mapping;
470
ev_page_cache_get_text (EvPageCache *cache,
473
EvPageCacheData *data;
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);
478
if (!(cache->flags & EV_PAGE_DATA_INCLUDE_TEXT))
481
data = &cache->page_list[page];
486
return EV_JOB_PAGE_DATA (data->job)->text;
492
ev_page_cache_get_text_layout (EvPageCache *cache,
497
EvPageCacheData *data;
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);
502
if (!(cache->flags & EV_PAGE_DATA_INCLUDE_TEXT_LAYOUT))
505
data = &cache->page_list[page];
507
*areas = data->text_layout;
508
*n_areas = data->text_layout_length;
514
*areas = EV_JOB_PAGE_DATA (data->job)->text_layout;
515
*n_areas = EV_JOB_PAGE_DATA (data->job)->text_layout_length;