From ae968ef84492ef65c91facd0e7ea1660e4c95a63 Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Sat, 3 Dec 2022 18:30:28 +0000 Subject: WIP: Add calc() handling to appropriate properties --- src/select/autogenerated_computed.h | 9 ++- src/select/autogenerated_propget.h | 6 +- src/select/autogenerated_propset.h | 34 +++++++++-- src/select/computed.c | 110 ++++++++++++++++++++++++++++++++++-- src/select/select_config.py | 4 +- 5 files changed, 146 insertions(+), 17 deletions(-) diff --git a/src/select/autogenerated_computed.h b/src/select/autogenerated_computed.h index c65cf98..ae9f09c 100644 --- a/src/select/autogenerated_computed.h +++ b/src/select/autogenerated_computed.h @@ -5,6 +5,11 @@ * Copyright 2017 The NetSurf Project */ +typedef union { + css_fixed value; + lwc_string *calc; +} css_fixed_or_calc; + struct css_computed_style_i { /* @@ -209,7 +214,7 @@ struct css_computed_style_i { css_fixed background_position_a; css_fixed background_position_b; css_color border_bottom_color; - css_fixed border_bottom_width; + css_fixed_or_calc border_bottom_width; css_color border_left_color; css_fixed border_left_width; css_color border_right_color; @@ -218,7 +223,7 @@ struct css_computed_style_i { css_fixed border_spacing_b; css_color border_top_color; css_fixed border_top_width; - css_fixed bottom; + css_fixed_or_calc bottom; css_fixed clip_a; css_fixed clip_b; css_fixed clip_c; diff --git a/src/select/autogenerated_propget.h b/src/select/autogenerated_propget.h index 6c958aa..7b6bac2 100644 --- a/src/select/autogenerated_propget.h +++ b/src/select/autogenerated_propget.h @@ -299,7 +299,7 @@ static inline uint8_t get_border_bottom_width_bits(const css_computed_style return (bits & 0x7); } static inline uint8_t get_border_bottom_width(const css_computed_style *style, - css_fixed *length, css_unit *unit) + css_fixed_or_calc *length, css_unit *unit) { uint32_t bits = style->i.bits[BORDER_BOTTOM_WIDTH_INDEX]; bits &= BORDER_BOTTOM_WIDTH_MASK; @@ -650,8 +650,8 @@ static inline uint8_t get_bottom_bits(const css_computed_style *style) /* 7bits: uuuuutt : unit | type */ return (bits & 0x3); } -static inline uint8_t get_bottom(const css_computed_style *style, css_fixed - *length, css_unit *unit) +static inline uint8_t get_bottom(const css_computed_style *style, + css_fixed_or_calc *length, css_unit *unit) { uint32_t bits = style->i.bits[BOTTOM_INDEX]; bits &= BOTTOM_MASK; diff --git a/src/select/autogenerated_propset.h b/src/select/autogenerated_propset.h index 71d1596..7d29755 100644 --- a/src/select/autogenerated_propset.h +++ b/src/select/autogenerated_propset.h @@ -5,8 +5,8 @@ * Copyright 2017 The NetSurf Project */ -/** Default values are 'initial value', unless the property is inherited, - * in which case it is 'inherit'. */ +#include "select/propget.h" + #define ALIGN_CONTENT_INDEX 10 #define ALIGN_CONTENT_SHIFT 20 @@ -222,15 +222,26 @@ static inline css_error set_border_bottom_style(css_computed_style *style, #define BORDER_BOTTOM_WIDTH_MASK 0xff static inline css_error set_border_bottom_width(css_computed_style *style, - uint8_t type, css_fixed length, css_unit unit) + uint8_t type, css_fixed_or_calc length, css_unit unit) { + uint32_t orig_bits = get_border_bottom_width_bits(style); + + /* 8bits: uuuuuttt : unit | type */ + if ((orig_bits & 0x7) == CSS_BORDER_WIDTH_WIDTH) { + if ((orig_bits & 0xf8) >> 3 == CSS_UNIT_CALC) { + lwc_string_unref(style->i.border_bottom_width.calc); + } + } + uint32_t *bits = &style->i.bits[BORDER_BOTTOM_WIDTH_INDEX]; /* 8bits: uuuuuttt : unit | type */ *bits = (*bits & ~BORDER_BOTTOM_WIDTH_MASK) | ((((uint32_t)type & 0x7) | (unit << 3)) << BORDER_BOTTOM_WIDTH_SHIFT); - style->i.border_bottom_width = length; + if (unit == CSS_UNIT_CALC) { + style->i.border_bottom_width.calc = lwc_string_ref(length.calc); + } return CSS_OK; } @@ -469,15 +480,26 @@ static inline css_error set_border_top_width(css_computed_style *style, uint8_t #define BOTTOM_MASK 0x3f800 static inline css_error set_bottom(css_computed_style *style, uint8_t type, - css_fixed length, css_unit unit) + css_fixed_or_calc length, css_unit unit) { + uint32_t orig_bits = get_bottom_bits(style); + + /* 7bits: uuuuutt : unit | type */ + if ((orig_bits & 0x3) == CSS_BOTTOM_SET) { + if ((orig_bits & 0x7c) >> 2 == CSS_UNIT_CALC) { + lwc_string_unref(style->i.bottom.calc); + } + } + uint32_t *bits = &style->i.bits[BOTTOM_INDEX]; /* 7bits: uuuuutt : unit | type */ *bits = (*bits & ~BOTTOM_MASK) | ((((uint32_t)type & 0x3) | (unit << 2)) << BOTTOM_SHIFT); - style->i.bottom = length; + if (unit == CSS_UNIT_CALC) { + style->i.bottom.calc = lwc_string_ref(length.calc); + } return CSS_OK; } diff --git a/src/select/computed.c b/src/select/computed.c index c257f17..2cc328d 100644 --- a/src/select/computed.c +++ b/src/select/computed.c @@ -30,6 +30,12 @@ static css_error compute_absolute_border_side_width(css_computed_style *style, css_fixed *len, css_unit *unit), css_error (*set)(css_computed_style *style, uint8_t type, css_fixed len, css_unit unit)); +static css_error compute_absolute_border_side_width_calc(css_computed_style *style, + const css_hint_length *ex_size, + uint8_t (*get)(const css_computed_style *style, + css_fixed_or_calc *len, css_unit *unit), + css_error (*set)(css_computed_style *style, uint8_t type, + css_fixed_or_calc len, css_unit unit)); static css_error compute_absolute_sides(css_computed_style *style, const css_hint_length *ex_size); static css_error compute_absolute_clip(css_computed_style *style, @@ -48,6 +54,12 @@ static css_error compute_absolute_length(css_computed_style *style, css_fixed *len, css_unit *unit), css_error (*set)(css_computed_style *style, uint8_t type, css_fixed len, css_unit unit)); +static css_error compute_absolute_length_calc(css_computed_style *style, + const css_hint_length *ex_size, + uint8_t (*get)(const css_computed_style *style, + css_fixed_or_calc *len, css_unit *unit), + css_error (*set)(css_computed_style *style, uint8_t type, + css_fixed_or_calc len, css_unit unit)); static css_error compute_absolute_length_pair(css_computed_style *style, const css_hint_length *ex_size, uint8_t (*get)(const css_computed_style *style, @@ -419,7 +431,20 @@ uint8_t css_computed_border_right_width(const css_computed_style *style, uint8_t css_computed_border_bottom_width(const css_computed_style *style, css_fixed *length, css_unit *unit) { - return get_border_bottom_width(style, length, unit); + css_fixed_or_calc temp; + uint8_t type = get_border_bottom_width(style, &temp, unit); + + if (type == CSS_BORDER_WIDTH_WIDTH) { + if (*unit == CSS_UNIT_CALC) { + *length = INTTOFIX(offsetof( + struct css_computed_style_i, + border_bottom_width)); + } else { + *length = temp.value; + } + } + + return type; } uint8_t css_computed_border_left_width(const css_computed_style *style, @@ -472,7 +497,7 @@ uint8_t css_computed_top(const css_computed_style *style, *unit = CSS_UNIT_PX; } else if (top == CSS_TOP_AUTO) { /* Top is auto => -bottom */ - *length = -style->i.bottom; + *length = -style->i.bottom.value; *unit = (css_unit) (bottom >> 2); } @@ -1448,7 +1473,7 @@ css_error compute_absolute_border_width(css_computed_style *style, if (error != CSS_OK) return error; - error = compute_absolute_border_side_width(style, ex_size, + error = compute_absolute_border_side_width_calc(style, ex_size, get_border_bottom_width, set_border_bottom_width); if (error != CSS_OK) @@ -1508,6 +1533,51 @@ css_error compute_absolute_border_side_width(css_computed_style *style, return set(style, CSS_BORDER_WIDTH_WIDTH, length, unit); } +/** + * Compute an absolute border side width + * + * \param style Style to process + * \param ex_size Ex size, in ems + * \param get Function to read length + * \param set Function to write length + * \return CSS_OK on success + */ +css_error compute_absolute_border_side_width_calc(css_computed_style *style, + const css_hint_length *ex_size, + uint8_t (*get)(const css_computed_style *style, + css_fixed_or_calc *len, css_unit *unit), + css_error (*set)(css_computed_style *style, uint8_t type, + css_fixed_or_calc len, css_unit unit)) +{ + css_fixed_or_calc length; + css_unit unit; + + switch (get(style, &length, &unit)) { + case CSS_BORDER_WIDTH_THIN: + length.value = INTTOFIX(1); + unit = CSS_UNIT_PX; + break; + case CSS_BORDER_WIDTH_MEDIUM: + length.value = INTTOFIX(2); + unit = CSS_UNIT_PX; + break; + case CSS_BORDER_WIDTH_THICK: + length.value = INTTOFIX(4); + unit = CSS_UNIT_PX; + break; + case CSS_BORDER_WIDTH_WIDTH: + if (unit == CSS_UNIT_EX) { + length.value = FMUL(length.value, ex_size->value); + unit = ex_size->unit; + } + break; + default: + return CSS_INVALID; + } + + return set(style, CSS_BORDER_WIDTH_WIDTH, length, unit); +} + /** * Compute absolute clip * @@ -1613,7 +1683,7 @@ css_error compute_absolute_sides(css_computed_style *style, if (error != CSS_OK) return error; - error = compute_absolute_length(style, ex_size, + error = compute_absolute_length_calc(style, ex_size, get_bottom, set_bottom); if (error != CSS_OK) return error; @@ -1759,6 +1829,38 @@ css_error compute_absolute_length(css_computed_style *style, return CSS_OK; } +/** + * Compute the absolute value of length + * + * \param style Style to process + * \param ex_size Ex size, in ems + * \param get Function to read length + * \param set Function to write length + * \return CSS_OK on success + */ +css_error compute_absolute_length_calc(css_computed_style *style, + const css_hint_length *ex_size, + uint8_t (*get)(const css_computed_style *style, + css_fixed_or_calc *len, css_unit *unit), + css_error (*set)(css_computed_style *style, uint8_t type, + css_fixed_or_calc len, css_unit unit)) +{ + css_unit unit = CSS_UNIT_PX; + css_fixed_or_calc length; + uint8_t type; + + type = get(style, &length, &unit); + + if (type == CSS_WIDTH_SET && unit == CSS_UNIT_EX) { + length.value = FMUL(length.value, ex_size->value); + unit = ex_size->unit; + + return set(style, type, length, unit); + } + + return CSS_OK; +} + /** * Compute the absolute value of length pair diff --git a/src/select/select_config.py b/src/select/select_config.py index fd9e765..bc22ea4 100644 --- a/src/select/select_config.py +++ b/src/select/select_config.py @@ -72,11 +72,11 @@ style = { ('border_left_color', 2, 'color'), ('border_top_width', 3, 'length', 'CSS_BORDER_WIDTH_WIDTH'), ('border_right_width', 3, 'length', 'CSS_BORDER_WIDTH_WIDTH'), - ('border_bottom_width', 3, 'length', 'CSS_BORDER_WIDTH_WIDTH'), + ('border_bottom_width', 3, (('length', None, 'calc'),), 'CSS_BORDER_WIDTH_WIDTH'), ('border_left_width', 3, 'length', 'CSS_BORDER_WIDTH_WIDTH'), ('top', 2, 'length', 'CSS_TOP_SET', None, None, 'get'), ('right', 2, 'length', 'CSS_RIGHT_SET', None, None, 'get'), - ('bottom', 2, 'length', 'CSS_BOTTOM_SET', None, None, 'get'), + ('bottom', 2, (('length', None, 'calc'),), 'CSS_BOTTOM_SET', None, None, 'get'), ('left', 2, 'length', 'CSS_LEFT_SET', None, None, 'get'), ('color', 1, 'color'), ('flex_basis', 2, 'length', 'CSS_FLEX_BASIS_SET'), -- cgit v1.2.3