summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Drake <tlsa@netsurf-browser.org>2011-04-27 13:50:49 +0000
committerMichael Drake <tlsa@netsurf-browser.org>2011-04-27 13:50:49 +0000
commit1304964f92249a1f8e685db89aa694f77307d6ae (patch)
tree706003fb75d65aa2fe2e6f6e2a08f6c0091ca1e0
parentd0e7a5ecacc8692b533c8102bfa6b2267f309ab9 (diff)
downloadnetsurf-1304964f92249a1f8e685db89aa694f77307d6ae.tar.gz
netsurf-1304964f92249a1f8e685db89aa694f77307d6ae.tar.bz2
Reduce number of page reflows and viewport
redraws as images are fetched: + Flag known-sized boxes generated by images. + Treat them as replaced all through layout. + Only reflow the document for fetched images if we don't already have the box at the right size. svn path=/trunk/netsurf/; revision=12243
-rw-r--r--render/box.h3
-rw-r--r--render/box_construct.c16
-rw-r--r--render/html.c47
-rw-r--r--render/html_redraw.c6
-rw-r--r--render/layout.c41
5 files changed, 85 insertions, 28 deletions
diff --git a/render/box.h b/render/box.h
index 0703c6da5..e7c19ad6d 100644
--- a/render/box.h
+++ b/render/box.h
@@ -126,7 +126,8 @@ typedef enum {
MEASURED = 1 << 5, /* text box width has been measured */
HAS_HEIGHT = 1 << 6, /* box has height (perhaps due to children) */
MAKE_HEIGHT = 1 << 7, /* box causes its own height */
- NEED_MIN = 1 << 8 /* minimum width is required for layout */
+ NEED_MIN = 1 << 8, /* minimum width is required for layout */
+ REPLACE_DIM = 1 << 9 /* replaced element has given dimensions */
} box_flags;
/* Sides of a box */
diff --git a/render/box_construct.c b/render/box_construct.c
index b47405c12..f780d0714 100644
--- a/render/box_construct.c
+++ b/render/box_construct.c
@@ -1159,6 +1159,11 @@ bool box_image(BOX_SPECIAL_PARAMS)
bool ok;
char *s, *url;
xmlChar *alt, *src;
+ enum css_width_e wtype;
+ enum css_height_e htype;
+ css_fixed value = 0;
+ css_unit wunit = CSS_UNIT_PX;
+ css_unit hunit = CSS_UNIT_PX;
if (box->style && css_computed_display(box->style,
n->parent == NULL) == CSS_DISPLAY_NONE)
@@ -1196,6 +1201,17 @@ bool box_image(BOX_SPECIAL_PARAMS)
ok = html_fetch_object(content, url, box, image_types,
content->available_width, 1000, false);
free(url);
+
+ wtype = css_computed_width(box->style, &value, &wunit);
+ htype = css_computed_height(box->style, &value, &hunit);
+
+ if (wtype == CSS_WIDTH_SET && wunit != CSS_UNIT_PCT &&
+ htype == CSS_HEIGHT_SET && hunit != CSS_UNIT_PCT) {
+ /* We know the dimensions the image will be shown at before it's
+ * fetched. */
+ box->flags |= REPLACE_DIM;
+ }
+
return ok;
}
diff --git a/render/html.c b/render/html.c
index cde8d79ef..cf9fdea81 100644
--- a/render/html.c
+++ b/render/html.c
@@ -1415,8 +1415,29 @@ nserror html_object_callback(hlcache_handle *object,
break;
case CONTENT_MSG_DONE:
- html_object_done(box, object, o->background);
- c->active--;
+
+ if (box->flags & REPLACE_DIM) {
+ union content_msg_data data;
+
+ c->active--;
+ html_object_done(box, object, o->background);
+
+ if (!box_visible(box))
+ break;
+
+ box_coords(box, &x, &y);
+
+ data.redraw.x = x + box->padding[LEFT];
+ data.redraw.y = y + box->padding[TOP];
+ data.redraw.width = box->width;
+ data.redraw.height = box->height;
+ data.redraw.full_redraw = true;
+
+ content_broadcast(c, CONTENT_MSG_REDRAW, data);
+ } else {
+ c->active--;
+ html_object_done(box, object, o->background);
+ }
break;
case CONTENT_MSG_ERROR:
@@ -1500,12 +1521,14 @@ nserror html_object_callback(hlcache_handle *object,
/* If 1) the configuration option to reflow pages while objects are
* fetched is set
* 2) an object is newly fetched & converted,
- * 3) the object's parent HTML is ready for reformat,
- * 4) the time since the previous reformat is more than the
+ * 3) the box's dimensions need to change due to being replaced
+ * 4) the object's parent HTML is ready for reformat,
+ * 5) the time since the previous reformat is more than the
* configured minimum time between reformats
* then reformat the page to display newly fetched objects */
else if (option_incremental_reflow &&
event->type == CONTENT_MSG_DONE &&
+ !(box->flags & REPLACE_DIM) &&
(c->status == CONTENT_STATUS_READY ||
c->status == CONTENT_STATUS_DONE) &&
(wallclock() > c->reformat_time)) {
@@ -1532,14 +1555,16 @@ void html_object_done(struct box *box, hlcache_handle *object,
box->object = object;
- /* invalidate parent min, max widths */
- for (b = box; b; b = b->parent)
- b->max_width = UNKNOWN_MAX_WIDTH;
+ if (!(box->flags & REPLACE_DIM)) {
+ /* invalidate parent min, max widths */
+ for (b = box; b; b = b->parent)
+ b->max_width = UNKNOWN_MAX_WIDTH;
- /* delete any clones of this box */
- while (box->next && (box->next->flags & CLONE)) {
- /* box_free_box(box->next); */
- box->next = box->next->next;
+ /* delete any clones of this box */
+ while (box->next && (box->next->flags & CLONE)) {
+ /* box_free_box(box->next); */
+ box->next = box->next->next;
+ }
}
}
diff --git a/render/html_redraw.c b/render/html_redraw.c
index 9ae43bce1..c5d20b26f 100644
--- a/render/html_redraw.c
+++ b/render/html_redraw.c
@@ -427,7 +427,8 @@ bool html_redraw_box(struct box *box, int x_parent, int y_parent,
if (bg_box && bg_box->type != BOX_BR &&
bg_box->type != BOX_TEXT &&
bg_box->type != BOX_INLINE_END &&
- (bg_box->type != BOX_INLINE || bg_box->object)) {
+ (bg_box->type != BOX_INLINE || bg_box->object ||
+ box->flags & REPLACE_DIM)) {
/* find intersection of clip box and border edge */
struct rect p;
p.x0 = x - border_left < r.x0 ? r.x0 : x - border_left;
@@ -471,7 +472,8 @@ bool html_redraw_box(struct box *box, int x_parent, int y_parent,
/* borders for block level content and replaced inlines */
if (box->style && box->type != BOX_TEXT &&
box->type != BOX_INLINE_END &&
- (box->type != BOX_INLINE || box->object) &&
+ (box->type != BOX_INLINE || box->object ||
+ box->flags & REPLACE_DIM) &&
(border_top || border_right ||
border_bottom || border_left)) {
if (!html_redraw_borders(box, x_parent, y_parent,
diff --git a/render/layout.c b/render/layout.c
index 2c97ead0a..ca3f84853 100644
--- a/render/layout.c
+++ b/render/layout.c
@@ -270,6 +270,8 @@ bool layout_block_context(struct box *block, int viewport_height,
layout_get_object_dimensions(block, &block->width,
&block->height, false, true);
return true;
+ } else if (block->flags & REPLACE_DIM) {
+ return true;
}
/* special case if the block contains an radio button or checkbox */
@@ -359,8 +361,9 @@ bool layout_block_context(struct box *block, int viewport_height,
* left and right margins to avoid any floats. */
lm = rm = 0;
- if (box->type == BOX_BLOCK || box->object) {
- if (!box->object && box->style &&
+ if (box->type == BOX_BLOCK || box->object) {
+ if (!box->object && !(box->flags & REPLACE_DIM) &&
+ box->style &&
css_computed_overflow(box->style) !=
CSS_OVERFLOW_VISIBLE) {
/* box establishes new block formatting context
@@ -1115,7 +1118,8 @@ void layout_block_find_dimensions(int available_width, int viewport_height,
&width, &height, &max_width, &min_width,
margin, padding, border);
- if (box->object && content_get_type(box->object) != CONTENT_HTML) {
+ if (box->object && !(box->flags & REPLACE_DIM) &&
+ content_get_type(box->object) != CONTENT_HTML) {
/* block-level replaced element, see 10.3.4 and 10.6.2 */
layout_get_object_dimensions(box, &width, &height,
true, true);
@@ -1432,7 +1436,8 @@ void layout_float_find_dimensions(int available_width,
padding[RIGHT] += scrollbar_width;
padding[BOTTOM] += scrollbar_width;
- if (box->object && content_get_type(box->object) != CONTENT_HTML) {
+ if (box->object && !(box->flags & REPLACE_DIM) &&
+ content_get_type(box->object) != CONTENT_HTML) {
/* Floating replaced element, with intrinsic width or height.
* See 10.3.6 and 10.6.2 */
layout_get_object_dimensions(box, &width, &height,
@@ -2011,7 +2016,8 @@ bool layout_inline_container(struct box *inline_container, int width,
whitespace == CSS_WHITE_SPACE_PRE_WRAP);
}
- if ((!c->object && c->text && (c->length || is_pre)) ||
+ if ((!c->object && !(c->flags & REPLACE_DIM) && c->text &&
+ (c->length || is_pre)) ||
c->type == BOX_BR)
has_text_children = true;
}
@@ -2363,7 +2369,8 @@ bool layout_line(struct box *first, int *width, int *y,
continue;
}
- if (!b->object && !b->gadget) {
+ if (!b->object && !b->gadget &&
+ !(b->flags & REPLACE_DIM)) {
/* inline non-replaced, 10.3.1 and 10.6.1 */
b->height = line_height(b->style ? b->style :
b->parent->parent->style);
@@ -2458,7 +2465,7 @@ bool layout_line(struct box *first, int *width, int *y,
b->height = AUTO;
}
- if (b->object) {
+ if (b->object && !(b->flags & REPLACE_DIM)) {
layout_get_object_dimensions(b, &b->width, &b->height,
true, true);
} else {
@@ -2551,7 +2558,7 @@ bool layout_line(struct box *first, int *width, int *y,
}
space_before = space_after;
- if (b->object)
+ if (b->object || b->flags & REPLACE_DIM)
space_after = 0;
else if (b->text || b->type == BOX_INLINE_END) {
if (b->space == UNKNOWN_WIDTH) {
@@ -2705,6 +2712,7 @@ bool layout_line(struct box *first, int *width, int *y,
if ((split_box->type == BOX_INLINE ||
split_box->type == BOX_TEXT) &&
!split_box->object &&
+ !(split_box->flags & REPLACE_DIM) &&
!split_box->gadget && split_box->text) {
/* skip leading spaces, otherwise code gets fooled into
* thinking it's all one long word */
@@ -2858,7 +2866,8 @@ bool layout_line(struct box *first, int *width, int *y,
d->y = *y;
continue;
} else if ((d->type == BOX_INLINE &&
- ((d->object || d->gadget) == false)) ||
+ ((d->object || d->gadget) == false) &&
+ !(d->flags & REPLACE_DIM)) ||
d->type == BOX_BR ||
d->type == BOX_TEXT ||
d->type == BOX_INLINE_END) {
@@ -3012,7 +3021,8 @@ struct box *layout_minmax_line(struct box *first,
assert(b->style);
font_plot_style_from_css(b->style, &fstyle);
- if (b->type == BOX_INLINE && !b->object) {
+ if (b->type == BOX_INLINE && !b->object &&
+ !(b->flags & REPLACE_DIM)) {
fixed = frac = 0;
calculate_mbp_width(b->style, LEFT, true, true, true,
&fixed, &frac);
@@ -3040,7 +3050,8 @@ struct box *layout_minmax_line(struct box *first,
continue;
}
- if (!b->object && !b->gadget) {
+ if (!b->object && !b->gadget &&
+ !(b->flags & REPLACE_DIM)) {
/* inline non-replaced, 10.3.1 and 10.6.1 */
if (!b->text)
continue;
@@ -3140,9 +3151,11 @@ struct box *layout_minmax_line(struct box *first,
height = AUTO;
}
- if (b->object) {
- layout_get_object_dimensions(b, &width, &height,
- true, false);
+ if (b->object || (b->flags & REPLACE_DIM)) {
+ if (b->object) {
+ layout_get_object_dimensions(b, &width, &height,
+ true, false);
+ }
fixed = frac = 0;
calculate_mbp_width(b->style, LEFT, true, true, true,