Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/shell
diff options
context:
space:
mode:
authorCarlos Garcia Campos <carlosgc@gnome.org>2007-06-13 08:54:53 (GMT)
committer Carlos Garcia Campos <carlosgc@src.gnome.org>2007-06-13 08:54:53 (GMT)
commit217797d63b2d3b1c9a7a0511af1bbf3d99f0d482 (patch)
tree7984c3b1bb57f723eb57c81f6ab4121b55e69510 /shell
parent83005d76d55eea57772ea2dc7224e45f856725be (diff)
Use cairo image surfaces instead of GDK pixbufs for drawing pages and
2007-06-13 Carlos Garcia Campos <carlosgc@gnome.org> * backend/dvi/dvi-document.c: (dvi_document_render), (dvi_document_render_pixbuf), (dvi_document_document_iface_init): * backend/impress/impress-document.c: (imp_render_get_from_drawable), (impress_document_render_pixbuf), (impress_document_render), (impress_document_document_iface_init), (impress_document_thumbnails_get_thumbnail): * backend/djvu/djvu-document-private.h: * backend/djvu/djvu-document.c: (djvu_document_render), (djvu_document_finalize), (djvu_document_document_iface_init), (djvu_document_thumbnails_get_thumbnail), (djvu_document_init): * backend/tiff/tiff-document.c: (tiff_document_render), (tiff_document_render_pixbuf), (tiff_document_document_iface_init): * backend/pdf/ev-poppler.cc: (pdf_document_render), (pdf_document_render_pixbuf), (pdf_document_document_iface_init), (pdf_selection_render_selection): * backend/comics/comics-document.c: (comics_document_render_pixbuf), (comics_document_render), (comics_document_document_iface_init): * backend/pixbuf/pixbuf-document.c: (pixbuf_document_render), (pixbuf_document_document_iface_init): * libdocument/ev-document-misc.[ch]: (ev_document_misc_surface_from_pixbuf), (ev_document_misc_surface_rotate_and_scale): * libdocument/ev-document.[ch]: (ev_document_render): * libdocument/ev-selection.[ch]: (ev_selection_render_selection): * shell/ev-pixbuf-cache.[ch]: (dispose_cache_job_info), (move_one_job), (copy_job_to_job_info), (add_job_if_needed), (ev_pixbuf_cache_get_surface), (new_selection_surface_needed), (clear_selection_if_needed), (ev_pixbuf_cache_style_changed), (ev_pixbuf_cache_get_selection_surface), (clear_job_selection): * shell/ev-jobs.[ch]: (ev_job_render_dispose), (render_finished_cb), (ev_job_render_run): * shell/ev-view.c: (draw_loading_text), (draw_one_page), (merge_selection_region): Use cairo image surfaces instead of GDK pixbufs for drawing pages and selections. svn path=/trunk/; revision=2499
Diffstat (limited to 'shell')
-rw-r--r--shell/ev-jobs.c18
-rw-r--r--shell/ev-jobs.h4
-rw-r--r--shell/ev-pixbuf-cache.c86
-rw-r--r--shell/ev-pixbuf-cache.h10
-rw-r--r--shell/ev-view.c216
5 files changed, 179 insertions, 155 deletions
diff --git a/shell/ev-jobs.c b/shell/ev-jobs.c
index 6ad4dfc..d9cdac8 100644
--- a/shell/ev-jobs.c
+++ b/shell/ev-jobs.c
@@ -4,6 +4,7 @@
#include "ev-document-links.h"
#include "ev-document-images.h"
#include "ev-document-factory.h"
+#include "ev-document-misc.h"
#include "ev-file-helpers.h"
#include "ev-document-fonts.h"
#include "ev-selection.h"
@@ -120,9 +121,9 @@ ev_job_render_dispose (GObject *object)
job = EV_JOB_RENDER (object);
- if (job->pixbuf) {
- g_object_unref (job->pixbuf);
- job->pixbuf = NULL;
+ if (job->surface) {
+ cairo_surface_destroy (job->surface);
+ job->surface = NULL;
}
if (job->rc) {
@@ -131,7 +132,7 @@ ev_job_render_dispose (GObject *object)
}
if (job->selection) {
- g_object_unref (job->selection);
+ cairo_surface_destroy (job->selection);
job->selection = NULL;
}
@@ -299,13 +300,16 @@ ev_job_render_new (EvDocument *document,
}
static void
-render_finished_cb (EvDocument *document, GdkPixbuf *pixbuf, EvJobRender *job)
+render_finished_cb (EvDocument *document,
+ GdkPixbuf *pixbuf,
+ EvJobRender *job)
{
g_signal_handlers_disconnect_by_func (EV_JOB (job)->document,
render_finished_cb, job);
+ /* FIXME: ps backend should be ported to cairo */
+ job->surface = ev_document_misc_surface_from_pixbuf (pixbuf);
EV_JOB (job)->finished = TRUE;
- job->pixbuf = g_object_ref (pixbuf);
ev_job_finished (EV_JOB (job));
}
@@ -325,7 +329,7 @@ ev_job_render_run (EvJobRender *job)
} else {
ev_document_fc_mutex_lock ();
- job->pixbuf = ev_document_render_pixbuf (EV_JOB (job)->document, job->rc);
+ job->surface = ev_document_render (EV_JOB (job)->document, job->rc);
if (job->include_links && EV_IS_DOCUMENT_LINKS (EV_JOB (job)->document))
job->link_mapping =
ev_document_links_get_links (EV_DOCUMENT_LINKS (EV_JOB (job)->document),
diff --git a/shell/ev-jobs.h b/shell/ev-jobs.h
index 1f210ec..fc681d3 100644
--- a/shell/ev-jobs.h
+++ b/shell/ev-jobs.h
@@ -121,13 +121,13 @@ struct _EvJobRender
EvRenderContext *rc;
gint target_width;
gint target_height;
- GdkPixbuf *pixbuf;
+ cairo_surface_t *surface;
GList *link_mapping;
GdkRegion *text_mapping;
GList *image_mapping;
- GdkPixbuf *selection;
+ cairo_surface_t *selection;
GdkRegion *selection_region;
EvRectangle selection_points;
GdkColor base;
diff --git a/shell/ev-pixbuf-cache.c b/shell/ev-pixbuf-cache.c
index 777e014..2c815c0 100644
--- a/shell/ev-pixbuf-cache.c
+++ b/shell/ev-pixbuf-cache.c
@@ -11,7 +11,7 @@ typedef struct _CacheJobInfo
EvRenderContext *rc;
/* Data we get from rendering */
- GdkPixbuf *pixbuf;
+ cairo_surface_t *surface;
GList *link_mapping;
GList *image_mapping;
GdkRegion *text_mapping;
@@ -23,7 +23,7 @@ typedef struct _CacheJobInfo
EvRectangle target_points;
gboolean points_set;
- GdkPixbuf *selection;
+ cairo_surface_t *selection;
GdkRegion *selection_region;
} CacheJobInfo;
@@ -74,10 +74,10 @@ static CacheJobInfo *find_job_cache (EvPixbufCache *pixbuf_cach
static void copy_job_to_job_info (EvJobRender *job_render,
CacheJobInfo *job_info,
EvPixbufCache *pixbuf_cache);
-static gboolean new_selection_pixbuf_needed(EvPixbufCache *pixbuf_cache,
- CacheJobInfo *job_info,
- gint page,
- gfloat scale);
+static gboolean new_selection_surface_needed(EvPixbufCache *pixbuf_cache,
+ CacheJobInfo *job_info,
+ gint page,
+ gfloat scale);
/* These are used for iterating through the prev and next arrays */
@@ -149,9 +149,9 @@ dispose_cache_job_info (CacheJobInfo *job_info,
g_object_unref (G_OBJECT (job_info->job));
job_info->job = NULL;
}
- if (job_info->pixbuf) {
- g_object_unref (G_OBJECT (job_info->pixbuf));
- job_info->pixbuf = NULL;
+ if (job_info->surface) {
+ cairo_surface_destroy (job_info->surface);
+ job_info->surface = NULL;
}
if (job_info->link_mapping) {
ev_link_mapping_free (job_info->link_mapping);
@@ -166,7 +166,7 @@ dispose_cache_job_info (CacheJobInfo *job_info,
job_info->text_mapping = NULL;
}
if (job_info->selection) {
- g_object_unref (G_OBJECT (job_info->selection));
+ cairo_surface_destroy (job_info->selection);
job_info->selection = NULL;
}
if (job_info->selection_region) {
@@ -321,7 +321,7 @@ move_one_job (CacheJobInfo *job_info,
*target_page = *job_info;
job_info->job = NULL;
- job_info->pixbuf = NULL;
+ job_info->surface = NULL;
job_info->link_mapping = NULL;
job_info->image_mapping = NULL;
@@ -411,10 +411,10 @@ copy_job_to_job_info (EvJobRender *job_render,
job_info->points_set = FALSE;
- if (job_info->pixbuf) {
- g_object_unref (G_OBJECT (job_info->pixbuf));
+ if (job_info->surface) {
+ cairo_surface_destroy (job_info->surface);
}
- job_info->pixbuf = g_object_ref (job_render->pixbuf);
+ job_info->surface = cairo_surface_reference (job_render->surface);
if (job_info->rc) {
g_object_unref (G_OBJECT (job_info->rc));
@@ -441,7 +441,7 @@ copy_job_to_job_info (EvJobRender *job_render,
if (job_render->include_selection) {
if (job_info->selection) {
- g_object_unref (G_OBJECT (job_info->selection));
+ cairo_surface_destroy (job_info->selection);
job_info->selection = NULL;
}
if (job_info->selection_region) {
@@ -451,7 +451,7 @@ copy_job_to_job_info (EvJobRender *job_render,
job_info->selection_points = job_render->selection_points;
job_info->selection_region = gdk_region_copy (job_render->selection_region);
- job_info->selection = g_object_ref (job_render->selection);
+ job_info->selection = cairo_surface_reference (job_render->selection);
g_assert (job_info->selection_points.x1 >= 0);
job_info->points_set = TRUE;
}
@@ -554,9 +554,9 @@ add_job_if_needed (EvPixbufCache *pixbuf_cache,
ev_page_cache_get_size (page_cache, page, rotation,
scale, &width, &height);
- if (job_info->pixbuf &&
- gdk_pixbuf_get_width (job_info->pixbuf) == width &&
- gdk_pixbuf_get_height (job_info->pixbuf) == height)
+ if (job_info->surface &&
+ cairo_image_surface_get_width (job_info->surface) == width &&
+ cairo_image_surface_get_height (job_info->surface) == height)
return;
/* make a new job now */
@@ -575,7 +575,7 @@ add_job_if_needed (EvPixbufCache *pixbuf_cache,
include_images = TRUE;
if (job_info->text_mapping == NULL)
include_text = TRUE;
- if (new_selection_pixbuf_needed (pixbuf_cache, job_info, page, scale)) {
+ if (new_selection_surface_needed (pixbuf_cache, job_info, page, scale)) {
include_selection = TRUE;
}
@@ -672,9 +672,9 @@ ev_pixbuf_cache_set_page_range (EvPixbufCache *pixbuf_cache,
ev_pixbuf_cache_add_jobs_if_needed (pixbuf_cache, rotation, scale);
}
-GdkPixbuf *
-ev_pixbuf_cache_get_pixbuf (EvPixbufCache *pixbuf_cache,
- gint page)
+cairo_surface_t *
+ev_pixbuf_cache_get_surface (EvPixbufCache *pixbuf_cache,
+ gint page)
{
CacheJobInfo *job_info;
@@ -688,7 +688,7 @@ ev_pixbuf_cache_get_pixbuf (EvPixbufCache *pixbuf_cache,
copy_job_to_job_info (EV_JOB_RENDER (job_info->job), job_info, pixbuf_cache);
}
- return job_info->pixbuf;
+ return job_info->surface;
}
GList *
@@ -733,26 +733,32 @@ ev_pixbuf_cache_get_image_mapping (EvPixbufCache *pixbuf_cache,
}
static gboolean
-new_selection_pixbuf_needed (EvPixbufCache *pixbuf_cache,
+new_selection_surface_needed (EvPixbufCache *pixbuf_cache,
CacheJobInfo *job_info,
gint page,
gfloat scale)
{
EvPageCache *page_cache;
- gint width, height;
if (job_info->selection) {
+ gint width, height;
+ gint selection_width, selection_height;
+
page_cache = ev_page_cache_get (pixbuf_cache->document);
- ev_page_cache_get_size (page_cache, page, job_info->rc->rotation,
+ ev_page_cache_get_size (page_cache, page,
+ job_info->rc->rotation,
scale, &width, &height);
+
+ selection_width = cairo_image_surface_get_width (job_info->selection);
+ selection_height = cairo_image_surface_get_height (job_info->selection);
- if (width != gdk_pixbuf_get_width (job_info->selection) ||
- height != gdk_pixbuf_get_height (job_info->selection))
+ if (width != selection_width || height != selection_height)
return TRUE;
} else {
if (job_info->points_set)
return TRUE;
}
+
return FALSE;
}
@@ -762,9 +768,9 @@ clear_selection_if_needed (EvPixbufCache *pixbuf_cache,
gint page,
gfloat scale)
{
- if (new_selection_pixbuf_needed (pixbuf_cache, job_info, page, scale)) {
+ if (new_selection_surface_needed (pixbuf_cache, job_info, page, scale)) {
if (job_info->selection)
- g_object_unref (job_info->selection);
+ cairo_surface_destroy (job_info->selection);
job_info->selection = NULL;
job_info->selection_points.x1 = -1;
}
@@ -818,13 +824,13 @@ ev_pixbuf_cache_style_changed (EvPixbufCache *pixbuf_cache)
job_info = pixbuf_cache->prev_job + i;
if (job_info->selection) {
- g_object_unref (G_OBJECT (job_info->selection));
+ cairo_surface_destroy (job_info->selection);
job_info->selection = NULL;
}
job_info = pixbuf_cache->next_job + i;
if (job_info->selection) {
- g_object_unref (G_OBJECT (job_info->selection));
+ cairo_surface_destroy (job_info->selection);
job_info->selection = NULL;
}
}
@@ -834,17 +840,17 @@ ev_pixbuf_cache_style_changed (EvPixbufCache *pixbuf_cache)
job_info = pixbuf_cache->job_list + i;
if (job_info->selection) {
- g_object_unref (G_OBJECT (job_info->selection));
+ cairo_surface_destroy (job_info->selection);
job_info->selection = NULL;
}
}
}
-GdkPixbuf *
-ev_pixbuf_cache_get_selection_pixbuf (EvPixbufCache *pixbuf_cache,
- gint page,
- gfloat scale,
- GdkRegion **region)
+cairo_surface_t *
+ev_pixbuf_cache_get_selection_surface (EvPixbufCache *pixbuf_cache,
+ gint page,
+ gfloat scale,
+ GdkRegion **region)
{
CacheJobInfo *job_info;
@@ -932,7 +938,7 @@ clear_job_selection (CacheJobInfo *job_info)
job_info->selection_points.x1 = -1;
if (job_info->selection) {
- g_object_unref (job_info->selection);
+ cairo_surface_destroy (job_info->selection);
job_info->selection = NULL;
}
}
diff --git a/shell/ev-pixbuf-cache.h b/shell/ev-pixbuf-cache.h
index 6f96dc1..79e0810 100644
--- a/shell/ev-pixbuf-cache.h
+++ b/shell/ev-pixbuf-cache.h
@@ -57,7 +57,7 @@ void ev_pixbuf_cache_set_page_range (EvPixbufCache *pixbuf_cache
gint rotation,
gfloat scale,
GList *selection_list);
-GdkPixbuf *ev_pixbuf_cache_get_pixbuf (EvPixbufCache *pixbuf_cache,
+cairo_surface_t *ev_pixbuf_cache_get_surface (EvPixbufCache *pixbuf_cache,
gint page);
GList *ev_pixbuf_cache_get_link_mapping (EvPixbufCache *pixbuf_cache,
gint page);
@@ -69,10 +69,10 @@ void ev_pixbuf_cache_clear (EvPixbufCache *pixbuf_cache
void ev_pixbuf_cache_style_changed (EvPixbufCache *pixbuf_cache);
/* Selection */
-GdkPixbuf *ev_pixbuf_cache_get_selection_pixbuf (EvPixbufCache *pixbuf_cache,
- gint page,
- gfloat scale,
- GdkRegion **region);
+cairo_surface_t *ev_pixbuf_cache_get_selection_surface (EvPixbufCache *pixbuf_cache,
+ gint page,
+ gfloat scale,
+ GdkRegion **region);
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/shell/ev-view.c b/shell/ev-view.c
index bcf3374..ba69b27 100644
--- a/shell/ev-view.c
+++ b/shell/ev-view.c
@@ -2003,6 +2003,9 @@ ev_view_button_press_event (GtkWidget *widget,
view->selection_info.in_drag = TRUE;
} else {
clear_selection (view);
+
+ view->selection_info.start.x = event->x + view->scroll_x;
+ view->selection_info.start.y = event->y + view->scroll_y;
}
gtk_widget_queue_draw (widget);
@@ -2015,10 +2018,10 @@ ev_view_button_press_event (GtkWidget *widget,
view->image_dnd_info.start.x = event->x + view->scroll_x;
view->image_dnd_info.start.y = event->y + view->scroll_y;
+ } else {
+ view->selection_info.start.x = event->x + view->scroll_x;
+ view->selection_info.start.y = event->y + view->scroll_y;
}
-
- view->selection_info.start.x = event->x + view->scroll_x;
- view->selection_info.start.y = event->y + view->scroll_y;
}
return TRUE;
case 2:
@@ -2773,8 +2776,6 @@ highlight_find_results (EvView *view, int page)
EvDocumentFind *find;
int i, results = 0;
- g_return_if_fail (EV_IS_DOCUMENT_FIND (view->document));
-
find = EV_DOCUMENT_FIND (view->document);
results = ev_document_find_get_n_results (find, page);
@@ -2804,7 +2805,7 @@ draw_loading_text (EvView *view,
{
cairo_t *cr;
gint width, height;
-
+
/* Don't annoy users with loading messages during presentations.
* FIXME: Temporary "workaround" for
* http://bugzilla.gnome.org/show_bug.cgi?id=320352 */
@@ -2812,17 +2813,15 @@ draw_loading_text (EvView *view,
return;
if (!view->loading_text) {
- const gchar *loading_text;
+ const gchar *loading_text = _("Loading...");
PangoLayout *layout;
PangoFontDescription *font_desc;
PangoRectangle logical_rect;
- gdouble real_scale;
gint target_width;
-
- loading_text = _("Loading...");
+ gdouble real_scale;
ev_document_fc_mutex_lock ();
-
+
layout = gtk_widget_create_pango_layout (GTK_WIDGET (view), loading_text);
font_desc = pango_font_description_new ();
@@ -2831,8 +2830,7 @@ draw_loading_text (EvView *view,
pango_font_description_set_size (font_desc, 10 * PANGO_SCALE);
pango_layout_set_font_description (layout, font_desc);
pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
-
- /* Make sure we fit the middle of the page */
+
target_width = MAX (page_area->width / 2, 1);
real_scale = ((double)target_width / (double) logical_rect.width) * (PANGO_SCALE * 10);
pango_font_description_set_size (font_desc, (int)real_scale);
@@ -2860,39 +2858,30 @@ draw_loading_text (EvView *view,
height = (page_area->height - cairo_image_surface_get_height (view->loading_text)) / 2;
cr = gdk_cairo_create (GTK_WIDGET (view)->window);
- cairo_set_source_surface (cr, view->loading_text,
- page_area->x + width,
- page_area->y + height);
+ cairo_translate (cr,
+ page_area->x + width,
+ page_area->y + height);
+ cairo_set_source_surface (cr, view->loading_text, 0, 0);
cairo_paint (cr);
cairo_destroy (cr);
}
static void
-draw_one_page (EvView *view,
- gint page,
- GdkRectangle *page_area,
- GtkBorder *border,
- GdkRectangle *expose_area,
- gboolean *page_ready)
+draw_one_page (EvView *view,
+ gint page,
+ GdkRectangle *page_area,
+ GtkBorder *border,
+ GdkRectangle *expose_area,
+ gboolean *page_ready)
{
- gint width, height;
- GdkPixbuf *current_pixbuf;
GdkRectangle overlap;
GdkRectangle real_page_area;
- EvViewSelection *selection;
- gint current_page;
g_assert (view->document);
if (! gdk_rectangle_intersect (page_area, expose_area, &overlap))
return;
-
- current_page = ev_page_cache_get_current_page (view->page_cache);
- selection = find_selection_for_page (view, page);
- ev_page_cache_get_size (view->page_cache,
- page, view->rotation,
- view->scale,
- &width, &height);
+
/* Render the document itself */
real_page_area = *page_area;
@@ -2903,80 +2892,100 @@ draw_one_page (EvView *view,
*page_ready = TRUE;
if (!view->presentation) {
- ev_document_misc_paint_one_page (GTK_WIDGET(view)->window,
+ gint current_page;
+
+ current_page = ev_page_cache_get_current_page (view->page_cache);
+ ev_document_misc_paint_one_page (GTK_WIDGET (view)->window,
GTK_WIDGET (view),
page_area, border,
page == current_page);
}
if (gdk_rectangle_intersect (&real_page_area, expose_area, &overlap)) {
- GdkPixbuf *selection_pixbuf = NULL;
- GdkPixbuf *scaled_image;
- GdkPixbuf *scaled_selection;
+ gint width, height;
+ gint page_width, page_height;
+ cairo_surface_t *page_surface = NULL;
+ gint selection_width, selection_height;
+ cairo_surface_t *selection_surface = NULL;
+ cairo_t *cr = NULL;
- current_pixbuf = ev_pixbuf_cache_get_pixbuf (view->pixbuf_cache, page);
+ page_surface = ev_pixbuf_cache_get_surface (view->pixbuf_cache, page);
- /* Get the selection pixbuf iff we have something to draw */
- if (current_pixbuf && view->selection_mode == EV_VIEW_SELECTION_TEXT && selection)
- selection_pixbuf = ev_pixbuf_cache_get_selection_pixbuf (view->pixbuf_cache,
- page,
- view->scale,
- NULL);
-
- if (current_pixbuf == NULL)
- scaled_image = NULL;
- else if (width == gdk_pixbuf_get_width (current_pixbuf) &&
- height == gdk_pixbuf_get_height (current_pixbuf))
- scaled_image = g_object_ref (current_pixbuf);
- else
- /* FIXME: We don't want to scale the whole area, just the right
- * area of it */
- scaled_image = gdk_pixbuf_scale_simple (current_pixbuf,
- width, height,
- GDK_INTERP_NEAREST);
-
- if (selection_pixbuf == NULL)
- scaled_selection = NULL;
- else if (width == gdk_pixbuf_get_width (selection_pixbuf) &&
- height == gdk_pixbuf_get_height (selection_pixbuf))
- scaled_selection = g_object_ref (selection_pixbuf);
- else
- /* FIXME: We don't want to scale the whole area, just the right
- * area of it */
- scaled_selection = gdk_pixbuf_scale_simple (selection_pixbuf,
- width, height,
- GDK_INTERP_NEAREST);
-
- if (scaled_image) {
- gdk_draw_pixbuf (GTK_WIDGET(view)->window,
- GTK_WIDGET (view)->style->fg_gc[GTK_STATE_NORMAL],
- scaled_image,
- overlap.x - real_page_area.x,
- overlap.y - real_page_area.y,
- overlap.x, overlap.y,
- overlap.width, overlap.height,
- GDK_RGB_DITHER_NORMAL,
- 0, 0);
- g_object_unref (scaled_image);
- } else {
+ if (!page_surface) {
draw_loading_text (view,
&real_page_area,
expose_area);
*page_ready = FALSE;
+
+ return;
+ }
+
+ ev_page_cache_get_size (view->page_cache,
+ page, view->rotation,
+ view->scale,
+ &width, &height);
+
+ cr = gdk_cairo_create (GTK_WIDGET (view)->window);
+
+ cairo_save (cr);
+
+ page_width = cairo_image_surface_get_width (page_surface);
+ page_height = cairo_image_surface_get_height (page_surface);
+
+ cairo_translate (cr, overlap.x, overlap.y);
+
+ if (width != page_width || height != page_height) {
+ cairo_pattern_set_filter (cairo_get_source (cr),
+ CAIRO_FILTER_FAST);
+ cairo_scale (cr,
+ (gdouble)width / page_width,
+ (gdouble)height / page_height);
}
- if (scaled_selection) {
- gdk_draw_pixbuf (GTK_WIDGET(view)->window,
- GTK_WIDGET (view)->style->fg_gc[GTK_STATE_NORMAL],
- scaled_selection,
- overlap.x - real_page_area.x,
- overlap.y - real_page_area.y,
- overlap.x, overlap.y,
- overlap.width, overlap.height,
- GDK_RGB_DITHER_NORMAL,
- 0, 0);
- g_object_unref (scaled_selection);
+ cairo_surface_set_device_offset (page_surface,
+ overlap.x - real_page_area.x,
+ overlap.y - real_page_area.y);
+
+ cairo_set_source_surface (cr, page_surface, 0, 0);
+ cairo_paint (cr);
+
+ cairo_restore (cr);
+
+ /* 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 (!selection_surface) {
+ cairo_destroy (cr);
+ return;
}
+
+ selection_width = cairo_image_surface_get_width (selection_surface);
+ selection_height = cairo_image_surface_get_height (selection_surface);
+
+ cairo_translate (cr, overlap.x, overlap.y);
+
+ if (width != selection_width || height != selection_height) {
+ cairo_pattern_set_filter (cairo_get_source (cr),
+ CAIRO_FILTER_FAST);
+ cairo_scale (cr,
+ (gdouble)width / selection_width,
+ (gdouble)height / selection_height);
+ }
+
+ cairo_surface_set_device_offset (selection_surface,
+ overlap.x - real_page_area.x,
+ overlap.y - real_page_area.y);
+
+ cairo_set_source_surface (cr, selection_surface, 0, 0);
+ cairo_paint (cr);
+ cairo_destroy (cr);
}
}
@@ -3569,7 +3578,7 @@ ev_view_set_zoom (EvView *view,
cairo_surface_destroy (view->loading_text);
view->loading_text = NULL;
}
-
+
view->scale = scale;
view->pending_resize = TRUE;
@@ -4453,8 +4462,6 @@ compute_new_selection_text (EvView *view,
}
-
-
/* Now create a list of EvViewSelection's for the affected
* pages. This could be an empty list, a list of just one
* page or a number of pages.*/
@@ -4561,10 +4568,12 @@ merge_selection_region (EvView *view,
* region too. */
if (new_sel) {
GdkRegion *tmp_region = NULL;
- ev_pixbuf_cache_get_selection_pixbuf (view->pixbuf_cache,
- cur_page,
- view->scale,
- &tmp_region);
+
+ ev_pixbuf_cache_get_selection_surface (view->pixbuf_cache,
+ cur_page,
+ view->scale,
+ &tmp_region);
+
if (tmp_region) {
new_sel->covered_region = gdk_region_copy (tmp_region);
}
@@ -4572,8 +4581,7 @@ merge_selection_region (EvView *view,
/* Now we figure out what needs redrawing */
if (old_sel && new_sel) {
- if (old_sel->covered_region &&
- new_sel->covered_region) {
+ if (old_sel->covered_region && new_sel->covered_region) {
/* We only want to redraw the areas that have
* changed, so we xor the old and new regions
* and redraw if it's different */
@@ -4605,6 +4613,12 @@ merge_selection_region (EvView *view,
GdkRectangle page_area;
GtkBorder border;
+ /* I don't know why but the region is smaller
+ * than expected. This hack fixes it, I guess
+ * 10 pixels more won't hurt
+ */
+ gdk_region_shrink (region, -5, -5);
+
get_page_extents (view, cur_page, &page_area, &border);
gdk_region_offset (region,
page_area.x + border.left - view->scroll_x,