[evince] libview: Split ev_pixbuf_cache_get_selection_surface into two functions



commit 90d658067cf0e0cd04f5222d89393d29ea5a9f92
Author: Jason Crain <jason aquaticape us>
Date:   Mon Jun 17 19:31:03 2013 +0200

    libview: Split ev_pixbuf_cache_get_selection_surface into two functions
    
    ev_pixbuf_cache_get_selection_surface returns the selection surface, and
    new function ev_pixbuf_cache_get_selection_region returns the selection
    region.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=669022

 libview/ev-pixbuf-cache.c |  121 ++++++++++++++++++++++++++++++++++++---------
 libview/ev-pixbuf-cache.h |    6 ++-
 libview/ev-view.c         |   16 +++---
 3 files changed, 109 insertions(+), 34 deletions(-)
---
diff --git a/libview/ev-pixbuf-cache.c b/libview/ev-pixbuf-cache.c
index 8f81481..852baf5 100644
--- a/libview/ev-pixbuf-cache.c
+++ b/libview/ev-pixbuf-cache.c
@@ -17,14 +17,17 @@ typedef struct _CacheJobInfo
        /* Selection data. 
         * Selection_points are the coordinates encapsulated in selection.
         * target_points is the target selection size. */
-       EvRectangle      selection_points;
        EvRectangle      target_points;
        EvSelectionStyle selection_style;
        gboolean         points_set;
        
        cairo_surface_t *selection;
-       cairo_region_t  *selection_region;
        gdouble          selection_scale;
+       EvRectangle      selection_points;
+
+       cairo_region_t *selection_region;
+       gdouble         selection_region_scale;
+       EvRectangle     selection_region_points;
 } CacheJobInfo;
 
 struct _EvPixbufCache
@@ -261,10 +264,14 @@ copy_job_to_job_info (EvJobRender   *job_render,
                }
 
                job_info->selection_points = job_render->selection_points;
-               job_info->selection_region = cairo_region_reference (job_render->selection_region);
                job_info->selection = cairo_surface_reference (job_render->selection);
                job_info->selection_scale = job_render->scale;
                g_assert (job_info->selection_points.x1 >= 0);
+
+               job_info->selection_region_points = job_render->selection_points;
+               job_info->selection_region = cairo_region_reference (job_render->selection_region);
+               job_info->selection_region_scale = job_render->scale;
+
                job_info->points_set = TRUE;
        }
 
@@ -833,11 +840,22 @@ new_selection_surface_needed (EvPixbufCache *pixbuf_cache,
        return FALSE;
 }
 
+static gboolean
+new_selection_region_needed (EvPixbufCache *pixbuf_cache,
+                            CacheJobInfo  *job_info,
+                            gint           page,
+                            gfloat         scale)
+{
+       if (job_info->selection_region || job_info->points_set)
+               return job_info->selection_region_scale != scale;
+       return FALSE;
+}
+
 static void
-clear_selection_if_needed (EvPixbufCache *pixbuf_cache,
-                          CacheJobInfo  *job_info,
-                          gint           page,
-                          gfloat         scale)
+clear_selection_surface_if_needed (EvPixbufCache *pixbuf_cache,
+                                   CacheJobInfo  *job_info,
+                                   gint           page,
+                                   gfloat         scale)
 {
        if (new_selection_surface_needed (pixbuf_cache, job_info, page, scale)) {
                if (job_info->selection)
@@ -847,6 +865,20 @@ clear_selection_if_needed (EvPixbufCache *pixbuf_cache,
        }
 }
 
+static void
+clear_selection_region_if_needed (EvPixbufCache *pixbuf_cache,
+                                  CacheJobInfo  *job_info,
+                                  gint           page,
+                                  gfloat         scale)
+{
+       if (new_selection_region_needed (pixbuf_cache, job_info, page, scale)) {
+               if (job_info->selection_region)
+                       cairo_region_destroy (job_info->selection_region);
+               job_info->selection_region = NULL;
+               job_info->selection_region_points.x1 = -1;
+       }
+}
+
 /* Clears the cache of jobs and pixbufs.
  */
 void
@@ -910,8 +942,7 @@ ev_pixbuf_cache_style_changed (EvPixbufCache *pixbuf_cache)
 cairo_surface_t *
 ev_pixbuf_cache_get_selection_surface (EvPixbufCache   *pixbuf_cache,
                                       gint             page,
-                                      gfloat           scale,
-                                      cairo_region_t **region)
+                                      gfloat           scale)
 {
        CacheJobInfo *job_info;
 
@@ -930,15 +961,12 @@ ev_pixbuf_cache_get_selection_surface (EvPixbufCache   *pixbuf_cache,
        /* If we have a running job, we just return what we have under the
         * assumption that it'll be updated later and we can scale it as need
         * be */
-       if (job_info->job && EV_JOB_RENDER (job_info->job)->include_selection) {
-               if (region)
-                       *region = job_info->selection_region;
+       if (job_info->job && EV_JOB_RENDER (job_info->job)->include_selection)
                return job_info->selection;
-       }
 
        /* Now, lets see if we need to resize the image.  If we do, we clear the
         * old one. */
-       clear_selection_if_needed (pixbuf_cache, job_info, page, scale);
+       clear_selection_surface_if_needed (pixbuf_cache, job_info, page, scale);
 
        /* Finally, we see if the two scales are the same, and get a new pixbuf
         * if needed.  We do this synchronously for now.  At some point, we
@@ -964,15 +992,7 @@ ev_pixbuf_cache_get_selection_surface (EvPixbufCache   *pixbuf_cache,
                rc = ev_render_context_new (ev_page, 0, scale);
                g_object_unref (ev_page);
 
-               if (job_info->selection_region)
-                       cairo_region_destroy (job_info->selection_region);
-               job_info->selection_region =
-                       ev_selection_get_selection_region (EV_SELECTION (pixbuf_cache->document),
-                                                          rc, job_info->selection_style,
-                                                          &(job_info->target_points));
-
                get_selection_colors (EV_VIEW (pixbuf_cache->view), &text, &base);
-
                ev_selection_render_selection (EV_SELECTION (pixbuf_cache->document),
                                               rc, &(job_info->selection),
                                               &(job_info->target_points),
@@ -984,11 +1004,64 @@ ev_pixbuf_cache_get_selection_surface (EvPixbufCache   *pixbuf_cache,
                g_object_unref (rc);
                ev_document_doc_mutex_unlock ();
        }
-       if (region)
-               *region = job_info->selection_region;
        return job_info->selection;
 }
 
+cairo_region_t *
+ev_pixbuf_cache_get_selection_region (EvPixbufCache *pixbuf_cache,
+                                     gint           page,
+                                     gfloat         scale)
+{
+       CacheJobInfo *job_info;
+
+       /* the document does not implement the selection interface */
+       if (!EV_IS_SELECTION (pixbuf_cache->document))
+               return NULL;
+
+       job_info = find_job_cache (pixbuf_cache, page);
+       if (job_info == NULL)
+               return NULL;
+
+       /* No selection on this page */
+       if (!job_info->points_set)
+               return NULL;
+
+       /* If we have a running job, we just return what we have under the
+        * assumption that it'll be updated later and we can scale it as need
+        * be */
+       if (job_info->job && EV_JOB_RENDER (job_info->job)->include_selection)
+               return job_info->selection_region;
+
+       /* Now, lets see if we need to resize the region.  If we do, we clear the
+        * old one. */
+       clear_selection_region_if_needed (pixbuf_cache, job_info, page, scale);
+
+       /* Finally, we see if the two scales are the same, and get a new region
+        * if needed.
+        */
+       if (ev_rect_cmp (&(job_info->target_points), &(job_info->selection_region_points))) {
+               EvRenderContext *rc;
+               EvPage *ev_page;
+
+               ev_document_doc_mutex_lock ();
+               ev_page = ev_document_get_page (pixbuf_cache->document, page);
+               rc = ev_render_context_new (ev_page, 0, scale);
+               g_object_unref (ev_page);
+
+               if (job_info->selection_region)
+                       cairo_region_destroy (job_info->selection_region);
+               job_info->selection_region =
+                       ev_selection_get_selection_region (EV_SELECTION (pixbuf_cache->document),
+                                                          rc, job_info->selection_style,
+                                                          &(job_info->target_points));
+               job_info->selection_region_points = job_info->target_points;
+               job_info->selection_region_scale = scale;
+               g_object_unref (rc);
+               ev_document_doc_mutex_unlock ();
+       }
+       return job_info->selection_region;
+}
+
 static void
 update_job_selection (CacheJobInfo    *job_info,
                      EvViewSelection *selection)
diff --git a/libview/ev-pixbuf-cache.h b/libview/ev-pixbuf-cache.h
index 2faf2a7..493807e 100644
--- a/libview/ev-pixbuf-cache.h
+++ b/libview/ev-pixbuf-cache.h
@@ -78,8 +78,10 @@ void           ev_pixbuf_cache_set_inverted_colors  (EvPixbufCache *pixbuf_cache
 /* Selection */
 cairo_surface_t *ev_pixbuf_cache_get_selection_surface (EvPixbufCache   *pixbuf_cache,
                                                        gint             page,
-                                                       gfloat           scale,
-                                                       cairo_region_t **region);
+                                                       gfloat           scale);
+cairo_region_t *ev_pixbuf_cache_get_selection_region (EvPixbufCache *pixbuf_cache,
+                                                     gint           page,
+                                                     gfloat         scale);
 void           ev_pixbuf_cache_set_selection_list   (EvPixbufCache *pixbuf_cache,
                                                     GList         *selection_list);
 GList         *ev_pixbuf_cache_get_selection_list   (EvPixbufCache *pixbuf_cache);
diff --git a/libview/ev-view.c b/libview/ev-view.c
index 6c99038..d0928b4 100644
--- a/libview/ev-view.c
+++ b/libview/ev-view.c
@@ -5298,14 +5298,16 @@ draw_one_page (EvView       *view,
 
                selection_surface = ev_pixbuf_cache_get_selection_surface (view->pixbuf_cache,
                                                                           page,
-                                                                          view->scale,
-                                                                          &region);
+                                                                          view->scale);
                if (selection_surface) {
                        draw_surface (cr, selection_surface, overlap.x, overlap.y, offset_x, offset_y,
                                      width, height);
                        return;
                }
 
+               region = ev_pixbuf_cache_get_selection_region (view->pixbuf_cache,
+                                                              page,
+                                                              view->scale);
                if (region) {
                        double scale_x, scale_y;
                        GdkRGBA color;
@@ -7049,13 +7051,11 @@ merge_selection_region (EvView *view,
                /* seed the cache with a new page.  We are going to need the new
                 * region too. */
                if (new_sel) {
-                       cairo_region_t *tmp_region = NULL;
-
-                       ev_pixbuf_cache_get_selection_surface (view->pixbuf_cache,
-                                                              cur_page,
-                                                              view->scale,
-                                                              &tmp_region);
+                       cairo_region_t *tmp_region;
 
+                       tmp_region = ev_pixbuf_cache_get_selection_region (view->pixbuf_cache,
+                                                                          cur_page,
+                                                                          view->scale);
                        if (tmp_region && !cairo_region_is_empty (tmp_region)) {
                                new_sel->covered_region = cairo_region_reference (tmp_region);
                        }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]