summaryrefslogtreecommitdiff
path: root/content
diff options
context:
space:
mode:
authorMichael Drake <michael.drake@codethink.co.uk>2021-02-09 20:30:53 +0000
committerMichael Drake <michael.drake@codethink.co.uk>2021-02-09 20:36:52 +0000
commit41a0c21812ed1fb59bf75cbe26a8b8c5e19e71a0 (patch)
treebe96f960f9d821f9f65e6a0aaf992281a4984f9a /content
parent9434fe1ff08cb9e009efa9cd434177d91948d12e (diff)
downloadnetsurf-41a0c21812ed1fb59bf75cbe26a8b8c5e19e71a0.tar.gz
netsurf-41a0c21812ed1fb59bf75cbe26a8b8c5e19e71a0.tar.bz2
html: Do list item counting at layout time.
Diffstat (limited to 'content')
-rw-r--r--content/handlers/html/box_construct.c101
-rw-r--r--content/handlers/html/layout.c79
2 files changed, 82 insertions, 98 deletions
diff --git a/content/handlers/html/box_construct.c b/content/handlers/html/box_construct.c
index a13357809..7bfc35e44 100644
--- a/content/handlers/html/box_construct.c
+++ b/content/handlers/html/box_construct.c
@@ -350,61 +350,6 @@ box_construct_generate(dom_node *n,
/**
- * compute the index for a list marker
- *
- * calculates a one based index of a list item
- */
-static unsigned int compute_list_marker_index(struct box *last)
-{
- /* Drill down into last child of parent
- * to find the list marker (if any)
- *
- * Floated list boxes end up as:
- *
- * parent
- * BOX_INLINE_CONTAINER
- * BOX_FLOAT_{LEFT,RIGHT}
- * BOX_BLOCK <-- list box
- * ...
- */
- while ((last != NULL) && (last->list_marker == NULL)) {
- struct box *last_inner = last;
-
- while (last_inner != NULL) {
- if (last_inner->list_marker != NULL) {
- break;
- }
- if (last_inner->type == BOX_INLINE_CONTAINER ||
- last_inner->type == BOX_FLOAT_LEFT ||
- last_inner->type == BOX_FLOAT_RIGHT) {
- last_inner = last_inner->last;
- } else {
- last_inner = NULL;
- }
- }
- if (last_inner != NULL) {
- last = last_inner;
- } else {
- last = last->prev;
- }
- }
-
- if ((last == NULL) || (last->list_marker == NULL)) {
- return 1;
- }
-
- return last->list_marker->rows + 1;
-}
-
-/**
- * initial length of a list marker buffer
- *
- * enough for 9,999,999,999,999,999,999 in decimal
- * or five characters for 4byte utf8
- */
-#define LIST_MARKER_SIZE 20
-
-/**
* Construct a list marker box
*
* \param box Box to attach marker to
@@ -422,8 +367,6 @@ box_construct_marker(struct box *box,
lwc_string *image_uri;
struct box *marker;
enum css_list_style_type_e list_style_type;
- size_t counter_len;
- css_error css_res;
marker = box_create(NULL, box->style, false, NULL, NULL, title,
NULL, ctx->bctx);
@@ -454,51 +397,13 @@ box_construct_marker(struct box *box,
marker->length = 3;
break;
+ default:
+ /* Numerical list counters get handled in layout. */
+ /* Fall through. */
case CSS_LIST_STYLE_TYPE_NONE:
marker->text = NULL;
marker->length = 0;
break;
-
- default:
- marker->rows = compute_list_marker_index(parent->last);
-
- marker->text = talloc_array(ctx->bctx, char, LIST_MARKER_SIZE);
- if (marker->text == NULL) {
- return false;
- }
-
- css_res = css_computed_format_list_style(box->style,
- marker->rows,
- marker->text,
- LIST_MARKER_SIZE,
- &counter_len);
- if (css_res == CSS_OK) {
- if (counter_len > LIST_MARKER_SIZE) {
- /*
- * use computed size as marker did not fit
- * in default allocation
- */
- marker->text = talloc_realloc(ctx->bctx,
- marker->text,
- char,
- counter_len);
- if (marker->text == NULL) {
- return false;
- }
- css_computed_format_list_style(box->style,
- marker->rows,
- marker->text,
- counter_len,
- &counter_len);
- }
- marker->length = counter_len;
- } else {
- /* failed to format marker so use none type */
- marker->text = NULL;
- marker->length = 0;
- }
- break;
-
}
if (css_computed_list_style_image(box->style, &image_uri) == CSS_LIST_STYLE_IMAGE_URI &&
diff --git a/content/handlers/html/layout.c b/content/handlers/html/layout.c
index 8303d7b35..2f222b9c9 100644
--- a/content/handlers/html/layout.c
+++ b/content/handlers/html/layout.c
@@ -4505,6 +4505,79 @@ layout__ordered_list_count(
box->rows = count;
}
+/**
+ * Set up the marker text for a numerical list item.
+ *
+ * \param[in] content The HTML content.
+ * \param[in] box The list item's main box.
+ */
+static void
+layout__set_numerical_marker_text(
+ const html_content *content,
+ struct box *box)
+{
+ struct box *marker = box->list_marker;
+ size_t counter_len;
+ css_error css_res;
+ enum {
+ /**
+ * initial length of a list marker buffer
+ *
+ * enough for 9,999,999,999,999,999,999 in decimal
+ * or five characters for 4-byte UTF-8.
+ */
+ LIST_MARKER_SIZE = 20,
+ };
+
+ marker->text = talloc_array(content->bctx, char, LIST_MARKER_SIZE);
+ if (marker->text == NULL) {
+ return;
+ }
+
+ css_res = css_computed_format_list_style(box->style, marker->rows,
+ marker->text, LIST_MARKER_SIZE, &counter_len);
+ if (css_res == CSS_OK) {
+ if (counter_len > LIST_MARKER_SIZE) {
+ /* Use computed size as marker did not fit in
+ * default allocation. */
+ marker->text = talloc_realloc(content->bctx,
+ marker->text,
+ char,
+ counter_len);
+ if (marker->text == NULL) {
+ return;
+ }
+ css_computed_format_list_style(box->style,
+ marker->rows, marker->text,
+ counter_len, &counter_len);
+ }
+ marker->length = counter_len;
+ }
+}
+
+/**
+ * Find out if box's style represents a numerical list style type.
+ *
+ * \param[in] b Box with style to test.
+ * \return true if box has numerical list style type, false otherwise.
+ */
+static bool
+layout__list_item_is_numerical(
+ const struct box *b)
+{
+ enum css_list_style_type_e t = css_computed_list_style_type(b->style);
+
+ switch (t) {
+ case CSS_LIST_STYLE_TYPE_DISC: /* Fall through. */
+ case CSS_LIST_STYLE_TYPE_CIRCLE: /* Fall through. */
+ case CSS_LIST_STYLE_TYPE_SQUARE: /* Fall through. */
+ case CSS_LIST_STYLE_TYPE_NONE:
+ return false;
+
+ default:
+ return true;
+ }
+}
/**
* Layout list markers.
@@ -4521,6 +4594,12 @@ layout_lists(const html_content *content, struct box *box)
for (child = box->children; child; child = child->next) {
if (child->list_marker) {
marker = child->list_marker;
+ if (layout__list_item_is_numerical(child)) {
+ if (marker->text == NULL) {
+ layout__set_numerical_marker_text(
+ content, child);
+ }
+ }
if (marker->object) {
marker->width =
content_get_width(marker->object);