99 #define FIRST_VISIBLE_PREV(pixbuf_cache) \
100 (MAX (0, pixbuf_cache->preload_cache_size - pixbuf_cache->start_page))
101 #define VISIBLE_NEXT_LEN(pixbuf_cache) \
102 (MIN(pixbuf_cache->preload_cache_size, ev_document_get_n_pages (pixbuf_cache->document) - (1 + pixbuf_cache->end_page)))
103 #define PAGE_CACHE_LEN(pixbuf_cache) \
104 ((pixbuf_cache->end_page - pixbuf_cache->start_page) + 1)
106 #define MAX_PRELOADED_PAGES 3
113 pixbuf_cache->start_page = -1;
114 pixbuf_cache->end_page = -1;
120 GObjectClass *object_class;
122 object_class = G_OBJECT_CLASS (
class);
128 g_signal_new (
"job-finished",
129 G_OBJECT_CLASS_TYPE (object_class),
130 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
133 g_cclosure_marshal_VOID__POINTER,
161 g_object_unref (pixbuf_cache->
model);
163 G_OBJECT_CLASS (ev_pixbuf_cache_parent_class)->finalize (
object);
170 g_signal_handlers_disconnect_by_func (job_info->
job,
174 g_object_unref (job_info->
job);
175 job_info->
job = NULL;
182 if (job_info == NULL)
189 cairo_surface_destroy (job_info->
surface);
193 cairo_region_destroy (job_info->
region);
197 cairo_surface_destroy (job_info->
selection);
225 G_OBJECT_CLASS (ev_pixbuf_cache_parent_class)->dispose (
object);
238 pixbuf_cache->
view = view;
239 pixbuf_cache->
model = g_object_ref (model);
250 if (pixbuf_cache->
max_size == max_size)
253 if (pixbuf_cache->
max_size > max_size)
261 #ifdef HAVE_HIDPI_SUPPORT
262 return gtk_widget_get_scale_factor (pixbuf_cache->
view);
272 #ifdef HAVE_HIDPI_SUPPORT
273 cairo_surface_set_device_scale (surface, device_scale, device_scale);
275 g_return_if_fail (device_scale == 1);
285 cairo_surface_destroy (job_info->
surface);
287 job_info->
surface = cairo_surface_reference (job_render->
surface);
296 cairo_surface_destroy (job_info->
selection);
319 end_job (job_info, pixbuf_cache);
334 g_object_unref (job);
341 job_info->
job = NULL;
342 g_object_unref (job);
363 if (job_info->
job == NULL)
378 end_job (job_info, pixbuf_cache);
391 int new_preload_cache_size,
400 if (page < (start_page - new_preload_cache_size) ||
401 page > (end_page + new_preload_cache_size)) {
407 if (page < start_page) {
408 page_offset = (page - (start_page - new_preload_cache_size));
410 g_assert (page_offset >= 0 &&
411 page_offset < new_preload_cache_size);
412 target_page = new_prev_job + page_offset;
414 }
else if (page > end_page) {
415 page_offset = (page - (end_page + 1));
417 g_assert (page_offset >= 0 &&
418 page_offset < new_preload_cache_size);
419 target_page = new_next_job + page_offset;
422 page_offset = page - start_page;
423 g_assert (page_offset >= 0 &&
424 page_offset <= ((end_page - start_page) + 1));
426 target_page = new_job_list + page_offset;
429 *target_page = *job_info;
430 job_info->
job = NULL;
434 if (new_priority != priority && target_page->
job) {
448 page_index, scale, rotation,
450 return height * cairo_format_stride_for_width (CAIRO_FORMAT_RGB24, width);
460 gsize range_size = 0;
461 gint new_preload_cache_size = 0;
466 for (i = start_page; i <= end_page; i++) {
470 if (range_size >= pixbuf_cache->
max_size)
471 return new_preload_cache_size;
474 while (((start_page - i > 0) || (end_page + i < n_pages)) &&
477 gboolean updated =
FALSE;
479 if (end_page + i < n_pages) {
482 if (page_size + range_size <= pixbuf_cache->max_size) {
483 range_size += page_size;
484 new_preload_cache_size++;
491 if (start_page - i > 0) {
494 if (page_size + range_size <= pixbuf_cache->max_size) {
495 range_size += page_size;
497 new_preload_cache_size++;
505 return new_preload_cache_size;
518 gint new_preload_cache_size;
519 guint new_job_list_len;
528 pixbuf_cache->
end_page == end_page &&
532 new_job_list_len = (end_page - start_page) + 1;
533 new_job_list = g_slice_alloc0 (
sizeof (
CacheJobInfo) * new_job_list_len);
534 if (new_preload_cache_size > 0) {
535 new_prev_job = g_slice_alloc0 (
sizeof (
CacheJobInfo) * new_preload_cache_size);
536 new_next_job = g_slice_alloc0 (
sizeof (
CacheJobInfo) * new_preload_cache_size);
550 new_job_list, new_prev_job, new_next_job,
551 new_preload_cache_size,
558 for (i = 0; i < PAGE_CACHE_LEN (pixbuf_cache) && page >= 0; i++) {
561 new_job_list, new_prev_job, new_next_job,
562 new_preload_cache_size,
573 new_job_list, new_prev_job, new_next_job,
574 new_preload_cache_size,
596 pixbuf_cache->
job_list = new_job_list;
597 pixbuf_cache->
prev_job = new_prev_job;
598 pixbuf_cache->
next_job = new_next_job;
614 if (page < pixbuf_cache->start_page) {
617 g_assert (page_offset >= 0 &&
618 page_offset < pixbuf_cache->preload_cache_size);
619 return pixbuf_cache->
prev_job + page_offset;
622 if (page > pixbuf_cache->
end_page) {
623 page_offset = (page - (pixbuf_cache->
end_page + 1));
625 g_assert (page_offset >= 0 &&
626 page_offset < pixbuf_cache->preload_cache_size);
627 return pixbuf_cache->
next_job + page_offset;
630 page_offset = page - pixbuf_cache->
start_page;
631 g_assert (page_offset >= 0 &&
633 return pixbuf_cache->
job_list + page_offset;
660 text->red = CLAMP ((guint) (fg.red * 65535), 0, 65535);
661 text->green = CLAMP ((guint) (fg.green * 65535), 0, 65535);
662 text->blue = CLAMP ((guint) (fg.blue * 65535), 0, 65535);
665 base->red = CLAMP ((guint) (bg.red * 65535), 0, 65535);
666 base->green = CLAMP ((guint) (bg.green * 65535), 0, 65535);
667 base->blue = CLAMP ((guint) (bg.blue * 65535), 0, 65535);
673 cairo_region_t *region,
685 cairo_region_destroy (job_info->
region);
686 job_info->
region = region ? cairo_region_reference (region) : NULL;
689 end_job (job_info, pixbuf_cache);
707 g_signal_connect (job_info->
job,
"finished",
728 page, scale, rotation,
733 cairo_image_surface_get_width (job_info->
surface) == width * device_scale &&
734 cairo_image_surface_get_height (job_info->
surface) == height * device_scale)
740 cairo_surface_destroy (job_info->
surface);
745 cairo_surface_destroy (job_info->
selection);
750 add_job (pixbuf_cache, job_info, NULL,
751 width, height, page, rotation, scale,
765 job_info = (pixbuf_cache->
prev_job + i);
769 page, rotation, scale,
784 job_info = (pixbuf_cache->
next_job + i);
785 page = pixbuf_cache->
end_page + 1 + i;
788 page, rotation, scale,
803 job_info = (pixbuf_cache->
job_list + i);
807 page, rotation, scale,
825 if (start_page < pixbuf_cache->start_page)
828 if (end_page > pixbuf_cache->
end_page)
834 if (end_page < pixbuf_cache->end_page)
844 GList *selection_list)
853 g_return_if_fail (end_page >= start_page);
875 gboolean inverted_colors)
887 job_info = pixbuf_cache->
prev_job + i;
888 if (job_info && job_info->
surface)
891 job_info = pixbuf_cache->
next_job + i;
892 if (job_info && job_info->
surface)
899 job_info = pixbuf_cache->
job_list + i;
900 if (job_info && job_info->
surface)
912 if (job_info == NULL)
958 cairo_surface_destroy (job_info->
selection);
1011 job_info = pixbuf_cache->
prev_job + i;
1013 cairo_surface_destroy (job_info->
selection);
1018 job_info = pixbuf_cache->
next_job + i;
1020 cairo_surface_destroy (job_info->
selection);
1029 job_info = pixbuf_cache->
job_list + i;
1031 cairo_surface_destroy (job_info->
selection);
1050 if (job_info == NULL)
1074 GdkColor text, base;
1092 0, &width, &height);
1096 g_object_unref (ev_page);
1109 g_object_unref (rc);
1127 if (job_info == NULL)
1162 g_object_unref (ev_page);
1172 g_object_unref (rc);
1195 cairo_surface_destroy (job_info->
selection);
1211 GList *selection_list)
1214 GList *list = selection_list;
1237 selection = list->data;
1256 selection = list->data;
1277 selection = list->data;
1299 GList *retval = NULL;
1318 selection->
page = page;
1322 retval = g_list_prepend (retval, selection);
1332 selection->
page = page;
1336 retval = g_list_prepend (retval, selection);
1348 selection->
page = page;
1352 retval = g_list_prepend (retval, selection);
1358 return g_list_reverse (retval);
1363 cairo_region_t *region,
1372 if (job_info == NULL)
1376 page, scale, rotation,
1378 add_job (pixbuf_cache, job_info, region,
1379 width, height, page, rotation, scale,