Commit 00efc5c1 authored by Jonathan Blandford's avatar Jonathan Blandford Committed by Jonathan Blandford

Clean up selection to be much smoother!

Sat Aug  6 01:12:44 2005  Jonathan Blandford  <jrb@redhat.com>

        * NOTES:
        * backend/ev-selection.c: (ev_selection_render_selection):
        * backend/ev-selection.h:
        * pdf/ev-poppler.cc:
        * shell/ev-jobs.c: (ev_job_render_dispose), (ev_job_render_new),
        (ev_job_render_run):
        * shell/ev-jobs.h:
        * shell/ev-pixbuf-cache.c: (dispose_cache_job_info),
        (ev_pixbuf_cache_new), (job_finished_cb), (add_job_if_needed),
        (convert_gdk_color_to_uint), (ev_pixbuf_cache_get_text_mapping),
        (ev_pixbuf_cache_style_changed),
        (ev_pixbuf_cache_get_selection_pixbuf),
        (ev_pixbuf_cache_set_selection_list),
        (ev_pixbuf_cache_get_selection_list):
        * shell/ev-pixbuf-cache.h:
        * shell/ev-utils.c: (ev_print_region_contents):
        * shell/ev-utils.h:
        * shell/ev-view.c: (ev_view_queue_draw_page),
        (selection_update_idle_cb), (ev_view_motion_notify_event),
        (ev_view_style_set), (draw_one_page), (ev_view_class_init),
        (setup_caches), (ev_view_find_next), (merge_selection_region),
        (selection_free):
        * shell/ev-window.c: (ev_window_update_fullscreen_popup):

        Clean up selection to be much smoother!
parent 7eceef43
Sat Aug 6 01:12:44 2005 Jonathan Blandford <jrb@redhat.com>
* NOTES:
* backend/ev-selection.c: (ev_selection_render_selection):
* backend/ev-selection.h:
* pdf/ev-poppler.cc:
* shell/ev-jobs.c: (ev_job_render_dispose), (ev_job_render_new),
(ev_job_render_run):
* shell/ev-jobs.h:
* shell/ev-pixbuf-cache.c: (dispose_cache_job_info),
(ev_pixbuf_cache_new), (job_finished_cb), (add_job_if_needed),
(convert_gdk_color_to_uint), (ev_pixbuf_cache_get_text_mapping),
(ev_pixbuf_cache_style_changed),
(ev_pixbuf_cache_get_selection_pixbuf),
(ev_pixbuf_cache_set_selection_list),
(ev_pixbuf_cache_get_selection_list):
* shell/ev-pixbuf-cache.h:
* shell/ev-utils.c: (ev_print_region_contents):
* shell/ev-utils.h:
* shell/ev-view.c: (ev_view_queue_draw_page),
(selection_update_idle_cb), (ev_view_motion_notify_event),
(ev_view_style_set), (draw_one_page), (ev_view_class_init),
(setup_caches), (ev_view_find_next), (merge_selection_region),
(selection_free):
* shell/ev-window.c: (ev_window_update_fullscreen_popup):
Clean up selection to be much smoother!
2005-08-05 Kristian Høgsberg <krh@redhat.com>
* pdf/ev-poppler.cc (pdf_selection_render_selection): Pass colors
......
......@@ -51,3 +51,12 @@ Thoughts on selection:
but for that to survive resizing, I might need to store the points as
doubles, etc. It should be possible to reconstruct it from the
existing EvViewSelection structs, so maybe I don't need it.
Things that can add to the selection:
* C-a/select all
* click-drag
* dbl click
* triple click
* shift-click
* search
* shift-cursor move (later)
......@@ -61,13 +61,16 @@ ev_selection_render_selection (EvSelection *selection,
EvRenderContext *rc,
GdkPixbuf **pixbuf,
EvRectangle *points,
EvRectangle *old_points)
EvRectangle *old_points,
guint text,
guint base)
{
EvSelectionIface *iface = EV_SELECTION_GET_IFACE (selection);
iface->render_selection (selection, rc,
pixbuf,
points, old_points);
points, old_points,
text, base);
}
GdkRegion *
......
......@@ -47,7 +47,9 @@ struct _EvSelectionIface
EvRenderContext *rc,
GdkPixbuf **pixbuf,
EvRectangle *points,
EvRectangle *old_points);
EvRectangle *old_points,
guint text,
guint base);
GdkRegion * (* get_selection_map) (EvSelection *selection,
EvRenderContext *rc);
GdkRegion * (* get_selection_region) (EvSelection *selection,
......@@ -60,7 +62,9 @@ void ev_selection_render_selection (EvSelection *selection,
EvRenderContext *rc,
GdkPixbuf **pixbuf,
EvRectangle *points,
EvRectangle *old_points);
EvRectangle *old_points,
guint text,
guint base);
GdkRegion *ev_selection_get_selection_map (EvSelection *selection,
EvRenderContext *rc);
GdkRegion *ev_selection_get_selection_region (EvSelection *selection,
......
......@@ -103,6 +103,20 @@ G_DEFINE_TYPE_WITH_CODE (PdfDocument, pdf_document, G_TYPE_OBJECT,
pdf_selection_iface_init);
});
static void
set_rc_data (PdfDocument *pdf_document,
EvRenderContext *rc)
{
if (rc->data == NULL) {
rc->data = poppler_document_get_page (pdf_document->document,
rc->page);
rc->destroy = g_object_unref;
} else {
g_assert (rc->page == poppler_page_get_index (POPPLER_PAGE (rc->data)));
}
}
static void
pdf_document_search_free (PdfDocumentSearch *search)
{
......@@ -330,17 +344,16 @@ pdf_document_render_pixbuf (EvDocument *document,
EvRenderContext *rc)
{
PdfDocument *pdf_document;
PopplerPage *poppler_page;
GdkPixbuf *pixbuf;
double width_points, height_points;
gint width, height;
pdf_document = PDF_DOCUMENT (document);
poppler_page = poppler_document_get_page (pdf_document->document,
rc->page);
set_page_orientation (pdf_document, poppler_page, rc->rotation);
poppler_page_get_size (poppler_page, &width_points, &height_points);
set_rc_data (pdf_document, rc);
set_page_orientation (pdf_document, POPPLER_PAGE (rc->data), rc->rotation);
poppler_page_get_size (POPPLER_PAGE (rc->data), &width_points, &height_points);
width = (int) ((width_points * rc->scale) + 0.5);
height = (int) ((height_points * rc->scale) + 0.5);
......@@ -348,13 +361,12 @@ pdf_document_render_pixbuf (EvDocument *document,
FALSE, 8,
width, height);
poppler_page_render_to_pixbuf (poppler_page,
poppler_page_render_to_pixbuf (POPPLER_PAGE (rc->data),
0, 0,
width, height,
rc->scale,
pixbuf);
g_object_unref (poppler_page);
return pixbuf;
}
......@@ -1169,19 +1181,20 @@ pdf_selection_render_selection (EvSelection *selection,
EvRenderContext *rc,
GdkPixbuf **pixbuf,
EvRectangle *points,
EvRectangle *old_points)
EvRectangle *old_points,
guint text,
guint base)
{
PdfDocument *pdf_document;
PopplerPage *poppler_page;
double width_points, height_points;
gint width, height;
pdf_document = PDF_DOCUMENT (selection);
poppler_page = poppler_document_get_page (pdf_document->document,
rc->page);
set_page_orientation (pdf_document, poppler_page, rc->rotation);
set_rc_data (pdf_document, rc);
poppler_page_get_size (poppler_page, &width_points, &height_points);
set_page_orientation (pdf_document, POPPLER_PAGE (rc->data), rc->rotation);
poppler_page_get_size (POPPLER_PAGE (rc->data), &width_points, &height_points);
width = (int) ((width_points * rc->scale) + 0.5);
height = (int) ((height_points * rc->scale) + 0.5);
......@@ -1191,16 +1204,12 @@ pdf_selection_render_selection (EvSelection *selection,
width, height);
}
/* FIXME: Hardcoded clearlooks selection color. We should
* track theme color changes and focus out event and update
* selection color accordingly. */
poppler_page_render_selection (poppler_page,
poppler_page_render_selection (POPPLER_PAGE (rc->data),
rc->scale, *pixbuf,
(PopplerRectangle *)points,
(PopplerRectangle *)old_points,
0x00ffffff, 0x007c99ad);
g_object_unref (poppler_page);
text,
base);
}
......@@ -1210,16 +1219,14 @@ pdf_selection_get_selection_region (EvSelection *selection,
EvRectangle *points)
{
PdfDocument *pdf_document;
PopplerPage *poppler_page;
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, rc->rotation);
retval = poppler_page_get_selection_region (poppler_page, rc->scale, (PopplerRectangle *) points);
g_object_unref (poppler_page);
set_rc_data (pdf_document, rc);
set_page_orientation (pdf_document, POPPLER_PAGE (rc->data), rc->rotation);
retval = poppler_page_get_selection_region ((PopplerPage *)rc->data, rc->scale, (PopplerRectangle *) points);
return retval;
}
......
......@@ -116,6 +116,16 @@ ev_job_render_dispose (GObject *object)
job->rc = NULL;
}
if (job->selection) {
g_object_unref (job->selection);
job->selection = NULL;
}
if (job->selection_region) {
gdk_region_destroy (job->selection_region);
job->selection_region = NULL;
}
(* G_OBJECT_CLASS (ev_job_render_parent_class)->dispose) (object);
}
......@@ -226,6 +236,8 @@ ev_job_render_new (EvDocument *document,
gint width,
gint height,
EvRectangle *selection_points,
guint text,
guint base,
gboolean include_links,
gboolean include_text,
gboolean include_selection)
......@@ -242,6 +254,8 @@ ev_job_render_new (EvDocument *document,
job->rc = g_object_ref (rc);
job->target_width = width;
job->target_height = height;
job->text = text;
job->base = base;
job->include_links = include_links;
job->include_text = include_text;
job->include_selection = include_selection;
......@@ -285,12 +299,18 @@ ev_job_render_run (EvJobRender *job)
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))
if (job->include_selection && EV_IS_SELECTION (EV_JOB (job)->document)) {
ev_selection_render_selection (EV_SELECTION (EV_JOB (job)->document),
job->rc,
&(job->selection),
&(job->selection_points),
NULL);
NULL,
job->text, job->base);
job->selection_region =
ev_selection_get_selection_region (EV_SELECTION (EV_JOB (job)->document),
job->rc,
&(job->selection_points));
}
EV_JOB (job)->finished = TRUE;
}
......
......@@ -118,7 +118,10 @@ struct _EvJobRender
GdkRegion *text_mapping;
GdkPixbuf *selection;
GdkRegion *selection_region;
EvRectangle selection_points;
guint base;
guint text;
gint include_links : 1;
gint include_text : 1;
......@@ -184,6 +187,8 @@ EvJob *ev_job_render_new (EvDocument *document,
gint width,
gint height,
EvRectangle *selection_points,
guint text,
guint base,
gboolean include_links,
gboolean include_text,
gboolean include_selection);
......
......@@ -10,12 +10,13 @@ typedef struct _CacheJobInfo
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.
* new_points is the target selection size. */
EvRectangle selection_points;
GdkPixbuf *selection;
GdkRegion *selection_region;
EvRectangle new_points;
} CacheJobInfo;
......@@ -23,7 +24,9 @@ struct _EvPixbufCache
{
GObject parent;
EvDocument *document;
/* We keep a link to our containing view just for style information. */
GtkWidget *view;
EvDocument *document;
int start_page;
int end_page;
......@@ -64,10 +67,11 @@ 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 guint convert_gdk_color_to_uint (GdkColor *color);
static gboolean new_selection_pixbuf_needed(EvPixbufCache *pixbuf_cache,
CacheJobInfo *job_info,
gint page,
gfloat scale);
/* These are used for iterating through the prev and next arrays */
......@@ -153,6 +157,10 @@ dispose_cache_job_info (CacheJobInfo *job_info,
g_object_unref (G_OBJECT (job_info->selection));
job_info->selection = NULL;
}
if (job_info->selection_region) {
gdk_region_destroy (job_info->selection_region);
job_info->selection_region = NULL;
}
job_info->selection_points.x1 = -1;
job_info->new_points.x1 = -1;
......@@ -178,11 +186,14 @@ ev_pixbuf_cache_dispose (GObject *object)
EvPixbufCache *
ev_pixbuf_cache_new (EvDocument *document)
ev_pixbuf_cache_new (GtkWidget *view,
EvDocument *document)
{
EvPixbufCache *pixbuf_cache;
pixbuf_cache = (EvPixbufCache *) g_object_new (EV_TYPE_PIXBUF_CACHE, NULL);
/* This is a backlink, so we don't ref this */
pixbuf_cache->view = view;
pixbuf_cache->document = document;
return pixbuf_cache;
......@@ -223,10 +234,14 @@ job_finished_cb (EvJob *job,
}
if (job_render->include_selection) {
pixbuf = g_object_ref (job_render->selection);
if (job_info->selection)
g_object_unref (job_info->selection);
if (job_info->selection_region)
gdk_region_destroy (job_info->selection_region);
job_info->selection_points = job_render->selection_points;
job_info->selection = job_render->selection;
job_info->selection_region = gdk_region_copy (job_render->selection_region);
job_info->selection = pixbuf;
g_assert (job_info->selection_points.x1 >= 0);
}
......@@ -487,6 +502,7 @@ add_job_if_needed (EvPixbufCache *pixbuf_cache,
gboolean include_text = FALSE;
gboolean include_selection = FALSE;
int width, height;
guint text, base;
if (job_info->job)
return;
......@@ -503,9 +519,9 @@ add_job_if_needed (EvPixbufCache *pixbuf_cache,
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);
ev_render_context_set_rotation (job_info->rc, rotation);
}
/* Figure out what else we need for this job */
......@@ -517,10 +533,16 @@ add_job_if_needed (EvPixbufCache *pixbuf_cache,
include_selection = TRUE;
}
gtk_widget_ensure_style (pixbuf_cache->view);
text = convert_gdk_color_to_uint (& (pixbuf_cache->view->style->text [GTK_STATE_SELECTED]));
base = convert_gdk_color_to_uint (& (pixbuf_cache->view->style->base [GTK_STATE_SELECTED]));
job_info->job = ev_job_render_new (pixbuf_cache->document,
job_info->rc,
width, height,
&(job_info->new_points),
text, base,
include_links,
include_text,
include_selection);
......@@ -643,6 +665,17 @@ ev_pixbuf_cache_get_link_mapping (EvPixbufCache *pixbuf_cache,
}
/* Selection */
static guint
convert_gdk_color_to_uint (GdkColor *color)
{
g_assert (color);
return 0xff << 24 |
(color->red & 0xff00) << 8 |
(color->green & 0xff00) |
(color->blue & 0xff00) >> 8;
}
static gboolean
new_selection_pixbuf_needed (EvPixbufCache *pixbuf_cache,
CacheJobInfo *job_info,
......@@ -683,7 +716,7 @@ clear_selection_if_needed (EvPixbufCache *pixbuf_cache,
GdkRegion *
ev_pixbuf_cache_get_text_mapping (EvPixbufCache *pixbuf_cache,
gint page)
gint page)
{
CacheJobInfo *job_info;
......@@ -718,10 +751,44 @@ ev_pixbuf_cache_clear (EvPixbufCache *pixbuf_cache)
}
void
ev_pixbuf_cache_style_changed (EvPixbufCache *pixbuf_cache)
{
gint i;
/* FIXME: doesn't update running jobs. */
for (i = 0; i < pixbuf_cache->preload_cache_size; i++) {
CacheJobInfo *job_info;
job_info = pixbuf_cache->prev_job + i;
if (job_info->selection) {
g_object_unref (G_OBJECT (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));
job_info->selection = NULL;
}
}
for (i = 0; i < PAGE_CACHE_LEN (pixbuf_cache); i++) {
CacheJobInfo *job_info;
job_info = pixbuf_cache->job_list + i;
if (job_info->selection) {
g_object_unref (G_OBJECT (job_info->selection));
job_info->selection = NULL;
}
}
}
GdkPixbuf *
ev_pixbuf_cache_get_selection_pixbuf (EvPixbufCache *pixbuf_cache,
gint page,
gfloat scale)
ev_pixbuf_cache_get_selection_pixbuf (EvPixbufCache *pixbuf_cache,
gint page,
gfloat scale,
GdkRegion **region)
{
CacheJobInfo *job_info;
......@@ -737,6 +804,10 @@ ev_pixbuf_cache_get_selection_pixbuf (EvPixbufCache *pixbuf_cache,
if (job_info->new_points.x1 < 0)
return NULL;
/* Update the rc */
g_assert (job_info->rc);
ev_render_context_set_scale (job_info->rc, scale);
/* 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 */
......@@ -753,33 +824,44 @@ ev_pixbuf_cache_get_selection_pixbuf (EvPixbufCache *pixbuf_cache,
* doesn't kill us. Rendering a few glyphs should really be fast.
*/
if (ev_rect_cmp (&(job_info->new_points), &(job_info->selection_points))) {
EvRenderContext *rc;
rc = ev_render_context_new (0, page, scale);
EvRectangle *old_points;
guint text, base;
/* we need to get a new selection pixbuf */
ev_document_doc_mutex_lock ();
if (job_info->selection_points.x1 < 0) {
g_assert (job_info->selection == NULL);
ev_selection_render_selection (EV_SELECTION (pixbuf_cache->document),
rc, &(job_info->selection),
&(job_info->new_points),
NULL);
old_points = NULL;
} else {
g_assert (job_info->selection != NULL);
ev_selection_render_selection (EV_SELECTION (pixbuf_cache->document),
rc, &(job_info->selection),
&(job_info->new_points),
&(job_info->selection_points));
old_points = &(job_info->selection_points);
}
if (job_info->selection_region)
gdk_region_destroy (job_info->selection_region);
job_info->selection_region =
ev_selection_get_selection_region (EV_SELECTION (pixbuf_cache->document),
job_info->rc,
&(job_info->new_points));
gtk_widget_ensure_style (pixbuf_cache->view);
text = convert_gdk_color_to_uint (& (pixbuf_cache->view->style->text [GTK_STATE_SELECTED]));
base = convert_gdk_color_to_uint (& (pixbuf_cache->view->style->base [GTK_STATE_SELECTED]));
ev_selection_render_selection (EV_SELECTION (pixbuf_cache->document),
job_info->rc, &(job_info->selection),
&(job_info->new_points),
old_points,
text, base);
job_info->selection_points = job_info->new_points;
ev_document_doc_mutex_unlock ();
}
if (region)
*region = job_info->selection_region;
return job_info->selection;
}
static void
update_job_selection (CacheJobInfo *job_info,
EvViewSelection *selection)
......@@ -802,7 +884,8 @@ clear_job_selection (CacheJobInfo *job_info)
}
/* This function will reset the selection on pages that no longer have them, and
* will update the target_selection on those that need it.
* will update the target_selection on those that need it. It will _not_ free
* the previous selection_list -- that's up to caller to do.
*/
void
ev_pixbuf_cache_set_selection_list (EvPixbufCache *pixbuf_cache,
......@@ -865,7 +948,7 @@ ev_pixbuf_cache_set_selection_list (EvPixbufCache *pixbuf_cache,
for (i = 0; i < pixbuf_cache->preload_cache_size; i++) {
if (page >= ev_page_cache_get_n_pages (page_cache))
break;
selection = NULL;
while (list) {
if (((EvViewSelection *)list->data)->page == page) {
......@@ -883,3 +966,73 @@ ev_pixbuf_cache_set_selection_list (EvPixbufCache *pixbuf_cache,
page ++;
}
}
/* Returns what the pixbuf cache thinks is */
GList *
ev_pixbuf_cache_get_selection_list (EvPixbufCache *pixbuf_cache)
{
EvPageCache *page_cache;
EvViewSelection *selection;
GList *retval = NULL;
int page;
int i;
g_return_val_if_fail (EV_IS_PIXBUF_CACHE (pixbuf_cache), NULL);
page_cache = ev_page_cache_get (pixbuf_cache->document);
/* We check each area to see what needs updating, and what needs freeing; */
page = pixbuf_cache->start_page - pixbuf_cache->preload_cache_size;
for (i = 0; i < pixbuf_cache->preload_cache_size; i++) {
if (page < 0) {
page ++;
continue;
}
if (pixbuf_cache->prev_job[i].selection_points.x1 != -1) {
selection = g_new0 (EvViewSelection, 1);
selection->page = page;
selection->rect = pixbuf_cache->prev_job[i].selection_points;
if (pixbuf_cache->prev_job[i].selection_region)
selection->covered_region = gdk_region_copy (pixbuf_cache->prev_job[i].selection_region);
retval = g_list_append (retval, selection);
}
page ++;
}
page = pixbuf_cache->start_page;
for (i = 0; i < PAGE_CACHE_LEN (pixbuf_cache); i++) {
if (pixbuf_cache->job_list[i].selection_points.x1 != -1) {
selection = g_new0 (EvViewSelection, 1);
selection->page = page;
selection->rect = pixbuf_cache->job_list[i].selection_points;
if (pixbuf_cache->job_list[i].selection_region)
selection->covered_region = gdk_region_copy (pixbuf_cache->job_list[i].selection_region);
retval = g_list_append (retval, selection);
}
page ++;
}
for (i = 0; i < pixbuf_cache->preload_cache_size; i++) {
if (page >= ev_page_cache_get_n_pages (page_cache))
break;
if (pixbuf_cache->next_job[i].selection_points.x1 != -1) {
selection = g_new0 (EvViewSelection, 1);
selection->page = page;
selection->rect = pixbuf_cache->next_job[i].selection_points;
if (pixbuf_cache->next_job[i].selection_region)
selection->covered_region = gdk_region_copy (pixbuf_cache->next_job[i].selection_region);
retval = g_list_append (retval, selection);
}
page ++;
}
return retval;
}
......@@ -42,13 +42,15 @@ G_BEGIN_DECLS
typedef struct {
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 (EvDocument *document);
EvPixbufCache *ev_pixbuf_cache_new (GtkWidget *view,
EvDocument *document);
void ev_pixbuf_cache_set_page_range (EvPixbufCache *pixbuf_cache,
gint start_page,
gint end_page,
......@@ -62,13 +64,16 @@ GList *ev_pixbuf_cache_get_link_mapping (EvPixbufCache *pixbuf_cache
GdkRegion *ev_pixbuf_cache_get_text_mapping (EvPixbufCache *pixbuf_cache,
gint page);
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);
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);
G_END_DECLS
......
......@@ -177,6 +177,35 @@ ev_pixbuf_add_shadow (GdkPixbuf *src, int size,
}
/* Simple function to output the contents of a region. Used solely for testing
* the region code.
*/
void
ev_print_region_contents (GdkRegion *region)
{
GdkRectangle *rectangles = NULL;
gint n_rectangles, i;
if (region == NULL) {
g_print ("<empty region>\n");
return;
}
g_print ("<region %p>\n", region);
gdk_region_get_rectangles (region, &rectangles, &n_rectangles);
for (i = 0; i < n_rectangles; i++) {
g_print ("\t(%d %d, %d %d) [%dx%d]\n",
rectangles[i].x,
rectangles[i].y,
rectangles[i].x + rectangles[i].width,
rectangles[i].y + rectangles[i].height,
rectangles[i].width,
rectangles[i].height);
}
g_free (rectangles);
}
#ifndef HAVE_G_FILE_SET_CONTENTS
#include <errno.h>
......
......@@ -22,12 +22,15 @@
#define __EV_UTILS_H__
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gtk/gtk.h>
G_BEGIN_DECLS
GdkPixbuf *ev_pixbuf_add_shadow (GdkPixbuf *src, int size,
int x_offset, int y_offset, double opacity);
void ev_print_region_contents (GdkRegion *region);
#ifndef HAVE_G_FILE_SET_CONTENTS
gboolean ev_file_set_contents (const gchar *filename,
......
......@@ -29,6 +29,7 @@
#include "ev-marshal.h"
#include "ev-view.h"
#include "ev-utils.h"
#include "ev-selection.h"
#include "ev-document-find.h"
#include "ev-document-misc.h"
......@@ -120,6 +121,10 @@ struct _EvView {
char *status;
char *find_status;
/* Scrolling */
GtkAdjustment *hadjustment;
GtkAdjustment *vadjustment;
gint scroll_x;
gint scroll_y;