summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Drake <tlsa@netsurf-browser.org>2022-12-03 18:28:54 +0000
committerMichael Drake <tlsa@netsurf-browser.org>2022-12-03 19:40:24 +0000
commitf5f4bf1abc8523c7c096cf66d83849bb43cc4c8e (patch)
treea76c7dffbfd678abf17076de7145fc1939f6a21a
parent05a9ed4f74162f8e53a4bc6620d7f8ca06b10434 (diff)
downloadlibcss-f5f4bf1abc8523c7c096cf66d83849bb43cc4c8e.tar.gz
select: Update computed style data structure for calc()
-rw-r--r--include/libcss/types.h4
-rw-r--r--src/parse/properties/font.c1
-rw-r--r--src/select/assets.py19
-rw-r--r--src/select/select_generator.py50
-rw-r--r--test/dump_computed.h3
5 files changed, 67 insertions, 10 deletions
diff --git a/include/libcss/types.h b/include/libcss/types.h
index 3fb28d3..c0b19da 100644
--- a/include/libcss/types.h
+++ b/include/libcss/types.h
@@ -109,7 +109,9 @@ typedef enum css_unit {
CSS_UNIT_S = 0x1a,
CSS_UNIT_HZ = 0x1b,
- CSS_UNIT_KHZ = 0x1c
+ CSS_UNIT_KHZ = 0x1c,
+
+ CSS_UNIT_CALC = 0x1d /**< Un-resolved calc() */
} css_unit;
/**
diff --git a/src/parse/properties/font.c b/src/parse/properties/font.c
index 7ce9701..b77e65c 100644
--- a/src/parse/properties/font.c
+++ b/src/parse/properties/font.c
@@ -45,6 +45,7 @@ static inline uint32_t css__to_parse_unit(css_unit u)
case CSS_UNIT_S: return UNIT_S;
case CSS_UNIT_HZ: return UNIT_HZ;
case CSS_UNIT_KHZ: return UNIT_KHZ;
+ case CSS_UNIT_CALC: assert(0);
}
return 0;
diff --git a/src/select/assets.py b/src/select/assets.py
index 67c6b6b..7786be4 100644
--- a/src/select/assets.py
+++ b/src/select/assets.py
@@ -12,16 +12,27 @@ copyright = '''\
*/
'''
+include_propget = '''\
+
+#include "select/propget.h"
+'''
+
+calc_unions = '''\
+
+typedef union {
+ css_fixed value;
+ lwc_string *calc;
+} css_fixed_or_calc;
+'''
+
assets = {}
assets['computed.h'] = {}
-assets['computed.h']['header'] = copyright
+assets['computed.h']['header'] = copyright + calc_unions
assets['computed.h']['footer'] = ''
assets['propset.h'] = {}
-assets['propset.h']['header'] = copyright + '''
-/** Default values are 'initial value', unless the property is inherited,
- * in which case it is 'inherit'. */'''
+assets['propset.h']['header'] = copyright + include_propget
assets['propset.h']['footer'] = ''
assets['propget.h'] = {}
diff --git a/src/select/select_generator.py b/src/select/select_generator.py
index 9e92909..2ea80e1 100644
--- a/src/select/select_generator.py
+++ b/src/select/select_generator.py
@@ -167,6 +167,7 @@ class CSSValue:
self.size = size # `None` means sizeof(ptr)
self.defaults = defaults
self.suffix = ''
+ self.calc = False
self.bits = None if bits_size is None else {
'name': bits_name,
'type': bits_type,
@@ -223,6 +224,13 @@ class CSSProperty:
def make_values(self, vals):
"""Make list of values for this property."""
+ self.has_calc = False
+
+ if vals is not None and any(len(val) > 2 and val[2] == 'calc' for val in vals):
+ self.has_calc = True
+
+ print(f"name: {self.name}, {vals}, has calc: {self.has_calc}")
+
if vals is None:
return []
elif type(vals) is str:
@@ -233,8 +241,10 @@ class CSSProperty:
for x in values:
if x[0] == v[0]:
value = CSSValue(*x)
- if len(v) == 2:
+ if len(v) > 1 and v[1] != None:
value.defaults = v[1]
+ if len(v) > 2 and v[2] == 'calc':
+ value.calc = True
if len(vals) > 1:
value.suffix = '_' + string.ascii_lowercase[i]
val_list.append(value)
@@ -322,13 +332,14 @@ class CSSProperty:
"""
vals = []
for v in self.values:
+ or_calc = '_or_calc' if v.calc else ''
star = '*' if pointer else ''
vt, vn = shift_star(v.type, v.name)
vn = star + vn + v.suffix
if pointer:
if v.name == 'counter_arr' or v.name == 'content_item':
vt = 'const ' + vt
- vals.append((vt, vn))
+ vals.append((vt + or_calc, vn))
if v.bits is not None:
bt = v.bits['type']
bn = star + v.bits['name'] + v.suffix
@@ -522,6 +533,25 @@ class CSSGroup:
t.append('{')
t.indent(1)
+ # Ensure any existing calc() values are freed
+ if p.has_calc:
+ t.append('uint32_t orig_bits = get_{}_bits(style);'.format(p.name))
+ t.append()
+
+ type_mask, shift_list, bits_comment = p.get_bits()
+ t.append(bits_comment)
+ t.append('if ((orig_bits & {}) == {}) {{'.format(type_mask, p.condition))
+ t.indent(1)
+ for i, v in enumerate(list(reversed(shift_list))):
+ t.append('if ((orig_bits & 0x{:x}) >> {} == CSS_UNIT_CALC) {{'.format(v[2], v[1]))
+ t.indent(1)
+ t.append('lwc_string_unref(style->i.{}.calc);'.format(p.name))
+ t.indent(-1)
+ t.append('}')
+ t.indent(-1)
+ t.append('}')
+ t.append()
+
t.append('uint32_t *bits = &style->i.bits[{}_INDEX];'.format(p.name.upper()))
t.append()
@@ -597,8 +627,14 @@ class CSSGroup:
t.append('}')
elif not v.is_ptr:
- t.append('style->i.{} = {};'.format(
- p.name + v.suffix, v.name + v.suffix))
+ if p.has_calc:
+ t.append('if (unit == CSS_UNIT_CALC) {')
+ t.append('\tstyle->i.{}.calc = lwc_string_ref({}.calc);'.format(
+ p.name + v.suffix, v.name + v.suffix))
+ t.append('}')
+ else:
+ t.append('style->i.{} = {};'.format(
+ p.name + v.suffix, v.name + v.suffix))
else:
raise ValueError('Cannot handle value ' + v.name +'!')
@@ -638,6 +674,7 @@ class CSSGroup:
t.indent(1)
for v in p.values:
+ print(f"name: {p.name}, has_calc: {p.has_calc}, v.name: {v.name}")
i_dot = '' if v.is_ptr and v.name != 'string' else 'i.'
t.append('*{} = style->{}{};'.format(
v.name + v.suffix, i_dot, p.name + v.suffix))
@@ -690,9 +727,12 @@ class CSSGroup:
r = []
for p in sorted(self.props, key=(lambda x: x.name)):
if bool(p.comments) == for_commented:
+ if (p.values == None or len(p.values) == 0):
+ continue
for v in p.values:
+ or_calc = '_or_calc' if v.calc else ''
v_type, v_name = shift_star(v.type, p.name)
- r.append('{} {}{};'.format(v_type, v_name, v.suffix))
+ r.append('{} {}{};'.format(v_type + or_calc, v_name, v.suffix))
return r
def make_text(self, filename):
diff --git a/test/dump_computed.h b/test/dump_computed.h
index 2ce7849..fd6923b 100644
--- a/test/dump_computed.h
+++ b/test/dump_computed.h
@@ -159,6 +159,9 @@ static size_t dump_css_unit(css_fixed val, css_unit unit, char *ptr, size_t len)
case CSS_UNIT_KHZ:
ret += snprintf(ptr + ret, len - ret, "kHz");
break;
+ case CSS_UNIT_CALC:
+ ret += snprintf(ptr + ret, len - ret, "calc()");
+ break;
}
return ret;