summaryrefslogtreecommitdiff
path: root/render
diff options
context:
space:
mode:
authorMichael Drake <tlsa@netsurf-browser.org>2008-09-21 19:18:27 +0000
committerMichael Drake <tlsa@netsurf-browser.org>2008-09-21 19:18:27 +0000
commit1850a494e7112731ecbf9f9e03e3bad3add600be (patch)
treed4f2787045c0da2edad847d4a1b436055f6d5927 /render
parentdd1afc041d1d30582db8971b6f0272421b7a23de (diff)
downloadnetsurf-1850a494e7112731ecbf9f9e03e3bad3add600be.tar.gz
netsurf-1850a494e7112731ecbf9f9e03e3bad3add600be.tar.bz2
Fix relative positioning to affect position of descendant floats which are in a block formatting context which is an ancestor of the relatively positioned box.
svn path=/trunk/netsurf/; revision=5390
Diffstat (limited to 'render')
-rw-r--r--render/layout.c66
1 files changed, 58 insertions, 8 deletions
diff --git a/render/layout.c b/render/layout.c
index 6e7ef29fc..cbabf5c7d 100644
--- a/render/layout.c
+++ b/render/layout.c
@@ -93,7 +93,8 @@ static void calculate_mbp_width(struct css_style *style, unsigned int side,
int *fixed, float *frac);
static void layout_lists(struct box *box,
const struct font_functions *font_func);
-static void layout_position_relative(struct box *root);
+static void layout_position_relative(struct box *root, struct box *fp,
+ int fx, int fy);
static void layout_compute_relative_offset(struct box *box, int *x, int *y);
static bool layout_position_absolute(struct box *box,
struct box *containing_block,
@@ -157,7 +158,7 @@ bool layout_document(struct content *content, int width, int height)
layout_lists(doc, font_func);
layout_position_absolute(doc, doc, 0, 0, content);
- layout_position_relative(doc);
+ layout_position_relative(doc, doc, 0, 0);
layout_calculate_descendant_bboxes(doc);
@@ -2852,11 +2853,28 @@ void layout_lists(struct box *box,
/**
* Adjust positions of relatively positioned boxes.
+ *
+ * \param root box to adjust the position of
+ * \param fp box which forms the block formatting context for children of
+ * "root" which are floats
+ * \param fx x offset due to intervening relatively positioned boxes
+ * between current box, "root", and the block formatting context
+ * box, "fp", for float children of "root"
+ * \param fy y offset due to intervening relatively positioned boxes
+ * between current box, "root", and the block formatting context
+ * box, "fp", for float children of "root"
*/
-void layout_position_relative(struct box *root)
+void layout_position_relative(struct box *root, struct box *fp, int fx, int fy)
{
- struct box *box;
+ struct box *box; /* for children of "root" */
+ struct box *fn; /* for block formatting context box for children of
+ * "box" */
+ struct box *fc; /* for float children of the block formatting context,
+ * "fp" */
+ int x, y; /* for the offsets resulting from any relative
+ * positioning on the current block */
+ int fnx, fny; /* for affsets which apply to flat children of "box" */
/**\todo ensure containing box is large enough after moving boxes */
@@ -2864,21 +2882,53 @@ void layout_position_relative(struct box *root)
/* Normal children */
for (box = root->children; box; box = box->next) {
- int x, y;
if (box->type == BOX_TEXT)
continue;
+ /* If relatively positioned, get offsets */
+ if (box->style && box->style->position == CSS_POSITION_RELATIVE)
+ layout_compute_relative_offset(box, &x, &y);
+ else
+ x = y = 0;
+
+ /* Adjust float coordinates.
+ * (note float x and y are relative to their block formatting
+ * context box and not their parent) */
+ if (box->style && (box->style->float_ == CSS_FLOAT_LEFT ||
+ box->style->float_ == CSS_FLOAT_RIGHT) &&
+ (fx != 0 || fy != 0)) {
+ /* box is a float and there is a float offset to
+ * apply */
+ for (fc = fp->float_children; fc; fc = fc->next_float) {
+ if (box == fc->children) {
+ /* Box is floated in the block
+ * formatting context block, fp.
+ * Apply float offsets. */
+ box->x += fx;
+ box->y += fy;
+ fx = fy = 0;
+ }
+ }
+ }
+
+ if (box->float_children) {
+ fn = box;
+ fnx = fny = 0;
+ } else {
+ fn = fp;
+ fnx = fx + x;
+ fny = fy + y;
+ }
+
/* recurse first */
- layout_position_relative(box);
+ layout_position_relative(box, fn, fnx, fny);
/* Ignore things we're not interested in. */
if (!box->style || (box->style &&
box->style->position != CSS_POSITION_RELATIVE))
continue;
- layout_compute_relative_offset(box, &x, &y);
-
box->x += x;
box->y += y;