Gitweb links:

...log 
http://git.netsurf-browser.org/libcss.git/shortlog/99e5168ecb0f7203ed0d4d6ce2f08f092760029b
...commit 
http://git.netsurf-browser.org/libcss.git/commit/99e5168ecb0f7203ed0d4d6ce2f08f092760029b
...tree 
http://git.netsurf-browser.org/libcss.git/tree/99e5168ecb0f7203ed0d4d6ce2f08f092760029b

The branch, lcneves/units has been updated
       via  99e5168ecb0f7203ed0d4d6ce2f08f092760029b (commit)
      from  16505397bc2d474e365d0b7a3b57e1b81fd28661 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commitdiff 
http://git.netsurf-browser.org/libcss.git/commit/?id=99e5168ecb0f7203ed0d4d6ce2f08f092760029b
commit 99e5168ecb0f7203ed0d4d6ce2f08f092760029b
Author: Lucas Neves <[email protected]>
Commit: Lucas Neves <[email protected]>

    WIP: Select: autogen for selection properties.

diff --git a/src/select/__pycache__/assets.cpython-36.pyc 
b/src/select/__pycache__/assets.cpython-36.pyc
index 9b622ce..b5bf9ca 100644
Binary files a/src/select/__pycache__/assets.cpython-36.pyc and 
b/src/select/__pycache__/assets.cpython-36.pyc differ
diff --git a/src/select/__pycache__/select_config.cpython-36.pyc 
b/src/select/__pycache__/select_config.cpython-36.pyc
index 55e01f8..3fdda2a 100644
Binary files a/src/select/__pycache__/select_config.cpython-36.pyc and 
b/src/select/__pycache__/select_config.cpython-36.pyc differ
diff --git a/src/select/assets.py b/src/select/assets.py
index 91bf92a..3f6b7d1 100644
--- a/src/select/assets.py
+++ b/src/select/assets.py
@@ -59,6 +59,27 @@ css_error css__compute_absolute_values(const 
css_computed_style *parent,
                        const css_hint *parent, css_hint *size),
                void *pw);
 
-#endif
-'''
+#endif'''
+
+assets['propset.h'] = {}
+assets['propset.h']['header'] = copyright + '''\
+/*
+ * This file is part of LibCSS
+ * Licensed under the MIT License,
+ *                http://www.opensource.org/licenses/mit-license.php
+ * Copyright 2009 John-Mark Bell <[email protected]>
+ */
+
+#ifndef css_select_propset_h_
+#define css_select_propset_h_
+
+#include <string.h>
+
+#include <libcss/computed.h>
+#include "computed.h"
+
+/** Default values are 'initial value', unless the property is inherited,
+ *  in which case it is 'inherit'. */'''
+assets['propset.h']['footer'] = '''
+#endif'''
 
diff --git a/src/select/autogenerated_computed.h 
b/src/select/autogenerated_computed.h
index a76c528..a319a58 100644
--- a/src/select/autogenerated_computed.h
+++ b/src/select/autogenerated_computed.h
@@ -13,6 +13,7 @@
 
 
 
+struct css_computed_uncommon_i {
 /*
  * Property                       Size (bits)     Size (bytes)
  * ---                            ---             ---
@@ -52,10 +53,60 @@
  * entry
  * 
  * cursor                           5             sizeof(ptr)
+ * 
  * ---                            ---             ---
  *                                116 bits         60 + 4sizeof(ptr) bytes
+ *                                ===================
+ *                                 75 + 4sizeof(ptr) bytes
+ * 
+ * Bit allocations:
+ * 
+ * 0  bbbbbbbbbbbccccccccoooooooouuuuu
+ * border_spacing; column_rule_width; outline_width; cursor
+ * 
+ * 1  wwwwwwwlllllllcccccccooooooobbbb
+ * word_spacing; letter_spacing; column_width; column_gap; break_before
+ * 
+ * 2  ccccccccccccccccccccccccccbbbboo
+ * clip; break_after; column_fill
+ * 
+ * 3  ccccbbbboolluuttnner............
+ * column_rule_style; break_inside; column_span; column_count;
+ * column_rule_color; outline_color; content; counter_increment; counter_reset
  */
+       uint32_t bits[4];
+       
+       css_fixed border_spacing_a;
+       css_fixed border_spacing_b;
+       css_fixed clip_a;
+       css_fixed clip_b;
+       css_fixed clip_c;
+       css_fixed clip_d;
+       int32_t column_count;
+       css_fixed column_gap;
+       css_color column_rule_color;
+       css_fixed column_rule_width;
+       css_fixed column_width;
+       css_fixed letter_spacing;
+       css_color outline_color;
+       css_fixed outline_width;
+       css_fixed word_spacing;
+};
 
+typedef struct css_computed_uncommon {
+       struct css_computed_uncommon_i i;
+       
+       css_computed_content_item *content;
+       css_computed_counter *counter_increment;
+       css_computed_counter *counter_reset;
+       lwc_string **cursor;
+       
+       struct css_computed_uncommon *next;
+       uint32_t count;
+       uint32_t bin;
+} css_computed_uncommon;
+
+typedef struct css_computed_page {
 /*
  * Property                       Size (bits)     Size (bytes)
  * ---                            ---             ---
@@ -65,10 +116,24 @@
  * page_break_inside                2             
  * widows                           1               4
  * 
+ * 
  * ---                            ---             ---
  *                                 10 bits          8 bytes
+ *                                ===================
+ *                                 10 bytes
+ * 
+ * Bit allocations:
+ * 
+ * 0  pppaaaggwo......................
+ * page_break_after; page_break_before; page_break_inside; widows; orphans
  */
+       uint32_t bits[1];
+       
+       int32_t orphans;
+       int32_t widows;
+} css_computed_page;
 
+struct css_computed_style_i {
 /*
  * Property                       Size (bits)     Size (bytes)
  * ---                            ---             ---
@@ -157,9 +222,115 @@
  * Encode quotes as an array of string objects, terminated with a blank entry.
  * 
  * quotes                           1             sizeof(ptr)
+ * 
  * ---                            ---             ---
  *                                329 bits        160 + 4sizeof(ptr) bytes
+ *                                ===================
+ *                                202 + 4sizeof(ptr) bytes
+ * 
+ * Bit allocations:
+ * 
+ * 0  bbbbbbbboooooooorrrrrrrrdddddddd
+ * border_bottom_width; border_left_width; border_top_width; border_right_width
+ * 
+ * 1  mmmmmmmbbbbbbbaaaaaaaiiiiiiioooo
+ * max_height; bottom; margin_bottom; min_height; border_left_style
+ * 
+ * 2  hhhhhhhrrrrrrrmmmmmmmaaaaaaatttt
+ * height; right; margin_top; margin_right; text_align
+ * 
+ * 3  mmmmmmmtttttttffffffflllllllbbbb
+ * max_width; top; flex_basis; line_height; border_right_style
+ * 
+ * 4  wwwwwwwmmmmmmmiiiiiiilllllllffff
+ * width; margin_left; min_width; left; font_weight
+ * 
+ * 5  bbbbbbbbbbbvvvvvvvvvfffffffffaaa
+ * background_position; vertical_align; font_size; align_content
+ * 
+ * 6  dddddtttttoooollllbbbbrrrraaaiii
+ * display; text_decoration; outline_style; list_style_type;
+ * border_bottom_style; border_top_style; align_items; align_self
+ * 
+ * 7  ppppppaaaaaaddddddttttttiiiiiicc
+ * padding_bottom; padding_left; padding_top; text_indent; padding_right;
+ * caption_side
+ * 
+ * 8  bboorrvvttddffaanniillcczzuueess
+ * border_bottom_color; border_collapse; border_left_color; visibility;
+ * table_layout; border_top_color; flex_wrap; background_attachment;
+ * font_style; font_variant; float; background_color; z_index; unicode_bidi;
+ * border_right_color; list_style_position
+ * 
+ * 9  wwwbbbcccfffooopppnnnjjjttteexxa
+ * white_space; background_repeat; clear; flex_direction; overflow; position;
+ * font_family; justify_content; text_transform; empty_cells; box_sizing;
+ * opacity
+ * 
+ * 10 ddfbcliqo.......................
+ * direction; flex_grow; background_image; color; flex_shrink;
+ * list_style_image; quotes; order
  */
+       uint32_t bits[11];
+       
+       css_color background_color;
+       lwc_string *background_image;
+       css_fixed background_position_a;
+       css_fixed background_position_b;
+       css_color border_bottom_color;
+       css_fixed border_bottom_width;
+       css_color border_left_color;
+       css_fixed border_left_width;
+       css_color border_right_color;
+       css_fixed border_right_width;
+       css_color border_top_color;
+       css_fixed border_top_width;
+       css_fixed bottom;
+       css_color color;
+       css_fixed flex_basis;
+       css_fixed flex_grow;
+       css_fixed flex_shrink;
+       css_fixed font_size;
+       css_fixed height;
+       css_fixed left;
+       css_fixed line_height;
+       lwc_string *list_style_image;
+       css_fixed margin_bottom;
+       css_fixed margin_left;
+       css_fixed margin_right;
+       css_fixed margin_top;
+       css_fixed max_height;
+       css_fixed max_width;
+       css_fixed min_height;
+       css_fixed min_width;
+       css_fixed opacity;
+       int32_t order;
+       css_fixed padding_bottom;
+       css_fixed padding_left;
+       css_fixed padding_right;
+       css_fixed padding_top;
+       css_fixed right;
+       css_fixed text_indent;
+       css_fixed top;
+       css_fixed vertical_align;
+       css_fixed width;
+       int32_t z_index;
+       
+       css_computed_uncommon *uncommon;
+       void *aural;
+};
+
+struct css_computed_style {
+       struct css_computed_style_i i;
+       
+       lwc_string **font_family;
+       lwc_string **quotes;
+       
+       css_computed_page *page;
+       struct css_computed_style *next;
+       uint32_t count;
+       uint32_t bin;
+};
 /**
  * Take a new reference to a computed style
  *
@@ -194,4 +365,4 @@ css_error css__compute_absolute_values(const 
css_computed_style *parent,
                        const css_hint *parent, css_hint *size),
                void *pw);
 
-#endif
+#endif
\ No newline at end of file
diff --git a/src/select/autogenerated_propset.h 
b/src/select/autogenerated_propset.h
new file mode 100644
index 0000000..4976929
--- /dev/null
+++ b/src/select/autogenerated_propset.h
@@ -0,0 +1,60 @@
+/*
+ * This file is part of LibCSS
+ * Licensed under the MIT License,
+ *                http://www.opensource.org/licenses/mit-license.php
+ * Copyright 2017 The NetSurf Project
+ */
+
+/*
+ * This file is part of LibCSS
+ * Licensed under the MIT License,
+ *                http://www.opensource.org/licenses/mit-license.php
+ * Copyright 2009 John-Mark Bell <[email protected]>
+ */
+
+#ifndef css_select_propset_h_
+#define css_select_propset_h_
+
+#include <string.h>
+
+#include <libcss/computed.h>
+#include "computed.h"
+
+/** Default values are 'initial value', unless the property is inherited,
+ *  in which case it is 'inherit'. */
+static const css_computed_uncommon default_uncommon = {
+       .i = {
+               .bits = {
+                       (CSS_BORDER_SPACING_SET << 21) | (
+                                       CSS_COLUMN_RULE_WIDTH_MEDIUM << 13) | (
+                                       CSS_OUTLINE_WIDTH_MEDIUM << 5) |
+                                       CSS_CURSOR_INHERIT,
+                       (CSS_WORD_SPACING_NORMAL << 25) | (
+                                       CSS_LETTER_SPACING_NORMAL << 18) | (
+                                       CSS_COLUMN_WIDTH_AUTO << 11) | (
+                                       CSS_COLUMN_GAP_NORMAL << 4) |
+                                       CSS_BREAK_BEFORE_AUTO,
+                       (CSS_CLIP_AUTO << 6) | (CSS_BREAK_AFTER_AUTO << 2) |
+                                       CSS_COLUMN_FILL_BALANCE,
+                       (CSS_COLUMN_RULE_STYLE_NONE << 28) | (
+                                       CSS_BREAK_INSIDE_AUTO << 24) | (
+                                       CSS_COLUMN_SPAN_NONE << 22) | (
+                                       CSS_COLUMN_COUNT_AUTO << 20) | (
+                                       CSS_COLUMN_RULE_CURRENT_COLOR << 18) | (
+                                       CSS_OUTLINE_COLOR_INVERT << 16) | (
+                                       CSS_CONTENT_NORMAL << 14) | (
+                                       CSS_COUNTER_INCREMENT_NONE << 13) | (
+                                       CSS_COUNTER_RESET_NONE << 12)
+               },
+       },
+};
+static const css_computed_page default_page = {
+       .bits = {
+               (CSS_PAGE_BREAK_AFTER_AUTO << 29) | (CSS_PAGE_BREAK_BEFORE_AUTO
+                               << 26) | (CSS_PAGE_BREAK_INSIDE_AUTO << 24) | (
+                               CSS_WIDOWS_SET << 23) | (CSS_ORPHANS_SET << 22)
+       },
+};
+
+
+#endif
\ No newline at end of file
diff --git a/src/select/select_config.py b/src/select/select_config.py
index e63dc8b..2f0899b 100644
--- a/src/select/select_config.py
+++ b/src/select/select_config.py
@@ -5,10 +5,11 @@
 
 # Configuration of CSS values
 values = {
-    ('length', 'css_fixed', 4, 0, 'unit', 'css_unit', 5, 'CSS_UNIT_PX'),
-    ('integer', 'int32_t', 4, 0),
-    ('fixed', 'css_fixed', 4, 0),
-    ('color', 'css_color', 4, 0),
+    ('length', 'css_fixed', 4, '0',
+        'unit', 'css_unit', 5, 'CSS_UNIT_PX'),
+    ('integer', 'int32_t', 4, '0'),
+    ('fixed', 'css_fixed', 4, '0'),
+    ('color', 'css_color', 4, '0'),
     ('string', 'lwc_string*'),
     ('string_arr', 'lwc_string**'),
     ('counter', 'css_computed_counter*'),
@@ -110,25 +111,25 @@ page = {
     ('page_break_after', 3, None, None, 'CSS_PAGE_BREAK_AFTER_AUTO'),
     ('page_break_before', 3, None, None, 'CSS_PAGE_BREAK_BEFORE_AUTO'),
     ('page_break_inside', 2, None, None, 'CSS_PAGE_BREAK_INSIDE_AUTO'),
-    ('widows', 1, 'integer', None, ('CSS_WIDOWS_SET', 2)),
-    ('orphans', 1, 'integer', None, ('CSS_ORPHANS_SET', 2))
+    ('widows', 1, 'integer', None, ('CSS_WIDOWS_SET', '2 << CSS_RADIX_POINT')),
+    ('orphans', 1, 'integer', None, ('CSS_ORPHANS_SET', '2 << 
CSS_RADIX_POINT'))
 }
 
 uncommon = {
     # Uncommon group
     ('border_spacing', 1, ('length', 'length'), 'CSS_BORDER_SPACING_SET',
-        ('CSS_BORDER_SPACING_SET', 0, 'CSS_UNIT_PX', 0, 'CSS_UNIT_PX')),
+        ('CSS_BORDER_SPACING_SET', '0', 'CSS_UNIT_PX', '0', 'CSS_UNIT_PX')),
     ('break_after', 4, None, None, 'CSS_BREAK_AFTER_AUTO'),
     ('break_before', 4, None, None, 'CSS_BREAK_BEFORE_AUTO'),
     ('break_inside', 4, None, None, 'CSS_BREAK_INSIDE_AUTO'),
     ('clip', 6, ('length', 'length', 'length', 'length'),
-        'CSS_CLIP_RECT', None, None, ('get', 'set')),
+        'CSS_CLIP_RECT', 'CSS_CLIP_AUTO', None, ('get', 'set')),
     ('column_count', 2, 'integer', None, 'CSS_COLUMN_COUNT_AUTO'),
     ('column_fill', 2, None, None, 'CSS_COLUMN_FILL_BALANCE'),
     ('column_gap', 2, 'length',
         'CSS_COLUMN_GAP_SET', 'CSS_COLUMN_GAP_NORMAL'),
     ('column_rule_color', 2, 'color', None,
-        ('CSS_COLUMN_RULE_CURRENT_COLOR', 0)),
+        ('CSS_COLUMN_RULE_CURRENT_COLOR', '0')),
     ('column_rule_style', 4, None, None, 'CSS_COLUMN_RULE_STYLE_NONE'),
     ('column_rule_width', 3, 'length',
         'CSS_COLUMN_RULE_WIDTH_WIDTH', 'CSS_COLUMN_RULE_WIDTH_MEDIUM'),
@@ -150,18 +151,16 @@ uncommon = {
     ('counter_reset', 1, 'counter', None, 'CSS_COUNTER_RESET_NONE',
         'Encode counter_reset as an array of name, value pairs, '
         'terminated with a blank entry.'),
-    ('cursor', 5, 'string_arr', 'CSS_CURSOR_AUTO', None,
+    ('cursor', 5, 'string_arr', 'CSS_CURSOR_AUTO', 'CSS_CURSOR_INHERIT',
         'Encode cursor uri(s) as an array of string objects, terminated '
         'with a blank entry'),
-    ('content', 2, 'content_item', 'CSS_CONTENT_NORMAL', None,
+    ('content', 2, 'content_item', 'CSS_CONTENT_NORMAL', 'CSS_CONTENT_NORMAL',
         'Encode content as an array of content items, terminated with '
         'a blank entry.')
 }
 
-groups = {
-    'main': { 'name': 'style', 'props': style },
-    'others': [
-        { 'name': 'uncommon', 'props': uncommon },
-        { 'name': 'page', 'props': page }
-    ]
-}
+groups = [
+    { 'name': 'uncommon', 'props': uncommon },
+    { 'name': 'page', 'props': page },
+    { 'name': 'style', 'props': style }
+]
diff --git a/src/select/select_generator.py b/src/select/select_generator.py
index 31fe613..d605f0b 100644
--- a/src/select/select_generator.py
+++ b/src/select/select_generator.py
@@ -3,13 +3,24 @@
 # http://www.opensource.org/licenses/mit-license.php
 # Copyright 2017 Lucas Neves <[email protected]>
 
+import math
+import string
 from select_config import values, groups
 from assets import assets
 
+def shift_star(value_type, prop_name):
+    '''Shifts the asterisks from a pointer type to its name.
+    i.e. `lwc_string** str_array` would become `lwc_string **str_array`'''
+    star_i = value_type.find('*')
+    v_type = value_type if star_i is -1 else value_type[:star_i]
+    v_name = prop_name if star_i is -1 else value_type[star_i:] + prop_name
+    return (v_type, v_name)
+
 class Text:
     def __init__(self):
         self._lines = []
         self._comment = False
+        self._esc_nl = False
         self._indent = 0
 
     name_width = 31
@@ -27,10 +38,15 @@ class Text:
         self.append(' */' if comm else '/*')
         self._comment = not comm
 
+    def escape_newline(self):
+        self._esc_nl = not self._esc_nl
+
     def append(self, text=None, pre_formatted=False):
         if not text:
-            self._lines.append('\t' * self._indent + ' * '
-                    if self._comment else '')
+            self._lines.append('{}{}{}'.format(
+                '\t' * self._indent,
+                ' * ' if self._comment else '',
+                '\t' * (9 - self._indent) + '\\' if self._esc_nl else ''))
             return
 
         if isinstance(text, list):
@@ -42,7 +58,7 @@ class Text:
             self._lines.append(text)
             return
 
-        column_max = 80
+        column_max = 72 if self._esc_nl else 80
         multiline = False
 
         while text:
@@ -54,16 +70,20 @@ class Text:
                 line += text
                 text = ''
             else:
-                break_index = text[:column_max - prefix_size].rfind(' ')
+                space_index = text[:column_max - prefix_size].rfind(' ')
+                paren_index = text[:column_max - prefix_size].rfind('(')
+                break_index = max(space_index, paren_index + 1)
                 line += text[:break_index].rstrip()
                 text = text[break_index:].lstrip()
+            if self._esc_nl:
+                line += '\t' * (9 - math.floor(len(line) / 8)) + '\\'
             self._lines.append(line)
             if text and not self._comment and not multiline:
                 self.indent(2)
                 multiline = True
 
         if multiline:
-            self._indent(-2)
+            self.indent(-2)
 
     def table_line(self):
         self.append('{0:{n}}{0:{b}}{0}'.format(
@@ -75,6 +95,9 @@ class Text:
             n=self.name_width, b=self.bits_width))
         self.table_line()
 
+    def result_line(self):
+        self.append(' ' * self.name_width + '=' * (self.bits_width + 3))
+
     def to_string(self):
         return '\n'.join(self._lines)
 
@@ -82,7 +105,7 @@ class CSSValue:
     'Values to be associated with properties.'
     def __init__(self, name, css_type, size=None, default='NULL',
                  bits_name=None, bits_type=None,
-                 bits_size=None, bits_default=0):
+                 bits_size=None, bits_default='0'):
         self.name = name
         self.type = css_type
         self.size = size #  `None` means sizeof(ptr)
@@ -105,6 +128,7 @@ class CSSProperty:
         self.condition = condition
         self.override = self.get_tuple(override)
         self.comments = comments
+        self.__shift = None
 
     __vals = [ CSSValue(*x) for x in values ]
 
@@ -153,22 +177,35 @@ class CSSProperty:
         return (name + bits_size + vars_size +
                 (' + ' if vars_size and ptr else '') + ptr)
 
+    @property
+    def shift(self):
+        if self.__shift is None:
+            raise NameError('Attribute `shift` not set yet!')
+        return self.__shift
+
+    @shift.setter
+    def shift(self, val):
+        if type(val) is not int:
+            raise TypeError('Value of `shift` must be an integer!')
+        if val < 0:
+            raise ValueError('Value of `shift` must be zero or positive!')
+        self.__shift = val
+
 class Bin:
     def __init__(self, first_object):
         self.contents = [ first_object ]
 
     @property
     def size(self):
-        return sum([ x['size'] for x in self.contents ])
+        return sum([ x.bits_size for x in self.contents ])
 
     def push(self, obj):
         self.contents.append(obj)
 
 class CSSGroup:
-    def __init__(self, config, is_main=False):
+    def __init__(self, config):
         self.name = config['name']
         self.props = [ CSSProperty(*x) for x in config['props'] ]
-        self.is_main = is_main
         self.__bits_array = None
 
     @property
@@ -193,15 +230,16 @@ class CSSGroup:
 
         bin_size = 32
         self.__bits_array = []
-        props = sorted([ { 'name': p.name, 'size': p.bits_size }
-            for p in self.props ], key=(lambda x: x['size']), reverse=True)
+        props = sorted(self.props, key=(lambda x: x.bits_size), reverse=True)
 
         for p in props:
             for b in self.__bits_array:
-                if b.size + p['size'] <= bin_size:
+                if b.size + p.bits_size <= bin_size:
                     b.push(p)
+                    p.shift = 32 - sum([ x.bits_size for x in b.contents ])
                     break
             else:
+                p.shift = 32 - p.bits_size
                 self.__bits_array.append(Bin(p))
 
             self.__bits_array.sort(key=(lambda x: x.size), reverse=True)
@@ -211,6 +249,11 @@ class CSSGroup:
     def make_computed_h(self):
         t = Text()
         t.append()
+
+        typedef = 'typedef ' if self.name is 'page' else ''
+        t.append('{}struct css_computed_{}{} {{'.format(
+            typedef, self.name, '' if self.name is 'page' else '_i'))
+
         t.comment()
         commented = []
         t.table_header()
@@ -220,6 +263,7 @@ class CSSGroup:
             else:
                 commented.extend(( '', prop.comments, '', prop.size_line ))
         t.append(commented)
+        t.append()
         t.table_line()
         t.append('{:{len_1}}{:>3}{:{len_2}}{:>3}{}{}'.format('',
             str(self.bits_size), ' bits', str(self.bytes_size),
@@ -227,18 +271,112 @@ class CSSGroup:
                     if self.ptr_size else '',
             ' bytes',
             len_1=Text.name_width, len_2=(Text.bits_width - 3)))
+        t.result_line()
+        t.append('{:{len_1}}{:>3}{}{}'.format('',
+            math.ceil(self.bits_size / 8) + self.bytes_size,
+            ' + ' + str(self.ptr_size) + 'sizeof(ptr)'
+                    if self.ptr_size else '',
+            ' bytes', len_1=Text.name_width))
+        t.append()
+
+        t.append('Bit allocations:')
+        for i, b in enumerate(self.bits_array):
+            bits = []
+            for prop in b.contents:
+                for char in prop.name + prop.name.upper():
+                    if char not in bits and char in string.ascii_letters:
+                        bits.extend(char * prop.bits_size)
+                        break
+            t.append()
+            t.append('{:<2} {:.<32}'.format(str(i), ''.join(bits)))
+            t.append('; '.join([ p.name for p in b.contents ]))
         t.comment()
 
+        t.indent(1)
+        t.append('uint32_t bits[' + str(len(self.bits_array)) + '];')
+        t.append()
+        t.append(self.make_value_declaration(for_commented=False))
+        if self.name is 'style':
+            t.append()
+            t.append('css_computed_uncommon *uncommon;')
+            t.append('void *aural;')
+        t.indent(-1)
+        t.append('}}{};'.format(
+            ' css_computed_' + self.name if typedef else ''))
+
+        if self.name is not 'page':
+            typedef = 'typedef ' if self.name is not 'style' else ''
+            t.append()
+            t.append('{}struct css_computed_{} {{'.format(
+                     typedef, self.name))
+            t.indent(1)
+            t.append('struct css_computed_' + self.name + '_i i;')
+            t.append()
+            t.append(self.make_value_declaration(for_commented=True))
+            t.append()
+            if self.name is 'style':
+                t.append('css_computed_page *page;')
+            t.append('struct css_computed_' + self.name + ' *next;')
+            t.append('uint32_t count;')
+            t.append('uint32_t bin;')
+            t.indent(-1)
+            t.append('}}{};'.format(
+                ' css_computed_' + self.name if typedef else ''))
+
+        return t.to_string()
+
+    def make_propset_h(self):
+        t = Text()
+
+        if self.name is not 'style':
+            t.append('static const css_computed_{0} default_{0} = {{'.format(
+                self.name))
+            t.indent(1)
+            if self.name is not 'page':
+                t.append('.i = {')
+                t.indent(1)
+            t.append('.bits = {') 
+            t.indent(1)
+            bits_ops = []
+            for b in self.bits_array:
+                or_ops = []
+                for p in b.contents:
+                    or_ops.append('({} << {})'.format(p.defaults[0],
+                                  str(p.shift)) if p.shift else p.defaults[0])
+                bits_ops.append(' | '.join(or_ops))
+            t.append(',\n'.join(bits_ops).split('\n'))
+            t.indent(-1)
+            t.append('},')
+
+            if self.name is not 'page':
+                t.indent(-1)
+                t.append('},')
+
+            t.indent(-1)
+            t.append('};')
+
         return t.to_string()
 
+    def make_value_declaration(self, for_commented):
+        r = []
+        for p in sorted(self.props, key=(lambda x: x.name)):
+            if bool(p.comments) == for_commented:
+                for i, v in enumerate(p.values):
+                    v_suffix = ('' if len(p.values) is 1 else
+                                '_' + string.ascii_lowercase[i])
+                    v_type, v_name = shift_star(v.type, p.name)
+                    r.append('{} {}{}{}'.format(v_type, v_name, v_suffix, ';'))
+        return r
+
     def make_text(self, filename):
         if filename == 'computed.h':
             return self.make_computed_h()
+        if filename == 'propset.h':
+            return self.make_propset_h()
         else:
             raise ValueError()
 
-css_groups = [ CSSGroup(g) for g in groups['others'] ]
-css_groups.append(CSSGroup(groups['main'], is_main=True))
+css_groups = [ CSSGroup(g) for g in groups ]
 
 for k, v in assets.items():
     # Key is filename string (e.g. "computed.h") without autogenerated_ prefix


-----------------------------------------------------------------------

Summary of changes:
 src/select/__pycache__/assets.cpython-36.pyc       |  Bin 1398 -> 1913 bytes
 .../__pycache__/select_config.cpython-36.pyc       |  Bin 6490 -> 6543 bytes
 src/select/assets.py                               |   25 ++-
 src/select/autogenerated_computed.h                |  173 +++++++++++++++++++-
 src/select/autogenerated_propset.h                 |   60 +++++++
 src/select/select_config.py                        |   35 ++--
 src/select/select_generator.py                     |  166 +++++++++++++++++--
 7 files changed, 424 insertions(+), 35 deletions(-)
 create mode 100644 src/select/autogenerated_propset.h

diff --git a/src/select/__pycache__/assets.cpython-36.pyc 
b/src/select/__pycache__/assets.cpython-36.pyc
index 9b622ce..b5bf9ca 100644
Binary files a/src/select/__pycache__/assets.cpython-36.pyc and 
b/src/select/__pycache__/assets.cpython-36.pyc differ
diff --git a/src/select/__pycache__/select_config.cpython-36.pyc 
b/src/select/__pycache__/select_config.cpython-36.pyc
index 55e01f8..3fdda2a 100644
Binary files a/src/select/__pycache__/select_config.cpython-36.pyc and 
b/src/select/__pycache__/select_config.cpython-36.pyc differ
diff --git a/src/select/assets.py b/src/select/assets.py
index 91bf92a..3f6b7d1 100644
--- a/src/select/assets.py
+++ b/src/select/assets.py
@@ -59,6 +59,27 @@ css_error css__compute_absolute_values(const 
css_computed_style *parent,
                        const css_hint *parent, css_hint *size),
                void *pw);
 
-#endif
-'''
+#endif'''
+
+assets['propset.h'] = {}
+assets['propset.h']['header'] = copyright + '''\
+/*
+ * This file is part of LibCSS
+ * Licensed under the MIT License,
+ *                http://www.opensource.org/licenses/mit-license.php
+ * Copyright 2009 John-Mark Bell <[email protected]>
+ */
+
+#ifndef css_select_propset_h_
+#define css_select_propset_h_
+
+#include <string.h>
+
+#include <libcss/computed.h>
+#include "computed.h"
+
+/** Default values are 'initial value', unless the property is inherited,
+ *  in which case it is 'inherit'. */'''
+assets['propset.h']['footer'] = '''
+#endif'''
 
diff --git a/src/select/autogenerated_computed.h 
b/src/select/autogenerated_computed.h
index a76c528..a319a58 100644
--- a/src/select/autogenerated_computed.h
+++ b/src/select/autogenerated_computed.h
@@ -13,6 +13,7 @@
 
 
 
+struct css_computed_uncommon_i {
 /*
  * Property                       Size (bits)     Size (bytes)
  * ---                            ---             ---
@@ -52,10 +53,60 @@
  * entry
  * 
  * cursor                           5             sizeof(ptr)
+ * 
  * ---                            ---             ---
  *                                116 bits         60 + 4sizeof(ptr) bytes
+ *                                ===================
+ *                                 75 + 4sizeof(ptr) bytes
+ * 
+ * Bit allocations:
+ * 
+ * 0  bbbbbbbbbbbccccccccoooooooouuuuu
+ * border_spacing; column_rule_width; outline_width; cursor
+ * 
+ * 1  wwwwwwwlllllllcccccccooooooobbbb
+ * word_spacing; letter_spacing; column_width; column_gap; break_before
+ * 
+ * 2  ccccccccccccccccccccccccccbbbboo
+ * clip; break_after; column_fill
+ * 
+ * 3  ccccbbbboolluuttnner............
+ * column_rule_style; break_inside; column_span; column_count;
+ * column_rule_color; outline_color; content; counter_increment; counter_reset
  */
+       uint32_t bits[4];
+       
+       css_fixed border_spacing_a;
+       css_fixed border_spacing_b;
+       css_fixed clip_a;
+       css_fixed clip_b;
+       css_fixed clip_c;
+       css_fixed clip_d;
+       int32_t column_count;
+       css_fixed column_gap;
+       css_color column_rule_color;
+       css_fixed column_rule_width;
+       css_fixed column_width;
+       css_fixed letter_spacing;
+       css_color outline_color;
+       css_fixed outline_width;
+       css_fixed word_spacing;
+};
 
+typedef struct css_computed_uncommon {
+       struct css_computed_uncommon_i i;
+       
+       css_computed_content_item *content;
+       css_computed_counter *counter_increment;
+       css_computed_counter *counter_reset;
+       lwc_string **cursor;
+       
+       struct css_computed_uncommon *next;
+       uint32_t count;
+       uint32_t bin;
+} css_computed_uncommon;
+
+typedef struct css_computed_page {
 /*
  * Property                       Size (bits)     Size (bytes)
  * ---                            ---             ---
@@ -65,10 +116,24 @@
  * page_break_inside                2             
  * widows                           1               4
  * 
+ * 
  * ---                            ---             ---
  *                                 10 bits          8 bytes
+ *                                ===================
+ *                                 10 bytes
+ * 
+ * Bit allocations:
+ * 
+ * 0  pppaaaggwo......................
+ * page_break_after; page_break_before; page_break_inside; widows; orphans
  */
+       uint32_t bits[1];
+       
+       int32_t orphans;
+       int32_t widows;
+} css_computed_page;
 
+struct css_computed_style_i {
 /*
  * Property                       Size (bits)     Size (bytes)
  * ---                            ---             ---
@@ -157,9 +222,115 @@
  * Encode quotes as an array of string objects, terminated with a blank entry.
  * 
  * quotes                           1             sizeof(ptr)
+ * 
  * ---                            ---             ---
  *                                329 bits        160 + 4sizeof(ptr) bytes
+ *                                ===================
+ *                                202 + 4sizeof(ptr) bytes
+ * 
+ * Bit allocations:
+ * 
+ * 0  bbbbbbbboooooooorrrrrrrrdddddddd
+ * border_bottom_width; border_left_width; border_top_width; border_right_width
+ * 
+ * 1  mmmmmmmbbbbbbbaaaaaaaiiiiiiioooo
+ * max_height; bottom; margin_bottom; min_height; border_left_style
+ * 
+ * 2  hhhhhhhrrrrrrrmmmmmmmaaaaaaatttt
+ * height; right; margin_top; margin_right; text_align
+ * 
+ * 3  mmmmmmmtttttttffffffflllllllbbbb
+ * max_width; top; flex_basis; line_height; border_right_style
+ * 
+ * 4  wwwwwwwmmmmmmmiiiiiiilllllllffff
+ * width; margin_left; min_width; left; font_weight
+ * 
+ * 5  bbbbbbbbbbbvvvvvvvvvfffffffffaaa
+ * background_position; vertical_align; font_size; align_content
+ * 
+ * 6  dddddtttttoooollllbbbbrrrraaaiii
+ * display; text_decoration; outline_style; list_style_type;
+ * border_bottom_style; border_top_style; align_items; align_self
+ * 
+ * 7  ppppppaaaaaaddddddttttttiiiiiicc
+ * padding_bottom; padding_left; padding_top; text_indent; padding_right;
+ * caption_side
+ * 
+ * 8  bboorrvvttddffaanniillcczzuueess
+ * border_bottom_color; border_collapse; border_left_color; visibility;
+ * table_layout; border_top_color; flex_wrap; background_attachment;
+ * font_style; font_variant; float; background_color; z_index; unicode_bidi;
+ * border_right_color; list_style_position
+ * 
+ * 9  wwwbbbcccfffooopppnnnjjjttteexxa
+ * white_space; background_repeat; clear; flex_direction; overflow; position;
+ * font_family; justify_content; text_transform; empty_cells; box_sizing;
+ * opacity
+ * 
+ * 10 ddfbcliqo.......................
+ * direction; flex_grow; background_image; color; flex_shrink;
+ * list_style_image; quotes; order
  */
+       uint32_t bits[11];
+       
+       css_color background_color;
+       lwc_string *background_image;
+       css_fixed background_position_a;
+       css_fixed background_position_b;
+       css_color border_bottom_color;
+       css_fixed border_bottom_width;
+       css_color border_left_color;
+       css_fixed border_left_width;
+       css_color border_right_color;
+       css_fixed border_right_width;
+       css_color border_top_color;
+       css_fixed border_top_width;
+       css_fixed bottom;
+       css_color color;
+       css_fixed flex_basis;
+       css_fixed flex_grow;
+       css_fixed flex_shrink;
+       css_fixed font_size;
+       css_fixed height;
+       css_fixed left;
+       css_fixed line_height;
+       lwc_string *list_style_image;
+       css_fixed margin_bottom;
+       css_fixed margin_left;
+       css_fixed margin_right;
+       css_fixed margin_top;
+       css_fixed max_height;
+       css_fixed max_width;
+       css_fixed min_height;
+       css_fixed min_width;
+       css_fixed opacity;
+       int32_t order;
+       css_fixed padding_bottom;
+       css_fixed padding_left;
+       css_fixed padding_right;
+       css_fixed padding_top;
+       css_fixed right;
+       css_fixed text_indent;
+       css_fixed top;
+       css_fixed vertical_align;
+       css_fixed width;
+       int32_t z_index;
+       
+       css_computed_uncommon *uncommon;
+       void *aural;
+};
+
+struct css_computed_style {
+       struct css_computed_style_i i;
+       
+       lwc_string **font_family;
+       lwc_string **quotes;
+       
+       css_computed_page *page;
+       struct css_computed_style *next;
+       uint32_t count;
+       uint32_t bin;
+};
 /**
  * Take a new reference to a computed style
  *
@@ -194,4 +365,4 @@ css_error css__compute_absolute_values(const 
css_computed_style *parent,
                        const css_hint *parent, css_hint *size),
                void *pw);
 
-#endif
+#endif
\ No newline at end of file
diff --git a/src/select/autogenerated_propset.h 
b/src/select/autogenerated_propset.h
new file mode 100644
index 0000000..4976929
--- /dev/null
+++ b/src/select/autogenerated_propset.h
@@ -0,0 +1,60 @@
+/*
+ * This file is part of LibCSS
+ * Licensed under the MIT License,
+ *                http://www.opensource.org/licenses/mit-license.php
+ * Copyright 2017 The NetSurf Project
+ */
+
+/*
+ * This file is part of LibCSS
+ * Licensed under the MIT License,
+ *                http://www.opensource.org/licenses/mit-license.php
+ * Copyright 2009 John-Mark Bell <[email protected]>
+ */
+
+#ifndef css_select_propset_h_
+#define css_select_propset_h_
+
+#include <string.h>
+
+#include <libcss/computed.h>
+#include "computed.h"
+
+/** Default values are 'initial value', unless the property is inherited,
+ *  in which case it is 'inherit'. */
+static const css_computed_uncommon default_uncommon = {
+       .i = {
+               .bits = {
+                       (CSS_BORDER_SPACING_SET << 21) | (
+                                       CSS_COLUMN_RULE_WIDTH_MEDIUM << 13) | (
+                                       CSS_OUTLINE_WIDTH_MEDIUM << 5) |
+                                       CSS_CURSOR_INHERIT,
+                       (CSS_WORD_SPACING_NORMAL << 25) | (
+                                       CSS_LETTER_SPACING_NORMAL << 18) | (
+                                       CSS_COLUMN_WIDTH_AUTO << 11) | (
+                                       CSS_COLUMN_GAP_NORMAL << 4) |
+                                       CSS_BREAK_BEFORE_AUTO,
+                       (CSS_CLIP_AUTO << 6) | (CSS_BREAK_AFTER_AUTO << 2) |
+                                       CSS_COLUMN_FILL_BALANCE,
+                       (CSS_COLUMN_RULE_STYLE_NONE << 28) | (
+                                       CSS_BREAK_INSIDE_AUTO << 24) | (
+                                       CSS_COLUMN_SPAN_NONE << 22) | (
+                                       CSS_COLUMN_COUNT_AUTO << 20) | (
+                                       CSS_COLUMN_RULE_CURRENT_COLOR << 18) | (
+                                       CSS_OUTLINE_COLOR_INVERT << 16) | (
+                                       CSS_CONTENT_NORMAL << 14) | (
+                                       CSS_COUNTER_INCREMENT_NONE << 13) | (
+                                       CSS_COUNTER_RESET_NONE << 12)
+               },
+       },
+};
+static const css_computed_page default_page = {
+       .bits = {
+               (CSS_PAGE_BREAK_AFTER_AUTO << 29) | (CSS_PAGE_BREAK_BEFORE_AUTO
+                               << 26) | (CSS_PAGE_BREAK_INSIDE_AUTO << 24) | (
+                               CSS_WIDOWS_SET << 23) | (CSS_ORPHANS_SET << 22)
+       },
+};
+
+
+#endif
\ No newline at end of file
diff --git a/src/select/select_config.py b/src/select/select_config.py
index e63dc8b..2f0899b 100644
--- a/src/select/select_config.py
+++ b/src/select/select_config.py
@@ -5,10 +5,11 @@
 
 # Configuration of CSS values
 values = {
-    ('length', 'css_fixed', 4, 0, 'unit', 'css_unit', 5, 'CSS_UNIT_PX'),
-    ('integer', 'int32_t', 4, 0),
-    ('fixed', 'css_fixed', 4, 0),
-    ('color', 'css_color', 4, 0),
+    ('length', 'css_fixed', 4, '0',
+        'unit', 'css_unit', 5, 'CSS_UNIT_PX'),
+    ('integer', 'int32_t', 4, '0'),
+    ('fixed', 'css_fixed', 4, '0'),
+    ('color', 'css_color', 4, '0'),
     ('string', 'lwc_string*'),
     ('string_arr', 'lwc_string**'),
     ('counter', 'css_computed_counter*'),
@@ -110,25 +111,25 @@ page = {
     ('page_break_after', 3, None, None, 'CSS_PAGE_BREAK_AFTER_AUTO'),
     ('page_break_before', 3, None, None, 'CSS_PAGE_BREAK_BEFORE_AUTO'),
     ('page_break_inside', 2, None, None, 'CSS_PAGE_BREAK_INSIDE_AUTO'),
-    ('widows', 1, 'integer', None, ('CSS_WIDOWS_SET', 2)),
-    ('orphans', 1, 'integer', None, ('CSS_ORPHANS_SET', 2))
+    ('widows', 1, 'integer', None, ('CSS_WIDOWS_SET', '2 << CSS_RADIX_POINT')),
+    ('orphans', 1, 'integer', None, ('CSS_ORPHANS_SET', '2 << 
CSS_RADIX_POINT'))
 }
 
 uncommon = {
     # Uncommon group
     ('border_spacing', 1, ('length', 'length'), 'CSS_BORDER_SPACING_SET',
-        ('CSS_BORDER_SPACING_SET', 0, 'CSS_UNIT_PX', 0, 'CSS_UNIT_PX')),
+        ('CSS_BORDER_SPACING_SET', '0', 'CSS_UNIT_PX', '0', 'CSS_UNIT_PX')),
     ('break_after', 4, None, None, 'CSS_BREAK_AFTER_AUTO'),
     ('break_before', 4, None, None, 'CSS_BREAK_BEFORE_AUTO'),
     ('break_inside', 4, None, None, 'CSS_BREAK_INSIDE_AUTO'),
     ('clip', 6, ('length', 'length', 'length', 'length'),
-        'CSS_CLIP_RECT', None, None, ('get', 'set')),
+        'CSS_CLIP_RECT', 'CSS_CLIP_AUTO', None, ('get', 'set')),
     ('column_count', 2, 'integer', None, 'CSS_COLUMN_COUNT_AUTO'),
     ('column_fill', 2, None, None, 'CSS_COLUMN_FILL_BALANCE'),
     ('column_gap', 2, 'length',
         'CSS_COLUMN_GAP_SET', 'CSS_COLUMN_GAP_NORMAL'),
     ('column_rule_color', 2, 'color', None,
-        ('CSS_COLUMN_RULE_CURRENT_COLOR', 0)),
+        ('CSS_COLUMN_RULE_CURRENT_COLOR', '0')),
     ('column_rule_style', 4, None, None, 'CSS_COLUMN_RULE_STYLE_NONE'),
     ('column_rule_width', 3, 'length',
         'CSS_COLUMN_RULE_WIDTH_WIDTH', 'CSS_COLUMN_RULE_WIDTH_MEDIUM'),
@@ -150,18 +151,16 @@ uncommon = {
     ('counter_reset', 1, 'counter', None, 'CSS_COUNTER_RESET_NONE',
         'Encode counter_reset as an array of name, value pairs, '
         'terminated with a blank entry.'),
-    ('cursor', 5, 'string_arr', 'CSS_CURSOR_AUTO', None,
+    ('cursor', 5, 'string_arr', 'CSS_CURSOR_AUTO', 'CSS_CURSOR_INHERIT',
         'Encode cursor uri(s) as an array of string objects, terminated '
         'with a blank entry'),
-    ('content', 2, 'content_item', 'CSS_CONTENT_NORMAL', None,
+    ('content', 2, 'content_item', 'CSS_CONTENT_NORMAL', 'CSS_CONTENT_NORMAL',
         'Encode content as an array of content items, terminated with '
         'a blank entry.')
 }
 
-groups = {
-    'main': { 'name': 'style', 'props': style },
-    'others': [
-        { 'name': 'uncommon', 'props': uncommon },
-        { 'name': 'page', 'props': page }
-    ]
-}
+groups = [
+    { 'name': 'uncommon', 'props': uncommon },
+    { 'name': 'page', 'props': page },
+    { 'name': 'style', 'props': style }
+]
diff --git a/src/select/select_generator.py b/src/select/select_generator.py
index 31fe613..d605f0b 100644
--- a/src/select/select_generator.py
+++ b/src/select/select_generator.py
@@ -3,13 +3,24 @@
 # http://www.opensource.org/licenses/mit-license.php
 # Copyright 2017 Lucas Neves <[email protected]>
 
+import math
+import string
 from select_config import values, groups
 from assets import assets
 
+def shift_star(value_type, prop_name):
+    '''Shifts the asterisks from a pointer type to its name.
+    i.e. `lwc_string** str_array` would become `lwc_string **str_array`'''
+    star_i = value_type.find('*')
+    v_type = value_type if star_i is -1 else value_type[:star_i]
+    v_name = prop_name if star_i is -1 else value_type[star_i:] + prop_name
+    return (v_type, v_name)
+
 class Text:
     def __init__(self):
         self._lines = []
         self._comment = False
+        self._esc_nl = False
         self._indent = 0
 
     name_width = 31
@@ -27,10 +38,15 @@ class Text:
         self.append(' */' if comm else '/*')
         self._comment = not comm
 
+    def escape_newline(self):
+        self._esc_nl = not self._esc_nl
+
     def append(self, text=None, pre_formatted=False):
         if not text:
-            self._lines.append('\t' * self._indent + ' * '
-                    if self._comment else '')
+            self._lines.append('{}{}{}'.format(
+                '\t' * self._indent,
+                ' * ' if self._comment else '',
+                '\t' * (9 - self._indent) + '\\' if self._esc_nl else ''))
             return
 
         if isinstance(text, list):
@@ -42,7 +58,7 @@ class Text:
             self._lines.append(text)
             return
 
-        column_max = 80
+        column_max = 72 if self._esc_nl else 80
         multiline = False
 
         while text:
@@ -54,16 +70,20 @@ class Text:
                 line += text
                 text = ''
             else:
-                break_index = text[:column_max - prefix_size].rfind(' ')
+                space_index = text[:column_max - prefix_size].rfind(' ')
+                paren_index = text[:column_max - prefix_size].rfind('(')
+                break_index = max(space_index, paren_index + 1)
                 line += text[:break_index].rstrip()
                 text = text[break_index:].lstrip()
+            if self._esc_nl:
+                line += '\t' * (9 - math.floor(len(line) / 8)) + '\\'
             self._lines.append(line)
             if text and not self._comment and not multiline:
                 self.indent(2)
                 multiline = True
 
         if multiline:
-            self._indent(-2)
+            self.indent(-2)
 
     def table_line(self):
         self.append('{0:{n}}{0:{b}}{0}'.format(
@@ -75,6 +95,9 @@ class Text:
             n=self.name_width, b=self.bits_width))
         self.table_line()
 
+    def result_line(self):
+        self.append(' ' * self.name_width + '=' * (self.bits_width + 3))
+
     def to_string(self):
         return '\n'.join(self._lines)
 
@@ -82,7 +105,7 @@ class CSSValue:
     'Values to be associated with properties.'
     def __init__(self, name, css_type, size=None, default='NULL',
                  bits_name=None, bits_type=None,
-                 bits_size=None, bits_default=0):
+                 bits_size=None, bits_default='0'):
         self.name = name
         self.type = css_type
         self.size = size #  `None` means sizeof(ptr)
@@ -105,6 +128,7 @@ class CSSProperty:
         self.condition = condition
         self.override = self.get_tuple(override)
         self.comments = comments
+        self.__shift = None
 
     __vals = [ CSSValue(*x) for x in values ]
 
@@ -153,22 +177,35 @@ class CSSProperty:
         return (name + bits_size + vars_size +
                 (' + ' if vars_size and ptr else '') + ptr)
 
+    @property
+    def shift(self):
+        if self.__shift is None:
+            raise NameError('Attribute `shift` not set yet!')
+        return self.__shift
+
+    @shift.setter
+    def shift(self, val):
+        if type(val) is not int:
+            raise TypeError('Value of `shift` must be an integer!')
+        if val < 0:
+            raise ValueError('Value of `shift` must be zero or positive!')
+        self.__shift = val
+
 class Bin:
     def __init__(self, first_object):
         self.contents = [ first_object ]
 
     @property
     def size(self):
-        return sum([ x['size'] for x in self.contents ])
+        return sum([ x.bits_size for x in self.contents ])
 
     def push(self, obj):
         self.contents.append(obj)
 
 class CSSGroup:
-    def __init__(self, config, is_main=False):
+    def __init__(self, config):
         self.name = config['name']
         self.props = [ CSSProperty(*x) for x in config['props'] ]
-        self.is_main = is_main
         self.__bits_array = None
 
     @property
@@ -193,15 +230,16 @@ class CSSGroup:
 
         bin_size = 32
         self.__bits_array = []
-        props = sorted([ { 'name': p.name, 'size': p.bits_size }
-            for p in self.props ], key=(lambda x: x['size']), reverse=True)
+        props = sorted(self.props, key=(lambda x: x.bits_size), reverse=True)
 
         for p in props:
             for b in self.__bits_array:
-                if b.size + p['size'] <= bin_size:
+                if b.size + p.bits_size <= bin_size:
                     b.push(p)
+                    p.shift = 32 - sum([ x.bits_size for x in b.contents ])
                     break
             else:
+                p.shift = 32 - p.bits_size
                 self.__bits_array.append(Bin(p))
 
             self.__bits_array.sort(key=(lambda x: x.size), reverse=True)
@@ -211,6 +249,11 @@ class CSSGroup:
     def make_computed_h(self):
         t = Text()
         t.append()
+
+        typedef = 'typedef ' if self.name is 'page' else ''
+        t.append('{}struct css_computed_{}{} {{'.format(
+            typedef, self.name, '' if self.name is 'page' else '_i'))
+
         t.comment()
         commented = []
         t.table_header()
@@ -220,6 +263,7 @@ class CSSGroup:
             else:
                 commented.extend(( '', prop.comments, '', prop.size_line ))
         t.append(commented)
+        t.append()
         t.table_line()
         t.append('{:{len_1}}{:>3}{:{len_2}}{:>3}{}{}'.format('',
             str(self.bits_size), ' bits', str(self.bytes_size),
@@ -227,18 +271,112 @@ class CSSGroup:
                     if self.ptr_size else '',
             ' bytes',
             len_1=Text.name_width, len_2=(Text.bits_width - 3)))
+        t.result_line()
+        t.append('{:{len_1}}{:>3}{}{}'.format('',
+            math.ceil(self.bits_size / 8) + self.bytes_size,
+            ' + ' + str(self.ptr_size) + 'sizeof(ptr)'
+                    if self.ptr_size else '',
+            ' bytes', len_1=Text.name_width))
+        t.append()
+
+        t.append('Bit allocations:')
+        for i, b in enumerate(self.bits_array):
+            bits = []
+            for prop in b.contents:
+                for char in prop.name + prop.name.upper():
+                    if char not in bits and char in string.ascii_letters:
+                        bits.extend(char * prop.bits_size)
+                        break
+            t.append()
+            t.append('{:<2} {:.<32}'.format(str(i), ''.join(bits)))
+            t.append('; '.join([ p.name for p in b.contents ]))
         t.comment()
 
+        t.indent(1)
+        t.append('uint32_t bits[' + str(len(self.bits_array)) + '];')
+        t.append()
+        t.append(self.make_value_declaration(for_commented=False))
+        if self.name is 'style':
+            t.append()
+            t.append('css_computed_uncommon *uncommon;')
+            t.append('void *aural;')
+        t.indent(-1)
+        t.append('}}{};'.format(
+            ' css_computed_' + self.name if typedef else ''))
+
+        if self.name is not 'page':
+            typedef = 'typedef ' if self.name is not 'style' else ''
+            t.append()
+            t.append('{}struct css_computed_{} {{'.format(
+                     typedef, self.name))
+            t.indent(1)
+            t.append('struct css_computed_' + self.name + '_i i;')
+            t.append()
+            t.append(self.make_value_declaration(for_commented=True))
+            t.append()
+            if self.name is 'style':
+                t.append('css_computed_page *page;')
+            t.append('struct css_computed_' + self.name + ' *next;')
+            t.append('uint32_t count;')
+            t.append('uint32_t bin;')
+            t.indent(-1)
+            t.append('}}{};'.format(
+                ' css_computed_' + self.name if typedef else ''))
+
+        return t.to_string()
+
+    def make_propset_h(self):
+        t = Text()
+
+        if self.name is not 'style':
+            t.append('static const css_computed_{0} default_{0} = {{'.format(
+                self.name))
+            t.indent(1)
+            if self.name is not 'page':
+                t.append('.i = {')
+                t.indent(1)
+            t.append('.bits = {') 
+            t.indent(1)
+            bits_ops = []
+            for b in self.bits_array:
+                or_ops = []
+                for p in b.contents:
+                    or_ops.append('({} << {})'.format(p.defaults[0],
+                                  str(p.shift)) if p.shift else p.defaults[0])
+                bits_ops.append(' | '.join(or_ops))
+            t.append(',\n'.join(bits_ops).split('\n'))
+            t.indent(-1)
+            t.append('},')
+
+            if self.name is not 'page':
+                t.indent(-1)
+                t.append('},')
+
+            t.indent(-1)
+            t.append('};')
+
         return t.to_string()
 
+    def make_value_declaration(self, for_commented):
+        r = []
+        for p in sorted(self.props, key=(lambda x: x.name)):
+            if bool(p.comments) == for_commented:
+                for i, v in enumerate(p.values):
+                    v_suffix = ('' if len(p.values) is 1 else
+                                '_' + string.ascii_lowercase[i])
+                    v_type, v_name = shift_star(v.type, p.name)
+                    r.append('{} {}{}{}'.format(v_type, v_name, v_suffix, ';'))
+        return r
+
     def make_text(self, filename):
         if filename == 'computed.h':
             return self.make_computed_h()
+        if filename == 'propset.h':
+            return self.make_propset_h()
         else:
             raise ValueError()
 
-css_groups = [ CSSGroup(g) for g in groups['others'] ]
-css_groups.append(CSSGroup(groups['main'], is_main=True))
+css_groups = [ CSSGroup(g) for g in groups ]
 
 for k, v in assets.items():
     # Key is filename string (e.g. "computed.h") without autogenerated_ prefix


-- 
Cascading Style Sheets library

_______________________________________________
netsurf-commits mailing list
[email protected]
http://listmaster.pepperfish.net/cgi-bin/mailman/listinfo/netsurf-commits-netsurf-browser.org

Reply via email to