From 83dc7cff581241907168d6f61ce25f798b8c442f Mon Sep 17 00:00:00 2001 From: Jonathan Blandford Date: Fri, 01 Jul 2005 04:11:08 +0000 Subject: Add I-Beam support to EvView. Now we can see where we can select! Sweet! Fri Jul 1 00:10:15 2005 Jonathan Blandford * backend/ev-selection.c: (ev_selection_get_selection_region), (ev_selection_get_selection_map): * backend/ev-selection.h: * pdf/ev-poppler.cc: * shell/ev-jobs.c: (ev_job_render_new), (ev_job_render_run): * shell/ev-jobs.h: * shell/ev-pixbuf-cache.c: (dispose_cache_job_info), (job_finished_cb), (copy_job_to_job_info), (add_job_if_needed), (ev_pixbuf_cache_get_text_mapping): * shell/ev-pixbuf-cache.h: * shell/ev-view.c: (location_in_text), (ev_view_motion_notify_event), (ev_view_set_cursor): Add I-Beam support to EvView. Now we can see where we can select! Sweet! --- diff --git a/ChangeLog b/ChangeLog index a63cb65..09c3de7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +Fri Jul 1 00:10:15 2005 Jonathan Blandford + + * backend/ev-selection.c: (ev_selection_get_selection_region), + (ev_selection_get_selection_map): + * backend/ev-selection.h: + * pdf/ev-poppler.cc: + * shell/ev-jobs.c: (ev_job_render_new), (ev_job_render_run): + * shell/ev-jobs.h: + * shell/ev-pixbuf-cache.c: (dispose_cache_job_info), + (job_finished_cb), (copy_job_to_job_info), (add_job_if_needed), + (ev_pixbuf_cache_get_text_mapping): + * shell/ev-pixbuf-cache.h: + * shell/ev-view.c: (location_in_text), + (ev_view_motion_notify_event), (ev_view_set_cursor): Add I-Beam + support to EvView. Now we can see where we can select! Sweet! + 2005-06-30 Kristian Høgsberg * shell/ev-view.c (ev_view_button_press_event): Fix diff --git a/backend/ev-selection.c b/backend/ev-selection.c index fc8caa6..074bbbc 100644 --- a/backend/ev-selection.c +++ b/backend/ev-selection.c @@ -70,11 +70,21 @@ ev_selection_render_selection (EvSelection *selection, points, old_points); } -GdkRegion *ev_selection_get_selection_region (EvSelection *selection, - EvRenderContext *rc, - EvRectangle *points) +GdkRegion * +ev_selection_get_selection_region (EvSelection *selection, + EvRenderContext *rc, + EvRectangle *points) { EvSelectionIface *iface = EV_SELECTION_GET_IFACE (selection); return iface->get_selection_region (selection, rc, points); } + +GdkRegion * +ev_selection_get_selection_map (EvSelection *selection, + EvRenderContext *rc) +{ + EvSelectionIface *iface = EV_SELECTION_GET_IFACE (selection); + + return iface->get_selection_map (selection, rc); +} diff --git a/backend/ev-selection.h b/backend/ev-selection.h index a07d639..8c5e224 100644 --- a/backend/ev-selection.h +++ b/backend/ev-selection.h @@ -48,6 +48,8 @@ struct _EvSelectionIface GdkPixbuf **pixbuf, EvRectangle *points, EvRectangle *old_points); + GdkRegion * (* get_selection_map) (EvSelection *selection, + EvRenderContext *rc); GdkRegion * (* get_selection_region) (EvSelection *selection, EvRenderContext *rc, EvRectangle *points); @@ -59,6 +61,8 @@ void ev_selection_render_selection (EvSelection *selection, GdkPixbuf **pixbuf, EvRectangle *points, EvRectangle *old_points); +GdkRegion *ev_selection_get_selection_map (EvSelection *selection, + EvRenderContext *rc); GdkRegion *ev_selection_get_selection_region (EvSelection *selection, EvRenderContext *rc, EvRectangle *points); diff --git a/pdf/ev-poppler.cc b/pdf/ev-poppler.cc index aa2ac90..aa33b7f 100644 --- a/pdf/ev-poppler.cc +++ b/pdf/ev-poppler.cc @@ -823,7 +823,6 @@ make_thumbnail_for_size (PdfDocument *pdf_document, PopplerPage *poppler_page; GdkPixbuf *pixbuf, *sub_pixbuf; int width, height; - int x_offset, y_offset; double scale; gdouble unscaled_width, unscaled_height; @@ -1239,11 +1238,35 @@ pdf_selection_get_selection_region (EvSelection *selection, return retval; } +GdkRegion * +pdf_selection_get_selection_map (EvSelection *selection, + EvRenderContext *rc) +{ + PdfDocument *pdf_document; + PopplerPage *poppler_page; + PopplerRectangle points; + GdkRegion *retval; + + pdf_document = PDF_DOCUMENT (selection); + poppler_page = poppler_document_get_page (pdf_document->document, + rc->page); + set_page_orientation (pdf_document, poppler_page); + + points.x1 = 0.0; + points.y1 = 0.0; + poppler_page_get_size (poppler_page, &(points.x2), &(points.y2)); + retval = poppler_page_get_selection_region (poppler_page, 1.0, &points); + g_object_unref (poppler_page); + + return retval; +} + static void pdf_selection_iface_init (EvSelectionIface *iface) { iface->render_selection = pdf_selection_render_selection; iface->get_selection_region = pdf_selection_get_selection_region; + iface->get_selection_map = pdf_selection_get_selection_map; } PdfDocument * diff --git a/shell/ev-jobs.c b/shell/ev-jobs.c index 3bc2fa8..4cc0c25 100644 --- a/shell/ev-jobs.c +++ b/shell/ev-jobs.c @@ -227,6 +227,7 @@ ev_job_render_new (EvDocument *document, gint height, EvRectangle *selection_points, gboolean include_links, + gboolean include_text, gboolean include_selection) { EvJobRender *job; @@ -242,6 +243,7 @@ ev_job_render_new (EvDocument *document, job->target_width = width; job->target_height = height; job->include_links = include_links; + job->include_text = include_text; job->include_selection = include_selection; if (include_selection) @@ -281,6 +283,8 @@ ev_job_render_run (EvJobRender *job) job->pixbuf = ev_document_render_pixbuf (EV_JOB (job)->document, job->rc); if (job->include_links) job->link_mapping = ev_document_get_links (EV_JOB (job)->document, job->rc->page); + if (job->include_text && EV_IS_SELECTION (EV_JOB (job)->document)) + job->text_mapping = ev_selection_get_selection_map (EV_SELECTION (EV_JOB (job)->document), job->rc); if (job->include_selection && EV_IS_SELECTION (EV_JOB (job)->document)) ev_selection_render_selection (EV_SELECTION (EV_JOB (job)->document), job->rc, diff --git a/shell/ev-jobs.h b/shell/ev-jobs.h index 9e46909..263f9a1 100644 --- a/shell/ev-jobs.h +++ b/shell/ev-jobs.h @@ -115,11 +115,13 @@ struct _EvJobRender GdkPixbuf *pixbuf; GList *link_mapping; + GdkRegion *text_mapping; GdkPixbuf *selection; EvRectangle selection_points; gint include_links : 1; + gint include_text : 1; gint include_selection : 1; }; @@ -182,6 +184,7 @@ EvJob *ev_job_render_new (EvDocument *document, gint height, EvRectangle *selection_points, gboolean include_links, + gboolean include_text, gboolean include_selection); void ev_job_render_run (EvJobRender *thumbnail); diff --git a/shell/ev-pixbuf-cache.c b/shell/ev-pixbuf-cache.c index 58ba3bf..a6127c3 100644 --- a/shell/ev-pixbuf-cache.c +++ b/shell/ev-pixbuf-cache.c @@ -9,6 +9,7 @@ typedef struct _CacheJobInfo GdkPixbuf *pixbuf; EvRenderContext *rc; GList *link_mapping; + GdkRegion *text_mapping; /* Selection info. If the *_points structs are unset, we put -1 in x1. * selection_points are the coordinates encapsulated in selection. @@ -144,6 +145,10 @@ dispose_cache_job_info (CacheJobInfo *job_info, ev_link_mapping_free (job_info->link_mapping); job_info->link_mapping = NULL; } + if (job_info->text_mapping) { + gdk_region_destroy (job_info->text_mapping); + job_info->text_mapping = NULL; + } if (job_info->selection) { g_object_unref (G_OBJECT (job_info->selection)); job_info->selection = NULL; @@ -210,6 +215,13 @@ job_finished_cb (EvJob *job, ev_link_mapping_free (job_info->link_mapping); job_info->link_mapping = job_render->link_mapping; } + + if (job_render->text_mapping) { + if (job_info->text_mapping) + gdk_region_destroy (job_info->text_mapping); + job_info->text_mapping = job_render->text_mapping; + } + if (job_render->include_selection) { if (job_info->selection) g_object_unref (job_info->selection); @@ -403,6 +415,8 @@ copy_job_to_job_info (EvJobRender *job_render, job_info->pixbuf = pixbuf; if (job_render->link_mapping) job_info->link_mapping = job_render->link_mapping; + if (job_render->text_mapping) + job_info->text_mapping = job_render->text_mapping; } static CacheJobInfo * @@ -468,6 +482,7 @@ add_job_if_needed (EvPixbufCache *pixbuf_cache, EvJobPriority priority) { gboolean include_links = FALSE; + gboolean include_text = FALSE; gboolean include_selection = FALSE; int width, height; @@ -495,6 +510,8 @@ add_job_if_needed (EvPixbufCache *pixbuf_cache, /* Figure out what else we need for this job */ if (job_info->link_mapping == NULL) include_links = TRUE; + if (job_info->text_mapping == NULL) + include_text = TRUE; if (new_selection_pixbuf_needed (pixbuf_cache, job_info, page, scale)) { include_selection = TRUE; } @@ -504,6 +521,7 @@ add_job_if_needed (EvPixbufCache *pixbuf_cache, width, height, &(job_info->new_points), include_links, + include_text, include_selection); ev_job_queue_add_job (job_info->job, priority); g_signal_connect (job_info->job, "finished", G_CALLBACK (job_finished_cb), pixbuf_cache); @@ -660,11 +678,23 @@ clear_selection_if_needed (EvPixbufCache *pixbuf_cache, } } -GList * -ev_pixbuf_cach_get_text_mapping (EvPixbufCache *pixbuf_cache, +GdkRegion * +ev_pixbuf_cache_get_text_mapping (EvPixbufCache *pixbuf_cache, gint page) { - return NULL; + CacheJobInfo *job_info; + + job_info = find_job_cache (pixbuf_cache, page); + if (job_info == NULL) + return NULL; + + /* We don't need to wait for the idle to handle the callback */ + if (job_info->job && + EV_JOB (job_info->job)->finished) { + copy_job_to_job_info (EV_JOB_RENDER (job_info->job), job_info, pixbuf_cache); + } + + return job_info->text_mapping; } GdkPixbuf * diff --git a/shell/ev-pixbuf-cache.h b/shell/ev-pixbuf-cache.h index 19d0311..3081c3b 100644 --- a/shell/ev-pixbuf-cache.h +++ b/shell/ev-pixbuf-cache.h @@ -58,9 +58,9 @@ GdkPixbuf *ev_pixbuf_cache_get_pixbuf (EvPixbufCache *pixbuf_cache gint page); GList *ev_pixbuf_cache_get_link_mapping (EvPixbufCache *pixbuf_cache, gint page); -/* Selection */ -GList *ev_pixbuf_cach_get_text_mapping (EvPixbufCache *pixbuf_cache, +GdkRegion *ev_pixbuf_cache_get_text_mapping (EvPixbufCache *pixbuf_cache, gint page); +/* Selection */ GdkPixbuf *ev_pixbuf_cache_get_selection_pixbuf (EvPixbufCache *pixbuf_cache, gint page, gfloat scale); diff --git a/shell/ev-view.c b/shell/ev-view.c index 9164267..476c791 100644 --- a/shell/ev-view.c +++ b/shell/ev-view.c @@ -78,6 +78,7 @@ static guint signals[N_SIGNALS]; typedef enum { EV_VIEW_CURSOR_NORMAL, + EV_VIEW_CURSOR_IBEAM, EV_VIEW_CURSOR_LINK, EV_VIEW_CURSOR_WAIT, EV_VIEW_CURSOR_HIDDEN, @@ -944,6 +945,28 @@ find_page_at_location (EvView *view, *page = -1; } +static gboolean +location_in_text (EvView *view, + gdouble x, + gdouble y) +{ + GdkRegion *region; + gint page = -1; + gint x_offset = 0, y_offset = 0; + + find_page_at_location (view, x, y, &page, &x_offset, &y_offset); + + if (page == -1) + return FALSE; + + region = ev_pixbuf_cache_get_text_mapping (view->pixbuf_cache, page); + + if (region) + return gdk_region_point_in (region, x_offset / view->scale, y_offset / view->scale); + else + return FALSE; +} + /*** Hyperref ***/ static EvLink * get_link_at_location (EvView *view, @@ -1420,11 +1443,13 @@ ev_view_motion_notify_event (GtkWidget *widget, ev_view_set_status (view, msg); ev_view_set_cursor (view, EV_VIEW_CURSOR_LINK); g_free (msg); + } else if (location_in_text (view, event->x + view->scroll_x, event->y + view->scroll_y)) { + ev_view_set_cursor (view, EV_VIEW_CURSOR_IBEAM); } else { ev_view_set_status (view, NULL); - if (view->cursor == EV_VIEW_CURSOR_LINK) { + if (view->cursor == EV_VIEW_CURSOR_LINK || + view->cursor == EV_VIEW_CURSOR_IBEAM) ev_view_set_cursor (view, EV_VIEW_CURSOR_NORMAL); - } } return TRUE; } @@ -3036,6 +3061,9 @@ ev_view_set_cursor (EvView *view, EvViewCursor new_cursor) case EV_VIEW_CURSOR_NORMAL: gdk_window_set_cursor (widget->window, NULL); break; + case EV_VIEW_CURSOR_IBEAM: + cursor = gdk_cursor_new_for_display (display, GDK_XTERM); + break; case EV_VIEW_CURSOR_LINK: cursor = gdk_cursor_new_for_display (display, GDK_HAND2); break; -- cgit v0.9.1