Index: ChangeLog =================================================================== RCS file: /cvs/gnome/evince/ChangeLog,v retrieving revision 1.838.2.2 diff -u -8 -p -r1.838.2.2 ChangeLog --- ChangeLog 11 Jul 2006 16:49:05 -0000 1.838.2.2 +++ ChangeLog 23 Jul 2006 15:50:41 -0000 @@ -1,8 +1,19 @@ +2006-07-23 Julien Rebetez + * shell/ev-pixbuf-cache.c: (add_job_if_needed), + (ev_pixbuf_cache_get_selection_list), (add_job), + (ev_pixbuf_cache_reload_page): + * shell/ev-pixbuf-cache.h: + * shell/ev-view.c: (render_form_field_content_for_page), + (handle_click_at_location): + Automatic Poppler re-rendering on field unfocus. + Added an add_job function to pixbuf-cache which allow to + add a job even if it isn't needed. + 2006-07-11 Julien Rebetez * shell/ev-view-private.h: * shell/ev-view.c: (job_finished_cb), (render_form_field_content_for_page), (handle_click_at_location): Evince now only render (using Pango) field content which hasn't been rendered by Poppler. 2006-06-21 Julien Rebetez Index: shell/ev-pixbuf-cache.c =================================================================== RCS file: /cvs/gnome/evince/shell/ev-pixbuf-cache.c,v retrieving revision 1.22.4.1 diff -u -8 -p -r1.22.4.1 ev-pixbuf-cache.c --- shell/ev-pixbuf-cache.c 21 Jun 2006 21:42:42 -0000 1.22.4.1 +++ shell/ev-pixbuf-cache.c 23 Jul 2006 15:50:45 -0000 @@ -72,16 +72,27 @@ static CacheJobInfo *find_job_cache 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); +void add_job (EvPixbufCache *pixbuf_cache, + CacheJobInfo *job_info, + EvPageCache *page_cache, + gint page, + gint rotation, + gfloat scale, + EvJobPriority priority, + int width, + int height); + + /* These are used for iterating through the prev and next arrays */ #define FIRST_VISABLE_PREV(pixbuf_cache) \ (MAX (0, pixbuf_cache->preload_cache_size + 1 - pixbuf_cache->start_page)) #define VISIBLE_NEXT_LEN(pixbuf_cache, page_cache) \ (MIN(pixbuf_cache->preload_cache_size, ev_page_cache_get_n_pages (page_cache) - (1 + pixbuf_cache->end_page))) #define PAGE_CACHE_LEN(pixbuf_cache) \ ((pixbuf_cache->end_page - pixbuf_cache->start_page) + 1) @@ -500,71 +511,31 @@ static void add_job_if_needed (EvPixbufCache *pixbuf_cache, CacheJobInfo *job_info, EvPageCache *page_cache, gint page, gint rotation, gfloat scale, EvJobPriority priority) { - gboolean include_form = FALSE; - gboolean include_links = FALSE; - gboolean include_text = FALSE; - gboolean include_selection = FALSE; int width, height; - GdkColor *text, *base; if (job_info->job) return; 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) return; /* make a new job now */ - if (job_info->rc == NULL) { - job_info->rc = ev_render_context_new (rotation, page, scale); - } else { - ev_render_context_set_rotation (job_info->rc, rotation); - ev_render_context_set_page (job_info->rc, page); - ev_render_context_set_scale (job_info->rc, scale); - } - - /* Figure out what else we need for this job */ - /* FIXME: if we don't set include_form to TRUE, sometimes the render job's form_field_mapping is NULL - although the page has some fields - if (job_info->form_field_mappings == NULL)*/ - include_form = TRUE; - 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; - } - - gtk_widget_ensure_style (pixbuf_cache->view); - - get_selection_colors (pixbuf_cache->view, &text, &base); - - job_info->job = ev_job_render_new (pixbuf_cache->document, - job_info->rc, - width, height, - &(job_info->target_points), - text, base, - include_form, - 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); + add_job(pixbuf_cache, job_info, page_cache, page, rotation, scale, priority, width, height); } static void ev_pixbuf_cache_add_jobs_if_needed (EvPixbufCache *pixbuf_cache, gint rotation, gfloat scale) { @@ -1029,16 +1000,96 @@ ev_pixbuf_cache_get_selection_list (EvPi selection->covered_region = gdk_region_copy (pixbuf_cache->next_job[i].selection_region); retval = g_list_append (retval, selection); } page ++; } return retval; +} + +void add_job (EvPixbufCache *pixbuf_cache, + CacheJobInfo *job_info, + EvPageCache *page_cache, + gint page, + gint rotation, + gfloat scale, + EvJobPriority priority, + int width, + int height) +{ + gboolean include_form = FALSE; + gboolean include_links = FALSE; + gboolean include_text = FALSE; + gboolean include_selection = FALSE; + GdkColor *text, *base; + + + if (job_info->rc == NULL) { + job_info->rc = ev_render_context_new (rotation, page, scale); + } else { + ev_render_context_set_rotation (job_info->rc, rotation); + ev_render_context_set_page (job_info->rc, page); + ev_render_context_set_scale (job_info->rc, scale); + } + + /* Figure out what else we need for this job */ + /* FIXME: if we don't set include_form to TRUE, sometimes the render job's form_field_mapping is NULL + although the page has some fields + if (job_info->form_field_mappings == NULL)*/ + include_form = TRUE; + 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; + } + + gtk_widget_ensure_style (pixbuf_cache->view); + + get_selection_colors (pixbuf_cache->view, &text, &base); + + job_info->job = ev_job_render_new (pixbuf_cache->document, + job_info->rc, + width, height, + &(job_info->target_points), + text, base, + include_form, + 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); + +} + +void +ev_pixbuf_cache_reload_page (EvPixbufCache *pixbuf_cache, + gint page, + gint rotation, + gfloat scale) +{ + CacheJobInfo *job_info; + EvPageCache *page_cache; + int width, height; + + if(page < pixbuf_cache->start_page || page > pixbuf_cache->end_page) + return; + + page_cache = ev_page_cache_get (pixbuf_cache->document); + ev_page_cache_get_size (page_cache, page, rotation, scale, &width, &height); + job_info = pixbuf_cache->job_list + (page - pixbuf_cache->start_page); + + //dispose_cache_job_info (job_info, pixbuf_cache); + + add_job(pixbuf_cache, job_info, page_cache, page, rotation, scale, EV_JOB_PRIORITY_HIGH, width, height); + + } GList * ev_pixbuf_cache_get_form_field_mapping (EvPixbufCache *pixbuf_cache, gint page) { CacheJobInfo *job_info; Index: shell/ev-pixbuf-cache.h =================================================================== RCS file: /cvs/gnome/evince/shell/ev-pixbuf-cache.h,v retrieving revision 1.9.6.1 diff -u -8 -p -r1.9.6.1 ev-pixbuf-cache.h --- shell/ev-pixbuf-cache.h 21 Jun 2006 21:42:42 -0000 1.9.6.1 +++ shell/ev-pixbuf-cache.h 23 Jul 2006 15:50:46 -0000 @@ -35,49 +35,55 @@ G_BEGIN_DECLS #define EV_IS_PIXBUF_CACHE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EV_TYPE_PIXBUF_CACHE)) /* The coordinates in the rect here are at scale == 1.0, so that we can ignore * resizings. There is one per page, maximum. */ typedef struct { - int page; - EvRectangle rect; - GdkRegion *covered_region; + int page; + EvRectangle rect; + GdkRegion *covered_region; } EvViewSelection; typedef struct _EvPixbufCache EvPixbufCache; typedef struct _EvPixbufCacheClass EvPixbufCacheClass; GType ev_pixbuf_cache_get_type (void) G_GNUC_CONST; EvPixbufCache *ev_pixbuf_cache_new (GtkWidget *view, - EvDocument *document); + EvDocument *document); void ev_pixbuf_cache_set_page_range (EvPixbufCache *pixbuf_cache, - gint start_page, - gint end_page, - gint rotation, - gfloat scale, - GList *selection_list); + gint start_page, + gint end_page, + gint rotation, + gfloat scale, + GList *selection_list); GdkPixbuf *ev_pixbuf_cache_get_pixbuf (EvPixbufCache *pixbuf_cache, - gint page); + gint page); GList *ev_pixbuf_cache_get_link_mapping (EvPixbufCache *pixbuf_cache, - gint page); + gint page); GdkRegion *ev_pixbuf_cache_get_text_mapping (EvPixbufCache *pixbuf_cache, - gint page); -GList *ev_pixbuf_cache_get_form_field_mapping (EvPixbufCache *pixbuf_cache, - gint page); + gint page); +GList *ev_pixbuf_cache_get_form_field_mapping (EvPixbufCache *pixbuf_cache, + gint page); void ev_pixbuf_cache_clear (EvPixbufCache *pixbuf_cache); void ev_pixbuf_cache_style_changed (EvPixbufCache *pixbuf_cache); +void ev_pixbuf_cache_reload_page (EvPixbufCache *pixbuf_cache, + gint page, + gint rotation, + gfloat scale); + /* Selection */ GdkPixbuf *ev_pixbuf_cache_get_selection_pixbuf (EvPixbufCache *pixbuf_cache, - gint page, - gfloat scale, - GdkRegion **region); + gint page, + gfloat scale, + GdkRegion **region); void ev_pixbuf_cache_set_selection_list (EvPixbufCache *pixbuf_cache, - GList *selection_list); + GList *selection_list); GList *ev_pixbuf_cache_get_selection_list (EvPixbufCache *pixbuf_cache); + G_END_DECLS #endif /* __EV_PIXBUF_CACHE_H__ */ Index: shell/ev-view.c =================================================================== RCS file: /cvs/gnome/evince/shell/ev-view.c,v retrieving revision 1.207.2.2 diff -u -8 -p -r1.207.2.2 ev-view.c --- shell/ev-view.c 11 Jul 2006 16:49:07 -0000 1.207.2.2 +++ shell/ev-view.c 23 Jul 2006 15:50:55 -0000 @@ -4422,17 +4422,25 @@ render_form_field_content_for_page (EvVi v[2] = d[1].x - view->scroll_x; v[3] = d[1].y - view->scroll_y; playout = gtk_widget_create_pango_layout(GTK_WIDGET(view), content); pfontdesc = pango_font_description_from_string("Sans 10"); pango_font_description_set_absolute_size(pfontdesc, 0.75*PANGO_SCALE*(v[3]-v[1])); pango_layout_set_width(playout, PANGO_SCALE*(v[2]-v[1])); pango_layout_set_font_description(playout, pfontdesc); - + //draw a rectangle to hide the not-up-to-date text from the last poppler rendering + //FIXME: the rect color is fixed to white.. perhaps it should be the same as the pdf background + gdk_draw_rectangle(GTK_WIDGET(view)->window, + GTK_WIDGET(view)->style->white_gc, + TRUE, + v[0], + v[1], + v[2]-v[0], + v[3]-v[1]); gdk_draw_layout(GTK_WIDGET(view)->window, GTK_WIDGET (view)->style->fg_gc[GTK_STATE_NORMAL], v[0], v[1], playout); } @@ -4465,32 +4473,39 @@ handle_click_at_location (EvView *view, form_field_mapping = ev_pixbuf_cache_get_form_field_mapping (view->pixbuf_cache, page); if (!form_field_mapping) return; new_field = ev_form_field_mapping_find (form_field_mapping, x_offset/view->scale, y_offset/view->scale); - if (!new_field) +/* if (!new_field) { return; + }*/ //store current entry text if (view->child) { if (GTK_IS_ENTRY(view->child->widget)) { ev_document_set_form_field_content(view->document, view->child->field_id, gtk_entry_get_text(GTK_ENTRY(view->child->widget))); if(view->pendingFormFields) g_array_append_val(view->pendingFormFields,view->child->field_id); + + ev_pixbuf_cache_reload_page(view->pixbuf_cache, page, view->rotation, view->scale); } } //clean current view widgets ev_view_remove_all(GTK_CONTAINER(view)); + + if (!new_field) { + return; + } p[0].x = new_field->x1; p[0].y = new_field->y1; p[1].x = new_field->x2; p[1].y = new_field->y2; doc_point_to_view_point (view, page, &p[0], &d[0]);