diff options
author | Michael Drake <michael.drake@codethink.co.uk> | 2021-02-09 20:30:53 +0000 |
---|---|---|
committer | Michael Drake <michael.drake@codethink.co.uk> | 2021-02-09 20:36:52 +0000 |
commit | 41a0c21812ed1fb59bf75cbe26a8b8c5e19e71a0 (patch) | |
tree | be96f960f9d821f9f65e6a0aaf992281a4984f9a | |
parent | 9434fe1ff08cb9e009efa9cd434177d91948d12e (diff) | |
download | netsurf-41a0c21812ed1fb59bf75cbe26a8b8c5e19e71a0.tar.gz |
html: Do list item counting at layout time.
-rw-r--r-- | content/handlers/html/box_construct.c | 101 | ||||
-rw-r--r-- | content/handlers/html/layout.c | 79 |
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); |