[evince] libview: Draw selection highlight from region
- From: Carlos Garcia Campos <carlosgc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evince] libview: Draw selection highlight from region
- Date: Mon, 17 Jun 2013 17:32:08 +0000 (UTC)
commit 9e89fb122fd02abcb1a9f5b57d92ea20e325f1ad
Author: Jason Crain <jason aquaticape us>
Date: Sat Jun 15 10:43:08 2013 -0500
libview: Draw selection highlight from region
Allows a fallback for backends which can implement get_selection_region
but not render_selection. Changes ev-pixbuf-cache so a redraw is only
done when the scale changes.
https://bugzilla.gnome.org/show_bug.cgi?id=669022
libview/ev-pixbuf-cache.c | 46 +++++++++++------------------
libview/ev-view-private.h | 3 ++
libview/ev-view.c | 71 ++++++++++++++++++++++++++++++++++++++-------
3 files changed, 80 insertions(+), 40 deletions(-)
---
diff --git a/libview/ev-pixbuf-cache.c b/libview/ev-pixbuf-cache.c
index 98719a3..8f81481 100644
--- a/libview/ev-pixbuf-cache.c
+++ b/libview/ev-pixbuf-cache.c
@@ -24,6 +24,7 @@ typedef struct _CacheJobInfo
cairo_surface_t *selection;
cairo_region_t *selection_region;
+ gdouble selection_scale;
} CacheJobInfo;
struct _EvPixbufCache
@@ -262,6 +263,7 @@ 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->points_set = TRUE;
}
@@ -602,21 +604,17 @@ ev_pixbuf_cache_clear_job_sizes (EvPixbufCache *pixbuf_cache,
}
static void
-get_selection_colors (GtkWidget *widget, GdkColor *text, GdkColor *base)
+get_selection_colors (EvView *view, GdkColor *text, GdkColor *base)
{
- GtkStyleContext *context = gtk_widget_get_style_context (widget);
- GtkStateFlags state = 0;
- GdkRGBA fg, bg;
+ GdkRGBA fg, bg;
- state |= gtk_widget_has_focus (widget) ? GTK_STATE_FLAG_SELECTED : GTK_STATE_FLAG_ACTIVE;
+ _ev_view_get_selection_colors (view, &bg, &fg);
- gtk_style_context_get_color (context, state, &fg);
text->pixel = 0;
text->red = CLAMP ((guint) (fg.red * 65535), 0, 65535);
text->green = CLAMP ((guint) (fg.green * 65535), 0, 65535);
text->blue = CLAMP ((guint) (fg.blue * 65535), 0, 65535);
- gtk_style_context_get_background_color (context, state, &bg);
base->pixel = 0;
base->red = CLAMP ((guint) (bg.red * 65535), 0, 65535);
base->green = CLAMP ((guint) (bg.green * 65535), 0, 65535);
@@ -647,7 +645,7 @@ add_job (EvPixbufCache *pixbuf_cache,
if (new_selection_surface_needed (pixbuf_cache, job_info, page, scale)) {
GdkColor text, base;
- get_selection_colors (pixbuf_cache->view, &text, &base);
+ get_selection_colors (EV_VIEW (pixbuf_cache->view), &text, &base);
ev_job_render_set_selection_info (EV_JOB_RENDER (job_info->job),
&(job_info->target_points),
job_info->selection_style,
@@ -830,24 +828,8 @@ new_selection_surface_needed (EvPixbufCache *pixbuf_cache,
gint page,
gfloat scale)
{
- if (job_info->selection) {
- gint width, height;
- gint selection_width, selection_height;
-
- _get_page_size_for_scale_and_rotation (pixbuf_cache->document,
- page, scale, 0,
- &width, &height);
-
- selection_width = cairo_image_surface_get_width (job_info->selection);
- selection_height = cairo_image_surface_get_height (job_info->selection);
-
- if (width != selection_width || height != selection_height)
- return TRUE;
- } else {
- if (job_info->points_set)
- return TRUE;
- }
-
+ if (job_info->selection || job_info->points_set)
+ return job_info->selection_scale != scale;
return FALSE;
}
@@ -902,12 +884,14 @@ ev_pixbuf_cache_style_changed (EvPixbufCache *pixbuf_cache)
if (job_info->selection) {
cairo_surface_destroy (job_info->selection);
job_info->selection = NULL;
+ job_info->selection_points.x1 = -1;
}
job_info = pixbuf_cache->next_job + i;
if (job_info->selection) {
cairo_surface_destroy (job_info->selection);
job_info->selection = NULL;
+ job_info->selection_points.x1 = -1;
}
}
@@ -918,6 +902,7 @@ ev_pixbuf_cache_style_changed (EvPixbufCache *pixbuf_cache)
if (job_info->selection) {
cairo_surface_destroy (job_info->selection);
job_info->selection = NULL;
+ job_info->selection_points.x1 = -1;
}
}
}
@@ -945,8 +930,11 @@ 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 (job_info->job && EV_JOB_RENDER (job_info->job)->include_selection) {
+ if (region)
+ *region = job_info->selection_region;
return job_info->selection;
+ }
/* Now, lets see if we need to resize the image. If we do, we clear the
* old one. */
@@ -969,7 +957,6 @@ ev_pixbuf_cache_get_selection_surface (EvPixbufCache *pixbuf_cache,
g_assert (job_info->selection == NULL);
old_points = NULL;
} else {
- g_assert (job_info->selection != NULL);
old_points = &(job_info->selection_points);
}
@@ -984,7 +971,7 @@ ev_pixbuf_cache_get_selection_surface (EvPixbufCache *pixbuf_cache,
rc, job_info->selection_style,
&(job_info->target_points));
- get_selection_colors (pixbuf_cache->view, &text, &base);
+ get_selection_colors (EV_VIEW (pixbuf_cache->view), &text, &base);
ev_selection_render_selection (EV_SELECTION (pixbuf_cache->document),
rc, &(job_info->selection),
@@ -993,6 +980,7 @@ ev_pixbuf_cache_get_selection_surface (EvPixbufCache *pixbuf_cache,
job_info->selection_style,
&text, &base);
job_info->selection_points = job_info->target_points;
+ job_info->selection_scale = scale;
g_object_unref (rc);
ev_document_doc_mutex_unlock ();
}
diff --git a/libview/ev-view-private.h b/libview/ev-view-private.h
index ebf6a0a..45d1079 100644
--- a/libview/ev-view-private.h
+++ b/libview/ev-view-private.h
@@ -260,6 +260,9 @@ void _ev_view_transform_doc_rect_to_view_rect (EvView *view,
int page,
EvRectangle *doc_rect,
GdkRectangle *view_rect);
+void _ev_view_get_selection_colors (EvView *view,
+ GdkRGBA *bg_color,
+ GdkRGBA *fg_color);
#endif /* __EV_VIEW_PRIVATE_H__ */
diff --git a/libview/ev-view.c b/libview/ev-view.c
index 8b3d794..6c99038 100644
--- a/libview/ev-view.c
+++ b/libview/ev-view.c
@@ -5183,6 +5183,45 @@ draw_surface (cairo_t *cr,
cairo_restore (cr);
}
+void
+_ev_view_get_selection_colors (EvView *view,
+ GdkRGBA *bg_color,
+ GdkRGBA *fg_color)
+{
+ GtkWidget *widget = GTK_WIDGET (view);
+ GtkStateFlags state;
+ GtkStyleContext *context;
+
+ state = gtk_widget_has_focus (widget) ? GTK_STATE_FLAG_SELECTED : GTK_STATE_FLAG_ACTIVE;
+ context = gtk_widget_get_style_context (widget);
+
+ if (bg_color)
+ gtk_style_context_get_background_color (context, state, bg_color);
+
+ if (fg_color)
+ gtk_style_context_get_color (context, state, fg_color);
+}
+
+static void
+draw_selection_region (cairo_t *cr,
+ cairo_region_t *region,
+ GdkRGBA *color,
+ gint x,
+ gint y,
+ gdouble scale_x,
+ gdouble scale_y)
+{
+ cairo_save (cr);
+ cairo_translate (cr, x, y);
+ cairo_scale (cr, scale_x, scale_y);
+ gdk_cairo_region (cr, region);
+ cairo_set_source_rgb (cr, color->red, color->green, color->blue);
+ cairo_set_operator (cr, CAIRO_OPERATOR_MULTIPLY);
+ cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
+ cairo_fill (cr);
+ cairo_restore (cr);
+}
+
static void
draw_one_page (EvView *view,
gint page,
@@ -5231,6 +5270,7 @@ draw_one_page (EvView *view,
cairo_surface_t *page_surface = NULL;
cairo_surface_t *selection_surface = NULL;
gint offset_x, offset_y;
+ cairo_region_t *region = NULL;
page_surface = ev_pixbuf_cache_get_surface (view->pixbuf_cache, page);
@@ -5251,22 +5291,31 @@ draw_one_page (EvView *view,
offset_y = overlap.y - real_page_area.y;
draw_surface (cr, page_surface, overlap.x, overlap.y, offset_x, offset_y, width, height);
-
+
/* Get the selection pixbuf iff we have something to draw */
- if (find_selection_for_page (view, page) &&
- view->selection_mode == EV_VIEW_SELECTION_TEXT) {
- selection_surface =
- ev_pixbuf_cache_get_selection_surface (view->pixbuf_cache,
- page,
- view->scale,
- NULL);
- }
+ if (!find_selection_for_page (view, page))
+ return;
- if (!selection_surface) {
+ selection_surface = ev_pixbuf_cache_get_selection_surface (view->pixbuf_cache,
+ page,
+ view->scale,
+ ®ion);
+ if (selection_surface) {
+ draw_surface (cr, selection_surface, overlap.x, overlap.y, offset_x, offset_y,
+ width, height);
return;
}
- draw_surface (cr, selection_surface, overlap.x, overlap.y, offset_x, offset_y, width, height);
+ if (region) {
+ double scale_x, scale_y;
+ GdkRGBA color;
+
+ scale_x = (gdouble)width / cairo_image_surface_get_width (page_surface);
+ scale_y = (gdouble)height / cairo_image_surface_get_height (page_surface);
+ _ev_view_get_selection_colors (view, &color, NULL);
+ draw_selection_region (cr, region, &color, real_page_area.x, real_page_area.y,
+ scale_x, scale_y);
+ }
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]