summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Drake <tlsa@netsurf-browser.org>2022-08-27 13:00:57 +0100
committerMichael Drake <mdrake.unique@gmail.com>2022-08-29 13:49:20 +0100
commit8d4c3080202d5c9cb1ffe0b67448c0392c53028b (patch)
tree990847a2b6afd4e8ea56dc7a5290a13436917d7c
parent9a4646ccb841105404f153cfc5f76cfe3d61b35f (diff)
downloadlibcss-8d4c3080202d5c9cb1ffe0b67448c0392c53028b.tar.gz
libcss-8d4c3080202d5c9cb1ffe0b67448c0392c53028b.tar.bz2
Select: Properties: Implement copy handler for complex properties
-rw-r--r--src/select/properties/content.c47
-rw-r--r--src/select/properties/counter_increment.c48
-rw-r--r--src/select/properties/counter_reset.c48
-rw-r--r--src/select/properties/cursor.c48
-rw-r--r--src/select/properties/font_family.c57
-rw-r--r--src/select/properties/helpers.h133
-rw-r--r--src/select/properties/quotes.c56
-rw-r--r--src/select/properties/text_align.c24
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, &copy);
+ 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, &copy);
+ 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, &copy);
+ 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, &copy);
+ 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, &copy);
+ 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, &quotes);
-
- 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, &quotes);
- }
-
- if (quotes != NULL) {
- lwc_string **i;
+ uint8_t type = get_quotes(from, &quotes);
- 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, &copy);
+ 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, &quotes);
- 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);
}