From 8d4c3080202d5c9cb1ffe0b67448c0392c53028b Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Sat, 27 Aug 2022 13:00:57 +0100 Subject: Select: Properties: Implement copy handler for complex properties --- src/select/properties/content.c | 47 +++++------ src/select/properties/counter_increment.c | 48 +++++------ src/select/properties/counter_reset.c | 48 +++++------ src/select/properties/cursor.c | 48 +++++------ src/select/properties/font_family.c | 57 +++++++------ src/select/properties/helpers.h | 133 ++++++++++++++++++++++++++++++ src/select/properties/quotes.c | 56 ++++++------- src/select/properties/text_align.c | 24 ++++-- 8 files changed, 306 insertions(+), 155 deletions(-) diff --git a/src/select/properties/content.c b/src/select/properties/content.c index df79fe1..32af49f 100644 --- a/src/select/properties/content.c +++ b/src/select/properties/content.c @@ -199,39 +199,40 @@ css_error css__initial_content(css_select_state *state) return set_content(state->computed, CSS_CONTENT_NORMAL, NULL); } -css_error css__compose_content(const css_computed_style *parent, - const css_computed_style *child, - css_computed_style *result) +css_error css__copy_content( + const css_computed_style *from, + css_computed_style *to) { css_error error; css_computed_content_item *copy = NULL; const css_computed_content_item *items = NULL; - uint8_t type = get_content(child, &items); + uint8_t type = get_content(from, &items); - if (type == CSS_CONTENT_INHERIT) { - type = get_content(parent, &items); + if (from == to) { + return CSS_OK; } - if (type == CSS_CONTENT_SET) { - size_t n_items = 0; - const css_computed_content_item *i; - - for (i = items; i->type != CSS_COMPUTED_CONTENT_NONE; - i++) - n_items++; - - copy = malloc((n_items + 1) * - sizeof(css_computed_content_item)); - if (copy == NULL) - return CSS_NOMEM; - - memcpy(copy, items, (n_items + 1) * - sizeof(css_computed_content_item)); + error = css__copy_computed_content_item_array(false, items, ©); + if (error != CSS_OK) { + return CSS_NOMEM; } - error = set_content(result, type, copy); - if (error != CSS_OK && copy != NULL) + error = set_content(to, type, copy); + if (error != CSS_OK) { free(copy); + } return error; } + +css_error css__compose_content(const css_computed_style *parent, + const css_computed_style *child, + css_computed_style *result) +{ + const css_computed_content_item *items = NULL; + uint8_t type = get_content(child, &items); + + return css__copy_content( + type == CSS_CONTENT_INHERIT ? parent : child, + result); +} diff --git a/src/select/properties/counter_increment.c b/src/select/properties/counter_increment.c index 1b75c25..2638838 100644 --- a/src/select/properties/counter_increment.c +++ b/src/select/properties/counter_increment.c @@ -48,38 +48,40 @@ css_error css__initial_counter_increment(css_select_state *state) CSS_COUNTER_INCREMENT_NONE, NULL); } -css_error css__compose_counter_increment(const css_computed_style *parent, - const css_computed_style *child, - css_computed_style *result) +css_error css__copy_counter_increment( + const css_computed_style *from, + css_computed_style *to) { css_error error; css_computed_counter *copy = NULL; - const css_computed_counter *items = NULL; - uint8_t type = get_counter_increment(child, &items); + const css_computed_counter *counter_increment = NULL; + uint8_t type = get_counter_increment(from, &counter_increment); - if (type == CSS_COUNTER_INCREMENT_INHERIT) { - type = get_counter_increment(parent, &items); + if (from == to) { + return CSS_OK; } - if (type == CSS_COUNTER_INCREMENT_NAMED && items != NULL) { - size_t n_items = 0; - const css_computed_counter *i; - - for (i = items; i->name != NULL; i++) - n_items++; - - copy = malloc((n_items + 1) * - sizeof(css_computed_counter)); - if (copy == NULL) - return CSS_NOMEM; - - memcpy(copy, items, (n_items + 1) * - sizeof(css_computed_counter)); + error = css__copy_computed_counter_array(false, counter_increment, ©); + if (error != CSS_OK) { + return CSS_NOMEM; } - error = set_counter_increment(result, type, copy); - if (error != CSS_OK && copy != NULL) + error = set_counter_increment(to, type, copy); + if (error != CSS_OK) { free(copy); + } return error; } + +css_error css__compose_counter_increment(const css_computed_style *parent, + const css_computed_style *child, + css_computed_style *result) +{ + const css_computed_counter *counter_increment = NULL; + uint8_t type = get_counter_increment(child, &counter_increment); + + return css__copy_counter_increment( + type == CSS_COUNTER_INCREMENT_INHERIT ? parent : child, + result); +} diff --git a/src/select/properties/counter_reset.c b/src/select/properties/counter_reset.c index e4ec8bf..fcb39a3 100644 --- a/src/select/properties/counter_reset.c +++ b/src/select/properties/counter_reset.c @@ -47,38 +47,40 @@ css_error css__initial_counter_reset(css_select_state *state) return set_counter_reset(state->computed, CSS_COUNTER_RESET_NONE, NULL); } -css_error css__compose_counter_reset(const css_computed_style *parent, - const css_computed_style *child, - css_computed_style *result) +css_error css__copy_counter_reset( + const css_computed_style *from, + css_computed_style *to) { css_error error; css_computed_counter *copy = NULL; - const css_computed_counter *items = NULL; - uint8_t type = get_counter_reset(child, &items); + const css_computed_counter *counter_reset = NULL; + uint8_t type = get_counter_reset(from, &counter_reset); - if (type == CSS_COUNTER_RESET_INHERIT) { - type = get_counter_reset(parent, &items); + if (from == to) { + return CSS_OK; } - if (type == CSS_COUNTER_RESET_NAMED && items != NULL) { - size_t n_items = 0; - const css_computed_counter *i; - - for (i = items; i->name != NULL; i++) - n_items++; - - copy = malloc((n_items + 1) * - sizeof(css_computed_counter)); - if (copy == NULL) - return CSS_NOMEM; - - memcpy(copy, items, (n_items + 1) * - sizeof(css_computed_counter)); + error = css__copy_computed_counter_array(false, counter_reset, ©); + if (error != CSS_OK) { + return CSS_NOMEM; } - error = set_counter_reset(result, type, copy); - if (error != CSS_OK && copy != NULL) + error = set_counter_reset(to, type, copy); + if (error != CSS_OK) { free(copy); + } return error; } + +css_error css__compose_counter_reset(const css_computed_style *parent, + const css_computed_style *child, + css_computed_style *result) +{ + const css_computed_counter *counter_reset = NULL; + uint8_t type = get_counter_reset(child, &counter_reset); + + return css__copy_counter_reset( + type == CSS_COUNTER_RESET_INHERIT ? parent : child, + result); +} diff --git a/src/select/properties/cursor.c b/src/select/properties/cursor.c index 7b1e39b..09955c6 100644 --- a/src/select/properties/cursor.c +++ b/src/select/properties/cursor.c @@ -164,38 +164,40 @@ css_error css__initial_cursor(css_select_state *state) return set_cursor(state->computed, CSS_CURSOR_AUTO, NULL); } -css_error css__compose_cursor(const css_computed_style *parent, - const css_computed_style *child, - css_computed_style *result) +css_error css__copy_cursor( + const css_computed_style *from, + css_computed_style *to) { css_error error; lwc_string **copy = NULL; - lwc_string **urls = NULL; - uint8_t type = get_cursor(child, &urls); + lwc_string **cursor = NULL; + uint8_t type = get_cursor(from, &cursor); - if (type == CSS_CURSOR_INHERIT) { - type = get_cursor(parent, &urls); + if (from == to) { + return CSS_OK; } - if (urls != NULL) { - lwc_string **i; - size_t n_urls = 0; - - for (i = urls; (*i) != NULL; i++) - n_urls++; - - copy = malloc((n_urls + 1) * - sizeof(lwc_string *)); - if (copy == NULL) - return CSS_NOMEM; - - memcpy(copy, urls, (n_urls + 1) * - sizeof(lwc_string *)); + error = css__copy_lwc_string_array(false, cursor, ©); + if (error != CSS_OK) { + return CSS_NOMEM; } - error = set_cursor(result, type, copy); - if (error != CSS_OK && copy != NULL) + error = set_cursor(to, type, copy); + if (error != CSS_OK) { free(copy); + } return error; } + +css_error css__compose_cursor(const css_computed_style *parent, + const css_computed_style *child, + css_computed_style *result) +{ + lwc_string **cursor = NULL; + uint8_t type = get_cursor(child, &cursor); + + return css__copy_cursor( + type == CSS_CURSOR_INHERIT ? parent : child, + result); +} diff --git a/src/select/properties/font_family.c b/src/select/properties/font_family.c index 30e746c..b0183e2 100644 --- a/src/select/properties/font_family.c +++ b/src/select/properties/font_family.c @@ -182,42 +182,41 @@ css_error css__initial_font_family(css_select_state *state) return css__set_font_family_from_hint(&hint, state->computed); } -css_error css__compose_font_family(const css_computed_style *parent, - const css_computed_style *child, - css_computed_style *result) +css_error css__copy_font_family( + const css_computed_style *from, + css_computed_style *to) { css_error error; - lwc_string **names = NULL; - uint8_t type = get_font_family(child, &names); - - if (type == CSS_FONT_FAMILY_INHERIT || result != child) { - size_t n_names = 0; - lwc_string **copy = NULL; - - if (type == CSS_FONT_FAMILY_INHERIT) - type = get_font_family(parent, &names); + lwc_string **copy = NULL; + lwc_string **font_family = NULL; + uint8_t type = get_font_family(from, &font_family); - if (names != NULL) { - lwc_string **i; - - for (i = names; (*i) != NULL; i++) - n_names++; + if (from == to) { + return CSS_OK; + } - copy = malloc((n_names + 1) * sizeof(lwc_string *)); - if (copy == NULL) - return CSS_NOMEM; + error = css__copy_lwc_string_array(false, font_family, ©); + if (error != CSS_OK) { + return CSS_NOMEM; + } - memcpy(copy, names, (n_names + 1) * - sizeof(lwc_string *)); - } + error = set_font_family(to, type, copy); + if (error != CSS_OK) { + free(copy); + } - error = set_font_family(result, type, copy); - if (error != CSS_OK && copy != NULL) - free(copy); + return error; +} - return error; - } +css_error css__compose_font_family(const css_computed_style *parent, + const css_computed_style *child, + css_computed_style *result) +{ + lwc_string **font_family = NULL; + uint8_t type = get_font_family(child, &font_family); - return CSS_OK; + return css__copy_font_family( + type == CSS_FONT_FAMILY_INHERIT ? parent : child, + result); } diff --git a/src/select/properties/helpers.h b/src/select/properties/helpers.h index 60e5b4c..16c5d7a 100644 --- a/src/select/properties/helpers.h +++ b/src/select/properties/helpers.h @@ -59,4 +59,137 @@ css_error css__cascade_counter_increment_reset(uint32_t opv, css_style *style, css_error (*fun)(css_computed_style *, uint8_t, css_computed_counter *)); +/** Copy NULL terminated array of lwc_string pointers. */ +static inline css_error css__copy_lwc_string_array( + bool ref, + lwc_string *const*orig, + lwc_string ***copy_out) +{ + size_t count = 0; + lwc_string **copy = NULL; + + if (orig != NULL) { + for (lwc_string *const*i = orig; (*i) != NULL; i++) { + count++; + } + + copy = malloc((count + 1) * sizeof(*copy)); + if (copy == NULL) { + return CSS_NOMEM; + } + + if (ref) { + for (size_t i = 0; i < count; i++) { + copy[i] = lwc_string_ref(orig[i]); + } + copy[count] = NULL; + } else { + memcpy(copy, orig, (count + 1) * sizeof(*copy)); + } + } + + *copy_out = copy; + return CSS_OK; +} + +/** Copy NULL-name terminated array of css_computed_counter items. */ +static inline css_error css__copy_computed_counter_array( + bool ref, + const css_computed_counter *orig, + css_computed_counter **copy_out) +{ + size_t count = 0; + css_computed_counter *copy = NULL; + + if (orig != NULL) { + for (const css_computed_counter *i = orig; + i->name != NULL; i++) { + count++; + } + + copy = malloc((count + 1) * sizeof(*copy)); + if (copy == NULL) { + return CSS_NOMEM; + } + + if (ref) { + for (size_t i = 0; i < count; i++) { + copy[i].name = lwc_string_ref(orig[i].name); + copy[i].value = orig[i].value; + } + copy[count].name = NULL; + copy[count].value = 0; + } else { + memcpy(copy, orig, (count + 1) * sizeof(*copy)); + } + } + + *copy_out = copy; + return CSS_OK; +} + +/** Copy type:none terminated array of css_computed_content_item items. */ +static inline css_error css__copy_computed_content_item_array( + bool ref, + const css_computed_content_item *orig, + css_computed_content_item **copy_out) +{ + size_t count = 0; + css_computed_content_item *copy = NULL; + + if (orig != NULL) { + for (const css_computed_content_item *i = orig; + i->type != CSS_COMPUTED_CONTENT_NONE; i++) { + count++; + } + + copy = malloc((count + 1) * sizeof(*copy)); + if (copy == NULL) { + return CSS_NOMEM; + } + + if (ref) { + for (size_t i = 0; i < count; i++) { + switch (orig[i].type) { + case CSS_COMPUTED_CONTENT_STRING: + copy[i].data.string = lwc_string_ref( + orig[i].data.string); + break; + case CSS_COMPUTED_CONTENT_URI: + copy[i].data.uri = lwc_string_ref( + orig[i].data.uri); + break; + case CSS_COMPUTED_CONTENT_ATTR: + copy[i].data.attr = lwc_string_ref( + orig[i].data.attr); + break; + case CSS_COMPUTED_CONTENT_COUNTER: + copy[i].data.counter.name = lwc_string_ref( + orig[i].data.counter.name); + copy[i].data.counter.style = + orig[i].data.counter.style; + break; + case CSS_COMPUTED_CONTENT_COUNTERS: + copy[i].data.counters.name = lwc_string_ref( + orig[i].data.counters.name); + copy[i].data.counters.sep = lwc_string_ref( + orig[i].data.counters.sep); + copy[i].data.counters.style = + orig[i].data.counters.style; + break; + default: + break; + } + copy[i].type = orig[i].type; + } + copy[count].type = CSS_COMPUTED_CONTENT_NONE; + } else { + memcpy(copy, orig, (count + 1) * sizeof(*copy)); + } + } + + *copy_out = copy; + return CSS_OK; +} + #endif diff --git a/src/select/properties/quotes.c b/src/select/properties/quotes.c index 9152f84..57fc48c 100644 --- a/src/select/properties/quotes.c +++ b/src/select/properties/quotes.c @@ -123,43 +123,41 @@ css_error css__initial_quotes(css_select_state *state) return css__set_quotes_from_hint(&hint, state->computed); } -css_error css__compose_quotes(const css_computed_style *parent, - const css_computed_style *child, - css_computed_style *result) +css_error css__copy_quotes( + const css_computed_style *from, + css_computed_style *to) { css_error error; + lwc_string **copy = NULL; lwc_string **quotes = NULL; - uint8_t type = get_quotes(child, "es); - - if (type == CSS_QUOTES_INHERIT || result != child) { - size_t n_quotes = 0; - lwc_string **copy = NULL; - - if (type == CSS_QUOTES_INHERIT) { - type = get_quotes(parent, "es); - } - - if (quotes != NULL) { - lwc_string **i; + uint8_t type = get_quotes(from, "es); - for (i = quotes; (*i) != NULL; i++) - n_quotes++; + if (from == to) { + return CSS_OK; + } - copy = malloc((n_quotes + 1) * sizeof(lwc_string *)); - if (copy == NULL) - return CSS_NOMEM; + error = css__copy_lwc_string_array(false, quotes, ©); + if (error != CSS_OK) { + return CSS_NOMEM; + } - memcpy(copy, quotes, (n_quotes + 1) * - sizeof(lwc_string *)); - } + error = set_quotes(to, type, copy); + if (error != CSS_OK) { + free(copy); + } - error = set_quotes(result, type, copy); - if (error != CSS_OK && copy != NULL) - free(copy); + return error; +} - return error; - } +css_error css__compose_quotes(const css_computed_style *parent, + const css_computed_style *child, + css_computed_style *result) +{ + lwc_string **quotes = NULL; + uint8_t type = get_quotes(child, "es); - return CSS_OK; + return css__copy_quotes( + type == CSS_QUOTES_INHERIT ? parent : child, + result); } diff --git a/src/select/properties/text_align.c b/src/select/properties/text_align.c index f2ba4e6..303f8f5 100644 --- a/src/select/properties/text_align.c +++ b/src/select/properties/text_align.c @@ -66,15 +66,24 @@ css_error css__initial_text_align(css_select_state *state) return set_text_align(state->computed, CSS_TEXT_ALIGN_DEFAULT); } +css_error css__copy_text_align( + const css_computed_style *from, + css_computed_style *to) +{ + if (from == to) { + return CSS_OK; + } + + return set_text_align(to, get_text_align(from)); +} + css_error css__compose_text_align(const css_computed_style *parent, const css_computed_style *child, css_computed_style *result) { uint8_t type = get_text_align(child); - if (type == CSS_TEXT_ALIGN_INHERIT) { - type = get_text_align(parent); - } else if (type == CSS_TEXT_ALIGN_INHERIT_IF_NON_MAGIC) { + if (type == CSS_TEXT_ALIGN_INHERIT_IF_NON_MAGIC) { /* This is purely for the benefit of HTML tables */ type = get_text_align(parent); @@ -83,10 +92,15 @@ css_error css__compose_text_align(const css_computed_style *parent, * inherit as normal. */ if (type == CSS_TEXT_ALIGN_LIBCSS_LEFT || type == CSS_TEXT_ALIGN_LIBCSS_CENTER || - type == CSS_TEXT_ALIGN_LIBCSS_RIGHT) + type == CSS_TEXT_ALIGN_LIBCSS_RIGHT) { type = CSS_TEXT_ALIGN_DEFAULT; + } + + return set_text_align(result, type); } - return set_text_align(result, type); + return css__copy_text_align( + type == CSS_TEXT_ALIGN_INHERIT ? parent : child, + result); } -- cgit v1.2.1