File: | libview/ev-pixbuf-cache.c |
Warning: | line 413, column 15 Dereference of null pointer (loaded from variable 'target_page') |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | #include <config.h> | |||
2 | #include "ev-pixbuf-cache.h" | |||
3 | #include "ev-job-scheduler.h" | |||
4 | #include "ev-view-private.h" | |||
5 | ||||
6 | typedef enum { | |||
7 | SCROLL_DIRECTION_DOWN, | |||
8 | SCROLL_DIRECTION_UP | |||
9 | } ScrollDirection; | |||
10 | ||||
11 | typedef struct _CacheJobInfo | |||
12 | { | |||
13 | EvJob *job; | |||
14 | gboolean page_ready; | |||
15 | ||||
16 | /* Region of the page that needs to be drawn */ | |||
17 | cairo_region_t *region; | |||
18 | ||||
19 | /* Data we get from rendering */ | |||
20 | cairo_surface_t *surface; | |||
21 | ||||
22 | /* Device scale factor of target widget */ | |||
23 | int device_scale; | |||
24 | ||||
25 | /* Selection data. | |||
26 | * Selection_points are the coordinates encapsulated in selection. | |||
27 | * target_points is the target selection size. */ | |||
28 | EvRectangle target_points; | |||
29 | EvSelectionStyle selection_style; | |||
30 | gboolean points_set; | |||
31 | ||||
32 | cairo_surface_t *selection; | |||
33 | gdouble selection_scale; | |||
34 | EvRectangle selection_points; | |||
35 | ||||
36 | cairo_region_t *selection_region; | |||
37 | gdouble selection_region_scale; | |||
38 | EvRectangle selection_region_points; | |||
39 | } CacheJobInfo; | |||
40 | ||||
41 | struct _EvPixbufCache | |||
42 | { | |||
43 | GObject parent; | |||
44 | ||||
45 | /* We keep a link to our containing view just for style information. */ | |||
46 | CtkWidget *view; | |||
47 | EvDocument *document; | |||
48 | EvDocumentModel *model; | |||
49 | int start_page; | |||
50 | int end_page; | |||
51 | ScrollDirection scroll_direction; | |||
52 | gboolean inverted_colors; | |||
53 | ||||
54 | gsize max_size; | |||
55 | ||||
56 | /* preload_cache_size is the number of pages prior to the current | |||
57 | * visible area that we cache. It's normally 1, but could be 2 in the | |||
58 | * case of twin pages. | |||
59 | */ | |||
60 | int preload_cache_size; | |||
61 | guint job_list_len; | |||
62 | ||||
63 | CacheJobInfo *prev_job; | |||
64 | CacheJobInfo *job_list; | |||
65 | CacheJobInfo *next_job; | |||
66 | }; | |||
67 | ||||
68 | struct _EvPixbufCacheClass | |||
69 | { | |||
70 | GObjectClass parent_class; | |||
71 | ||||
72 | void (* job_finished) (EvPixbufCache *pixbuf_cache); | |||
73 | }; | |||
74 | ||||
75 | ||||
76 | enum | |||
77 | { | |||
78 | JOB_FINISHED, | |||
79 | N_SIGNALS, | |||
80 | }; | |||
81 | ||||
82 | static guint signals[N_SIGNALS] = {0, }; | |||
83 | ||||
84 | static void ev_pixbuf_cache_finalize (GObject *object); | |||
85 | static void ev_pixbuf_cache_dispose (GObject *object); | |||
86 | static void job_finished_cb (EvJob *job, | |||
87 | EvPixbufCache *pixbuf_cache); | |||
88 | static CacheJobInfo *find_job_cache (EvPixbufCache *pixbuf_cache, | |||
89 | int page); | |||
90 | static gboolean new_selection_surface_needed(EvPixbufCache *pixbuf_cache, | |||
91 | CacheJobInfo *job_info, | |||
92 | gint page, | |||
93 | gfloat scale); | |||
94 | ||||
95 | ||||
96 | /* These are used for iterating through the prev and next arrays */ | |||
97 | #define FIRST_VISIBLE_PREV(pixbuf_cache)((((0) > (pixbuf_cache->preload_cache_size - pixbuf_cache ->start_page)) ? (0) : (pixbuf_cache->preload_cache_size - pixbuf_cache->start_page))) \ | |||
98 | (MAX (0, pixbuf_cache->preload_cache_size - pixbuf_cache->start_page)(((0) > (pixbuf_cache->preload_cache_size - pixbuf_cache ->start_page)) ? (0) : (pixbuf_cache->preload_cache_size - pixbuf_cache->start_page))) | |||
99 | #define VISIBLE_NEXT_LEN(pixbuf_cache)((((pixbuf_cache->preload_cache_size) < (ev_document_get_n_pages (pixbuf_cache->document) - (1 + pixbuf_cache->end_page ))) ? (pixbuf_cache->preload_cache_size) : (ev_document_get_n_pages (pixbuf_cache->document) - (1 + pixbuf_cache->end_page )))) \ | |||
100 | (MIN(pixbuf_cache->preload_cache_size, ev_document_get_n_pages (pixbuf_cache->document) - (1 + pixbuf_cache->end_page))(((pixbuf_cache->preload_cache_size) < (ev_document_get_n_pages (pixbuf_cache->document) - (1 + pixbuf_cache->end_page ))) ? (pixbuf_cache->preload_cache_size) : (ev_document_get_n_pages (pixbuf_cache->document) - (1 + pixbuf_cache->end_page )))) | |||
101 | #define PAGE_CACHE_LEN(pixbuf_cache)(pixbuf_cache->start_page>=0?((pixbuf_cache->end_page - pixbuf_cache->start_page) + 1):0) \ | |||
102 | (pixbuf_cache->start_page>=0?((pixbuf_cache->end_page - pixbuf_cache->start_page) + 1):0) | |||
103 | ||||
104 | #define MAX_PRELOADED_PAGES3 3 | |||
105 | ||||
106 | G_DEFINE_TYPE (EvPixbufCache, ev_pixbuf_cache, G_TYPE_OBJECT)static void ev_pixbuf_cache_init (EvPixbufCache *self); static void ev_pixbuf_cache_class_init (EvPixbufCacheClass *klass); static GType ev_pixbuf_cache_get_type_once (void); static gpointer ev_pixbuf_cache_parent_class = ((void*)0); static gint EvPixbufCache_private_offset ; static void ev_pixbuf_cache_class_intern_init (gpointer klass ) { ev_pixbuf_cache_parent_class = g_type_class_peek_parent ( klass); if (EvPixbufCache_private_offset != 0) g_type_class_adjust_private_offset (klass, &EvPixbufCache_private_offset); ev_pixbuf_cache_class_init ((EvPixbufCacheClass*) klass); } __attribute__ ((__unused__) ) static inline gpointer ev_pixbuf_cache_get_instance_private (EvPixbufCache *self) { return (((gpointer) ((guint8*) (self ) + (glong) (EvPixbufCache_private_offset)))); } GType ev_pixbuf_cache_get_type (void) { static gsize static_g_define_type_id = 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer), "Expression evaluates to false"); (void) ( 0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (*(&static_g_define_type_id)) gapg_temp_newval; __typeof__ ((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id ); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5) ; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id )); }))) { GType g_define_type_id = ev_pixbuf_cache_get_type_once (); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id) = (g_define_type_id) ) : (void) 0; g_once_init_leave ((&static_g_define_type_id ), (gsize) (g_define_type_id)); })); } return static_g_define_type_id ; } __attribute__ ((__noinline__)) static GType ev_pixbuf_cache_get_type_once (void) { GType g_define_type_id = g_type_register_static_simple (((GType) ((20) << (2))), g_intern_static_string ("EvPixbufCache" ), sizeof (EvPixbufCacheClass), (GClassInitFunc)(void (*)(void )) ev_pixbuf_cache_class_intern_init, sizeof (EvPixbufCache), (GInstanceInitFunc)(void (*)(void)) ev_pixbuf_cache_init, (GTypeFlags ) 0); { {{};} } return g_define_type_id; } | |||
107 | ||||
108 | static void | |||
109 | ev_pixbuf_cache_init (EvPixbufCache *pixbuf_cache) | |||
110 | { | |||
111 | pixbuf_cache->start_page = -1; | |||
112 | pixbuf_cache->end_page = -1; | |||
113 | } | |||
114 | ||||
115 | static void | |||
116 | ev_pixbuf_cache_class_init (EvPixbufCacheClass *class) | |||
117 | { | |||
118 | GObjectClass *object_class; | |||
119 | ||||
120 | object_class = G_OBJECT_CLASS (class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((class)), (((GType) ((20) << (2)))))))); | |||
121 | ||||
122 | object_class->finalize = ev_pixbuf_cache_finalize; | |||
123 | object_class->dispose = ev_pixbuf_cache_dispose; | |||
124 | ||||
125 | signals[JOB_FINISHED] = | |||
126 | g_signal_new ("job-finished", | |||
127 | G_OBJECT_CLASS_TYPE (object_class)((((GTypeClass*) (object_class))->g_type)), | |||
128 | G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, | |||
129 | G_STRUCT_OFFSET (EvPixbufCacheClass, job_finished)((glong) __builtin_offsetof(EvPixbufCacheClass, job_finished) ), | |||
130 | NULL((void*)0), NULL((void*)0), | |||
131 | g_cclosure_marshal_VOID__POINTER, | |||
132 | G_TYPE_NONE((GType) ((1) << (2))), 1, | |||
133 | G_TYPE_POINTER((GType) ((17) << (2)))); | |||
134 | } | |||
135 | ||||
136 | static void | |||
137 | ev_pixbuf_cache_finalize (GObject *object) | |||
138 | { | |||
139 | EvPixbufCache *pixbuf_cache; | |||
140 | ||||
141 | pixbuf_cache = EV_PIXBUF_CACHE (object)((((EvPixbufCache*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((object)), ((ev_pixbuf_cache_get_type ())))))); | |||
142 | ||||
143 | if (pixbuf_cache->job_list) { | |||
144 | g_slice_free1 (sizeof (CacheJobInfo) * pixbuf_cache->job_list_len, | |||
145 | pixbuf_cache->job_list); | |||
146 | pixbuf_cache->job_list = NULL((void*)0); | |||
147 | } | |||
148 | if (pixbuf_cache->prev_job) { | |||
149 | g_slice_free1 (sizeof (CacheJobInfo) * pixbuf_cache->preload_cache_size, | |||
150 | pixbuf_cache->prev_job); | |||
151 | pixbuf_cache->prev_job = NULL((void*)0); | |||
152 | } | |||
153 | if (pixbuf_cache->next_job) { | |||
154 | g_slice_free1 (sizeof (CacheJobInfo) * pixbuf_cache->preload_cache_size, | |||
155 | pixbuf_cache->next_job); | |||
156 | pixbuf_cache->next_job = NULL((void*)0); | |||
157 | } | |||
158 | ||||
159 | g_object_unref (pixbuf_cache->model); | |||
160 | ||||
161 | G_OBJECT_CLASS (ev_pixbuf_cache_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((ev_pixbuf_cache_parent_class)), (((GType) ((20) << (2))))))))->finalize (object); | |||
162 | } | |||
163 | ||||
164 | static void | |||
165 | end_job (CacheJobInfo *job_info, | |||
166 | gpointer data) | |||
167 | { | |||
168 | g_signal_handlers_disconnect_by_func (job_info->job,g_signal_handlers_disconnect_matched ((job_info->job), (GSignalMatchType ) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*) 0), (((GCallback) (job_finished_cb))), (data)) | |||
169 | G_CALLBACK (job_finished_cb),g_signal_handlers_disconnect_matched ((job_info->job), (GSignalMatchType ) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*) 0), (((GCallback) (job_finished_cb))), (data)) | |||
170 | data)g_signal_handlers_disconnect_matched ((job_info->job), (GSignalMatchType ) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*) 0), (((GCallback) (job_finished_cb))), (data)); | |||
171 | ev_job_cancel (job_info->job); | |||
172 | g_object_unref (job_info->job); | |||
173 | job_info->job = NULL((void*)0); | |||
174 | } | |||
175 | ||||
176 | static void | |||
177 | dispose_cache_job_info (CacheJobInfo *job_info, | |||
178 | gpointer data) | |||
179 | { | |||
180 | if (job_info == NULL((void*)0)) | |||
181 | return; | |||
182 | ||||
183 | if (job_info->job) | |||
184 | end_job (job_info, data); | |||
185 | ||||
186 | if (job_info->surface) { | |||
187 | cairo_surface_destroy (job_info->surface); | |||
188 | job_info->surface = NULL((void*)0); | |||
189 | } | |||
190 | if (job_info->region) { | |||
191 | cairo_region_destroy (job_info->region); | |||
192 | job_info->region = NULL((void*)0); | |||
193 | } | |||
194 | if (job_info->selection) { | |||
195 | cairo_surface_destroy (job_info->selection); | |||
196 | job_info->selection = NULL((void*)0); | |||
197 | } | |||
198 | if (job_info->selection_region) { | |||
199 | cairo_region_destroy (job_info->selection_region); | |||
200 | job_info->selection_region = NULL((void*)0); | |||
201 | } | |||
202 | ||||
203 | job_info->points_set = FALSE(0); | |||
204 | } | |||
205 | ||||
206 | static void | |||
207 | ev_pixbuf_cache_dispose (GObject *object) | |||
208 | { | |||
209 | EvPixbufCache *pixbuf_cache; | |||
210 | int i; | |||
211 | ||||
212 | pixbuf_cache = EV_PIXBUF_CACHE (object)((((EvPixbufCache*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((object)), ((ev_pixbuf_cache_get_type ())))))); | |||
213 | ||||
214 | for (i = 0; i < pixbuf_cache->preload_cache_size; i++) { | |||
215 | dispose_cache_job_info (pixbuf_cache->prev_job + i, pixbuf_cache); | |||
216 | dispose_cache_job_info (pixbuf_cache->next_job + i, pixbuf_cache); | |||
217 | } | |||
218 | ||||
219 | for (i = 0; i < PAGE_CACHE_LEN (pixbuf_cache)(pixbuf_cache->start_page>=0?((pixbuf_cache->end_page - pixbuf_cache->start_page) + 1):0); i++) { | |||
220 | dispose_cache_job_info (pixbuf_cache->job_list + i, pixbuf_cache); | |||
221 | } | |||
222 | ||||
223 | G_OBJECT_CLASS (ev_pixbuf_cache_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((ev_pixbuf_cache_parent_class)), (((GType) ((20) << (2))))))))->dispose (object); | |||
224 | } | |||
225 | ||||
226 | ||||
227 | EvPixbufCache * | |||
228 | ev_pixbuf_cache_new (CtkWidget *view, | |||
229 | EvDocumentModel *model, | |||
230 | gsize max_size) | |||
231 | { | |||
232 | EvPixbufCache *pixbuf_cache; | |||
233 | ||||
234 | pixbuf_cache = (EvPixbufCache *) g_object_new (EV_TYPE_PIXBUF_CACHE(ev_pixbuf_cache_get_type ()), NULL((void*)0)); | |||
235 | /* This is a backlink, so we don't ref this */ | |||
236 | pixbuf_cache->view = view; | |||
237 | pixbuf_cache->model = g_object_ref (model)((__typeof__ (model)) (g_object_ref) (model)); | |||
238 | pixbuf_cache->document = ev_document_model_get_document (model); | |||
239 | pixbuf_cache->max_size = max_size; | |||
240 | ||||
241 | return pixbuf_cache; | |||
242 | } | |||
243 | ||||
244 | void | |||
245 | ev_pixbuf_cache_set_max_size (EvPixbufCache *pixbuf_cache, | |||
246 | gsize max_size) | |||
247 | { | |||
248 | if (pixbuf_cache->max_size == max_size) | |||
249 | return; | |||
250 | ||||
251 | if (pixbuf_cache->max_size > max_size) | |||
252 | ev_pixbuf_cache_clear (pixbuf_cache); | |||
253 | pixbuf_cache->max_size = max_size; | |||
254 | } | |||
255 | ||||
256 | static int | |||
257 | get_device_scale (EvPixbufCache *pixbuf_cache) | |||
258 | { | |||
259 | return ctk_widget_get_scale_factor (pixbuf_cache->view); | |||
260 | } | |||
261 | ||||
262 | static void | |||
263 | set_device_scale_on_surface (cairo_surface_t *surface, | |||
264 | int device_scale) | |||
265 | { | |||
266 | cairo_surface_set_device_scale (surface, device_scale, device_scale); | |||
267 | } | |||
268 | ||||
269 | static void | |||
270 | copy_job_to_job_info (EvJobRender *job_render, | |||
271 | CacheJobInfo *job_info, | |||
272 | EvPixbufCache *pixbuf_cache) | |||
273 | { | |||
274 | if (job_info->surface) { | |||
275 | cairo_surface_destroy (job_info->surface); | |||
276 | } | |||
277 | job_info->surface = cairo_surface_reference (job_render->surface); | |||
278 | set_device_scale_on_surface (job_info->surface, job_info->device_scale); | |||
279 | if (pixbuf_cache->inverted_colors) { | |||
280 | ev_document_misc_invert_surface (job_info->surface); | |||
281 | } | |||
282 | ||||
283 | job_info->points_set = FALSE(0); | |||
284 | if (job_render->include_selection) { | |||
285 | if (job_info->selection) { | |||
286 | cairo_surface_destroy (job_info->selection); | |||
287 | job_info->selection = NULL((void*)0); | |||
288 | } | |||
289 | if (job_info->selection_region) { | |||
290 | cairo_region_destroy (job_info->selection_region); | |||
291 | job_info->selection_region = NULL((void*)0); | |||
292 | } | |||
293 | ||||
294 | job_info->selection_points = job_render->selection_points; | |||
295 | job_info->selection = cairo_surface_reference (job_render->selection); | |||
296 | if (job_info->selection) | |||
297 | set_device_scale_on_surface (job_info->selection, job_info->device_scale); | |||
298 | job_info->selection_scale = job_render->scale * job_info->device_scale; | |||
299 | g_assert (job_info->selection_points.x1 >= 0)do { if (job_info->selection_points.x1 >= 0) ; else g_assertion_message_expr ("LectorView", "ev-pixbuf-cache.c", 299, ((const char*) (__func__ )), "job_info->selection_points.x1 >= 0"); } while (0); | |||
300 | ||||
301 | job_info->selection_region_points = job_render->selection_points; | |||
302 | job_info->selection_region = cairo_region_reference (job_render->selection_region); | |||
303 | job_info->selection_region_scale = job_render->scale; | |||
304 | ||||
305 | job_info->points_set = TRUE(!(0)); | |||
306 | } | |||
307 | ||||
308 | if (job_info->job) | |||
309 | end_job (job_info, pixbuf_cache); | |||
310 | ||||
311 | job_info->page_ready = TRUE(!(0)); | |||
312 | } | |||
313 | ||||
314 | static void | |||
315 | job_finished_cb (EvJob *job, | |||
316 | EvPixbufCache *pixbuf_cache) | |||
317 | { | |||
318 | CacheJobInfo *job_info; | |||
319 | EvJobRender *job_render = EV_JOB_RENDER (job)((((EvJobRender*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((job)), ((ev_job_render_get_type())))))); | |||
320 | ||||
321 | /* If the job is outside of our interest, we silently discard it */ | |||
322 | if ((job_render->page < (pixbuf_cache->start_page - pixbuf_cache->preload_cache_size)) || | |||
323 | (job_render->page > (pixbuf_cache->end_page + pixbuf_cache->preload_cache_size))) { | |||
324 | g_object_unref (job); | |||
325 | return; | |||
326 | } | |||
327 | ||||
328 | job_info = find_job_cache (pixbuf_cache, job_render->page); | |||
329 | ||||
330 | copy_job_to_job_info (job_render, job_info, pixbuf_cache); | |||
331 | g_signal_emit (pixbuf_cache, signals[JOB_FINISHED], 0, job_info->region); | |||
332 | } | |||
333 | ||||
334 | /* This checks a job to see if the job would generate the right sized pixbuf | |||
335 | * given a scale. If it won't, it removes the job and clears it to NULL. | |||
336 | */ | |||
337 | static void | |||
338 | check_job_size_and_unref (EvPixbufCache *pixbuf_cache, | |||
339 | CacheJobInfo *job_info, | |||
340 | gfloat scale) | |||
341 | { | |||
342 | gint width, height; | |||
343 | gint device_scale; | |||
344 | ||||
345 | g_assert (job_info)do { if (job_info) ; else g_assertion_message_expr ("LectorView" , "ev-pixbuf-cache.c", 345, ((const char*) (__func__)), "job_info" ); } while (0); | |||
346 | ||||
347 | if (job_info->job == NULL((void*)0)) | |||
348 | return; | |||
349 | ||||
350 | device_scale = get_device_scale (pixbuf_cache); | |||
351 | if (job_info->device_scale == device_scale) { | |||
352 | _get_page_size_for_scale_and_rotation (job_info->job->document, | |||
353 | EV_JOB_RENDER (job_info->job)((((EvJobRender*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((job_info->job)), ((ev_job_render_get_type()))))))->page, | |||
354 | scale, | |||
355 | EV_JOB_RENDER (job_info->job)((((EvJobRender*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((job_info->job)), ((ev_job_render_get_type()))))))->rotation, | |||
356 | &width, &height); | |||
357 | if (width * device_scale == EV_JOB_RENDER (job_info->job)((((EvJobRender*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((job_info->job)), ((ev_job_render_get_type()))))))->target_width && | |||
358 | height * device_scale == EV_JOB_RENDER (job_info->job)((((EvJobRender*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((job_info->job)), ((ev_job_render_get_type()))))))->target_height) | |||
359 | return; | |||
360 | } | |||
361 | ||||
362 | end_job (job_info, pixbuf_cache); | |||
363 | } | |||
364 | ||||
365 | /* Do all function that copies a job from an older cache to it's position in the | |||
366 | * new cache. It clears the old job if it doesn't have a place. | |||
367 | */ | |||
368 | static void | |||
369 | move_one_job (CacheJobInfo *job_info, | |||
370 | EvPixbufCache *pixbuf_cache, | |||
371 | int page, | |||
372 | CacheJobInfo *new_job_list, | |||
373 | CacheJobInfo *new_prev_job, | |||
374 | CacheJobInfo *new_next_job, | |||
375 | int new_preload_cache_size, | |||
376 | int start_page, | |||
377 | int end_page, | |||
378 | gint priority) | |||
379 | { | |||
380 | CacheJobInfo *target_page = NULL((void*)0); | |||
381 | int page_offset; | |||
382 | gint new_priority; | |||
383 | ||||
384 | if (page < (start_page - new_preload_cache_size) || | |||
385 | page > (end_page + new_preload_cache_size)) { | |||
386 | dispose_cache_job_info (job_info, pixbuf_cache); | |||
387 | return; | |||
388 | } | |||
389 | ||||
390 | /* find the target page to copy it over to. */ | |||
391 | if (page < start_page) { | |||
392 | page_offset = (page - (start_page - new_preload_cache_size)); | |||
393 | ||||
394 | g_assert (page_offset >= 0 &&do { if (page_offset >= 0 && page_offset < new_preload_cache_size ) ; else g_assertion_message_expr ("LectorView", "ev-pixbuf-cache.c" , 395, ((const char*) (__func__)), "page_offset >= 0 && page_offset < new_preload_cache_size" ); } while (0) | |||
395 | page_offset < new_preload_cache_size)do { if (page_offset >= 0 && page_offset < new_preload_cache_size ) ; else g_assertion_message_expr ("LectorView", "ev-pixbuf-cache.c" , 395, ((const char*) (__func__)), "page_offset >= 0 && page_offset < new_preload_cache_size" ); } while (0); | |||
396 | target_page = new_prev_job + page_offset; | |||
397 | new_priority = EV_JOB_PRIORITY_LOW; | |||
398 | } else if (page > end_page) { | |||
399 | page_offset = (page - (end_page + 1)); | |||
400 | ||||
401 | g_assert (page_offset >= 0 &&do { if (page_offset >= 0 && page_offset < new_preload_cache_size ) ; else g_assertion_message_expr ("LectorView", "ev-pixbuf-cache.c" , 402, ((const char*) (__func__)), "page_offset >= 0 && page_offset < new_preload_cache_size" ); } while (0) | |||
402 | page_offset < new_preload_cache_size)do { if (page_offset >= 0 && page_offset < new_preload_cache_size ) ; else g_assertion_message_expr ("LectorView", "ev-pixbuf-cache.c" , 402, ((const char*) (__func__)), "page_offset >= 0 && page_offset < new_preload_cache_size" ); } while (0); | |||
403 | target_page = new_next_job + page_offset; | |||
404 | new_priority = EV_JOB_PRIORITY_LOW; | |||
405 | } else { | |||
406 | page_offset = page - start_page; | |||
407 | g_assert (page_offset >= 0 &&do { if (page_offset >= 0 && page_offset <= ((end_page - start_page) + 1)) ; else g_assertion_message_expr ("LectorView" , "ev-pixbuf-cache.c", 408, ((const char*) (__func__)), "page_offset >= 0 && page_offset <= ((end_page - start_page) + 1)" ); } while (0) | |||
408 | page_offset <= ((end_page - start_page) + 1))do { if (page_offset >= 0 && page_offset <= ((end_page - start_page) + 1)) ; else g_assertion_message_expr ("LectorView" , "ev-pixbuf-cache.c", 408, ((const char*) (__func__)), "page_offset >= 0 && page_offset <= ((end_page - start_page) + 1)" ); } while (0); | |||
409 | new_priority = EV_JOB_PRIORITY_URGENT; | |||
410 | target_page = new_job_list + page_offset; | |||
411 | } | |||
412 | ||||
413 | *target_page = *job_info; | |||
| ||||
414 | job_info->job = NULL((void*)0); | |||
415 | job_info->region = NULL((void*)0); | |||
416 | job_info->surface = NULL((void*)0); | |||
417 | ||||
418 | if (new_priority != priority && target_page->job) { | |||
419 | ev_job_scheduler_update_job (target_page->job, new_priority); | |||
420 | } | |||
421 | } | |||
422 | ||||
423 | static gsize | |||
424 | ev_pixbuf_cache_get_page_size (EvPixbufCache *pixbuf_cache, | |||
425 | gint page_index, | |||
426 | gdouble scale, | |||
427 | gint rotation) | |||
428 | { | |||
429 | gint width, height; | |||
430 | ||||
431 | _get_page_size_for_scale_and_rotation (pixbuf_cache->document, | |||
432 | page_index, scale, rotation, | |||
433 | &width, &height); | |||
434 | return height * cairo_format_stride_for_width (CAIRO_FORMAT_RGB24, width); | |||
435 | } | |||
436 | ||||
437 | static gint | |||
438 | ev_pixbuf_cache_get_preload_size (EvPixbufCache *pixbuf_cache, | |||
439 | gint start_page, | |||
440 | gint end_page, | |||
441 | gdouble scale, | |||
442 | gint rotation) | |||
443 | { | |||
444 | gsize range_size = 0; | |||
445 | gint new_preload_cache_size = 0; | |||
446 | gint i; | |||
447 | guint n_pages = ev_document_get_n_pages (pixbuf_cache->document); | |||
448 | ||||
449 | /* Get the size of the current range */ | |||
450 | for (i = start_page; i <= end_page; i++) { | |||
451 | range_size += ev_pixbuf_cache_get_page_size (pixbuf_cache, i, scale, rotation); | |||
452 | } | |||
453 | ||||
454 | if (range_size >= pixbuf_cache->max_size) | |||
455 | return new_preload_cache_size; | |||
456 | ||||
457 | i = 1; | |||
458 | while (((start_page - i > 0) || (end_page + i < n_pages)) && | |||
459 | new_preload_cache_size < MAX_PRELOADED_PAGES3) { | |||
460 | gsize page_size; | |||
461 | gboolean updated = FALSE(0); | |||
462 | ||||
463 | if (end_page + i < n_pages) { | |||
464 | page_size = ev_pixbuf_cache_get_page_size (pixbuf_cache, end_page + i, | |||
465 | scale, rotation); | |||
466 | if (page_size + range_size <= pixbuf_cache->max_size) { | |||
467 | range_size += page_size; | |||
468 | new_preload_cache_size++; | |||
469 | updated = TRUE(!(0)); | |||
470 | } else { | |||
471 | break; | |||
472 | } | |||
473 | } | |||
474 | ||||
475 | if (start_page - i > 0) { | |||
476 | page_size = ev_pixbuf_cache_get_page_size (pixbuf_cache, start_page - i, | |||
477 | scale, rotation); | |||
478 | if (page_size + range_size <= pixbuf_cache->max_size) { | |||
479 | range_size += page_size; | |||
480 | if (!updated) | |||
481 | new_preload_cache_size++; | |||
482 | } else { | |||
483 | break; | |||
484 | } | |||
485 | } | |||
486 | i++; | |||
487 | } | |||
488 | ||||
489 | return new_preload_cache_size; | |||
490 | } | |||
491 | ||||
492 | static void | |||
493 | ev_pixbuf_cache_update_range (EvPixbufCache *pixbuf_cache, | |||
494 | gint start_page, | |||
495 | gint end_page, | |||
496 | guint rotation, | |||
497 | gdouble scale) | |||
498 | { | |||
499 | CacheJobInfo *new_job_list; | |||
500 | CacheJobInfo *new_prev_job = NULL((void*)0); | |||
501 | CacheJobInfo *new_next_job = NULL((void*)0); | |||
502 | gint new_preload_cache_size; | |||
503 | guint new_job_list_len; | |||
504 | int i, page; | |||
505 | ||||
506 | new_preload_cache_size = ev_pixbuf_cache_get_preload_size (pixbuf_cache, | |||
507 | start_page, | |||
508 | end_page, | |||
509 | scale, | |||
510 | rotation); | |||
511 | if (pixbuf_cache->start_page == start_page && | |||
512 | pixbuf_cache->end_page == end_page && | |||
513 | pixbuf_cache->preload_cache_size == new_preload_cache_size) | |||
514 | return; | |||
515 | ||||
516 | new_job_list_len = (end_page - start_page) + 1; | |||
517 | new_job_list = g_slice_alloc0 (sizeof (CacheJobInfo) * new_job_list_len); | |||
518 | if (new_preload_cache_size > 0) { | |||
519 | new_prev_job = g_slice_alloc0 (sizeof (CacheJobInfo) * new_preload_cache_size); | |||
520 | new_next_job = g_slice_alloc0 (sizeof (CacheJobInfo) * new_preload_cache_size); | |||
521 | } | |||
522 | ||||
523 | /* We go through each job in the old cache and either clear it or move | |||
524 | * it to a new location. */ | |||
525 | ||||
526 | /* Start with the prev cache. */ | |||
527 | page = pixbuf_cache->start_page - pixbuf_cache->preload_cache_size; | |||
528 | for (i = 0; i < pixbuf_cache->preload_cache_size; i++) { | |||
529 | if (page < 0) { | |||
530 | dispose_cache_job_info (pixbuf_cache->prev_job + i, pixbuf_cache); | |||
531 | } else { | |||
532 | move_one_job (pixbuf_cache->prev_job + i, | |||
533 | pixbuf_cache, page, | |||
534 | new_job_list, new_prev_job, new_next_job, | |||
535 | new_preload_cache_size, | |||
536 | start_page, end_page, EV_JOB_PRIORITY_LOW); | |||
537 | } | |||
538 | page ++; | |||
539 | } | |||
540 | ||||
541 | page = pixbuf_cache->start_page; | |||
542 | for (i = 0; i < PAGE_CACHE_LEN (pixbuf_cache)(pixbuf_cache->start_page>=0?((pixbuf_cache->end_page - pixbuf_cache->start_page) + 1):0) && page >= 0; i++) { | |||
543 | move_one_job (pixbuf_cache->job_list + i, | |||
544 | pixbuf_cache, page, | |||
545 | new_job_list, new_prev_job, new_next_job, | |||
546 | new_preload_cache_size, | |||
547 | start_page, end_page, EV_JOB_PRIORITY_URGENT); | |||
548 | page ++; | |||
549 | } | |||
550 | ||||
551 | for (i = 0; i < pixbuf_cache->preload_cache_size; i++) { | |||
552 | if (page >= ev_document_get_n_pages (pixbuf_cache->document)) { | |||
553 | dispose_cache_job_info (pixbuf_cache->next_job + i, pixbuf_cache); | |||
554 | } else { | |||
555 | move_one_job (pixbuf_cache->next_job + i, | |||
556 | pixbuf_cache, page, | |||
557 | new_job_list, new_prev_job, new_next_job, | |||
558 | new_preload_cache_size, | |||
559 | start_page, end_page, EV_JOB_PRIORITY_LOW); | |||
560 | } | |||
561 | page ++; | |||
562 | } | |||
563 | ||||
564 | if (pixbuf_cache->job_list) { | |||
565 | g_slice_free1 (sizeof (CacheJobInfo) * pixbuf_cache->job_list_len, | |||
566 | pixbuf_cache->job_list); | |||
567 | } | |||
568 | if (pixbuf_cache->prev_job) { | |||
569 | g_slice_free1 (sizeof (CacheJobInfo) * pixbuf_cache->preload_cache_size, | |||
570 | pixbuf_cache->prev_job); | |||
571 | } | |||
572 | if (pixbuf_cache->next_job) { | |||
573 | g_slice_free1 (sizeof (CacheJobInfo) * pixbuf_cache->preload_cache_size, | |||
574 | pixbuf_cache->next_job); | |||
575 | } | |||
576 | ||||
577 | pixbuf_cache->preload_cache_size = new_preload_cache_size; | |||
578 | pixbuf_cache->job_list_len = new_job_list_len; | |||
579 | ||||
580 | pixbuf_cache->job_list = new_job_list; | |||
581 | pixbuf_cache->prev_job = new_prev_job; | |||
582 | pixbuf_cache->next_job = new_next_job; | |||
583 | ||||
584 | pixbuf_cache->start_page = start_page; | |||
585 | pixbuf_cache->end_page = end_page; | |||
586 | } | |||
587 | ||||
588 | static CacheJobInfo * | |||
589 | find_job_cache (EvPixbufCache *pixbuf_cache, | |||
590 | int page) | |||
591 | { | |||
592 | int page_offset; | |||
593 | ||||
594 | if (page < (pixbuf_cache->start_page - pixbuf_cache->preload_cache_size) || | |||
595 | page > (pixbuf_cache->end_page + pixbuf_cache->preload_cache_size)) | |||
596 | return NULL((void*)0); | |||
597 | ||||
598 | if (page < pixbuf_cache->start_page) { | |||
599 | page_offset = (page - (pixbuf_cache->start_page - pixbuf_cache->preload_cache_size)); | |||
600 | ||||
601 | g_assert (page_offset >= 0 &&do { if (page_offset >= 0 && page_offset < pixbuf_cache ->preload_cache_size) ; else g_assertion_message_expr ("LectorView" , "ev-pixbuf-cache.c", 602, ((const char*) (__func__)), "page_offset >= 0 && page_offset < pixbuf_cache->preload_cache_size" ); } while (0) | |||
602 | page_offset < pixbuf_cache->preload_cache_size)do { if (page_offset >= 0 && page_offset < pixbuf_cache ->preload_cache_size) ; else g_assertion_message_expr ("LectorView" , "ev-pixbuf-cache.c", 602, ((const char*) (__func__)), "page_offset >= 0 && page_offset < pixbuf_cache->preload_cache_size" ); } while (0); | |||
603 | return pixbuf_cache->prev_job + page_offset; | |||
604 | } | |||
605 | ||||
606 | if (page > pixbuf_cache->end_page) { | |||
607 | page_offset = (page - (pixbuf_cache->end_page + 1)); | |||
608 | ||||
609 | g_assert (page_offset >= 0 &&do { if (page_offset >= 0 && page_offset < pixbuf_cache ->preload_cache_size) ; else g_assertion_message_expr ("LectorView" , "ev-pixbuf-cache.c", 610, ((const char*) (__func__)), "page_offset >= 0 && page_offset < pixbuf_cache->preload_cache_size" ); } while (0) | |||
610 | page_offset < pixbuf_cache->preload_cache_size)do { if (page_offset >= 0 && page_offset < pixbuf_cache ->preload_cache_size) ; else g_assertion_message_expr ("LectorView" , "ev-pixbuf-cache.c", 610, ((const char*) (__func__)), "page_offset >= 0 && page_offset < pixbuf_cache->preload_cache_size" ); } while (0); | |||
611 | return pixbuf_cache->next_job + page_offset; | |||
612 | } | |||
613 | ||||
614 | page_offset = page - pixbuf_cache->start_page; | |||
615 | g_assert (page_offset >= 0 &&do { if (page_offset >= 0 && page_offset <= (pixbuf_cache ->start_page>=0?((pixbuf_cache->end_page - pixbuf_cache ->start_page) + 1):0)) ; else g_assertion_message_expr ("LectorView" , "ev-pixbuf-cache.c", 616, ((const char*) (__func__)), "page_offset >= 0 && page_offset <= PAGE_CACHE_LEN(pixbuf_cache)" ); } while (0) | |||
616 | page_offset <= PAGE_CACHE_LEN(pixbuf_cache))do { if (page_offset >= 0 && page_offset <= (pixbuf_cache ->start_page>=0?((pixbuf_cache->end_page - pixbuf_cache ->start_page) + 1):0)) ; else g_assertion_message_expr ("LectorView" , "ev-pixbuf-cache.c", 616, ((const char*) (__func__)), "page_offset >= 0 && page_offset <= PAGE_CACHE_LEN(pixbuf_cache)" ); } while (0); | |||
617 | return pixbuf_cache->job_list + page_offset; | |||
618 | } | |||
619 | ||||
620 | static void | |||
621 | ev_pixbuf_cache_clear_job_sizes (EvPixbufCache *pixbuf_cache, | |||
622 | gfloat scale) | |||
623 | { | |||
624 | int i; | |||
625 | ||||
626 | for (i = 0; i < PAGE_CACHE_LEN (pixbuf_cache)(pixbuf_cache->start_page>=0?((pixbuf_cache->end_page - pixbuf_cache->start_page) + 1):0); i++) { | |||
627 | check_job_size_and_unref (pixbuf_cache, pixbuf_cache->job_list + i, scale); | |||
628 | } | |||
629 | ||||
630 | for (i = 0; i < pixbuf_cache->preload_cache_size; i++) { | |||
631 | check_job_size_and_unref (pixbuf_cache, pixbuf_cache->prev_job + i, scale); | |||
632 | check_job_size_and_unref (pixbuf_cache, pixbuf_cache->next_job + i, scale); | |||
633 | } | |||
634 | } | |||
635 | ||||
636 | static void | |||
637 | get_selection_colors (EvView *view, CdkColor *text, CdkColor *base) | |||
638 | { | |||
639 | CdkRGBA fg, bg; | |||
640 | ||||
641 | _ev_view_get_selection_colors (view, &bg, &fg); | |||
642 | ||||
643 | text->pixel = 0; | |||
644 | text->red = CLAMP ((guint) (fg.red * 65535), 0, 65535)((((guint) (fg.red * 65535)) > (65535)) ? (65535) : ((((guint ) (fg.red * 65535)) < (0)) ? (0) : ((guint) (fg.red * 65535 )))); | |||
645 | text->green = CLAMP ((guint) (fg.green * 65535), 0, 65535)((((guint) (fg.green * 65535)) > (65535)) ? (65535) : (((( guint) (fg.green * 65535)) < (0)) ? (0) : ((guint) (fg.green * 65535)))); | |||
646 | text->blue = CLAMP ((guint) (fg.blue * 65535), 0, 65535)((((guint) (fg.blue * 65535)) > (65535)) ? (65535) : ((((guint ) (fg.blue * 65535)) < (0)) ? (0) : ((guint) (fg.blue * 65535 )))); | |||
647 | ||||
648 | base->pixel = 0; | |||
649 | base->red = CLAMP ((guint) (bg.red * 65535), 0, 65535)((((guint) (bg.red * 65535)) > (65535)) ? (65535) : ((((guint ) (bg.red * 65535)) < (0)) ? (0) : ((guint) (bg.red * 65535 )))); | |||
650 | base->green = CLAMP ((guint) (bg.green * 65535), 0, 65535)((((guint) (bg.green * 65535)) > (65535)) ? (65535) : (((( guint) (bg.green * 65535)) < (0)) ? (0) : ((guint) (bg.green * 65535)))); | |||
651 | base->blue = CLAMP ((guint) (bg.blue * 65535), 0, 65535)((((guint) (bg.blue * 65535)) > (65535)) ? (65535) : ((((guint ) (bg.blue * 65535)) < (0)) ? (0) : ((guint) (bg.blue * 65535 )))); | |||
652 | } | |||
653 | ||||
654 | static void | |||
655 | add_job (EvPixbufCache *pixbuf_cache, | |||
656 | CacheJobInfo *job_info, | |||
657 | cairo_region_t *region, | |||
658 | gint width, | |||
659 | gint height, | |||
660 | gint page, | |||
661 | gint rotation, | |||
662 | gfloat scale, | |||
663 | EvJobPriority priority) | |||
664 | { | |||
665 | job_info->device_scale = get_device_scale (pixbuf_cache); | |||
666 | job_info->page_ready = FALSE(0); | |||
667 | ||||
668 | if (job_info->region) | |||
669 | cairo_region_destroy (job_info->region); | |||
670 | job_info->region = region ? cairo_region_reference (region) : NULL((void*)0); | |||
671 | ||||
672 | if (job_info->job) | |||
673 | end_job (job_info, pixbuf_cache); | |||
674 | ||||
675 | job_info->job = ev_job_render_new (pixbuf_cache->document, | |||
676 | page, rotation, | |||
677 | scale * job_info->device_scale, | |||
678 | width * job_info->device_scale, | |||
679 | height * job_info->device_scale); | |||
680 | ||||
681 | if (new_selection_surface_needed (pixbuf_cache, job_info, page, scale)) { | |||
682 | CdkColor text, base; | |||
683 | ||||
684 | get_selection_colors (EV_VIEW (pixbuf_cache->view)((((EvView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((pixbuf_cache->view)), ((ev_view_get_type ())))))), &text, &base); | |||
685 | ev_job_render_set_selection_info (EV_JOB_RENDER (job_info->job)((((EvJobRender*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((job_info->job)), ((ev_job_render_get_type())))))), | |||
686 | &(job_info->target_points), | |||
687 | job_info->selection_style, | |||
688 | &text, &base); | |||
689 | } | |||
690 | ||||
691 | g_signal_connect (job_info->job, "finished",g_signal_connect_data ((job_info->job), ("finished"), (((GCallback ) (job_finished_cb))), (pixbuf_cache), ((void*)0), (GConnectFlags ) 0) | |||
692 | G_CALLBACK (job_finished_cb),g_signal_connect_data ((job_info->job), ("finished"), (((GCallback ) (job_finished_cb))), (pixbuf_cache), ((void*)0), (GConnectFlags ) 0) | |||
693 | pixbuf_cache)g_signal_connect_data ((job_info->job), ("finished"), (((GCallback ) (job_finished_cb))), (pixbuf_cache), ((void*)0), (GConnectFlags ) 0); | |||
694 | ev_job_scheduler_push_job (job_info->job, priority); | |||
695 | } | |||
696 | ||||
697 | static void | |||
698 | add_job_if_needed (EvPixbufCache *pixbuf_cache, | |||
699 | CacheJobInfo *job_info, | |||
700 | gint page, | |||
701 | gint rotation, | |||
702 | gfloat scale, | |||
703 | EvJobPriority priority) | |||
704 | { | |||
705 | gint device_scale = get_device_scale (pixbuf_cache); | |||
706 | gint width, height; | |||
707 | ||||
708 | if (job_info->job) | |||
709 | return; | |||
710 | ||||
711 | _get_page_size_for_scale_and_rotation (pixbuf_cache->document, | |||
712 | page, scale, rotation, | |||
713 | &width, &height); | |||
714 | ||||
715 | if (job_info->surface && | |||
716 | job_info->device_scale == device_scale && | |||
717 | cairo_image_surface_get_width (job_info->surface) == width * device_scale && | |||
718 | cairo_image_surface_get_height (job_info->surface) == height * device_scale) | |||
719 | return; | |||
720 | ||||
721 | /* Free old surfaces for non visible pages */ | |||
722 | if (priority == EV_JOB_PRIORITY_LOW) { | |||
723 | if (job_info->surface) { | |||
724 | cairo_surface_destroy (job_info->surface); | |||
725 | job_info->surface = NULL((void*)0); | |||
726 | } | |||
727 | ||||
728 | if (job_info->selection) { | |||
729 | cairo_surface_destroy (job_info->selection); | |||
730 | job_info->selection = NULL((void*)0); | |||
731 | } | |||
732 | } | |||
733 | ||||
734 | add_job (pixbuf_cache, job_info, NULL((void*)0), | |||
735 | width, height, page, rotation, scale, | |||
736 | priority); | |||
737 | } | |||
738 | ||||
739 | static void | |||
740 | add_prev_jobs_if_needed (EvPixbufCache *pixbuf_cache, | |||
741 | gint rotation, | |||
742 | gfloat scale) | |||
743 | { | |||
744 | CacheJobInfo *job_info; | |||
745 | int page; | |||
746 | int i; | |||
747 | ||||
748 | for (i = pixbuf_cache->preload_cache_size - 1; i >= FIRST_VISIBLE_PREV(pixbuf_cache)((((0) > (pixbuf_cache->preload_cache_size - pixbuf_cache ->start_page)) ? (0) : (pixbuf_cache->preload_cache_size - pixbuf_cache->start_page))); i--) { | |||
749 | job_info = (pixbuf_cache->prev_job + i); | |||
750 | page = pixbuf_cache->start_page - pixbuf_cache->preload_cache_size + i; | |||
751 | ||||
752 | add_job_if_needed (pixbuf_cache, job_info, | |||
753 | page, rotation, scale, | |||
754 | EV_JOB_PRIORITY_LOW); | |||
755 | } | |||
756 | } | |||
757 | ||||
758 | static void | |||
759 | add_next_jobs_if_needed (EvPixbufCache *pixbuf_cache, | |||
760 | gint rotation, | |||
761 | gfloat scale) | |||
762 | { | |||
763 | CacheJobInfo *job_info; | |||
764 | int page; | |||
765 | int i; | |||
766 | ||||
767 | for (i = 0; i < VISIBLE_NEXT_LEN(pixbuf_cache)((((pixbuf_cache->preload_cache_size) < (ev_document_get_n_pages (pixbuf_cache->document) - (1 + pixbuf_cache->end_page ))) ? (pixbuf_cache->preload_cache_size) : (ev_document_get_n_pages (pixbuf_cache->document) - (1 + pixbuf_cache->end_page )))); i++) { | |||
768 | job_info = (pixbuf_cache->next_job + i); | |||
769 | page = pixbuf_cache->end_page + 1 + i; | |||
770 | ||||
771 | add_job_if_needed (pixbuf_cache, job_info, | |||
772 | page, rotation, scale, | |||
773 | EV_JOB_PRIORITY_LOW); | |||
774 | } | |||
775 | } | |||
776 | ||||
777 | static void | |||
778 | ev_pixbuf_cache_add_jobs_if_needed (EvPixbufCache *pixbuf_cache, | |||
779 | gint rotation, | |||
780 | gfloat scale) | |||
781 | { | |||
782 | CacheJobInfo *job_info; | |||
783 | int page; | |||
784 | int i; | |||
785 | ||||
786 | for (i = 0; i < PAGE_CACHE_LEN (pixbuf_cache)(pixbuf_cache->start_page>=0?((pixbuf_cache->end_page - pixbuf_cache->start_page) + 1):0); i++) { | |||
787 | job_info = (pixbuf_cache->job_list + i); | |||
788 | page = pixbuf_cache->start_page + i; | |||
789 | ||||
790 | add_job_if_needed (pixbuf_cache, job_info, | |||
791 | page, rotation, scale, | |||
792 | EV_JOB_PRIORITY_URGENT); | |||
793 | } | |||
794 | ||||
795 | if (pixbuf_cache->scroll_direction == SCROLL_DIRECTION_UP) { | |||
796 | add_prev_jobs_if_needed (pixbuf_cache, rotation, scale); | |||
797 | add_next_jobs_if_needed (pixbuf_cache, rotation, scale); | |||
798 | } else { | |||
799 | add_next_jobs_if_needed (pixbuf_cache, rotation, scale); | |||
800 | add_prev_jobs_if_needed (pixbuf_cache, rotation, scale); | |||
801 | } | |||
802 | } | |||
803 | ||||
804 | static ScrollDirection | |||
805 | ev_pixbuf_cache_get_scroll_direction (EvPixbufCache *pixbuf_cache, | |||
806 | gint start_page, | |||
807 | gint end_page) | |||
808 | { | |||
809 | if (start_page < pixbuf_cache->start_page) | |||
810 | return SCROLL_DIRECTION_UP; | |||
811 | ||||
812 | if (end_page > pixbuf_cache->end_page) | |||
813 | return SCROLL_DIRECTION_DOWN; | |||
814 | ||||
815 | if (start_page > pixbuf_cache->start_page) | |||
816 | return SCROLL_DIRECTION_DOWN; | |||
817 | ||||
818 | if (end_page < pixbuf_cache->end_page) | |||
819 | return SCROLL_DIRECTION_UP; | |||
820 | ||||
821 | return pixbuf_cache->scroll_direction; | |||
822 | } | |||
823 | ||||
824 | void | |||
825 | ev_pixbuf_cache_set_page_range (EvPixbufCache *pixbuf_cache, | |||
826 | gint start_page, | |||
827 | gint end_page, | |||
828 | GList *selection_list) | |||
829 | { | |||
830 | gdouble scale = ev_document_model_get_scale (pixbuf_cache->model); | |||
831 | gint rotation = ev_document_model_get_rotation (pixbuf_cache->model); | |||
832 | ||||
833 | g_return_if_fail (EV_IS_PIXBUF_CACHE (pixbuf_cache))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((pixbuf_cache)); GType __t = ((ev_pixbuf_cache_get_type ( ))); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("LectorView" , ((const char*) (__func__)), "EV_IS_PIXBUF_CACHE (pixbuf_cache)" ); return; } } while (0); | |||
| ||||
834 | ||||
835 | g_return_if_fail (start_page >= 0 && start_page < ev_document_get_n_pages (pixbuf_cache->document))do { if ((start_page >= 0 && start_page < ev_document_get_n_pages (pixbuf_cache->document))) { } else { g_return_if_fail_warning ("LectorView", ((const char*) (__func__)), "start_page >= 0 && start_page < ev_document_get_n_pages (pixbuf_cache->document)" ); return; } } while (0); | |||
836 | g_return_if_fail (end_page >= 0 && end_page < ev_document_get_n_pages (pixbuf_cache->document))do { if ((end_page >= 0 && end_page < ev_document_get_n_pages (pixbuf_cache->document))) { } else { g_return_if_fail_warning ("LectorView", ((const char*) (__func__)), "end_page >= 0 && end_page < ev_document_get_n_pages (pixbuf_cache->document)" ); return; } } while (0); | |||
837 | g_return_if_fail (end_page >= start_page)do { if ((end_page >= start_page)) { } else { g_return_if_fail_warning ("LectorView", ((const char*) (__func__)), "end_page >= start_page" ); return; } } while (0); | |||
838 | ||||
839 | pixbuf_cache->scroll_direction = ev_pixbuf_cache_get_scroll_direction (pixbuf_cache, start_page, end_page); | |||
840 | ||||
841 | /* First, resize the page_range as needed. We cull old pages | |||
842 | * mercilessly. */ | |||
843 | ev_pixbuf_cache_update_range (pixbuf_cache, start_page, end_page, rotation, scale); | |||
844 | ||||
845 | /* Then, we update the current jobs to see if any of them are the wrong | |||
846 | * size, we remove them if we need to. */ | |||
847 | ev_pixbuf_cache_clear_job_sizes (pixbuf_cache, scale); | |||
848 | ||||
849 | /* Next, we update the target selection for our pages */ | |||
850 | ev_pixbuf_cache_set_selection_list (pixbuf_cache, selection_list); | |||
851 | ||||
852 | /* Finally, we add the new jobs for all the sizes that don't have a | |||
853 | * pixbuf */ | |||
854 | ev_pixbuf_cache_add_jobs_if_needed (pixbuf_cache, rotation, scale); | |||
855 | } | |||
856 | ||||
857 | void | |||
858 | ev_pixbuf_cache_set_inverted_colors (EvPixbufCache *pixbuf_cache, | |||
859 | gboolean inverted_colors) | |||
860 | { | |||
861 | gint i; | |||
862 | ||||
863 | if (pixbuf_cache->inverted_colors == inverted_colors) | |||
864 | return; | |||
865 | ||||
866 | pixbuf_cache->inverted_colors = inverted_colors; | |||
867 | ||||
868 | for (i = 0; i < pixbuf_cache->preload_cache_size; i++) { | |||
869 | CacheJobInfo *job_info; | |||
870 | ||||
871 | job_info = pixbuf_cache->prev_job + i; | |||
872 | if (job_info && job_info->surface) | |||
873 | ev_document_misc_invert_surface (job_info->surface); | |||
874 | ||||
875 | job_info = pixbuf_cache->next_job + i; | |||
876 | if (job_info && job_info->surface) | |||
877 | ev_document_misc_invert_surface (job_info->surface); | |||
878 | } | |||
879 | ||||
880 | for (i = 0; i < PAGE_CACHE_LEN (pixbuf_cache)(pixbuf_cache->start_page>=0?((pixbuf_cache->end_page - pixbuf_cache->start_page) + 1):0); i++) { | |||
881 | CacheJobInfo *job_info; | |||
882 | ||||
883 | job_info = pixbuf_cache->job_list + i; | |||
884 | if (job_info && job_info->surface) | |||
885 | ev_document_misc_invert_surface (job_info->surface); | |||
886 | } | |||
887 | } | |||
888 | ||||
889 | cairo_surface_t * | |||
890 | ev_pixbuf_cache_get_surface (EvPixbufCache *pixbuf_cache, | |||
891 | gint page) | |||
892 | { | |||
893 | CacheJobInfo *job_info; | |||
894 | ||||
895 | job_info = find_job_cache (pixbuf_cache, page); | |||
896 | if (job_info == NULL((void*)0)) | |||
897 | return NULL((void*)0); | |||
898 | ||||
899 | if (job_info->page_ready) | |||
900 | return job_info->surface; | |||
901 | ||||
902 | /* We don't need to wait for the idle to handle the callback */ | |||
903 | if (job_info->job && | |||
904 | EV_JOB_RENDER (job_info->job)((((EvJobRender*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((job_info->job)), ((ev_job_render_get_type()))))))->page_ready) { | |||
905 | copy_job_to_job_info (EV_JOB_RENDER (job_info->job)((((EvJobRender*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((job_info->job)), ((ev_job_render_get_type())))))), job_info, pixbuf_cache); | |||
906 | g_signal_emit (pixbuf_cache, signals[JOB_FINISHED], 0, job_info->region); | |||
907 | } | |||
908 | ||||
909 | return job_info->surface; | |||
910 | } | |||
911 | ||||
912 | static gboolean | |||
913 | new_selection_surface_needed (EvPixbufCache *pixbuf_cache, | |||
914 | CacheJobInfo *job_info, | |||
915 | gint page, | |||
916 | gfloat scale) | |||
917 | { | |||
918 | if (job_info->selection) | |||
919 | return job_info->selection_scale != scale; | |||
920 | return job_info->points_set; | |||
921 | } | |||
922 | ||||
923 | static gboolean | |||
924 | new_selection_region_needed (EvPixbufCache *pixbuf_cache, | |||
925 | CacheJobInfo *job_info, | |||
926 | gint page, | |||
927 | gfloat scale) | |||
928 | { | |||
929 | if (job_info->selection_region) | |||
930 | return job_info->selection_region_scale != scale; | |||
931 | return job_info->points_set; | |||
932 | } | |||
933 | ||||
934 | static void | |||
935 | clear_selection_surface_if_needed (EvPixbufCache *pixbuf_cache, | |||
936 | CacheJobInfo *job_info, | |||
937 | gint page, | |||
938 | gfloat scale) | |||
939 | { | |||
940 | if (new_selection_surface_needed (pixbuf_cache, job_info, page, scale)) { | |||
941 | if (job_info->selection) | |||
942 | cairo_surface_destroy (job_info->selection); | |||
943 | job_info->selection = NULL((void*)0); | |||
944 | job_info->selection_points.x1 = -1; | |||
945 | } | |||
946 | } | |||
947 | ||||
948 | static void | |||
949 | clear_selection_region_if_needed (EvPixbufCache *pixbuf_cache, | |||
950 | CacheJobInfo *job_info, | |||
951 | gint page, | |||
952 | gfloat scale) | |||
953 | { | |||
954 | if (new_selection_region_needed (pixbuf_cache, job_info, page, scale)) { | |||
955 | if (job_info->selection_region) | |||
956 | cairo_region_destroy (job_info->selection_region); | |||
957 | job_info->selection_region = NULL((void*)0); | |||
958 | job_info->selection_region_points.x1 = -1; | |||
959 | } | |||
960 | } | |||
961 | ||||
962 | /* Clears the cache of jobs and pixbufs. | |||
963 | */ | |||
964 | void | |||
965 | ev_pixbuf_cache_clear (EvPixbufCache *pixbuf_cache) | |||
966 | { | |||
967 | int i; | |||
968 | ||||
969 | if (!pixbuf_cache->job_list) | |||
970 | return; | |||
971 | ||||
972 | for (i = 0; i < pixbuf_cache->preload_cache_size; i++) { | |||
973 | dispose_cache_job_info (pixbuf_cache->prev_job + i, pixbuf_cache); | |||
974 | dispose_cache_job_info (pixbuf_cache->next_job + i, pixbuf_cache); | |||
975 | } | |||
976 | ||||
977 | for (i = 0; i < PAGE_CACHE_LEN (pixbuf_cache)(pixbuf_cache->start_page>=0?((pixbuf_cache->end_page - pixbuf_cache->start_page) + 1):0); i++) { | |||
978 | dispose_cache_job_info (pixbuf_cache->job_list + i, pixbuf_cache); | |||
979 | } | |||
980 | } | |||
981 | ||||
982 | ||||
983 | void | |||
984 | ev_pixbuf_cache_style_changed (EvPixbufCache *pixbuf_cache) | |||
985 | { | |||
986 | gint i; | |||
987 | ||||
988 | if (!pixbuf_cache->job_list) | |||
989 | return; | |||
990 | ||||
991 | /* FIXME: doesn't update running jobs. */ | |||
992 | for (i = 0; i < pixbuf_cache->preload_cache_size; i++) { | |||
993 | CacheJobInfo *job_info; | |||
994 | ||||
995 | job_info = pixbuf_cache->prev_job + i; | |||
996 | if (job_info->selection) { | |||
997 | cairo_surface_destroy (job_info->selection); | |||
998 | job_info->selection = NULL((void*)0); | |||
999 | job_info->selection_points.x1 = -1; | |||
1000 | } | |||
1001 | ||||
1002 | job_info = pixbuf_cache->next_job + i; | |||
1003 | if (job_info->selection) { | |||
1004 | cairo_surface_destroy (job_info->selection); | |||
1005 | job_info->selection = NULL((void*)0); | |||
1006 | job_info->selection_points.x1 = -1; | |||
1007 | } | |||
1008 | } | |||
1009 | ||||
1010 | for (i = 0; i < PAGE_CACHE_LEN (pixbuf_cache)(pixbuf_cache->start_page>=0?((pixbuf_cache->end_page - pixbuf_cache->start_page) + 1):0); i++) { | |||
1011 | CacheJobInfo *job_info; | |||
1012 | ||||
1013 | job_info = pixbuf_cache->job_list + i; | |||
1014 | if (job_info->selection) { | |||
1015 | cairo_surface_destroy (job_info->selection); | |||
1016 | job_info->selection = NULL((void*)0); | |||
1017 | job_info->selection_points.x1 = -1; | |||
1018 | } | |||
1019 | } | |||
1020 | } | |||
1021 | ||||
1022 | cairo_surface_t * | |||
1023 | ev_pixbuf_cache_get_selection_surface (EvPixbufCache *pixbuf_cache, | |||
1024 | gint page, | |||
1025 | gfloat scale) | |||
1026 | { | |||
1027 | CacheJobInfo *job_info; | |||
1028 | ||||
1029 | /* the document does not implement the selection interface */ | |||
1030 | if (!EV_IS_SELECTION (pixbuf_cache->document)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (pixbuf_cache->document)); GType __t = ((ev_selection_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) | |||
1031 | return NULL((void*)0); | |||
1032 | ||||
1033 | job_info = find_job_cache (pixbuf_cache, page); | |||
1034 | if (job_info == NULL((void*)0)) | |||
1035 | return NULL((void*)0); | |||
1036 | ||||
1037 | /* No selection on this page */ | |||
1038 | if (!job_info->points_set) | |||
1039 | return NULL((void*)0); | |||
1040 | ||||
1041 | /* If we have a running job, we just return what we have under the | |||
1042 | * assumption that it'll be updated later and we can scale it as need | |||
1043 | * be */ | |||
1044 | if (job_info->job && EV_JOB_RENDER (job_info->job)((((EvJobRender*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((job_info->job)), ((ev_job_render_get_type()))))))->include_selection) | |||
1045 | return job_info->selection; | |||
1046 | ||||
1047 | /* Now, lets see if we need to resize the image. If we do, we clear the | |||
1048 | * old one. */ | |||
1049 | clear_selection_surface_if_needed (pixbuf_cache, job_info, page, scale); | |||
1050 | ||||
1051 | /* Finally, we see if the two scales are the same, and get a new pixbuf | |||
1052 | * if needed. We do this synchronously for now. At some point, we | |||
1053 | * _should_ be able to get rid of the doc_mutex, so the synchronicity | |||
1054 | * doesn't kill us. Rendering a few glyphs should really be fast. | |||
1055 | */ | |||
1056 | if (ev_rect_cmp (&(job_info->target_points), &(job_info->selection_points))) { | |||
1057 | EvRectangle *old_points; | |||
1058 | CdkColor text, base; | |||
1059 | EvRenderContext *rc; | |||
1060 | EvPage *ev_page; | |||
1061 | ||||
1062 | /* we need to get a new selection pixbuf */ | |||
1063 | ev_document_doc_mutex_lock (); | |||
1064 | if (job_info->selection_points.x1 < 0) { | |||
1065 | g_assert (job_info->selection == NULL)do { if (job_info->selection == ((void*)0)) ; else g_assertion_message_expr ("LectorView", "ev-pixbuf-cache.c", 1065, ((const char*) (__func__ )), "job_info->selection == NULL"); } while (0); | |||
1066 | old_points = NULL((void*)0); | |||
1067 | } else { | |||
1068 | old_points = &(job_info->selection_points); | |||
1069 | } | |||
1070 | ||||
1071 | ev_page = ev_document_get_page (pixbuf_cache->document, page); | |||
1072 | rc = ev_render_context_new (ev_page, 0, scale * job_info->device_scale); | |||
1073 | g_object_unref (ev_page); | |||
1074 | ||||
1075 | get_selection_colors (EV_VIEW (pixbuf_cache->view)((((EvView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((pixbuf_cache->view)), ((ev_view_get_type ())))))), &text, &base); | |||
1076 | ev_selection_render_selection (EV_SELECTION (pixbuf_cache->document)((((EvSelection*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((pixbuf_cache->document)), ((ev_selection_get_type ()) ))))), | |||
1077 | rc, &(job_info->selection), | |||
1078 | &(job_info->target_points), | |||
1079 | old_points, | |||
1080 | job_info->selection_style, | |||
1081 | &text, &base); | |||
1082 | if (job_info->selection) | |||
1083 | set_device_scale_on_surface (job_info->selection, job_info->device_scale); | |||
1084 | job_info->selection_points = job_info->target_points; | |||
1085 | job_info->selection_scale = scale * job_info->device_scale; | |||
1086 | g_object_unref (rc); | |||
1087 | ev_document_doc_mutex_unlock (); | |||
1088 | } | |||
1089 | return job_info->selection; | |||
1090 | } | |||
1091 | ||||
1092 | cairo_region_t * | |||
1093 | ev_pixbuf_cache_get_selection_region (EvPixbufCache *pixbuf_cache, | |||
1094 | gint page, | |||
1095 | gfloat scale) | |||
1096 | { | |||
1097 | CacheJobInfo *job_info; | |||
1098 | ||||
1099 | /* the document does not implement the selection interface */ | |||
1100 | if (!EV_IS_SELECTION (pixbuf_cache->document)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (pixbuf_cache->document)); GType __t = ((ev_selection_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) | |||
1101 | return NULL((void*)0); | |||
1102 | ||||
1103 | job_info = find_job_cache (pixbuf_cache, page); | |||
1104 | if (job_info == NULL((void*)0)) | |||
1105 | return NULL((void*)0); | |||
1106 | ||||
1107 | /* No selection on this page */ | |||
1108 | if (!job_info->points_set) | |||
1109 | return NULL((void*)0); | |||
1110 | ||||
1111 | /* If we have a running job, we just return what we have under the | |||
1112 | * assumption that it'll be updated later and we can scale it as need | |||
1113 | * be */ | |||
1114 | if (job_info->job && EV_JOB_RENDER (job_info->job)((((EvJobRender*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((job_info->job)), ((ev_job_render_get_type()))))))->include_selection) | |||
1115 | return job_info->selection_region && !cairo_region_is_empty(job_info->selection_region) ? | |||
1116 | job_info->selection_region : NULL((void*)0); | |||
1117 | ||||
1118 | /* Now, lets see if we need to resize the region. If we do, we clear the | |||
1119 | * old one. */ | |||
1120 | clear_selection_region_if_needed (pixbuf_cache, job_info, page, scale); | |||
1121 | ||||
1122 | /* Finally, we see if the two scales are the same, and get a new region | |||
1123 | * if needed. | |||
1124 | */ | |||
1125 | if (ev_rect_cmp (&(job_info->target_points), &(job_info->selection_region_points))) { | |||
1126 | EvRenderContext *rc; | |||
1127 | EvPage *ev_page; | |||
1128 | ||||
1129 | ev_document_doc_mutex_lock (); | |||
1130 | ev_page = ev_document_get_page (pixbuf_cache->document, page); | |||
1131 | rc = ev_render_context_new (ev_page, 0, scale); | |||
1132 | g_object_unref (ev_page); | |||
1133 | ||||
1134 | if (job_info->selection_region) | |||
1135 | cairo_region_destroy (job_info->selection_region); | |||
1136 | job_info->selection_region = | |||
1137 | ev_selection_get_selection_region (EV_SELECTION (pixbuf_cache->document)((((EvSelection*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((pixbuf_cache->document)), ((ev_selection_get_type ()) ))))), | |||
1138 | rc, job_info->selection_style, | |||
1139 | &(job_info->target_points)); | |||
1140 | job_info->selection_region_points = job_info->target_points; | |||
1141 | job_info->selection_region_scale = scale; | |||
1142 | g_object_unref (rc); | |||
1143 | ev_document_doc_mutex_unlock (); | |||
1144 | } | |||
1145 | return job_info->selection_region && !cairo_region_is_empty(job_info->selection_region) ? | |||
1146 | job_info->selection_region : NULL((void*)0); | |||
1147 | } | |||
1148 | ||||
1149 | static void | |||
1150 | update_job_selection (CacheJobInfo *job_info, | |||
1151 | EvViewSelection *selection) | |||
1152 | { | |||
1153 | job_info->points_set = TRUE(!(0)); | |||
1154 | job_info->target_points = selection->rect; | |||
1155 | job_info->selection_style = selection->style; | |||
1156 | } | |||
1157 | ||||
1158 | static void | |||
1159 | clear_job_selection (CacheJobInfo *job_info) | |||
1160 | { | |||
1161 | job_info->points_set = FALSE(0); | |||
1162 | job_info->selection_points.x1 = -1; | |||
1163 | ||||
1164 | if (job_info->selection) { | |||
1165 | cairo_surface_destroy (job_info->selection); | |||
1166 | job_info->selection = NULL((void*)0); | |||
1167 | } | |||
1168 | ||||
1169 | if (job_info->selection_region) { | |||
1170 | cairo_region_destroy (job_info->selection_region); | |||
1171 | job_info->selection_region = NULL((void*)0); | |||
1172 | } | |||
1173 | } | |||
1174 | ||||
1175 | /* This function will reset the selection on pages that no longer have them, and | |||
1176 | * will update the target_selection on those that need it. It will _not_ free | |||
1177 | * the previous selection_list -- that's up to caller to do. | |||
1178 | */ | |||
1179 | void | |||
1180 | ev_pixbuf_cache_set_selection_list (EvPixbufCache *pixbuf_cache, | |||
1181 | GList *selection_list) | |||
1182 | { | |||
1183 | EvViewSelection *selection; | |||
1184 | GList *list = selection_list; | |||
1185 | int page; | |||
1186 | int i; | |||
1187 | ||||
1188 | g_return_if_fail (EV_IS_PIXBUF_CACHE (pixbuf_cache))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((pixbuf_cache)); GType __t = ((ev_pixbuf_cache_get_type ( ))); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("LectorView" , ((const char*) (__func__)), "EV_IS_PIXBUF_CACHE (pixbuf_cache)" ); return; } } while (0); | |||
1189 | ||||
1190 | if (!EV_IS_SELECTION (pixbuf_cache->document)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (pixbuf_cache->document)); GType __t = ((ev_selection_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) | |||
1191 | return; | |||
1192 | ||||
1193 | if (pixbuf_cache->start_page == -1 || pixbuf_cache->end_page == -1) | |||
1194 | return; | |||
1195 | ||||
1196 | /* We check each area to see what needs updating, and what needs freeing; */ | |||
1197 | page = pixbuf_cache->start_page - pixbuf_cache->preload_cache_size; | |||
1198 | for (i = 0; i < pixbuf_cache->preload_cache_size; i++) { | |||
1199 | if (page < 0) { | |||
1200 | page ++; | |||
1201 | continue; | |||
1202 | } | |||
1203 | ||||
1204 | selection = NULL((void*)0); | |||
1205 | while (list) { | |||
1206 | if (((EvViewSelection *)list->data)->page == page) { | |||
1207 | selection = list->data; | |||
1208 | break; | |||
1209 | } else if (((EvViewSelection *)list->data)->page > page) | |||
1210 | break; | |||
1211 | list = list->next; | |||
1212 | } | |||
1213 | ||||
1214 | if (selection) | |||
1215 | update_job_selection (pixbuf_cache->prev_job + i, selection); | |||
1216 | else | |||
1217 | clear_job_selection (pixbuf_cache->prev_job + i); | |||
1218 | page ++; | |||
1219 | } | |||
1220 | ||||
1221 | page = pixbuf_cache->start_page; | |||
1222 | for (i = 0; i < PAGE_CACHE_LEN (pixbuf_cache)(pixbuf_cache->start_page>=0?((pixbuf_cache->end_page - pixbuf_cache->start_page) + 1):0); i++) { | |||
1223 | selection = NULL((void*)0); | |||
1224 | while (list) { | |||
1225 | if (((EvViewSelection *)list->data)->page == page) { | |||
1226 | selection = list->data; | |||
1227 | break; | |||
1228 | } else if (((EvViewSelection *)list->data)->page > page) | |||
1229 | break; | |||
1230 | list = list->next; | |||
1231 | } | |||
1232 | ||||
1233 | if (selection) | |||
1234 | update_job_selection (pixbuf_cache->job_list + i, selection); | |||
1235 | else | |||
1236 | clear_job_selection (pixbuf_cache->job_list + i); | |||
1237 | page ++; | |||
1238 | } | |||
1239 | ||||
1240 | for (i = 0; i < pixbuf_cache->preload_cache_size; i++) { | |||
1241 | if (page >= ev_document_get_n_pages (pixbuf_cache->document)) | |||
1242 | break; | |||
1243 | ||||
1244 | selection = NULL((void*)0); | |||
1245 | while (list) { | |||
1246 | if (((EvViewSelection *)list->data)->page == page) { | |||
1247 | selection = list->data; | |||
1248 | break; | |||
1249 | } else if (((EvViewSelection *)list->data)->page > page) | |||
1250 | break; | |||
1251 | list = list->next; | |||
1252 | } | |||
1253 | ||||
1254 | if (selection) | |||
1255 | update_job_selection (pixbuf_cache->next_job + i, selection); | |||
1256 | else | |||
1257 | clear_job_selection (pixbuf_cache->next_job + i); | |||
1258 | page ++; | |||
1259 | } | |||
1260 | } | |||
1261 | ||||
1262 | ||||
1263 | /* Returns what the pixbuf cache thinks is */ | |||
1264 | ||||
1265 | GList * | |||
1266 | ev_pixbuf_cache_get_selection_list (EvPixbufCache *pixbuf_cache) | |||
1267 | { | |||
1268 | EvViewSelection *selection; | |||
1269 | GList *retval = NULL((void*)0); | |||
1270 | int page; | |||
1271 | int i; | |||
1272 | ||||
1273 | g_return_val_if_fail (EV_IS_PIXBUF_CACHE (pixbuf_cache), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((pixbuf_cache)); GType __t = ((ev_pixbuf_cache_get_type ( ))); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("LectorView" , ((const char*) (__func__)), "EV_IS_PIXBUF_CACHE (pixbuf_cache)" ); return (((void*)0)); } } while (0); | |||
1274 | ||||
1275 | if (pixbuf_cache->start_page == -1 || pixbuf_cache->end_page == -1) | |||
1276 | return NULL((void*)0); | |||
1277 | ||||
1278 | /* We check each area to see what needs updating, and what needs freeing; */ | |||
1279 | page = pixbuf_cache->start_page - pixbuf_cache->preload_cache_size; | |||
1280 | for (i = 0; i < pixbuf_cache->preload_cache_size; i++) { | |||
1281 | if (page < 0) { | |||
1282 | page ++; | |||
1283 | continue; | |||
1284 | } | |||
1285 | ||||
1286 | if (pixbuf_cache->prev_job[i].selection_points.x1 != -1) { | |||
1287 | selection = g_slice_new0 (EvViewSelection)((EvViewSelection*) g_slice_alloc0 (sizeof (EvViewSelection)) ); | |||
1288 | selection->page = page; | |||
1289 | selection->rect = pixbuf_cache->prev_job[i].selection_points; | |||
1290 | if (pixbuf_cache->prev_job[i].selection_region) | |||
1291 | selection->covered_region = cairo_region_reference (pixbuf_cache->prev_job[i].selection_region); | |||
1292 | retval = g_list_prepend (retval, selection); | |||
1293 | } | |||
1294 | ||||
1295 | page ++; | |||
1296 | } | |||
1297 | ||||
1298 | page = pixbuf_cache->start_page; | |||
1299 | for (i = 0; i < PAGE_CACHE_LEN (pixbuf_cache)(pixbuf_cache->start_page>=0?((pixbuf_cache->end_page - pixbuf_cache->start_page) + 1):0); i++) { | |||
1300 | if (pixbuf_cache->job_list[i].selection_points.x1 != -1) { | |||
1301 | selection = g_slice_new0 (EvViewSelection)((EvViewSelection*) g_slice_alloc0 (sizeof (EvViewSelection)) ); | |||
1302 | selection->page = page; | |||
1303 | selection->rect = pixbuf_cache->job_list[i].selection_points; | |||
1304 | if (pixbuf_cache->job_list[i].selection_region) | |||
1305 | selection->covered_region = cairo_region_reference (pixbuf_cache->job_list[i].selection_region); | |||
1306 | retval = g_list_prepend (retval, selection); | |||
1307 | } | |||
1308 | ||||
1309 | page ++; | |||
1310 | } | |||
1311 | ||||
1312 | for (i = 0; i < pixbuf_cache->preload_cache_size; i++) { | |||
1313 | if (page >= ev_document_get_n_pages (pixbuf_cache->document)) | |||
1314 | break; | |||
1315 | ||||
1316 | if (pixbuf_cache->next_job[i].selection_points.x1 != -1) { | |||
1317 | selection = g_slice_new0 (EvViewSelection)((EvViewSelection*) g_slice_alloc0 (sizeof (EvViewSelection)) ); | |||
1318 | selection->page = page; | |||
1319 | selection->rect = pixbuf_cache->next_job[i].selection_points; | |||
1320 | if (pixbuf_cache->next_job[i].selection_region) | |||
1321 | selection->covered_region = cairo_region_reference (pixbuf_cache->next_job[i].selection_region); | |||
1322 | retval = g_list_prepend (retval, selection); | |||
1323 | } | |||
1324 | ||||
1325 | page ++; | |||
1326 | } | |||
1327 | ||||
1328 | return g_list_reverse (retval); | |||
1329 | } | |||
1330 | ||||
1331 | void | |||
1332 | ev_pixbuf_cache_reload_page (EvPixbufCache *pixbuf_cache, | |||
1333 | cairo_region_t *region, | |||
1334 | gint page, | |||
1335 | gint rotation, | |||
1336 | gdouble scale) | |||
1337 | { | |||
1338 | CacheJobInfo *job_info; | |||
1339 | gint width, height; | |||
1340 | ||||
1341 | job_info = find_job_cache (pixbuf_cache, page); | |||
1342 | if (job_info == NULL((void*)0)) | |||
1343 | return; | |||
1344 | ||||
1345 | _get_page_size_for_scale_and_rotation (pixbuf_cache->document, | |||
1346 | page, scale, rotation, | |||
1347 | &width, &height); | |||
1348 | add_job (pixbuf_cache, job_info, region, | |||
1349 | width, height, page, rotation, scale, | |||
1350 | EV_JOB_PRIORITY_URGENT); | |||
1351 | } | |||
1352 | ||||
1353 |