Commit bebd9cea authored by Jonathan Blandford's avatar Jonathan Blandford Committed by Jonathan Blandford

New file with some random thoughts.

Wed Feb  2 21:13:11 2005  Jonathan Blandford  <jrb@redhat.com>

        * NOTES: New file with some random thoughts.

        * TODO: Update.

        * backend/ev-document-misc.c:
        (ev_document_misc_get_page_border_size): New function to
        canonicalize shadow drawing sizes.  Possibly goofy.

        * shell/ev-view.c: (ev_view_size_request), (set_document_page),
        (ev_view_best_fit), (ev_view_fit_width):
        * pdf/xpdf/pdf-document.cc:
        * pixbuf/pixbuf-document.c: (pixbuf_document_get_page_size):
        * ps/ps-document.c: (ps_document_get_page_size):
        * backend/ev-document-misc.h:
        * backend/ev-document.c: (ev_document_get_page_size):
        * backend/ev-document.h: get_page_size now takes a page number
        parameter.  Made all the backends/frontends honor it.

        * data/evince-ui.xml: Added a multiple-page mode.  Uncomment to
        see.  Doesn't work yet.

        * shell/Makefile.am:
        * shell/ev-page-view.[ch]: New multi-page view.  Really rough.
        Doesn't do anything yet.

        * shell/ev-sidebar-thumbnails.c:
        (ev_sidebar_thumbnails_set_document): [1..n_pages] instead of
        [0..n_pages-1]

        * shell/ev-window.c: (update_action_sensitivity),
        (ev_window_setup_document), (ev_window_set_page_mode),
        (ev_window_page_mode_cb), (ev_window_init): Clean up the
        view-swapping code a bit so we can have multiple views on a
        document.  Add the multi-page view, though it can't be turned on
        yet.
parent e6bb7c7e
Wed Feb 2 21:13:11 2005 Jonathan Blandford <jrb@redhat.com>
* NOTES: New file with some random thoughts.
* TODO: Update.
* backend/ev-document-misc.c:
(ev_document_misc_get_page_border_size): New function to
canonicalize shadow drawing sizes. Possibly goofy.
* shell/ev-view.c: (ev_view_size_request), (set_document_page),
(ev_view_best_fit), (ev_view_fit_width):
* pdf/xpdf/pdf-document.cc:
* pixbuf/pixbuf-document.c: (pixbuf_document_get_page_size):
* ps/ps-document.c: (ps_document_get_page_size):
* backend/ev-document-misc.h:
* backend/ev-document.c: (ev_document_get_page_size):
* backend/ev-document.h: get_page_size now takes a page number
parameter. Made all the backends/frontends honor it.
* data/evince-ui.xml: Added a multiple-page mode. Uncomment to
see. Doesn't work yet.
* shell/Makefile.am:
* shell/ev-page-view.[ch]: New multi-page view. Really rough.
Doesn't do anything yet.
* shell/ev-sidebar-thumbnails.c:
(ev_sidebar_thumbnails_set_document): [1..n_pages] instead of
[0..n_pages-1]
* shell/ev-window.c: (update_action_sensitivity),
(ev_window_setup_document), (ev_window_set_page_mode),
(ev_window_page_mode_cb), (ev_window_init): Clean up the
view-swapping code a bit so we can have multiple views on a
document. Add the multi-page view, though it can't be turned on
yet.
2005-02-01 Marco Pesenti Gritti <marco@gnome.org>
* shell/ev-application.c: (ev_application_open):
......
SOME RANDOM COMMENTS:
=====================
* We assume that all documents can be broken down into a linear
collection of pages.
* If a document type doesn't break down in such a way (like web pages)
then it's probably not a good fit for this application.
* Each page has a natural page size in pixels. This is generally
ignored in favor of a scale-to-fit mode, but is occasionally
important for backends like the image backend.
* Each page is not necessarily the same size.
* We refer to pages by page number. This number ranges from 1 to
document->n_pages. A page index of -1 means the current set page,
and a page index of 0 is not used.
--
Thoughts on threading:
* The primary thing we are trying to do is minimize switching pages, as
doing so is slow for backends. Additionally, some operations on the
backend are slow, leaving poor interactivity. This
--
......@@ -6,7 +6,13 @@ Improve Find system
Display location of results in thumbnails?
Only display thumbnails of pages found?
Implement multi-page view for continuous page scrolling
Move to three page views:
* Single page (prolly default for some backends)
* Continuous scrolling
* Side-by-side continuous scrolling
Sidebar improvements for ps/pixbuf, or PDF files without a TOC.
Improve look of combobox Thumbnails/Index
......@@ -16,6 +22,16 @@ Document Properties Dialog for document meta-data
Provide Desktop icon Thumbnailer for Documents
Make an object that handles the page count.
Move to having three sizing types:
* Free zooming
* constrain to width
* constrain to height
* also, maybe add a 1-1 button. Possibly dubious, though.
------- TODONE ------- (move finished TODO items here)
Create a TODO list
......
#include "ev-document-misc.h"
#include <string.h>
#include <gtk/gtk.h>
/* Returns a new GdkPixbuf that is suitable for placing in the thumbnail view.
* It is four pixels wider and taller than the source. If source_pixbuf is not
......@@ -62,3 +63,31 @@ ev_document_misc_get_thumbnail_frame (int width,
return retval;
}
void
ev_document_misc_get_page_border_size (gint page_width,
gint page_height,
gint *left_border,
gint *right_border,
gint *top_border,
gint *bottom_border)
{
g_assert (left_border);
g_assert (right_border);
g_assert (top_border);
g_assert (bottom_border);
*left_border = 1;
*top_border = 1;
if (page_width < 100) {
*right_border = 2;
*bottom_border = 2;
} else if (page_width < 500) {
*right_border = 3;
*left_border = 3;
} else {
*right_border = 4;
*bottom_border = 4;
}
}
......@@ -32,6 +32,13 @@ GdkPixbuf *ev_document_misc_get_thumbnail_frame (int width,
int height,
GdkPixbuf *source_pixbuf);
void ev_document_misc_get_page_border_size (gint page_width,
gint page_height,
gint *left_border,
gint *right_border,
gint *top_border,
gint *bottom_border);
G_END_DECLS
#endif /* EV_DOCUMENT_MISC_H */
......@@ -164,11 +164,12 @@ ev_document_set_page_offset (EvDocument *document,
void
ev_document_get_page_size (EvDocument *document,
int page,
int *width,
int *height)
{
EvDocumentIface *iface = EV_DOCUMENT_GET_IFACE (document);
iface->get_page_size (document, width, height);
iface->get_page_size (document, page, width, height);
}
char *
......
......@@ -74,6 +74,7 @@ struct _EvDocumentIface
int x,
int y);
void (* get_page_size) (EvDocument *document,
int page,
int *width,
int *height);
char * (* get_text) (EvDocument *document,
......@@ -112,6 +113,7 @@ void ev_document_set_page_offset (EvDocument *document,
int x,
int y);
void ev_document_get_page_size (EvDocument *document,
int page,
int *width,
int *height);
char *ev_document_get_text (EvDocument *document,
......
......@@ -56,5 +56,10 @@
<toolitem action="ViewZoomOut"/>
<toolitem action="ViewBestFit"/>
<toolitem action="ViewPageWidth"/>
<!--
<separator/>
<toolitem action="SinglePage"/>
<toolitem action="ContinuousPage"/>
-->
</toolbar>
</ui>
......@@ -350,21 +350,32 @@ pdf_document_set_page_offset (EvDocument *document,
static void
pdf_document_get_page_size (EvDocument *document,
int page,
int *width,
int *height)
{
PdfDocument *pdf_document = PDF_DOCUMENT (document);
Page *the_page;
/* set some default values */
if (width)
*width = 1;
if (height)
*height = 1;
if (document_validate_page (pdf_document)) {
if (page == -1 && document_validate_page (pdf_document)) {
if (width)
*width = pdf_document->out->getBitmapWidth();
if (height)
*height = pdf_document->out->getBitmapHeight();
} else {
if (width)
*width = 1;
if (height)
*height = 1;
return;
}
the_page = pdf_document->doc->getCatalog ()->getPage (page);
if (the_page) {
*width = (int) the_page->getWidth ();
*height = (int) the_page->getHeight ();
}
}
......@@ -1244,8 +1255,7 @@ pdf_document_thumbnails_get_dimensions (EvDocumentThumbnails *document_thumbnail
Thumb *thumb = NULL;
gdouble page_ratio;
/* getPage seems to want page + 1 for some reason; */
the_page = pdf_document->doc->getCatalog ()->getPage (page + 1);
the_page = pdf_document->doc->getCatalog ()->getPage (page);
the_page->getThumb (&the_thumb);
if (!(the_thumb.isNull () || the_thumb.isNone())) {
......
......@@ -137,6 +137,7 @@ pixbuf_document_set_page_offset (EvDocument *document,
static void
pixbuf_document_get_page_size (EvDocument *document,
int page,
int *width,
int *height)
{
......
......@@ -1784,9 +1784,12 @@ ps_document_set_page_offset (EvDocument *document,
static void
ps_document_get_page_size (EvDocument *document,
int *width,
int *height)
int page,
int *width,
int *height)
{
/* Post script documents never vary in size */
PSDocument *gs = PS_DOCUMENT (document);
if (width) {
......
......@@ -25,6 +25,8 @@ evince_SOURCES= \
ev-marshal.h \
ev-page-action.c \
ev-page-action.h \
ev-page-view.c \
ev-page-view.h \
ev-password.h \
ev-password.c \
ev-password-view.h \
......
/*
* Copyright (C) 2005 Jonathan Blandford
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "config.h"
#include "ev-page-view.h"
#include "ev-marshal.h"
#include "ev-document-misc.h"
#include <gtk/gtk.h>
/* We keep a cached array of all the page sizes. The info is accessed via
* page_sizes [page - 1], as pages start at 1 */
typedef struct _EvPageViewInfo
{
gint width;
gint height;
} EvPageViewInfo;
struct _EvPageViewPrivate
{
gint width, height;
gint page_spacing;
GdkWindow *bin_window;
EvDocument *document;
EvPageViewInfo *page_sizes;
GtkAdjustment *hadjustment;
GtkAdjustment *vadjustment;
gdouble scale;
/* Page information*/
gint n_pages;
gint max_page_width;
/* these two are only set if uniform_page_size is set */
gint uniform_page_width;
gint uniform_page_height;
guint uniform_page_size : 1;
};
static void ev_page_view_init (EvPageView *page_view);
static void ev_page_view_class_init (EvPageViewClass *klass);
static void ev_page_view_set_scroll_adjustments (EvPageView *page_view,
GtkAdjustment *hadjustment,
GtkAdjustment *vadjustment);
static void ev_page_view_size_request (GtkWidget *widget,
GtkRequisition *requisition);
static void ev_page_view_size_allocate (GtkWidget *widget,
GtkAllocation *allocation);
static gboolean ev_page_view_expose (GtkWidget *widget,
GdkEventExpose *expose);
static void ev_page_view_realize (GtkWidget *widget);
static void ev_page_view_unrealize (GtkWidget *widget);
static void ev_page_view_map (GtkWidget *widget);
static void ev_page_view_load (EvPageView *page_view);
static void ev_page_view_adjustment_changed (GtkAdjustment *adjustment,
EvPageView *page_view);
static void ev_page_view_update_size (EvPageView *page_view);
G_DEFINE_TYPE (EvPageView, ev_page_view, GTK_TYPE_WIDGET)
#define EV_PAGE_VIEW_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EV_TYPE_PAGE_VIEW, EvPageViewPrivate))
static void
ev_page_view_init (EvPageView *page_view)
{
page_view->priv = EV_PAGE_VIEW_GET_PRIVATE (page_view);
page_view->priv->width = 1;
page_view->priv->height = 1;
page_view->priv->page_spacing = 10;
page_view->priv->scale = 1.0;
/* Make some stuff up */
page_view->priv->n_pages = 0;
page_view->priv->uniform_page_width = -1;
page_view->priv->uniform_page_height = -1;
page_view->priv->uniform_page_size = FALSE;
}
static void
ev_page_view_class_init (EvPageViewClass *klass)
{
GObjectClass *o_class;
GtkWidgetClass *widget_class;
o_class = (GObjectClass *) klass;
widget_class = (GtkWidgetClass *) klass;
klass->set_scroll_adjustments = ev_page_view_set_scroll_adjustments;
g_type_class_add_private (klass, sizeof (EvPageViewPrivate));
widget_class->size_request = ev_page_view_size_request;
widget_class->size_allocate = ev_page_view_size_allocate;
widget_class->expose_event = ev_page_view_expose;
widget_class->realize = ev_page_view_realize;
widget_class->unrealize = ev_page_view_unrealize;
widget_class->map = ev_page_view_map;
widget_class->set_scroll_adjustments_signal =
g_signal_new ("set_scroll_adjustments",
G_TYPE_FROM_CLASS (o_class),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
G_STRUCT_OFFSET (EvPageViewClass, set_scroll_adjustments),
NULL, NULL,
ev_marshal_VOID__OBJECT_OBJECT,
G_TYPE_NONE, 2,
GTK_TYPE_ADJUSTMENT,
GTK_TYPE_ADJUSTMENT);
}
static void
ev_page_view_set_scroll_adjustments (EvPageView *page_view,
GtkAdjustment *hadjustment,
GtkAdjustment *vadjustment)
{
gboolean need_adjust = FALSE;
if (hadjustment)
g_return_if_fail (GTK_IS_ADJUSTMENT (hadjustment));
else
hadjustment = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
if (vadjustment)
g_return_if_fail (GTK_IS_ADJUSTMENT (vadjustment));
else
vadjustment = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
if (page_view->priv->hadjustment && (page_view->priv->hadjustment != hadjustment))
{
g_signal_handlers_disconnect_matched (page_view->priv->hadjustment, G_SIGNAL_MATCH_DATA,
0, 0, NULL, NULL, page_view);
g_object_unref (page_view->priv->hadjustment);
}
if (page_view->priv->vadjustment && (page_view->priv->vadjustment != vadjustment))
{
g_signal_handlers_disconnect_matched (page_view->priv->vadjustment, G_SIGNAL_MATCH_DATA,
0, 0, NULL, NULL, page_view);
g_object_unref (page_view->priv->vadjustment);
}
if (page_view->priv->hadjustment != hadjustment)
{
page_view->priv->hadjustment = hadjustment;
g_object_ref (page_view->priv->hadjustment);
gtk_object_sink (GTK_OBJECT (page_view->priv->hadjustment));
g_signal_connect (page_view->priv->hadjustment, "value_changed",
G_CALLBACK (ev_page_view_adjustment_changed),
page_view);
need_adjust = TRUE;
}
if (page_view->priv->vadjustment != vadjustment)
{
page_view->priv->vadjustment = vadjustment;
g_object_ref (page_view->priv->vadjustment);
gtk_object_sink (GTK_OBJECT (page_view->priv->vadjustment));
g_signal_connect (page_view->priv->vadjustment, "value_changed",
G_CALLBACK (ev_page_view_adjustment_changed),
page_view);
need_adjust = TRUE;
}
if (need_adjust)
ev_page_view_adjustment_changed (NULL, page_view);
}
static void
ev_page_view_update_size (EvPageView *page_view)
{
gint left_border;
gint right_border;
gint top_border;
gint bottom_border;
gint width, height;
g_assert (page_view->priv->scale > 0.0);
if (page_view->priv->uniform_page_size) {
width = (int) (page_view->priv->uniform_page_width *
page_view->priv->scale);
height = (int) (page_view->priv->uniform_page_height *
page_view->priv->scale);
ev_document_misc_get_page_border_size (width, height,
& left_border, & right_border,
& top_border, & bottom_border);
page_view->priv->width = width
+ page_view->priv->page_spacing * 2
+ left_border
+ right_border;
page_view->priv->height =
((height
+ page_view->priv->page_spacing
+ top_border
+ bottom_border)
* page_view->priv->n_pages) +
page_view->priv->page_spacing;
} else {
int i;
page_view->priv->width = 0;
page_view->priv->height = page_view->priv->page_spacing;
for (i = 0; i < page_view->priv->n_pages; i++) {
width = page_view->priv->page_sizes[i].width *
page_view->priv->scale;
height = page_view->priv->page_sizes[i].height *
page_view->priv->scale;
ev_document_misc_get_page_border_size (width, height,
& left_border, & right_border,
& top_border, & bottom_border);
width = width
+ page_view->priv->page_spacing * 2
+ left_border
+ right_border;
height = height
+ page_view->priv->page_spacing
+ top_border
+ bottom_border;
page_view->priv->width = MAX (width, page_view->priv->width);
page_view->priv->height += height;
}
}
}
static void
ev_page_view_size_request (GtkWidget *widget,
GtkRequisition *requisition)
{
EvPageView *page_view;
page_view = EV_PAGE_VIEW (widget);
ev_page_view_update_size (page_view);
requisition->width = page_view->priv->width;
requisition->height = page_view->priv->height;
}
static void
ev_page_view_paint_one_page (EvPageView *page_view,
GdkRectangle *area,
gint left_border,
gint right_border,
gint top_border,
gint bottom_border)
{
GtkWidget *widget;
widget = GTK_WIDGET (page_view);
g_print ("paint one page (%d,%d) %dx%d\n",
area->x, area->y,
area->width,
area->height);
gdk_draw_rectangle (page_view->priv->bin_window,
widget->style->black_gc,
TRUE,
area->x,
area->y,
area->width,
area->height);
gdk_draw_rectangle (page_view->priv->bin_window,
widget->style->white_gc,
TRUE,
area->x + left_border,
area->y + top_border,
area->width - (left_border + right_border),
area->height - (top_border + bottom_border));
gdk_draw_rectangle (page_view->priv->bin_window,
widget->style->mid_gc[widget->state],
TRUE,
area->x,
area->y + area->height - (bottom_border - top_border),
bottom_border - top_border,
bottom_border - top_border);
gdk_draw_rectangle (page_view->priv->bin_window,
widget->style->mid_gc[widget->state],
TRUE,
area->x + area->width - (right_border - left_border),
area->y,
right_border - left_border,
right_border - left_border);
}
static void
ev_page_view_expose_uniform (GtkWidget *widget,
GdkEventExpose *expose)
{
EvPageView *page_view;
gint left_border;
gint right_border;
gint top_border;
gint bottom_border;
int x_offset = 0;
GdkRectangle rectangle;
gint width, height;
int i;
page_view = EV_PAGE_VIEW (widget);
width = (int) (page_view->priv->uniform_page_width *
page_view->priv->scale);
height = (int) (page_view->priv->uniform_page_height *
page_view->priv->scale);
if (widget->allocation.width > page_view->priv->width)
x_offset = (widget->allocation.width - page_view->priv->width)/2;
ev_document_misc_get_page_border_size (width, height,
& left_border,
& right_border,
& top_border,
& bottom_border);
rectangle.x = page_view->priv->page_spacing + x_offset;
rectangle.y = page_view->priv->page_spacing;
rectangle.width = width
+ left_border
+ right_border;
rectangle.height = height
+ top_border
+ bottom_border;
for (i = 0; i < page_view->priv->n_pages; i++) {
GdkRectangle unused;
if (gdk_rectangle_intersect (&rectangle,
&expose->area,
&unused))
ev_page_view_paint_one_page (page_view,
& rectangle,
left_border, right_border,
top_border, bottom_border);
rectangle.y += rectangle.height
+ page_view->priv->page_spacing;
}
}
static void
ev_page_view_expose_pages (GtkWidget *widget,
GdkEventExpose *expose)
{
EvPageView *page_view;
gint left_border;
gint right_border;
gint top_border;
gint bottom_border;
int x_offset = 0;
GdkRectangle rectangle;
gint width, height;
int i;
page_view = EV_PAGE_VIEW (widget);
width = (int) (page_view->priv->uniform_page_width *
page_view->priv->scale);
height = (int) (page_view->priv->uniform_page_height *
page_view->priv->scale);
if (widget->allocation.width > page_view->priv->width)
x_offset = (widget->allocation.width - page_view->priv->width)/2;
ev_document_misc_get_page_border_size (width, height,
& left_border,
& right_border,
& top_border,
& bottom_border);
rectangle.x = page_view->priv->page_spacing + x_offset;
rectangle.y = page_view->priv->page_spacing;
rectangle.width = width
+ left_border
+ right_border;
rectangle.height = height
+ top_border
+ bottom_border;
for (i = 0; i < page_view->priv->n_pages; i++) {
GdkRectangle unused;
if (gdk_rectangle_intersect (&rectangle,