diff options
author | Jason Crain <[email protected]> | 2013-06-15 10:43:08 -0500 |
---|---|---|
committer | raveit65 <[email protected]> | 2017-09-06 18:25:34 +0200 |
commit | d758271a60f8d081d1a0701b48d68981dcad9804 (patch) | |
tree | 69fad9b6afab351b7a7dbf358cec0226be8e5c12 /libview/ev-view.c | |
parent | b062ae0ca9eeb927a111a92bb9d41f3a77630f71 (diff) | |
download | atril-d758271a60f8d081d1a0701b48d68981dcad9804.tar.bz2 atril-d758271a60f8d081d1a0701b48d68981dcad9804.tar.xz |
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
origin commit:
https://git.gnome.org/browse/evince/commit/?h=gnome-3-10&id=9e89fb1
Diffstat (limited to 'libview/ev-view.c')
-rw-r--r-- | libview/ev-view.c | 71 |
1 files changed, 60 insertions, 11 deletions
diff --git a/libview/ev-view.c b/libview/ev-view.c index 50838662..99604221 100644 --- a/libview/ev-view.c +++ b/libview/ev-view.c @@ -5469,6 +5469,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, @@ -5510,6 +5549,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; double device_scale_x = 1, device_scale_y = 1; page_surface = ev_pixbuf_cache_get_surface (view->pixbuf_cache, page); @@ -5535,22 +5575,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); + } } } |