summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--render/box.c138
-rw-r--r--render/html.c35
-rw-r--r--render/html.h8
-rw-r--r--render/layout.c13
-rw-r--r--render/layout.h2
5 files changed, 112 insertions, 84 deletions
diff --git a/render/box.c b/render/box.c
index c62fbb947..d9fcb6233 100644
--- a/render/box.c
+++ b/render/box.c
@@ -45,7 +45,7 @@ struct box_status {
struct content *content;
char *href;
char *title;
- struct form* current_form;
+ struct form *current_form;
char *id;
};
@@ -169,6 +169,7 @@ static bool plugin_decode(struct content* content, char* url, struct box* box,
struct object_params* po);
static struct box_multi_length *box_parse_multi_lengths(const char *s,
unsigned int *count);
+static bool box_contains_point(struct box *box, int x, int y);
#define box_is_float(box) (box->type == BOX_FLOAT_LEFT || \
box->type == BOX_FLOAT_RIGHT)
@@ -295,27 +296,35 @@ void box_insert_sibling(struct box *box, struct box *new_box)
void xml_to_box(xmlNode *n, struct content *c)
{
+ struct box root;
struct box_status status = {c, 0, 0, 0, 0};
- LOG(("node %p", n));
assert(c->type == CONTENT_HTML);
- c->data.html.layout = box_create(0, 0, 0, 0, c->data.html.box_pool);
- c->data.html.layout->type = BOX_BLOCK;
+ root.type = BOX_BLOCK;
+ root.style = NULL;
+ root.next = NULL;
+ root.prev = NULL;
+ root.children = NULL;
+ root.last = NULL;
+ root.parent = NULL;
+ root.float_children = NULL;
+ root.next_float = NULL;
c->data.html.style = xcalloc(1, sizeof(struct css_style));
memcpy(c->data.html.style, &css_base_style, sizeof(struct css_style));
- c->data.html.style->font_size.value.length.value = option_font_size * 0.1;
+ c->data.html.style->font_size.value.length.value =
+ option_font_size * 0.1;
c->data.html.fonts = nsfont_new_set();
c->data.html.object_count = 0;
c->data.html.object = xcalloc(0, sizeof(*c->data.html.object));
- convert_xml_to_box(n, c, c->data.html.style,
- c->data.html.layout, 0, status);
- LOG(("normalising"));
- box_normalise_block(c->data.html.layout->children,
- c->data.html.box_pool);
+ convert_xml_to_box(n, c, c->data.html.style, &root, 0, status);
+ box_normalise_block(&root, c->data.html.box_pool);
+
+ c->data.html.layout = root.children;
+ c->data.html.layout->parent = NULL;
}
@@ -1554,7 +1563,7 @@ void box_dump(struct box * box, unsigned int depth)
for (i = 0; i < depth; i++)
fprintf(stderr, " ");
-/* fprintf(stderr, "%p ", box); */
+ fprintf(stderr, "%p ", box);
fprintf(stderr, "x%i y%i w%i h%i ", box->x, box->y, box->width, box->height);
if ((unsigned long)box->max_width != UNKNOWN_MAX_WIDTH)
fprintf(stderr, "min%i max%i ", box->min_width, box->max_width);
@@ -1593,6 +1602,10 @@ void box_dump(struct box * box, unsigned int depth)
fprintf(stderr, " [%s]", box->title);
if (box->id != 0)
fprintf(stderr, " <%s>", box->id);
+ if (box->float_children)
+ fprintf(stderr, " float_children %p", box->float_children);
+ if (box->next_float)
+ fprintf(stderr, " next_float %p", box->next_float);
fprintf(stderr, "\n");
for (c = box->children; c != 0; c = c->next)
@@ -1740,7 +1753,7 @@ void box_normalise_table_spans( struct box *table )
assert( 0 != table_cell->rows );
last_column = table_cell->start_column + 1;
}
- }
+ }
rows_left--;
}
}
@@ -1970,7 +1983,7 @@ static unsigned int calculate_table_row( struct columns *col_info,
col_info->spans = xrealloc( col_info->spans,
sizeof( *col_info->spans ) * ( cell_end_col + 1 ));
col_info->num_columns = cell_end_col;
-
+
/* Mark new final column as sentinal */
col_info->spans[ cell_end_col ].row_span = 0;
col_info->spans[ cell_end_col ].auto_row =
@@ -2078,7 +2091,7 @@ static void box_normalise_table_row(struct box *row,
if (( col_info->spans[i].auto_column ) && ( 0 == col_info->spans[i].row_span )) {
col_info->spans[i].auto_column = false;
}
- }
+ }
}
col_info->current_column = 0;
col_info->extra = false;
@@ -2922,8 +2935,8 @@ void box_coords(struct box *box, int *x, int *y)
} while (!box->float_children);
} else
box = box->parent;
- *x += box->x;
- *y += box->y;
+ *x += box->x - box->scroll_x;
+ *y += box->y - box->scroll_y;
}
}
@@ -2932,7 +2945,7 @@ void box_coords(struct box *box, int *x, int *y)
* Find the boxes at a point.
*
* \param box box to search children of
- * \param x point to find, in global document coordinates
+ * \param x point to find, in global document coordinates
* \param y point to find, in global document coordinates
* \param box_x position of box, in global document coordinates, updated
* to position of returned box, if any
@@ -2976,12 +2989,9 @@ struct box *box_at_point(struct box *box, int x, int y,
/* consider floats first, since they will often overlap other boxes */
for (child = box->float_children; child; child = child->next_float) {
- if (bx + child->x + child->descendant_x0 <= x &&
- x < bx + child->x + child->descendant_x1 &&
- by + child->y + child->descendant_y0 <= y &&
- y < by + child->y + child->descendant_y1) {
- *box_x += child->x;
- *box_y += child->y;
+ if (box_contains_point(child, x - bx, y - by)) {
+ *box_x += child->x - child->scroll_x;
+ *box_y += child->y - child->scroll_y;
return child;
}
}
@@ -2990,12 +3000,9 @@ struct box *box_at_point(struct box *box, int x, int y,
for (child = box->children; child; child = child->next) {
if (box_is_float(child))
continue;
- if (bx + child->x + child->descendant_x0 <= x &&
- x < bx + child->x + child->descendant_x1 &&
- by + child->y + child->descendant_y0 <= y &&
- y < by + child->y + child->descendant_y1) {
- *box_x += child->x;
- *box_y += child->y;
+ if (box_contains_point(child, x - bx, y - by)) {
+ *box_x += child->x - child->scroll_x;
+ *box_y += child->y - child->scroll_y;
return child;
}
}
@@ -3004,41 +3011,33 @@ siblings:
/* siblings and siblings of ancestors */
while (box) {
if (!box_is_float(box)) {
- bx -= box->x;
- by -= box->y;
+ bx -= box->x - box->scroll_x;
+ by -= box->y - box->scroll_y;
for (sibling = box->next; sibling;
sibling = sibling->next) {
if (box_is_float(sibling))
continue;
- if (bx + sibling->x +
- sibling->descendant_x0 <= x &&
- x < bx + sibling->x +
- sibling->descendant_x1 &&
- by + sibling->y +
- sibling->descendant_y0 <= y &&
- y < by + sibling->y +
- sibling->descendant_y1) {
- *box_x = bx + sibling->x;
- *box_y = by + sibling->y;
+ if (box_contains_point(sibling,
+ x - bx, y - by)) {
+ *box_x = bx + sibling->x -
+ sibling->scroll_x;
+ *box_y = by + sibling->y -
+ sibling->scroll_y;
return sibling;
}
}
box = box->parent;
} else {
- bx -= box->x;
- by -= box->y;
+ bx -= box->x - box->scroll_x;
+ by -= box->y - box->scroll_y;
for (sibling = box->next_float; sibling;
sibling = sibling->next_float) {
- if (bx + sibling->x +
- sibling->descendant_x0 <= x &&
- x < bx + sibling->x +
- sibling->descendant_x1 &&
- by + sibling->y +
- sibling->descendant_y0 <= y &&
- y < by + sibling->y +
- sibling->descendant_y1) {
- *box_x = bx + sibling->x;
- *box_y = by + sibling->y;
+ if (box_contains_point(sibling,
+ x - bx, y - by)) {
+ *box_x = bx + sibling->x -
+ sibling->scroll_x;
+ *box_y = by + sibling->y -
+ sibling->scroll_y;
return sibling;
}
}
@@ -3053,6 +3052,39 @@ 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
+ * \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)
+{
+ if (box->style && (box->style->overflow == CSS_OVERFLOW_HIDDEN ||
+ box->style->overflow == CSS_OVERFLOW_SCROLL)) {
+ if (box->x <= x &&
+ x < box->x + box->padding[LEFT] + box->width +
+ box->padding[RIGHT] &&
+ box->y <= y &&
+ y < box->y + box->padding[TOP] + box->height +
+ box->padding[BOTTOM])
+ return true;
+ } else {
+ 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)
+ return true;
+ }
+ return false;
+}
+
+
+/**
* Find the box containing an object at the given coordinates, if any.
*
* \param c content to search, must have type CONTENT_HTML
diff --git a/render/html.c b/render/html.c
index d3e359f85..abbbb92b9 100644
--- a/render/html.c
+++ b/render/html.c
@@ -185,7 +185,6 @@ bool html_convert(struct content *c, int width, int height)
xmlDoc *document;
xmlNode *html, *head;
union content_msg_data msg_data;
- int descendant_width;
/* finish parsing */
htmlParseChunk(c->data.html.parser, "", 0, 1);
@@ -252,21 +251,11 @@ bool html_convert(struct content *c, int width, int height)
content_set_status(c, messages_get("Formatting"));
content_broadcast(c, CONTENT_MSG_STATUS, msg_data);
LOG(("Layout document"));
- layout_document(c->data.html.layout->children, width,
+ layout_document(c->data.html.layout, width,
c->data.html.box_pool);
/*box_dump(c->data.html.layout->children, 0);*/
-
- descendant_width = c->data.html.layout->children->descendant_x1 -
- c->data.html.layout->children->descendant_x0;
-
- LOG(("Available width: %d, Returned Width: %d, Required width: %d", width, c->data.html.layout->children->width, descendant_width));
-
- if (descendant_width > c->data.html.layout->children->width)
- c->width = descendant_width;
- else
- c->width = c->data.html.layout->children->width;
-
- c->height = c->data.html.layout->children->height;
+ c->width = c->data.html.layout->descendant_x1;
+ c->height = c->data.html.layout->descendant_y1;
if (c->active == 0) {
c->status = CONTENT_STATUS_DONE;
@@ -881,22 +870,10 @@ void html_stop(struct content *c)
void html_reformat(struct content *c, int width, int height)
{
- int descendant_width;
-
- layout_document(c->data.html.layout->children, width,
+ layout_document(c->data.html.layout, width,
c->data.html.box_pool);
-
- descendant_width = c->data.html.layout->children->descendant_x1 -
- c->data.html.layout->children->descendant_x0;
-
- LOG(("Available width: %d, Returned Width: %d, Required width: %d", width, c->data.html.layout->children->width, descendant_width));
-
- if (descendant_width > c->data.html.layout->children->width)
- c->width = descendant_width;
- else
- c->width = c->data.html.layout->children->width;
-
- c->height = c->data.html.layout->children->height;
+ c->width = c->data.html.layout->descendant_x1;
+ c->height = c->data.html.layout->descendant_y1;
}
diff --git a/render/html.h b/render/html.h
index 74b19434c..ec27dc531 100644
--- a/render/html.h
+++ b/render/html.h
@@ -23,8 +23,9 @@
struct box;
struct browser_window;
struct content;
-struct object_params;
struct imagemap;
+struct object_params;
+struct plotters;
/* entries in stylesheet_content */
#define STYLESHEET_BASE 0 /* base style sheet */
@@ -75,6 +76,9 @@ struct content_html_data {
struct browser_window *bw;
};
+/** Render padding and margin box outlines in html_redraw(). */
+extern bool html_redraw_debug;
+
bool html_create(struct content *c, const char *params[]);
bool html_process_data(struct content *c, char *data, unsigned int size);
@@ -91,7 +95,7 @@ void html_open(struct content *c, struct browser_window *bw,
struct object_params *params);
void html_close(struct content *c);
-/* in riscos/htmlredraw.c */
+/* in render/html_redraw.c */
bool html_redraw(struct content *c, int x, int y,
int width, int height,
int clip_x0, int clip_y0, int clip_x1, int clip_y1,
diff --git a/render/layout.c b/render/layout.c
index f7717f0df..a59c23da0 100644
--- a/render/layout.c
+++ b/render/layout.c
@@ -356,6 +356,12 @@ void layout_block_find_dimensions(int available_width, struct box *box)
box->width = layout_solve_width(available_width, width, margin,
padding, border);
+ if (style->overflow == CSS_OVERFLOW_SCROLL) {
+ /* make space for vertical scrollbar */
+ box->width -= SCROLLBAR_WIDTH;
+ box->padding[RIGHT] += SCROLLBAR_WIDTH;
+ }
+
if (box->object && box->object->type == CONTENT_HTML &&
box->width != box->object->available_width) {
content_reformat(box->object, box->width, box->height);
@@ -418,6 +424,9 @@ int layout_solve_width(int available_width, int width,
void layout_float_find_dimensions(int available_width,
struct css_style *style, struct box *box)
{
+ int scrollbar_width = style->overflow == CSS_OVERFLOW_SCROLL ?
+ SCROLLBAR_WIDTH : 0;
+
layout_find_dimensions(available_width, style,
box->margin, box->padding, box->border);
@@ -452,6 +461,8 @@ void layout_float_find_dimensions(int available_width,
break;
}
+ box->padding[RIGHT] += scrollbar_width;
+
if (box->object) {
/* floating replaced element, see 10.3.6 and 10.6.2 */
if (box->width == AUTO && box->height == AUTO) {
@@ -474,6 +485,8 @@ void layout_float_find_dimensions(int available_width,
box->width = box->min_width;
if (box->max_width < box->width)
box->width = box->max_width;
+ } else {
+ box->width -= scrollbar_width;
}
if (box->margin[TOP] == AUTO)
diff --git a/render/layout.h b/render/layout.h
index 20a993c14..a46a6e399 100644
--- a/render/layout.h
+++ b/render/layout.h
@@ -18,6 +18,8 @@
#include "netsurf/utils/pool.h"
+#define SCROLLBAR_WIDTH 16
+
bool layout_document(struct box *box, int width, pool box_pool);
bool layout_block_context(struct box *block, pool box_pool);
bool layout_inline_container(struct box *box, int width,