summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xamiga/gui.c63
-rw-r--r--desktop/browser.c32
-rw-r--r--desktop/browser.h11
-rw-r--r--desktop/browser_private.h4
-rw-r--r--desktop/frames.c61
-rw-r--r--desktop/gui.h13
6 files changed, 178 insertions, 6 deletions
diff --git a/amiga/gui.c b/amiga/gui.c
index 293379283..185049d26 100755
--- a/amiga/gui.c
+++ b/amiga/gui.c
@@ -1036,6 +1036,36 @@ void ami_update_quals(struct gui_window_2 *gwin)
}
}
+bool ami_ns_to_screen_coords(struct gui_window_2 *gwin, int *x, int *y)
+{
+ ULONG xs, ys;
+ int ns_x = *x;
+ int ns_y = *y;
+ struct IBox *bbox;
+
+ GetAttr(SPACE_AreaBox, (Object *)gwin->objects[GID_BROWSER], (ULONG *)&bbox);
+
+ ns_x *= gwin->bw->scale;
+ ns_y *= gwin->bw->scale;
+
+ if((ns_x < 0) || (ns_x > bbox->Width) || (ns_y < 0) || (ns_y > bbox->Height))
+ return false;
+
+ ami_get_hscroll_pos(gwin, (ULONG *)&xs);
+ ami_get_vscroll_pos(gwin, (ULONG *)&ys);
+
+ ns_x += xs;
+ ns_y += ys;
+
+ ns_x += bbox->Left;
+ ns_y += bbox->Top;
+
+ *x = ns_x;
+ *y = ns_y;
+
+ return true;
+}
+
bool ami_mouse_to_ns_coords(struct gui_window_2 *gwin, int *x, int *y,
int mouse_x, int mouse_y)
{
@@ -3565,6 +3595,39 @@ void ami_do_redraw(struct gui_window_2 *g)
g->new_content = false;
}
+bool gui_window_copy_box(struct gui_window *g, const struct rect *rect, int x, int y)
+{
+ struct IBox *bbox;
+ struct gui_window_2 *gwin = g->shared;
+ int src_x = rect->x0;
+ int src_y = rect->y0;
+ int dest_x = x;
+ int dest_y = y;
+ int src_x1 = rect->x1;
+ int src_y1 = rect->y1;
+printf("%ld,%ld,%ld,%ld,%ld,%ld\n", src_x, src_y, src_x1, src_y1, dest_x, dest_y);
+ if(ami_ns_to_screen_coords(gwin, &src_x, &src_y) == false) return false;
+ if(ami_ns_to_screen_coords(gwin, &src_x1, &src_y1) == false) return false;
+ if(ami_ns_to_screen_coords(gwin, &dest_x, &dest_y) == false) return false;
+printf("== %ld,%ld,%ld,%ld,%ld,%ld\n", src_x, src_y, src_x1, src_y1, dest_x, dest_y);
+
+ if(nsoption_bool(faster_scroll) == false) return false; /* for testing */
+
+ BltBitMapTags(BLITA_SrcType, BLITT_RASTPORT,
+ BLITA_Source, gwin->win->RPort,
+ BLITA_SrcX, src_x,
+ BLITA_SrcY, src_y,
+ BLITA_DestType, BLITT_RASTPORT,
+ BLITA_Dest, gwin->win->RPort,
+ BLITA_DestX, dest_x,
+ BLITA_DestY, dest_y,
+ BLITA_Width, src_x1 - src_x,
+ BLITA_Height, src_y1 - src_y,
+ TAG_DONE);
+
+ return true;
+}
+
void ami_refresh_window(struct gui_window_2 *gwin)
{
/* simplerefresh only */
diff --git a/desktop/browser.c b/desktop/browser.c
index 89484609e..0ecb0ac77 100644
--- a/desktop/browser.c
+++ b/desktop/browser.c
@@ -1947,6 +1947,38 @@ void browser_window_update_box(struct browser_window *bw, struct rect *rect)
}
+/* exported interface, documented in browser.h */
+void browser_window_copy_box(struct browser_window *bw, struct rect *rect, int x, int y)
+{
+ int pos_x;
+ int pos_y;
+ struct browser_window *top;
+
+ assert(bw);
+
+ if (bw->window != NULL) {
+ /* Front end window */
+ if(gui_window_copy_box(bw->window, rect, x, y) == false) {
+ gui_window_update_box(bw->window, rect);
+ }
+ } else {
+ /* Core managed browser window */
+ browser_window_get_position(bw, true, &pos_x, &pos_y);
+
+ top = browser_window_get_root(bw);
+
+ rect->x0 += pos_x / bw->scale;
+ rect->y0 += pos_y / bw->scale;
+ rect->x1 += pos_x / bw->scale;
+ rect->y1 += pos_y / bw->scale;
+
+ if(gui_window_copy_box(top->window, rect, x + pos_x, y + pos_y) == false) {
+ gui_window_update_box(top->window, rect);
+ }
+ }
+}
+
+
/**
* Stop all fetching activity in a browser window.
*
diff --git a/desktop/browser.h b/desktop/browser.h
index f3c68fa09..b0965e1c3 100644
--- a/desktop/browser.h
+++ b/desktop/browser.h
@@ -95,6 +95,17 @@ void browser_window_set_scale(struct browser_window *bw, float scale, bool all);
float browser_window_get_scale(struct browser_window *bw);
/**
+ * Copy an area of the browser window to the given x,y co-ordinates.
+ * Source and destination may overlap.
+ *
+ * \param bw browser window
+ * \param rect area to copy
+ * \param x x-coordinate of destination to copy to
+ * \param y y-coordinate of destination to copy to
+ */
+void browser_window_copy_box(struct browser_window *bw, struct rect *rect, int x, int y);
+
+/**
* Get access to any content, link URLs and objects (images) currently
* at the given (x, y) coordinates.
*
diff --git a/desktop/browser_private.h b/desktop/browser_private.h
index 91372acc3..d008d887a 100644
--- a/desktop/browser_private.h
+++ b/desktop/browser_private.h
@@ -110,6 +110,10 @@ struct browser_window {
struct scrollbar *scroll_x; /**< Horizontal scroll. */
struct scrollbar *scroll_y; /**< Vertical scroll. */
+
+ /** previous scroll offsets */
+ int prev_scroll_x;
+ int prev_scroll_y;
/** scale of window contents */
float scale;
diff --git a/desktop/frames.c b/desktop/frames.c
index cc2cabfd2..6dd0d09b4 100644
--- a/desktop/frames.c
+++ b/desktop/frames.c
@@ -63,14 +63,63 @@ void browser_window_scroll_callback(void *client_data,
if (bw->browser_window_type == BROWSER_WINDOW_IFRAME) {
html_redraw_a_box(bw->parent->current_content, bw->box);
} else {
- struct rect rect;
+ struct rect rect_x;
+ struct rect rect_y;
+ struct rect copyrect;
+ int dest_x = 0;
+ int dest_y = 0;
+ int cur_x = scrollbar_get_offset(bw->scroll_x);
+ int cur_y = scrollbar_get_offset(bw->scroll_y);
+
+ rect_y.x0 = 0;
+ rect_y.x1 = bw->width;
+ rect_x.y0 = 0;
+ rect_x.y1 = bw->height;
+
+ if(cur_y > bw->prev_scroll_y) {
+ copyrect.y0 = cur_y - bw->prev_scroll_y;
+ copyrect.y1 = bw->height;
+ dest_y = 0;
+
+ rect_y.y0 = bw->height - copyrect.y0;
+ rect_y.y1 = bw->height;
+
+ rect_x.y0 = 0;
+ rect_x.y1 = rect_y.y0;
+ } else {
+ copyrect.y0 = 0;
+ copyrect.y1 = bw->height - (cur_y - bw->prev_scroll_y);
+ dest_y = cur_y - bw->prev_scroll_y;
+
+ rect_y.y0 = 0;
+ rect_y.y1 = cur_y - bw->prev_scroll_y;
+
+ rect_x.y0 = rect_y.y1;
+ rect_x.y1 = bw->height;
+ }
- rect.x0 = scrollbar_get_offset(bw->scroll_x);
- rect.y0 = scrollbar_get_offset(bw->scroll_y);
- rect.x1 = rect.x0 + bw->width;
- rect.y1 = rect.y0 + bw->height;
+ if(cur_x > bw->prev_scroll_x) {
+ copyrect.x0 = cur_x - bw->prev_scroll_x;
+ copyrect.x1 = bw->width;
+ dest_x = 0;
+
+ rect_x.x0 = bw->height - copyrect.x0;
+ rect_x.x1 = bw->height;
+ } else {
+ copyrect.x0 = 0;
+ copyrect.x1 = bw->width - (cur_x - bw->prev_scroll_x);
+ dest_x = cur_x - bw->prev_scroll_x;
- browser_window_update_box(bw, &rect);
+ rect_x.x0 = 0;
+ rect_x.x1 = cur_x - bw->prev_scroll_x;
+ }
+
+ browser_window_copy_box(bw, &copyrect, dest_x, dest_y);
+ browser_window_update_box(bw, &rect_y);
+ browser_window_update_box(bw, &rect_x);
+
+ bw->prev_scroll_x = scrollbar_get_offset(bw->scroll_x);
+ bw->prev_scroll_y = scrollbar_get_offset(bw->scroll_y);
}
break;
case SCROLLBAR_MSG_SCROLL_START:
diff --git a/desktop/gui.h b/desktop/gui.h
index 48684c3c5..551848586 100644
--- a/desktop/gui.h
+++ b/desktop/gui.h
@@ -79,6 +79,19 @@ void gui_window_set_title(struct gui_window *g, const char *title);
void gui_window_redraw_window(struct gui_window *g);
void gui_window_update_box(struct gui_window *g,
const struct rect *rect);
+
+/**
+ * Copy an area of the displayed gui_window to the co-ordinates
+ * specified by x,y. NB: source and destination may overlap.
+ *
+ * \param g The window to perform the copy on.
+ * \param rect The rectangle to copy.
+ * \param x The X co-ordinate to copy to.
+ * \param y The Y co-ordinate to copy to.
+ * \return true if the region could be copied, false otherwise.
+ */
+bool gui_window_copy_box(struct gui_window *g, const struct rect *rect, int x, int y);
+
bool gui_window_get_scroll(struct gui_window *g, int *sx, int *sy);
void gui_window_set_scroll(struct gui_window *g, int sx, int sy);
void gui_window_scroll_visible(struct gui_window *g, int x0, int y0,