summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Drake <tlsa@netsurf-browser.org>2009-04-27 10:20:44 +0000
committerMichael Drake <tlsa@netsurf-browser.org>2009-04-27 10:20:44 +0000
commit044a9534008fd77a2cf8755943f3fe42fa177d54 (patch)
tree34375628059d79308fde785fd2a48a06a56a8b7f
parent9f7a794b1f7f8407973fd44fc18878dd39c1bd12 (diff)
downloadnetsurf-044a9534008fd77a2cf8755943f3fe42fa177d54.tar.gz
netsurf-044a9534008fd77a2cf8755943f3fe42fa177d54.tar.bz2
Make box_at_point() only return boxes if the point is physically contained within them, and not if the point is mearly in the descendant area. (Fixes sites like BBC F1 page where whole page became an iPlayer link.)
svn path=/trunk/netsurf/; revision=7335
-rw-r--r--render/box.c126
-rw-r--r--render/box.h5
2 files changed, 81 insertions, 50 deletions
diff --git a/render/box.c b/render/box.c
index 08272d166..1735eba56 100644
--- a/render/box.c
+++ b/render/box.c
@@ -34,7 +34,7 @@
#include "utils/log.h"
#include "utils/talloc.h"
-static bool box_contains_point(struct box *box, int x, int y);
+static bool box_contains_point(struct box *box, int x, int y, bool *physically);
#define box_is_float(box) (box->type == BOX_FLOAT_LEFT || \
box->type == BOX_FLOAT_RIGHT)
@@ -302,12 +302,13 @@ void box_bounds(struct box *box, struct rect *r)
* \endcode
*/
-struct box *box_at_point(struct box *box, int x, int y,
+struct box *box_at_point(struct box *box, const int x, const int y,
int *box_x, int *box_y,
struct content **content)
{
int bx = *box_x, by = *box_y;
struct box *child, *sibling;
+ bool physically;
assert(box);
@@ -324,10 +325,15 @@ struct box *box_at_point(struct box *box, int x, int y,
/* consider floats second, since they will often overlap other boxes */
for (child = box->float_children; child; child = child->next_float) {
- if (box_contains_point(child, x - bx, y - by)) {
+ if (box_contains_point(child, x - bx, y - by, &physically)) {
*box_x = bx + child->x - child->scroll_x;
*box_y = by + child->y - child->scroll_y;
- return child;
+
+ if (physically)
+ return child;
+ else
+ return box_at_point(child, x, y, box_x, box_y,
+ content);
}
}
@@ -336,20 +342,24 @@ non_float_children:
for (child = box->children; child; child = child->next) {
if (box_is_float(child))
continue;
- if (box_contains_point(child, x - bx, y - by)) {
+ if (box_contains_point(child, x - bx, y - by, &physically)) {
*box_x = bx + child->x - child->scroll_x;
*box_y = by + child->y - child->scroll_y;
- return child;
+
+ if (physically)
+ return child;
+ else
+ return box_at_point(child, x, y, box_x, box_y,
+ content);
}
}
/* marker boxes */
if (box->list_marker) {
- if (box_contains_point(box->list_marker, x - bx, y - by)) {
- *box_x = bx + box->list_marker->x -
- box->list_marker->scroll_x;
- *box_y = by + box->list_marker->y -
- box->list_marker->scroll_y;
+ if (box_contains_point(box->list_marker, x - bx, y - by,
+ &physically)) {
+ *box_x = bx + box->list_marker->x;
+ *box_y = by + box->list_marker->y;
return box->list_marker;
}
}
@@ -363,12 +373,19 @@ siblings:
for (sibling = box->next_float; sibling;
sibling = sibling->next_float) {
if (box_contains_point(sibling,
- x - bx, y - by)) {
+ x - bx, y - by, &physically)) {
*box_x = bx + sibling->x -
sibling->scroll_x;
*box_y = by + sibling->y -
sibling->scroll_y;
- return sibling;
+
+ if (physically)
+ return sibling;
+ else
+ return box_at_point(sibling,
+ x, y,
+ box_x, box_y,
+ content);
}
}
/* ascend to float's parent */
@@ -385,13 +402,20 @@ siblings:
sibling = sibling->next) {
if (box_is_float(sibling))
continue;
- if (box_contains_point(sibling,
- x - bx, y - by)) {
+ if (box_contains_point(sibling, x - bx, y - by,
+ &physically)) {
*box_x = bx + sibling->x -
sibling->scroll_x;
*box_y = by + sibling->y -
sibling->scroll_y;
- return sibling;
+
+ if (physically)
+ return sibling;
+ else
+ return box_at_point(sibling,
+ x, y,
+ box_x, box_y,
+ content);
}
}
box = box->parent;
@@ -405,47 +429,55 @@ siblings:
/**
* Determine if a point lies within a box.
*
- * \param box box to consider
- * \param x coordinate relative to box parent
- * \param y coordinate relative to box parent
+ * \param box box to consider
+ * \param x coordinate relative to box parent
+ * \param y coordinate relative to box parent
+ * \param physically if function returning true, physically is set true if
+ * point is within the box's physical dimensions and false
+ * if the point is not within the box's physical dimensions
+ * but is in the area defined by the box's descendants.
+ * if function returning false, physically is undefined.
* \return true if the point is within the box or a descendant box
*
* This is a helper function for box_at_point().
*/
-bool box_contains_point(struct box *box, int x, int y)
+bool box_contains_point(struct box *box, int x, int y, bool *physically)
{
- if ((box->style && box->style->overflow != CSS_OVERFLOW_VISIBLE) ||
- box->inline_end) {
- if (box->x <= x + box->border[LEFT] &&
- x < box->x + box->padding[LEFT] + box->width +
- box->border[RIGHT] + box->padding[RIGHT] &&
- box->y <= y + box->border[TOP] &&
- y < box->y + box->padding[TOP] + box->height +
- box->border[BOTTOM] + box->padding[BOTTOM])
- return true;
- if (box->list_marker && box->list_marker->x <= x +
- box->list_marker->border[LEFT] &&
- x < box->list_marker->x +
- box->list_marker->padding[LEFT] +
- box->list_marker->width +
- box->list_marker->border[RIGHT] +
- box->list_marker->padding[RIGHT] &&
- box->list_marker->y <= y +
- box->list_marker->border[TOP] &&
- y < box->list_marker->y +
- box->list_marker->padding[TOP] +
- box->list_marker->height +
- box->list_marker->border[BOTTOM] +
- box->list_marker->padding[BOTTOM]) {
- return true;
- }
- } else {
+ if (box->x <= x + box->border[LEFT] &&
+ x < box->x + box->padding[LEFT] + box->width +
+ box->border[RIGHT] + box->padding[RIGHT] &&
+ box->y <= y + box->border[TOP] &&
+ y < box->y + box->padding[TOP] + box->height +
+ box->border[BOTTOM] + box->padding[BOTTOM]) {
+ *physically = true;
+ return true;
+ }
+ if (box->list_marker && box->list_marker->x <= x +
+ box->list_marker->border[LEFT] &&
+ x < box->list_marker->x +
+ box->list_marker->padding[LEFT] +
+ box->list_marker->width +
+ box->list_marker->border[RIGHT] +
+ box->list_marker->padding[RIGHT] &&
+ box->list_marker->y <= y +
+ box->list_marker->border[TOP] &&
+ y < box->list_marker->y +
+ box->list_marker->padding[TOP] +
+ box->list_marker->height +
+ box->list_marker->border[BOTTOM] +
+ box->list_marker->padding[BOTTOM]) {
+ *physically = true;
+ return true;
+ }
+ if (box->style && box->style->overflow == CSS_OVERFLOW_VISIBLE) {
if (box->x + box->descendant_x0 <= x &&
x < box->x + box->descendant_x1 &&
box->y + box->descendant_y0 <= y &&
- y < box->y + box->descendant_y1)
+ y < box->y + box->descendant_y1) {
+ *physically = false;
return true;
+ }
}
return false;
}
diff --git a/render/box.h b/render/box.h
index 5d31a198b..9a90c21a4 100644
--- a/render/box.h
+++ b/render/box.h
@@ -293,9 +293,8 @@ void box_free_box(struct box *box);
void box_free_object_params(struct object_params *op);
void box_bounds(struct box *box, struct rect *r);
void box_coords(struct box *box, int *x, int *y);
-struct box *box_at_point(struct box *box, int x, int y,
- int *box_x, int *box_y,
- struct content **content);
+struct box *box_at_point(struct box *box, const int x, const int y,
+ int *box_x, int *box_y, struct content **content);
struct box *box_object_at_point(struct content *c, int x, int y);
struct box *box_href_at_point(struct content *c, int x, int y);
struct box *box_find_by_id(struct box *box, const char *id);