1, css: support dynamic use, master
authoryu.dongliang <18588496441@163.com>
Mon, 1 Jun 2026 12:07:58 +0000 (20:07 +0800)
committeryu.dongliang <18588496441@163.com>
Mon, 1 Jun 2026 12:08:06 +0000 (20:08 +0800)
2, support opacity for simple image

41 files changed:
examples/img.png
examples/klematis.jpg [new file with mode: 0644]
examples/klematis2.jpg [new file with mode: 0644]
examples/opacity.html [new file with mode: 0644]
examples/style.css
html/abc_css.c
html/abc_css_border.c
html/abc_css_color.c
html/abc_html.c
html/abc_html.h
html/abc_obj.c
html/abc_obj.h
html/main.c
ui/Makefile
ui/__render_bg_image.c
ui/__render_border.c
ui/__render_text.c
ui/__render_text_gl.c [new file with mode: 0644]
ui/abc.h
ui/abc_layout.c
ui/abc_layout_audio.c
ui/abc_layout_body.c
ui/abc_layout_div.c
ui/abc_layout_form.c
ui/abc_layout_h1.c
ui/abc_layout_hr.c
ui/abc_layout_img.c
ui/abc_layout_input.c
ui/abc_layout_label.c
ui/abc_layout_table.c
ui/abc_layout_td.c
ui/abc_layout_text.c
ui/abc_layout_video.c
ui/abc_render_hr.c
ui/abc_render_img.c
ui/abc_render_input.c
ui/abc_render_label.c
ui/abc_render_li.c
ui/abc_render_td.c
ui/abc_render_text.c
ui/main.c

index 17f8bd1c8b4fecfe3c8f8373b33c27d24710cbc4..a3a560bac13023cabcd43e8f56612dad057dcd02 100644 (file)
Binary files a/examples/img.png and b/examples/img.png differ
diff --git a/examples/klematis.jpg b/examples/klematis.jpg
new file mode 100644 (file)
index 0000000..b87e920
Binary files /dev/null and b/examples/klematis.jpg differ
diff --git a/examples/klematis2.jpg b/examples/klematis2.jpg
new file mode 100644 (file)
index 0000000..2f32901
Binary files /dev/null and b/examples/klematis2.jpg differ
diff --git a/examples/opacity.html b/examples/opacity.html
new file mode 100644 (file)
index 0000000..a2528cb
--- /dev/null
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>菜鸟教程(runoob.com)</title>
+<style>
+img
+{
+       opacity:0.4;
+       filter:alpha(opacity=40); /* 适用 IE8 及其更早版本 */
+}
+img:hover
+{
+       opacity:1.0;
+       filter:alpha(opacity=100); /* 适用 IE8 及其更早版本 */
+}
+</style>
+</head>
+<body>
+
+<h1>图片透明度</h1>
+<p>opacity 属性通常与 :hover 选择器一起使用,在鼠标移动到图片上后改变图片的透明度:</p>
+<img src="klematis.jpg"  width="150" height="113" alt="klematis">
+<img src="klematis2.jpg" width="150" height="113" alt="klematis">
+
+<p><b>注意:</b>在 IE 中必须声明 &lt;!DOCTYPE&gt; 才能保证 :hover 选择器能够有效。</p>
+</body>
+</html>
index 23371ec52a18fb89b6c147f1fb478df6e71ee696..4416259d7d177abe2601e3b77e7e80e8c71a9f06 100644 (file)
@@ -1,6 +1,7 @@
 body
 {
 body
 {
-       background: #b0c4de  url('img.png')     repeat-x right 上 ;
+       background:#b0c4de  url('img.png') repeat-x right top;
+       border: 2px solid red;
 }
 h1 {background-color:#6495ed;}
 
 }
 h1 {background-color:#6495ed;}
 
index ed6793d660a126a4abe708b7f3369d2cee7677ca..ddf0e17bcb347693492a71db2257dee1cb6f3903 100644 (file)
@@ -4,24 +4,24 @@ int            __html_add_attr   (abc_obj_t*  obj, int type, char** names, const
 html_label_t*  __html_find_label (const char* name);
 html_label_t*  __html_find_label2(const int   type);
 
 html_label_t*  __html_find_label (const char* name);
 html_label_t*  __html_find_label2(const int   type);
 
-static int __css_drop_comment(abc_obj_t* css)
+static int __css_drop_comment(abc_obj_t* style)
 {
 {
-       abc_char_t* c = __io_pop_char(&css->io);
+       abc_char_t* c = __io_pop_char(&style->io);
        if (!c)
                return -EINVAL;
 
        if ('*' != c->c) {
        if (!c)
                return -EINVAL;
 
        if ('*' != c->c) {
-               __io_push_char(&css->io, c);
+               __io_push_char(&style->io, c);
                return 1;
        }
 
                return 1;
        }
 
-       css->text_pos++;
+       style->text_pos++;
        free(c);
        c = NULL;
 
        int prev = 0;
        while (1) {
        free(c);
        c = NULL;
 
        int prev = 0;
        while (1) {
-               c = __io_pop_char(&css->io);
+               c = __io_pop_char(&style->io);
                if (!c)
                        return -EINVAL;
 
                if (!c)
                        return -EINVAL;
 
@@ -33,10 +33,10 @@ static int __css_drop_comment(abc_obj_t* css)
                        return -EINVAL;
 
                if ('\n' == tmp) {
                        return -EINVAL;
 
                if ('\n' == tmp) {
-                       css->text_line++;
-                       css->text_pos = 0;
+                       style->text_line++;
+                       style->text_pos = 0;
                } else {
                } else {
-                       css->text_pos++;
+                       style->text_pos++;
 
                        if ('*' == prev && '/' == tmp)
                                break;
 
                        if ('*' == prev && '/' == tmp)
                                break;
@@ -55,20 +55,20 @@ static int __css_end_value(int c)
        return 0;
 }
 
        return 0;
 }
 
-static int __css_parse_str(abc_obj_t* css, scf_string_t* s, int (*end)(int c))
+static int __css_parse_str(abc_obj_t* style, scf_string_t* s, int (*end)(int c))
 {
        abc_char_t* c  = NULL;
        int         c0 = ' ';
 
        while (1) {
 {
        abc_char_t* c  = NULL;
        int         c0 = ' ';
 
        while (1) {
-               c = __io_pop_char(&css->io);
+               c = __io_pop_char(&style->io);
                if (!c)
                        return -EINVAL;
 
                if (!c)
                        return -EINVAL;
 
-               css->text_pos += c->len;
+               style->text_pos += c->len;
 
                if ('/' == c->c) {
 
                if ('/' == c->c) {
-                       int ret = __css_drop_comment(css);
+                       int ret = __css_drop_comment(style);
                        if (0 == ret) {
                                free(c);
                                continue;
                        if (0 == ret) {
                                free(c);
                                continue;
@@ -86,16 +86,15 @@ static int __css_parse_str(abc_obj_t* css, scf_string_t* s, int (*end)(int c))
                int ret = 0;
                switch (c->c) { // drop more ' ' & add c to string
                        case '\n':
                int ret = 0;
                switch (c->c) { // drop more ' ' & add c to string
                        case '\n':
-                               css->text_line++;
-                               css->text_pos = 0;
+                               style->text_line++;
+                               style->text_pos = 0;
                        case '\t':
                        case '\r':
                        case ' ':
                                if (' ' == c0
                                                || '>' == c0 || '+' == c0 || '~' == c0
                                                || ',' == c0 || ':' == c0 || '.' == c0 || '#' == c0
                        case '\t':
                        case '\r':
                        case ' ':
                                if (' ' == c0
                                                || '>' == c0 || '+' == c0 || '~' == c0
                                                || ',' == c0 || ':' == c0 || '.' == c0 || '#' == c0
-                                               || '[' == c0 || ']' == c0
-                                               || '(' == c0 || ')' == c0)
+                                               || '[' == c0 || ']' == c0 || '(' == c0)
                                        break;
 
                                ret = scf_string_cat_cstr_len(s, " ", 1);
                                        break;
 
                                ret = scf_string_cat_cstr_len(s, " ", 1);
@@ -139,13 +138,13 @@ static int __css_parse_str(abc_obj_t* css, scf_string_t* s, int (*end)(int c))
        return tmp;
 }
 
        return tmp;
 }
 
-static int __css_parse_value(abc_obj_t* css, abc_attr_t* attr)
+static int __css_parse_value(abc_obj_t* style, abc_attr_t* attr)
 {
        scf_string_t* value = scf_string_alloc();
        if (!value)
                return -ENOMEM;
 
 {
        scf_string_t* value = scf_string_alloc();
        if (!value)
                return -ENOMEM;
 
-       int tmp = __css_parse_str(css, value, __css_end_value);
+       int tmp = __css_parse_str(style, value, __css_end_value);
 
        switch (tmp) {
                case ';':
 
        switch (tmp) {
                case ';':
@@ -171,13 +170,13 @@ static int __css_end_attr(int c)
        return 0;
 }
 
        return 0;
 }
 
-static int __css_parse_attr2(abc_obj_t* css, abc_obj_t* obj, const html_attr_t* attrs, int n_attrs)
+static int __css_parse_attr2(abc_obj_t* style, css_rule_t* css, const html_attr_t* attrs, int n_attrs)
 {
        scf_string_t* key = scf_string_alloc();
        if (!key)
                return -ENOMEM;
 
 {
        scf_string_t* key = scf_string_alloc();
        if (!key)
                return -ENOMEM;
 
-       int tmp = __css_parse_str(css, key, __css_end_attr);
+       int tmp = __css_parse_str(style, key, __css_end_attr);
 
        switch (tmp) {
                case ':':
 
        switch (tmp) {
                case ':':
@@ -194,45 +193,43 @@ static int __css_parse_attr2(abc_obj_t* css, abc_obj_t* obj, const html_attr_t*
        int i;
        int j;
        int k;
        int i;
        int j;
        int k;
-       if (attrs && n_attrs > 0) {
-               for (i = 0; i < n_attrs; i++) {
+       for (i = 0; attrs && i < n_attrs; i++) {
 
 
-                       for (j = 0; attrs[i].names[j]; j++) {
-                               if (!__html_strcmp(attrs[i].names[j], key->data))
-                                       goto found;
-                       }
+               for (j = 0; attrs[i].names[j]; j++) {
+                       if (!__html_strcmp(attrs[i].names[j], key->data))
+                               goto found;
                }
        }
 
                }
        }
 
-       scf_loge("invalid HTML attribute '%s' in file: %s, line: %d\n", key->data, css->file->data, css->text_pos);
+       scf_loge("invalid HTML attribute '%s' in file: %s, line: %d\n", key->data, style->file->data, style->text_pos);
        scf_string_free(key);
        return -EINVAL;
 
 found:
        k = attrs[i].type;
        scf_string_free(key);
        return -EINVAL;
 
 found:
        k = attrs[i].type;
-       assert(k >= ABC_HTML_ATTR_ID && k < ABC_HTML_CSS_NB);
+       assert(k >= ABC_CSS_CLASS && k < ABC_HTML_CSS_NB);
 
 
-       attr = obj->attrs[k - ABC_HTML_ATTR_ID];
+       attr = css->attrs[k - ABC_CSS_CLASS];
        if (!attr) {
        if (!attr) {
-               int ret = __html_add_attr(obj, attrs[i].type, attrs[i].names, attrs[i].value, attrs[i].flags);
+               int ret = __html_add_attr((abc_obj_t*)css, attrs[i].type, attrs[i].names, attrs[i].value, attrs[i].flags);
                if (ret < 0)
                        return ret;
 
                if (ret < 0)
                        return ret;
 
-               attr = obj->attrs[k - ABC_HTML_ATTR_ID];
+               attr = css->attrs[k - ABC_CSS_CLASS];
        }
 
        scf_string_free(key);
        key = NULL;
 
        }
 
        scf_string_free(key);
        key = NULL;
 
-       return __css_parse_value(css, attr);
+       return __css_parse_value(style, attr);
 }
 
 }
 
-static int __css_parse_attr(abc_obj_t* css, abc_obj_t* obj, const html_attr_t* attrs, int n_attrs)
+static int __css_parse_attr(abc_obj_t* style, css_rule_t* css, const html_attr_t* attrs, int n_attrs)
 {
        int ret = 0;
 
        while (1) {
 {
        int ret = 0;
 
        while (1) {
-               ret = __css_parse_attr2(css, obj, attrs, n_attrs);
+               ret = __css_parse_attr2(style, css, attrs, n_attrs);
 
                if ('}' == ret || EOF == ret)
                        break;
 
                if ('}' == ret || EOF == ret)
                        break;
@@ -244,125 +241,51 @@ static int __css_parse_attr(abc_obj_t* css, abc_obj_t* obj, const html_attr_t* a
        return ret;
 }
 
        return ret;
 }
 
-static int __css_parse_comma(abc_obj_t* css, abc_obj_t* obj)
+static int __css_parse_type(css_rule_t* css)
 {
 {
-       html_label_t*  label;
-       scf_list_t     h;
-
-       scf_list_init(&h);
-
        int combinator = -1;
        int combinator = -1;
-       int id         = 0;
-       int class      = 0;
-       int attr       = 0;
+       int id         = -1;
+       int class      = -1;
+       int attr       = -1;
        int pseClass   = -1;
        int pseElement = -1;
        int c;
        int i;
        int pseClass   = -1;
        int pseElement = -1;
        int c;
        int i;
+
        int j = -1;
        int j = -1;
-       int k = -1;
+       int k = css->text->len;
 
 
-       for (i = obj->text->len - 1; i >= 0; i--) {
-               c  = obj->text->data[i];
+       for (i = css->text->len - 1; i >= 0; i--) {
+               c  = css->text->data[i];
 
                assert('\t' != c);
                assert('\r' != c);
                assert('\n' != c);
 
                assert('\t' != c);
                assert('\r' != c);
                assert('\n' != c);
-
-               if (' ' == c) {
-                       if (combinator < 0 && k >= 0)
-                               combinator = i;
-                       continue;
-               }
-
-               if (',' == c) {
-                       if (k < 0)
-                               continue;
-
-                       assert(j >= 0);
-
-                       scf_string_t* key = scf_string_cstr_len(obj->text->data + j, k + 1 - j);
-                       if (!key) {
-                               scf_list_clear(&h, abc_obj_t, list, abc_obj_free);
-                               return -ENOMEM;
-                       }
-
-                       if (id > 0)
-                               label = __html_find_label2(ABC_CSS_ID);
-                       else if (class > 0)
-                               label = __html_find_label2(ABC_CSS_CLASS);
-                       else if (attr > 0)
-                               label = __html_find_label2(ABC_CSS_ATTR);
-
-                       else if (pseClass > 0)
-                               label = __html_find_label2(ABC_CSS_PSE_CLASS);
-                       else if (pseElement > 0)
-                               label = __html_find_label2(ABC_CSS_PSE_ELEMENT);
-
-                       else if (j < combinator && combinator < k)
-                               label = __html_find_label2(ABC_CSS_COMBINATOR);
-                       else {
-                               label = __html_find_label(key->data);
-                               if (!label) {
-                                       scf_loge("css selector '%s' invalid, file: %s, line: %d, pos: %d\n", key->data, obj->file->data, obj->line, j);
-
-                                       scf_string_free(key);
-                                       scf_list_clear(&h, abc_obj_t, list, abc_obj_free);
-                                       return -EINVAL;
-                               }
-                       }
-
-                       abc_obj_t* rule = abc_obj_alloc(obj->file, obj->line, j, label->type);
-                       if (!rule) {
-                               scf_string_free(key);
-                               scf_list_clear(&h, abc_obj_t, list, abc_obj_free);
-                               return -ENOMEM;
-                       }
-
-                       rule->flags  = label->flags;
-                       rule->keys   = label->names;
-                       rule->parent = css;
-
-                       if (rule->type < ABC_HTML_NB)
-                               scf_string_free(key);
-                       else
-                               rule->text = key;
-                       key = NULL;
-
-                       int ret = abc_obj_copy_attrs(rule, obj);
-                       if (ret < 0) {
-                               abc_obj_free(rule);
-                               scf_list_clear(&h, abc_obj_t, list, abc_obj_free);
-                               return ret;
-                       }
-
-                       scf_list_add_front(&h, &rule->list);
-
-                       combinator = -1;
-                       id         = 0;
-                       class      = 0;
-                       attr       = 0;
-                       pseClass   = -1;
-                       pseElement = -1;
-
-                       j = -1;
-                       k = -1;
-                       continue;
-               }
-
-               j = i;
-               if (k < 0)
-                       k = i;
+               assert (',' != c);
 
                switch (c) {
                        case '#':
 
                switch (c) {
                        case '#':
-                               id++;
+                               if (id < 0)
+                                       id = i;
+
+                               if (j < 0)
+                                       j = i;
                                break;
                                break;
+
                        case '.':
                        case '.':
-                               class++;
+                               if (class < 0)
+                                       class = i;
+
+                               if (j < 0)
+                                       j = i;
                                break;
                                break;
+
                        case '[':
                        case '[':
-                               attr++;
+                               if (attr < 0)
+                                       attr = i;
+
+                               if (j < 0)
+                                       j = i;
                                break;
 
                        case ':':
                                break;
 
                        case ':':
@@ -372,140 +295,177 @@ static int __css_parse_comma(abc_obj_t* css, abc_obj_t* obj)
                                        pseElement =  i;
                                        pseClass   = -1;
                                }
                                        pseElement =  i;
                                        pseClass   = -1;
                                }
+
+                               if (j < 0)
+                                       k = i;
                                break;
 
                                break;
 
+                       case ' ':
                        case '>':
                        case '+':
                        case '~':
                                if (combinator < 0)
                                        combinator = i;
                        case '>':
                        case '+':
                        case '~':
                                if (combinator < 0)
                                        combinator = i;
+
+                               if (j < 0)
+                                       j = i;
                                break;
                        default:
                                break;
                };
        }
 
                                break;
                        default:
                                break;
                };
        }
 
-       if (k >= 0) {
-               assert(k < obj->text->len);
-
-               obj->text->data[k + 1] = '\0';
-               obj->text->len         = k + 1;
-
-               if (id > 0)
-                       label = __html_find_label2(ABC_CSS_ID);
-               else if (class > 0)
-                       label = __html_find_label2(ABC_CSS_CLASS);
-               else if (attr > 0)
-                       label = __html_find_label2(ABC_CSS_ATTR);
-
-               else if (pseClass > 0)
-                       label = __html_find_label2(ABC_CSS_PSE_CLASS);
-               else if (pseElement > 0)
-                       label = __html_find_label2(ABC_CSS_PSE_ELEMENT);
-
-               else if (0 < combinator && combinator < k)
-                       label = __html_find_label2(ABC_CSS_COMBINATOR);
-               else {
-                       label = __html_find_label(obj->text->data);
-                       if (!label) {
-                               scf_loge("css selector '%s' invalid, file: %s, line: %d, pos: %d\n", obj->text->data, obj->file->data, obj->line, k);
-
-                               scf_list_clear(&h, abc_obj_t, list, abc_obj_free);
-                               return -EINVAL;
-                       }
-               }
+       html_label_t*  label;
 
 
-               obj->type   = label->type;
-               obj->flags  = label->flags;
-               obj->keys   = label->names;
-               obj->parent = css;
+       if (id >= 0)
+               label = __html_find_label2(ABC_CSS_ID);
 
 
-               if (obj->type < ABC_HTML_NB) {
-                       scf_string_free(obj->text);
-                       obj->text = NULL;
-               }
+       else if (class >= 0)
+               label = __html_find_label2(ABC_CSS_CLASS);
 
 
-               scf_list_add_front(&h, &obj->list);
+       else if (attr >= 0)
+               label = __html_find_label2(ABC_CSS_ATTR);
 
 
-               scf_list_mov2(&css->childs, &h);
-               return 0;
+       else if (pseClass >= 0)
+               label = __html_find_label2(ABC_CSS_PSE_CLASS);
+
+       else if (pseElement >= 0)
+               label = __html_find_label2(ABC_CSS_PSE_ELEMENT);
+
+       else if (combinator >= 0)
+               label = __html_find_label2(ABC_CSS_COMBINATOR);
+       else {
+               label = __html_find_label(css->text->data);
+               if (!label) {
+                       scf_loge("css selector '%s' invalid, file: %s, line: %d\n", css->text->data, css->file->data, css->line);
+                       return -EINVAL;
+               }
+
+               scf_string_free(css->text);
+               css->text = NULL;
        }
 
        }
 
-       scf_list_clear(&h, abc_obj_t, list, abc_obj_free);
-       return -EINVAL;
+       css->type  = label->type;
+       css->keys  = label->names;
+       css->flags = label->flags;
+
+       if (css->text) {
+               css->last_key     = j < 0 ? 0 : j;
+               css->last_key_end = k;
+
+               scf_logi("css selector '%s', last key: %.*s\n", css->text->data,
+                               (int)(css->last_key_end - css->last_key),
+                               css->text->data + css->last_key);
+       }
+       return 0;
 }
 
 static int __css_end_obj(int c)
 {
 }
 
 static int __css_end_obj(int c)
 {
-       if ('{' == c || EOF == c)
+       if (',' == c || '{' == c || EOF == c)
                return 1;
        return 0;
 }
 
                return 1;
        return 0;
 }
 
-static int __css_parse_obj(abc_obj_t* css, abc_char_t* c)
+static int __css_parse_selectors(abc_obj_t* style, scf_string_t* key, html_label_t* label, scf_list_t* h)
+{
+       int tmp = EOF;
+       do {
+               if (!key) {
+                       key = scf_string_alloc();
+                       if (!key)
+                               return -ENOMEM;
+               }
+
+               tmp = __css_parse_str(style, key, __css_end_obj);
+               if (EOF == tmp)
+                       break;
+
+               if (key->len > 0) {
+                       css_rule_t* css = css_rule_alloc(style->file, style->text_line, style->text_pos, label->type);
+                       if (!css) {
+                               scf_string_free(key);
+                               return -ENOMEM;
+                       }
+
+                       css->flags  = label->flags;
+                       css->keys   = label->names;
+                       css->parent = style;
+
+                       css->text = key;
+                       key = NULL;
+
+                       scf_list_add_tail(h, &css->list);
+               }
+       } while ('{' != tmp);
+
+       if (key)
+               scf_string_free(key);
+
+       return tmp;
+}
+
+static int __css_parse_obj(abc_obj_t* style, abc_char_t* c)
 {
        html_label_t*  label;
 {
        html_label_t*  label;
-       abc_obj_t*     obj;
        scf_string_t*  key = scf_string_cstr_len(c->utf8, c->len);
 
        scf_string_t*  key = scf_string_cstr_len(c->utf8, c->len);
 
-       css->text_pos += c->len;
+       style->text_pos += c->len;
        free(c);
        c = NULL;
 
        if (!key)
                return -ENOMEM;
 
        free(c);
        c = NULL;
 
        if (!key)
                return -ENOMEM;
 
-       int tmp = __css_parse_str(css, key, __css_end_obj);
-       switch (tmp) {
-               case '{':
-                       break;
-               default:
-                       scf_string_free(key);
-                       return -EINVAL;
-                       break;
-       };
-
        label = __html_find_label2(ABC_CSS_COMBINATOR);
        if (!label) {
        label = __html_find_label2(ABC_CSS_COMBINATOR);
        if (!label) {
-               scf_loge("invalid HTML label '%s' in file: %s, line: %d\n", key->data, css->file->data, css->text_line);
+               scf_loge("invalid HTML label '%s' in file: %s, line: %d\n", key->data, style->file->data, style->text_line);
                scf_string_free(key);
                return -EINVAL;
        }
 
                scf_string_free(key);
                return -EINVAL;
        }
 
-       obj = abc_obj_alloc(css->file, css->text_line, css->text_pos, label->type);
-       if (!obj) {
-               scf_string_free(key);
-               return -ENOMEM;
-       }
-
-       obj->flags  = label->flags;
-       obj->keys   = label->names;
-       obj->parent = css;
+       scf_list_t   h;
+       scf_list_t*  l;
+       css_rule_t*  css;
+       css_rule_t*  src;
 
 
-       obj->text = key;
-       key = NULL;
+       scf_list_init(&h);
 
 
-       int ret;
-       switch (tmp) {
-               case '{':
-                       ret = __css_parse_attr(css, obj, label->attrs, label->n_attrs);
-                       if (ret < 0) {
-                               abc_obj_free(obj);
-                               return ret;
-                       }
-                       break;
-               default:
-                       break;
+       int ret = __css_parse_selectors(style, key, label, &h);
+       if ('{' != ret) {
+               ret = -EINVAL;
+               goto error;
        };
 
        };
 
-       ret = __css_parse_comma(css, obj);
-       if (ret < 0)
-               abc_obj_free(obj);
+       if (scf_list_empty(&h))
+               return 0;
+
+       src = NULL;
+       for (l  = scf_list_head(&h); l != scf_list_sentinel(&h); l = scf_list_next(l)) {
+               css = scf_list_data(l, css_rule_t, list);
+
+               if (!src) {
+                       src = css;
+                       ret = __css_parse_attr(style, css, label->attrs, label->n_attrs);
+               } else
+                       ret = abc_css_copy_attrs(css, src);
+               if (ret < 0)
+                       goto error;
 
 
+               ret = __css_parse_type(css);
+               if (ret < 0)
+                       goto error;
+       }
+
+       scf_list_mov2(&style->css, &h);
+       return 0;
+
+error:
+       scf_list_clear(&h, css_rule_t, list, css_rule_free);
        return ret;
 }
 
        return ret;
 }
 
-int abc_css_parse(abc_obj_t* css)
+int abc_css_parse(abc_obj_t* style)
 {
        scf_string_t*  spath = NULL;
        abc_char_t*    c;
 {
        scf_string_t*  spath = NULL;
        abc_char_t*    c;
@@ -515,23 +475,23 @@ int abc_css_parse(abc_obj_t* css)
        char*          path;
        int            n;
 
        char*          path;
        int            n;
 
-       switch (css->type)
+       switch (style->type)
        {
                case ABC_HTML_STYLE:
        {
                case ABC_HTML_STYLE:
-                       if (!css->text)
+                       if (!style->text)
                                return 0;
 
                        n    = 0;
                        io   = abc_io_array[ABC_PROTO_STR];
                                return 0;
 
                        n    = 0;
                        io   = abc_io_array[ABC_PROTO_STR];
-                       path = css->text->data;
+                       path = style->text->data;
                        break;
 
                case ABC_HTML_LINK:
                        break;
 
                case ABC_HTML_LINK:
-                       href = abc_obj_get_attr(css, ABC_HTML_ATTR_HREF);
+                       href = abc_obj_get_attr(style, ABC_HTML_ATTR_HREF);
                        if (!href)
                                return 0;
 
                        if (!href)
                                return 0;
 
-                       n = __io_url_path(&io, &spath, css->file->data, href->value->data, href->value->len);
+                       n = __io_url_path(&io, &spath, style->file->data, href->value->data, href->value->len);
                        if (n < 0)
                                return n;
 
                        if (n < 0)
                                return n;
 
@@ -542,19 +502,19 @@ int abc_css_parse(abc_obj_t* css)
                        break;
        };
 
                        break;
        };
 
-       scf_logw("css->file: %s, path: %s\n", css->file->data, path);
+       scf_logw("style->file: %s, path: %s\n", style->file->data, path);
 
 
-       css->io.proto = io->proto;
-       css->io.priv  = NULL;
-       css->io.open  = io->open;
-       css->io.close = io->close;
-       css->io.popc  = io->popc;
-       css->io.post  = io->post;
+       style->io.proto = io->proto;
+       style->io.priv  = NULL;
+       style->io.open  = io->open;
+       style->io.close = io->close;
+       style->io.popc  = io->popc;
+       style->io.post  = io->post;
 
 
-       css->text_line = 1;
-       css->text_pos  = 0;
+       style->text_line  = 1;
+       style->text_pos   = 0;
 
 
-       int ret = io->open(&css->io, path + n);
+       int ret = io->open(&style->io, path + n);
        if (spath) {
                scf_string_free(spath);
                spath = NULL;
        if (spath) {
                scf_string_free(spath);
                spath = NULL;
@@ -563,7 +523,7 @@ int abc_css_parse(abc_obj_t* css)
                return ret;
 
        while (1) {
                return ret;
 
        while (1) {
-               c = __io_pop_char(&css->io);
+               c = __io_pop_char(&style->io);
                if (!c) {
                        ret = -1;
                        break;
                if (!c) {
                        ret = -1;
                        break;
@@ -576,20 +536,20 @@ int abc_css_parse(abc_obj_t* css)
                }
 
                if ('\n' == c->c) {
                }
 
                if ('\n' == c->c) {
-                       css->text_line++;
-                       css->text_pos = 0;
+                       style->text_line++;
+                       style->text_pos = 0;
                        free(c);
                        continue;
                }
 
                if (' ' == c->c || '\t' == c->c || '\r' == c->c) {
                        free(c);
                        continue;
                }
 
                if (' ' == c->c || '\t' == c->c || '\r' == c->c) {
-                       css->text_pos++;
+                       style->text_pos++;
                        free(c);
                        continue;
                }
 
                if ('/' == c->c) {
                        free(c);
                        continue;
                }
 
                if ('/' == c->c) {
-                       ret = __css_drop_comment(css);
+                       ret = __css_drop_comment(style);
                        if (0 == ret) {
                                free(c);
                                continue;
                        if (0 == ret) {
                                free(c);
                                continue;
@@ -603,20 +563,20 @@ int abc_css_parse(abc_obj_t* css)
                                ||  '.'    == c->c
                                ||  '['    == c->c) {
 
                                ||  '.'    == c->c
                                ||  '['    == c->c) {
 
-                       ret = __css_parse_obj(css, c);
+                       ret = __css_parse_obj(style, c);
                        if (ret < 0) {
                        if (ret < 0) {
-                               scf_loge("css->text_line: %d, css->text_pos: %d\n", css->text_line, css->text_pos);
+                               scf_loge("style->text_line: %d, style->text_pos: %d\n", style->text_line, style->text_pos);
                                break;
                        }
                } else {
                                break;
                        }
                } else {
-                       scf_loge("'%c'(%#x), css->text_line: %d, css->text_pos: %d\n", c->c, c->c, css->text_line, css->text_pos);
+                       scf_loge("'%c'(%#x), style->text_line: %d, style->text_pos: %d\n", c->c, c->c, style->text_line, style->text_pos);
                        free(c);
                        ret = -1;
                        break;
                }
        }
 
                        free(c);
                        ret = -1;
                        break;
                }
        }
 
-       io->close(&css->io);
+       io->close(&style->io);
        return ret;
 }
 
        return ret;
 }
 
@@ -822,161 +782,6 @@ static void __css_set_attr(abc_obj_t* obj, abc_attr_t* attr)
        };
 }
 
        };
 }
 
-static int __css_set_pse_dynamic(abc_obj_t* obj, abc_obj_t* pse)
-{
-       scf_list_t*  l;
-       abc_obj_t*   pse2;
-
-       for (l   = scf_list_head(&obj->css_pse_rules); l != scf_list_sentinel(&obj->css_pse_rules); l = scf_list_next(l)) {
-               pse2 = scf_list_data(l, abc_obj_t, list);
-
-               if (pse2->type == pse->type
-                               && pse2->text->len == pse->text->len
-                               && !__html_strcmp(pse2->text->data, pse->text->data))
-                       break;
-       }
-
-       if (l == scf_list_sentinel(&obj->css_pse_rules))
-       {
-               pse2 = abc_obj_alloc(pse->file, pse->line, pse->pos, pse->type);
-               if (!pse2)
-                       return -ENOMEM;
-
-               pse2->text = scf_string_clone(pse->text);
-               if (!pse2->text) {
-                       abc_obj_free(pse2);
-                       return -ENOMEM;
-               }
-
-               pse2->flags = pse->flags;
-               pse2->keys  = pse->keys;
-
-               scf_list_add_tail(&obj->css_pse_rules, &pse2->list);
-       }
-
-       int ret = abc_obj_copy_attrs(pse2, pse);
-       if (ret < 0)
-               return ret;
-
-       switch (pse->css_pse_type) {
-               case ABC_CSS_LINK:
-                       abc_obj_set_css(obj, pse);
-                       break;
-               default:
-                       break;
-       };
-
-       scf_slist_clear(pse2->css_pse_chain, pse_link_t, next, free);
-
-       pse2->css_pse_chain = pse->css_pse_chain;
-       pse ->css_pse_chain = NULL;
-}
-
-static void __css_merge(abc_obj_t* dst, abc_obj_t* src)
-{
-       abc_attr_t*  s;
-       abc_attr_t*  d;
-       int i;
-
-       for (i = 0; i < sizeof(src->attrs) / sizeof(src->attrs[0]); i++) {
-               s  = src->attrs[i];
-
-               if (!s || !s->value || 0 == s->value->len)
-                       continue;
-
-               d = dst->attrs[i];
-               if (d)
-                       SCF_XCHG(d->value, s->value);
-               else {
-                       dst->attrs[i] = s;
-                       src->attrs[i] = NULL;
-               }
-       }
-}
-
-int abc_css_merge(abc_html_t* html, abc_obj_t* css)
-{
-       if (!html || !css)
-               return -EINVAL;
-
-       if (!html->css)
-               html->css = css;
-       else
-               scf_list_mov2(&html->css->childs, &css->childs);
-
-       scf_list_t*  s;
-       scf_list_t*  d;
-       abc_obj_t*   src; // merge from
-       abc_obj_t*   dst; // merge to
-
-       for (s  = scf_list_tail(&html->css->childs); s != scf_list_sentinel(&html->css->childs); ) {
-               src = scf_list_data(s, abc_obj_t, list);
-               s   = scf_list_prev(s);
-
-               for (d  = s; d != scf_list_sentinel(&html->css->childs); d = scf_list_prev(d)) {
-                       dst = scf_list_data(d, abc_obj_t, list);
-
-                       if (src->type == dst->type) {
-                               if (src->type > ABC_HTML_NB && scf_string_cmp(src->text, dst->text))
-                                       continue;
-
-                               __css_merge(dst, src);
-
-                               scf_list_del(&src->list);
-                               abc_obj_free(src);
-                               break;
-                       }
-               }
-       }
-
-       scf_list_t  h_id;
-       scf_list_t  h_class;
-       scf_list_t  h_pse_class;
-       scf_list_t  h_pse_element;
-
-       scf_list_init(&h_id);
-       scf_list_init(&h_class);
-       scf_list_init(&h_pse_class);
-       scf_list_init(&h_pse_element);
-
-       for (s  = scf_list_head(&html->css->childs); s != scf_list_sentinel(&html->css->childs); ) {
-               src = scf_list_data(s, abc_obj_t, list);
-               s   = scf_list_next(s);
-
-               switch (src->type) {
-                       case ABC_CSS_ID:
-                               scf_list_del(&src->list);
-                               scf_list_add_tail(&h_id, &src->list);
-                               break;
-
-                       case ABC_CSS_CLASS:
-                       case ABC_CSS_ATTR:
-                               scf_list_del(&src->list);
-                               scf_list_add_tail(&h_class, &src->list);
-                               break;
-
-                       case ABC_CSS_PSE_CLASS:
-                               scf_list_del(&src->list);
-                               scf_list_add_tail(&h_pse_class, &src->list);
-                               break;
-
-                       case ABC_CSS_PSE_ELEMENT:
-                               scf_list_del(&src->list);
-                               scf_list_add_tail(&h_pse_element, &src->list);
-                               break;
-                       default:
-                               break;
-               };
-       }
-
-       // sort css priority, the last is the highest
-       scf_list_mov2(&html->css->childs, &h_pse_element);
-       scf_list_mov2(&html->css->childs, &h_pse_class);
-       scf_list_mov2(&html->css->childs, &h_class);
-       scf_list_mov2(&html->css->childs, &h_id);
-       return 0;
-}
-
 static abc_obj_t* __css_filter_pse(abc_obj_t* current, abc_attr_t* pse)
 {
        scf_list_t*  l;
 static abc_obj_t* __css_filter_pse(abc_obj_t* current, abc_attr_t* pse)
 {
        scf_list_t*  l;
@@ -997,6 +802,13 @@ static abc_obj_t* __css_filter_pse(abc_obj_t* current, abc_attr_t* pse)
                        }
                        break;
 
                        }
                        break;
 
+               case ABC_CSS_VISITED:
+               case ABC_CSS_HOVER:
+               case ABC_CSS_ACTIVE:
+
+                       if (!(pse->flags & ABC_CSS_FLAG_ON))
+                               return NULL;
+                       break;
                default:
                        break;
        };
                default:
                        break;
        };
@@ -1004,12 +816,11 @@ static abc_obj_t* __css_filter_pse(abc_obj_t* current, abc_attr_t* pse)
        return current;
 }
 
        return current;
 }
 
-static abc_obj_t* __css_select_by_key(abc_obj_t* css, abc_obj_t* current, scf_vector_t* vec, int next, const char* key, int len)
+static abc_obj_t* __css_select_by_key(css_rule_t* css, abc_obj_t* current, scf_vector_t* vec, int next, const char* key, int len)
 {
        scf_list_t*  l;
        abc_obj_t*   tmp;
        abc_attr_t*  pse;
 {
        scf_list_t*  l;
        abc_obj_t*   tmp;
        abc_attr_t*  pse;
-       pse_link_t*  pseLink;
 
        assert(next >= 0 && next < vec->size);
 
 
        assert(next >= 0 && next < vec->size);
 
@@ -1082,24 +893,10 @@ static abc_obj_t* __css_select_by_key(abc_obj_t* css, abc_obj_t* current, scf_ve
                        if (!pse)
                                return NULL;
 
                        if (!pse)
                                return NULL;
 
-                       if (css->css_pse_type < pse->type)
-                               css->css_pse_type = pse->type;
-
                        current = __css_filter_pse(current, pse);
                        if (!current)
                                return NULL;
 
                        current = __css_filter_pse(current, pse);
                        if (!current)
                                return NULL;
 
-                       pseLink = calloc(1, sizeof(pse_link_t));
-                       if (!pseLink)
-                               return NULL;
-
-                       pseLink->obj       = current;
-                       pseLink->pse_type  = pse->type;
-                       pseLink->next      = css->css_pse_chain;
-
-                       css->css_pse_chain = pseLink;
-                       pseLink = NULL;
-
                        scf_logd("current: %s, key: %.*s, j: %d, k: %d, next: %.*s\n", current->keys[0], len, key, j, k,
                                        k - j, css->text->data + j);
                        break;
                        scf_logd("current: %s, key: %.*s, j: %d, k: %d, next: %.*s\n", current->keys[0], len, key, j, k,
                                        k - j, css->text->data + j);
                        break;
@@ -1112,13 +909,12 @@ static abc_obj_t* __css_select_by_key(abc_obj_t* css, abc_obj_t* current, scf_ve
        return current;
 }
 
        return current;
 }
 
-static abc_obj_t* __css_select_by_id_class(abc_obj_t* css, abc_obj_t* current, scf_vector_t* vec, int next, int type, const char* value, int len)
+static abc_obj_t* __css_select_by_id_class(css_rule_t* css, abc_obj_t* current, scf_vector_t* vec, int next, int type, const char* value, int len)
 {
        scf_list_t*  l;
        abc_obj_t*   tmp;
        abc_attr_t*  attr;
        abc_attr_t*  pse;
 {
        scf_list_t*  l;
        abc_obj_t*   tmp;
        abc_attr_t*  attr;
        abc_attr_t*  pse;
-       pse_link_t*  pseLink;
 
        assert(next >= 0 && next < vec->size);
 
 
        assert(next >= 0 && next < vec->size);
 
@@ -1200,24 +996,10 @@ static abc_obj_t* __css_select_by_id_class(abc_obj_t* css, abc_obj_t* current, s
                        if (!pse)
                                return NULL;
 
                        if (!pse)
                                return NULL;
 
-                       if (css->css_pse_type < pse->type)
-                               css->css_pse_type = pse->type;
-
                        current = __css_filter_pse(current, pse);
                        if (!current)
                                return NULL;
 
                        current = __css_filter_pse(current, pse);
                        if (!current)
                                return NULL;
 
-                       pseLink = calloc(1, sizeof(pse_link_t));
-                       if (!pseLink)
-                               return NULL;
-
-                       pseLink->obj       = current;
-                       pseLink->pse_type  = pse->type;
-                       pseLink->next      = css->css_pse_chain;
-
-                       css->css_pse_chain = pseLink;
-                       pseLink = NULL;
-
                        scf_logd("current: %s, key: %.*s, j: %d, k: %d, next: %.*s\n", current->keys[0], len, value, j, k,
                                        k - j, css->text->data + j);
                        break;
                        scf_logd("current: %s, key: %.*s, j: %d, k: %d, next: %.*s\n", current->keys[0], len, value, j, k,
                                        k - j, css->text->data + j);
                        break;
@@ -1232,13 +1014,12 @@ static abc_obj_t* __css_select_by_id_class(abc_obj_t* css, abc_obj_t* current, s
        return current;
 }
 
        return current;
 }
 
-static abc_obj_t* __css_select_by_attr(abc_obj_t* css, abc_obj_t* current, scf_vector_t* vec, int next, const char* key, int len)
+static abc_obj_t* __css_select_by_attr(css_rule_t* css, abc_obj_t* current, scf_vector_t* vec, int next, const char* key, int len)
 {
        scf_list_t*  l;
        abc_obj_t*   tmp;
        abc_attr_t*  attr;
        abc_attr_t*  pse;
 {
        scf_list_t*  l;
        abc_obj_t*   tmp;
        abc_attr_t*  attr;
        abc_attr_t*  pse;
-       pse_link_t*  pseLink;
 
        assert(next >= 0 && next < vec->size);
 
 
        assert(next >= 0 && next < vec->size);
 
@@ -1408,25 +1189,11 @@ static abc_obj_t* __css_select_by_attr(abc_obj_t* css, abc_obj_t* current, scf_v
                        if (!pse)
                                return NULL;
 
                        if (!pse)
                                return NULL;
 
-                       if (css->css_pse_type < pse->type)
-                               css->css_pse_type = pse->type;
-
                        current = __css_filter_pse(current, pse);
                        if (!current)
                                return NULL;
 
                        current = __css_filter_pse(current, pse);
                        if (!current)
                                return NULL;
 
-                       pseLink = calloc(1, sizeof(pse_link_t));
-                       if (!pseLink)
-                               return NULL;
-
-                       pseLink->obj       = current;
-                       pseLink->pse_type  = pse->type;
-                       pseLink->next      = css->css_pse_chain;
-
-                       css->css_pse_chain = pseLink;
-                       pseLink = NULL;
-
-                       scf_logd("current: %s, key: %.*s, m: %d, n: %d, next: %.*s\n", current->keys[0], len, key, m, n,
+                       scf_logi("current: %s, key: %.*s, m: %d, n: %d, next: %.*s\n", current->keys[0], len, key, m, n,
                                        n - m, css->text->data + m);
                        break;
                default:
                                        n - m, css->text->data + m);
                        break;
                default:
@@ -1445,7 +1212,7 @@ static abc_obj_t* __css_select_by_attr(abc_obj_t* css, abc_obj_t* current, scf_v
        return current;
 }
 
        return current;
 }
 
-static int __css_use_complex(abc_obj_t* css, abc_obj_t* obj)
+static int __css_use_complex(css_rule_t* css, abc_obj_t* obj)
 {
        scf_vector_t* vec;
        abc_obj_t*    current = obj;
 {
        scf_vector_t* vec;
        abc_obj_t*    current = obj;
@@ -1462,9 +1229,6 @@ static int __css_use_complex(abc_obj_t* css, abc_obj_t* obj)
        if (ret < 0)
                goto end;
 
        if (ret < 0)
                goto end;
 
-       css->css_pse_type = 0;
-       scf_slist_clear(css->css_pse_chain, pse_link_t, next, free);
-
        int n_sqares = 0;
 
        for (i = css->text->len - 1; i >= 0; i--) {
        int n_sqares = 0;
 
        for (i = css->text->len - 1; i >= 0; i--) {
@@ -1539,8 +1303,8 @@ static int __css_use_complex(abc_obj_t* css, abc_obj_t* obj)
                                        if (i > 0 && ':' == css->text->data[i - 1])
                                        {
                                                if (j < css->text->len) {
                                        if (i > 0 && ':' == css->text->data[i - 1])
                                        {
                                                if (j < css->text->len) {
-                                                       scf_loge("pse element must be the last for combinators '%s', file: %s, line: %d\n",
-                                                                       css->text->data, css->file->data, css->text_line);
+                                                       scf_loge("pse element must be the last for combinators '%s', file: %s\n",
+                                                                       css->text->data, css->file->data);
                                                        ret = 0;
                                                        goto end;
                                                }
                                                        ret = 0;
                                                        goto end;
                                                }
@@ -1575,18 +1339,76 @@ static int __css_use_complex(abc_obj_t* css, abc_obj_t* obj)
                }
        }
 
                }
        }
 
-       if (css->css_pse_type < ABC_CSS_PSE_STATIC)
-               abc_obj_set_css(obj, css);
-       else
-               __css_set_pse_dynamic(obj, css);
+       abc_obj_set_css(obj, css);
 
        ret = 0;
 end:
 
        ret = 0;
 end:
-       scf_slist_clear(css->css_pse_chain, pse_link_t, next, free);
        scf_vector_free(vec);
        return ret;
 }
 
        scf_vector_free(vec);
        return ret;
 }
 
+int css_hash_update_attrs(css_hash_t* h, css_rule_t* r)
+{
+       abc_attr_t*  attr;
+       abc_attr_t*  copy;
+       int i;
+
+       for (i = 0; i < sizeof(r->attrs) / sizeof(r->attrs[0]); i++) {
+               attr = r->attrs[i];
+               if (!attr)
+                       continue;
+
+               copy = calloc(1, sizeof(abc_attr_t));
+               if (!copy)
+                       return -ENOMEM;
+
+               copy->value = scf_string_clone(attr->value);
+               if (!copy->value) {
+                       abc_attr_free(copy);
+                       return -ENOMEM;
+               }
+
+               copy->type  = attr->type;
+               copy->keys  = attr->keys;
+               copy->flags = attr->flags;
+
+               if (h->attrs[i])
+                       abc_attr_free(h->attrs[i]);
+
+               h->attrs[i] = copy;
+       }
+
+       return 0;
+}
+
+int abc_css_merge(abc_html_t* html, abc_obj_t* obj)
+{
+       if (!html || !obj)
+               return -EINVAL;
+
+       if (!html->css) {
+               html->css = abc_css_alloc();
+               if (!html->css)
+                       return -ENOMEM;
+       }
+
+       scf_list_t*  l;
+       css_rule_t*  css;
+       css_hash_t*  h;
+
+       for (l  = scf_list_head(&obj->css); l != scf_list_sentinel(&obj->css); l = scf_list_next(l)) {
+               css = scf_list_data(l, css_rule_t, list);
+
+               h = &(html->css->hash[css->type]);
+
+               scf_list_add_tail(&h->rules, &css->hash);
+
+               css_hash_update_attrs(h, css);
+       }
+
+       return 0;
+}
+
 int abc_css_use(abc_html_t* html, abc_obj_t* obj)
 {
        if (!html || !obj)
 int abc_css_use(abc_html_t* html, abc_obj_t* obj)
 {
        if (!html || !obj)
@@ -1594,28 +1416,28 @@ int abc_css_use(abc_html_t* html, abc_obj_t* obj)
 
        scf_list_t*  l;
        abc_attr_t*  attr;
 
        scf_list_t*  l;
        abc_attr_t*  attr;
-       abc_obj_t*   css;
+       css_rule_t*  css;
 
 
+       int64_t tv0 = gettime();
        if (html->css) {
        if (html->css) {
-               for (l  = scf_list_head(&html->css->childs); l != scf_list_sentinel(&html->css->childs); l = scf_list_next(l)) {
-                       css = scf_list_data(l, abc_obj_t, list);
+               css_hash_t*  h = &(html->css->hash[obj->type]);
 
 
-                       switch (css->type)
-                       {
-                               case ABC_CSS_ID:
-                               case ABC_CSS_CLASS:
-                               case ABC_CSS_ATTR:
-                               case ABC_CSS_PSE_CLASS:
-                               case ABC_CSS_PSE_ELEMENT:
-                               case ABC_CSS_COMBINATOR:
-                                       __css_use_complex(css, obj);
-                                       break;
+               int i;
+               for (i   = 0; i < sizeof(h->attrs) / sizeof(h->attrs[0]); i++) {
+                       attr = h->attrs[i];
+                       if (attr)
+                               __css_set_attr(obj, attr);
+               }
 
 
-                               default:
-                                       if (css->type == obj->type)
-                                               abc_obj_set_css(obj, css);
-                                       break;
-                       };
+               for (i = ABC_CSS_COMBINATOR; i < ABC_CSS_SELECTOR_NB; i++)
+               {
+                       h = &(html->css->hash[i]);
+
+                       for (l  = scf_list_head(&h->rules); l != scf_list_sentinel(&h->rules); l = scf_list_next(l)) {
+                               css = scf_list_data(l, css_rule_t, hash);
+
+                               __css_use_complex(css, obj);
+                       }
                }
        }
 
                }
        }
 
@@ -1627,7 +1449,7 @@ int abc_css_use(abc_html_t* html, abc_obj_t* obj)
                html_label_t*  label = __html_find_label2(obj->type);
                abc_io_t*      io    = abc_io_array[ABC_PROTO_STR];
 
                html_label_t*  label = __html_find_label2(obj->type);
                abc_io_t*      io    = abc_io_array[ABC_PROTO_STR];
 
-               css = abc_obj_alloc(obj->file, obj->line, obj->pos, ABC_HTML_STYLE);
+               abc_obj_t* css = abc_obj_alloc(obj->file, obj->line, obj->pos, ABC_HTML_STYLE);
                if (!css)
                        return -ENOMEM;
 
                if (!css)
                        return -ENOMEM;
 
@@ -1647,7 +1469,7 @@ int abc_css_use(abc_html_t* html, abc_obj_t* obj)
                        return ret;
                }
 
                        return ret;
                }
 
-               ret = __css_parse_attr(css, css, label->attrs, label->n_attrs);
+               ret = __css_parse_attr(css, (css_rule_t*)css, label->attrs, label->n_attrs);
                io->close(&css->io);
                if (ret < 0 && EOF != ret) {
                        abc_obj_free(css);
                io->close(&css->io);
                if (ret < 0 && EOF != ret) {
                        abc_obj_free(css);
@@ -1666,10 +1488,12 @@ int abc_css_use(abc_html_t* html, abc_obj_t* obj)
                abc_obj_free(css);
        }
 
                abc_obj_free(css);
        }
 
+       int64_t tv1 = gettime();
+       scf_logi("tv1 - tv0: %ld\n", tv1 - tv0);
        return 0;
 }
 
        return 0;
 }
 
-void abc_obj_set_css(abc_obj_t* obj, abc_obj_t* css)
+void abc_obj_set_css(abc_obj_t* obj, css_rule_t* css)
 {
        abc_attr_t*  attr;
        int i;
 {
        abc_attr_t*  attr;
        int i;
@@ -1682,29 +1506,28 @@ void abc_obj_set_css(abc_obj_t* obj, abc_obj_t* css)
        }
 }
 
        }
 }
 
-int abc_css_active(abc_obj_t* obj)
+int abc_css_clear(abc_obj_t* obj, int pse_start, int pse_end)
 {
 {
-       scf_list_t*  l;
-       abc_obj_t*   css;
-       pse_link_t*  pseLink;
-
-       int n = 0;
-       for (l  = scf_list_head(&obj->css_pse_rules); l != scf_list_sentinel(&obj->css_pse_rules); l = scf_list_next(l)) {
-               css = scf_list_data(l, abc_obj_t, list);
+       abc_attr_t*  attr;
+       int i;
 
 
-               pseLink = css->css_pse_chain;
-               while (pseLink) {
-                       if (pseLink->obj->css_pse_type != pseLink->pse_type)
-                               break;
+       for (i = pse_start; i <= pse_end; i++)
+       {
+               attr = abc_obj_get_attr(obj, i);
+               if (attr)
+                       attr->flags &= ~ABC_CSS_FLAG_ON;
+       }
 
 
-                       pseLink = pseLink->next;
-               }
+       return 0;
+}
 
 
-               if (!pseLink) {
-                       abc_obj_set_css(obj, css);
-                       n++;
-               }
+int abc_css_active(abc_obj_t* obj, int pse)
+{
+       abc_attr_t* attr = abc_obj_get_attr(obj, pse);
+       if (attr) {
+               attr->flags |= ABC_CSS_FLAG_ON;
+               return 1;
        }
 
        }
 
-       return n;
+       return 0;
 }
 }
index a696d7f283bdb4906513e493bb846b3e6886afb1..fcde40d9ce333a78eab5caf805a76e3b190c9f6c 100644 (file)
@@ -33,11 +33,12 @@ static void __css_border_type(int* type, const char* name, size_t name_len)
        }
 }
 
        }
 }
 
-int  abc_css_border2(double border_color[3], int* border_width, int* border_style, abc_obj_t* obj, int width, const uint8_t* str)
+int  abc_css_border2(double border_color[4], int* border_width, int* border_style, abc_obj_t* obj, int width, const uint8_t* str)
 {
        border_color[0] = 0.0;
        border_color[1] = 0.0;
        border_color[2] = 0.0;
 {
        border_color[0] = 0.0;
        border_color[1] = 0.0;
        border_color[2] = 0.0;
+       border_color[3] = 1.0;
        *border_width   = 0;
        *border_style   = ABC_BORDER_SOLID;
 
        *border_width   = 0;
        *border_style   = ABC_BORDER_SOLID;
 
@@ -100,7 +101,7 @@ int  abc_css_border2(double border_color[3], int* border_width, int* border_styl
                        } else if (p) {
 
                                if (i > 1)
                        } else if (p) {
 
                                if (i > 1)
-                                       abc_css_color(border_color, border_color + 1, border_color + 2, p, -1);
+                                       abc_css_color(border_color, p, -1);
                                else if (1 == i)
                                        __css_border_type(border_style, p, (size_t)(str - p));
 
                                else if (1 == i)
                                        __css_border_type(border_style, p, (size_t)(str - p));
 
@@ -141,7 +142,7 @@ static int __css_margin(abc_obj_t* obj, int width, int type)
 
 static int __css_border(abc_obj_t* obj, int width, int type)
 {
 
 static int __css_border(abc_obj_t* obj, int width, int type)
 {
-       double color[3];
+       double color[4];
        int    style;
        int    w = 0;
 
        int    style;
        int    w = 0;
 
index 3783bc345afb697c336f75d44b578facc51a3036..a63dc921625c6f54454c9e1b2781f2d8166a5b8d 100644 (file)
@@ -319,61 +319,60 @@ static css_color_t  css_colors[] =
        {css_YellowGreen,     0x9acd32},
 };
 
        {css_YellowGreen,     0x9acd32},
 };
 
-int abc_css_color(double* r, double* g, double* b, const uint8_t* str, size_t len)
+int abc_css_color(double rgba[4], const uint8_t* str, size_t len)
 {
 {
-       *r = 0.0;
-       *g = 0.0;
-       *b = 0.0;
+       rgba[0] = 0.0;
+       rgba[1] = 0.0;
+       rgba[2] = 0.0;
+       rgba[3] = 1.0;
 
        if (!str || 0 == len)
                return 0;
 
        if ('#' == *str) {
 
        if (!str || 0 == len)
                return 0;
 
        if ('#' == *str) {
-               uint64_t value = 0;
-               long     i;
+               int   v = 0;
+               long  i;
 
                for (i = 1; i < len && str[i]; i++) {
                        int c = str[i];
 
                        if ('0' <= c && '9' >= c) {
 
                for (i = 1; i < len && str[i]; i++) {
                        int c = str[i];
 
                        if ('0' <= c && '9' >= c) {
-                               value <<= 4;
-                               value += c - '0';
+                               v <<= 4;
+                               v += c - '0';
                        } else {
                                c |= 0x20;
 
                                if ('a' <= c && 'f' >= c) {
                        } else {
                                c |= 0x20;
 
                                if ('a' <= c && 'f' >= c) {
-                                       value <<= 4;
-                                       value += c - 'a' + 10;
+                                       v <<= 4;
+                                       v  += c - 'a' + 10;
                                }
                        }
                                }
                        }
+
+                       if (0 == i % 2) {
+                               rgba[i / 2 - 1] = v / 255.0;
+                               v = 0;
+                       }
                }
 
                }
 
-               *r = ((value >> 16) & 0xff) / 255.0;
-               *g = ((value >>  8) & 0xff) / 255.0;
-               *b = ( value        & 0xff) / 255.0;
+       } else if (!__html_strncmp(str, "rgb",  3)
+                       || !__html_strncmp(str, "rgba", 4)) {
 
 
-       } else if (!__html_strncmp(str, "rgb(", 4)) {
                long i;
                long i;
-               long j = 4;
+               for (i = 3; i < len && str[i]; i++) {
+                       if ('(' == str[i])
+                               break;
+               }
+
+               long j = ++i;
                int  k = 0;
 
                int  k = 0;
 
-               for (i = 4; i < len && str[i]; i++) {
+               for ( ; i < len && str[i]; i++) {
                        int c = str[i];
 
                        if (',' == c || ')' == c) {
                        int c = str[i];
 
                        if (',' == c || ')' == c) {
-                               switch (k) {
-                                       case 0:
-                                               *r = atof(str + j) / 255.0;
-                                               break;
-                                       case 1:
-                                               *g = atof(str + j) / 255.0;
-                                               break;
-                                       case 2:
-                                               *b = atof(str + j) / 255.0;
-                                               break;
-                               };
-
-                               if (++k > 2)
+                               rgba[k] = atof(str + j) / 255.0;
+
+                               if (++k > 3)
                                        break;
                                j = i + 1;
                        }
                                        break;
                                j = i + 1;
                        }
@@ -385,10 +384,12 @@ int abc_css_color(double* r, double* g, double* b, const uint8_t* str, size_t le
 
                        int j;
                        for (j = 0; c->names[j]; j++) {
 
                        int j;
                        for (j = 0; c->names[j]; j++) {
+
                                if (!__html_strncmp(c->names[j], str, len)) {
                                if (!__html_strncmp(c->names[j], str, len)) {
-                                       *r = ((c->color >> 16) & 0xff) / 255.0;
-                                       *g = ((c->color >>  8) & 0xff) / 255.0;
-                                       *b = ( c->color        & 0xff) / 255.0;
+
+                                       rgba[0] = ((c->color >> 16) & 0xff) / 255.0;
+                                       rgba[1] = ((c->color >>  8) & 0xff) / 255.0;
+                                       rgba[2] = ( c->color        & 0xff) / 255.0;
                                        return 0;
                                }
                        }
                                        return 0;
                                }
                        }
@@ -400,15 +401,17 @@ int abc_css_color(double* r, double* g, double* b, const uint8_t* str, size_t le
        return 0;
 }
 
        return 0;
 }
 
-int abc_css_scrollbar_color(double thumb[3], double track[3], const uint8_t* str)
+int abc_css_scrollbar_color(double thumb[4], double track[4], const uint8_t* str)
 {
        thumb[0] = 0.0;
        thumb[1] = 0.0;
        thumb[2] = 0.0;
 {
        thumb[0] = 0.0;
        thumb[1] = 0.0;
        thumb[2] = 0.0;
+       thumb[3] = 1.0;
 
        track[0] = 0.0;
        track[1] = 0.0;
        track[2] = 0.0;
 
        track[0] = 0.0;
        track[1] = 0.0;
        track[2] = 0.0;
+       track[3] = 0.0;
 
        if (!str)
                return 0;
 
        if (!str)
                return 0;
@@ -432,10 +435,10 @@ int abc_css_scrollbar_color(double thumb[3], double track[3], const uint8_t* str
                } else if ('\0' == c || ' ' == c || '\t' == c || '\r' == c || '\n' == c) {
 
                        if (0 == k) {
                } else if ('\0' == c || ' ' == c || '\t' == c || '\r' == c || '\n' == c) {
 
                        if (0 == k) {
-                               abc_css_color(thumb, thumb + 1, thumb + 2, str + j, i - 1 - j);
+                               abc_css_color(thumb, str + j, i - 1 - j);
                                k = 1;
                        } else {
                                k = 1;
                        } else {
-                               abc_css_color(track, track + 1, track + 2, str + j, i - 1 - j);
+                               abc_css_color(track, str + j, i - 1 - j);
                                break;
                        }
 
                                break;
                        }
 
index b193055ffb3f9a6265861701c1e6a69539235627..445eea5c90632f1a4992bf724441b70f1343c9bc 100644 (file)
@@ -3,6 +3,7 @@
 // HTML & CSS attrs
 static char* src_keys[]        = {"src",        "源",       NULL};
 static char* rel_keys[]        = {"rel",        "关系",     NULL};
 // HTML & CSS attrs
 static char* src_keys[]        = {"src",        "源",       NULL};
 static char* rel_keys[]        = {"rel",        "关系",     NULL};
+static char* alt_keys[]        = {"alt",        "替代文本", NULL};
 static char* href_keys[]       = {"href",       "地址",     NULL};
 
 static char* width_keys[]      = {"width",      "宽度",     NULL};
 static char* href_keys[]       = {"href",       "地址",     NULL};
 
 static char* width_keys[]      = {"width",      "宽度",     NULL};
@@ -10,6 +11,8 @@ static char* height_keys[]     = {"height",     "高度",     NULL};
 
 static char* display_keys[]        = {"display",         "显示模式", NULL};
 static char* visible_keys[]        = {"visibility",      "可见性",   NULL};
 
 static char* display_keys[]        = {"display",         "显示模式", NULL};
 static char* visible_keys[]        = {"visibility",      "可见性",   NULL};
+static char* opacity_keys[]        = {"opacity",         "透明度",   NULL};
+static char* filter_keys[]         = {"filter",          "滤镜",     NULL};
 
 static char* margin_keys[]         = {"margin",          "外边距",   NULL};
 static char* margin_top_keys[]     = {"margin-top",      "上边缘",   NULL};
 
 static char* margin_keys[]         = {"margin",          "外边距",   NULL};
 static char* margin_top_keys[]     = {"margin-top",      "上边缘",   NULL};
@@ -191,18 +194,18 @@ static html_attr_t  html_attrs[] =
 
 #define ABC_CSS_SELECTOR(type) \
        {style_keys,          "",        ABC_HTML_ATTR_STYLE,         ABC_HTML_FLAG_SHOW}, \
 
 #define ABC_CSS_SELECTOR(type) \
        {style_keys,          "",        ABC_HTML_ATTR_STYLE,         ABC_HTML_FLAG_SHOW}, \
-       {class_keys,          "",        ABC_HTML_ATTR_CLASS,         ABC_HTML_FLAG_SHOW}, \
        {title_keys,          "",        ABC_HTML_ATTR_TITLE,         ABC_HTML_FLAG_SHOW}, \
        {type_keys,          #type,      ABC_HTML_ATTR_TYPE,          ABC_HTML_FLAG_SHOW}, \
        {name_keys,           "",        ABC_HTML_ATTR_NAME,          ABC_HTML_FLAG_SHOW}, \
        {title_keys,          "",        ABC_HTML_ATTR_TITLE,         ABC_HTML_FLAG_SHOW}, \
        {type_keys,          #type,      ABC_HTML_ATTR_TYPE,          ABC_HTML_FLAG_SHOW}, \
        {name_keys,           "",        ABC_HTML_ATTR_NAME,          ABC_HTML_FLAG_SHOW}, \
-       {id_keys,             "",        ABC_HTML_ATTR_ID,            ABC_HTML_FLAG_SHOW},
+       {class_keys,          "",        ABC_CSS_CLASS,               ABC_HTML_FLAG_SHOW}, \
+       {id_keys,             "",        ABC_CSS_ID,                  ABC_HTML_FLAG_SHOW},
 
 #define ABC_CSS_BACK_GROUND(color) \
        {bg_keys,             "",        ABC_HTML_ATTR_BG,            ABC_HTML_FLAG_SHOW}, \
        {bg_color_keys,       #color,    ABC_HTML_ATTR_BG_COLOR,      ABC_HTML_FLAG_SHOW}, \
        {bg_image_keys,       "",        ABC_HTML_ATTR_BG_IMAGE,      ABC_HTML_FLAG_SHOW}, \
        {bg_repeat_keys,      "",        ABC_HTML_ATTR_BG_REPEAT,     ABC_HTML_FLAG_SHOW}, \
 
 #define ABC_CSS_BACK_GROUND(color) \
        {bg_keys,             "",        ABC_HTML_ATTR_BG,            ABC_HTML_FLAG_SHOW}, \
        {bg_color_keys,       #color,    ABC_HTML_ATTR_BG_COLOR,      ABC_HTML_FLAG_SHOW}, \
        {bg_image_keys,       "",        ABC_HTML_ATTR_BG_IMAGE,      ABC_HTML_FLAG_SHOW}, \
        {bg_repeat_keys,      "",        ABC_HTML_ATTR_BG_REPEAT,     ABC_HTML_FLAG_SHOW}, \
-       {bg_position_keys,    "",        ABC_HTML_ATTR_BG_POSITION,   ABC_HTML_FLAG_SHOW},
+       {bg_position_keys,    "",        ABC_HTML_ATTR_BG_POSITION,   ABC_HTML_FLAG_SHOW}, \
 
 #define ABC_CSS_FONT(font, size, color, style) \
        {font_keys,           #font,     ABC_HTML_ATTR_FONT,          0}, \
 
 #define ABC_CSS_FONT(font, size, color, style) \
        {font_keys,           #font,     ABC_HTML_ATTR_FONT,          0}, \
@@ -216,6 +219,12 @@ static html_attr_t  html_attrs[] =
        {text_transform_keys,  "",          ABC_HTML_ATTR_TEXT_TRANSFORM,  ABC_HTML_FLAG_SHOW}, \
        {text_indent_keys,     "",          ABC_HTML_ATTR_TEXT_INDENT,     ABC_HTML_FLAG_SHOW},
 
        {text_transform_keys,  "",          ABC_HTML_ATTR_TEXT_TRANSFORM,  ABC_HTML_FLAG_SHOW}, \
        {text_indent_keys,     "",          ABC_HTML_ATTR_TEXT_INDENT,     ABC_HTML_FLAG_SHOW},
 
+#define ABC_CSS_PSE_MOUSE() \
+       {css_link_keys,     "",  ABC_CSS_LINK,        ABC_HTML_FLAG_SHOW}, \
+       {css_visited_keys,  "",  ABC_CSS_VISITED,     ABC_HTML_FLAG_SHOW}, \
+       {css_hover_keys,    "",  ABC_CSS_HOVER,       ABC_HTML_FLAG_SHOW}, \
+       {css_active_keys,   "",  ABC_CSS_ACTIVE,      ABC_HTML_FLAG_SHOW},
+
        ABC_CSS_BOX(block, , , 12px)
        ABC_CSS_SCROLL(scroll, 12px, orangeRed white)
        ABC_CSS_SELECTOR()
        ABC_CSS_BOX(block, , , 12px)
        ABC_CSS_SCROLL(scroll, 12px, orangeRed white)
        ABC_CSS_SELECTOR()
@@ -227,6 +236,9 @@ static html_attr_t  html_attrs[] =
        {xmlns_keys,       "",           ABC_HTML_ATTR_XMLNS,     0},
        {xmlang_keys,      "",           ABC_HTML_ATTR_XMLANG,    0},
        {lang_keys,        "",           ABC_HTML_ATTR_LANG,      0},
        {xmlns_keys,       "",           ABC_HTML_ATTR_XMLNS,     0},
        {xmlang_keys,      "",           ABC_HTML_ATTR_XMLANG,    0},
        {lang_keys,        "",           ABC_HTML_ATTR_LANG,      0},
+
+       {opacity_keys,     "1.0",        ABC_CSS_OPACITY,         ABC_HTML_FLAG_SHOW},
+       {filter_keys,      "",           ABC_CSS_FILTER,          0},
 };
 
 static html_attr_t  meta_attrs[] =
 };
 
 static html_attr_t  meta_attrs[] =
@@ -245,6 +257,9 @@ static html_attr_t  body_attrs[] =
 
        ABC_CSS_FONT(SimSong, 16, black, )
        ABC_CSS_TEXT(left, )
 
        ABC_CSS_FONT(SimSong, 16, black, )
        ABC_CSS_TEXT(left, )
+
+       {opacity_keys,     "1.0",        ABC_CSS_OPACITY,         ABC_HTML_FLAG_SHOW},
+       {filter_keys,      "",           ABC_CSS_FILTER,          0},
 };
 
 static html_attr_t  div_attrs[] =
 };
 
 static html_attr_t  div_attrs[] =
@@ -256,6 +271,11 @@ static html_attr_t  div_attrs[] =
 
        ABC_CSS_FONT(SimSong, 16, black, )
        ABC_CSS_TEXT(left, )
 
        ABC_CSS_FONT(SimSong, 16, black, )
        ABC_CSS_TEXT(left, )
+
+       ABC_CSS_PSE_MOUSE()
+
+       {opacity_keys,     "",           ABC_CSS_OPACITY,         ABC_HTML_FLAG_SHOW},
+       {filter_keys,      "",           ABC_CSS_FILTER,          0},
 };
 
 static html_attr_t  h1_attrs[] =
 };
 
 static html_attr_t  h1_attrs[] =
@@ -267,6 +287,11 @@ static html_attr_t  h1_attrs[] =
 
        ABC_CSS_FONT(SimHei, 40, black, )
        ABC_CSS_TEXT(left, )
 
        ABC_CSS_FONT(SimHei, 40, black, )
        ABC_CSS_TEXT(left, )
+
+       ABC_CSS_PSE_MOUSE()
+
+       {opacity_keys,     "",           ABC_CSS_OPACITY,         ABC_HTML_FLAG_SHOW},
+       {filter_keys,      "",           ABC_CSS_FILTER,          0},
 };
 
 static html_attr_t  h2_attrs[] =
 };
 
 static html_attr_t  h2_attrs[] =
@@ -278,6 +303,11 @@ static html_attr_t  h2_attrs[] =
 
        ABC_CSS_FONT(SimHei, 32, black, )
        ABC_CSS_TEXT(left, )
 
        ABC_CSS_FONT(SimHei, 32, black, )
        ABC_CSS_TEXT(left, )
+
+       ABC_CSS_PSE_MOUSE()
+
+       {opacity_keys,     "",           ABC_CSS_OPACITY,         ABC_HTML_FLAG_SHOW},
+       {filter_keys,      "",           ABC_CSS_FILTER,          0},
 };
 
 static html_attr_t  h3_attrs[] =
 };
 
 static html_attr_t  h3_attrs[] =
@@ -289,6 +319,11 @@ static html_attr_t  h3_attrs[] =
 
        ABC_CSS_FONT(SimHei, 28, black, )
        ABC_CSS_TEXT(left, )
 
        ABC_CSS_FONT(SimHei, 28, black, )
        ABC_CSS_TEXT(left, )
+
+       ABC_CSS_PSE_MOUSE()
+
+       {opacity_keys,     "",           ABC_CSS_OPACITY,         ABC_HTML_FLAG_SHOW},
+       {filter_keys,      "",           ABC_CSS_FILTER,          0},
 };
 
 static html_attr_t  h4_attrs[] =
 };
 
 static html_attr_t  h4_attrs[] =
@@ -300,6 +335,11 @@ static html_attr_t  h4_attrs[] =
 
        ABC_CSS_FONT(SimHei, 24, black, )
        ABC_CSS_TEXT(left, )
 
        ABC_CSS_FONT(SimHei, 24, black, )
        ABC_CSS_TEXT(left, )
+
+       ABC_CSS_PSE_MOUSE()
+
+       {opacity_keys,     "",           ABC_CSS_OPACITY,         ABC_HTML_FLAG_SHOW},
+       {filter_keys,      "",           ABC_CSS_FILTER,          0},
 };
 
 static html_attr_t  h5_attrs[] =
 };
 
 static html_attr_t  h5_attrs[] =
@@ -311,6 +351,11 @@ static html_attr_t  h5_attrs[] =
 
        ABC_CSS_FONT(SimHei, 20, black, )
        ABC_CSS_TEXT(left, )
 
        ABC_CSS_FONT(SimHei, 20, black, )
        ABC_CSS_TEXT(left, )
+
+       ABC_CSS_PSE_MOUSE()
+
+       {opacity_keys,     "",           ABC_CSS_OPACITY,         ABC_HTML_FLAG_SHOW},
+       {filter_keys,      "",           ABC_CSS_FILTER,          0},
 };
 
 static html_attr_t  h6_attrs[] =
 };
 
 static html_attr_t  h6_attrs[] =
@@ -322,6 +367,11 @@ static html_attr_t  h6_attrs[] =
 
        ABC_CSS_FONT(SimHei, 16, black, )
        ABC_CSS_TEXT(left, )
 
        ABC_CSS_FONT(SimHei, 16, black, )
        ABC_CSS_TEXT(left, )
+
+       ABC_CSS_PSE_MOUSE()
+
+       {opacity_keys,     "",           ABC_CSS_OPACITY,         ABC_HTML_FLAG_SHOW},
+       {filter_keys,      "",           ABC_CSS_FILTER,          0},
 };
 
 static html_attr_t  hr_attrs[] =
 };
 
 static html_attr_t  hr_attrs[] =
@@ -333,6 +383,9 @@ static html_attr_t  hr_attrs[] =
 
        ABC_CSS_FONT(SimHei, 16, lightGray, )
        ABC_CSS_TEXT(left, )
 
        ABC_CSS_FONT(SimHei, 16, lightGray, )
        ABC_CSS_TEXT(left, )
+
+       {opacity_keys,     "",           ABC_CSS_OPACITY,         ABC_HTML_FLAG_SHOW},
+       {filter_keys,      "",           ABC_CSS_FILTER,          0},
 };
 
 static html_attr_t  p_attrs[] =
 };
 
 static html_attr_t  p_attrs[] =
@@ -345,6 +398,11 @@ static html_attr_t  p_attrs[] =
        ABC_CSS_FONT(SimSong, 16, black, )
        ABC_CSS_TEXT(left, )
 
        ABC_CSS_FONT(SimSong, 16, black, )
        ABC_CSS_TEXT(left, )
 
+       ABC_CSS_PSE_MOUSE()
+
+       {opacity_keys,         "", ABC_CSS_OPACITY,     ABC_HTML_FLAG_SHOW},
+       {filter_keys,          "", ABC_CSS_FILTER,      0},
+
        {css_first_child_keys, "", ABC_CSS_FIRST_CHILD, ABC_HTML_FLAG_SHOW},
 };
 
        {css_first_child_keys, "", ABC_CSS_FIRST_CHILD, ABC_HTML_FLAG_SHOW},
 };
 
@@ -365,6 +423,9 @@ static html_attr_t  css_id_attrs[] =
        ABC_CSS_TEXT(left, )
        ABC_CSS_LIST()
 
        ABC_CSS_TEXT(left, )
        ABC_CSS_LIST()
 
+       {opacity_keys,         "",  ABC_CSS_OPACITY,               ABC_HTML_FLAG_SHOW},
+       {filter_keys,          "",  ABC_CSS_FILTER,                0},
+
        {vertical_align_keys,  "",  ABC_HTML_ATTR_VERTICAL_ALIGN,  ABC_HTML_FLAG_SHOW},
 };
 
        {vertical_align_keys,  "",  ABC_HTML_ATTR_VERTICAL_ALIGN,  ABC_HTML_FLAG_SHOW},
 };
 
@@ -378,6 +439,9 @@ static html_attr_t  b_attrs[] =
        ABC_CSS_FONT(SimHei, 16, , bold)
        ABC_CSS_TEXT(left, )
 
        ABC_CSS_FONT(SimHei, 16, , bold)
        ABC_CSS_TEXT(left, )
 
+       {opacity_keys,         "", ABC_CSS_OPACITY,     ABC_HTML_FLAG_SHOW},
+       {filter_keys,          "", ABC_CSS_FILTER,      0},
+
        {css_first_child_keys, "", ABC_CSS_FIRST_CHILD, ABC_HTML_FLAG_SHOW},
 };
 
        {css_first_child_keys, "", ABC_CSS_FIRST_CHILD, ABC_HTML_FLAG_SHOW},
 };
 
@@ -391,6 +455,9 @@ static html_attr_t  i_attrs[] =
        ABC_CSS_FONT(SimSong, 16, , italic)
        ABC_CSS_TEXT(left, )
 
        ABC_CSS_FONT(SimSong, 16, , italic)
        ABC_CSS_TEXT(left, )
 
+       {opacity_keys,         "", ABC_CSS_OPACITY,     ABC_HTML_FLAG_SHOW},
+       {filter_keys,          "", ABC_CSS_FILTER,      0},
+
        {css_first_child_keys, "", ABC_CSS_FIRST_CHILD, ABC_HTML_FLAG_SHOW},
 };
 
        {css_first_child_keys, "", ABC_CSS_FIRST_CHILD, ABC_HTML_FLAG_SHOW},
 };
 
@@ -404,11 +471,12 @@ static html_attr_t  a_attrs[] =
        ABC_CSS_FONT(SimSong, 16, blue, )
        ABC_CSS_TEXT(left, underline)
 
        ABC_CSS_FONT(SimSong, 16, blue, )
        ABC_CSS_TEXT(left, underline)
 
-       {href_keys,         "",  ABC_HTML_ATTR_HREF,  ABC_HTML_FLAG_SHOW},
-       {css_link_keys,     "",  ABC_CSS_LINK,        ABC_HTML_FLAG_SHOW},
-       {css_visited_keys,  "",  ABC_CSS_VISITED,     ABC_HTML_FLAG_SHOW},
-       {css_hover_keys,    "",  ABC_CSS_HOVER,       ABC_HTML_FLAG_SHOW},
-       {css_active_keys,   "",  ABC_CSS_ACTIVE,      ABC_HTML_FLAG_SHOW},
+       ABC_CSS_PSE_MOUSE()
+
+       {opacity_keys, "",  ABC_CSS_OPACITY,     ABC_HTML_FLAG_SHOW},
+       {filter_keys,  "",  ABC_CSS_FILTER,      0},
+
+       {href_keys,    "",  ABC_HTML_ATTR_HREF,  ABC_HTML_FLAG_SHOW},
 };
 
 static html_attr_t  link_attrs[] =
 };
 
 static html_attr_t  link_attrs[] =
@@ -424,7 +492,13 @@ static html_attr_t  img_attrs[] =
        ABC_CSS_SCROLL( , , )
        ABC_CSS_SELECTOR()
 
        ABC_CSS_SCROLL( , , )
        ABC_CSS_SELECTOR()
 
-       {src_keys,       "",  ABC_HTML_ATTR_SRC,  ABC_HTML_FLAG_SHOW},
+       ABC_CSS_PSE_MOUSE()
+
+       {src_keys,        "",  ABC_HTML_ATTR_SRC,   ABC_HTML_FLAG_SHOW},
+       {alt_keys,        "",  ABC_HTML_ATTR_ALT,   ABC_HTML_FLAG_SHOW},
+
+       {opacity_keys,    "",  ABC_CSS_OPACITY,     ABC_HTML_FLAG_SHOW},
+       {filter_keys,     "",  ABC_CSS_FILTER,      0},
 };
 
 static html_attr_t  video_attrs[] =
 };
 
 static html_attr_t  video_attrs[] =
@@ -433,7 +507,12 @@ static html_attr_t  video_attrs[] =
        ABC_CSS_SCROLL( , , )
        ABC_CSS_SELECTOR()
 
        ABC_CSS_SCROLL( , , )
        ABC_CSS_SELECTOR()
 
+       ABC_CSS_PSE_MOUSE()
+
        {control_keys,  "",  ABC_HTML_ATTR_CONTROLS,  0},
        {control_keys,  "",  ABC_HTML_ATTR_CONTROLS,  0},
+
+       {opacity_keys,  "",  ABC_CSS_OPACITY,         ABC_HTML_FLAG_SHOW},
+       {filter_keys,   "",  ABC_CSS_FILTER,          0},
 };
 
 static html_attr_t  audio_attrs[] =
 };
 
 static html_attr_t  audio_attrs[] =
@@ -457,8 +536,13 @@ static html_attr_t  input_attrs[] =
        ABC_CSS_FONT(SimSong, 16, black, )
        ABC_CSS_TEXT(left, )
 
        ABC_CSS_FONT(SimSong, 16, black, )
        ABC_CSS_TEXT(left, )
 
+       ABC_CSS_PSE_MOUSE()
+
        {size_keys,     "",      ABC_HTML_ATTR_SIZE,   ABC_HTML_FLAG_SHOW},
        {value_keys,    "",      ABC_HTML_ATTR_VALUE,  ABC_HTML_FLAG_SHOW},
        {size_keys,     "",      ABC_HTML_ATTR_SIZE,   ABC_HTML_FLAG_SHOW},
        {value_keys,    "",      ABC_HTML_ATTR_VALUE,  ABC_HTML_FLAG_SHOW},
+
+       {opacity_keys,  "",      ABC_CSS_OPACITY,      ABC_HTML_FLAG_SHOW},
+       {filter_keys,   "",      ABC_CSS_FILTER,       0},
 };
 
 static html_attr_t  label_attrs[] =
 };
 
 static html_attr_t  label_attrs[] =
@@ -656,7 +740,7 @@ html_label_t* __html_find_label2(const int type)
 
 int __html_add_attr(abc_obj_t* obj, int type, char** names, const char* value, int flags)
 {
 
 int __html_add_attr(abc_obj_t* obj, int type, char** names, const char* value, int flags)
 {
-       if (type < ABC_HTML_ATTR_ID || type >= ABC_HTML_CSS_NB)
+       if (type < ABC_CSS_CLASS || type >= ABC_HTML_CSS_NB)
                return -EINVAL;
 
        abc_attr_t* attr = calloc(1, sizeof(abc_attr_t));
                return -EINVAL;
 
        abc_attr_t* attr = calloc(1, sizeof(abc_attr_t));
@@ -673,7 +757,7 @@ int __html_add_attr(abc_obj_t* obj, int type, char** names, const char* value, i
        attr->keys  = names;
        attr->flags = flags;
 
        attr->keys  = names;
        attr->flags = flags;
 
-       int i = type - ABC_HTML_ATTR_ID;
+       int i = type - ABC_CSS_CLASS;
        if (obj->attrs[i])
                abc_attr_free(obj->attrs[i]);
 
        if (obj->attrs[i])
                abc_attr_free(obj->attrs[i]);
 
@@ -898,6 +982,9 @@ void abc_html_close(abc_html_t* html)
                if (html->file)
                        scf_string_free(html->file);
 
                if (html->file)
                        scf_string_free(html->file);
 
+               if (html->css)
+                       abc_css_free(html->css);
+
                if (html->js)
                        scf_parse_close(html->js);
 
                if (html->js)
                        scf_parse_close(html->js);
 
@@ -1519,10 +1606,8 @@ static int __html_parse_obj(abc_html_t* html, abc_char_t* c)
                        if (abc_css_parse(obj) < 0)
                                return -1;
 
                        if (abc_css_parse(obj) < 0)
                                return -1;
 
-                       if (abc_css_merge(html, obj) < 0) {
-                               scf_loge("\n");
+                       if (abc_css_merge(html, obj) < 0)
                                return -1;
                                return -1;
-                       }
                        break;
 
                case ABC_HTML_VIDEO:
                        break;
 
                case ABC_HTML_VIDEO:
@@ -1531,10 +1616,7 @@ static int __html_parse_obj(abc_html_t* html, abc_char_t* c)
                case ABC_HTML_AUDIO:
                        if (__html_add_controls(obj) < 0)
                                return -1;
                case ABC_HTML_AUDIO:
                        if (__html_add_controls(obj) < 0)
                                return -1;
-
                default:
                default:
-                       if (abc_css_use(html, obj) < 0)
-                               return -1;
                        break;
        };
 
                        break;
        };
 
index 760e3f6f8eff203e9b3af062cb0b69aba0de0409..9d788289abf28e1c200dcf5c6377906c64eb9b6c 100644 (file)
@@ -32,7 +32,8 @@ struct abc_html_s
 
        abc_obj_t*      root;
        abc_obj_t*      current;
 
        abc_obj_t*      root;
        abc_obj_t*      current;
-       abc_obj_t*      css;
+
+       abc_css_t*      css;
 
        abc_io_t        io;
 
 
        abc_io_t        io;
 
@@ -50,16 +51,18 @@ int  abc_html_post (abc_html_t** pp, abc_html_t* form, abc_obj_t* submit);
 void abc_html_close(abc_html_t*  html);
 
 int  abc_html_parse(abc_html_t* html);
 void abc_html_close(abc_html_t*  html);
 
 int  abc_html_parse(abc_html_t* html);
-int  abc_css_parse (abc_obj_t*  css);
-int  abc_css_merge (abc_html_t* html, abc_obj_t* css);
+int  abc_css_parse (abc_obj_t*  style);
+int  abc_css_merge (abc_html_t* html, abc_obj_t* obj);
 int  abc_css_use   (abc_html_t* html, abc_obj_t* obj);
 int  abc_css_use   (abc_html_t* html, abc_obj_t* obj);
-int  abc_css_active(abc_obj_t*  obj);
+
+int  abc_css_clear (abc_obj_t*  obj, int pse_start, int pse_end);
+int  abc_css_active(abc_obj_t*  obj, int pse);
 
 int  abc_css_bg_position(float*  x, float*  y, float   w, float h, abc_obj_t* obj, const uint8_t* str);
 
 
 int  abc_css_bg_position(float*  x, float*  y, float   w, float h, abc_obj_t* obj, const uint8_t* str);
 
-int  abc_css_color (double* r, double* g, double* b, const uint8_t* str, size_t len);
+int  abc_css_color(double rgba[4], const uint8_t* str, size_t len);
 
 
-int  abc_css_border2(double border_color[3], int* border_width, int* border_style, abc_obj_t* obj, int width, const uint8_t* str);
+int  abc_css_border2(double border_color[4], int* border_width, int* border_style, abc_obj_t* obj, int width, const uint8_t* str);
 
 int  abc_css_length (abc_obj_t* obj, int width, const uint8_t* str);
 void abc_css_margin (abc_obj_t* obj, int width);
 
 int  abc_css_length (abc_obj_t* obj, int width, const uint8_t* str);
 void abc_css_margin (abc_obj_t* obj, int width);
@@ -75,7 +78,7 @@ int  abc_css_overflow(const uint8_t* str);
 int  abc_css_display (const uint8_t* str);
 
 int  abc_css_scrollbar_width(const uint8_t* str);
 int  abc_css_display (const uint8_t* str);
 
 int  abc_css_scrollbar_width(const uint8_t* str);
-int  abc_css_scrollbar_color(double thumb[3], double track[3], const uint8_t* str);
+int  abc_css_scrollbar_color(double thumb[4], double track[4], const uint8_t* str);
 
 void abc_overflow_show(int* x, int* y, int* w, int* h, int mask_x, int mask_y, int mask_w, int mask_h);
 
 
 void abc_overflow_show(int* x, int* y, int* w, int* h, int mask_x, int mask_y, int mask_w, int mask_h);
 
index f3ca27f7d6be03377098f0fcba7cdf0bce87ba71..40b026116698cf6168f24a500883a9e6ab9b8536 100644 (file)
@@ -17,10 +17,9 @@ abc_obj_t*   abc_obj_alloc(scf_string_t* file, int line, int pos, int type)
 
        scf_list_init(&obj->list);
        scf_list_init(&obj->childs);
 
        scf_list_init(&obj->list);
        scf_list_init(&obj->childs);
-       scf_list_init(&obj->css_pse_rules);
+       scf_list_init(&obj->css);
 
        obj->type = type;
 
        obj->type = type;
-
        obj->line = line;
        obj->pos  = pos;
 
        obj->line = line;
        obj->pos  = pos;
 
@@ -30,9 +29,6 @@ abc_obj_t*    abc_obj_alloc(scf_string_t* file, int line, int pos, int type)
 void abc_obj_free(abc_obj_t* obj)
 {
        if (obj) {
 void abc_obj_free(abc_obj_t* obj)
 {
        if (obj) {
-               if (obj->value)
-                       scf_string_free(obj->value);
-
                if (obj->text)
                        scf_string_free(obj->text);
 
                if (obj->text)
                        scf_string_free(obj->text);
 
@@ -61,14 +57,55 @@ void abc_obj_free(abc_obj_t* obj)
                                abc_attr_free(obj->attrs[i]);
                }
 
                                abc_attr_free(obj->attrs[i]);
                }
 
-               scf_list_clear(&obj->childs,        abc_obj_t,  list, abc_obj_free);
-               scf_list_clear(&obj->css_pse_rules, abc_obj_t,  list, abc_obj_free);
-               scf_slist_clear(obj->css_pse_chain, pse_link_t, next, free);
+               scf_list_clear(&obj->css,    css_rule_t, list, css_rule_free);
+               scf_list_clear(&obj->childs, abc_obj_t,  list, abc_obj_free);
 
                free(obj);
        }
 }
 
 
                free(obj);
        }
 }
 
+void abc_css_free(abc_css_t* css)
+{
+       if (css) {
+               scf_list_t* l;
+               css_rule_t* r;
+               css_hash_t* h;
+               int i;
+               int j;
+
+               for (i = 0; i < ABC_CSS_SELECTOR_NB; i++) {
+                       h  = &(css->hash[i]);
+
+                       for (l = scf_list_head(&h->rules); l != scf_list_sentinel(&h->rules); ) {
+                               r  = scf_list_data(l, css_rule_t, hash);
+                               l  = scf_list_next(l);
+
+                               scf_list_del(&r->hash);
+                       }
+
+                       for (j = 0; j < sizeof(h->attrs) / sizeof(h->attrs); j++) {
+                               if (h->attrs[j])
+                                       abc_attr_free(h->attrs[j]);
+                       }
+               }
+
+               free(css);
+       }
+}
+
+abc_css_t* abc_css_alloc()
+{
+       abc_css_t* css = calloc(1, sizeof(abc_css_t));
+       if (!css)
+               return NULL;
+
+       int i;
+       for (i = 0; i < ABC_CSS_SELECTOR_NB; i++)
+               scf_list_init(&(css->hash[i].rules));
+
+       return css;
+}
+
 void abc_attr_free(abc_attr_t* attr)
 {
        if (attr) {
 void abc_attr_free(abc_attr_t* attr)
 {
        if (attr) {
@@ -79,6 +116,46 @@ void abc_attr_free(abc_attr_t* attr)
        }
 }
 
        }
 }
 
+css_rule_t* css_rule_alloc(scf_string_t* file, int line, int pos, int type)
+{
+       css_rule_t* css = calloc(1, sizeof(css_rule_t));
+       if (!css)
+               return NULL;
+
+       if (file) {
+               css->file = scf_string_clone(file);
+
+               if (!css->file) {
+                       free(css);
+                       return NULL;
+               }
+       }
+
+       scf_list_init(&css->list);
+
+       css->type = type;
+       return css;
+}
+
+void css_rule_free(css_rule_t* css)
+{
+       if (css) {
+               if (css->text)
+                       scf_string_free(css->text);
+
+               if (css->file)
+                       scf_string_free(css->file);
+
+               int i;
+               for (i   = 0; i < sizeof(css->attrs) / sizeof(css->attrs[0]); i++) {
+                       if (css->attrs[i])
+                               abc_attr_free(css->attrs[i]);
+               }
+
+               free(css);
+       }
+}
+
 void abc_dfs_update_xy(abc_obj_t* root, int dx, int dy)
 {
        scf_list_t*  l;
 void abc_dfs_update_xy(abc_obj_t* root, int dx, int dy)
 {
        scf_list_t*  l;
@@ -207,7 +284,7 @@ int abc_obj_cmp_keys(abc_obj_t* obj, const char* name, size_t len)
        return -1;
 }
 
        return -1;
 }
 
-int abc_obj_copy_attrs(abc_obj_t* dst, abc_obj_t* src)
+int abc_css_copy_attrs(css_rule_t* dst, css_rule_t* src)
 {
        abc_attr_t*  attr;
        abc_attr_t*  copy;
 {
        abc_attr_t*  attr;
        abc_attr_t*  copy;
@@ -246,10 +323,10 @@ int abc_obj_set_attr(abc_obj_t* obj, int key, const char* value, size_t len)
        scf_string_t* s;
        abc_attr_t*   attr;
 
        scf_string_t* s;
        abc_attr_t*   attr;
 
-       if (key < ABC_HTML_ATTR_ID || key >= ABC_HTML_CSS_NB)
+       if (key < ABC_CSS_CLASS || key >= ABC_HTML_CSS_NB)
                return -EINVAL;
 
                return -EINVAL;
 
-       attr = obj->attrs[key - ABC_HTML_ATTR_ID];
+       attr = obj->attrs[key - ABC_CSS_CLASS];
        if (!attr)
                return -EINVAL;
 
        if (!attr)
                return -EINVAL;
 
@@ -289,27 +366,26 @@ abc_attr_t* abc_obj_find_attr(abc_obj_t* obj, int key)
        return NULL;
 }
 
        return NULL;
 }
 
-void abc_css_print(abc_obj_t* obj)
+void abc_css_print(css_rule_t* css)
 {
 {
-       if (!obj)
+       if (!css)
                return;
 
                return;
 
-       if (!(ABC_HTML_FLAG_SHOW & obj->flags))
+       if (!(ABC_HTML_FLAG_SHOW & css->flags))
                return;
 
                return;
 
-       if (obj->text)
-               printf("%s ", obj->text->data);
-       else if (obj->keys)
-               printf("%s ", obj->keys[0]);
+       if (css->text)
+               printf("%s ", css->text->data);
+       else if (css->keys)
+               printf("%s ", css->keys[0]);
 
 
-       pse_link_t*  pseLink;
        abc_attr_t*  attr;
        int i;
 
        printf("{\n");
 
        abc_attr_t*  attr;
        int i;
 
        printf("{\n");
 
-       for (i   = 0; i < sizeof(obj->attrs) / sizeof(obj->attrs[0]); i++) {
-               attr = obj->attrs[i];
+       for (i   = 0; i < sizeof(css->attrs) / sizeof(css->attrs[0]); i++) {
+               attr = css->attrs[i];
 
                if (!attr || !attr->value || 0 == attr->value->len)
                        continue;
 
                if (!attr || !attr->value || 0 == attr->value->len)
                        continue;
@@ -318,15 +394,6 @@ void abc_css_print(abc_obj_t* obj)
                        printf("    %s: %s;\n", attr->keys[0], attr->value->data);
        }
 
                        printf("    %s: %s;\n", attr->keys[0], attr->value->data);
        }
 
-       pseLink = obj->css_pse_chain;
-       while (pseLink) {
-               attr = abc_obj_get_attr(pseLink->obj, pseLink->pse_type);
-
-               printf("%s%s ", pseLink->obj->keys[0], attr->keys[0]);
-
-               pseLink = pseLink->next;
-       }
-
        printf("}\n");
 }
 
        printf("}\n");
 }
 
@@ -346,6 +413,7 @@ void abc_obj_print(abc_obj_t* obj)
        scf_list_t*  l;
        abc_attr_t*  attr;
        abc_obj_t*   child;
        scf_list_t*  l;
        abc_attr_t*  attr;
        abc_obj_t*   child;
+       css_rule_t*  css;
 
        if (!obj)
                return;
 
        if (!obj)
                return;
@@ -380,30 +448,16 @@ void abc_obj_print(abc_obj_t* obj)
        if (obj->text)
                printf("%s\n", obj->text->data);
 
        if (obj->text)
                printf("%s\n", obj->text->data);
 
-       for (l = scf_list_head(&obj->childs); l != scf_list_sentinel(&obj->childs); l = scf_list_next(l)) {
-               child = scf_list_data(l, abc_obj_t, list);
+       for (l  = scf_list_head(&obj->css); l != scf_list_sentinel(&obj->css); l = scf_list_next(l)) {
+               css = scf_list_data(l, css_rule_t, list);
 
 
-               switch (obj->type)
-               {
-                       case ABC_HTML_LINK:
-                               attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_TYPE);
-
-                               if (!attr || __html_strcmp(attr->value->data, "text/css"))
-                                       break;
-                       case ABC_HTML_STYLE:
-                               abc_css_print(child);
-                               break;
-
-                       default:
-                               abc_obj_print(child);
-                               break;
-               };
+               abc_css_print(css);
        }
 
        }
 
-       for (l = scf_list_head(&obj->css_pse_rules); l != scf_list_sentinel(&obj->css_pse_rules); l = scf_list_next(l)) {
+       for (l    = scf_list_head(&obj->childs); l != scf_list_sentinel(&obj->childs); l = scf_list_next(l)) {
                child = scf_list_data(l, abc_obj_t, list);
 
                child = scf_list_data(l, abc_obj_t, list);
 
-               abc_css_print(child);
+               abc_obj_print(child);
        }
 
        if (ABC_HTML_FLAG_CLOSE == (obj->flags & (ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SINGLE))) {
        }
 
        if (ABC_HTML_FLAG_CLOSE == (obj->flags & (ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SINGLE))) {
index 6d98d4489a72f1c8d45a45b2bfadaea0b92de0cb..452ea0d73a017ee692093458e9e654e593b46597 100644 (file)
@@ -9,7 +9,10 @@
 typedef struct abc_obj_s    abc_obj_t;
 typedef struct abc_attr_s   abc_attr_t;
 typedef struct abc_text_s   abc_text_t;
 typedef struct abc_obj_s    abc_obj_t;
 typedef struct abc_attr_s   abc_attr_t;
 typedef struct abc_text_s   abc_text_t;
-typedef struct pse_link_s   pse_link_t;
+
+typedef struct abc_css_s    abc_css_t;
+typedef struct css_rule_s   css_rule_t;
+typedef struct css_hash_s   css_hash_t;
 
 enum abc_objs
 {
 
 enum abc_objs
 {
@@ -72,17 +75,26 @@ enum abc_objs
        ABC_CORE_TEXT, // not HTML label, only for browser core to layout & draw text
        ABC_HTML_NB,   // total HTML objects
 
        ABC_CORE_TEXT, // not HTML label, only for browser core to layout & draw text
        ABC_HTML_NB,   // total HTML objects
 
-       ABC_HTML_ATTR_ID,
-       ABC_HTML_ATTR_TYPE,
+       // css selectors
+       ABC_CSS_COMBINATOR = ABC_HTML_NB,
+       ABC_CSS_PSE_ELEMENT,
+       ABC_CSS_PSE_CLASS,
+       ABC_CSS_ATTR,
+
+       ABC_CSS_CLASS, // also for html attr 'class'
+       ABC_CSS_ID,    // also for html attr 'id'
+       ABC_CSS_SELECTOR_NB,
+
+       ABC_HTML_ATTR_TYPE  = ABC_CSS_SELECTOR_NB,
        ABC_HTML_ATTR_NAME,
        ABC_HTML_ATTR_VALUE,
        ABC_HTML_ATTR_NAME,
        ABC_HTML_ATTR_VALUE,
-       ABC_HTML_ATTR_CLASS,
        ABC_HTML_ATTR_TITLE,
        ABC_HTML_ATTR_STYLE,
 
        ABC_HTML_ATTR_HREF,
        ABC_HTML_ATTR_SRC,
        ABC_HTML_ATTR_REL,
        ABC_HTML_ATTR_TITLE,
        ABC_HTML_ATTR_STYLE,
 
        ABC_HTML_ATTR_HREF,
        ABC_HTML_ATTR_SRC,
        ABC_HTML_ATTR_REL,
+       ABC_HTML_ATTR_ALT,
 
        ABC_HTML_ATTR_FOR,
 
 
        ABC_HTML_ATTR_FOR,
 
@@ -159,6 +171,9 @@ enum abc_objs
        ABC_CSS_SCROLLBAR_WIDTH,
        ABC_CSS_SCROLLBAR_COLOR,
 
        ABC_CSS_SCROLLBAR_WIDTH,
        ABC_CSS_SCROLLBAR_COLOR,
 
+       ABC_CSS_OPACITY,
+       ABC_CSS_FILTER,
+
        ABC_CSS_LIST_STYLE,
        ABC_CSS_LIST_STYLE_TYPE,
        ABC_CSS_LIST_STYLE_IMAGE,
        ABC_CSS_LIST_STYLE,
        ABC_CSS_LIST_STYLE_TYPE,
        ABC_CSS_LIST_STYLE_IMAGE,
@@ -167,26 +182,12 @@ enum abc_objs
        // css pse class (element)
        ABC_CSS_FIRST_CHILD,
 
        // css pse class (element)
        ABC_CSS_FIRST_CHILD,
 
-       ABC_CSS_PSE_STATIC, // css pse static barrier, all pse classes (elements) above only based on HTML topology
-
        ABC_CSS_LINK,
        ABC_CSS_LINK,
-       ABC_CSS_VISITED,
        ABC_CSS_HOVER,
        ABC_CSS_ACTIVE,
        ABC_CSS_HOVER,
        ABC_CSS_ACTIVE,
+       ABC_CSS_VISITED,
 
 
-       ABC_CSS_PSE_DYNAMIC, // css pse dynamic barrier, pse classes (elements) above based on user operations
-
-       ABC_HTML_CSS_NB = ABC_CSS_PSE_DYNAMIC, // total HTML & CSS attrs
-
-       // css selectors
-       ABC_CSS_ATTR,
-       ABC_CSS_PSE_CLASS,
-       ABC_CSS_PSE_ELEMENT,
-       ABC_CSS_COMBINATOR,
-
-       // css selectors from html attrs above
-       ABC_CSS_ID    = ABC_HTML_ATTR_ID,
-       ABC_CSS_CLASS = ABC_HTML_ATTR_CLASS,
+       ABC_HTML_CSS_NB, // total HTML & CSS attrs
 };
 
 enum abc_display_type
 };
 
 enum abc_display_type
@@ -248,18 +249,11 @@ struct abc_text_s
        int             h;
 };
 
        int             h;
 };
 
-struct pse_link_s
-{
-       pse_link_t*     next;
-
-       abc_obj_t*      obj;
-       int             pse_type;
-};
-
 #define ABC_HTML_FLAG_OPEN   0
 #define ABC_HTML_FLAG_CLOSE  1
 #define ABC_HTML_FLAG_SINGLE 2
 #define ABC_HTML_FLAG_SHOW   4
 #define ABC_HTML_FLAG_OPEN   0
 #define ABC_HTML_FLAG_CLOSE  1
 #define ABC_HTML_FLAG_SINGLE 2
 #define ABC_HTML_FLAG_SHOW   4
+#define ABC_CSS_FLAG_ON      8
 
 struct abc_attr_s
 {
 
 struct abc_attr_s
 {
@@ -272,37 +266,74 @@ struct abc_attr_s
        abc_obj_t*      parent;
 };
 
        abc_obj_t*      parent;
 };
 
+struct css_rule_s
+{
+       int             type;
+       uint32_t        flags;
+
+       char**          keys;
+       scf_string_t*   text;
+
+       abc_obj_t*      parent;
+
+       scf_list_t      list;
+
+       abc_attr_t*     attrs[ABC_HTML_CSS_NB - ABC_CSS_CLASS];
+
+       scf_string_t*   file; // file name
+       int             line; // line
+       int             pos;  // position
+
+       int             last_key;
+       int             last_key_end;
+       scf_list_t      hash;
+};
+
+struct css_hash_s
+{
+       scf_list_t      rules;
+       abc_attr_t*     attrs[ABC_HTML_CSS_NB - ABC_CSS_CLASS];
+};
+
+struct abc_css_s
+{
+       css_hash_t      hash[ABC_CSS_SELECTOR_NB];
+};
+
 struct abc_obj_s
 {
        int             type;
        uint32_t        flags;
 
        char**          keys;
 struct abc_obj_s
 {
        int             type;
        uint32_t        flags;
 
        char**          keys;
-       scf_string_t*   value;
+       scf_string_t*   text;
 
        abc_obj_t*      parent;
 
        scf_list_t      list;
 
        abc_obj_t*      parent;
 
        scf_list_t      list;
+
+       abc_attr_t*     attrs[ABC_HTML_CSS_NB - ABC_CSS_CLASS];
+
+       scf_string_t*   file; // file name
+       int             line; // line
+       int             pos;  // position
+
+       int             text_line;
+       int             text_pos;
+       scf_list_t      css;
+
        scf_list_t      childs;
        int             n_childs;
        int             n_texts;
 
        scf_list_t      childs;
        int             n_childs;
        int             n_texts;
 
-       abc_attr_t*     attrs[ABC_HTML_CSS_NB - ABC_HTML_ATTR_ID];
-
        void*           gtk_builder;
        abc_filter_t*   av_filter;
        abc_avio_t*     vout;
        void*           gtk_builder;
        abc_filter_t*   av_filter;
        abc_avio_t*     vout;
+       abc_img_t*      img;
 
 
-       scf_string_t*   text;
        abc_text_t*     text_splits; // for layout, split a long text to multi-lines and save every-line here
        abc_text_t*     text_splits; // for layout, split a long text to multi-lines and save every-line here
-       int             text_line;
-       int             text_pos;
        abc_io_t        io;
 
        abc_io_t        io;
 
-       pse_link_t*     css_pse_chain;
-       scf_list_t      css_pse_rules;
-       int             css_pse_type;
-
        int             border_top;
        int             border_bottom;
        int             border_left;
        int             border_top;
        int             border_bottom;
        int             border_left;
@@ -367,11 +398,6 @@ struct abc_obj_s
        int             progress;
        uint32_t        jiffies; // timeout numbers of sys timer
 
        int             progress;
        uint32_t        jiffies; // timeout numbers of sys timer
 
-
-       scf_string_t*   file; // file name
-       int             line; // line
-       int             pos;  // position
-
        scf_string_t*   js_path;
        scf_string_t*   js_obj;
        scf_string_t*   js_so;
        scf_string_t*   js_path;
        scf_string_t*   js_obj;
        scf_string_t*   js_so;
@@ -380,6 +406,8 @@ struct abc_obj_s
        uint32_t        clicked:1;
        uint32_t        visited:1;
 
        uint32_t        clicked:1;
        uint32_t        visited:1;
 
+       uint32_t        css_use:1;
+
        uint32_t        w_set:1;
        uint32_t        h_set:1;
 
        uint32_t        w_set:1;
        uint32_t        h_set:1;
 
@@ -393,16 +421,22 @@ abc_obj_t*     abc_obj_alloc(scf_string_t* file, int line, int pos, int type);
 void           abc_obj_free (abc_obj_t*    obj);
 void           abc_attr_free(abc_attr_t*   attr);
 
 void           abc_obj_free (abc_obj_t*    obj);
 void           abc_attr_free(abc_attr_t*   attr);
 
+abc_css_t*     abc_css_alloc();
+void           abc_css_free (abc_css_t*    css);
+
+css_rule_t*    css_rule_alloc(scf_string_t* file, int line, int pos, int type);
+void           css_rule_free (css_rule_t*   css);
+
 abc_obj_t*     abc_obj_find (abc_obj_t*    root, int x, int y);
 void           abc_obj_print(abc_obj_t*    obj);
 
 abc_obj_t*     abc_obj_find (abc_obj_t*    root, int x, int y);
 void           abc_obj_print(abc_obj_t*    obj);
 
-int            abc_obj_cmp_keys  (abc_obj_t* obj, const char* name, size_t len);
-int            abc_obj_copy_attrs(abc_obj_t* dst, abc_obj_t*  src);
+int            abc_css_copy_attrs(css_rule_t* dst, css_rule_t* src);
+void           abc_obj_set_css   (abc_obj_t*  obj, css_rule_t* css);
 
 
-void           abc_obj_set_css  (abc_obj_t* obj, abc_obj_t* css);
 int            abc_obj_set_attr (abc_obj_t* obj, int key, const char* value, size_t len);
 
 int            abc_obj_set_attr (abc_obj_t* obj, int key, const char* value, size_t len);
 
-abc_attr_t*    abc_obj_get_attr2(abc_obj_t* obj, const char* key, int len);
+int            abc_obj_cmp_keys (abc_obj_t* obj, const char* name, size_t len);
+abc_attr_t*    abc_obj_get_attr2(abc_obj_t* obj, const char* key,  int    len);
 abc_attr_t*    abc_obj_find_attr(abc_obj_t* obj, int key);
 
 abc_obj_t*     abc_obj_find_type(abc_obj_t* root, int type);
 abc_attr_t*    abc_obj_find_attr(abc_obj_t* obj, int key);
 
 abc_obj_t*     abc_obj_find_type(abc_obj_t* root, int type);
@@ -417,10 +451,10 @@ scf_string_t*  abc_ol_list_style(abc_obj_t* obj, int num);
 
 static inline abc_attr_t* abc_obj_get_attr(abc_obj_t* obj, int key)
 {
 
 static inline abc_attr_t* abc_obj_get_attr(abc_obj_t* obj, int key)
 {
-       if (key < ABC_HTML_ATTR_ID || key >= ABC_HTML_CSS_NB)
+       if (key < ABC_CSS_CLASS || key >= ABC_HTML_CSS_NB)
                return NULL;
 
                return NULL;
 
-       return obj->attrs[key - ABC_HTML_ATTR_ID];
+       return obj->attrs[key - ABC_CSS_CLASS];
 }
 
 #endif
 }
 
 #endif
index 4a8eb4b0fbb61e210f645ea7cfcd1f1795723514..561c8057f4d0bba04896d5c44291ae1f7d0fbe9b 100644 (file)
@@ -1,5 +1,27 @@
 #include"abc_html.h"
 
 #include"abc_html.h"
 
+void abc_css_recursive_use(abc_html_t* html, abc_obj_t* obj)
+{
+       scf_list_t*  l;
+       abc_attr_t*  attr;
+       abc_obj_t*   child;
+       css_rule_t*  css;
+
+       if (!obj)
+               return;
+
+       if (!obj->css_use && ABC_CORE_TEXT != obj->type) {
+               obj->css_use = 1;
+               abc_css_use(html, obj);
+       }
+
+       for (l    = scf_list_head(&obj->childs); l != scf_list_sentinel(&obj->childs); l = scf_list_next(l)) {
+               child = scf_list_data(l, abc_obj_t, list);
+
+               abc_css_recursive_use(html, child);
+       }
+}
+
 int main(int argc, char* argv[])
 {
        abc_html_t* html = NULL;
 int main(int argc, char* argv[])
 {
        abc_html_t* html = NULL;
@@ -24,6 +46,8 @@ int main(int argc, char* argv[])
 
        printf("\n");
 
 
        printf("\n");
 
+       abc_css_recursive_use(html, html->root);
+
        if (html->root)
                abc_obj_print(html->root);
 
        if (html->root)
                abc_obj_print(html->root);
 
index 44553a775e2a45a4b3a24def3981b79aec598972..fe8d516dcb9ff9fc231d74b11754835836bcde67 100644 (file)
@@ -24,6 +24,8 @@ CFILES += abc_render_body.c
 CFILES += __render_border.c
 CFILES += __render_bg_image.c
 CFILES += __render_text.c
 CFILES += __render_border.c
 CFILES += __render_bg_image.c
 CFILES += __render_text.c
+CFILES += __render_text_gl.c
+
 CFILES += abc_render_text.c
 
 CFILES += abc_render_empty.c
 CFILES += abc_render_text.c
 
 CFILES += abc_render_empty.c
index 9e13429ed333d9e61d743478d6db65bbfb0bd13c..7ccc008c5ba43403ed21695ea1fb1bfbca131cdf 100644 (file)
@@ -97,12 +97,10 @@ static int __render_draw_bg_image(abc_render_t* render, abc_obj_t* obj, int widt
                return ret;
        }
 
                return ret;
        }
 
-       double r = 0.0;
-       double g = 0.0;
-       double b = 0.0;
+       double rgba[4] = {0.0, 0.0, 0.0, 1.0};
        attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_BG_COLOR);
        if (attr)
        attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_BG_COLOR);
        if (attr)
-               abc_css_color(&r, &g, &b, attr->value->data, attr->value->len);
+               abc_css_color(rgba, attr->value->data, attr->value->len);
 
        if (0 == program)
                __init_program(&program, vert_shader, frag_shader);
 
        if (0 == program)
                __init_program(&program, vert_shader, frag_shader);
@@ -113,6 +111,29 @@ static int __render_draw_bg_image(abc_render_t* render, abc_obj_t* obj, int widt
        if (0 == texture_rgba)
                __init_texture(&texture_rgba, GL_RGBA, img->width, img->height, NULL);
 
        if (0 == texture_rgba)
                __init_texture(&texture_rgba, GL_RGBA, img->width, img->height, NULL);
 
+       int x = obj->x + obj->margin_left + obj->border_left;
+       int y = obj->y + obj->margin_top  + obj->border_top;
+       int w = obj->w - obj->margin_left - obj->border_left - obj->border_right  - obj->margin_right;
+       int h = obj->h - obj->margin_top  - obj->border_top  - obj->border_bottom - obj->margin_bottom;
+
+       int view_x = x;
+       int view_y = y;
+       int view_w = w;
+       int view_h = h;
+
+       switch (obj->overflow_type)
+       {
+               case ABC_OVERFLOW_HIDDEN:
+               case ABC_OVERFLOW_SCROLL:
+               case ABC_OVERFLOW_AUTO:
+                       abc_overflow_show(&view_x, &view_y, &view_w, &view_h,
+                                       obj->view_x,
+                                       obj->view_y, obj->view_w, obj->view_h);
+                       break;
+               default:
+                       break;
+       };
+
        float mvp[16];
        __compute_mvp(mvp, 0, 0, 0);
 
        float mvp[16];
        __compute_mvp(mvp, 0, 0, 0);
 
@@ -120,30 +141,45 @@ static int __render_draw_bg_image(abc_render_t* render, abc_obj_t* obj, int widt
 
        GLfloat vert_update[] =
        {
 
        GLfloat vert_update[] =
        {
-                2.0 *  obj->x           / (float)width  - 1.0,
-               -2.0 * (obj->y + obj->h) / (float)height + 1.0,
+                2.0 *  view_x           / (float)width  - 1.0,
+               -2.0 * (view_y + view_h) / (float)height + 1.0,
+
+                2.0 * (view_x + view_w) / (float)width  - 1.0,
+               -2.0 * (view_y + view_h) / (float)height + 1.0,
+
+                2.0 *  view_x           / (float)width  - 1.0,
+               -2.0 *  view_y           / (float)height + 1.0,
+
+                2.0 * (view_x + view_w) / (float)width  - 1.0,
+               -2.0 *  view_y           / (float)height + 1.0,
+       };
+
+       GLfloat texture_update[] =
+       {
+               (view_x - x)          / (float)w,
+               (view_y + view_h - y) / (float)h,
 
 
-                2.0 * (obj->x + obj->w) / (float)width  - 1.0,
-               -2.0 * (obj->y + obj->h) / (float)height + 1.0,
+               (view_x + view_w - x) / (float)w,
+               (view_y + view_h - y) / (float)h,
 
 
-                2.0 *  obj->x           / (float)width  - 1.0,
-               -2.0 *  obj->y           / (float)height + 1.0,
+               (view_x - x)          / (float)w,
+               (view_y - y)          / (float)h,
 
 
-                2.0 * (obj->x + obj->w) / (float)width  - 1.0,
-               -2.0 *  obj->y           / (float)height + 1.0,
+               (view_x + view_w - x) / (float)w,
+               (view_y - y)          / (float)h,
        };
 
        };
 
-       GLfloat x = 0.0;
-       GLfloat y = 0.0;
-       GLfloat w = img->width  / (float)obj->w;
-       GLfloat h = img->height / (float)obj->h;
+       GLfloat ix = 0.0;
+       GLfloat iy = 0.0;
+       GLfloat iw = img->width  / (float)w;
+       GLfloat ih = img->height / (float)h;
 
 
-       if (w > 1.0 || h > 1.0)
+       if (iw > 1.0 || ih > 1.0)
        {
        {
-               GLfloat max = w > h ? w : h;
+               GLfloat max = iw > ih ? iw : ih;
 
 
-               w /= max;
-               h /= max;
+               iw /= max;
+               ih /= max;
        }
 
        GLint repeat_x = 1;
        }
 
        GLint repeat_x = 1;
@@ -153,14 +189,14 @@ static int __render_draw_bg_image(abc_render_t* render, abc_obj_t* obj, int widt
 
        attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_BG_POSITION);
        if (attr) {
 
        attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_BG_POSITION);
        if (attr) {
-               abc_css_bg_position(&x, &y, w, h, obj, attr->value->data);
+               abc_css_bg_position(&ix, &iy, iw, ih, obj, attr->value->data);
 
 
-               scf_logd("background-position: %s, x: %f, y: %f, w: %f, h: %f\n", attr->value->data, x, y, w, h);
+               scf_logd("background-position: %s, ix: %f, iy: %f, iw: %f, ih: %f\n", attr->value->data, ix, iy, iw, ih);
 
 
-               if (x + w > 1.0)
+               if (ix + iw > 1.0)
                        index_x = -1;
 
                        index_x = -1;
 
-               if (y + h > 1.0)
+               if (iy + ih > 1.0)
                        index_y = -1;
        }
 
                        index_y = -1;
        }
 
@@ -178,7 +214,7 @@ static int __render_draw_bg_image(abc_render_t* render, abc_obj_t* obj, int widt
                }
        }
 
                }
        }
 
-       scf_logd("repeat_x: %d, repeat_y: %d, index_x: %d, index_y: %d\n", repeat_x, repeat_y, index_x, index_y);
+       scf_logi("repeat_x: %d, repeat_y: %d, index_x: %d, index_y: %d\n", repeat_x, repeat_y, index_x, index_y);
 
        glUseProgram(program);
 
 
        glUseProgram(program);
 
@@ -198,8 +234,8 @@ static int __render_draw_bg_image(abc_render_t* render, abc_obj_t* obj, int widt
        glTexImage2D   (GL_TEXTURE_2D, 0, GL_RGBA, img->width, img->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, bgra);
        glUniform1i(uniform_rgba,  0);
 
        glTexImage2D   (GL_TEXTURE_2D, 0, GL_RGBA, img->width, img->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, bgra);
        glUniform1i(uniform_rgba,  0);
 
-       glUniform4f(uniform_rect,  x, y, w, h);
-       glUniform4f(uniform_color, r, g, b, 1.0);
+       glUniform4f(uniform_rect,  ix, iy, iw, ih);
+       glUniform4f(uniform_color, rgba[0], rgba[1], rgba[2], rgba[3]);
 
        glUniform1i(uniform_repeat_x, repeat_x);
        glUniform1i(uniform_repeat_y, repeat_y);
 
        glUniform1i(uniform_repeat_x, repeat_x);
        glUniform1i(uniform_repeat_y, repeat_y);
index 734c9a65e03f2203f2d1aa9f4e84c8a9aaa929e6..9a0adebc2cc6a20a1218f6fc21c7f005eaa209b1 100644 (file)
@@ -188,13 +188,13 @@ static int __render_draw_border(abc_render_t* render, abc_obj_t* obj, int width,
        int border = 0;
        int border_style = ABC_BORDER_SOLID;
 
        int border = 0;
        int border_style = ABC_BORDER_SOLID;
 
-       double fgColor[3] = {0.0, 0.0, 0.0};
+       double fgColor[4] = {0.0, 0.0, 0.0, 1.0};
        double bgColor[4] = {0.0, 0.0, 0.0, 0.0};
 
        abc_attr_t* attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_BG_COLOR);
        if (attr && attr->value->len > 0) {
                bgColor[3] = 1.0;
        double bgColor[4] = {0.0, 0.0, 0.0, 0.0};
 
        abc_attr_t* attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_BG_COLOR);
        if (attr && attr->value->len > 0) {
                bgColor[3] = 1.0;
-               abc_css_color(bgColor, bgColor + 1, bgColor + 2, attr->value->data, attr->value->len);
+               abc_css_color(bgColor, attr->value->data, attr->value->len);
        }
 
        attr = abc_obj_get_attr(obj, ABC_CSS_BORDER_TOP);
        }
 
        attr = abc_obj_get_attr(obj, ABC_CSS_BORDER_TOP);
@@ -203,7 +203,7 @@ static int __render_draw_border(abc_render_t* render, abc_obj_t* obj, int width,
        else {
                attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_COLOR);
                if (attr)
        else {
                attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_COLOR);
                if (attr)
-                       abc_css_color(fgColor, fgColor + 1, fgColor + 2, attr->value->data, attr->value->len);
+                       abc_css_color(fgColor, attr->value->data, attr->value->len);
        }
 
        int x = obj->x + obj->margin_left;
        }
 
        int x = obj->x + obj->margin_left;
@@ -383,7 +383,7 @@ static int __render_draw_border(abc_render_t* render, abc_obj_t* obj, int width,
 
        glUniform1f(uniform_x_border, x_border);
        glUniform1f(uniform_y_border, y_border);
 
        glUniform1f(uniform_x_border, x_border);
        glUniform1f(uniform_y_border, y_border);
-       glUniform4f(uniform_color,    fgColor[0], fgColor[1], fgColor[2], 1.0);
+       glUniform4f(uniform_color,    fgColor[0], fgColor[1], fgColor[2], fgColor[3]);
        glUniform4f(uniform_bgColor,  bgColor[0], bgColor[1], bgColor[2], bgColor[3]);
 
        glUniform4f(uniform_thumbColor, thumbColor[0], thumbColor[1], thumbColor[2], thumbColor[3]);
        glUniform4f(uniform_bgColor,  bgColor[0], bgColor[1], bgColor[2], bgColor[3]);
 
        glUniform4f(uniform_thumbColor, thumbColor[0], thumbColor[1], thumbColor[2], thumbColor[3]);
index ec7db0ffce18e5c7154f9bf3d45548daacf83bf0..121fdd04b98bb0107cb1b547623bc888dfe4740d 100644 (file)
@@ -1,38 +1,5 @@
 #include"abc.h"
 
 #include"abc.h"
 
-static const char* vert_shader =
-       "#version 330 core\n"
-       "layout(location = 0) in vec4 position; \n"
-       "layout(location = 1) in vec2 a_texCoord; \n"
-       "out vec2 v_texCoord; \n"
-       "uniform mat4 mvp; \n"
-       "void main() { \n"
-               "gl_Position = mvp * position; \n"
-               "v_texCoord  = a_texCoord; \n"
-       "} \n";
-
-static const char* frag_shader =
-       "#version 330 core\n"
-       "in  vec2 v_texCoord; \n"
-       "out vec4 outputColor; \n"
-       "uniform sampler2D tex_rgba; \n"
-       "void main() { \n"
-       "    vec2 xy = v_texCoord; \n"
-       "    vec4 v  = texture2D(tex_rgba, xy).rgba; \n"
-       "    outputColor = vec4(v.b, v.g, v.r, v.a); \n"
-       "} \n";
-
-
-static GLuint program = 0;
-
-static GLuint vao = 0;
-static GLuint buffers[2]   = {0};
-static GLuint texture_rgba = 0;
-
-static GLuint uniform_mvp;
-static GLuint uniform_rgba;
-
-
 static int __render_fini_text(abc_render_t* render)
 {
        return 0;
 static int __render_fini_text(abc_render_t* render)
 {
        return 0;
@@ -99,10 +66,8 @@ int __init_text(cairo_t* cr, abc_obj_t* obj, int num_flag, double scale)
        }
 
        cairo_text_extents_t  extents;
        }
 
        cairo_text_extents_t  extents;
-       double r = 0.0;
-       double g = 0.0;
-       double b = 0.0;
-       double size = 16.0;
+       double rgba[4] = {0.0, 0.0, 0.0, 1.0};
+       double size    = 16.0;
 
        attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_SIZE);
        if (attr)
 
        attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_SIZE);
        if (attr)
@@ -110,10 +75,10 @@ int __init_text(cairo_t* cr, abc_obj_t* obj, int num_flag, double scale)
 
        attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_COLOR);
        if (attr)
 
        attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_COLOR);
        if (attr)
-               abc_css_color(&r, &g, &b, attr->value->data, attr->value->len);
+               abc_css_color(rgba, attr->value->data, attr->value->len);
 
        cairo_set_font_size  (cr, size * scale);
 
        cairo_set_font_size  (cr, size * scale);
-       cairo_set_source_rgba(cr, r, g, b, 1.0);
+       cairo_set_source_rgba(cr, rgba[0], rgba[1], rgba[2], rgba[3]);
 
        if (ABC_HTML_OL == obj->parent->type && num_flag)
        {
 
        if (ABC_HTML_OL == obj->parent->type && num_flag)
        {
@@ -190,15 +155,6 @@ static int __render_draw_text(abc_render_t* render, abc_obj_t* obj, int width, i
 
        scf_logd("obj->type: %d, obj->w: %d, obj->h: %d, w: %d, h: %d\n", obj->type, obj->w, obj->h, w, h);
 
 
        scf_logd("obj->type: %d, obj->w: %d, obj->h: %d, w: %d, h: %d\n", obj->type, obj->w, obj->h, w, h);
 
-       if (0 == program)
-               __init_program(&program, vert_shader, frag_shader);
-
-       if (0 == vao)
-               __init_buffers(&vao, buffers);
-
-       if (0 == texture_rgba)
-               __init_texture(&texture_rgba, GL_RGBA, w_text, h_text, NULL);
-
        abc_attr_t*       attr;
        cairo_surface_t*  surface;
        cairo_t*          cr;
        abc_attr_t*       attr;
        cairo_surface_t*  surface;
        cairo_t*          cr;
@@ -207,18 +163,16 @@ static int __render_draw_text(abc_render_t* render, abc_obj_t* obj, int width, i
        if (!bgra)
                return -ENOMEM;
 
        if (!bgra)
                return -ENOMEM;
 
-       double r = 0.0;
-       double g = 0.0;
-       double b = 0.0;
-       attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_BG_COLOR);
-       if (attr)
-               abc_css_color(&r, &g, &b, attr->value->data, attr->value->len);
+       double rgba[4] = {0.0, 0.0, 0.0, 0.0};
+       attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_BG_COLOR);
+       if (attr && attr->value->len > 0)
+               abc_css_color(rgba, attr->value->data, attr->value->len);
 
        surface = cairo_image_surface_create_for_data(bgra, CAIRO_FORMAT_ARGB32, w_text, h_text, w_text * 4);
        cr      = cairo_create(surface);
 
 
        surface = cairo_image_surface_create_for_data(bgra, CAIRO_FORMAT_ARGB32, w_text, h_text, w_text * 4);
        cr      = cairo_create(surface);
 
-       cairo_set_line_width(cr, 1);
-       cairo_set_source_rgba(cr, r, g, b, 0.0);
+       cairo_set_line_width (cr, 1);
+       cairo_set_source_rgba(cr, rgba[0], rgba[1], rgba[2], rgba[3]);
        cairo_rectangle(cr, 0, 0, w_text, h_text);
        cairo_fill(cr);
        cairo_stroke(cr);
        cairo_rectangle(cr, 0, 0, w_text, h_text);
        cairo_fill(cr);
        cairo_stroke(cr);
@@ -250,70 +204,17 @@ static int __render_draw_text(abc_render_t* render, abc_obj_t* obj, int width, i
                        break;
        };
 
                        break;
        };
 
-       float mvp[16];
-       __compute_mvp(mvp, 0, 0, 0);
-
        scf_logd("%s, x: %d, y: %d, w: %d, h: %d\n", obj->text->data, obj->x, obj->y, obj->w, obj->h);
 
        scf_logd("%s, x: %d, y: %d, w: %d, h: %d\n", obj->text->data, obj->x, obj->y, obj->w, obj->h);
 
-       GLfloat vert_update[] =
-       {
-                2.0 *  view_x           / (float)width  - 1.0,
-               -2.0 * (view_y + view_h) / (float)height + 1.0,
-
-                2.0 * (view_x + view_w) / (float)width  - 1.0,
-               -2.0 * (view_y + view_h) / (float)height + 1.0,
-
-                2.0 *  view_x           / (float)width  - 1.0,
-               -2.0 *  view_y           / (float)height + 1.0,
-
-                2.0 * (view_x + view_w) / (float)width  - 1.0,
-               -2.0 *  view_y           / (float)height + 1.0,
-       };
-
-       GLfloat texture_update[] =
-       {
-               (view_x - x)          / (float)w,
-               (view_y + view_h - y) / (float)h,
-
-               (view_x + view_w - x) / (float)w,
-               (view_y + view_h - y) / (float)h,
-
-               (view_x - x)          / (float)w,
-               (view_y - y)          / (float)h,
-
-               (view_x + view_w - x) / (float)w,
-               (view_y - y)          / (float)h,
-       };
-
-       glUseProgram(program);
-       uniform_rgba = glGetUniformLocation(program, "tex_rgba");
-       uniform_mvp  = glGetUniformLocation(program, "mvp");
-
-       glUniformMatrix4fv(uniform_mvp, 1, GL_FALSE, mvp);
-
-       // board
-       glActiveTexture(GL_TEXTURE0);
-       glBindTexture  (GL_TEXTURE_2D, texture_rgba);
-       glTexImage2D   (GL_TEXTURE_2D, 0, GL_RGBA, w_text, h_text, 0, GL_RGBA, GL_UNSIGNED_BYTE, bgra);
-       glUniform1i(uniform_rgba, 0);
-
-       // draw
-       glBindBuffer   (GL_ARRAY_BUFFER, buffers[0]);
-       glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vert_update), vert_update);
-
-       glBindBuffer   (GL_ARRAY_BUFFER, buffers[1]);
-       glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(texture_update), texture_update);
-
-       glBindVertexArray(vao);
-
-       glEnable(GL_BLEND);
-       glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
-
-       glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
-       glDisable(GL_BLEND);
+       float mvp[16];
+       __compute_mvp(mvp, 0, 0, 0);
 
 
-       glBindVertexArray(0);
-       glUseProgram(0);
+       __render_text_gl(obj, bgra, w_text, h_text, width, height,
+                                x,
+                                        y,
+                                        w,
+                                        h,
+                                        view_x, view_y, view_w, view_h, mvp);
 
        free(bgra);
        return 0;
 
        free(bgra);
        return 0;
diff --git a/ui/__render_text_gl.c b/ui/__render_text_gl.c
new file mode 100644 (file)
index 0000000..a8e7f11
--- /dev/null
@@ -0,0 +1,124 @@
+#include"abc.h"
+
+static const char* vert_shader =
+       "#version 330 core\n"
+       "layout(location = 0) in vec4 position; \n"
+       "layout(location = 1) in vec2 a_texCoord; \n"
+       "out vec2 v_texCoord; \n"
+       "uniform mat4 mvp; \n"
+       "void main() { \n"
+               "gl_Position = mvp * position; \n"
+               "v_texCoord  = a_texCoord; \n"
+       "} \n";
+
+static const char* frag_shader =
+       "#version 330 core\n"
+       "in  vec2 v_texCoord; \n"
+       "out vec4 outputColor; \n"
+       "uniform float opacity; \n"
+       "uniform sampler2D tex_rgba; \n"
+       "void main() { \n"
+       "    vec2 xy = v_texCoord; \n"
+       "    vec4 v  = texture2D(tex_rgba, xy).rgba; \n"
+       "    v *= opacity;\n"
+       "    outputColor = vec4(v.b, v.g, v.r, v.a); \n"
+       "} \n";
+
+
+static GLuint program = 0;
+
+static GLuint vao = 0;
+static GLuint buffers[2]   = {0};
+static GLuint texture_rgba = 0;
+
+static GLuint uniform_mvp;
+static GLuint uniform_rgba;
+static GLuint uniform_opacity;
+
+
+int __render_text_gl(abc_obj_t* obj, const char* bgra, int w_text, int h_text, int width, int height,
+               int x,
+               int y,
+               int w,
+               int h,
+               int view_x, int view_y, int view_w, int view_h, float mvp[16])
+{
+       if (0 == program)
+               __init_program(&program, vert_shader, frag_shader);
+
+       if (0 == vao)
+               __init_buffers(&vao, buffers);
+
+       if (0 == texture_rgba)
+               __init_texture(&texture_rgba, GL_RGBA, w_text, h_text, NULL);
+
+       GLfloat opacity = 1.0;
+
+       abc_attr_t* attr = abc_obj_get_attr(obj, ABC_CSS_OPACITY);
+       if (attr && attr->value->len > 0)
+               opacity = atof(attr->value->data);
+
+       GLfloat vert_update[] =
+       {
+                2.0 *  view_x           / (float)width  - 1.0,
+               -2.0 * (view_y + view_h) / (float)height + 1.0,
+
+                2.0 * (view_x + view_w) / (float)width  - 1.0,
+               -2.0 * (view_y + view_h) / (float)height + 1.0,
+
+                2.0 *  view_x           / (float)width  - 1.0,
+               -2.0 *  view_y           / (float)height + 1.0,
+
+                2.0 * (view_x + view_w) / (float)width  - 1.0,
+               -2.0 *  view_y           / (float)height + 1.0,
+       };
+
+       GLfloat texture_update[] =
+       {
+               (view_x - x)          / (float)w,
+               (view_y + view_h - y) / (float)h,
+
+               (view_x + view_w - x) / (float)w,
+               (view_y + view_h - y) / (float)h,
+
+               (view_x - x)          / (float)w,
+               (view_y - y)          / (float)h,
+
+               (view_x + view_w - x) / (float)w,
+               (view_y - y)          / (float)h,
+       };
+
+       glUseProgram(program);
+       uniform_mvp     = glGetUniformLocation(program, "mvp");
+       uniform_rgba    = glGetUniformLocation(program, "tex_rgba");
+       uniform_opacity = glGetUniformLocation(program, "opacity");
+
+       glUniformMatrix4fv(uniform_mvp, 1, GL_FALSE, mvp);
+
+       // board
+       glActiveTexture(GL_TEXTURE0);
+       glBindTexture  (GL_TEXTURE_2D, texture_rgba);
+       glTexImage2D   (GL_TEXTURE_2D, 0, GL_RGBA, w_text, h_text, 0, GL_RGBA, GL_UNSIGNED_BYTE, bgra);
+       glUniform1i(uniform_rgba, 0);
+
+       glUniform1f(uniform_opacity, opacity);
+
+       // draw
+       glBindBuffer   (GL_ARRAY_BUFFER, buffers[0]);
+       glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vert_update), vert_update);
+
+       glBindBuffer   (GL_ARRAY_BUFFER, buffers[1]);
+       glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(texture_update), texture_update);
+
+       glBindVertexArray(vao);
+
+       glEnable(GL_BLEND);
+       glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+
+       glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+       glDisable(GL_BLEND);
+
+       glBindVertexArray(0);
+       glUseProgram(0);
+       return 0;
+}
index 61a0ec3e7f290df5a2a19b6d082564e2cc590d59..eec7d6205c0ecfea48bad36673042f28c1063f47 100644 (file)
--- a/ui/abc.h
+++ b/ui/abc.h
@@ -13,7 +13,7 @@ typedef struct abc_render_s  abc_render_t;
 typedef struct abc_layout_s  abc_layout_t;
 typedef struct abc_ctx_s     abc_ctx_t;
 
 typedef struct abc_layout_s  abc_layout_t;
 typedef struct abc_ctx_s     abc_ctx_t;
 
-typedef int  (*abc_layout_pt)(abc_layout_t* layout, abc_obj_t* obj, int width, int height);
+typedef int  (*abc_layout_pt)(abc_ctx_t* ctx, abc_obj_t* obj, int width, int height);
 
 struct abc_layout_s
 {
 
 struct abc_layout_s
 {
@@ -83,6 +83,13 @@ void __draw_text(cairo_text_extents_t* extents, cairo_t* cr, const char* text, d
 int __init_text  (cairo_t* cr, abc_obj_t* obj, int num_flag, double scale);
 int __layout_text(cairo_t* cr, abc_obj_t* obj, int x, int width, cairo_text_extents_t* extents);
 
 int __init_text  (cairo_t* cr, abc_obj_t* obj, int num_flag, double scale);
 int __layout_text(cairo_t* cr, abc_obj_t* obj, int x, int width, cairo_text_extents_t* extents);
 
+int __render_text_gl(abc_obj_t* obj, const char* bgra, int w_text, int h_text, int width, int height,
+               int x,
+               int y,
+               int w,
+               int h,
+               int view_x, int view_y, int view_w, int view_h, float mvp[16]);
+
 extern abc_render_t  __render_border;
 extern abc_render_t  __render_bg_image;
 extern abc_render_t  __render_text;
 extern abc_render_t  __render_border;
 extern abc_render_t  __render_bg_image;
 extern abc_render_t  __render_text;
index 1a348a08be1fa3284ca8706c7ad0e1caf20892f4..244380ba30b0091b33b744e79df471bcbcd0f597 100644 (file)
@@ -1,30 +1,30 @@
 #include"abc.h"
 
 #include"abc.h"
 
-int abc_layout_body (abc_layout_t* layout, abc_obj_t* obj, int width, int height);
+int abc_layout_body (abc_ctx_t* ctx, abc_obj_t* obj, int width, int height);
 
 
-int abc_layout_text(abc_layout_t* layout, abc_obj_t* obj, int width, int height);
+int abc_layout_text(abc_ctx_t* ctx, abc_obj_t* obj, int width, int height);
 
 
-int abc_layout_div  (abc_layout_t* layout, abc_obj_t* obj, int width, int height);
-int abc_layout_h1   (abc_layout_t* layout, abc_obj_t* obj, int width, int height);
-int abc_layout_hr   (abc_layout_t* layout, abc_obj_t* obj, int width, int height);
-int abc_layout_img  (abc_layout_t* layout, abc_obj_t* obj, int width, int height);
+int abc_layout_div  (abc_ctx_t* ctx, abc_obj_t* obj, int width, int height);
+int abc_layout_h1   (abc_ctx_t* ctx, abc_obj_t* obj, int width, int height);
+int abc_layout_hr   (abc_ctx_t* ctx, abc_obj_t* obj, int width, int height);
+int abc_layout_img  (abc_ctx_t* ctx, abc_obj_t* obj, int width, int height);
 
 
-int abc_layout_form (abc_layout_t* layout, abc_obj_t* obj, int width, int height);
-int abc_layout_label(abc_layout_t* layout, abc_obj_t* obj, int width, int height);
-int abc_layout_input(abc_layout_t* layout, abc_obj_t* obj, int width, int height);
+int abc_layout_form (abc_ctx_t* ctx, abc_obj_t* obj, int width, int height);
+int abc_layout_label(abc_ctx_t* ctx, abc_obj_t* obj, int width, int height);
+int abc_layout_input(abc_ctx_t* ctx, abc_obj_t* obj, int width, int height);
 
 
-int abc_layout_table(abc_layout_t* layout, abc_obj_t* obj, int width, int height);
-int abc_layout_td   (abc_layout_t* layout, abc_obj_t* obj, int width, int height);
+int abc_layout_table(abc_ctx_t* ctx, abc_obj_t* obj, int width, int height);
+int abc_layout_td   (abc_ctx_t* ctx, abc_obj_t* obj, int width, int height);
 
 
-int abc_layout_video(abc_layout_t* layout, abc_obj_t* obj, int width, int height);
-int abc_layout_audio(abc_layout_t* layout, abc_obj_t* obj, int width, int height);
+int abc_layout_video(abc_ctx_t* ctx, abc_obj_t* obj, int width, int height);
+int abc_layout_audio(abc_ctx_t* ctx, abc_obj_t* obj, int width, int height);
 
 
-int abc_layout_empty(abc_layout_t* layout, abc_obj_t* obj, int width, int height)
+int abc_layout_empty(abc_ctx_t* ctx, abc_obj_t* obj, int width, int height)
 {
        return 0;
 }
 
 {
        return 0;
 }
 
-int abc_layout_html(abc_layout_t* layout, abc_obj_t* obj, int width, int height)
+int abc_layout_html(abc_ctx_t* ctx, abc_obj_t* obj, int width, int height)
 {
        obj->w = obj->w0;
        obj->h = obj->h0;
 {
        obj->w = obj->w0;
        obj->h = obj->h0;
@@ -83,7 +83,7 @@ static abc_layout_pt abc_layouts[ABC_HTML_NB] =
        [ABC_HTML_LINK]     = abc_layout_empty,
 };
 
        [ABC_HTML_LINK]     = abc_layout_empty,
 };
 
-int abc_layout_obj(abc_layout_t* layout, abc_obj_t* obj, int width, int height)
+int abc_layout_obj(abc_ctx_t* ctx, abc_obj_t* obj, int width, int height)
 {
        if (obj->type >= ABC_HTML_NB)
                return 0;
 {
        if (obj->type >= ABC_HTML_NB)
                return 0;
@@ -92,7 +92,7 @@ int abc_layout_obj(abc_layout_t* layout, abc_obj_t* obj, int width, int height)
        if (!f)
                return -EINVAL;
 
        if (!f)
                return -EINVAL;
 
-       return f(layout, obj, width, height);
+       return f(ctx, obj, width, height);
 }
 
 #define LAYOUT_POS_FIXED(X, W, W_SET, L_SET, R_SET, L, R) \
 }
 
 #define LAYOUT_POS_FIXED(X, W, W_SET, L_SET, R_SET, L, R) \
@@ -235,7 +235,7 @@ int abc_layout_css(abc_obj_t* obj)
        return obj->position_type;
 }
 
        return obj->position_type;
 }
 
-int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height)
+int abc_layout_root(abc_ctx_t* ctx, abc_obj_t* root, int width, int height)
 {
        if (!root)
                return -EINVAL;
 {
        if (!root)
                return -EINVAL;
@@ -248,6 +248,14 @@ int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height)
                        || ABC_HTML_LINK  == root->type)
                return 0;
 
                        || ABC_HTML_LINK  == root->type)
                return 0;
 
+       if (!root->css_use && ABC_CORE_TEXT != root->type) {
+               root->css_use = 1;
+
+               int ret = abc_css_use(ctx->current, root);
+               if (ret < 0)
+                       return ret;
+       }
+
        abc_attr_t* attr;
 
        int root_w = width;
        abc_attr_t* attr;
 
        int root_w = width;
@@ -384,7 +392,7 @@ int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height)
                                child->x = root->x + root->left;
                                child->y = y + h;
 
                                child->x = root->x + root->left;
                                child->y = y + h;
 
-                               ret = abc_layout_root(NULL, child, root_w, root_h);
+                               ret = abc_layout_root(ctx, child, root_w, root_h);
                                if (ret < 0)
                                        return ret;
 
                                if (ret < 0)
                                        return ret;
 
@@ -409,7 +417,7 @@ int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height)
                                child->x = x;
                                child->y = y;
 
                                child->x = x;
                                child->y = y;
 
-                               ret = abc_layout_root(NULL, child, root_w, root_h);
+                               ret = abc_layout_root(ctx, child, root_w, root_h);
                                if (ret < 0)
                                        return ret;
 
                                if (ret < 0)
                                        return ret;
 
@@ -449,7 +457,7 @@ int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height)
                                        child->x = root->x + root->left;
                                        child->y = y;
 
                                        child->x = root->x + root->left;
                                        child->y = y;
 
-                                       ret = abc_layout_root(NULL, child, root_w, root_h);
+                                       ret = abc_layout_root(ctx, child, root_w, root_h);
                                        if (ret < 0)
                                                return ret;
 
                                        if (ret < 0)
                                                return ret;
 
@@ -480,7 +488,7 @@ int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height)
        root->content_w = root->w;
        root->content_h = root->h;
 
        root->content_w = root->w;
        root->content_h = root->h;
 
-       int ret = abc_layout_obj(NULL, root, width, height);
+       int ret = abc_layout_obj(ctx, root, width, height);
        if (ret < 0)
                return ret;
 #if 0
        if (ret < 0)
                return ret;
 #if 0
index b8b7f75005f5c886e3cebd5643769ce0cea417d5..5a84331db5af852efda2c8409c28deb6a215aad8 100644 (file)
@@ -1,6 +1,6 @@
 #include"abc.h"
 
 #include"abc.h"
 
-int abc_layout_audio(abc_layout_t* layout, abc_obj_t* obj, int width, int height)
+int abc_layout_audio(abc_ctx_t* ctx, abc_obj_t* obj, int width, int height)
 {
        abc_obj_t* attr;
 
 {
        abc_obj_t* attr;
 
index f3743162b88b06d09d5e03c294889f927ca933c4..ba5e9ef5fd2c79f39c8bb6891d317994c2be7a09 100644 (file)
@@ -1,6 +1,6 @@
 #include"abc.h"
 
 #include"abc.h"
 
-int abc_layout_body(abc_layout_t* layout, abc_obj_t* obj, int width, int height)
+int abc_layout_body(abc_ctx_t* ctx, abc_obj_t* obj, int width, int height)
 {
        return 0;
 }
 {
        return 0;
 }
index ea423e49dc9e0a72077829825504c492104d35aa..cd12b30be96effd44f3216a28268bd72091c7669 100644 (file)
@@ -1,6 +1,6 @@
 #include"abc.h"
 
 #include"abc.h"
 
-int abc_layout_div(abc_layout_t* layout, abc_obj_t* obj, int width, int height)
+int abc_layout_div(abc_ctx_t* ctx, abc_obj_t* obj, int width, int height)
 {
        abc_attr_t*           attr;
        cairo_text_extents_t  extents;
 {
        abc_attr_t*           attr;
        cairo_text_extents_t  extents;
index a51e25e72aa15b57f187fff75a20013f86ec0ff8..e5d9ffa76af8fa3ff7755ad0ee2920f39ef5beb7 100644 (file)
@@ -1,6 +1,6 @@
 #include"abc.h"
 
 #include"abc.h"
 
-int abc_layout_form(abc_layout_t* layout, abc_obj_t* obj, int width, int height)
+int abc_layout_form(abc_ctx_t* ctx, abc_obj_t* obj, int width, int height)
 {
        abc_attr_t*           attr;
        abc_attr_t*           style;
 {
        abc_attr_t*           attr;
        abc_attr_t*           style;
index 7a8bf0018be86dc5d61c9f8fa580938231472fcf..c045ee882ca50ea4d11895b9b2c2a20b54a2abd4 100644 (file)
@@ -1,6 +1,6 @@
 #include"abc.h"
 
 #include"abc.h"
 
-int abc_layout_h1(abc_layout_t* layout, abc_obj_t* obj, int width, int height)
+int abc_layout_h1(abc_ctx_t* ctx, abc_obj_t* obj, int width, int height)
 {
        abc_attr_t*           attr;
        abc_attr_t*           style;
 {
        abc_attr_t*           attr;
        abc_attr_t*           style;
index 66392223d68a6798f3d220de3ab23af38b59f86a..fb2f80ff6cce0bdfceecc522384267d3fe32dccd 100644 (file)
@@ -1,6 +1,6 @@
 #include"abc.h"
 
 #include"abc.h"
 
-int abc_layout_hr(abc_layout_t* layout, abc_obj_t* obj, int width, int height)
+int abc_layout_hr(abc_ctx_t* ctx, abc_obj_t* obj, int width, int height)
 {
        int size = 16;
 
 {
        int size = 16;
 
index 5842d89864c8a6cce289a5ed81bf7cfec34ae5db..1e17a7c1167c27eb8bc9993ddc69fb49ac1cea04 100644 (file)
@@ -1,10 +1,51 @@
 #include"abc.h"
 
 #include"abc.h"
 
-int abc_layout_img(abc_layout_t* layout, abc_obj_t* obj, int width, int height)
+int abc_layout_img(abc_ctx_t* ctx, abc_obj_t* obj, int width, int height)
 {
        obj->w_set = abc_css_width (obj, width);
        obj->h_set = abc_css_height(obj, height);
 
 {
        obj->w_set = abc_css_width (obj, width);
        obj->h_set = abc_css_height(obj, height);
 
+       if (obj->w_set && obj->h_set)
+               return 0;
+
+       abc_attr_t* attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_SRC);
+       if (!attr) {
+               scf_loge("src image not found\n");
+               return -EINVAL;
+       }
+
+       if (obj->img) {
+               abc_img_close(obj->img);
+               obj->img = NULL;
+       }
+
+       scf_string_t*  spath = NULL;
+       abc_io_t*      io    = NULL;
+
+       int ret = __io_url_path(&io, &spath, obj->file->data, attr->value->data, attr->value->len);
+       if (ret < 0)
+               return ret;
+
+       ret = abc_img_open(&obj->img, spath->data);
+
+       scf_string_free(spath);
+       spath = NULL;
+       if (ret < 0)
+               return ret;
+
+       int iw = obj->img->width;
+       int ih = obj->img->height;
+
+       if (obj->w_set && obj->w > 0 && iw > 0)
+               obj->h = ih * obj->w / iw;
+
+       else if (obj->h_set && obj->h > 0 && ih > 0)
+               obj->w = iw * obj->h / ih;
+       else {
+               obj->w = iw;
+               obj->h = ih;
+       }
+
        scf_logi("w: %d, h: %d\n", obj->w, obj->h);
        return 0;
 }
        scf_logi("w: %d, h: %d\n", obj->w, obj->h);
        return 0;
 }
index 28bf15c4bdf6baa5e2c17f875bb1d1375d485fc4..3ce2572f698af7689e6115e281b2b43f93455213 100644 (file)
@@ -1,6 +1,6 @@
 #include"abc.h"
 
 #include"abc.h"
 
-int abc_layout_input(abc_layout_t* layout, abc_obj_t* obj, int width, int height)
+int abc_layout_input(abc_ctx_t* ctx, abc_obj_t* obj, int width, int height)
 {
        abc_attr_t*           attr;
        cairo_text_extents_t  extents;
 {
        abc_attr_t*           attr;
        cairo_text_extents_t  extents;
index 8e4d8e7546d8b33cfb4b151672ced8519aec9eca..87e557c14365738d4e958ae9f2e7ad6d7b959ab7 100644 (file)
@@ -1,6 +1,6 @@
 #include"abc.h"
 
 #include"abc.h"
 
-int abc_layout_label(abc_layout_t* layout, abc_obj_t* obj, int width, int height)
+int abc_layout_label(abc_ctx_t* ctx, abc_obj_t* obj, int width, int height)
 {
        abc_attr_t*           attr;
        cairo_text_extents_t  extents;
 {
        abc_attr_t*           attr;
        cairo_text_extents_t  extents;
index 95e6ee355f9da5b8bb72618edb902fc1f3e91193..770b376643c4dd8568e4df10ab5a02c885fc5e24 100644 (file)
@@ -1,6 +1,6 @@
 #include"abc.h"
 
 #include"abc.h"
 
-int abc_layout_table(abc_layout_t* layout, abc_obj_t* obj, int width, int height)
+int abc_layout_table(abc_ctx_t* ctx, abc_obj_t* obj, int width, int height)
 {
        scf_list_t*  l;
        scf_list_t*  l2;
 {
        scf_list_t*  l;
        scf_list_t*  l2;
index a770ec3d33b3c5d0006a84423a34825dc11c5107..78ec13b27bc3689302eca18f7b66059e1fae880b 100644 (file)
@@ -1,6 +1,6 @@
 #include"abc.h"
 
 #include"abc.h"
 
-int abc_layout_td(abc_layout_t* layout, abc_obj_t* obj, int width, int height)
+int abc_layout_td(abc_ctx_t* ctx, abc_obj_t* obj, int width, int height)
 {
        abc_obj_t*            table;
        abc_attr_t*           attr;
 {
        abc_obj_t*            table;
        abc_attr_t*           attr;
index 4786d3566a61628c6b697a85c24507a841f19605..cb11c1b6079ff7f542e4687892997bff7060ec56 100644 (file)
@@ -58,6 +58,8 @@ int __layout_text(cairo_t* cr, abc_obj_t* obj, int x, int width, cairo_text_exte
        cairo_text_extents (cr, obj->text->data, extents);
 
        int w = extents->x_bearing + extents->x_advance;
        cairo_text_extents (cr, obj->text->data, extents);
 
        int w = extents->x_bearing + extents->x_advance;
+
+       w = (w + size - 1) / size * size;
        if (x + w <= width) {
                extents->width = w;
                return 0;
        if (x + w <= width) {
                extents->width = w;
                return 0;
@@ -93,6 +95,7 @@ int __layout_text(cairo_t* cr, abc_obj_t* obj, int x, int width, cairo_text_exte
                                return n;
 
                        w = tmp.x_bearing + tmp.x_advance;
                                return n;
 
                        w = tmp.x_bearing + tmp.x_advance;
+                       w = (w + size - 1) / size * size;
                        if (x + w <= width) {
                                x = 0;
 
                        if (x + w <= width) {
                                x = 0;
 
@@ -124,7 +127,7 @@ int __layout_text(cairo_t* cr, abc_obj_t* obj, int x, int width, cairo_text_exte
        return 0;
 }
 
        return 0;
 }
 
-int abc_layout_text(abc_layout_t* layout, abc_obj_t* obj, int width, int height)
+int abc_layout_text(abc_ctx_t* ctx, abc_obj_t* obj, int width, int height)
 {
        abc_obj_t*            parent = obj->parent;
        abc_attr_t*           attr;
 {
        abc_obj_t*            parent = obj->parent;
        abc_attr_t*           attr;
index f46e7b3fce11bb779e485c6484b4b9c2b2adfe92..1cced803e58b2e98a3a9931e270af0d42aa0d7e6 100644 (file)
@@ -108,7 +108,7 @@ error:
        return ret;
 }
 
        return ret;
 }
 
-int abc_layout_video(abc_layout_t* layout, abc_obj_t* obj, int width, int height)
+int abc_layout_video(abc_ctx_t* ctx, abc_obj_t* obj, int width, int height)
 {
        abc_attr_t*  attr;
 
 {
        abc_attr_t*  attr;
 
@@ -116,7 +116,6 @@ int abc_layout_video(abc_layout_t* layout, abc_obj_t* obj, int width, int height
        int h = 0;
 
        if (!obj->av_filter) {
        int h = 0;
 
        if (!obj->av_filter) {
-
                int ret = __av_filter_init(obj);
                if (ret < 0) {
                        scf_loge("open video failed\n");
                int ret = __av_filter_init(obj);
                if (ret < 0) {
                        scf_loge("open video failed\n");
index 374bc6f8e5fdb0e6d6f0e89de948d71a930cf6e3..a45071813235e84948a397d6d49debcee32f1811 100644 (file)
@@ -55,18 +55,18 @@ static int __render_draw_hr(abc_render_t* render, abc_obj_t* obj, int width, int
        if (0 == vao)
                __init_buffers(&vao, buffers);
 
        if (0 == vao)
                __init_buffers(&vao, buffers);
 
-       double fgColor[3] = {0.0, 0.0, 0.0};
+       double fgColor[4] = {0.0, 0.0, 0.0, 1.0};
        double bgColor[4] = {0.0, 0.0, 0.0, 0.0};
 
        abc_attr_t* attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_BG_COLOR);
        if (attr && attr->value->len > 0) {
                bgColor[3] = 1.0;
        double bgColor[4] = {0.0, 0.0, 0.0, 0.0};
 
        abc_attr_t* attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_BG_COLOR);
        if (attr && attr->value->len > 0) {
                bgColor[3] = 1.0;
-               abc_css_color(bgColor, bgColor + 1, bgColor + 2, attr->value->data, attr->value->len);
+               abc_css_color(bgColor, attr->value->data, attr->value->len);
        }
 
        attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_COLOR);
        if (attr)
        }
 
        attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_COLOR);
        if (attr)
-               abc_css_color(fgColor, fgColor + 1, fgColor + 2, attr->value->data, attr->value->len);
+               abc_css_color(fgColor, attr->value->data, attr->value->len);
 
        int x = obj->x + obj->margin_left;
        int y = obj->y + obj->margin_top;
 
        int x = obj->x + obj->margin_left;
        int y = obj->y + obj->margin_top;
@@ -144,7 +144,7 @@ static int __render_draw_hr(abc_render_t* render, abc_obj_t* obj, int width, int
 
        glUniformMatrix4fv(uniform_mvp, 1, GL_FALSE, mvp);
 
 
        glUniformMatrix4fv(uniform_mvp, 1, GL_FALSE, mvp);
 
-       glUniform4f(uniform_color,      fgColor[0], fgColor[1], fgColor[2], 1.0);
+       glUniform4f(uniform_color,      fgColor[0], fgColor[1], fgColor[2], fgColor[3]);
        glUniform4f(uniform_bgColor,    bgColor[0], bgColor[1], bgColor[2], bgColor[3]);
        glUniform1f(uniform_line_width, 1.0 / (float)h);
 
        glUniform4f(uniform_bgColor,    bgColor[0], bgColor[1], bgColor[2], bgColor[3]);
        glUniform1f(uniform_line_width, 1.0 / (float)h);
 
index 8c4fede9d21ba69d2b3645fb9845439228b8887b..a75f46ed3dc0d451028eface9025465cdbd4dc6f 100644 (file)
@@ -1,39 +1,6 @@
 #include"abc.h"
 #include"abc_ffmpeg.h"
 
 #include"abc.h"
 #include"abc_ffmpeg.h"
 
-static const char* vert_shader =
-       "#version 330 core\n"
-       "layout(location = 0) in vec4 position; \n"
-       "layout(location = 1) in vec2 a_texCoord; \n"
-       "out vec2 v_texCoord; \n"
-       "uniform mat4 mvp; \n"
-       "void main() { \n"
-               "gl_Position = mvp * position; \n"
-               "v_texCoord  = a_texCoord; \n"
-       "} \n";
-
-static const char* frag_shader =
-       "#version 330 core\n"
-       "in  vec2 v_texCoord; \n"
-       "out vec4 outputColor; \n"
-       "uniform sampler2D tex_rgba; \n"
-       "void main() { \n"
-       "    vec2 xy = v_texCoord; \n"
-       "    vec4 v  = texture2D(tex_rgba, xy).rgba; \n"
-       "    outputColor = vec4(v.b, v.g, v.r, 1.0); \n"
-       "} \n";
-
-
-static GLuint program = 0;
-
-static GLuint vao = 0;
-static GLuint buffers[2]   = {0};
-static GLuint texture_rgba = 0;
-
-static GLuint uniform_mvp;
-static GLuint uniform_rgba;
-
-
 static int _render_fini_img(abc_render_t* render)
 {
        return 0;
 static int _render_fini_img(abc_render_t* render)
 {
        return 0;
@@ -42,88 +9,84 @@ static int _render_fini_img(abc_render_t* render)
 static int _render_draw_img(abc_render_t* render, abc_obj_t* obj, int width, int height, abc_ctx_t* ctx)
 {
        abc_attr_t* attr;
 static int _render_draw_img(abc_render_t* render, abc_obj_t* obj, int width, int height, abc_ctx_t* ctx)
 {
        abc_attr_t* attr;
-       abc_img_t*  img = NULL;
+       int ret;
+
+       if (!obj->img) {
+               attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_SRC);
+               if (!attr) {
+                       scf_loge("src image not found\n");
+                       return -EINVAL;
+               }
+
+               scf_string_t*  spath = NULL;
+               abc_io_t*      io    = NULL;
 
 
-       attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_SRC);
-       if (!attr) {
-               scf_loge("src image of '%s' not found\n", obj->keys[0]);
-               return -1;
+               ret = __io_url_path(&io, &spath, obj->file->data, attr->value->data, attr->value->len);
+               if (ret < 0)
+                       return ret;
+
+               ret = abc_img_open(&obj->img, spath->data);
+
+               scf_string_free(spath);
+               spath = NULL;
+               if (ret < 0)
+                       return ret;
        }
 
        }
 
-       int ret = abc_img_open(&img, attr->value->data);
-       if (ret < 0)
-               return ret;
+       int iw = obj->img->width;
+       int ih = obj->img->height;
 
 
-       uint8_t* bgra = calloc(1, img->width * img->height * 4);
+       uint8_t* bgra = calloc(1, iw * ih * 4);
        if (!bgra) {
        if (!bgra) {
-               abc_img_close(img);
+               abc_img_close(obj->img);
+               obj->img = NULL;
                return -ENOMEM;
        }
 
                return -ENOMEM;
        }
 
-       ret = abc_img_read(img, bgra, img->width * img->height * 4);
+       ret = abc_img_read(obj->img, bgra, iw * ih * 4);
+
+       abc_img_close(obj->img);
+       obj->img = NULL;
        if (ret < 0) {
        if (ret < 0) {
-               abc_img_close(img);
                free(bgra);
                return ret;
        }
 
                free(bgra);
                return ret;
        }
 
-       if (0 == program)
-               __init_program(&program, vert_shader, frag_shader);
-
-       if (0 == vao)
-               __init_buffers(&vao, buffers);
-
-       if (0 == texture_rgba)
-               __init_texture(&texture_rgba, GL_RGBA, img->width, img->height, NULL);
-
-       float mvp[16];
-       __compute_mvp(mvp, 0, 0, 0);
-
-       scf_logi("%s, x: %d, y: %d, w: %d, h: %d\n", obj->keys[0], obj->x, obj->y, obj->w, obj->h);
-
        int x = obj->x + obj->left;
        int y = obj->y + obj->top;
        int w = obj->w - obj->left - obj->right;
        int h = obj->h - obj->top  - obj->bottom;
 
        int x = obj->x + obj->left;
        int y = obj->y + obj->top;
        int w = obj->w - obj->left - obj->right;
        int h = obj->h - obj->top  - obj->bottom;
 
-       GLfloat vert_update[] =
-       {
-                2.0 *  x      / (float)width  - 1.0,
-               -2.0 * (y + h) / (float)height + 1.0,
-
-                2.0 * (x + w) / (float)width  - 1.0,
-               -2.0 * (y + h) / (float)height + 1.0,
-
-                2.0 *  x      / (float)width  - 1.0,
-               -2.0 *  y      / (float)height + 1.0,
+       int view_x = x;
+       int view_y = y;
+       int view_w = w;
+       int view_h = h;
 
 
-                2.0 * (x + w) / (float)width  - 1.0,
-               -2.0 *  y      / (float)height + 1.0,
+       switch (obj->overflow_type)
+       {
+               case ABC_OVERFLOW_HIDDEN:
+               case ABC_OVERFLOW_SCROLL:
+               case ABC_OVERFLOW_AUTO:
+                       abc_overflow_show(&view_x, &view_y, &view_w, &view_h,
+                                       obj->view_x,
+                                       obj->view_y, obj->view_w, obj->view_h);
+                       break;
+               default:
+                       break;
        };
 
        };
 
-       glUseProgram(program);
-       uniform_rgba = glGetUniformLocation(program, "tex_rgba");
-       uniform_mvp  = glGetUniformLocation(program, "mvp");
+       scf_logd("%s, x: %d, y: %d, w: %d, h: %d\n", obj->keys[0], obj->x, obj->y, obj->w, obj->h);
 
 
-       glUniformMatrix4fv(uniform_mvp, 1, GL_FALSE, mvp);
-
-       glActiveTexture(GL_TEXTURE0);
-       glBindTexture  (GL_TEXTURE_2D, texture_rgba);
-       glTexImage2D   (GL_TEXTURE_2D, 0, GL_RGBA, img->width, img->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, bgra);
-       glUniform1i(uniform_rgba, 0);
-
-       // draw
-       glBindBuffer   (GL_ARRAY_BUFFER, buffers[0]);
-       glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vert_update), vert_update);
-
-       glBindVertexArray(vao);
-
-       glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+       float mvp[16];
+       __compute_mvp(mvp, 0, 0, 0);
 
 
-       glBindVertexArray(0);
-       glUseProgram(0);
+       __render_text_gl(obj, bgra, iw, ih, width, height,
+                                x,
+                                        y,
+                                        w,
+                                        h,
+                                        view_x, view_y, view_w, view_h, mvp);
 
 
-       abc_img_close(img);
        free(bgra);
        return 0;
 }
        free(bgra);
        return 0;
 }
index 8bb74d6676132a8e94d08c265f423ba4e5e4ee7b..13931aa35a82a5f68d81a9c17ba91801f37fdb90 100644 (file)
@@ -1,38 +1,5 @@
 #include"abc.h"
 
 #include"abc.h"
 
-static const char* vert_shader =
-       "#version 330 core\n"
-       "layout(location = 0) in vec4 position; \n"
-       "layout(location = 1) in vec2 a_texCoord; \n"
-       "out vec2 v_texCoord; \n"
-       "uniform mat4 mvp; \n"
-       "void main() { \n"
-               "gl_Position = mvp * position; \n"
-               "v_texCoord  = a_texCoord; \n"
-       "} \n";
-
-static const char* frag_shader =
-       "#version 330 core\n"
-       "in  vec2 v_texCoord; \n"
-       "out vec4 outputColor; \n"
-       "uniform sampler2D tex_rgba; \n"
-       "void main() { \n"
-       "    vec2 xy = v_texCoord; \n"
-       "    vec4 v  = texture2D(tex_rgba, xy).rgba; \n"
-       "    outputColor = vec4(v.b, v.g, v.r, 1.0); \n"
-       "} \n";
-
-
-static GLuint program = 0;
-
-static GLuint vao = 0;
-static GLuint buffers[2]   = {0};
-static GLuint texture_rgba = 0;
-
-static GLuint uniform_mvp;
-static GLuint uniform_rgba;
-
-
 static int _render_fini_input(abc_render_t* render)
 {
        return 0;
 static int _render_fini_input(abc_render_t* render)
 {
        return 0;
@@ -50,15 +17,6 @@ static int _render_draw_input(abc_render_t* render, abc_obj_t* obj, int width, i
        int w_text = w * ctx->gl_scale;
        int h_text = h * ctx->gl_scale;
 
        int w_text = w * ctx->gl_scale;
        int h_text = h * ctx->gl_scale;
 
-       if (0 == program)
-               __init_program(&program, vert_shader, frag_shader);
-
-       if (0 == vao)
-               __init_buffers(&vao, buffers);
-
-       if (0 == texture_rgba)
-               __init_texture(&texture_rgba, GL_RGBA, w_text, h_text, NULL);
-
        abc_attr_t*           type;
        abc_attr_t*           attr;
        cairo_text_extents_t  extents;
        abc_attr_t*           type;
        abc_attr_t*           attr;
        cairo_text_extents_t  extents;
@@ -72,15 +30,13 @@ static int _render_draw_input(abc_render_t* render, abc_obj_t* obj, int width, i
        surface = cairo_image_surface_create_for_data(bgra, CAIRO_FORMAT_ARGB32, w_text, h_text, w_text * 4);
        cr      = cairo_create(surface);
 
        surface = cairo_image_surface_create_for_data(bgra, CAIRO_FORMAT_ARGB32, w_text, h_text, w_text * 4);
        cr      = cairo_create(surface);
 
-       double r = 0.0;
-       double g = 0.0;
-       double b = 0.0;
+       double rgba[4] = {0.0, 0.0, 0.0, 0.0};
        attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_BG_COLOR);
        attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_BG_COLOR);
-       if (attr)
-               abc_css_color(&r, &g, &b, attr->value->data, attr->value->len);
+       if (attr && attr->value->len > 0)
+               abc_css_color(rgba, attr->value->data, attr->value->len);
 
        cairo_set_line_width (cr, 1);
 
        cairo_set_line_width (cr, 1);
-       cairo_set_source_rgba(cr, r, g, b, 1.0);
+       cairo_set_source_rgba(cr, rgba[0], rgba[1], rgba[2], rgba[3]);
        cairo_rectangle(cr, 0, 0, w_text, h_text);
        cairo_fill(cr);
        cairo_stroke(cr);
        cairo_rectangle(cr, 0, 0, w_text, h_text);
        cairo_fill(cr);
        cairo_stroke(cr);
@@ -89,9 +45,13 @@ static int _render_draw_input(abc_render_t* render, abc_obj_t* obj, int width, i
        if (attr)
                cairo_select_font_face(cr, attr->value->data, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
 
        if (attr)
                cairo_select_font_face(cr, attr->value->data, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
 
+       rgba[0] = 0.0;
+       rgba[1] = 0.0;
+       rgba[2] = 0.0;
+       rgba[3] = 1.0;
        attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_COLOR);
        if (attr)
        attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_COLOR);
        if (attr)
-               abc_css_color(&r, &g, &b, attr->value->data, attr->value->len);
+               abc_css_color(rgba, attr->value->data, attr->value->len);
 
        int size = 16;
        attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_SIZE);
 
        int size = 16;
        attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_SIZE);
@@ -99,7 +59,7 @@ static int _render_draw_input(abc_render_t* render, abc_obj_t* obj, int width, i
                size = atoi(attr->value->data);
 
        cairo_set_font_size  (cr, size * ctx->gl_scale);
                size = atoi(attr->value->data);
 
        cairo_set_font_size  (cr, size * ctx->gl_scale);
-       cairo_set_source_rgba(cr, r, g, b, 1.0);
+       cairo_set_source_rgba(cr, rgba[0], rgba[1], rgba[2], rgba[3]);
 
        int x_cursor = 2;
 
 
        int x_cursor = 2;
 
@@ -172,61 +132,12 @@ static int _render_draw_input(abc_render_t* render, abc_obj_t* obj, int width, i
 
        scf_logd("x: %d, y: %d, w: %d, h: %d\n", obj->x, obj->y, obj->w, obj->h);
 
 
        scf_logd("x: %d, y: %d, w: %d, h: %d\n", obj->x, obj->y, obj->w, obj->h);
 
-       GLfloat vert_update[] =
-       {
-                2.0 *  view_x           / (float)width  - 1.0,
-               -2.0 * (view_y + view_h) / (float)height + 1.0,
-
-                2.0 * (view_x + view_w) / (float)width  - 1.0,
-               -2.0 * (view_y + view_h) / (float)height + 1.0,
-
-                2.0 *  view_x           / (float)width  - 1.0,
-               -2.0 *  view_y           / (float)height + 1.0,
-
-                2.0 * (view_x + view_w) / (float)width  - 1.0,
-               -2.0 *  view_y           / (float)height + 1.0,
-       };
-
-       GLfloat texture_update[] =
-       {
-               (view_x - x)          / (float)w,
-               (view_y + view_h - y) / (float)h,
-
-               (view_x + view_w - x) / (float)w,
-               (view_y + view_h - y) / (float)h,
-
-               (view_x - x)          / (float)w,
-               (view_y - y)          / (float)h,
-
-               (view_x + view_w - x) / (float)w,
-               (view_y - y)          / (float)h,
-       };
-
-       glUseProgram(program);
-       uniform_rgba = glGetUniformLocation(program, "tex_rgba");
-       uniform_mvp  = glGetUniformLocation(program, "mvp");
-
-       glUniformMatrix4fv(uniform_mvp, 1, GL_FALSE, mvp);
-
-       // board
-       glActiveTexture(GL_TEXTURE0);
-       glBindTexture  (GL_TEXTURE_2D, texture_rgba);
-       glTexImage2D   (GL_TEXTURE_2D, 0, GL_RGBA, w_text, h_text, 0, GL_RGBA, GL_UNSIGNED_BYTE, bgra);
-       glUniform1i(uniform_rgba, 0);
-
-       // draw
-       glBindBuffer   (GL_ARRAY_BUFFER, buffers[0]);
-       glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vert_update), vert_update);
-
-       glBindBuffer   (GL_ARRAY_BUFFER, buffers[1]);
-       glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(texture_update), texture_update);
-
-       glBindVertexArray(vao);
-
-       glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
-
-       glBindVertexArray(0);
-       glUseProgram(0);
+       __render_text_gl(obj, bgra, w_text, h_text, width, height,
+                                x,
+                                        y,
+                                        w,
+                                        h,
+                                        view_x, view_y, view_w, view_h, mvp);
 
        free(bgra);
        return 0;
 
        free(bgra);
        return 0;
index e1394bfc0647fa6e87efffd0c3a7b0ceee442102..c36a3cde38b1a4f4caf56e4a539198ce86df9080 100644 (file)
@@ -1,38 +1,5 @@
 #include"abc.h"
 
 #include"abc.h"
 
-static const char* vert_shader =
-       "#version 330 core\n"
-       "layout(location = 0) in vec4 position; \n"
-       "layout(location = 1) in vec2 a_texCoord; \n"
-       "out vec2 v_texCoord; \n"
-       "uniform mat4 mvp; \n"
-       "void main() { \n"
-               "gl_Position = mvp * position; \n"
-               "v_texCoord  = a_texCoord; \n"
-       "} \n";
-
-static const char* frag_shader =
-       "#version 330 core\n"
-       "in  vec2 v_texCoord; \n"
-       "out vec4 outputColor; \n"
-       "uniform sampler2D tex_rgba; \n"
-       "void main() { \n"
-       "    vec2 xy = v_texCoord; \n"
-       "    vec4 v  = texture2D(tex_rgba, xy).rgba; \n"
-       "    outputColor = vec4(v.b, v.g, v.r, 1.0); \n"
-       "} \n";
-
-
-static GLuint program = 0;
-
-static GLuint vao = 0;
-static GLuint buffers[2]   = {0};
-static GLuint texture_rgba = 0;
-
-static GLuint uniform_mvp;
-static GLuint uniform_rgba;
-
-
 static int _render_fini_label(abc_render_t* render)
 {
        return 0;
 static int _render_fini_label(abc_render_t* render)
 {
        return 0;
@@ -53,15 +20,6 @@ static int _render_draw_label(abc_render_t* render, abc_obj_t* obj, int width, i
        int w_text = w * ctx->gl_scale;
        int h_text = h * ctx->gl_scale;
 
        int w_text = w * ctx->gl_scale;
        int h_text = h * ctx->gl_scale;
 
-       if (0 == program)
-               __init_program(&program, vert_shader, frag_shader);
-
-       if (0 == vao)
-               __init_buffers(&vao, buffers);
-
-       if (0 == texture_rgba)
-               __init_texture(&texture_rgba, GL_RGBA, w_text, h_text, NULL);
-
        abc_attr_t*           type;
        abc_attr_t*           attr;
        cairo_text_extents_t  extents;
        abc_attr_t*           type;
        abc_attr_t*           attr;
        cairo_text_extents_t  extents;
@@ -75,15 +33,14 @@ static int _render_draw_label(abc_render_t* render, abc_obj_t* obj, int width, i
        surface = cairo_image_surface_create_for_data(bgra, CAIRO_FORMAT_ARGB32, w_text, h_text, w_text * 4);
        cr      = cairo_create(surface);
 
        surface = cairo_image_surface_create_for_data(bgra, CAIRO_FORMAT_ARGB32, w_text, h_text, w_text * 4);
        cr      = cairo_create(surface);
 
-       double r = 0.0;
-       double g = 0.0;
-       double b = 0.0;
+       double rgba[4] = {0.0, 0.0, 0.0, 0.0};
+
        attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_BG_COLOR);
        attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_BG_COLOR);
-       if (attr)
-               abc_css_color(&r, &g, &b, attr->value->data, attr->value->len);
+       if (attr && attr->value->len > 0)
+               abc_css_color(rgba, attr->value->data, attr->value->len);
 
        cairo_set_line_width (cr, 1);
 
        cairo_set_line_width (cr, 1);
-       cairo_set_source_rgba(cr, r, g, b, 1.0);
+       cairo_set_source_rgba(cr, rgba[0], rgba[1], rgba[2], rgba[3]);
        cairo_rectangle(cr, 0, 0, w_text, h_text);
        cairo_fill(cr);
        cairo_stroke(cr);
        cairo_rectangle(cr, 0, 0, w_text, h_text);
        cairo_fill(cr);
        cairo_stroke(cr);
@@ -94,7 +51,7 @@ static int _render_draw_label(abc_render_t* render, abc_obj_t* obj, int width, i
 
        attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_COLOR);
        if (attr)
 
        attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_COLOR);
        if (attr)
-               abc_css_color(&r, &g, &b, attr->value->data, attr->value->len);
+               abc_css_color(rgba, attr->value->data, attr->value->len);
 
        int size = 16;
        attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_SIZE);
 
        int size = 16;
        attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_SIZE);
@@ -102,7 +59,7 @@ static int _render_draw_label(abc_render_t* render, abc_obj_t* obj, int width, i
                size = atoi(attr->value->data);
 
        cairo_set_font_size  (cr, size * ctx->gl_scale);
                size = atoi(attr->value->data);
 
        cairo_set_font_size  (cr, size * ctx->gl_scale);
-       cairo_set_source_rgba(cr, r, g, b, 1.0);
+       cairo_set_source_rgba(cr, rgba[0], rgba[1], rgba[2], rgba[3]);
 
        cairo_text_extents(cr, obj->text->data, &extents);
        cairo_move_to  (cr, extents.x_bearing, -extents.y_bearing + (h_text - extents.height) / 2);
 
        cairo_text_extents(cr, obj->text->data, &extents);
        cairo_move_to  (cr, extents.x_bearing, -extents.y_bearing + (h_text - extents.height) / 2);
@@ -139,61 +96,12 @@ static int _render_draw_label(abc_render_t* render, abc_obj_t* obj, int width, i
 
        scf_logd("x: %d, y: %d, w: %d, h: %d\n", obj->x, obj->y, obj->w, obj->h);
 
 
        scf_logd("x: %d, y: %d, w: %d, h: %d\n", obj->x, obj->y, obj->w, obj->h);
 
-       GLfloat vert_update[] =
-       {
-                2.0 *  view_x           / (float)width  - 1.0,
-               -2.0 * (view_y + view_h) / (float)height + 1.0,
-
-                2.0 * (view_x + view_w) / (float)width  - 1.0,
-               -2.0 * (view_y + view_h) / (float)height + 1.0,
-
-                2.0 *  view_x           / (float)width  - 1.0,
-               -2.0 *  view_y           / (float)height + 1.0,
-
-                2.0 * (view_x + view_w) / (float)width  - 1.0,
-               -2.0 *  view_y           / (float)height + 1.0,
-       };
-
-       GLfloat texture_update[] =
-       {
-               (view_x - x)          / (float)w,
-               (view_y + view_h - y) / (float)h,
-
-               (view_x + view_w - x) / (float)w,
-               (view_y + view_h - y) / (float)h,
-
-               (view_x - x)          / (float)w,
-               (view_y - y)          / (float)h,
-
-               (view_x + view_w - x) / (float)w,
-               (view_y - y)          / (float)h,
-       };
-
-       glUseProgram(program);
-       uniform_rgba = glGetUniformLocation(program, "tex_rgba");
-       uniform_mvp  = glGetUniformLocation(program, "mvp");
-
-       glUniformMatrix4fv(uniform_mvp, 1, GL_FALSE, mvp);
-
-       // board
-       glActiveTexture(GL_TEXTURE0);
-       glBindTexture  (GL_TEXTURE_2D, texture_rgba);
-       glTexImage2D   (GL_TEXTURE_2D, 0, GL_RGBA, w_text, h_text, 0, GL_RGBA, GL_UNSIGNED_BYTE, bgra);
-       glUniform1i(uniform_rgba, 0);
-
-       // draw
-       glBindBuffer   (GL_ARRAY_BUFFER, buffers[0]);
-       glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vert_update), vert_update);
-
-       glBindBuffer   (GL_ARRAY_BUFFER, buffers[1]);
-       glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(texture_update), texture_update);
-
-       glBindVertexArray(vao);
-
-       glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
-
-       glBindVertexArray(0);
-       glUseProgram(0);
+       __render_text_gl(obj, bgra, w_text, h_text, width, height,
+                                x,
+                                        y,
+                                        w,
+                                        h,
+                                        view_x, view_y, view_w, view_h, mvp);
 
        free(bgra);
        return 0;
 
        free(bgra);
        return 0;
index 0a83184a7cb6e02b0ae0e88e8a70467c703cb7af..2407ae7ace378a9ff3676cc72667b695c4d7809a 100644 (file)
@@ -63,24 +63,22 @@ static int _render_draw_li(abc_render_t* render, abc_obj_t* obj, int width, int
        if (!bgra)
                return -ENOMEM;
 
        if (!bgra)
                return -ENOMEM;
 
-       double r = 0.0;
-       double g = 0.0;
-       double b = 0.0;
-       int    size = 16;
+       double rgba[4] = {0.0, 0.0, 0.0, 0.0};
+       int    size    = 16;
 
        attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_SIZE);
        if (attr)
                size = atoi(attr->value->data);
 
        attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_BG_COLOR);
 
        attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_SIZE);
        if (attr)
                size = atoi(attr->value->data);
 
        attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_BG_COLOR);
-       if (attr)
-               abc_css_color(&r, &g, &b, attr->value->data, attr->value->len);
+       if (attr && attr->value->len > 0)
+               abc_css_color(rgba, attr->value->data, attr->value->len);
 
        surface = cairo_image_surface_create_for_data(bgra, CAIRO_FORMAT_ARGB32, w_text, h_text, w_text * 4);
        cr      = cairo_create(surface);
 
 
        surface = cairo_image_surface_create_for_data(bgra, CAIRO_FORMAT_ARGB32, w_text, h_text, w_text * 4);
        cr      = cairo_create(surface);
 
-       cairo_set_line_width(cr, 1);
-       cairo_set_source_rgb(cr, r, g, b);
+       cairo_set_line_width (cr, 1);
+       cairo_set_source_rgba(cr, rgba[0], rgba[1], rgba[2], rgba[3]);
        cairo_rectangle(cr, 0, 0, w_text, h_text);
        cairo_fill(cr);
        cairo_stroke(cr);
        cairo_rectangle(cr, 0, 0, w_text, h_text);
        cairo_fill(cr);
        cairo_stroke(cr);
@@ -118,8 +116,8 @@ static int _render_draw_li(abc_render_t* render, abc_obj_t* obj, int width, int
                surface = cairo_image_surface_create_for_data(bgra1, CAIRO_FORMAT_ARGB32, w_order, h_order, w_order * 4);
                cr      = cairo_create(surface);
 
                surface = cairo_image_surface_create_for_data(bgra1, CAIRO_FORMAT_ARGB32, w_order, h_order, w_order * 4);
                cr      = cairo_create(surface);
 
-               cairo_set_line_width(cr, 1.0 * ctx->gl_scale);
-               cairo_set_source_rgb(cr, r, g, b);
+               cairo_set_line_width (cr, 1);
+               cairo_set_source_rgba(cr, rgba[0], rgba[1], rgba[2], rgba[3]);
                cairo_rectangle(cr, 0, 0, w_order, h_order);
                cairo_fill(cr);
                cairo_stroke(cr);
                cairo_rectangle(cr, 0, 0, w_order, h_order);
                cairo_fill(cr);
                cairo_stroke(cr);
@@ -140,14 +138,15 @@ static int _render_draw_li(abc_render_t* render, abc_obj_t* obj, int width, int
                        scf_string_free(s);
                        s = NULL;
                } else {
                        scf_string_free(s);
                        s = NULL;
                } else {
-                       r = 0.0;
-                       g = 0.0;
-                       b = 0.0;
+                       rgba[0] = 0.0;
+                       rgba[1] = 0.0;
+                       rgba[2] = 0.0;
+                       rgba[3] = 1.0;
                        attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_COLOR);
                        if (attr)
                        attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_COLOR);
                        if (attr)
-                               abc_css_color(&r, &g, &b, attr->value->data, attr->value->len);
+                               abc_css_color(rgba, attr->value->data, attr->value->len);
 
 
-                       cairo_set_source_rgb(cr, r, g, b);
+                       cairo_set_source_rgba(cr, rgba[0], rgba[1], rgba[2], rgba[3]);
 
                        attr = abc_obj_find_attr(obj, ABC_CSS_LIST_STYLE_TYPE);
                        if (attr) {
 
                        attr = abc_obj_find_attr(obj, ABC_CSS_LIST_STYLE_TYPE);
                        if (attr) {
index 59dc0440945b3a8248ecdc043b77299014e653bf..bc27b56c048c8576d59f67e1dbb97d8f97d3c553 100644 (file)
@@ -1,38 +1,5 @@
 #include"abc.h"
 
 #include"abc.h"
 
-static const char* vert_shader =
-       "#version 330 core\n"
-       "layout(location = 0) in vec4 position; \n"
-       "layout(location = 1) in vec2 a_texCoord; \n"
-       "out vec2 v_texCoord; \n"
-       "uniform mat4 mvp; \n"
-       "void main() { \n"
-               "gl_Position = mvp * position; \n"
-               "v_texCoord  = a_texCoord; \n"
-       "} \n";
-
-static const char* frag_shader =
-       "#version 330 core\n"
-       "in  vec2 v_texCoord; \n"
-       "out vec4 outputColor; \n"
-       "uniform sampler2D tex_rgba; \n"
-       "void main() { \n"
-       "    vec2 xy = v_texCoord; \n"
-       "    vec4 v  = texture2D(tex_rgba, xy).rgba; \n"
-       "    outputColor = vec4(v.b, v.g, v.r, 1.0); \n"
-       "} \n";
-
-
-static GLuint program = 0;
-
-static GLuint vao = 0;
-static GLuint buffers[2]   = {0};
-static GLuint texture_rgba = 0;
-
-static GLuint uniform_mvp;
-static GLuint uniform_rgba;
-
-
 static int _render_fini_td(abc_render_t* render)
 {
        return 0;
 static int _render_fini_td(abc_render_t* render)
 {
        return 0;
@@ -55,15 +22,6 @@ static int _render_draw_td(abc_render_t* render, abc_obj_t* obj, int width, int
        int w_text = w * ctx->gl_scale;
        int h_text = h * ctx->gl_scale;
 
        int w_text = w * ctx->gl_scale;
        int h_text = h * ctx->gl_scale;
 
-       if (0 == program)
-               __init_program(&program, vert_shader, frag_shader);
-
-       if (0 == vao)
-               __init_buffers(&vao, buffers);
-
-       if (0 == texture_rgba)
-               __init_texture(&texture_rgba, GL_RGBA, w_text, h_text, NULL);
-
        uint8_t* bgra = calloc(1, w_text * h_text * 4);
        if (!bgra)
                return -ENOMEM;
        uint8_t* bgra = calloc(1, w_text * h_text * 4);
        if (!bgra)
                return -ENOMEM;
@@ -78,27 +36,27 @@ static int _render_draw_td(abc_render_t* render, abc_obj_t* obj, int width, int
        cairo_set_line_width(cr, 1);
 
        // clear table element's area with background-color
        cairo_set_line_width(cr, 1);
 
        // clear table element's area with background-color
-       double r = 1.0;
-       double g = 1.0;
-       double b = 1.0;
+       double rgba[4] = {0.0, 0.0, 0.0, 0.0};
+
        attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_BG_COLOR);
        attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_BG_COLOR);
-       if (attr)
-               abc_css_color(&r, &g, &b, attr->value->data, attr->value->len);
+       if (attr && attr->value->len > 0)
+               abc_css_color(rgba, attr->value->data, attr->value->len);
 
 
-       cairo_set_source_rgb(cr, r, g, b);
+       cairo_set_source_rgba(cr, rgba[0], rgba[1], rgba[2], rgba[3]);
        cairo_rectangle(cr, 0, 0, w_text, h_text);
        cairo_fill(cr);
        cairo_stroke(cr);
 
        // draw text
        cairo_rectangle(cr, 0, 0, w_text, h_text);
        cairo_fill(cr);
        cairo_stroke(cr);
 
        // draw text
-       r = 0.0;
-       g = 0.0;
-       b = 0.0;
+       rgba[0] = 0.0;
+       rgba[1] = 0.0;
+       rgba[2] = 0.0;
+       rgba[3] = 1.0;
        attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_COLOR);
        if (attr)
        attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_COLOR);
        if (attr)
-               abc_css_color(&r, &g, &b, attr->value->data, attr->value->len);
+               abc_css_color(rgba, attr->value->data, attr->value->len);
 
 
-       cairo_set_source_rgb(cr, r, g, b);
+       cairo_set_source_rgba(cr, rgba[0], rgba[1], rgba[2], rgba[3]);
 
        attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT);
        if (attr)
 
        attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT);
        if (attr)
@@ -143,47 +101,35 @@ static int _render_draw_td(abc_render_t* render, abc_obj_t* obj, int width, int
        surface = NULL;
        cr = NULL;
 
        surface = NULL;
        cr = NULL;
 
-       float mvp[16];
-       __compute_mvp(mvp, 0, 0, 0);
-
-       scf_logd("%s, x: %d, y: %d, w: %d, h: %d\n", obj->text->data, obj->x, obj->y, obj->w, obj->h);
+       int view_x = x;
+       int view_y = y;
+       int view_w = w;
+       int view_h = h;
 
 
-       GLfloat vert_update[] =
+       switch (obj->overflow_type)
        {
        {
-                2.0 *  x      / (float)width  - 1.0,
-               -2.0 * (y + h) / (float)height + 1.0,
-
-                2.0 * (x + w) / (float)width  - 1.0,
-               -2.0 * (y + h) / (float)height + 1.0,
-
-                2.0 *  x      / (float)width  - 1.0,
-               -2.0 *  y      / (float)height + 1.0,
-
-                2.0 * (x + w) / (float)width  - 1.0,
-               -2.0 *  y      / (float)height + 1.0,
+               case ABC_OVERFLOW_HIDDEN:
+               case ABC_OVERFLOW_SCROLL:
+               case ABC_OVERFLOW_AUTO:
+                       abc_overflow_show(&view_x, &view_y, &view_w, &view_h,
+                                       obj->view_x,
+                                       obj->view_y, obj->view_w, obj->view_h);
+                       break;
+               default:
+                       break;
        };
 
        };
 
-       glUseProgram(program);
-       uniform_rgba = glGetUniformLocation(program, "tex_rgba");
-       uniform_mvp  = glGetUniformLocation(program, "mvp");
-
-       glUniformMatrix4fv(uniform_mvp, 1, GL_FALSE, mvp);
-
-       glActiveTexture(GL_TEXTURE0);
-       glBindTexture  (GL_TEXTURE_2D, texture_rgba);
-       glTexImage2D   (GL_TEXTURE_2D, 0, GL_RGBA, w_text, h_text, 0, GL_RGBA, GL_UNSIGNED_BYTE, bgra);
-       glUniform1i(uniform_rgba, 0);
-
-       // draw
-       glBindBuffer   (GL_ARRAY_BUFFER, buffers[0]);
-       glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vert_update), vert_update);
-
-       glBindVertexArray(vao);
+       scf_logd("%s, x: %d, y: %d, w: %d, h: %d\n", obj->text->data, obj->x, obj->y, obj->w, obj->h);
 
 
-       glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+       float mvp[16];
+       __compute_mvp(mvp, 0, 0, 0);
 
 
-       glBindVertexArray(0);
-       glUseProgram(0);
+       __render_text_gl(obj, bgra, w_text, h_text, width, height,
+                                x,
+                                        y,
+                                        w,
+                                        h,
+                                        view_x, view_y, view_w, view_h, mvp);
 
        free(bgra);
        return 0;
 
        free(bgra);
        return 0;
index ba04295c5a4a5b7adb75b53be2cc201b75d47cdc..04da387cb835214fcf5a8f15b9c3e78b49f724e5 100644 (file)
@@ -1,38 +1,5 @@
 #include"abc.h"
 
 #include"abc.h"
 
-static const char* vert_shader =
-       "#version 330 core\n"
-       "layout(location = 0) in vec4 position; \n"
-       "layout(location = 1) in vec2 a_texCoord; \n"
-       "out vec2 v_texCoord; \n"
-       "uniform mat4 mvp; \n"
-       "void main() { \n"
-               "gl_Position = mvp * position; \n"
-               "v_texCoord  = a_texCoord; \n"
-       "} \n";
-
-static const char* frag_shader =
-       "#version 330 core\n"
-       "in  vec2 v_texCoord; \n"
-       "out vec4 outputColor; \n"
-       "uniform sampler2D tex_rgba; \n"
-       "void main() { \n"
-       "    vec2 xy = v_texCoord; \n"
-       "    vec4 v  = texture2D(tex_rgba, xy).rgba; \n"
-       "    outputColor = vec4(v.b, v.g, v.r, v.a); \n"
-       "} \n";
-
-
-static GLuint program = 0;
-
-static GLuint vao = 0;
-static GLuint buffers[2]   = {0};
-static GLuint texture_rgba = 0;
-
-static GLuint uniform_mvp;
-static GLuint uniform_rgba;
-
-
 static int _render_fini_text(abc_render_t* render)
 {
        return 0;
 static int _render_fini_text(abc_render_t* render)
 {
        return 0;
@@ -41,7 +8,7 @@ static int _render_fini_text(abc_render_t* render)
 static int _draw_text_line(abc_obj_t* obj, const char* text,
                int x, int y, int w, int h, int width, int height,
                float  mvp[16],
 static int _draw_text_line(abc_obj_t* obj, const char* text,
                int x, int y, int w, int h, int width, int height,
                float  mvp[16],
-               double bcolor[3], double fcolor[3], int font_size, int bold, int italic, int line_type, double line_width, double scale)
+               double bcolor[4], double fcolor[4], int font_size, int bold, int italic, int line_type, double line_width, double scale)
 {
        int w_text = w * scale;
        int h_text = h * scale;
 {
        int w_text = w * scale;
        int h_text = h * scale;
@@ -57,8 +24,8 @@ static int _draw_text_line(abc_obj_t* obj, const char* text,
        surface = cairo_image_surface_create_for_data(bgra, CAIRO_FORMAT_ARGB32, w_text, h_text, w_text * 4);
        cr      = cairo_create(surface);
 
        surface = cairo_image_surface_create_for_data(bgra, CAIRO_FORMAT_ARGB32, w_text, h_text, w_text * 4);
        cr      = cairo_create(surface);
 
-       cairo_set_line_width(cr, 1);
-       cairo_set_source_rgba(cr, bcolor[0], bcolor[1], bcolor[2], 0.0);
+       cairo_set_line_width (cr, 1);
+       cairo_set_source_rgba(cr, bcolor[0], bcolor[1], bcolor[2], bcolor[3]);
        cairo_rectangle(cr, 0, 0, w_text, h_text);
        cairo_fill(cr);
        cairo_stroke(cr);
        cairo_rectangle(cr, 0, 0, w_text, h_text);
        cairo_fill(cr);
        cairo_stroke(cr);
@@ -68,7 +35,7 @@ static int _draw_text_line(abc_obj_t* obj, const char* text,
                cairo_select_font_face(cr, attr->value->data, italic, bold);
 
        cairo_set_font_size  (cr, font_size * scale);
                cairo_select_font_face(cr, attr->value->data, italic, bold);
 
        cairo_set_font_size  (cr, font_size * scale);
-       cairo_set_source_rgba(cr, fcolor[0], fcolor[1], fcolor[2], 1.0);
+       cairo_set_source_rgba(cr, fcolor[0], fcolor[1], fcolor[2], fcolor[3]);
 
        __draw_text(&extents, cr, text, 0, 0, obj->y_bearing * scale, line_type, line_width * scale);
 
 
        __draw_text(&extents, cr, text, 0, 0, obj->y_bearing * scale, line_type, line_width * scale);
 
@@ -79,52 +46,42 @@ static int _draw_text_line(abc_obj_t* obj, const char* text,
        surface = NULL;
        cr = NULL;
 
        surface = NULL;
        cr = NULL;
 
-       scf_logd("%s, x: %d, y: %d, w: %d, h: %d\n", obj->text->data, obj->x, obj->y, obj->w, obj->h);
-
-       GLfloat vert_update[] =
-       {
-                2.0 *  x      / (float)width  - 1.0,
-               -2.0 * (y + h) / (float)height + 1.0,
-
-                2.0 * (x + w) / (float)width  - 1.0,
-               -2.0 * (y + h) / (float)height + 1.0,
+       abc_obj_t* parent = obj->parent;
 
 
-                2.0 *  x      / (float)width  - 1.0,
-               -2.0 *  y      / (float)height + 1.0,
+       int view_x = x;
+       int view_y = y;
+       int view_w = w;
+       int view_h = h;
 
 
-                2.0 * (x + w) / (float)width  - 1.0,
-               -2.0 *  y      / (float)height + 1.0,
+       switch (obj->overflow_type)
+       {
+               case ABC_OVERFLOW_SCROLL:
+               case ABC_OVERFLOW_AUTO:
+               case ABC_OVERFLOW_HIDDEN:
+                       if (parent && (x < parent->view_x
+                                               || y < parent->view_y
+                                               || x + w > parent->view_x + parent->view_w
+                                               || y + h > parent->view_y + parent->view_h)) {
+
+                               abc_overflow_show(&view_x, &view_y, &view_w, &view_h,
+                                               parent->view_x,
+                                               parent->view_y,
+                                               parent->view_w - parent->border_right  - parent->padding_right,
+                                               parent->view_h - parent->border_bottom - parent->padding_bottom);
+                       }
+                       break;
+               default:
+                       break;
        };
 
        };
 
-       glUseProgram(program);
-       uniform_rgba = glGetUniformLocation(program, "tex_rgba");
-       uniform_mvp  = glGetUniformLocation(program, "mvp");
-
-       glUniformMatrix4fv(uniform_mvp, 1, GL_FALSE, mvp);
-
-       // board
-       glActiveTexture(GL_TEXTURE0);
-       glBindTexture  (GL_TEXTURE_2D, texture_rgba);
-       glTexImage2D   (GL_TEXTURE_2D, 0, GL_RGBA, w_text, h_text, 0, GL_RGBA, GL_UNSIGNED_BYTE, bgra);
-       glUniform1i(uniform_rgba, 0);
-
-       // draw
-       glBindBuffer   (GL_ARRAY_BUFFER, buffers[0]);
-       glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vert_update), vert_update);
-
-       glBindBuffer   (GL_ARRAY_BUFFER, buffers[1]);
-       glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(texture_array), texture_array);
-
-       glBindVertexArray(vao);
-
-       glEnable(GL_BLEND);
-       glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
-
-       glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
-       glDisable(GL_BLEND);
+       scf_logd("%s, x: %d, y: %d, w: %d, h: %d\n", obj->text->data, obj->x, obj->y, obj->w, obj->h);
 
 
-       glBindVertexArray(0);
-       glUseProgram(0);
+       __render_text_gl(obj, bgra, w_text, h_text, width, height,
+                                x,
+                                        y,
+                                        w,
+                                        h,
+                                        view_x, view_y, view_w, view_h, mvp);
 
        free(bgra);
        return 0;
 
        free(bgra);
        return 0;
@@ -135,32 +92,23 @@ static int _render_draw_text(abc_render_t* render, abc_obj_t* obj, int width, in
        if (obj->w <= 0 || obj->h <= 0)
                return 0;
 
        if (obj->w <= 0 || obj->h <= 0)
                return 0;
 
-       if (0 == program)
-               __init_program(&program, vert_shader, frag_shader);
-
-       if (0 == vao)
-               __init_buffers(&vao, buffers);
-
-       if (0 == texture_rgba)
-               __init_texture(&texture_rgba, GL_RGBA, obj->w, obj->h, NULL);
-
        abc_text_t*  t;
        abc_attr_t*  attr;
 
        abc_text_t*  t;
        abc_attr_t*  attr;
 
-       double bcolor[3] = {0.0};
-       double fcolor[3] = {0.0};
+       double bcolor[4] = {0.0, 0.0, 0.0, 0.0};
+       double fcolor[4] = {0.0, 0.0, 0.0, 1.0};
 
        double size   = 16.0;
        int    bold   = CAIRO_FONT_WEIGHT_NORMAL;
        int    italic = CAIRO_FONT_SLANT_NORMAL;
 
 
        double size   = 16.0;
        int    bold   = CAIRO_FONT_WEIGHT_NORMAL;
        int    italic = CAIRO_FONT_SLANT_NORMAL;
 
-       attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_BG_COLOR);
-       if (attr)
-               abc_css_color(bcolor, bcolor + 1, bcolor + 2, attr->value->data, attr->value->len);
+       attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_BG_COLOR);
+       if (attr && attr->value->len > 0)
+               abc_css_color(bcolor, attr->value->data, attr->value->len);
 
        attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_COLOR);
        if (attr)
 
        attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_COLOR);
        if (attr)
-               abc_css_color(fcolor, fcolor + 1, fcolor + 2, attr->value->data, attr->value->len);
+               abc_css_color(fcolor, attr->value->data, attr->value->len);
 
        attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_SIZE);
        if (attr)
 
        attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_SIZE);
        if (attr)
index a0a64affcd766460cd8586ff8fe2169f316977ea..50a81fa19a2803b55e3ba7d1cf1742f19983d318 100644 (file)
--- a/ui/main.c
+++ b/ui/main.c
@@ -50,7 +50,7 @@ static gboolean render(GtkGLArea* self, GdkGLContext* context, gpointer user_dat
        glClearColor(1.0, 1.0, 1.0, 1.0);
        glClear(GL_COLOR_BUFFER_BIT);
 
        glClearColor(1.0, 1.0, 1.0, 1.0);
        glClear(GL_COLOR_BUFFER_BIT);
 
-       int ret = abc_layout_root(NULL, root, width, height);
+       int ret = abc_layout_root(ctx, root, width, height);
 
        ret = abc_render_root(ctx, root, width, height);
 
 
        ret = abc_render_root(ctx, root, width, height);
 
@@ -88,32 +88,25 @@ static int __do_button_move(abc_ctx_t* ctx, int x, int y)
                gdk_window_set_cursor(window, cursor);
                g_object_unref(cursor);
 
                gdk_window_set_cursor(window, cursor);
                g_object_unref(cursor);
 
+               abc_css_clear(prev, ABC_CSS_LINK, ABC_CSS_ACTIVE);
                if (prev->visited)
                if (prev->visited)
-                       prev->css_pse_type = ABC_CSS_VISITED;
+                       abc_css_active(prev, ABC_CSS_VISITED);
                else
                else
-                       prev->css_pse_type = ABC_CSS_LINK;
-
-               abc_css_active(prev);
+                       abc_css_active(prev, ABC_CSS_LINK);
 
                prev->mouse_down_x = -1;
                prev->mouse_down_y = -1;
                prev->mouse_move_x = -1;
                prev->mouse_move_y = -1;
 
 
                prev->mouse_down_x = -1;
                prev->mouse_down_y = -1;
                prev->mouse_move_x = -1;
                prev->mouse_move_y = -1;
 
-               if (ABC_HTML == prev->type)
-                       scf_logw("prev: %p mouse down_x: %d, down_y: %d, move_x: %d, move_y: %d\n", prev,
-                                       prev->mouse_down_x,
-                                       prev->mouse_down_y,
-                                       prev->mouse_move_x,
-                                       prev->mouse_move_y);
-
+               prev->css_use = 0;
                prev->clicked = 0;
                ret = 1;
        }
 
        if (obj) {
                prev->clicked = 0;
                ret = 1;
        }
 
        if (obj) {
-               scf_logd("obj: %s, type: %d, x: %d, y: %d, w: %d, h: %d, event x: %d, y: %d\n",
-                               obj->keys[0], obj->type, obj->x, obj->y, obj->w, obj->h, x, y);
+               scf_logi("obj: %p, type: %d, x: %d, y: %d, w: %d, h: %d, event x: %d, y: %d\n",
+                               obj, obj->type, obj->x, obj->y, obj->w, obj->h, x, y);
 
                switch (obj->type)
                {
 
                switch (obj->type)
                {
@@ -153,18 +146,19 @@ static int __do_button_move(abc_ctx_t* ctx, int x, int y)
                                break;
                };
 
                                break;
                };
 
-               if (ABC_HTML == obj->type)
+               if (ABC_HTML_IMG == obj->type)
                        scf_logw("obj: %p, mouse down_x: %d, down_y: %d, move_x: %d, move_y: %d\n", obj,
                                        obj->mouse_down_x,
                                        obj->mouse_down_y,
                                        obj->mouse_move_x,
                                        obj->mouse_move_y);
 
                        scf_logw("obj: %p, mouse down_x: %d, down_y: %d, move_x: %d, move_y: %d\n", obj,
                                        obj->mouse_down_x,
                                        obj->mouse_down_y,
                                        obj->mouse_move_x,
                                        obj->mouse_move_y);
 
-               obj->css_pse_type = ABC_CSS_HOVER;
+               abc_css_clear(obj, ABC_CSS_LINK, ABC_CSS_ACTIVE);
 
 
-               ret |= abc_css_active(obj);
+               ret |= abc_css_active(obj, ABC_CSS_HOVER);
 
                ctx->current->current = obj;
 
                ctx->current->current = obj;
+               obj->css_use = 0;
        }
 
        return ret;
        }
 
        return ret;
@@ -220,10 +214,9 @@ static int __do_button_release(abc_ctx_t* ctx, int x, int y)
        obj->mouse_move_x = -1;
        obj->mouse_move_y = -1;
 
        obj->mouse_move_x = -1;
        obj->mouse_move_y = -1;
 
-       obj->visited      = 1;
-       obj->css_pse_type = ABC_CSS_VISITED;
-
-       abc_css_active(obj);
+       abc_css_clear (obj, ABC_CSS_LINK, ABC_CSS_ACTIVE);
+       abc_css_active(obj, ABC_CSS_VISITED);
+       obj->css_use = 0;
 
        scf_logd("obj: %s, x: %d, y: %d, w: %d, h: %d, event x: %d, y: %d\n",
                        obj->keys[0], obj->x, obj->y, obj->w, obj->h, x, y);
 
        scf_logd("obj: %s, x: %d, y: %d, w: %d, h: %d, event x: %d, y: %d\n",
                        obj->keys[0], obj->x, obj->y, obj->w, obj->h, x, y);
@@ -391,9 +384,10 @@ static gboolean button_press_event(GtkWidget* self, GdkEventButton* event, gpoin
                                                obj->mouse_move_x,
                                                obj->mouse_move_y);
 
                                                obj->mouse_move_x,
                                                obj->mouse_move_y);
 
-                       obj->css_pse_type = ABC_CSS_ACTIVE;
+                       abc_css_clear (obj, ABC_CSS_LINK, ABC_CSS_ACTIVE);
+                       abc_css_active(obj, ABC_CSS_ACTIVE);
+                       obj->css_use = 0;
 
 
-                       abc_css_active(obj);
                        gtk_gl_area_queue_render(ctx->gl_area);
                }
        }
                        gtk_gl_area_queue_render(ctx->gl_area);
                }
        }