Gitweb links:
...log
http://git.netsurf-browser.org/netsurf.git/shortlog/3763ff16e046d60f7c2f1c4ec8e79f19a9ab495e
...commit
http://git.netsurf-browser.org/netsurf.git/commit/3763ff16e046d60f7c2f1c4ec8e79f19a9ab495e
...tree
http://git.netsurf-browser.org/netsurf.git/tree/3763ff16e046d60f7c2f1c4ec8e79f19a9ab495e
The branch, tlsa/flex has been updated
discards d9cefab1e100ca77342a168c5c603baccfbc70f2 (commit)
discards a49d334a53b22640ce4980db9487fd5c36629afb (commit)
discards 9975b2f262bc550e7b9afc391ea91c2f268b0d24 (commit)
discards 2937067d5c6bdc2d615bbae48efcb62e530608a1 (commit)
discards 66d0185fbc1471682964d2af5e3d864cc4af8f1d (commit)
discards 4e4b5cb6f289d81764840965e0782191292a15ea (commit)
discards a99213bfd96e76363140d7a927c68e732a4f28df (commit)
discards 31c71f9e24a2863f08c1eb8246d3c230118e4042 (commit)
discards 7882bfc6c9f88cb624b2e8c439ffe0a543d971a7 (commit)
discards a1b26bc0d0e2e94086ed93b54c6e5ad0634d558c (commit)
discards ca1f2238765df39a2edd5f0deba3b243a76984f9 (commit)
discards ff8f85601c7936a8adc9a2f43aff206dc5bd9b20 (commit)
via 3763ff16e046d60f7c2f1c4ec8e79f19a9ab495e (commit)
via 4bde73fce3b188b87384cba8beb108907fafacb2 (commit)
via db083bdd61c9395b3a48ae67dd63b59f64092468 (commit)
via 4b18dd0bdc55dd73ed1a43e06a697266d0ed5590 (commit)
via fac0e16a3431c9ae320fe798f82f0e504c915389 (commit)
via d24835c56634bc687698ef48e650a4ceadbaf636 (commit)
via a6b7b8e38833e7d8d5f4bffc454d7418e491481b (commit)
via e455f157f3e4c8cd8c6e3ef4730d95dbf95b9528 (commit)
via 05d645dc45d4d803a61e6fe811e6312f563deabe (commit)
via eb56aaaaf1c89eee0f4b8c7cb6dfbaf6c55cd889 (commit)
via 1d14229c3b2f7c071a260f3d2035193227b286cb (commit)
via e174d0995ae8a07df43e23901410dcdd2f82221e (commit)
via aa6273ea0ea099aa9a5e0b5b233a66abd4890794 (commit)
via 388952b222953cbed410c189c27c85c0f5e58d44 (commit)
via 7d833537aaefe179760db7aab10720a24357410d (commit)
This update added new revisions after undoing existing revisions. That is
to say, the old revision is not a strict subset of the new revision. This
situation occurs when you --force push a change and generate a repository
containing something like this:
* -- * -- B -- O -- O -- O (d9cefab1e100ca77342a168c5c603baccfbc70f2)
\
N -- N -- N (3763ff16e046d60f7c2f1c4ec8e79f19a9ab495e)
When this happens we assume that you've already had alert emails for all
of the O revisions, and so we here report only the revisions in the N
branch from the common base, B.
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commitdiff
http://git.netsurf-browser.org/netsurf.git/commit/?id=3763ff16e046d60f7c2f1c4ec8e79f19a9ab495e
commit 3763ff16e046d60f7c2f1c4ec8e79f19a9ab495e
Author: Michael Drake <[email protected]>
Commit: Michael Drake <[email protected]>
html: layout: Initial implementation of display: flex
diff --git a/content/handlers/css/utils.h b/content/handlers/css/utils.h
index 0b05374..ee241e2 100644
--- a/content/handlers/css/utils.h
+++ b/content/handlers/css/utils.h
@@ -36,11 +36,9 @@ static inline uint8_t ns_computed_display(
uint8_t value = css_computed_display(style, root);
switch (value) {
- case CSS_DISPLAY_FLEX:
case CSS_DISPLAY_GRID:
return CSS_DISPLAY_BLOCK;
- case CSS_DISPLAY_INLINE_FLEX:
case CSS_DISPLAY_INLINE_GRID:
return CSS_DISPLAY_INLINE_BLOCK;
@@ -61,11 +59,9 @@ static inline uint8_t ns_computed_display_static(
uint8_t value = css_computed_display_static(style);
switch (value) {
- case CSS_DISPLAY_FLEX:
case CSS_DISPLAY_GRID:
return CSS_DISPLAY_BLOCK;
- case CSS_DISPLAY_INLINE_FLEX:
case CSS_DISPLAY_INLINE_GRID:
return CSS_DISPLAY_INLINE_BLOCK;
@@ -76,7 +72,6 @@ static inline uint8_t ns_computed_display_static(
return value;
}
-
static inline uint8_t ns_computed_min_height(
const css_computed_style *style,
css_fixed *length, css_unit *unit)
diff --git a/content/handlers/html/Makefile b/content/handlers/html/Makefile
index 8bb329b..e41cc1d 100644
--- a/content/handlers/html/Makefile
+++ b/content/handlers/html/Makefile
@@ -16,6 +16,7 @@ S_HTML := box_construct.c \
imagemap.c \
interaction.c \
layout.c \
+ layout_flex.c \
object.c \
redraw.c \
redraw_border.c \
diff --git a/content/handlers/html/box.h b/content/handlers/html/box.h
index 1059556..df2b99d 100644
--- a/content/handlers/html/box.h
+++ b/content/handlers/html/box.h
@@ -66,7 +66,9 @@ typedef enum {
BOX_BR,
BOX_TEXT,
BOX_INLINE_END,
- BOX_NONE
+ BOX_NONE,
+ BOX_FLEX,
+ BOX_INLINE_FLEX,
} box_type;
diff --git a/content/handlers/html/box_construct.c
b/content/handlers/html/box_construct.c
index 12d9df8..eeadb84 100644
--- a/content/handlers/html/box_construct.c
+++ b/content/handlers/html/box_construct.c
@@ -86,28 +86,30 @@ struct box_construct_props {
static const content_type image_types = CONTENT_IMAGE;
-/**
- * mapping from CSS display to box type this table must be in sync
- * with libcss' css_display enum
- */
+/* mapping from CSS display to box type
+ * this table must be in sync with libcss' css_display enum */
static const box_type box_map[] = {
- 0, /* CSS_DISPLAY_INHERIT, */
- BOX_INLINE, /* CSS_DISPLAY_INLINE, */
- BOX_BLOCK, /* CSS_DISPLAY_BLOCK, */
- BOX_BLOCK, /* CSS_DISPLAY_LIST_ITEM, */
- BOX_INLINE, /* CSS_DISPLAY_RUN_IN, */
- BOX_INLINE_BLOCK, /* CSS_DISPLAY_INLINE_BLOCK, */
- BOX_TABLE, /* CSS_DISPLAY_TABLE, */
- BOX_TABLE, /* CSS_DISPLAY_INLINE_TABLE, */
- BOX_TABLE_ROW_GROUP, /* CSS_DISPLAY_TABLE_ROW_GROUP, */
- BOX_TABLE_ROW_GROUP, /* CSS_DISPLAY_TABLE_HEADER_GROUP, */
- BOX_TABLE_ROW_GROUP, /* CSS_DISPLAY_TABLE_FOOTER_GROUP, */
- BOX_TABLE_ROW, /* CSS_DISPLAY_TABLE_ROW, */
- BOX_NONE, /* CSS_DISPLAY_TABLE_COLUMN_GROUP, */
- BOX_NONE, /* CSS_DISPLAY_TABLE_COLUMN, */
- BOX_TABLE_CELL, /* CSS_DISPLAY_TABLE_CELL, */
- BOX_INLINE, /* CSS_DISPLAY_TABLE_CAPTION, */
- BOX_NONE /* CSS_DISPLAY_NONE */
+ BOX_BLOCK, /* CSS_DISPLAY_INHERIT */
+ BOX_INLINE, /* CSS_DISPLAY_INLINE */
+ BOX_BLOCK, /* CSS_DISPLAY_BLOCK */
+ BOX_BLOCK, /* CSS_DISPLAY_LIST_ITEM */
+ BOX_INLINE, /* CSS_DISPLAY_RUN_IN */
+ BOX_INLINE_BLOCK, /* CSS_DISPLAY_INLINE_BLOCK */
+ BOX_TABLE, /* CSS_DISPLAY_TABLE */
+ BOX_TABLE, /* CSS_DISPLAY_INLINE_TABLE */
+ BOX_TABLE_ROW_GROUP, /* CSS_DISPLAY_TABLE_ROW_GROUP */
+ BOX_TABLE_ROW_GROUP, /* CSS_DISPLAY_TABLE_HEADER_GROUP */
+ BOX_TABLE_ROW_GROUP, /* CSS_DISPLAY_TABLE_FOOTER_GROUP */
+ BOX_TABLE_ROW, /* CSS_DISPLAY_TABLE_ROW */
+ BOX_NONE, /* CSS_DISPLAY_TABLE_COLUMN_GROUP */
+ BOX_NONE, /* CSS_DISPLAY_TABLE_COLUMN */
+ BOX_TABLE_CELL, /* CSS_DISPLAY_TABLE_CELL */
+ BOX_INLINE, /* CSS_DISPLAY_TABLE_CAPTION */
+ BOX_NONE, /* CSS_DISPLAY_NONE */
+ BOX_FLEX, /* CSS_DISPLAY_FLEX */
+ BOX_INLINE_FLEX, /* CSS_DISPLAY_INLINE_FLEX */
+ BOX_BLOCK, /* CSS_DISPLAY_GRID */
+ BOX_INLINE_BLOCK, /* CSS_DISPLAY_INLINE_GRID */
};
@@ -142,7 +144,6 @@ static inline bool box_is_root(dom_node *n)
return true;
}
-
/**
* Extract transient construction properties
*
@@ -438,6 +439,23 @@ box_construct_marker(struct box *box,
return true;
}
+static inline bool box__style_is_float(const struct box *box)
+{
+ return css_computed_float(box->style) == CSS_FLOAT_LEFT ||
+ css_computed_float(box->style) == CSS_FLOAT_RIGHT;
+}
+
+static inline bool box__is_flex(const struct box *box)
+{
+ return box->type == BOX_FLEX || box->type == BOX_INLINE_FLEX;
+}
+
+static inline bool box__containing_block_is_flex(
+ const struct box_construct_props *props)
+{
+ return props->containing_block != NULL &&
+ box__is_flex(props->containing_block);
+}
/**
* Construct the box tree for an XML element.
@@ -451,6 +469,7 @@ box_construct_element(struct box_construct_ctx *ctx, bool
*convert_children)
{
dom_string *title0, *s;
lwc_string *id = NULL;
+ enum css_display_e css_display;
struct box *box = NULL, *old_box;
css_select_results *styles = NULL;
lwc_string *bgimage_uri;
@@ -549,16 +568,15 @@ box_construct_element(struct box_construct_ctx *ctx, bool
*convert_children)
dom_string_unref(s);
}
+ css_display = ns_computed_display_static(box->style);
+
/* Set box type from computed display */
if ((css_computed_position(box->style) == CSS_POSITION_ABSOLUTE ||
- css_computed_position(box->style) ==
- CSS_POSITION_FIXED) &&
- (ns_computed_display_static(box->style) ==
- CSS_DISPLAY_INLINE ||
- ns_computed_display_static(box->style) ==
- CSS_DISPLAY_INLINE_BLOCK ||
- ns_computed_display_static(box->style) ==
- CSS_DISPLAY_INLINE_TABLE)) {
+ css_computed_position(box->style) == CSS_POSITION_FIXED) &&
+ (css_display == CSS_DISPLAY_INLINE ||
+ css_display == CSS_DISPLAY_INLINE_BLOCK ||
+ css_display == CSS_DISPLAY_INLINE_TABLE ||
+ css_display == CSS_DISPLAY_INLINE_FLEX)) {
/* Special case for absolute positioning: make absolute inlines
* into inline block so that the boxes are constructed in an
* inline container as if they were not absolutely positioned.
@@ -572,6 +590,21 @@ box_construct_element(struct box_construct_ctx *ctx, bool
*convert_children)
/* Normal mapping */
box->type = box_map[ns_computed_display(box->style,
props.node_is_root)];
+
+ if (props.containing_block->type == BOX_FLEX ||
+ props.containing_block->type == BOX_INLINE_FLEX) {
+ /* Blockification */
+ switch (box->type) {
+ case BOX_INLINE_FLEX:
+ box->type = BOX_FLEX;
+ break;
+ case BOX_INLINE_BLOCK:
+ box->type = BOX_BLOCK;
+ break;
+ default:
+ break;
+ }
+ }
}
if (convert_special_elements(ctx->n,
@@ -587,10 +620,9 @@ box_construct_element(struct box_construct_ctx *ctx, bool
*convert_children)
box->styles->styles[CSS_PSEUDO_ELEMENT_BEFORE]);
}
- if (box->type == BOX_NONE ||
- (ns_computed_display(box->style,
- props.node_is_root) == CSS_DISPLAY_NONE &&
- props.node_is_root == false)) {
+ if (box->type == BOX_NONE || (ns_computed_display(box->style,
+ props.node_is_root) == CSS_DISPLAY_NONE &&
+ props.node_is_root == false)) {
css_select_results_destroy(styles);
box->styles = NULL;
box->style = NULL;
@@ -625,8 +657,9 @@ box_construct_element(struct box_construct_ctx *ctx, bool
*convert_children)
(box->type == BOX_INLINE ||
box->type == BOX_BR ||
box->type == BOX_INLINE_BLOCK ||
- css_computed_float(box->style) == CSS_FLOAT_LEFT ||
- css_computed_float(box->style) == CSS_FLOAT_RIGHT) &&
+ box->type == BOX_INLINE_FLEX ||
+ (box__style_is_float(box) &&
+ !box__containing_block_is_flex(&props))) &&
props.node_is_root == false) {
/* Found an inline child of a block without a current container
* (i.e. this box is the first child of its parent, or was
@@ -674,6 +707,7 @@ box_construct_element(struct box_construct_ctx *ctx, bool
*convert_children)
box->flags |= CONVERT_CHILDREN;
if (box->type == BOX_INLINE || box->type == BOX_BR ||
+ box->type == BOX_INLINE_FLEX ||
box->type == BOX_INLINE_BLOCK) {
/* Inline container must exist, as we'll have
* created it above if it didn't */
@@ -690,6 +724,7 @@ box_construct_element(struct box_construct_ctx *ctx, bool
*convert_children)
}
if (props.node_is_root == false &&
+ box__containing_block_is_flex(&props) == false
&&
(css_computed_float(box->style) ==
CSS_FLOAT_LEFT ||
css_computed_float(box->style) ==
@@ -1342,7 +1377,6 @@ struct box *box_for_node(dom_node *n)
return box;
}
-
/* exported function documented in html/box_construct.h */
bool
box_extract_link(const html_content *content,
diff --git a/content/handlers/html/box_inspect.c
b/content/handlers/html/box_inspect.c
index b6b9f81..181f58c 100644
--- a/content/handlers/html/box_inspect.c
+++ b/content/handlers/html/box_inspect.c
@@ -724,6 +724,14 @@ void box_dump(FILE *stream, struct box *box, unsigned int
depth, bool style)
fprintf(stream, "TEXT ");
break;
+ case BOX_FLEX:
+ fprintf(stream, "FLEX ");
+ break;
+
+ case BOX_INLINE_FLEX:
+ fprintf(stream, "INLINE_FLEX ");
+ break;
+
default:
fprintf(stream, "Unknown box type ");
}
diff --git a/content/handlers/html/box_inspect.h
b/content/handlers/html/box_inspect.h
index b9161f1..a218326 100644
--- a/content/handlers/html/box_inspect.h
+++ b/content/handlers/html/box_inspect.h
@@ -139,5 +139,17 @@ static inline bool box_is_first_child(struct box *b)
return (b->parent == NULL || b == b->parent->children);
}
+static inline unsigned box_count_children(const struct box *b)
+{
+ const struct box *c = b->children;
+ unsigned count = 0;
+
+ while (c != NULL) {
+ count++;
+ c = c->next;
+ }
+
+ return count;
+}
#endif
diff --git a/content/handlers/html/box_normalise.c
b/content/handlers/html/box_normalise.c
index 1b6a345..8f25b03 100644
--- a/content/handlers/html/box_normalise.c
+++ b/content/handlers/html/box_normalise.c
@@ -177,6 +177,7 @@ box_normalise_table_row(struct box *row,
return false;
cell = child;
break;
+ case BOX_FLEX:
case BOX_BLOCK:
case BOX_INLINE_CONTAINER:
case BOX_TABLE:
@@ -211,6 +212,7 @@ box_normalise_table_row(struct box *row,
cell->prev = child->prev;
while (child != NULL && (
+ child->type == BOX_FLEX ||
child->type == BOX_BLOCK ||
child->type == BOX_INLINE_CONTAINER ||
child->type == BOX_TABLE ||
@@ -238,6 +240,7 @@ box_normalise_table_row(struct box *row,
break;
case BOX_INLINE:
case BOX_INLINE_END:
+ case BOX_INLINE_FLEX:
case BOX_INLINE_BLOCK:
case BOX_FLOAT_LEFT:
case BOX_FLOAT_RIGHT:
@@ -314,6 +317,7 @@ box_normalise_table_row_group(struct box *row_group,
c) == false)
return false;
break;
+ case BOX_FLEX:
case BOX_BLOCK:
case BOX_INLINE_CONTAINER:
case BOX_TABLE:
@@ -348,6 +352,7 @@ box_normalise_table_row_group(struct box *row_group,
row->prev = child->prev;
while (child != NULL && (
+ child->type == BOX_FLEX ||
child->type == BOX_BLOCK ||
child->type == BOX_INLINE_CONTAINER ||
child->type == BOX_TABLE ||
@@ -377,6 +382,7 @@ box_normalise_table_row_group(struct box *row_group,
break;
case BOX_INLINE:
case BOX_INLINE_END:
+ case BOX_INLINE_FLEX:
case BOX_INLINE_BLOCK:
case BOX_FLOAT_LEFT:
case BOX_FLOAT_RIGHT:
@@ -648,6 +654,7 @@ box_normalise_table(struct box *table, const struct box
*root, html_content * c)
return false;
}
break;
+ case BOX_FLEX:
case BOX_BLOCK:
case BOX_INLINE_CONTAINER:
case BOX_TABLE:
@@ -686,6 +693,7 @@ box_normalise_table(struct box *table, const struct box
*root, html_content * c)
row_group->prev = child->prev;
while (child != NULL && (
+ child->type == BOX_FLEX ||
child->type == BOX_BLOCK ||
child->type == BOX_INLINE_CONTAINER ||
child->type == BOX_TABLE ||
@@ -716,6 +724,7 @@ box_normalise_table(struct box *table, const struct box
*root, html_content * c)
break;
case BOX_INLINE:
case BOX_INLINE_END:
+ case BOX_INLINE_FLEX:
case BOX_INLINE_BLOCK:
case BOX_FLOAT_LEFT:
case BOX_FLOAT_RIGHT:
@@ -806,6 +815,181 @@ box_normalise_table(struct box *table, const struct box
*root, html_content * c)
return true;
}
+static bool box_normalise_flex(
+ struct box *flex_container,
+ const struct box *root,
+ html_content *c)
+{
+ struct box *child;
+ struct box *next_child;
+ struct box *implied_flex_item;
+ css_computed_style *style;
+ nscss_select_ctx ctx;
+
+ assert(flex_container != NULL);
+ assert(root != NULL);
+
+ ctx.root_style = root->style;
+
+#ifdef BOX_NORMALISE_DEBUG
+ NSLOG(netsurf, INFO, "flex_container %p, flex_container->type %u",
+ flex_container, flex_container->type);
+#endif
+
+ assert(flex_container->type == BOX_FLEX ||
+ flex_container->type == BOX_INLINE_FLEX);
+
+ for (child = flex_container->children; child != NULL; child =
next_child) {
+#ifdef BOX_NORMALISE_DEBUG
+ NSLOG(netsurf, INFO, "child %p, child->type = %d",
+ child, child->type);
+#endif
+
+ next_child = child->next; /* child may be destroyed */
+
+ switch (child->type) {
+ case BOX_FLEX:
+ /* ok */
+ if (box_normalise_flex(child, root, c) == false)
+ return false;
+ break;
+ case BOX_BLOCK:
+ /* ok */
+ if (box_normalise_block(child, root, c) == false)
+ return false;
+ break;
+ case BOX_INLINE_CONTAINER:
+ /* insert implied flex item */
+ assert(flex_container->style != NULL);
+
+ ctx.ctx = c->select_ctx;
+ ctx.quirks = (c->quirks ==
DOM_DOCUMENT_QUIRKS_MODE_FULL);
+ ctx.base_url = c->base_url;
+ ctx.universal = c->universal;
+
+ style = nscss_get_blank_style(&ctx, &c->unit_len_ctx,
+ flex_container->style);
+ if (style == NULL)
+ return false;
+
+ implied_flex_item = box_create(NULL, style, true,
+ flex_container->href,
+ flex_container->target,
+ NULL, NULL, c->bctx);
+ if (implied_flex_item == NULL) {
+ css_computed_style_destroy(style);
+ return false;
+ }
+ implied_flex_item->type = BOX_BLOCK;
+
+ if (child->prev == NULL)
+ flex_container->children = implied_flex_item;
+ else
+ child->prev->next = implied_flex_item;
+
+ implied_flex_item->prev = child->prev;
+
+ while (child != NULL &&
+ child->type == BOX_INLINE_CONTAINER) {
+ box_add_child(implied_flex_item, child);
+
+ next_child = child->next;
+ child->next = NULL;
+ child = next_child;
+ }
+
+ implied_flex_item->last->next = NULL;
+ implied_flex_item->next = next_child = child;
+ if (implied_flex_item->next != NULL)
+ implied_flex_item->next->prev =
implied_flex_item;
+ else
+ flex_container->last = implied_flex_item;
+ implied_flex_item->parent = flex_container;
+
+ if (box_normalise_block(implied_flex_item,
+ root, c) == false)
+ return false;
+ break;
+
+ case BOX_TABLE:
+ if (box_normalise_table(child, root, c) == false)
+ return false;
+ break;
+ case BOX_INLINE:
+ case BOX_INLINE_END:
+ case BOX_INLINE_FLEX:
+ case BOX_INLINE_BLOCK:
+ case BOX_FLOAT_LEFT:
+ case BOX_FLOAT_RIGHT:
+ case BOX_BR:
+ case BOX_TEXT:
+ /* should have been wrapped in inline
+ container by convert_xml_to_box() */
+ assert(0);
+ break;
+ case BOX_TABLE_ROW_GROUP:
+ case BOX_TABLE_ROW:
+ case BOX_TABLE_CELL:
+ /* insert implied table */
+ assert(flex_container->style != NULL);
+
+ ctx.ctx = c->select_ctx;
+ ctx.quirks = (c->quirks ==
DOM_DOCUMENT_QUIRKS_MODE_FULL);
+ ctx.base_url = c->base_url;
+ ctx.universal = c->universal;
+
+ style = nscss_get_blank_style(&ctx, &c->unit_len_ctx,
+ flex_container->style);
+ if (style == NULL)
+ return false;
+
+ implied_flex_item = box_create(NULL, style, true,
+ flex_container->href,
+ flex_container->target,
+ NULL, NULL, c->bctx);
+ if (implied_flex_item == NULL) {
+ css_computed_style_destroy(style);
+ return false;
+ }
+ implied_flex_item->type = BOX_TABLE;
+
+ if (child->prev == NULL)
+ flex_container->children = implied_flex_item;
+ else
+ child->prev->next = implied_flex_item;
+
+ implied_flex_item->prev = child->prev;
+
+ while (child != NULL && (
+ child->type == BOX_TABLE_ROW_GROUP ||
+ child->type == BOX_TABLE_ROW ||
+ child->type == BOX_TABLE_CELL)) {
+ box_add_child(implied_flex_item, child);
+
+ next_child = child->next;
+ child->next = NULL;
+ child = next_child;
+ }
+
+ implied_flex_item->last->next = NULL;
+ implied_flex_item->next = next_child = child;
+ if (implied_flex_item->next != NULL)
+ implied_flex_item->next->prev =
implied_flex_item;
+ else
+ flex_container->last = implied_flex_item;
+ implied_flex_item->parent = flex_container;
+
+ if (box_normalise_table(implied_flex_item,
+ root, c) == false)
+ return false;
+ break;
+ default:
+ assert(0);
+ }
+ }
+
+ return true;
+}
static bool
box_normalise_inline_container(struct box *cont,
@@ -836,6 +1020,11 @@ box_normalise_inline_container(struct box *cont,
if (box_normalise_block(child, root, c) == false)
return false;
break;
+ case BOX_INLINE_FLEX:
+ /* ok */
+ if (box_normalise_flex(child, root, c) == false)
+ return false;
+ break;
case BOX_FLOAT_LEFT:
case BOX_FLOAT_RIGHT:
/* ok */
@@ -852,6 +1041,11 @@ box_normalise_inline_container(struct box *cont,
c) == false)
return false;
break;
+ case BOX_FLEX:
+ if (box_normalise_flex(child->children, root,
+ c) == false)
+ return false;
+ break;
default:
assert(0);
}
@@ -870,6 +1064,7 @@ box_normalise_inline_container(struct box *cont,
box_free(child);
}
break;
+ case BOX_FLEX:
case BOX_BLOCK:
case BOX_INLINE_CONTAINER:
case BOX_TABLE:
@@ -888,7 +1083,6 @@ box_normalise_inline_container(struct box *cont,
return true;
}
-
/* Exported function documented in html/box_normalise.h */
bool
box_normalise_block(struct box *block, const struct box *root, html_content *c)
@@ -920,6 +1114,11 @@ box_normalise_block(struct box *block, const struct box
*root, html_content *c)
next_child = child->next; /* child may be destroyed */
switch (child->type) {
+ case BOX_FLEX:
+ /* ok */
+ if (box_normalise_flex(child, root, c) == false)
+ return false;
+ break;
case BOX_BLOCK:
/* ok */
if (box_normalise_block(child, root, c) == false)
@@ -935,6 +1134,7 @@ box_normalise_block(struct box *block, const struct box
*root, html_content *c)
break;
case BOX_INLINE:
case BOX_INLINE_END:
+ case BOX_INLINE_FLEX:
case BOX_INLINE_BLOCK:
case BOX_FLOAT_LEFT:
case BOX_FLOAT_RIGHT:
diff --git a/content/handlers/html/box_normalise.h
b/content/handlers/html/box_normalise.h
index 591feab..377cd90 100644
--- a/content/handlers/html/box_normalise.h
+++ b/content/handlers/html/box_normalise.h
@@ -50,14 +50,15 @@
* The tree is modified to satisfy the following:
* \code
* parent permitted child nodes
- * BLOCK, INLINE_BLOCK BLOCK, INLINE_CONTAINER, TABLE
- * INLINE_CONTAINER INLINE, INLINE_BLOCK, FLOAT_LEFT, FLOAT_RIGHT, BR, TEXT
+ * BLOCK, INLINE_BLOCK BLOCK, INLINE_CONTAINER, TABLE, FLEX
+ * FLEX, INLINE_FLEX BLOCK, INLINE_CONTAINER, TABLE, FLEX
+ * INLINE_CONTAINER INLINE, INLINE_BLOCK, FLOAT_LEFT, FLOAT_RIGHT, BR,
TEXT, INLINE_FLEX
* INLINE, TEXT none
* TABLE at least 1 TABLE_ROW_GROUP
* TABLE_ROW_GROUP at least 1 TABLE_ROW
* TABLE_ROW at least 1 TABLE_CELL
- * TABLE_CELL BLOCK, INLINE_CONTAINER, TABLE (same as BLOCK)
- * FLOAT_(LEFT|RIGHT) exactly 1 BLOCK or TABLE
+ * TABLE_CELL BLOCK, INLINE_CONTAINER, TABLE, FLEX (same as BLOCK)
+ * FLOAT_(LEFT|RIGHT) exactly 1 BLOCK, TABLE or FLEX
* \endcode
*/
bool box_normalise_block(struct box *block, const struct box *root, struct
html_content *c);
diff --git a/content/handlers/html/box_special.c
b/content/handlers/html/box_special.c
index f761557..db3c412 100644
--- a/content/handlers/html/box_special.c
+++ b/content/handlers/html/box_special.c
@@ -560,8 +560,18 @@ static bool
box_input_text(html_content *html, struct box *box, struct dom_node *node)
{
struct box *inline_container, *inline_box;
+ uint8_t display = css_computed_display_static(box->style);
- box->type = BOX_INLINE_BLOCK;
+ switch (display) {
+ case CSS_DISPLAY_GRID:
+ case CSS_DISPLAY_FLEX:
+ case CSS_DISPLAY_BLOCK:
+ box->type = BOX_BLOCK;
+ break;
+ default:
+ box->type = BOX_INLINE_BLOCK;
+ break;
+ }
inline_container = box_create(NULL, 0, false, 0, 0, 0, 0, html->bctx);
if (!inline_container)
@@ -825,8 +835,8 @@ box_canvas(dom_node *n,
}
*convert_children = false;
- if (box->style &&
- ns_computed_display(box->style, box_is_root(n)) == CSS_DISPLAY_NONE)
+ if (box->style && ns_computed_display(box->style,
+ box_is_root(n)) == CSS_DISPLAY_NONE)
return true;
/* This is replaced content */
@@ -854,8 +864,8 @@ box_embed(dom_node *n,
dom_string *src;
dom_exception err;
- if (box->style &&
- ns_computed_display(box->style, box_is_root(n)) == CSS_DISPLAY_NONE)
+ if (box->style && ns_computed_display(box->style,
+ box_is_root(n)) == CSS_DISPLAY_NONE)
return true;
params = talloc(content->bctx, struct object_params);
@@ -1025,8 +1035,8 @@ box_iframe(dom_node *n,
struct content_html_iframe *iframe;
int i;
- if (box->style &&
- ns_computed_display(box->style, box_is_root(n)) == CSS_DISPLAY_NONE)
+ if (box->style && ns_computed_display(box->style,
+ box_is_root(n)) == CSS_DISPLAY_NONE)
return true;
if (box->style &&
@@ -1154,8 +1164,8 @@ box_image(dom_node *n,
css_unit wunit = CSS_UNIT_PX;
css_unit hunit = CSS_UNIT_PX;
- if (box->style &&
- ns_computed_display(box->style, box_is_root(n)) == CSS_DISPLAY_NONE)
+ if (box->style && ns_computed_display(box->style,
+ box_is_root(n)) == CSS_DISPLAY_NONE)
return true;
/* handle alt text */
@@ -1322,10 +1332,9 @@ box_input(dom_node *n,
corestring_lwc_image)) {
gadget->type = GADGET_IMAGE;
- if (box->style &&
- ns_computed_display(box->style,
+ if (box->style && ns_computed_display(box->style,
box_is_root(n)) != CSS_DISPLAY_NONE &&
- nsoption_bool(foreground_images) == true) {
+ nsoption_bool(foreground_images) == true) {
dom_string *s;
err = dom_element_get_attribute(n, corestring_dom_src,
&s);
@@ -1405,8 +1414,8 @@ box_object(dom_node *n,
dom_node *c;
dom_exception err;
- if (box->style &&
- ns_computed_display(box->style, box_is_root(n)) == CSS_DISPLAY_NONE)
+ if (box->style && ns_computed_display(box->style,
+ box_is_root(n)) == CSS_DISPLAY_NONE)
return true;
if (box_get_attribute(n, "usemap", content->bctx, &box->usemap) ==
diff --git a/content/handlers/html/layout.c b/content/handlers/html/layout.c
index 816775c..431075d 100644
--- a/content/handlers/html/layout.c
+++ b/content/handlers/html/layout.c
@@ -522,11 +522,11 @@ layout_minmax_line(struct box *first,
if (lh__box_is_float_box(b)) {
assert(b->children);
- if (b->children->type == BOX_BLOCK)
- layout_minmax_block(b->children, font_func,
+ if (b->children->type == BOX_TABLE)
+ layout_minmax_table(b->children, font_func,
content);
else
- layout_minmax_table(b->children, font_func,
+ layout_minmax_block(b->children, font_func,
content);
b->min_width = b->children->min_width;
b->max_width = b->children->max_width;
@@ -536,7 +536,7 @@ layout_minmax_line(struct box *first,
continue;
}
- if (b->type == BOX_INLINE_BLOCK) {
+ if (b->type == BOX_INLINE_BLOCK || b->type == BOX_INLINE_FLEX) {
layout_minmax_block(b, font_func, content);
if (min < b->min_width)
min = b->min_width;
@@ -869,7 +869,6 @@ layout_minmax_inline_container(struct box *inline_container,
inline_container->max_width);
}
-
/**
* Calculate minimum and maximum width of a block.
*
@@ -900,6 +899,8 @@ static void layout_minmax_block(
bool child_has_height = false;
assert(block->type == BOX_BLOCK ||
+ block->type == BOX_FLEX ||
+ block->type == BOX_INLINE_FLEX ||
block->type == BOX_INLINE_BLOCK ||
block->type == BOX_TABLE_CELL);
@@ -915,7 +916,8 @@ static void layout_minmax_block(
/* set whether the minimum width is of any interest for this box */
if (((block->parent && lh__box_is_float_box(block->parent)) ||
- block->type == BOX_INLINE_BLOCK) &&
+ block->type == BOX_INLINE_BLOCK ||
+ block->type == BOX_INLINE_FLEX) &&
wtype != CSS_WIDTH_SET) {
/* box shrinks to fit; need minimum width */
block->flags |= NEED_MIN;
@@ -926,6 +928,9 @@ static void layout_minmax_block(
wtype != CSS_WIDTH_SET) {
/* box inside shrink-to-fit context; need minimum width */
block->flags |= NEED_MIN;
+ } else if (block->parent && (block->parent->type == BOX_FLEX)) {
+ /* box is flex item */
+ block->flags |= NEED_MIN;
}
if (block->gadget && (block->gadget->type == GADGET_TEXTBOX ||
@@ -975,6 +980,7 @@ static void layout_minmax_block(
/* recurse through children */
for (child = block->children; child; child = child->next) {
switch (child->type) {
+ case BOX_FLEX:
case BOX_BLOCK:
layout_minmax_block(child, font_func,
content);
@@ -1016,10 +1022,20 @@ static void layout_minmax_block(
continue;
}
- if (min < child->min_width)
- min = child->min_width;
- if (max < child->max_width)
- max = child->max_width;
+ if (lh__box_is_flex_container(block) &&
+ layout_flex__main_is_horizontal(block)
&&
+ block->style != NULL &&
+ css_computed_flex_wrap(block->style) ==
+ CSS_FLEX_WRAP_NOWRAP) {
+ min += child->min_width;
+ max += child->max_width;
+
+ } else {
+ if (min < child->min_width)
+ min = child->min_width;
+ if (max < child->max_width)
+ max = child->max_width;
+ }
if (child_has_height)
block->flags |= HAS_HEIGHT;
@@ -1032,7 +1048,7 @@ static void layout_minmax_block(
}
/* fixed width takes priority */
- if (block->type != BOX_TABLE_CELL) {
+ if (block->type != BOX_TABLE_CELL && !lh__box_is_flex_item(block)) {
bool border_box = bs == CSS_BOX_SIZING_BORDER_BOX;
enum css_max_width_e max_type;
enum css_min_width_e min_type;
@@ -1121,7 +1137,8 @@ static void layout_minmax_block(
block->max_width = (max + extra_fixed) / (1.0 - extra_frac);
}
- assert(0 <= block->min_width && block->min_width <= block->max_width);
+ assert(0 <= block->min_width);
+ assert(block->min_width <= block->max_width);
}
@@ -2283,7 +2300,9 @@ static bool layout_block_object(struct box *block)
{
assert(block);
assert(block->type == BOX_BLOCK ||
+ block->type == BOX_FLEX ||
block->type == BOX_INLINE_BLOCK ||
+ block->type == BOX_INLINE_FLEX ||
block->type == BOX_TABLE ||
block->type == BOX_TABLE_CELL);
assert(block->object);
@@ -2577,12 +2596,20 @@ layout_float_find_dimensions(
*/
static bool layout_float(struct box *b, int width, html_content *content)
{
- assert(b->type == BOX_TABLE || b->type == BOX_BLOCK ||
- b->type == BOX_INLINE_BLOCK);
+ assert(b->type == BOX_TABLE ||
+ b->type == BOX_BLOCK ||
+ b->type == BOX_INLINE_BLOCK ||
+ b->type == BOX_FLEX ||
+ b->type == BOX_INLINE_FLEX);
layout_float_find_dimensions(&content->unit_len_ctx, width, b->style,
b);
- if (b->type == BOX_TABLE) {
- if (!layout_table(b, width, content))
- return false;
+ if (b->type == BOX_TABLE || b->type == BOX_INLINE_FLEX) {
+ if (b->type == BOX_TABLE) {
+ if (!layout_table(b, width, content))
+ return false;
+ } else {
+ if (!layout_flex(b, width, content))
+ return false;
+ }
if (b->margin[LEFT] == AUTO)
b->margin[LEFT] = 0;
if (b->margin[RIGHT] == AUTO)
@@ -2591,8 +2618,9 @@ static bool layout_float(struct box *b, int width,
html_content *content)
b->margin[TOP] = 0;
if (b->margin[BOTTOM] == AUTO)
b->margin[BOTTOM] = 0;
- } else
+ } else {
return layout_block_context(b, -1, content);
+ }
return true;
}
@@ -2800,7 +2828,8 @@ layout_line(struct box *first,
x += space_after;
- if (b->type == BOX_INLINE_BLOCK) {
+ if (b->type == BOX_INLINE_BLOCK ||
+ b->type == BOX_INLINE_FLEX) {
if (b->max_width != UNKNOWN_WIDTH)
if (!layout_float(b, *width, content))
return false;
@@ -3020,7 +3049,8 @@ layout_line(struct box *first,
b->x = x;
if ((b->type == BOX_INLINE && !b->inline_end) ||
- b->type == BOX_INLINE_BLOCK) {
+ b->type == BOX_INLINE_BLOCK ||
+ b->type == BOX_INLINE_FLEX) {
b->x += b->margin[LEFT] + b->border[LEFT].width;
x = b->x + b->padding[LEFT] + b->width +
b->padding[RIGHT] +
@@ -3521,7 +3551,9 @@ bool layout_block_context(
assert(block->type == BOX_BLOCK ||
block->type == BOX_INLINE_BLOCK ||
- block->type == BOX_TABLE_CELL);
+ block->type == BOX_TABLE_CELL ||
+ block->type == BOX_FLEX ||
+ block->type == BOX_INLINE_FLEX);
assert(block->width != UNKNOWN_WIDTH);
assert(block->width != AUTO);
@@ -3590,7 +3622,9 @@ bool layout_block_context(
enum css_overflow_e overflow_x = CSS_OVERFLOW_VISIBLE;
enum css_overflow_e overflow_y = CSS_OVERFLOW_VISIBLE;
- assert(box->type == BOX_BLOCK || box->type == BOX_TABLE ||
+ assert(box->type == BOX_BLOCK ||
+ box->type == BOX_FLEX ||
+ box->type == BOX_TABLE ||
box->type == BOX_INLINE_CONTAINER);
/* Tables are laid out before being positioned, because the
@@ -3641,7 +3675,9 @@ bool layout_block_context(
* left and right margins to avoid any floats. */
lm = rm = 0;
- if (box->type == BOX_BLOCK || box->flags & IFRAME) {
+ if (box->type == BOX_FLEX ||
+ box->type == BOX_BLOCK ||
+ box->flags & IFRAME) {
if (lh__box_is_object(box) == false &&
box->style &&
(overflow_x != CSS_OVERFLOW_VISIBLE ||
@@ -3727,6 +3763,7 @@ bool layout_block_context(
/* Vertical margin */
if (((box->type == BOX_BLOCK && (box->flags & HAS_HEIGHT)) ||
+ box->type == BOX_FLEX ||
box->type == BOX_TABLE ||
(box->type == BOX_INLINE_CONTAINER &&
!box_is_first_child(box)) ||
@@ -3751,11 +3788,19 @@ bool layout_block_context(
/* Unless the box has an overflow style of visible, the box
* establishes a new block context. */
- if (box->type == BOX_BLOCK && box->style &&
- (overflow_x != CSS_OVERFLOW_VISIBLE ||
- overflow_y != CSS_OVERFLOW_VISIBLE)) {
+ if (box->type == BOX_FLEX ||
+ (box->type == BOX_BLOCK && box->style &&
+ (overflow_x != CSS_OVERFLOW_VISIBLE ||
+ overflow_y != CSS_OVERFLOW_VISIBLE))) {
- layout_block_context(box, viewport_height, content);
+ if (box->type == BOX_FLEX) {
+ if (!layout_flex(box, box->width, content)) {
+ return false;
+ }
+ } else {
+ layout_block_context(box,
+ viewport_height, content);
+ }
cy += box->padding[TOP];
@@ -3776,7 +3821,8 @@ bool layout_block_context(
goto advance_to_next_box;
}
- NSLOG(layout, DEBUG, "box %p, cx %i, cy %i", box, cx, cy);
+ NSLOG(layout, DEBUG, "box %p, cx %i, cy %i, width %i",
+ box, cx, cy, box->width);
/* Layout (except tables). */
if (box->object) {
@@ -4552,7 +4598,9 @@ layout_absolute(struct box *box,
int space;
assert(box->type == BOX_BLOCK || box->type == BOX_TABLE ||
- box->type == BOX_INLINE_BLOCK);
+ box->type == BOX_INLINE_BLOCK ||
+ box->type == BOX_FLEX ||
+ box->type == BOX_INLINE_FLEX);
/* The static position is where the box would be if it was not
* absolutely positioned. The x and y are filled in by
@@ -4787,6 +4835,13 @@ layout_absolute(struct box *box,
box->float_container = NULL;
layout_solve_width(box, box->parent->width, box->width, 0, 0,
-1, -1);
+ } else if (box->type == BOX_FLEX || box->type == BOX_INLINE_FLEX) {
+ /* layout_table also expects the containing block to be
+ * stored in the float_container field */
+ box->float_container = containing_block;
+ if (!layout_flex(box, width, content))
+ return false;
+ box->float_container = NULL;
}
/* 10.6.4 */
@@ -4923,7 +4978,9 @@ layout_position_absolute(struct box *box,
for (c = box->children; c; c = c->next) {
if ((c->type == BOX_BLOCK || c->type == BOX_TABLE ||
- c->type == BOX_INLINE_BLOCK) &&
+ c->type == BOX_INLINE_BLOCK ||
+ c->type == BOX_FLEX ||
+ c->type == BOX_INLINE_FLEX) &&
(css_computed_position(c->style) ==
CSS_POSITION_ABSOLUTE ||
css_computed_position(c->style) ==
diff --git a/content/handlers/html/layout_flex.c
b/content/handlers/html/layout_flex.c
new file mode 100644
index 0000000..64797af
--- /dev/null
+++ b/content/handlers/html/layout_flex.c
@@ -0,0 +1,830 @@
+/*
+ * Copyright 2022 Michael Drake <[email protected]>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * \file
+ * HTML layout implementation: display: flex.
+ *
+ * Layout is carried out in two stages:
+ *
+ * 1. + calculation of minimum / maximum box widths, and
+ * + determination of whether block level boxes will have >zero height
+ *
+ * 2. + layout (position and dimensions)
+ *
+ * In most cases the functions for the two stages are a corresponding pair
+ * layout_minmax_X() and layout_X().
+ */
+
+#include <string.h>
+
+#include "utils/log.h"
+#include "utils/utils.h"
+
+#include "html/box.h"
+#include "html/html.h"
+#include "html/private.h"
+#include "html/box_inspect.h"
+#include "html/layout_internal.h"
+
+struct flex_item_data {
+ enum css_flex_basis_e basis;
+ css_fixed basis_length;
+ css_unit basis_unit;
+ struct box *box;
+
+ css_fixed shrink;
+ css_fixed grow;
+
+ int min_main;
+ int max_main;
+ int min_cross;
+ int max_cross;
+
+ int target_main_size;
+ int base_size;
+ int main_size;
+ size_t line;
+
+ bool freeze;
+ bool min_violation;
+ bool max_violation;
+};
+
+struct flex_line_data {
+ int main_size;
+ int cross_size;
+
+ size_t first;
+ size_t count;
+ size_t frozen;
+};
+
+struct flex_ctx {
+ html_content *content;
+ const struct box *flex;
+ const css_unit_ctx *unit_len_ctx;
+
+ int main_size;
+ int cross_size;
+
+ bool horizontal;
+ enum css_flex_wrap_e wrap;
+
+ struct flex_items {
+ size_t count;
+ struct flex_item_data *data;
+ } item;
+
+ struct flex_lines {
+ size_t count;
+ size_t alloc;
+ struct flex_line_data *data;
+ } line;
+};
+
+static void layout_flex_ctx__destroy(struct flex_ctx *ctx)
+{
+ if (ctx != NULL) {
+ free(ctx->item.data);
+ free(ctx->line.data);
+ free(ctx);
+ }
+}
+
+static struct flex_ctx *layout_flex_ctx__create(
+ html_content *content,
+ const struct box *flex)
+{
+ struct flex_ctx *ctx;
+
+ ctx = calloc(1, sizeof(*ctx));
+ if (ctx == NULL) {
+ return NULL;
+ }
+ ctx->line.alloc = 1;
+
+ ctx->item.count = box_count_children(flex);
+ ctx->item.data = calloc(ctx->item.count, sizeof(*ctx->item.data));
+ if (ctx->item.data == NULL) {
+ layout_flex_ctx__destroy(ctx);
+ return NULL;
+ }
+
+ ctx->line.alloc = 1;
+ ctx->line.data = calloc(ctx->line.alloc, sizeof(*ctx->line.data));
+ if (ctx->line.data == NULL) {
+ layout_flex_ctx__destroy(ctx);
+ return NULL;
+ }
+
+ ctx->flex = flex;
+ ctx->content = content;
+ ctx->unit_len_ctx = &content->unit_len_ctx;
+
+ ctx->wrap = css_computed_flex_wrap(flex->style);
+ ctx->horizontal = layout_flex__main_is_horizontal(flex);
+
+ return ctx;
+}
+
+static bool layout_flex_item(
+ const struct flex_ctx *ctx,
+ const struct flex_item_data *item,
+ int available_width)
+{
+ bool success;
+ struct box *b = item->box;
+
+ switch (b->type) {
+ case BOX_BLOCK:
+ success = layout_block_context(b, -1,
+ ctx->content);
+ break;
+ case BOX_TABLE:
+ b->float_container = b->parent;
+ success = layout_table(b, available_width,
+ ctx->content);
+ b->float_container = NULL;
+ break;
+ case BOX_FLEX:
+ b->float_container = b->parent;
+ success = layout_flex(b, available_width,
+ ctx->content);
+ b->float_container = NULL;
+ break;
+ default:
+ assert(0 && "Bad flex item back type");
+ success = false;
+ break;
+ }
+
+ return success;
+}
+
+static inline bool layout_flex__base_and_main_sizes(
+ const struct flex_ctx *ctx,
+ struct flex_item_data *item,
+ int available_width)
+{
+ struct box *b = item->box;
+ int content_min_width = b->min_width;
+ int content_max_width = b->max_width;
+ int delta_outer_main = lh__delta_outer_main(ctx->flex, b);
+
+ NSLOG(flex, WARNING, "box %p: delta_outer_main: %i",
+ b, delta_outer_main);
+
+ if (item->basis == CSS_FLEX_BASIS_SET) {
+ if (item->basis_unit == CSS_UNIT_PCT) {
+ item->base_size = FPCT_OF_INT_TOINT(
+ item->basis_length,
+ available_width);
+ } else {
+ item->base_size = FIXTOINT(css_unit_len2device_px(
+ b->style, ctx->unit_len_ctx,
+ item->basis_length,
+ item->basis_unit));
+ }
+
+ } else if (item->basis == CSS_FLEX_BASIS_AUTO) {
+ item->base_size = ctx->horizontal ? b->width : b->height;
+ } else {
+ item->base_size = AUTO;
+ }
+
+ if (ctx->horizontal == false) {
+ if (b->width == AUTO) {
+ b->width = min(available_width, content_max_width);
+ b->width -= lh__delta_outer_width(b);
+ }
+
+ if (!layout_flex_item(ctx, item, b->width)) {
+ NSLOG(flex, WARNING, "box %p: layout failed", b);
+ return false;
+ }
+ }
+
+ if (item->base_size == AUTO) {
+ if (ctx->horizontal == false) {
+ item->base_size = b->height;
+ } else {
+ item->base_size = content_max_width - delta_outer_main;
+ }
+ }
+
+ item->base_size += delta_outer_main;
+
+ if (ctx->horizontal) {
+ item->base_size = min(item->base_size, available_width);
+ item->base_size = max(item->base_size, content_min_width);
+ }
+
+ item->target_main_size = item->base_size;
+ item->main_size = item->base_size;
+
+ if (item->max_main > 0 &&
+ item->main_size > item->max_main + delta_outer_main) {
+ item->main_size = item->max_main + delta_outer_main;
+ }
+
+ if (item->main_size < item->min_main + delta_outer_main) {
+ item->main_size = item->min_main + delta_outer_main;
+ }
+
+ NSLOG(flex, WARNING, "flex-item box: %p: base_size: %i, main_size %i",
+ b, item->base_size, item->main_size);
+
+ return true;
+}
+
+static void layout_flex_ctx__populate_item_data(
+ const struct flex_ctx *ctx,
+ const struct box *flex,
+ int available_width)
+{
+ size_t i = 0;
+ bool horizontal = ctx->horizontal;
+
+ for (struct box *b = flex->children; b != NULL; b = b->next) {
+ struct flex_item_data *item = &ctx->item.data[i++];
+
+ b->float_container = b->parent;
+ layout_find_dimensions(ctx->unit_len_ctx, available_width, -1,
+ b, b->style, &b->width, &b->height,
+ horizontal ? &item->max_main : &item->max_cross,
+ horizontal ? &item->min_main : &item->min_cross,
+ horizontal ? &item->max_cross : &item->max_main,
+ horizontal ? &item->min_cross : &item->min_main,
+ b->margin, b->padding, b->border);
+ b->float_container = NULL;
+
+ NSLOG(flex, WARNING, "flex-item box: %p: width: %i",
+ b, b->width);
+
+ item->box = b;
+ item->basis = css_computed_flex_basis(b->style,
+ &item->basis_length, &item->basis_unit);
+
+ css_computed_flex_shrink(b->style, &item->shrink);
+ css_computed_flex_grow(b->style, &item->grow);
+
+ layout_flex__base_and_main_sizes(ctx, item, available_width);
+ }
+}
+
+static bool layout_flex_ctx__ensure_line(struct flex_ctx *ctx)
+{
+ struct flex_line_data *temp;
+ size_t line_alloc = ctx->line.alloc * 2;
+
+ if (ctx->line.alloc > ctx->line.count) {
+ return true;
+ }
+
+ temp = realloc(ctx->line.data, sizeof(*ctx->line.data) * line_alloc);
+ if (temp == NULL) {
+ return false;
+ }
+ ctx->line.data = temp;
+
+ memset(ctx->line.data + ctx->line.alloc, 0,
+ sizeof(*ctx->line.data) * (line_alloc - ctx->line.alloc));
+ ctx->line.alloc = line_alloc;
+
+ return true;
+}
+
+static struct flex_line_data *layout_flex__build_line(struct flex_ctx *ctx,
+ size_t item_index, int available_width, html_content *content)
+{
+ struct flex_line_data *line;
+ int available_main;
+ int used_main = 0;
+
+ if (!layout_flex_ctx__ensure_line(ctx)) {
+ return 0;
+ }
+
+ line = &ctx->line.data[ctx->line.count];
+ line->first = item_index;
+
+ if (ctx->horizontal) {
+ available_main = available_width;
+ } else {
+ available_main = ctx->flex->height;
+ }
+
+ NSLOG(flex, WARNING, "flex container %p: available main: %i",
+ ctx->flex, available_main);
+
+ while (item_index < ctx->item.count) {
+ struct flex_item_data *item = &ctx->item.data[item_index];
+ struct box *b = item->box;
+ int main;
+
+ main = ctx->horizontal ?
+ item->main_size :
+ b->height + lh__delta_outer_main(ctx->flex, b);
+
+ if (ctx->wrap == CSS_FLEX_WRAP_NOWRAP ||
+ main + used_main <= available_main ||
+ lh__box_is_absolute(item->box) ||
+ available_main == AUTO ||
+ line->count == 0 ||
+ main == 0) {
+ if (lh__box_is_absolute(item->box) == false) {
+ line->main_size += item->main_size;
+ used_main += main;
+ }
+ item->line = ctx->line.count;
+ line->count++;
+ item_index++;
+ } else {
+ break;
+ }
+ }
+
+ if (line->count > 0) {
+ ctx->line.count++;
+ } else {
+ NSLOG(layout, ERROR, "Failed to fit any flex items");
+ }
+
+ return line;
+}
+
+static inline void layout_flex__item_freeze(
+ struct flex_line_data *line,
+ struct flex_item_data *item)
+{
+ item->freeze = true;
+ line->frozen++;
+
+ NSLOG(flex, WARNING, "flex-item box: %p: Frozen at target_main_size:
%i",
+ item->box, item->target_main_size);
+}
+
+static inline int layout_flex__remaining_free_space(
+ struct flex_ctx *ctx,
+ struct flex_line_data *line,
+ css_fixed *unfrozen_factor_sum,
+ int initial_free_space,
+ int available_space,
+ bool grow)
+{
+ int remaining_free_space = available_space;
+ size_t item_count = line->first + line->count;
+
+ *unfrozen_factor_sum = 0;
+
+ for (size_t i = line->first; i < item_count; i++) {
+ struct flex_item_data *item = &ctx->item.data[i];
+
+ if (item->freeze) {
+ remaining_free_space -= item->target_main_size;
+ } else {
+ remaining_free_space -= item->base_size;
+
+ *unfrozen_factor_sum += grow ?
+ item->grow : item->shrink;
+ }
+ }
+
+ if (*unfrozen_factor_sum < F_1) {
+ int free_space = FIXTOINT(FMUL(INTTOFIX(initial_free_space),
+ *unfrozen_factor_sum));
+
+ if (free_space < remaining_free_space) {
+ remaining_free_space = free_space;
+ }
+ }
+
+ NSLOG(flex, WARNING, "Remaining free space: %i", remaining_free_space);
+
+ return remaining_free_space;
+}
+
+static inline int layout_flex__get_min_max_violations(
+ struct flex_ctx *ctx,
+ struct flex_line_data *line)
+{
+
+ int total_violation = 0;
+ size_t item_count = line->first + line->count;
+
+ for (size_t i = line->first; i < item_count; i++) {
+ struct flex_item_data *item = &ctx->item.data[i];
+ int target_main_size = item->target_main_size;
+
+ NSLOG(flex, WARNING, "item %p: target_main_size: %i",
+ item->box, target_main_size);
+
+ if (item->freeze) {
+ continue;
+ }
+
+ if (item->max_main > 0 &&
+ target_main_size > item->max_main) {
+ target_main_size = item->max_main;
+ item->max_violation = true;
+ NSLOG(flex, WARNING, "Violation: max_main: %i",
+ item->max_main);
+ }
+
+ if (target_main_size < item->min_main) {
+ target_main_size = item->min_main;
+ item->min_violation = true;
+ NSLOG(flex, WARNING, "Violation: min_main: %i",
+ item->min_main);
+ }
+
+ if (target_main_size < item->box->min_width) {
+ target_main_size = item->box->min_width;
+ item->min_violation = true;
+ NSLOG(flex, WARNING, "Violation: box min_width: %i",
+ item->box->min_width);
+ }
+
+ if (target_main_size < 0) {
+ target_main_size = 0;
+ item->min_violation = true;
+ NSLOG(flex, WARNING, "Violation: less than 0");
+ }
+
+ total_violation += target_main_size - item->target_main_size;
+ item->target_main_size = target_main_size;
+ }
+
+ NSLOG(flex, WARNING, "Total violation: %i", total_violation);
+
+ return total_violation;
+}
+
+static inline void layout_flex__distribute_free_space(
+ struct flex_ctx *ctx,
+ struct flex_line_data *line,
+ css_fixed unfrozen_factor_sum,
+ int remaining_free_space,
+ bool grow)
+{
+ size_t item_count = line->first + line->count;
+
+ if (grow) {
+ for (size_t i = line->first; i < item_count; i++) {
+ struct flex_item_data *item = &ctx->item.data[i];
+ css_fixed ratio;
+
+ if (item->freeze) {
+ continue;
+ }
+
+ ratio = FDIV(item->grow, unfrozen_factor_sum);
+
+ item->target_main_size = item->base_size +
+ FIXTOINT(FMUL(
+ INTTOFIX(remaining_free_space),
+ ratio));
+ }
+ } else {
+ css_fixed scaled_shrink_factor_sum = 0;
+
+ for (size_t i = line->first; i < item_count; i++) {
+ struct flex_item_data *item = &ctx->item.data[i];
+ css_fixed scaled_shrink_factor;
+
+ if (item->freeze) {
+ continue;
+ }
+
+ scaled_shrink_factor = FMUL(
+ item->shrink,
+ INTTOFIX(item->base_size));
+ scaled_shrink_factor_sum += scaled_shrink_factor;
+ }
+
+ for (size_t i = line->first; i < item_count; i++) {
+ struct flex_item_data *item = &ctx->item.data[i];
+ css_fixed scaled_shrink_factor;
+ css_fixed ratio;
+
+ if (item->freeze) {
+ continue;
+ } else if (scaled_shrink_factor_sum == 0) {
+ item->target_main_size = item->main_size;
+ layout_flex__item_freeze(line, item);
+ continue;
+ }
+
+ scaled_shrink_factor = FMUL(
+ item->shrink,
+ INTTOFIX(item->base_size));
+ ratio = FDIV(scaled_shrink_factor,
+ scaled_shrink_factor_sum);
+
+ item->target_main_size = item->base_size -
+ FIXTOINT(FMUL(
+ INTTOFIX(abs(remaining_free_space)),
+ ratio));
+ }
+ }
+}
+
+static bool layout_flex__resolve_line_horizontal(
+ struct flex_ctx *ctx,
+ struct flex_line_data *line,
+ int available_width)
+{
+ size_t item_count = line->first + line->count;
+ int x = ctx->flex->padding[LEFT];
+
+ for (size_t i = line->first; i < item_count; i++) {
+ struct flex_item_data *item = &ctx->item.data[i];
+ struct box *b = item->box;
+ bool success = false;
+
+ b->width = item->target_main_size - lh__delta_outer_width(b);
+
+ success = layout_flex_item(ctx, item, b->width);
+ if (!success) {
+ NSLOG(flex, WARNING, "box %p: layout failed", b);
+ return false;
+ }
+
+ b->y = ctx->flex->padding[TOP] + ctx->cross_size +
+ lh__non_auto_margin(b, TOP) +
+ b->border[TOP].width;
+
+ b->x = x + lh__non_auto_margin(b, LEFT) +
+ b->border[LEFT].width;
+
+ if (lh__box_is_absolute(b) == false) {
+ int height;
+
+ height = b->height + lh__delta_outer_height(b);
+ if (line->cross_size < height) {
+ line->cross_size = height;
+ }
+
+ x += b->width + lh__delta_outer_width(b);
+ }
+ }
+
+ return true;
+}
+
+static bool layout_flex__resolve_line_vertical(
+ struct flex_ctx *ctx,
+ struct flex_line_data *line,
+ int available_width)
+{
+ size_t item_count = line->first + line->count;
+ int y = ctx->flex->padding[TOP];
+
+ for (size_t i = line->first; i < item_count; i++) {
+ struct flex_item_data *item = &ctx->item.data[i];
+ struct box *b = item->box;
+
+ b->x = ctx->flex->padding[LEFT] + ctx->cross_size +
+ lh__non_auto_margin(b, LEFT) +
+ b->border[LEFT].width;
+
+ b->y = y + lh__non_auto_margin(b, TOP) +
+ b->border[TOP].width;
+
+ if (lh__box_is_absolute(b) == false) {
+ int width;
+
+ width = b->width + lh__delta_outer_width(b);
+ if (line->cross_size < width) {
+ line->cross_size = width;
+ }
+
+ y += b->height + lh__delta_outer_height(b);
+ }
+ }
+
+ return true;
+}
+
+/** 9.7. Resolving Flexible Lengths */
+static bool layout_flex__resolve_line(
+ struct flex_ctx *ctx,
+ struct flex_line_data *line,
+ int available_width)
+{
+ bool grow = (line->main_size < available_width);
+ size_t item_count = line->first + line->count;
+ int available_space = available_width;
+ int initial_free_space;
+
+ available_space = available_width;
+ if (ctx->horizontal == false) {
+ available_space = ctx->flex->height;
+ if (available_space == AUTO) {
+ available_space = INT_MAX;
+ }
+ }
+
+ initial_free_space = available_space;
+
+ NSLOG(flex, WARNING, "box %p: line %zu: first: %zu, count: %zu",
+ ctx->flex, line - ctx->line.data,
+ line->first, line->count);
+ NSLOG(flex, WARNING, "Line main_size: %i, available_space: %i",
+ line->main_size, available_space);
+
+ for (size_t i = line->first; i < item_count; i++) {
+ struct flex_item_data *item = &ctx->item.data[i];
+
+ /* 3. Size inflexible items */
+ if (grow) {
+ if (item->grow == 0 ||
+ item->base_size > item->main_size) {
+ item->target_main_size = item->main_size;
+ layout_flex__item_freeze(line, item);
+ }
+ } else {
+ if (item->shrink == 0 ||
+ item->base_size < item->main_size) {
+ item->target_main_size = item->main_size;
+ layout_flex__item_freeze(line, item);
+ }
+ }
+
+ /* 4. Calculate initial free space */
+ if (item->freeze) {
+ initial_free_space -= item->target_main_size;
+ } else {
+ initial_free_space -= item->base_size;
+ }
+ }
+
+ /* 5. Loop */
+ while (line->frozen < line->count) {
+ css_fixed unfrozen_factor_sum;
+ int remaining_free_space;
+ int total_violation;
+
+ NSLOG(flex, WARNING, "flex-container: %p: Resolver pass",
+ ctx->flex);
+
+ /* b */
+ remaining_free_space = layout_flex__remaining_free_space(ctx,
+ line, &unfrozen_factor_sum, initial_free_space,
+ available_space, grow);
+
+ /* c */
+ if (remaining_free_space != 0) {
+ layout_flex__distribute_free_space(ctx,
+ line, unfrozen_factor_sum,
+ remaining_free_space, grow);
+ }
+
+ /* d */
+ total_violation = layout_flex__get_min_max_violations(
+ ctx, line);
+
+ /* e */
+ for (size_t i = line->first; i < item_count; i++) {
+ struct flex_item_data *item = &ctx->item.data[i];
+
+ if (total_violation == 0 ||
+ (total_violation > 0 && item->min_violation) ||
+ (total_violation < 0 && item->max_violation)) {
+ layout_flex__item_freeze(line, item);
+ }
+ }
+ }
+
+ if (ctx->horizontal) {
+ if (!layout_flex__resolve_line_horizontal(ctx,
+ line, available_width)) {
+ return false;
+ }
+ } else {
+ if (!layout_flex__resolve_line_vertical(ctx,
+ line, available_width)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+static bool layout_flex__collect_items_into_lines(
+ struct flex_ctx *ctx,
+ int available_width,
+ html_content *content)
+{
+ size_t pos = 0;
+
+ while (pos < ctx->item.count) {
+ struct flex_line_data *line;
+
+ line = layout_flex__build_line(ctx, pos,
+ available_width, content);
+ if (line == NULL) {
+ return false;
+ }
+
+ pos += line->count;
+
+ NSLOG(flex, WARNING, "flex-container: %p: "
+ "fitted: %zu (total: %zu/%zu)",
+ ctx->flex, line->count,
+ pos, ctx->item.count);
+
+ if (!layout_flex__resolve_line(ctx, line, available_width)) {
+ return false;
+ }
+
+ ctx->cross_size += line->cross_size;
+ if (ctx->main_size < line->main_size) {
+ ctx->main_size = line->main_size;
+ }
+ }
+
+ return true;
+}
+
+/**
+ * Layout a flex container.
+ *
+ * \param[in] flex table to layout
+ * \param[in] available_width width of containing block
+ * \param[in] content memory pool for any new boxes
+ * \return true on success, false on memory exhaustion
+ */
+bool layout_flex(struct box *flex, int available_width,
+ html_content *content)
+{
+ int max_height, min_height;
+ struct flex_ctx *ctx;
+ bool success = false;
+
+ ctx = layout_flex_ctx__create(content, flex);
+ if (ctx == NULL) {
+ return false;
+ }
+
+ NSLOG(flex, WARNING, "box %p: %s, available_width %i, width: %i", flex,
+ ctx->horizontal ? "horizontal" : "vertical",
+ available_width, flex->width);
+
+ layout_find_dimensions(
+ ctx->unit_len_ctx, available_width, -1,
+ flex, flex->style, NULL, &flex->height,
+ NULL, NULL, &max_height, &min_height,
+ flex->margin, flex->padding, flex->border);
+
+ available_width = min(available_width, flex->width);
+
+ layout_flex_ctx__populate_item_data(ctx, flex, available_width);
+
+ /* Place items onto lines. */
+ success = layout_flex__collect_items_into_lines(ctx,
+ available_width, content);
+ if (!success) {
+ goto cleanup;
+ }
+
+ if (flex->height == AUTO) {
+ flex->height = ctx->horizontal ?
+ ctx->cross_size :
+ ctx->main_size;
+ }
+
+ if (flex->height != AUTO) {
+ if (max_height >= 0 && flex->height > max_height) {
+ flex->height = max_height;
+ }
+ if (min_height > 0 && flex->height < min_height) {
+ flex->height = min_height;
+ }
+ }
+
+ success = true;
+
+cleanup:
+ layout_flex_ctx__destroy(ctx);
+
+ NSLOG(flex, WARNING, "box %p: %s", flex,
+ success ? "success" : "failure");
+ return success;
+}
diff --git a/content/handlers/html/layout_internal.h
b/content/handlers/html/layout_internal.h
index 39b42b1..75d6de7 100644
--- a/content/handlers/html/layout_internal.h
+++ b/content/handlers/html/layout_internal.h
@@ -106,11 +106,25 @@ static inline bool lh__box_is_float_box(const struct box
*b)
static inline bool lh__box_is_inline_flow(const struct box *b)
{
return b->type == BOX_INLINE ||
+ b->type == BOX_INLINE_FLEX ||
b->type == BOX_INLINE_BLOCK ||
b->type == BOX_TEXT ||
b->type == BOX_INLINE_END;
}
+/** Layout helper: Check whether box takes part in inline flow. */
+static inline bool lh__box_is_flex_container(const struct box *b)
+{
+ return b->type == BOX_FLEX ||
+ b->type == BOX_INLINE_FLEX;
+}
+
+/** Layout helper: Check whether box takes part in inline flow. */
+static inline bool lh__box_is_flex_item(const struct box *b)
+{
+ return (b->parent != NULL) && lh__box_is_flex_container(b->parent);
+}
+
/** Layout helper: Check whether box is inline level. (Includes BR.) */
static inline bool lh__box_is_inline_level(const struct box *b)
{
@@ -147,6 +161,76 @@ static inline bool lh__have_border(
return border_style_funcs[side](style) != CSS_BORDER_STYLE_NONE;
}
+static inline bool lh__box_is_absolute(const struct box *b)
+{
+ return css_computed_position(b->style) == CSS_POSITION_ABSOLUTE ||
+ css_computed_position(b->style) == CSS_POSITION_FIXED;
+}
+
+static inline bool layout_flex__main_is_horizontal(const struct box *flex)
+{
+ const css_computed_style *style = flex->style;
+
+ assert(style != NULL);
+
+ switch (css_computed_flex_direction(style)) {
+ default: /* Fallthrough. */
+ case CSS_FLEX_DIRECTION_ROW: /* Fallthrough. */
+ case CSS_FLEX_DIRECTION_ROW_REVERSE:
+ return true;
+ case CSS_FLEX_DIRECTION_COLUMN: /* Fallthrough. */
+ case CSS_FLEX_DIRECTION_COLUMN_REVERSE:
+ return false;
+ }
+}
+
+static inline int lh__non_auto_margin(const struct box *b, enum box_side side)
+{
+ return (b->margin[side] == AUTO) ? 0 : b->margin[side];
+}
+
+static inline int lh__delta_outer_height(const struct box *b)
+{
+ return b->padding[TOP] +
+ b->padding[BOTTOM] +
+ b->border[TOP].width +
+ b->border[BOTTOM].width +
+ lh__non_auto_margin(b, TOP) +
+ lh__non_auto_margin(b, BOTTOM);
+}
+
+static inline int lh__delta_outer_width(const struct box *b)
+{
+ return b->padding[LEFT] +
+ b->padding[RIGHT] +
+ b->border[LEFT].width +
+ b->border[RIGHT].width +
+ lh__non_auto_margin(b, LEFT) +
+ lh__non_auto_margin(b, RIGHT);
+}
+
+static inline int lh__delta_outer_main(
+ const struct box *flex,
+ const struct box *b)
+{
+ if (layout_flex__main_is_horizontal(flex)) {
+ return lh__delta_outer_width(b);
+ } else {
+ return lh__delta_outer_height(b);
+ }
+}
+
+static inline int lh__delta_outer_cross(
+ const struct box *flex,
+ const struct box *b)
+{
+ if (layout_flex__main_is_horizontal(flex) == false) {
+ return lh__delta_outer_width(b);
+ } else {
+ return lh__delta_outer_height(b);
+ }
+}
+
/**
* Determine width of margin, borders, and padding on one side of a box.
*
commitdiff
http://git.netsurf-browser.org/netsurf.git/commit/?id=4bde73fce3b188b87384cba8beb108907fafacb2
commit 4bde73fce3b188b87384cba8beb108907fafacb2
Author: Michael Drake <[email protected]>
Commit: Michael Drake <[email protected]>
html: box_dump: Indicate descendant bounding box values
diff --git a/content/handlers/html/box_inspect.c
b/content/handlers/html/box_inspect.c
index b4b1394..b6b9f81 100644
--- a/content/handlers/html/box_inspect.c
+++ b/content/handlers/html/box_inspect.c
@@ -660,7 +660,7 @@ void box_dump(FILE *stream, struct box *box, unsigned int
depth, bool style)
if (box->max_width != UNKNOWN_MAX_WIDTH) {
fprintf(stream, "min%i max%i ", box->min_width, box->max_width);
}
- fprintf(stream, "(%i %i %i %i) ",
+ fprintf(stream, "desc(%i %i %i %i) ",
box->descendant_x0, box->descendant_y0,
box->descendant_x1, box->descendant_y1);
commitdiff
http://git.netsurf-browser.org/netsurf.git/commit/?id=db083bdd61c9395b3a48ae67dd63b59f64092468
commit db083bdd61c9395b3a48ae67dd63b59f64092468
Author: Michael Drake <[email protected]>
Commit: Michael Drake <[email protected]>
layout: minmax pass: Improve handling of {min|max}_width properties
diff --git a/content/handlers/html/layout.c b/content/handlers/html/layout.c
index f632bdc..816775c 100644
--- a/content/handlers/html/layout.c
+++ b/content/handlers/html/layout.c
@@ -895,6 +895,8 @@ static void layout_minmax_block(
css_fixed height = 0;
css_unit hunit = CSS_UNIT_PX;
enum css_box_sizing_e bs = CSS_BOX_SIZING_CONTENT_BOX;
+ bool using_min_border_box = false;
+ bool using_max_border_box = false;
bool child_has_height = false;
assert(block->type == BOX_BLOCK ||
@@ -1030,23 +1032,40 @@ static void layout_minmax_block(
}
/* fixed width takes priority */
- if (block->type != BOX_TABLE_CELL && wtype == CSS_WIDTH_SET &&
- wunit != CSS_UNIT_PCT) {
- min = max = FIXTOINT(css_unit_len2device_px(block->style,
- &content->unit_len_ctx, width, wunit));
- if (bs == CSS_BOX_SIZING_BORDER_BOX) {
- int border_box_fixed = 0;
- float border_box_frac = 0;
- calculate_mbp_width(&content->unit_len_ctx,
- block->style, LEFT,
- false, true, true,
- &border_box_fixed, &border_box_frac);
- calculate_mbp_width(&content->unit_len_ctx,
- block->style, RIGHT,
- false, true, true,
- &border_box_fixed, &border_box_frac);
- if (min < border_box_fixed) {
- min = max = border_box_fixed;
+ if (block->type != BOX_TABLE_CELL) {
+ bool border_box = bs == CSS_BOX_SIZING_BORDER_BOX;
+ enum css_max_width_e max_type;
+ enum css_min_width_e min_type;
+ css_unit unit = CSS_UNIT_PX;
+ css_fixed value = 0;
+
+ if (wtype == CSS_WIDTH_SET && wunit != CSS_UNIT_PCT) {
+ min = max = FIXTOINT(
+ css_unit_len2device_px(block->style,
+ &content->unit_len_ctx, width, wunit));
+ using_max_border_box = border_box;
+ using_min_border_box = border_box;
+ }
+
+ min_type = css_computed_min_width(block->style, &value, &unit);
+ if (min_type == CSS_MIN_WIDTH_SET && unit != CSS_UNIT_PCT) {
+ int val = FIXTOINT(css_unit_len2device_px(block->style,
+ &content->unit_len_ctx, value, unit));
+
+ if (min < val) {
+ min = val;
+ using_min_border_box = border_box;
+ }
+ }
+
+ max_type = css_computed_max_width(block->style, &value, &unit);
+ if (max_type == CSS_MAX_WIDTH_SET && unit != CSS_UNIT_PCT) {
+ int val = FIXTOINT(css_unit_len2device_px(block->style,
+ &content->unit_len_ctx, value, unit));
+
+ if (val >= 0 && max > val) {
+ max = val;
+ using_max_border_box = border_box;
}
}
}
@@ -1060,22 +1079,30 @@ static void layout_minmax_block(
/* add margins, border, padding to min, max widths */
/* Note: we don't know available width here so percentage margin
* and paddings are wrong. */
- if (bs == CSS_BOX_SIZING_BORDER_BOX && wtype == CSS_WIDTH_SET) {
- /* Border and padding included in width, so just get margin */
- calculate_mbp_width(&content->unit_len_ctx,
- block->style, LEFT, true, false, false,
- &extra_fixed, &extra_frac);
- calculate_mbp_width(&content->unit_len_ctx,
- block->style, RIGHT, true, false, false,
- &extra_fixed, &extra_frac);
- } else {
- calculate_mbp_width(&content->unit_len_ctx,
- block->style, LEFT, true, true, true,
- &extra_fixed, &extra_frac);
- calculate_mbp_width(&content->unit_len_ctx,
- block->style, RIGHT, true, true, true,
- &extra_fixed, &extra_frac);
+ calculate_mbp_width(&content->unit_len_ctx, block->style, LEFT,
+ false, true, true, &extra_fixed, &extra_frac);
+ calculate_mbp_width(&content->unit_len_ctx, block->style, RIGHT,
+ false, true, true, &extra_fixed, &extra_frac);
+
+ if (using_max_border_box) {
+ max -= extra_fixed;
+ max = max(max, 0);
+ }
+
+ if (using_min_border_box) {
+ min -= extra_fixed;
+ min = max(min, 0);
}
+
+ if (max < min) {
+ min = max;
+ }
+
+ calculate_mbp_width(&content->unit_len_ctx, block->style, LEFT,
+ true, false, false, &extra_fixed, &extra_frac);
+ calculate_mbp_width(&content->unit_len_ctx, block->style, RIGHT,
+ true, false, false, &extra_fixed, &extra_frac);
+
if (extra_fixed < 0)
extra_fixed = 0;
if (extra_frac < 0)
commitdiff
http://git.netsurf-browser.org/netsurf.git/commit/?id=4b18dd0bdc55dd73ed1a43e06a697266d0ed5590
commit 4b18dd0bdc55dd73ed1a43e06a697266d0ed5590
Author: Michael Drake <[email protected]>
Commit: Michael Drake <[email protected]>
layout: minmax table: Change logging level to error
diff --git a/content/handlers/html/layout.c b/content/handlers/html/layout.c
index 9fe93a7..f632bdc 100644
--- a/content/handlers/html/layout.c
+++ b/content/handlers/html/layout.c
@@ -283,7 +283,7 @@ static void layout_minmax_table(struct box *table,
return;
if (table_calculate_column_types(&content->unit_len_ctx, table) ==
false) {
- NSLOG(netsurf, WARNING,
+ NSLOG(netsurf, ERROR,
"Could not establish table column types.");
return;
}
commitdiff
http://git.netsurf-browser.org/netsurf.git/commit/?id=fac0e16a3431c9ae320fe798f82f0e504c915389
commit fac0e16a3431c9ae320fe798f82f0e504c915389
Author: Michael Drake <[email protected]>
Commit: Michael Drake <[email protected]>
layout: calculate_mbp_width: Preserve percentage values
diff --git a/content/handlers/html/layout_internal.h
b/content/handlers/html/layout_internal.h
index 0c171ef..39b42b1 100644
--- a/content/handlers/html/layout_internal.h
+++ b/content/handlers/html/layout_internal.h
@@ -181,7 +181,7 @@ static inline void calculate_mbp_width(
type = margin_funcs[side](style, &value, &unit);
if (type == CSS_MARGIN_SET) {
if (unit == CSS_UNIT_PCT) {
- *frac += FIXTOINT(FDIV(value, F_100));
+ *frac += FIXTOFLT(FDIV(value, F_100));
} else {
*fixed += FIXTOINT(css_unit_len2device_px(
style, unit_len_ctx,
@@ -205,7 +205,7 @@ static inline void calculate_mbp_width(
if (padding) {
padding_funcs[side](style, &value, &unit);
if (unit == CSS_UNIT_PCT) {
- *frac += FIXTOINT(FDIV(value, F_100));
+ *frac += FIXTOFLT(FDIV(value, F_100));
} else {
*fixed += FIXTOINT(css_unit_len2device_px(
style, unit_len_ctx,
commitdiff
http://git.netsurf-browser.org/netsurf.git/commit/?id=d24835c56634bc687698ef48e650a4ceadbaf636
commit d24835c56634bc687698ef48e650a4ceadbaf636
Author: Michael Drake <[email protected]>
Commit: Michael Drake <[email protected]>
log: Add flex logging catagory
diff --git a/utils/log.c b/utils/log.c
index 68b188e..8cc42a3 100644
--- a/utils/log.c
+++ b/utils/log.c
@@ -99,6 +99,7 @@ NSLOG_DEFINE_CATEGORY(plot, "Rendering system");
NSLOG_DEFINE_CATEGORY(schedule, "Scheduler");
NSLOG_DEFINE_CATEGORY(fbtk, "Framebuffer toolkit");
NSLOG_DEFINE_CATEGORY(layout, "Layout");
+NSLOG_DEFINE_CATEGORY(flex, "Flex");
NSLOG_DEFINE_CATEGORY(dukky, "Duktape JavaScript Binding");
NSLOG_DEFINE_CATEGORY(jserrors, "JavaScript error messages");
diff --git a/utils/log.h b/utils/log.h
index 02a886c..b7aa833 100644
--- a/utils/log.h
+++ b/utils/log.h
@@ -84,6 +84,7 @@ NSLOG_DECLARE_CATEGORY(plot);
NSLOG_DECLARE_CATEGORY(schedule);
NSLOG_DECLARE_CATEGORY(fbtk);
NSLOG_DECLARE_CATEGORY(layout);
+NSLOG_DECLARE_CATEGORY(flex);
NSLOG_DECLARE_CATEGORY(dukky);
NSLOG_DECLARE_CATEGORY(jserrors);
commitdiff
http://git.netsurf-browser.org/netsurf.git/commit/?id=a6b7b8e38833e7d8d5f4bffc454d7418e491481b
commit a6b7b8e38833e7d8d5f4bffc454d7418e491481b
Author: Michael Drake <[email protected]>
Commit: Michael Drake <[email protected]>
html: layout: Improve block container assertions
diff --git a/content/handlers/html/layout.c b/content/handlers/html/layout.c
index 99e9bcf..9fe93a7 100644
--- a/content/handlers/html/layout.c
+++ b/content/handlers/html/layout.c
@@ -4433,9 +4433,9 @@ layout_compute_offsets(const css_unit_ctx *unit_len_ctx,
css_fixed value = 0;
css_unit unit = CSS_UNIT_PX;
- assert(containing_block->width != UNKNOWN_WIDTH &&
- containing_block->width != AUTO &&
- containing_block->height != AUTO);
+ assert(containing_block->width != UNKNOWN_WIDTH);
+ assert(containing_block->width != AUTO);
+ assert(containing_block->height != AUTO);
/* left */
type = css_computed_left(box->style, &value, &unit);
commitdiff
http://git.netsurf-browser.org/netsurf.git/commit/?id=e455f157f3e4c8cd8c6e3ef4730d95dbf95b9528
commit e455f157f3e4c8cd8c6e3ef4730d95dbf95b9528
Author: Michael Drake <[email protected]>
Commit: Michael Drake <[email protected]>
html: layout: Split out common helpers
diff --git a/content/handlers/html/layout.c b/content/handlers/html/layout.c
index cb5be5d..99e9bcf 100644
--- a/content/handlers/html/layout.c
+++ b/content/handlers/html/layout.c
@@ -67,13 +67,9 @@
#include "html/font.h"
#include "html/form_internal.h"
#include "html/layout.h"
+#include "html/layout_internal.h"
#include "html/table.h"
-#define AUTO INT_MIN
-
-/* Fixed point percentage (a) of an integer (b), to an integer */
-#define FPCT_OF_INT_TOINT(a, b) (FIXTOINT(FDIV((a * b), F_100)))
-
typedef uint8_t (*css_len_func)(
const css_computed_style *style,
css_fixed *length, css_unit *unit);
@@ -84,7 +80,7 @@ typedef uint8_t (*css_border_color_func)(
css_color *color);
/** Array of per-side access functions for computed style margins. */
-static const css_len_func margin_funcs[4] = {
+const css_len_func margin_funcs[4] = {
[TOP] = css_computed_margin_top,
[RIGHT] = css_computed_margin_right,
[BOTTOM] = css_computed_margin_bottom,
@@ -92,7 +88,7 @@ static const css_len_func margin_funcs[4] = {
};
/** Array of per-side access functions for computed style paddings. */
-static const css_len_func padding_funcs[4] = {
+const css_len_func padding_funcs[4] = {
[TOP] = css_computed_padding_top,
[RIGHT] = css_computed_padding_right,
[BOTTOM] = css_computed_padding_bottom,
@@ -100,7 +96,7 @@ static const css_len_func padding_funcs[4] = {
};
/** Array of per-side access functions for computed style border_widths. */
-static const css_len_func border_width_funcs[4] = {
+const css_len_func border_width_funcs[4] = {
[TOP] = css_computed_border_top_width,
[RIGHT] = css_computed_border_right_width,
[BOTTOM] = css_computed_border_bottom_width,
@@ -108,67 +104,15 @@ static const css_len_func border_width_funcs[4] = {
};
/** Array of per-side access functions for computed style border styles. */
-static const css_border_style_func border_style_funcs[4] = {
+const css_border_style_func border_style_funcs[4] = {
[TOP] = css_computed_border_top_style,
[RIGHT] = css_computed_border_right_style,
[BOTTOM] = css_computed_border_bottom_style,
[LEFT] = css_computed_border_left_style,
};
-/** Layout helper: Check for CSS border on given side. */
-static inline bool lh__have_border(
- enum box_side side,
- const css_computed_style *style)
-{
- return border_style_funcs[side](style) != CSS_BORDER_STYLE_NONE;
-}
-
-/** Layout helper: Check whether box is a float. */
-static inline bool lh__box_is_float_box(const struct box *b)
-{
- return b->type == BOX_FLOAT_LEFT ||
- b->type == BOX_FLOAT_RIGHT;
-}
-
-/** Layout helper: Check whether box takes part in inline flow. */
-static inline bool lh__box_is_inline_flow(const struct box *b)
-{
- return b->type == BOX_INLINE ||
- b->type == BOX_INLINE_BLOCK ||
- b->type == BOX_TEXT ||
- b->type == BOX_INLINE_END;
-}
-
-/** Layout helper: Check whether box is inline level. (Includes BR.) */
-static inline bool lh__box_is_inline_level(const struct box *b)
-{
- return lh__box_is_inline_flow(b) ||
- b->type == BOX_BR;
-}
-
-/** Layout helper: Check whether box is inline level. (Includes BR, floats.) */
-static inline bool lh__box_is_inline_content(const struct box *b)
-{
- return lh__box_is_float_box(b) ||
- lh__box_is_inline_level(b);
-}
-
-/** Layout helper: Check whether box is an object. */
-static inline bool lh__box_is_object(const struct box *b)
-{
- return b->object ||
- (b->flags & (IFRAME | REPLACE_DIM));
-}
-
-/** Layout helper: Check whether box is replaced. */
-static inline bool lh__box_is_replace(const struct box *b)
-{
- return b->gadget ||
- lh__box_is_object(b);
-}
-
/** Array of per-side access functions for computed style border colors. */
-static const css_border_color_func border_color_funcs[4] = {
+const css_border_color_func border_color_funcs[4] = {
[TOP] = css_computed_border_top_color,
[RIGHT] = css_computed_border_right_color,
[BOTTOM] = css_computed_border_bottom_color,
@@ -176,10 +120,6 @@ static const css_border_color_func border_color_funcs[4] =
{
};
/* forward declaration to break cycles */
-static bool layout_block_context(
- struct box *block,
- int viewport_height,
- html_content *content);
static void layout_minmax_block(
struct box *block,
const struct gui_layout_table *font_func,
@@ -315,74 +255,6 @@ static int layout_text_indent(
/**
- * Determine width of margin, borders, and padding on one side of a box.
- *
- * \param unit_len_ctx CSS length conversion context for document
- * \param style style to measure
- * \param side side of box to measure
- * \param margin whether margin width is required
- * \param border whether border width is required
- * \param padding whether padding width is required
- * \param fixed increased by sum of fixed margin, border, and padding
- * \param frac increased by sum of fractional margin and padding
- */
-static void
-calculate_mbp_width(const css_unit_ctx *unit_len_ctx,
- const css_computed_style *style,
- unsigned int side,
- bool margin,
- bool border,
- bool padding,
- int *fixed,
- float *frac)
-{
- css_fixed value = 0;
- css_unit unit = CSS_UNIT_PX;
-
- assert(style);
-
- /* margin */
- if (margin) {
- enum css_margin_e type;
-
- type = margin_funcs[side](style, &value, &unit);
- if (type == CSS_MARGIN_SET) {
- if (unit == CSS_UNIT_PCT) {
- *frac += FIXTOINT(FDIV(value, F_100));
- } else {
- *fixed += FIXTOINT(css_unit_len2device_px(
- style, unit_len_ctx,
- value, unit));
- }
- }
- }
-
- /* border */
- if (border) {
- if (lh__have_border(side, style)) {
- border_width_funcs[side](style, &value, &unit);
-
- *fixed += FIXTOINT(css_unit_len2device_px(
- style, unit_len_ctx,
- value, unit));
- }
- }
-
- /* padding */
- if (padding) {
- padding_funcs[side](style, &value, &unit);
- if (unit == CSS_UNIT_PCT) {
- *frac += FIXTOINT(FDIV(value, F_100));
- } else {
- *fixed += FIXTOINT(css_unit_len2device_px(
- style, unit_len_ctx,
- value, unit));
- }
- }
-}
-
-
-/**
* Calculate minimum and maximum width of a table.
*
* \param table box of type TABLE
@@ -1227,375 +1099,6 @@ static void layout_minmax_block(
/**
- * Adjust a specified width or height for the box-sizing property.
- *
- * This turns the specified dimension into a content-box dimension.
- *
- * \param unit_len_ctx Length conversion context
- * \param box gadget to adjust dimensions of
- * \param available_width width of containing block
- * \param setwidth set true if the dimension to be tweaked is a width,
- * else set false for a height
- * \param dimension current value for given width/height dimension.
- * updated to new value after consideration of
- * gadget properties.
- */
-static void layout_handle_box_sizing(
- const css_unit_ctx *unit_len_ctx,
- const struct box *box,
- int available_width,
- bool setwidth,
- int *dimension)
-{
- enum css_box_sizing_e bs;
-
- assert(box && box->style);
-
- bs = css_computed_box_sizing(box->style);
-
- if (bs == CSS_BOX_SIZING_BORDER_BOX) {
- int orig = *dimension;
- int fixed = 0;
- float frac = 0;
-
- calculate_mbp_width(unit_len_ctx, box->style,
- setwidth ? LEFT : TOP,
- false, true, true, &fixed, &frac);
- calculate_mbp_width(unit_len_ctx, box->style,
- setwidth ? RIGHT : BOTTOM,
- false, true, true, &fixed, &frac);
- orig -= frac * available_width + fixed;
- *dimension = orig > 0 ? orig : 0;
- }
-}
-
-
-/**
- * Calculate width, height, and thickness of margins, paddings, and borders.
- *
- * \param unit_len_ctx Length conversion context
- * \param available_width width of containing block
- * \param viewport_height height of viewport in pixels or -ve if unknown
- * \param box current box
- * \param style style giving width, height, margins, paddings,
- * and borders
- * \param width updated to width, may be NULL
- * \param height updated to height, may be NULL
- * \param max_width updated to max-width, may be NULL
- * \param min_width updated to min-width, may be NULL
- * \param max_height updated to max-height, may be NULL
- * \param min_height updated to min-height, may be NULL
- * \param margin filled with margins, may be NULL
- * \param padding filled with paddings, may be NULL
- * \param border filled with border widths, may be NULL
- */
-static void
-layout_find_dimensions(const css_unit_ctx *unit_len_ctx,
- int available_width,
- int viewport_height,
- const struct box *box,
- const css_computed_style *style,
- int *width,
- int *height,
- int *max_width,
- int *min_width,
- int *max_height,
- int *min_height,
- int margin[4],
- int padding[4],
- struct box_border border[4])
-{
- struct box *containing_block = NULL;
- unsigned int i;
-
- if (width) {
- enum css_width_e wtype;
- css_fixed value = 0;
- css_unit unit = CSS_UNIT_PX;
-
- wtype = css_computed_width(style, &value, &unit);
-
- if (wtype == CSS_WIDTH_SET) {
- if (unit == CSS_UNIT_PCT) {
- *width = FPCT_OF_INT_TOINT(
- value, available_width);
- } else {
- *width = FIXTOINT(css_unit_len2device_px(
- style, unit_len_ctx,
- value, unit));
- }
- } else {
- *width = AUTO;
- }
-
- if (*width != AUTO) {
- layout_handle_box_sizing(unit_len_ctx, box,
available_width,
- true, width);
- }
- }
-
- if (height) {
- enum css_height_e htype;
- css_fixed value = 0;
- css_unit unit = CSS_UNIT_PX;
-
- htype = css_computed_height(style, &value, &unit);
-
- if (htype == CSS_HEIGHT_SET) {
- if (unit == CSS_UNIT_PCT) {
- enum css_height_e cbhtype;
-
- if (css_computed_position(box->style) ==
- CSS_POSITION_ABSOLUTE &&
- box->parent) {
- /* Box is absolutely positioned */
- assert(box->float_container);
- containing_block = box->float_container;
- } else if (box->float_container &&
- css_computed_position(box->style) !=
- CSS_POSITION_ABSOLUTE &&
- (css_computed_float(box->style) ==
- CSS_FLOAT_LEFT ||
- css_computed_float(box->style) ==
- CSS_FLOAT_RIGHT)) {
- /* Box is a float */
- assert(box->parent &&
- box->parent->parent &&
- box->parent->parent->parent);
-
- containing_block =
- box->parent->parent->parent;
- } else if (box->parent && box->parent->type !=
- BOX_INLINE_CONTAINER) {
- /* Box is a block level element */
- containing_block = box->parent;
- } else if (box->parent && box->parent->type ==
- BOX_INLINE_CONTAINER) {
- /* Box is an inline block */
- assert(box->parent->parent);
- containing_block = box->parent->parent;
- }
-
- if (containing_block) {
- css_fixed f = 0;
- css_unit u = CSS_UNIT_PX;
-
- cbhtype = css_computed_height(
- containing_block->style,
- &f, &u);
- }
-
- if (containing_block &&
- containing_block->height != AUTO &&
- (css_computed_position(box->style) ==
- CSS_POSITION_ABSOLUTE ||
- cbhtype == CSS_HEIGHT_SET)) {
- /* Box is absolutely positioned or its
- * containing block has a valid
- * specified height.
- * (CSS 2.1 Section 10.5) */
- *height = FPCT_OF_INT_TOINT(value,
- containing_block->height);
- } else if ((!box->parent ||
- !box->parent->parent) &&
- viewport_height >= 0) {
- /* If root element or it's child
- * (HTML or BODY) */
- *height = FPCT_OF_INT_TOINT(value,
- viewport_height);
- } else {
- /* precentage height not permissible
- * treat height as auto */
- *height = AUTO;
- }
- } else {
- *height = FIXTOINT(css_unit_len2device_px(
- style, unit_len_ctx,
- value, unit));
- }
- } else {
- *height = AUTO;
- }
-
- if (*height != AUTO) {
- layout_handle_box_sizing(unit_len_ctx, box,
available_width,
- false, height);
- }
- }
-
- if (max_width) {
- enum css_max_width_e type;
- css_fixed value = 0;
- css_unit unit = CSS_UNIT_PX;
-
- type = css_computed_max_width(style, &value, &unit);
-
- if (type == CSS_MAX_WIDTH_SET) {
- if (unit == CSS_UNIT_PCT) {
- *max_width = FPCT_OF_INT_TOINT(value,
- available_width);
- } else {
- *max_width = FIXTOINT(css_unit_len2device_px(
- style, unit_len_ctx,
- value, unit));
- }
- } else {
- /* Inadmissible */
- *max_width = -1;
- }
-
- if (*max_width != -1) {
- layout_handle_box_sizing(unit_len_ctx, box,
available_width,
- true, max_width);
- }
- }
-
- if (min_width) {
- enum css_min_width_e type;
- css_fixed value = 0;
- css_unit unit = CSS_UNIT_PX;
-
- type = ns_computed_min_width(style, &value, &unit);
-
- if (type == CSS_MIN_WIDTH_SET) {
- if (unit == CSS_UNIT_PCT) {
- *min_width = FPCT_OF_INT_TOINT(value,
- available_width);
- } else {
- *min_width = FIXTOINT(css_unit_len2device_px(
- style, unit_len_ctx,
- value, unit));
- }
- } else {
- /* Inadmissible */
- *min_width = 0;
- }
-
- if (*min_width != 0) {
- layout_handle_box_sizing(unit_len_ctx, box,
available_width,
- true, min_width);
- }
- }
-
- if (max_height) {
- enum css_max_height_e type;
- css_fixed value = 0;
- css_unit unit = CSS_UNIT_PX;
-
- type = css_computed_max_height(style, &value, &unit);
-
- if (type == CSS_MAX_HEIGHT_SET) {
- if (unit == CSS_UNIT_PCT) {
- /* TODO: handle percentage */
- *max_height = -1;
- } else {
- *max_height = FIXTOINT(css_unit_len2device_px(
- style, unit_len_ctx,
- value, unit));
- }
- } else {
- /* Inadmissible */
- *max_height = -1;
- }
- }
-
- if (min_height) {
- enum css_min_height_e type;
- css_fixed value = 0;
- css_unit unit = CSS_UNIT_PX;
-
- type = ns_computed_min_height(style, &value, &unit);
-
- if (type == CSS_MIN_HEIGHT_SET) {
- if (unit == CSS_UNIT_PCT) {
- /* TODO: handle percentage */
- *min_height = 0;
- } else {
- *min_height = FIXTOINT(css_unit_len2device_px(
- style, unit_len_ctx,
- value, unit));
- }
- } else {
- /* Inadmissible */
- *min_height = 0;
- }
- }
-
- for (i = 0; i != 4; i++) {
- if (margin) {
- enum css_margin_e type = CSS_MARGIN_AUTO;
- css_fixed value = 0;
- css_unit unit = CSS_UNIT_PX;
-
- type = margin_funcs[i](style, &value, &unit);
-
- if (type == CSS_MARGIN_SET) {
- if (unit == CSS_UNIT_PCT) {
- margin[i] = FPCT_OF_INT_TOINT(value,
- available_width);
- } else {
- margin[i] =
FIXTOINT(css_unit_len2device_px(
- style, unit_len_ctx,
- value, unit));
- }
- } else {
- margin[i] = AUTO;
- }
- }
-
- if (padding) {
- css_fixed value = 0;
- css_unit unit = CSS_UNIT_PX;
-
- padding_funcs[i](style, &value, &unit);
-
- if (unit == CSS_UNIT_PCT) {
- padding[i] = FPCT_OF_INT_TOINT(value,
- available_width);
- } else {
- padding[i] = FIXTOINT(css_unit_len2device_px(
- style, unit_len_ctx,
- value, unit));
- }
- }
-
- /* Table cell borders are populated in table.c */
- if (border && box->type != BOX_TABLE_CELL) {
- enum css_border_style_e bstyle = CSS_BORDER_STYLE_NONE;
- css_color color = 0;
- css_fixed value = 0;
- css_unit unit = CSS_UNIT_PX;
-
- border_width_funcs[i](style, &value, &unit);
- bstyle = border_style_funcs[i](style);
- border_color_funcs[i](style, &color);
-
- border[i].style = bstyle;
- border[i].c = color;
-
- if (bstyle == CSS_BORDER_STYLE_HIDDEN ||
- bstyle == CSS_BORDER_STYLE_NONE)
- /* spec unclear: following Mozilla */
- border[i].width = 0;
- else
- border[i].width =
FIXTOINT(css_unit_len2device_px(
- style, unit_len_ctx,
- value, unit));
-
- /* Special case for border-collapse: make all borders
- * on table/table-row-group/table-row zero width. */
- if (css_computed_border_collapse(style) ==
- CSS_BORDER_COLLAPSE_COLLAPSE &&
- (box->type == BOX_TABLE ||
- box->type == BOX_TABLE_ROW_GROUP ||
- box->type == BOX_TABLE_ROW))
- border[i].width = 0;
- }
- }
-}
-
-
-/**
* Find next block that current margin collapses to.
*
* \param unit_len_ctx Length conversion context
@@ -2058,15 +1561,10 @@ static void layout_move_children(struct box *box, int
x, int y)
}
-/**
- * Layout a table.
- *
- * \param table table to layout
- * \param available_width width of containing block
- * \param content memory pool for any new boxes
- * \return true on success, false on memory exhaustion
- */
-static bool layout_table(struct box *table, int available_width,
+/* Documented in layout_internal.h */
+bool layout_table(
+ struct box *table,
+ int available_width,
html_content *content)
{
unsigned int columns = table->columns; /* total columns */
@@ -3977,21 +3475,11 @@ static bool layout_inline_container(struct box
*inline_container, int width,
}
-/**
- * Layout a block formatting context.
- *
- * \param block BLOCK, INLINE_BLOCK, or TABLE_CELL to layout
- * \param viewport_height Height of viewport in pixels or -ve if unknown
- * \param content Memory pool for any new boxes
- * \return true on success, false on memory exhaustion
- *
- * This function carries out layout of a block and its children, as described
- * in CSS 2.1 9.4.1.
- */
-static bool
-layout_block_context(struct box *block,
- int viewport_height,
- html_content *content)
+/* Documented in layout_intertnal.h */
+bool layout_block_context(
+ struct box *block,
+ int viewport_height,
+ html_content *content)
{
struct box *box;
int cx, cy; /**< current coordinates */
diff --git a/content/handlers/html/layout_internal.h
b/content/handlers/html/layout_internal.h
new file mode 100644
index 0000000..0c171ef
--- /dev/null
+++ b/content/handlers/html/layout_internal.h
@@ -0,0 +1,584 @@
+/*
+ * Copyright 2003 James Bursa <[email protected]>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * \file
+ * HTML layout private interface.
+ */
+
+#ifndef NETSURF_HTML_LAYOUT_INTERNAL_H
+#define NETSURF_HTML_LAYOUT_INTERNAL_H
+
+#define AUTO INT_MIN
+
+/* Fixed point percentage (a) of an integer (b), to an integer */
+#define FPCT_OF_INT_TOINT(a, b) (FIXTOINT(FDIV((a * b), F_100)))
+
+/**
+ * Layout a block formatting context.
+ *
+ * \param block BLOCK, INLINE_BLOCK, or TABLE_CELL to layout
+ * \param viewport_height Height of viewport in pixels or -ve if unknown
+ * \param content Memory pool for any new boxes
+ * \return true on success, false on memory exhaustion
+ *
+ * This function carries out layout of a block and its children, as described
+ * in CSS 2.1 9.4.1.
+ */
+bool layout_block_context(
+ struct box *block,
+ int viewport_height,
+ html_content *content);
+
+/**
+ * Layout a table.
+ *
+ * \param table table to layout
+ * \param available_width width of containing block
+ * \param content memory pool for any new boxes
+ * \return true on success, false on memory exhaustion
+ */
+bool layout_table(
+ struct box *table,
+ int available_width,
+ html_content *content);
+
+/**
+ * Layout a flex container.
+ *
+ * \param[in] flex table to layout
+ * \param[in] available_width width of containing block
+ * \param[in] content memory pool for any new boxes
+ * \return true on success, false on memory exhaustion
+ */
+bool layout_flex(
+ struct box *flex,
+ int available_width,
+ html_content *content);
+
+typedef uint8_t (*css_len_func)(
+ const css_computed_style *style,
+ css_fixed *length, css_unit *unit);
+typedef uint8_t (*css_border_style_func)(
+ const css_computed_style *style);
+typedef uint8_t (*css_border_color_func)(
+ const css_computed_style *style,
+ css_color *color);
+
+/** Array of per-side access functions for computed style margins. */
+extern const css_len_func margin_funcs[4];
+
+/** Array of per-side access functions for computed style paddings. */
+extern const css_len_func padding_funcs[4];
+
+/** Array of per-side access functions for computed style border_widths. */
+extern const css_len_func border_width_funcs[4];
+
+/** Array of per-side access functions for computed style border styles. */
+extern const css_border_style_func border_style_funcs[4];
+
+/** Array of per-side access functions for computed style border colors. */
+extern const css_border_color_func border_color_funcs[4];
+
+/** Layout helper: Check whether box is a float. */
+static inline bool lh__box_is_float_box(const struct box *b)
+{
+ return b->type == BOX_FLOAT_LEFT ||
+ b->type == BOX_FLOAT_RIGHT;
+}
+
+/** Layout helper: Check whether box takes part in inline flow. */
+static inline bool lh__box_is_inline_flow(const struct box *b)
+{
+ return b->type == BOX_INLINE ||
+ b->type == BOX_INLINE_BLOCK ||
+ b->type == BOX_TEXT ||
+ b->type == BOX_INLINE_END;
+}
+
+/** Layout helper: Check whether box is inline level. (Includes BR.) */
+static inline bool lh__box_is_inline_level(const struct box *b)
+{
+ return lh__box_is_inline_flow(b) ||
+ b->type == BOX_BR;
+}
+
+/** Layout helper: Check whether box is inline level. (Includes BR, floats.) */
+static inline bool lh__box_is_inline_content(const struct box *b)
+{
+ return lh__box_is_float_box(b) ||
+ lh__box_is_inline_level(b);
+}
+
+/** Layout helper: Check whether box is an object. */
+static inline bool lh__box_is_object(const struct box *b)
+{
+ return b->object ||
+ (b->flags & (IFRAME | REPLACE_DIM));
+}
+
+/** Layout helper: Check whether box is replaced. */
+static inline bool lh__box_is_replace(const struct box *b)
+{
+ return b->gadget ||
+ lh__box_is_object(b);
+}
+
+/** Layout helper: Check for CSS border on given side. */
+static inline bool lh__have_border(
+ enum box_side side,
+ const css_computed_style *style)
+{
+ return border_style_funcs[side](style) != CSS_BORDER_STYLE_NONE;
+}
+
+/**
+ * Determine width of margin, borders, and padding on one side of a box.
+ *
+ * \param unit_len_ctx CSS length conversion context for document
+ * \param style style to measure
+ * \param side side of box to measure
+ * \param margin whether margin width is required
+ * \param border whether border width is required
+ * \param padding whether padding width is required
+ * \param fixed increased by sum of fixed margin, border, and padding
+ * \param frac increased by sum of fractional margin and padding
+ */
+static inline void calculate_mbp_width(
+ const css_unit_ctx *unit_len_ctx,
+ const css_computed_style *style,
+ unsigned int side,
+ bool margin,
+ bool border,
+ bool padding,
+ int *fixed,
+ float *frac)
+{
+ css_fixed value = 0;
+ css_unit unit = CSS_UNIT_PX;
+
+ assert(style);
+
+ /* margin */
+ if (margin) {
+ enum css_margin_e type;
+
+ type = margin_funcs[side](style, &value, &unit);
+ if (type == CSS_MARGIN_SET) {
+ if (unit == CSS_UNIT_PCT) {
+ *frac += FIXTOINT(FDIV(value, F_100));
+ } else {
+ *fixed += FIXTOINT(css_unit_len2device_px(
+ style, unit_len_ctx,
+ value, unit));
+ }
+ }
+ }
+
+ /* border */
+ if (border) {
+ if (lh__have_border(side, style)) {
+ border_width_funcs[side](style, &value, &unit);
+
+ *fixed += FIXTOINT(css_unit_len2device_px(
+ style, unit_len_ctx,
+ value, unit));
+ }
+ }
+
+ /* padding */
+ if (padding) {
+ padding_funcs[side](style, &value, &unit);
+ if (unit == CSS_UNIT_PCT) {
+ *frac += FIXTOINT(FDIV(value, F_100));
+ } else {
+ *fixed += FIXTOINT(css_unit_len2device_px(
+ style, unit_len_ctx,
+ value, unit));
+ }
+ }
+}
+
+/**
+ * Adjust a specified width or height for the box-sizing property.
+ *
+ * This turns the specified dimension into a content-box dimension.
+ *
+ * \param unit_len_ctx Length conversion context
+ * \param box gadget to adjust dimensions of
+ * \param available_width width of containing block
+ * \param setwidth set true if the dimension to be tweaked is a width,
+ * else set false for a height
+ * \param dimension current value for given width/height dimension.
+ * updated to new value after consideration of
+ * gadget properties.
+ */
+static inline void layout_handle_box_sizing(
+ const css_unit_ctx *unit_len_ctx,
+ const struct box *box,
+ int available_width,
+ bool setwidth,
+ int *dimension)
+{
+ enum css_box_sizing_e bs;
+
+ assert(box && box->style);
+
+ bs = css_computed_box_sizing(box->style);
+
+ if (bs == CSS_BOX_SIZING_BORDER_BOX) {
+ int orig = *dimension;
+ int fixed = 0;
+ float frac = 0;
+
+ calculate_mbp_width(unit_len_ctx, box->style,
+ setwidth ? LEFT : TOP,
+ false, true, true, &fixed, &frac);
+ calculate_mbp_width(unit_len_ctx, box->style,
+ setwidth ? RIGHT : BOTTOM,
+ false, true, true, &fixed, &frac);
+ orig -= frac * available_width + fixed;
+ *dimension = orig > 0 ? orig : 0;
+ }
+}
+
+/**
+ * Calculate width, height, and thickness of margins, paddings, and borders.
+ *
+ * \param unit_len_ctx Length conversion context
+ * \param available_width width of containing block
+ * \param viewport_height height of viewport in pixels or -ve if unknown
+ * \param box current box
+ * \param style style giving width, height, margins, paddings,
+ * and borders
+ * \param width updated to width, may be NULL
+ * \param height updated to height, may be NULL
+ * \param max_width updated to max-width, may be NULL
+ * \param min_width updated to min-width, may be NULL
+ * \param max_height updated to max-height, may be NULL
+ * \param min_height updated to min-height, may be NULL
+ * \param margin filled with margins, may be NULL
+ * \param padding filled with paddings, may be NULL
+ * \param border filled with border widths, may be NULL
+ */
+static inline void layout_find_dimensions(
+ const css_unit_ctx *unit_len_ctx,
+ int available_width,
+ int viewport_height,
+ const struct box *box,
+ const css_computed_style *style,
+ int *width,
+ int *height,
+ int *max_width,
+ int *min_width,
+ int *max_height,
+ int *min_height,
+ int margin[4],
+ int padding[4],
+ struct box_border border[4])
+{
+ struct box *containing_block = NULL;
+ unsigned int i;
+
+ if (width) {
+ enum css_width_e wtype;
+ css_fixed value = 0;
+ css_unit unit = CSS_UNIT_PX;
+
+ wtype = css_computed_width(style, &value, &unit);
+
+ if (wtype == CSS_WIDTH_SET) {
+ if (unit == CSS_UNIT_PCT) {
+ *width = FPCT_OF_INT_TOINT(
+ value, available_width);
+ } else {
+ *width = FIXTOINT(css_unit_len2device_px(
+ style, unit_len_ctx,
+ value, unit));
+ }
+ } else {
+ *width = AUTO;
+ }
+
+ if (*width != AUTO) {
+ layout_handle_box_sizing(unit_len_ctx, box,
+ available_width, true, width);
+ }
+ }
+
+ if (height) {
+ enum css_height_e htype;
+ css_fixed value = 0;
+ css_unit unit = CSS_UNIT_PX;
+
+ htype = css_computed_height(style, &value, &unit);
+
+ if (htype == CSS_HEIGHT_SET) {
+ if (unit == CSS_UNIT_PCT) {
+ enum css_height_e cbhtype;
+
+ if (css_computed_position(box->style) ==
+ CSS_POSITION_ABSOLUTE &&
+ box->parent) {
+ /* Box is absolutely positioned */
+ assert(box->float_container);
+ containing_block = box->float_container;
+ } else if (box->float_container &&
+ css_computed_position(box->style) !=
+ CSS_POSITION_ABSOLUTE &&
+ (css_computed_float(box->style) ==
+ CSS_FLOAT_LEFT ||
+ css_computed_float(box->style) ==
+ CSS_FLOAT_RIGHT)) {
+ /* Box is a float */
+ assert(box->parent &&
+ box->parent->parent &&
+ box->parent->parent->parent);
+
+ containing_block =
+ box->parent->parent->parent;
+ } else if (box->parent && box->parent->type !=
+ BOX_INLINE_CONTAINER) {
+ /* Box is a block level element */
+ containing_block = box->parent;
+ } else if (box->parent && box->parent->type ==
+ BOX_INLINE_CONTAINER) {
+ /* Box is an inline block */
+ assert(box->parent->parent);
+ containing_block = box->parent->parent;
+ }
+
+ if (containing_block) {
+ css_fixed f = 0;
+ css_unit u = CSS_UNIT_PX;
+
+ cbhtype = css_computed_height(
+ containing_block->style,
+ &f, &u);
+ }
+
+ if (containing_block &&
+ containing_block->height != AUTO &&
+ (css_computed_position(box->style) ==
+ CSS_POSITION_ABSOLUTE ||
+ cbhtype == CSS_HEIGHT_SET)) {
+ /* Box is absolutely positioned or its
+ * containing block has a valid
+ * specified height.
+ * (CSS 2.1 Section 10.5) */
+ *height = FPCT_OF_INT_TOINT(value,
+ containing_block->height);
+ } else if ((!box->parent ||
+ !box->parent->parent) &&
+ viewport_height >= 0) {
+ /* If root element or it's child
+ * (HTML or BODY) */
+ *height = FPCT_OF_INT_TOINT(value,
+ viewport_height);
+ } else {
+ /* precentage height not permissible
+ * treat height as auto */
+ *height = AUTO;
+ }
+ } else {
+ *height = FIXTOINT(css_unit_len2device_px(
+ style, unit_len_ctx,
+ value, unit));
+ }
+ } else {
+ *height = AUTO;
+ }
+
+ if (*height != AUTO) {
+ layout_handle_box_sizing(unit_len_ctx, box,
+ available_width, false, height);
+ }
+ }
+
+ if (max_width) {
+ enum css_max_width_e type;
+ css_fixed value = 0;
+ css_unit unit = CSS_UNIT_PX;
+
+ type = css_computed_max_width(style, &value, &unit);
+
+ if (type == CSS_MAX_WIDTH_SET) {
+ if (unit == CSS_UNIT_PCT) {
+ *max_width = FPCT_OF_INT_TOINT(value,
+ available_width);
+ } else {
+ *max_width = FIXTOINT(css_unit_len2device_px(
+ style, unit_len_ctx,
+ value, unit));
+ }
+ } else {
+ /* Inadmissible */
+ *max_width = -1;
+ }
+
+ if (*max_width != -1) {
+ layout_handle_box_sizing(unit_len_ctx, box,
+ available_width, true, max_width);
+ }
+ }
+
+ if (min_width) {
+ enum css_min_width_e type;
+ css_fixed value = 0;
+ css_unit unit = CSS_UNIT_PX;
+
+ type = ns_computed_min_width(style, &value, &unit);
+
+ if (type == CSS_MIN_WIDTH_SET) {
+ if (unit == CSS_UNIT_PCT) {
+ *min_width = FPCT_OF_INT_TOINT(value,
+ available_width);
+ } else {
+ *min_width = FIXTOINT(css_unit_len2device_px(
+ style, unit_len_ctx,
+ value, unit));
+ }
+ } else {
+ /* Inadmissible */
+ *min_width = 0;
+ }
+
+ if (*min_width != 0) {
+ layout_handle_box_sizing(unit_len_ctx, box,
+ available_width, true, min_width);
+ }
+ }
+
+ if (max_height) {
+ enum css_max_height_e type;
+ css_fixed value = 0;
+ css_unit unit = CSS_UNIT_PX;
+
+ type = css_computed_max_height(style, &value, &unit);
+
+ if (type == CSS_MAX_HEIGHT_SET) {
+ if (unit == CSS_UNIT_PCT) {
+ /* TODO: handle percentage */
+ *max_height = -1;
+ } else {
+ *max_height = FIXTOINT(css_unit_len2device_px(
+ style, unit_len_ctx,
+ value, unit));
+ }
+ } else {
+ /* Inadmissible */
+ *max_height = -1;
+ }
+ }
+
+ if (min_height) {
+ enum css_min_height_e type;
+ css_fixed value = 0;
+ css_unit unit = CSS_UNIT_PX;
+
+ type = ns_computed_min_height(style, &value, &unit);
+
+ if (type == CSS_MIN_HEIGHT_SET) {
+ if (unit == CSS_UNIT_PCT) {
+ /* TODO: handle percentage */
+ *min_height = 0;
+ } else {
+ *min_height = FIXTOINT(css_unit_len2device_px(
+ style, unit_len_ctx,
+ value, unit));
+ }
+ } else {
+ /* Inadmissible */
+ *min_height = 0;
+ }
+ }
+
+ for (i = 0; i != 4; i++) {
+ if (margin) {
+ enum css_margin_e type = CSS_MARGIN_AUTO;
+ css_fixed value = 0;
+ css_unit unit = CSS_UNIT_PX;
+
+ type = margin_funcs[i](style, &value, &unit);
+
+ if (type == CSS_MARGIN_SET) {
+ if (unit == CSS_UNIT_PCT) {
+ margin[i] = FPCT_OF_INT_TOINT(value,
+ available_width);
+ } else {
+ margin[i] =
FIXTOINT(css_unit_len2device_px(
+ style, unit_len_ctx,
+ value, unit));
+ }
+ } else {
+ margin[i] = AUTO;
+ }
+ }
+
+ if (padding) {
+ css_fixed value = 0;
+ css_unit unit = CSS_UNIT_PX;
+
+ padding_funcs[i](style, &value, &unit);
+
+ if (unit == CSS_UNIT_PCT) {
+ padding[i] = FPCT_OF_INT_TOINT(value,
+ available_width);
+ } else {
+ padding[i] = FIXTOINT(css_unit_len2device_px(
+ style, unit_len_ctx,
+ value, unit));
+ }
+ }
+
+ /* Table cell borders are populated in table.c */
+ if (border && box->type != BOX_TABLE_CELL) {
+ enum css_border_style_e bstyle = CSS_BORDER_STYLE_NONE;
+ css_color color = 0;
+ css_fixed value = 0;
+ css_unit unit = CSS_UNIT_PX;
+
+ border_width_funcs[i](style, &value, &unit);
+ bstyle = border_style_funcs[i](style);
+ border_color_funcs[i](style, &color);
+
+ border[i].style = bstyle;
+ border[i].c = color;
+
+ if (bstyle == CSS_BORDER_STYLE_HIDDEN ||
+ bstyle == CSS_BORDER_STYLE_NONE)
+ /* spec unclear: following Mozilla */
+ border[i].width = 0;
+ else
+ border[i].width =
FIXTOINT(css_unit_len2device_px(
+ style, unit_len_ctx,
+ value, unit));
+
+ /* Special case for border-collapse: make all borders
+ * on table/table-row-group/table-row zero width. */
+ if (css_computed_border_collapse(style) ==
+ CSS_BORDER_COLLAPSE_COLLAPSE &&
+ (box->type == BOX_TABLE ||
+ box->type == BOX_TABLE_ROW_GROUP ||
+ box->type == BOX_TABLE_ROW))
+ border[i].width = 0;
+ }
+ }
+}
+
+#endif
commitdiff
http://git.netsurf-browser.org/netsurf.git/commit/?id=05d645dc45d4d803a61e6fe811e6312f563deabe
commit 05d645dc45d4d803a61e6fe811e6312f563deabe
Author: Michael Drake <[email protected]>
Commit: Michael Drake <[email protected]>
css: Fix dump of display: inline-flex
diff --git a/content/handlers/css/dump.c b/content/handlers/css/dump.c
index 1e448e0..4138f93 100644
--- a/content/handlers/css/dump.c
+++ b/content/handlers/css/dump.c
@@ -864,6 +864,12 @@ void nscss_dump_computed_style(FILE *stream, const
css_computed_style *style)
case CSS_DISPLAY_NONE:
fprintf(stream, "display: none ");
break;
+ case CSS_DISPLAY_FLEX:
+ fprintf(stream, "display: flex ");
+ break;
+ case CSS_DISPLAY_INLINE_FLEX:
+ fprintf(stream, "display: inline-flex ");
+ break;
default:
break;
}
commitdiff
http://git.netsurf-browser.org/netsurf.git/commit/?id=eb56aaaaf1c89eee0f4b8c7cb6dfbaf6c55cd889
commit eb56aaaaf1c89eee0f4b8c7cb6dfbaf6c55cd889
Author: Michael Drake <[email protected]>
Commit: Michael Drake <[email protected]>
layout: Constify box through layout_find_dimensions().
diff --git a/content/handlers/html/layout.c b/content/handlers/html/layout.c
index 442ced6..cb5be5d 100644
--- a/content/handlers/html/layout.c
+++ b/content/handlers/html/layout.c
@@ -1293,7 +1293,7 @@ static void
layout_find_dimensions(const css_unit_ctx *unit_len_ctx,
int available_width,
int viewport_height,
- struct box *box,
+ const struct box *box,
const css_computed_style *style,
int *width,
int *height,
commitdiff
http://git.netsurf-browser.org/netsurf.git/commit/?id=1d14229c3b2f7c071a260f3d2035193227b286cb
commit 1d14229c3b2f7c071a260f3d2035193227b286cb
Author: Michael Drake <[email protected]>
Commit: Michael Drake <[email protected]>
layout: Constify box through layout_handle_box_sizing().
diff --git a/content/handlers/html/layout.c b/content/handlers/html/layout.c
index fb4010d..442ced6 100644
--- a/content/handlers/html/layout.c
+++ b/content/handlers/html/layout.c
@@ -1242,7 +1242,7 @@ static void layout_minmax_block(
*/
static void layout_handle_box_sizing(
const css_unit_ctx *unit_len_ctx,
- struct box *box,
+ const struct box *box,
int available_width,
bool setwidth,
int *dimension)
commitdiff
http://git.netsurf-browser.org/netsurf.git/commit/?id=e174d0995ae8a07df43e23901410dcdd2f82221e
commit e174d0995ae8a07df43e23901410dcdd2f82221e
Author: Michael Drake <[email protected]>
Commit: Michael Drake <[email protected]>
layout: Add helpers for various box type checks.
diff --git a/content/handlers/html/layout.c b/content/handlers/html/layout.c
index 4d55bb5..fb4010d 100644
--- a/content/handlers/html/layout.c
+++ b/content/handlers/html/layout.c
@@ -123,6 +123,50 @@ static inline bool lh__have_border(
return border_style_funcs[side](style) != CSS_BORDER_STYLE_NONE;
}
+/** Layout helper: Check whether box is a float. */
+static inline bool lh__box_is_float_box(const struct box *b)
+{
+ return b->type == BOX_FLOAT_LEFT ||
+ b->type == BOX_FLOAT_RIGHT;
+}
+
+/** Layout helper: Check whether box takes part in inline flow. */
+static inline bool lh__box_is_inline_flow(const struct box *b)
+{
+ return b->type == BOX_INLINE ||
+ b->type == BOX_INLINE_BLOCK ||
+ b->type == BOX_TEXT ||
+ b->type == BOX_INLINE_END;
+}
+
+/** Layout helper: Check whether box is inline level. (Includes BR.) */
+static inline bool lh__box_is_inline_level(const struct box *b)
+{
+ return lh__box_is_inline_flow(b) ||
+ b->type == BOX_BR;
+}
+
+/** Layout helper: Check whether box is inline level. (Includes BR, floats.) */
+static inline bool lh__box_is_inline_content(const struct box *b)
+{
+ return lh__box_is_float_box(b) ||
+ lh__box_is_inline_level(b);
+}
+
+/** Layout helper: Check whether box is an object. */
+static inline bool lh__box_is_object(const struct box *b)
+{
+ return b->object ||
+ (b->flags & (IFRAME | REPLACE_DIM));
+}
+
+/** Layout helper: Check whether box is replaced. */
+static inline bool lh__box_is_replace(const struct box *b)
+{
+ return b->gadget ||
+ lh__box_is_object(b);
+}
+
/** Array of per-side access functions for computed style border colors. */
static const css_border_color_func border_color_funcs[4] = {
[TOP] = css_computed_border_top_color,
@@ -595,11 +639,7 @@ layout_minmax_line(struct box *first,
css_fixed value = 0;
css_unit unit = CSS_UNIT_PX;
- assert(b->type == BOX_INLINE || b->type == BOX_INLINE_BLOCK ||
- b->type == BOX_FLOAT_LEFT ||
- b->type == BOX_FLOAT_RIGHT ||
- b->type == BOX_BR || b->type == BOX_TEXT ||
- b->type == BOX_INLINE_END);
+ assert(lh__box_is_inline_content(b));
NSLOG(layout, DEBUG, "%p: min %i, max %i", b, min, max);
@@ -608,7 +648,7 @@ layout_minmax_line(struct box *first,
break;
}
- if (b->type == BOX_FLOAT_LEFT || b->type == BOX_FLOAT_RIGHT) {
+ if (lh__box_is_float_box(b)) {
assert(b->children);
if (b->children->type == BOX_BLOCK)
layout_minmax_block(b->children, font_func,
@@ -675,8 +715,7 @@ layout_minmax_line(struct box *first,
continue;
}
- if (!b->object && !(b->flags & IFRAME) && !b->gadget &&
- !(b->flags & REPLACE_DIM)) {
+ if (lh__box_is_replace(b) == false) {
/* inline non-replaced, 10.3.1 and 10.6.1 */
bool no_wrap_box;
if (!b->text)
@@ -1001,8 +1040,7 @@ static void layout_minmax_block(
}
/* set whether the minimum width is of any interest for this box */
- if (((block->parent && (block->parent->type == BOX_FLOAT_LEFT ||
- block->parent->type == BOX_FLOAT_RIGHT)) ||
+ if (((block->parent && lh__box_is_float_box(block->parent)) ||
block->type == BOX_INLINE_BLOCK) &&
wtype != CSS_WIDTH_SET) {
/* box shrinks to fit; need minimum width */
@@ -3216,20 +3254,14 @@ layout_line(struct box *first,
for (x = 0, b = first; x <= x1 - x0 && b != 0; b = b->next) {
int min_width, max_width, min_height, max_height;
- assert(b->type == BOX_INLINE || b->type == BOX_INLINE_BLOCK ||
- b->type == BOX_FLOAT_LEFT ||
- b->type == BOX_FLOAT_RIGHT ||
- b->type == BOX_BR || b->type == BOX_TEXT ||
- b->type == BOX_INLINE_END);
-
+ assert(lh__box_is_inline_content(b));
NSLOG(layout, DEBUG, "pass 1: b %p, x %i", b, x);
-
if (b->type == BOX_BR)
break;
- if (b->type == BOX_FLOAT_LEFT || b->type == BOX_FLOAT_RIGHT)
+ if (lh__box_is_float_box(b))
continue;
if (b->type == BOX_INLINE_BLOCK &&
(css_computed_position(b->style) ==
@@ -3295,8 +3327,7 @@ layout_line(struct box *first,
continue;
}
- if (!b->object && !(b->flags & IFRAME) && !b->gadget &&
- !(b->flags & REPLACE_DIM)) {
+ if (lh__box_is_replace(b) == false) {
/* inline non-replaced, 10.3.1 and 10.6.1 */
b->height = line_height(&content->unit_len_ctx,
b->style ? b->style :
@@ -3456,10 +3487,7 @@ layout_line(struct box *first,
CSS_POSITION_FIXED)) {
b->x = x + space_after;
- } else if (b->type == BOX_INLINE ||
- b->type == BOX_INLINE_BLOCK ||
- b->type == BOX_TEXT ||
- b->type == BOX_INLINE_END) {
+ } else if (lh__box_is_inline_flow(b)) {
assert(b->width != UNKNOWN_WIDTH);
x_previous = x;
@@ -3798,9 +3826,7 @@ layout_line(struct box *first,
d->y = *y;
continue;
} else if ((d->type == BOX_INLINE &&
- ((d->object || d->gadget) == false) &&
- !(d->flags & IFRAME) &&
- !(d->flags & REPLACE_DIM)) ||
+ lh__box_is_replace(d) == false) ||
d->type == BOX_BR ||
d->type == BOX_TEXT ||
d->type == BOX_INLINE_END) {
@@ -3921,8 +3947,7 @@ static bool layout_inline_container(struct box
*inline_container, int width,
whitespace == CSS_WHITE_SPACE_PRE_WRAP);
}
- if ((!c->object && !(c->flags & REPLACE_DIM) &&
- !(c->flags & IFRAME) &&
+ if ((lh__box_is_object(c) == false &&
c->text && (c->length || is_pre)) ||
c->type == BOX_BR)
has_text_children = true;
@@ -4102,8 +4127,7 @@ layout_block_context(struct box *block,
lm = rm = 0;
if (box->type == BOX_BLOCK || box->flags & IFRAME) {
- if (!box->object && !(box->flags & IFRAME) &&
- !(box->flags & REPLACE_DIM) &&
+ if (lh__box_is_object(box) == false &&
box->style &&
(overflow_x != CSS_OVERFLOW_VISIBLE ||
overflow_y != CSS_OVERFLOW_VISIBLE)) {
commitdiff
http://git.netsurf-browser.org/netsurf.git/commit/?id=aa6273ea0ea099aa9a5e0b5b233a66abd4890794
commit aa6273ea0ea099aa9a5e0b5b233a66abd4890794
Author: Michael Drake <[email protected]>
Commit: Michael Drake <[email protected]>
layout: Add helper for checking if a style has a border on a side.
diff --git a/content/handlers/html/layout.c b/content/handlers/html/layout.c
index f50a711..4d55bb5 100644
--- a/content/handlers/html/layout.c
+++ b/content/handlers/html/layout.c
@@ -115,6 +115,14 @@ static const css_border_style_func border_style_funcs[4] =
{
[LEFT] = css_computed_border_left_style,
};
+/** Layout helper: Check for CSS border on given side. */
+static inline bool lh__have_border(
+ enum box_side side,
+ const css_computed_style *style)
+{
+ return border_style_funcs[side](style) != CSS_BORDER_STYLE_NONE;
+}
+
/** Array of per-side access functions for computed style border colors. */
static const css_border_color_func border_color_funcs[4] = {
[TOP] = css_computed_border_top_color,
@@ -307,8 +315,7 @@ calculate_mbp_width(const css_unit_ctx *unit_len_ctx,
/* border */
if (border) {
- if (border_style_funcs[side](style) !=
- CSS_BORDER_STYLE_NONE) {
+ if (lh__have_border(side, style)) {
border_width_funcs[side](style, &value, &unit);
*fixed += FIXTOINT(css_unit_len2device_px(
commitdiff
http://git.netsurf-browser.org/netsurf.git/commit/?id=388952b222953cbed410c189c27c85c0f5e58d44
commit 388952b222953cbed410c189c27c85c0f5e58d44
Author: Michael Drake <[email protected]>
Commit: Michael Drake <[email protected]>
layout: Drop redundant else block.
diff --git a/content/handlers/html/layout.c b/content/handlers/html/layout.c
index c06fdf6..f50a711 100644
--- a/content/handlers/html/layout.c
+++ b/content/handlers/html/layout.c
@@ -5024,8 +5024,6 @@ layout_absolute(struct box *box,
containing_block->padding[RIGHT];
containing_block->height += containing_block->padding[TOP] +
containing_block->padding[BOTTOM];
- } else {
- /** \todo inline containers */
}
layout_compute_offsets(&content->unit_len_ctx, box, containing_block,
commitdiff
http://git.netsurf-browser.org/netsurf.git/commit/?id=7d833537aaefe179760db7aab10720a24357410d
commit 7d833537aaefe179760db7aab10720a24357410d
Author: Michael Drake <[email protected]>
Commit: Michael Drake <[email protected]>
css: Update display property helper for grid
diff --git a/content/handlers/css/utils.h b/content/handlers/css/utils.h
index 541677a..0b05374 100644
--- a/content/handlers/css/utils.h
+++ b/content/handlers/css/utils.h
@@ -28,35 +28,49 @@ extern css_fixed nscss_screen_dpi;
/**
* Temporary helper wrappers for for libcss computed style getter, while
- * we don't support flexbox related property values.
+ * we don't support all values of display.
*/
-
static inline uint8_t ns_computed_display(
const css_computed_style *style, bool root)
{
uint8_t value = css_computed_display(style, root);
- if (value == CSS_DISPLAY_FLEX) {
+ switch (value) {
+ case CSS_DISPLAY_FLEX:
+ case CSS_DISPLAY_GRID:
return CSS_DISPLAY_BLOCK;
- } else if (value == CSS_DISPLAY_INLINE_FLEX) {
+ case CSS_DISPLAY_INLINE_FLEX:
+ case CSS_DISPLAY_INLINE_GRID:
return CSS_DISPLAY_INLINE_BLOCK;
+
+ default:
+ break;
}
return value;
}
-
+/**
+ * Temporary helper wrappers for for libcss computed style getter, while
+ * we don't support all values of display.
+ */
static inline uint8_t ns_computed_display_static(
const css_computed_style *style)
{
uint8_t value = css_computed_display_static(style);
- if (value == CSS_DISPLAY_FLEX) {
+ switch (value) {
+ case CSS_DISPLAY_FLEX:
+ case CSS_DISPLAY_GRID:
return CSS_DISPLAY_BLOCK;
- } else if (value == CSS_DISPLAY_INLINE_FLEX) {
+ case CSS_DISPLAY_INLINE_FLEX:
+ case CSS_DISPLAY_INLINE_GRID:
return CSS_DISPLAY_INLINE_BLOCK;
+
+ default:
+ break;
}
return value;
-----------------------------------------------------------------------
Summary of changes:
Makefile | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/Makefile b/Makefile
index c30994f..f66f796 100644
--- a/Makefile
+++ b/Makefile
@@ -56,7 +56,7 @@ VQ=@
# Override this only if the host compiler is called something different
BUILD_CC := cc
-BUILD_CFLAGS = -I/usr/local -g -W -Wall -Wundef -Wpointer-arith -Wcast-align \
+BUILD_CFLAGS = -g -W -Wall -Wundef -Wpointer-arith -Wcast-align \
-Wwrite-strings -Wmissing-declarations -Wuninitialized \
-Wno-unused-parameter
@@ -147,7 +147,7 @@ $(eval $(call pkg_config_find_and_add,libdom,DOM))
$(eval $(call pkg_config_find_and_add,libnsutils,nsutils))
# Common libraries without pkg-config support
-LDFLAGS += -L/usr/local -lz
+LDFLAGS += -lz
# Optional libraries with pkgconfig
@@ -324,7 +324,6 @@ endif
OBJECTS := $(sort $(addprefix $(OBJROOT)/,$(subst /,_,$(patsubst
%.c,%.o,$(patsubst %.cpp,%.o,$(patsubst %.m,%.o,$(patsubst
%.s,%.o,$(SOURCES))))))))
-
# Include directory flags
IFLAGS = $(addprefix -I,$(INCLUDE_DIRS))
--
NetSurf Browser
_______________________________________________
netsurf-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]