html: use an array to save label's attrs, now get it O(1), master
authoryu.dongliang <18588496441@163.com>
Sat, 16 May 2026 11:14:58 +0000 (19:14 +0800)
committeryu.dongliang <18588496441@163.com>
Sat, 16 May 2026 11:15:00 +0000 (19:15 +0800)
css : support complex pse class (element) chain for HTML object.

22 files changed:
examples/overflow.html [new file with mode: 0644]
examples/p_pse_class.html
examples/position.html [new file with mode: 0644]
html/abc_css.c
html/abc_css_border.c
html/abc_css_length.c
html/abc_css_position.c
html/abc_html.c
html/abc_html.h
html/abc_obj.c
html/abc_obj.h
ui/Makefile
ui/__render_bg_image.c
ui/abc_layout.c
ui/abc_layout_div.c
ui/abc_layout_h1.c
ui/abc_layout_img.c
ui/abc_layout_text.c
ui/abc_render.c
ui/abc_render_audio.c
ui/abc_render_img.c
ui/main.c

diff --git a/examples/overflow.html b/examples/overflow.html
new file mode 100644 (file)
index 0000000..89fb8f7
--- /dev/null
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<style>
+div {
+       background-color:gray;
+       width: 200px;
+       height: 50px;
+       border: 1px dotted black;
+       overflow: visible;
+}
+</style>
+</head>
+
+<body>
+
+<div id="overflowTest">
+<p>这里的文本内容会溢出元素框。</p>
+<p>这里的文本内容会溢出元素框。</p>
+<p>这里的文本内容会溢出元素框。</p>
+</div>
+
+</body>
+</html>
index 2e1e5eaa6d8f381857d23cc42970993070757853..7e13772db6dc2f4b81fb68a48a831ccf37ac6c01 100644 (file)
@@ -12,12 +12,20 @@ p:first-child b
 {
        color:red;
 }
 {
        color:red;
 }
+
+.violet:first-child b
+{
+       color:violet;
+}
 </style>
 </head>
 
 <body>
 </style>
 </head>
 
 <body>
+<p class="violet">I am a <b>strong</b> man. I am a <b>strong</b> man.</p>
+
 <p>I am a <b>strong</b> man. I am a <b>strong</b> man.</p>
 <p>I am a <b>strong</b> man. I am a <b>strong</b> man.</p>
 <p>I am a <b>strong</b> man. I am a <b>strong</b> man.</p>
 <p>I am a <b>strong</b> man. I am a <b>strong</b> man.</p>
+
 <p><b>注意:</b> 当 :first-child 作用于 IE8 以及更早版本的浏览器, !DOCTYPE 必须已经定义.</p>
 </body>
 </html>
 <p><b>注意:</b> 当 :first-child 作用于 IE8 以及更早版本的浏览器, !DOCTYPE 必须已经定义.</p>
 </body>
 </html>
diff --git a/examples/position.html b/examples/position.html
new file mode 100644 (file)
index 0000000..59f698f
--- /dev/null
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<style>
+h2.pos_left
+{
+       position:relative;
+       left:-10px;
+}
+
+h2.pos_right
+{
+       position:relative;
+       left:10px;
+}
+</style>
+</head>
+
+<body>
+<h2>这是位于正常位置的标题</h2>
+<h2 class="pos_left">这个标题相对于其正常位置向左移动</h2>
+<h2 class="pos_right">这个标题相对于其正常位置向右移动</h2>
+<p>相对定位会按照元素的原始位置对该元素进行移动。</p>
+<p>样式 "left:-20px" 从元素的原始左侧位置减去 20 像素。</p>
+<p>样式 "left:20px" 向元素的原始左侧位置增加 20 像素。</p>
+</body>
+</html>
index cb71c3d11d6ee45b9be5053889651c1e6fdff765..25aeac1f959a260f573b861cbfc2c99b884838dc 100644 (file)
@@ -187,6 +187,7 @@ static int __css_parse_attr2(abc_obj_t* css, abc_obj_t* obj, const html_attr_t*
 
        int i;
        int j;
 
        int i;
        int j;
+       int k;
        if (attrs && n_attrs > 0) {
                for (i = 0; i < n_attrs; i++) {
 
        if (attrs && n_attrs > 0) {
                for (i = 0; i < n_attrs; i++) {
 
@@ -202,22 +203,16 @@ static int __css_parse_attr2(abc_obj_t* css, abc_obj_t* obj, const html_attr_t*
        return -EINVAL;
 
 found:
        return -EINVAL;
 
 found:
-       for (l   = scf_list_head(&obj->attrs); l != scf_list_sentinel(&obj->attrs); l = scf_list_next(l)) {
-               attr = scf_list_data(l, abc_obj_t, list);
-
-               for (j = 0; attr->keys[j]; j++) {
-                       if (!__html_strcmp(attr->keys[j], key->data))
-                               break;
-               }
-       }
+       k = attrs[i].type;
+       assert(k >= ABC_HTML_ATTR_ID && k < ABC_HTML_CSS_NB);
 
 
-       if (l == scf_list_sentinel(&obj->attrs)) {
+       attr = obj->attrs[k - ABC_HTML_ATTR_ID];
+       if (!attr) {
                int ret = __html_add_attr(obj, attrs[i].type, attrs[i].names, attrs[i].value, attrs[i].flags);
                if (ret < 0)
                        return ret;
 
                int ret = __html_add_attr(obj, attrs[i].type, attrs[i].names, attrs[i].value, attrs[i].flags);
                if (ret < 0)
                        return ret;
 
-               l    = scf_list_tail(&obj->attrs);
-               attr = scf_list_data(l, abc_obj_t, list);
+               attr = obj->attrs[k - ABC_HTML_ATTR_ID];
        }
 
        scf_string_free(key);
        }
 
        scf_string_free(key);
@@ -738,91 +733,74 @@ static void __css_set_attr(abc_obj_t* obj, abc_obj_t* attr)
        };
 }
 
        };
 }
 
-static void __css_set_pse(abc_obj_t* obj, abc_obj_t* pse, int colon)
+static int __css_set_pse_dynamic(abc_obj_t* obj, abc_obj_t* pse)
 {
 {
-       scf_string_t*  s;
-       scf_list_t*    l;
-       abc_obj_t*     attr;
-       abc_obj_t*     attr2;
-       abc_obj_t*     pse2;
-
-       if (scf_list_empty(&pse->attrs))
-               return;
+       scf_list_t*  l;
+       abc_obj_t*   pse2;
 
 
-       if (colon > 0 && ':' == pse->text->data[colon - 1])
-               colon--;
+       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);
 
 
-       char* key = pse->text->data + colon;
-       int   len = pse->text->len  - colon;
+               if (pse2->type == pse->type
+                               && pse2->text->len == pse->text->len
+                               && !__html_strcmp(pse2->text->data, pse->text->data))
+                       break;
+       }
 
 
-       pse2 = abc_obj_get_attr2(obj, key, len);
-       if (!pse2) {
+       if (l == scf_list_sentinel(&obj->css_pse_rules))
+       {
                pse2 = abc_obj_alloc(pse->file, pse->line, pse->pos, pse->type);
                if (!pse2)
                pse2 = abc_obj_alloc(pse->file, pse->line, pse->pos, pse->type);
                if (!pse2)
-                       return;
+                       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;
 
                pse2->flags = pse->flags;
                pse2->keys  = pse->keys;
-       }
-
-       s = scf_string_clone(pse->text);
-       if (!s)
-               return;
-
-       if (pse2->text)
-               scf_string_free(pse2->text);
-
-       pse2->text = s;
-
-       for (l = scf_list_head(&pse->attrs); l != scf_list_sentinel(&pse->attrs); l = scf_list_next(l)) {
-               attr = scf_list_data(l, abc_obj_t, list);
-
-               if (!attr->value || 0 == attr->value->len)
-                       continue;
 
 
-               attr2 = abc_obj_alloc(attr->file, attr->line, attr->pos, attr->type);
-               if (!attr2)
-                       return;
+               scf_list_add_tail(&obj->css_pse_rules, &pse2->list);
+       }
 
 
-               attr2->value = scf_string_clone(attr->value);
-               if (!attr2->value) {
-                       abc_obj_free(attr2);
-                       return;
-               }
+       int ret = abc_obj_copy_attrs(pse2, pse);
+       if (ret < 0)
+               return ret;
 
 
-               attr2->keys  = attr->keys;
-               attr2->flags = attr->flags;
+       switch (pse->css_pse_type) {
+               case ABC_CSS_LINK:
+                       abc_obj_set_css(obj, pse);
+                       break;
+               default:
+                       break;
+       };
 
 
-               scf_list_add_tail(&pse2->attrs, &attr2->list);
+       scf_slist_clear(pse2->css_pse_chain, pse_link_t, next, free);
 
 
-               switch (pse->css_pse_type)
-               {
-                       case ABC_CSS_FIRST_CHILD:
-                       case ABC_CSS_LINK:
-                               __css_set_attr(obj, attr);
-                               break;
-                       default:
-                               break;
-               };
-       }
+       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)
 {
 }
 
 static void __css_merge(abc_obj_t* dst, abc_obj_t* src)
 {
-       scf_list_t*  l;
-       abc_obj_t*   s;
-       abc_obj_t*   d;
+       abc_obj_t*  s;
+       abc_obj_t*  d;
+       int i;
 
 
-       for (l = scf_list_head(&src->attrs); l != scf_list_sentinel(&src->attrs); ) {
-               s  = scf_list_data(l, abc_obj_t, list);
-               l  = scf_list_next(l);
+       for (i = 0; i < sizeof(src->attrs) / sizeof(src->attrs[0]); i++) {
+               s  = src->attrs[i];
 
 
-               d = abc_obj_get_attr(dst, s->type);
+               if (!s || !s->value || 0 == s->value->len)
+                       continue;
+
+               d = dst->attrs[i];
                if (d)
                        SCF_XCHG(d->value, s->value);
                else {
                if (d)
                        SCF_XCHG(d->value, s->value);
                else {
-                       scf_list_del(&s->list);
-                       scf_list_add_tail(&dst->attrs, &s->list);
+                       dst->attrs[i] = s;
+                       src->attrs[i] = NULL;
                }
        }
 }
                }
        }
 }
@@ -941,6 +919,7 @@ static abc_obj_t* __css_select_by_key(abc_obj_t* css, abc_obj_t* current, scf_ve
        scf_list_t*  l;
        abc_obj_t*   tmp;
        abc_obj_t*   pse;
        scf_list_t*  l;
        abc_obj_t*   tmp;
        abc_obj_t*   pse;
+       pse_link_t*  pseLink;
 
        assert(next >= 0 && next < vec->size);
 
 
        assert(next >= 0 && next < vec->size);
 
@@ -1020,6 +999,17 @@ static abc_obj_t* __css_select_by_key(abc_obj_t* css, abc_obj_t* current, scf_ve
                        if (!current)
                                return NULL;
 
                        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;
@@ -1037,6 +1027,8 @@ static abc_obj_t* __css_select_by_attr(abc_obj_t* css, abc_obj_t* current, scf_v
        scf_list_t*  l;
        abc_obj_t*   tmp;
        abc_obj_t*   attr;
        scf_list_t*  l;
        abc_obj_t*   tmp;
        abc_obj_t*   attr;
+       abc_obj_t*   pse;
+       pse_link_t*  pseLink;
 
        assert(next >= 0 && next < vec->size);
 
 
        assert(next >= 0 && next < vec->size);
 
@@ -1100,6 +1092,45 @@ static abc_obj_t* __css_select_by_attr(abc_obj_t* css, abc_obj_t* current, scf_v
 
                        current = tmp;
                        break;
 
                        current = tmp;
                        break;
+
+               case ':':
+                       assert(next - 1 >= 0 && next - 1 < vec->size);
+
+                       scf_logd("current: %s, key: %.*s, j: %d, next: %s\n", current->keys[0], len, key, j, css->text->data + j);
+
+                       k = (intptr_t) vec->data[next - 1];
+                       if (k <= j)
+                               return NULL;
+
+                       current = __css_select_by_attr(css, current, vec, next - 1, type, key, len);
+                       if (!current)
+                               return NULL;
+
+                       pse = abc_obj_get_attr2(current, css->text->data + j, k - j);
+                       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;
+
+                       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;
                default:
                        attr = abc_obj_get_attr(current, type);
 
                default:
                        attr = abc_obj_get_attr(current, type);
 
@@ -1116,7 +1147,6 @@ static int __css_use_complex(abc_obj_t* css, abc_obj_t* obj)
        scf_vector_t* vec;
        abc_obj_t*    current = obj;
 
        scf_vector_t* vec;
        abc_obj_t*    current = obj;
 
-       int colon = -1;
        int c;
        int i;
        int j = css->text->len;
        int c;
        int i;
        int j = css->text->len;
@@ -1130,6 +1160,7 @@ static int __css_use_complex(abc_obj_t* css, abc_obj_t* obj)
                goto end;
 
        css->css_pse_type = 0;
                goto end;
 
        css->css_pse_type = 0;
+       scf_slist_clear(css->css_pse_chain, pse_link_t, next, free);
 
        for (i = css->text->len - 1; i >= 0; i--) {
                c  = css->text->data[i];
 
        for (i = css->text->len - 1; i >= 0; i--) {
                c  = css->text->data[i];
@@ -1154,9 +1185,6 @@ static int __css_use_complex(abc_obj_t* css, abc_obj_t* obj)
                                break;
 
                        case ':':
                                break;
 
                        case ':':
-                               if (colon < 0)
-                                       colon = i;
-
                                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) {
@@ -1194,13 +1222,14 @@ static int __css_use_complex(abc_obj_t* css, abc_obj_t* obj)
                }
        }
 
                }
        }
 
-       if (colon < 0)
+       if (css->css_pse_type < ABC_CSS_PSE_STATIC)
                abc_obj_set_css(obj, css);
        else
                abc_obj_set_css(obj, css);
        else
-               __css_set_pse(obj, css, colon);
+               __css_set_pse_dynamic(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;
 }
@@ -1264,15 +1293,16 @@ int abc_css_use(abc_html_t* html, abc_obj_t* obj)
                if (ret < 0 && EOF != ret)
                        return ret;
 
                if (ret < 0 && EOF != ret)
                        return ret;
 
-               for (l   = scf_list_head(&css->attrs); l != scf_list_sentinel(&css->attrs); ) {
-                       attr = scf_list_data(l, abc_obj_t, list);
-                       l    = scf_list_next(l);
+               int i;
+               for (i   = 0; i < sizeof(css->attrs) / sizeof(css->attrs[0]); i++) {
+                       attr = css->attrs[i];
+                       if (!attr)
+                               continue;
 
                        __css_set_attr(obj, attr);
 
 
                        __css_set_attr(obj, attr);
 
-                       scf_list_del(&attr->list);
                        abc_obj_free(attr);
                        abc_obj_free(attr);
-                       attr = NULL;
+                       css->attrs[i] = NULL;
                }
        }
 
                }
        }
 
@@ -1280,13 +1310,41 @@ int abc_css_use(abc_html_t* html, abc_obj_t* obj)
 }
 
 void abc_obj_set_css(abc_obj_t* obj, abc_obj_t* css)
 }
 
 void abc_obj_set_css(abc_obj_t* obj, abc_obj_t* css)
+{
+       abc_obj_t*  attr;
+       int i;
+
+       for (i   = 0; i < sizeof(css->attrs) / sizeof(css->attrs[0]); i++) {
+               attr = css->attrs[i];
+
+               if (attr)
+                       __css_set_attr(obj, attr);
+       }
+}
+
+int abc_css_active(abc_obj_t* obj)
 {
        scf_list_t*  l;
 {
        scf_list_t*  l;
-       abc_obj_t*   attr;
+       abc_obj_t*   css;
+       pse_link_t*  pseLink;
 
 
-       for (l   = scf_list_head(&css->attrs); l != scf_list_sentinel(&css->attrs); l = scf_list_next(l)) {
-               attr = scf_list_data(l, abc_obj_t, list);
+       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);
 
 
-               __css_set_attr(obj, attr);
+               pseLink = css->css_pse_chain;
+               while (pseLink) {
+                       if (pseLink->obj->css_pse_type != pseLink->pse_type)
+                               break;
+
+                       pseLink = pseLink->next;
+               }
+
+               if (!pseLink) {
+                       abc_obj_set_css(obj, css);
+                       n++;
+               }
        }
        }
+
+       return n;
 }
 }
index adfc471839126bffae99e9caba79c4326b05af5b..47b8f9a41dd7b2b9d040b4f0296e794ce86a6c5a 100644 (file)
@@ -38,7 +38,7 @@ int abc_css_border(double* r, double* g, double* b, int* width, int* type, abc_o
        *r = 0.0;
        *g = 0.0;
        *b = 0.0;
        *r = 0.0;
        *g = 0.0;
        *b = 0.0;
-       *width = 1;
+       *width = 0;
        *type  = ABC_BORDER_SOLID;
 
        const uint8_t* p    = NULL;
        *type  = ABC_BORDER_SOLID;
 
        const uint8_t* p    = NULL;
@@ -141,15 +141,15 @@ int abc_css_margin(abc_obj_t* obj)
        double g = 0.0;
        double b = 0.0;
 
        double g = 0.0;
        double b = 0.0;
 
-       abc_obj_t* attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_MARGIN);
+       abc_obj_t* attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_MARGIN);
        if (attr)
                margin = atoi(attr->value->data);
 
        if (attr)
                margin = atoi(attr->value->data);
 
-       attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_BORDER);
+       attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_BORDER);
        if (attr)
                abc_css_border(&r, &g, &b, &border, &type, obj, attr->value->data);
 
        if (attr)
                abc_css_border(&r, &g, &b, &border, &type, obj, attr->value->data);
 
-       attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_PADDING);
+       attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_PADDING);
        if (attr)
                padding = atoi(attr->value->data);
 
        if (attr)
                padding = atoi(attr->value->data);
 
index 45d2c7e7a676995f4c4fcd79b460dc38e1a51354..2a4f47949beb4ecfd071a7b6bde350e44ac4288d 100644 (file)
@@ -7,6 +7,8 @@ int abc_css_length(abc_obj_t* obj, const uint8_t* str, int len)
 
        int     x       = 0;
        double  value   = 0.0;
 
        int     x       = 0;
        double  value   = 0.0;
+       double  decimal = 0.1;
+       int     neg     = 0;
        int     dot     = 0;
        int     percent = 0;
        int     prev    = 0;
        int     dot     = 0;
        int     percent = 0;
        int     prev    = 0;
@@ -15,8 +17,10 @@ int abc_css_length(abc_obj_t* obj, const uint8_t* str, int len)
        do {
                c = *str;
 
        do {
                c = *str;
 
-               if ('.' == c)
-                       dot = 10;
+               if ('-' == c)
+                       neg++;
+               else if ('.' == c)
+                       dot++;
                else if ('%' == c)
                        percent++;
 
                else if ('%' == c)
                        percent++;
 
@@ -26,9 +30,9 @@ int abc_css_length(abc_obj_t* obj, const uint8_t* str, int len)
 
                } else if ('0' <= c && '9' >= c) {
 
 
                } else if ('0' <= c && '9' >= c) {
 
-                       if (dot > 0) {
-                               value += (c - '0') / (double)dot;
-                               dot   *= 10;
+                       if (dot) {
+                               value   += (c - '0') * decimal;
+                               decimal *= 0.1;
                        } else {
                                value *= 10.0;
                                value += c - '0';
                        } else {
                                value *= 10.0;
                                value += c - '0';
@@ -39,12 +43,16 @@ int abc_css_length(abc_obj_t* obj, const uint8_t* str, int len)
                        if (' ' == prev || '\t' == prev || '\r' == prev || '\n' == prev)
                                goto next;
 
                        if (' ' == prev || '\t' == prev || '\r' == prev || '\n' == prev)
                                goto next;
 
+                       if (neg)
+                               value = -value;
+
                        if (percent)
                                x = value * 0.01 * len;
                        else if (unit) {
                                // for other css units, ignore
                                x = value;
                        if (percent)
                                x = value * 0.01 * len;
                        else if (unit) {
                                // for other css units, ignore
                                x = value;
-                       }
+                       } else
+                               x = value;
 
                        unit    = NULL;
                        value   = 0.0;
 
                        unit    = NULL;
                        value   = 0.0;
index 52cb844befe853477bd9e89cca551e8378c10554..bd82a81f0f4d255caad43e36ec56d431cd15c76e 100644 (file)
@@ -35,7 +35,7 @@ static void __css_pos_value(float* value, const char* name, size_t name_len)
        }
 }
 
        }
 }
 
-int abc_css_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)
 {
        *x = 0.5 - w / 2;
        *y = 0.5 - h / 2;
 {
        *x = 0.5 - w / 2;
        *y = 0.5 - h / 2;
@@ -118,3 +118,20 @@ next:
 
        return 0;
 }
 
        return 0;
 }
+
+int abc_css_position(const uint8_t* str)
+{
+       if (!__html_strcmp(str, "relative"))
+               return ABC_POSITION_RELATIVE;
+
+       else if (!__html_strcmp(str, "absolute"))
+               return ABC_POSITION_ABSOLUTE;
+
+       else if (!__html_strcmp(str, "fixed"))
+               return ABC_POSITION_FIXED;
+
+       else if (!__html_strcmp(str, "sticky"))
+               return ABC_POSITION_STICKY;
+
+       return ABC_POSITION_STATIC;
+}
index f2f27158aee1cbe0a66f902302b0559574a486b7..bd87a4f74cb6521aa64d1a320362b3fc54e8bfae 100644 (file)
@@ -11,6 +11,14 @@ static char* margin_keys[]     = {"margin",     "外边距",   NULL};
 static char* border_keys[]     = {"border",     "边框",     NULL};
 static char* padding_keys[]    = {"padding",    "内边距",   NULL};
 
 static char* border_keys[]     = {"border",     "边框",     NULL};
 static char* padding_keys[]    = {"padding",    "内边距",   NULL};
 
+static char* overflow_keys[]   = {"overflow",   NULL};
+
+static char* position_keys[]   = {"position",   "定位",     NULL};
+static char* top_keys[]        = {"top",        "上",       NULL};
+static char* bottom_keys[]     = {"bottom",     "下",       NULL};
+static char* left_keys[]       = {"left",       "左",       NULL};
+static char* right_keys[]      = {"right",      "右",       NULL};
+
 static char* font_keys[]       = {"font",       "字体",     NULL};
 static char* font_size_keys[]  = {"font-size",  "字号",     NULL};
 static char* font_color_keys[] = {"font-color", "字体颜色", "color", "颜色", NULL};
 static char* font_keys[]       = {"font",       "字体",     NULL};
 static char* font_size_keys[]  = {"font-size",  "字号",     NULL};
 static char* font_color_keys[] = {"font-color", "字体颜色", "color", "颜色", NULL};
@@ -141,8 +149,16 @@ static html_attr_t  body_attrs[] =
        {border_keys,     #border,     ABC_HTML_ATTR_BORDER,          ABC_HTML_FLAG_SHOW}, \
        {padding_keys,    #padding,    ABC_HTML_ATTR_PADDING,         ABC_HTML_FLAG_SHOW}, \
        \
        {border_keys,     #border,     ABC_HTML_ATTR_BORDER,          ABC_HTML_FLAG_SHOW}, \
        {padding_keys,    #padding,    ABC_HTML_ATTR_PADDING,         ABC_HTML_FLAG_SHOW}, \
        \
-       {width_keys,       "",         ABC_HTML_ATTR_WIDTH,           ABC_HTML_FLAG_SHOW}, \
-       {height_keys,      "",         ABC_HTML_ATTR_HEIGHT,          ABC_HTML_FLAG_SHOW},
+       {overflow_keys,   "",          ABC_HTML_ATTR_OVERFLOW,        ABC_HTML_FLAG_SHOW}, \
+       \
+       {position_keys,   "",          ABC_HTML_ATTR_POSITION,        ABC_HTML_FLAG_SHOW}, \
+       {top_keys,        "",          ABC_HTML_ATTR_TOP,             ABC_HTML_FLAG_SHOW}, \
+       {bottom_keys,     "",          ABC_HTML_ATTR_BOTTOM,          ABC_HTML_FLAG_SHOW}, \
+       {left_keys,       "",          ABC_HTML_ATTR_LEFT,            ABC_HTML_FLAG_SHOW}, \
+       {right_keys,      "",          ABC_HTML_ATTR_RIGHT,           ABC_HTML_FLAG_SHOW}, \
+       \
+       {width_keys,      "",          ABC_HTML_ATTR_WIDTH,           ABC_HTML_FLAG_SHOW}, \
+       {height_keys,     "",          ABC_HTML_ATTR_HEIGHT,          ABC_HTML_FLAG_SHOW},
 
 #define ABC_CSS_SELECTOR() \
        {style_keys,       "",         ABC_HTML_ATTR_STYLE,           ABC_HTML_FLAG_SHOW}, \
 
 #define ABC_CSS_SELECTOR() \
        {style_keys,       "",         ABC_HTML_ATTR_STYLE,           ABC_HTML_FLAG_SHOW}, \
@@ -176,6 +192,16 @@ static html_attr_t  body_attrs[] =
        ABC_CSS_TEXT(left, )
 };
 
        ABC_CSS_TEXT(left, )
 };
 
+static html_attr_t  div_attrs[] =
+{
+       ABC_CSS_BOX(2px, , 2px)
+       ABC_CSS_SELECTOR()
+       ABC_CSS_BACK_GROUND()
+
+       ABC_CSS_FONT(SimSong, 16, black, )
+       ABC_CSS_TEXT(left, )
+};
+
 static html_attr_t  h1_attrs[] =
 {
        ABC_CSS_BOX(2px, , 2px)
 static html_attr_t  h1_attrs[] =
 {
        ABC_CSS_BOX(2px, , 2px)
@@ -441,7 +467,7 @@ static html_label_t  html_labels[] =
        {head_keys,       ABC_HTML_HEAD,     0,                            NULL,          ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
        {title_keys,      ABC_HTML_TITLE,    0,                            NULL,          ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
        {body_keys,       ABC_HTML_BODY,     abc_number_of(body_attrs),    body_attrs,    ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
        {head_keys,       ABC_HTML_HEAD,     0,                            NULL,          ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
        {title_keys,      ABC_HTML_TITLE,    0,                            NULL,          ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
        {body_keys,       ABC_HTML_BODY,     abc_number_of(body_attrs),    body_attrs,    ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
-       {div_keys,        ABC_HTML_DIV,      abc_number_of(body_attrs),    body_attrs,    ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
+       {div_keys,        ABC_HTML_DIV,      abc_number_of(div_attrs),     div_attrs,     ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
 
        {h1_keys,         ABC_HTML_H1,       abc_number_of(h1_attrs),      h1_attrs,      ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
        {h2_keys,         ABC_HTML_H2,       abc_number_of(h2_attrs),      h2_attrs,      ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
 
        {h1_keys,         ABC_HTML_H1,       abc_number_of(h1_attrs),      h1_attrs,      ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
        {h2_keys,         ABC_HTML_H2,       abc_number_of(h2_attrs),      h2_attrs,      ABC_HTML_FLAG_CLOSE | ABC_HTML_FLAG_SHOW},
@@ -530,6 +556,9 @@ 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)
+               return -EINVAL;
+
        abc_obj_t* attr = abc_obj_alloc(NULL, 0, 0, type);
        if (!attr)
                return -ENOMEM;
        abc_obj_t* attr = abc_obj_alloc(NULL, 0, 0, type);
        if (!attr)
                return -ENOMEM;
@@ -544,7 +573,11 @@ int __html_add_attr(abc_obj_t* obj, int type, char** names, const char* value, i
 
        attr->flags = flags;
 
 
        attr->flags = flags;
 
-       scf_list_add_tail(&obj->attrs, &attr->list);
+       int i = type - ABC_HTML_ATTR_ID;
+       if (obj->attrs[i])
+               abc_obj_free(obj->attrs[i]);
+
+       obj->attrs[i] = attr;
        return 0;
 }
 
        return 0;
 }
 
@@ -597,8 +630,10 @@ static int __html_load_attrs(abc_obj_t* obj, html_attr_t* attrs, int n_attrs)
 
        } else if (obj->parent) {
 
 
        } else if (obj->parent) {
 
-               for (l   = scf_list_head(&obj->parent->attrs); l != scf_list_sentinel(&obj->parent->attrs); l = scf_list_next(l)) {
-                       attr = scf_list_data(l, abc_obj_t, list);
+               for (i   = 0; i < sizeof(obj->parent->attrs) / sizeof(obj->parent->attrs[0]); i++) {
+                       attr = obj->parent->attrs[i];
+                       if (!attr)
+                               continue;
 
                        ret = __html_add_attr(obj, attr->type, attr->keys, attr->value->data, 0);
                        if (ret < 0)
 
                        ret = __html_add_attr(obj, attr->type, attr->keys, attr->value->data, 0);
                        if (ret < 0)
@@ -1043,22 +1078,23 @@ static int __html_parse_attr2(abc_html_t* html, abc_obj_t* obj, const html_attr_
        free(c);
        c = NULL;
 
        free(c);
        c = NULL;
 
-       scf_list_t* l;
        abc_obj_t*  attr;
        abc_obj_t*  attr;
+       int i;
+       int j;
 
 
-       for (l   = scf_list_head(&obj->attrs); l != scf_list_sentinel(&obj->attrs); l = scf_list_next(l)) {
-               attr = scf_list_data(l, abc_obj_t, list);
-
-               int j;
-               for (j = 0; attr->keys[j]; j++) {
+       for (i   = 0; i < sizeof(obj->attrs) / sizeof(obj->attrs[0]); i++) {
+               attr = obj->attrs[i];
+               if (!attr)
+                       continue;
 
 
+               for (j = 0; attr->keys[j]; j++)
+               {
                        if (!__html_strcmp(attr->keys[j], key->data))
                                goto found;
                }
        }
 
                        if (!__html_strcmp(attr->keys[j], key->data))
                                goto found;
                }
        }
 
-       if (l == scf_list_sentinel(&obj->attrs)) {
-
+       if (i >= sizeof(obj->attrs) / sizeof(obj->attrs[0])) {
                scf_loge("invalid HTML attribute '%s' in file: %s, line: %d\n", key->data, html->file->data, html->n_lines);
                scf_string_free(key);
                return -1;
                scf_loge("invalid HTML attribute '%s' in file: %s, line: %d\n", key->data, html->file->data, html->n_lines);
                scf_string_free(key);
                return -1;
index 6bfb8f32832965041027c362d5febcdf63108ad7..617cff4db1a9e0135cc3ac4a7c81711fb863a5cb 100644 (file)
@@ -53,10 +53,11 @@ 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_use   (abc_html_t* html, abc_obj_t* obj);
 int  abc_css_parse (abc_obj_t*  css);
 int  abc_css_merge (abc_html_t* html, abc_obj_t* css);
 int  abc_css_use   (abc_html_t* html, abc_obj_t* obj);
+int  abc_css_active(abc_obj_t*  obj);
 
 
-int  abc_css_color   (double* r, double* g, double* b, const uint8_t* str);
-int  abc_css_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);
 int  abc_css_border(double* r, double* g, double* b, int* width, int* type, abc_obj_t* obj, const uint8_t* str);
 int  abc_css_margin(abc_obj_t* obj);
 int  abc_css_length(abc_obj_t* obj, const uint8_t* str, int len);
 int  abc_css_border(double* r, double* g, double* b, int* width, int* type, abc_obj_t* obj, const uint8_t* str);
 int  abc_css_margin(abc_obj_t* obj);
 int  abc_css_length(abc_obj_t* obj, const uint8_t* str, int len);
@@ -64,4 +65,6 @@ int  abc_css_length(abc_obj_t* obj, const uint8_t* str, int len);
 int  abc_css_width (abc_obj_t* obj, int width,  int margin);
 int  abc_css_height(abc_obj_t* obj, int height, int margin);
 
 int  abc_css_width (abc_obj_t* obj, int width,  int margin);
 int  abc_css_height(abc_obj_t* obj, int height, int margin);
 
+int  abc_css_position(const uint8_t* str);
+
 #endif
 #endif
index 91c39d216bc63c70e1b733a06247f6818730207d..b4553575097f0ea587e7ab06fbc848cf90d16d47 100644 (file)
@@ -16,8 +16,8 @@ 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->list);
-       scf_list_init(&obj->attrs);
        scf_list_init(&obj->childs);
        scf_list_init(&obj->childs);
+       scf_list_init(&obj->css_pse_rules);
 
        obj->type = type;
 
 
        obj->type = type;
 
@@ -56,8 +56,9 @@ void abc_obj_free(abc_obj_t* obj)
                        abc_filter_close(obj->av_filter, 0);
 #endif
 
                        abc_filter_close(obj->av_filter, 0);
 #endif
 
-               scf_list_clear(&obj->attrs,  abc_obj_t, list, abc_obj_free);
-               scf_list_clear(&obj->childs, abc_obj_t, list, abc_obj_free);
+               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);
 
                free(obj);
        }
 
                free(obj);
        }
@@ -119,12 +120,14 @@ 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_obj_copy_attrs(abc_obj_t* dst, abc_obj_t* src)
 {
-       scf_list_t*  l;
-       abc_obj_t*   attr;
-       abc_obj_t*   copy;
+       abc_obj_t*  attr;
+       abc_obj_t*  copy;
+       int i;
 
 
-       for (l   = scf_list_head(&src->attrs); l != scf_list_sentinel(&src->attrs); l = scf_list_next(l)) {
-               attr = scf_list_data(l, abc_obj_t, list);
+       for (i   = 0; i < sizeof(src->attrs) / sizeof(src->attrs[0]); i++) {
+               attr = src->attrs[i];
+               if (!attr)
+                       continue;
 
                copy = abc_obj_alloc(attr->file, attr->line, attr->pos, attr->type);
                if (!copy)
 
                copy = abc_obj_alloc(attr->file, attr->line, attr->pos, attr->type);
                if (!copy)
@@ -139,7 +142,10 @@ int abc_obj_copy_attrs(abc_obj_t* dst, abc_obj_t* src)
                copy->keys  = attr->keys;
                copy->flags = attr->flags;
 
                copy->keys  = attr->keys;
                copy->flags = attr->flags;
 
-               scf_list_add_tail(&dst->attrs, &copy->list);
+               if (dst->attrs[i])
+                       abc_obj_free(dst->attrs[i]);
+
+               dst->attrs[i] = copy;
        }
 
        return 0;
        }
 
        return 0;
@@ -148,70 +154,94 @@ int abc_obj_copy_attrs(abc_obj_t* dst, abc_obj_t* src)
 int abc_obj_set_attr(abc_obj_t* obj, int key, const char* value, size_t len)
 {
        scf_string_t* s;
 int abc_obj_set_attr(abc_obj_t* obj, int key, const char* value, size_t len)
 {
        scf_string_t* s;
-       scf_list_t*   l;
        abc_obj_t*    attr;
 
        abc_obj_t*    attr;
 
-       for (l   = scf_list_head(&obj->attrs); l != scf_list_sentinel(&obj->attrs); l = scf_list_next(l)) {
-               attr = scf_list_data(l, abc_obj_t, list);
+       if (key < ABC_HTML_ATTR_ID || key >= ABC_HTML_CSS_NB)
+               return -EINVAL;
 
 
-               if (attr->type == key) {
-                       s = scf_string_cstr_len(value, len);
-                       if (s) {
-                               scf_string_free(attr->value);
-                               attr->value = s;
-                               return 0;
-                       }
-                       return -ENOMEM;
-               }
-       }
+       attr = obj->attrs[key - ABC_HTML_ATTR_ID];
+       if (!attr)
+               return -EINVAL;
+
+       s = scf_string_cstr_len(value, len);
+       if (!s)
+               return -ENOMEM;
 
 
-       return -EINVAL;
+       scf_string_free(attr->value);
+       attr->value = s;
+       return 0;
 }
 
 abc_obj_t* abc_obj_get_attr2(abc_obj_t* obj, const char* key, int len)
 {
 }
 
 abc_obj_t* abc_obj_get_attr2(abc_obj_t* obj, const char* key, int len)
 {
-       scf_list_t*  l;
-       abc_obj_t*   attr;
+       abc_obj_t*  attr;
+       int i;
 
 
-       for (l   = scf_list_head(&obj->attrs); l != scf_list_sentinel(&obj->attrs); l = scf_list_next(l)) {
-               attr = scf_list_data(l, abc_obj_t, list);
+       for (i   = 0; i < sizeof(obj->attrs) / sizeof(obj->attrs[0]); i++) {
+               attr = obj->attrs[i];
 
 
-               if (!abc_obj_cmp_keys(attr, key, len))
+               if (attr && !abc_obj_cmp_keys(attr, key, len))
                        return attr;
        }
 
        return NULL;
 }
 
                        return attr;
        }
 
        return NULL;
 }
 
-abc_obj_t* abc_obj_get_attr(abc_obj_t* obj, int key)
+abc_obj_t* abc_obj_find_attr(abc_obj_t* obj, int key)
 {
 {
-       scf_list_t*  l;
-       abc_obj_t*   attr;
+       abc_obj_t* attr;
 
 
-       for (l   = scf_list_head(&obj->attrs); l != scf_list_sentinel(&obj->attrs); l = scf_list_next(l)) {
-               attr = scf_list_data(l, abc_obj_t, list);
+       while (obj) {
+               attr = abc_obj_get_attr(obj, key);
 
 
-               if (attr->type == key)
+               if (attr && attr->value && attr->value->len > 0)
                        return attr;
                        return attr;
+
+               obj = obj->parent;
        }
 
        return NULL;
 }
 
        }
 
        return NULL;
 }
 
-abc_obj_t* abc_obj_find_attr(abc_obj_t* obj, int key)
+void abc_css_print(abc_obj_t* obj)
 {
 {
-       abc_obj_t* attr;
+       if (!obj)
+               return;
 
 
-       while (obj) {
-               attr = abc_obj_get_attr(obj, key);
+       if (!(ABC_HTML_FLAG_SHOW & obj->flags))
+               return;
 
 
-               if (attr && attr->value && attr->value->len > 0)
-                       return attr;
+       if (obj->text)
+               printf("%s ", obj->text->data);
+       else if (obj->keys)
+               printf("%s ", obj->keys[0]);
 
 
-               obj = obj->parent;
+       pse_link_t* pseLink;
+       abc_obj_t*  attr;
+       int i;
+
+       printf("{\n");
+
+       for (i   = 0; i < sizeof(obj->attrs) / sizeof(obj->attrs[0]); i++) {
+               attr = obj->attrs[i];
+
+               if (!attr || !attr->value || 0 == attr->value->len)
+                       continue;
+
+               if (ABC_HTML_FLAG_SHOW & attr->flags)
+                       printf("    %s: %s;\n", attr->keys[0], attr->value->data);
        }
 
        }
 
-       return NULL;
+       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");
 }
 
 void abc_obj_print(abc_obj_t* obj)
 }
 
 void abc_obj_print(abc_obj_t* obj)
@@ -232,8 +262,11 @@ void abc_obj_print(abc_obj_t* obj)
        } else if (obj->keys)
                printf("<%s", obj->keys[0]);
 
        } else if (obj->keys)
                printf("<%s", obj->keys[0]);
 
-       for (l = scf_list_head(&obj->attrs); l != scf_list_sentinel(&obj->attrs); l = scf_list_next(l)) {
-               attr = scf_list_data(l, abc_obj_t, list);
+       int i;
+       for (i   = 0; i < sizeof(obj->attrs) / sizeof(obj->attrs[0]); i++) {
+               attr = obj->attrs[i];
+               if (!attr)
+                       continue;
 
                if (ABC_HTML_FLAG_SHOW & attr->flags)
                        abc_obj_print(attr);
 
                if (ABC_HTML_FLAG_SHOW & attr->flags)
                        abc_obj_print(attr);
@@ -252,7 +285,27 @@ void abc_obj_print(abc_obj_t* 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);
 
        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_obj_print(child);
+               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;
+               };
+       }
+
+       for (l = scf_list_head(&obj->css_pse_rules); l != scf_list_sentinel(&obj->css_pse_rules); l = scf_list_next(l)) {
+               child = scf_list_data(l, abc_obj_t, list);
+
+               abc_css_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))) {
@@ -306,8 +359,11 @@ static int __abc_obj_to_string(abc_obj_t* obj, scf_string_t* s)
                        return ret;
        }
 
                        return ret;
        }
 
-       for (l = scf_list_head(&obj->attrs); l != scf_list_sentinel(&obj->attrs); l = scf_list_next(l)) {
-               attr = scf_list_data(l, abc_obj_t, list);
+       int i;
+       for (i   = 0; i < sizeof(obj->attrs) / sizeof(obj->attrs[0]); i++) {
+               attr = obj->attrs[i];
+               if (!attr)
+                       continue;
 
                if (ABC_HTML_FLAG_SHOW & attr->flags) {
                        ret = __abc_obj_to_string(attr, s);
 
                if (ABC_HTML_FLAG_SHOW & attr->flags) {
                        ret = __abc_obj_to_string(attr, s);
index 85a8b5124e47b00a4cf47f33dfb01b26eaba4438..c63fb660fd62b7fcfcf8bc942132195432f05844 100644 (file)
@@ -6,8 +6,9 @@
 #include"abc_ffmpeg.h"
 #include"abc_io.h"
 
 #include"abc_ffmpeg.h"
 #include"abc_io.h"
 
-typedef struct abc_obj_s   abc_obj_t;
-typedef struct abc_text_s  abc_text_t;
+typedef struct abc_obj_s    abc_obj_t;
+typedef struct abc_text_s   abc_text_t;
+typedef struct pse_link_s   pse_link_t;
 
 enum abc_objs
 {
 
 enum abc_objs
 {
@@ -112,6 +113,14 @@ enum abc_objs
        ABC_HTML_ATTR_BORDER,
        ABC_HTML_ATTR_PADDING,
 
        ABC_HTML_ATTR_BORDER,
        ABC_HTML_ATTR_PADDING,
 
+       ABC_HTML_ATTR_POSITION,
+       ABC_HTML_ATTR_TOP,
+       ABC_HTML_ATTR_BOTTOM,
+       ABC_HTML_ATTR_LEFT,
+       ABC_HTML_ATTR_RIGHT,
+
+       ABC_HTML_ATTR_OVERFLOW,
+
        ABC_HTML_ATTR_XMLNS,
        ABC_HTML_ATTR_XMLANG,
        ABC_HTML_ATTR_LANG,
        ABC_HTML_ATTR_XMLNS,
        ABC_HTML_ATTR_XMLANG,
        ABC_HTML_ATTR_LANG,
@@ -124,7 +133,7 @@ enum abc_objs
 
        ABC_HTML_ATTR_CONTROLS,
 
 
        ABC_HTML_ATTR_CONTROLS,
 
-       // css objects
+       // css attrs
        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,
@@ -132,16 +141,19 @@ enum abc_objs
 
        ABC_CSS_BORDER_COLLAPSE,
 
 
        ABC_CSS_BORDER_COLLAPSE,
 
-       // css pse class or pse element, first status onload
+       // css pse class (element)
        ABC_CSS_FIRST_CHILD,
        ABC_CSS_FIRST_CHILD,
-       ABC_CSS_LINK,
 
 
-       // status after user operations
+       ABC_CSS_PSE_STATIC, // css pse static barrier, all pse classes (elements) above only based on HTML topology
+
+       ABC_CSS_LINK,
        ABC_CSS_VISITED,
        ABC_CSS_HOVER,
        ABC_CSS_ACTIVE,
 
        ABC_CSS_VISITED,
        ABC_CSS_HOVER,
        ABC_CSS_ACTIVE,
 
-       // ... new css add here
+       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_PSE_CLASS,
 
        // css selectors
        ABC_CSS_PSE_CLASS,
@@ -149,8 +161,10 @@ enum abc_objs
        ABC_CSS_COMBINATOR,
 
        // css selectors from html attrs above
        ABC_CSS_COMBINATOR,
 
        // css selectors from html attrs above
-       ABC_CSS_ID    = ABC_HTML_ATTR_ID,
-       ABC_CSS_CLASS = ABC_HTML_ATTR_CLASS,
+       ABC_CSS_ID       = ABC_HTML_ATTR_ID,
+       ABC_CSS_CLASS    = ABC_HTML_ATTR_CLASS,
+       ABC_CSS_POSITION = ABC_HTML_ATTR_POSITION,
+       ABC_CSS_OVERFLOW = ABC_HTML_ATTR_OVERFLOW,
 };
 
 enum abc_border_style
 };
 
 enum abc_border_style
@@ -160,6 +174,15 @@ enum abc_border_style
        ABC_BORDER_DASHED,
 };
 
        ABC_BORDER_DASHED,
 };
 
+enum abc_position_style
+{
+       ABC_POSITION_STATIC,
+       ABC_POSITION_RELATIVE,
+       ABC_POSITION_ABSOLUTE,
+       ABC_POSITION_FIXED,
+       ABC_POSITION_STICKY,
+};
+
 enum abc_line_style
 {
        ABC_LINE_NONE,
 enum abc_line_style
 {
        ABC_LINE_NONE,
@@ -179,28 +202,49 @@ 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
+
 struct abc_obj_s
 {
 struct abc_obj_s
 {
-       scf_list_t      list;
+       int             type;
+       uint32_t        flags;
 
 
-       scf_list_t      attrs;
+       char**          keys;
+       scf_string_t*   value;
+
+       abc_obj_t*      parent;
+
+       scf_list_t      list;
        scf_list_t      childs;
        int             n_childs;
        int             index;
 
        scf_list_t      childs;
        int             n_childs;
        int             index;
 
-       abc_obj_t*      parent;
+       abc_obj_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;
 
-       int             type;
+       scf_string_t*   text;
+       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;
 
 
-#define ABC_HTML_FLAG_OPEN   0
-#define ABC_HTML_FLAG_CLOSE  1
-#define ABC_HTML_FLAG_SINGLE 2
-#define ABC_HTML_FLAG_SHOW   4
-       uint32_t        flags;
+       pse_link_t*     css_pse_chain;
+       scf_list_t      css_pse_rules;
+       int             css_pse_type;
 
        int             d; // margin + border + padding
        int             w0;
 
        int             d; // margin + border + padding
        int             w0;
@@ -221,16 +265,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
 
-       char**          keys;
-       scf_string_t*   value;
-       scf_string_t*   text;
-       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;
-
-       int             css_pse_type;
 
        scf_string_t*   file; // file name
        int             line; // line
 
        scf_string_t*   file; // file name
        int             line; // line
@@ -260,7 +294,6 @@ 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);
 
 abc_obj_t*     abc_obj_get_attr2(abc_obj_t* obj, const char* key, int len);
 int            abc_obj_set_attr (abc_obj_t* obj, int key, const char* value, size_t len);
 
 abc_obj_t*     abc_obj_get_attr2(abc_obj_t* obj, const char* key, int len);
-abc_obj_t*     abc_obj_get_attr (abc_obj_t* obj, int key);
 abc_obj_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_obj_t*     abc_obj_find_attr(abc_obj_t* obj, int key);
 
 abc_obj_t*     abc_obj_find_type(abc_obj_t* root, int type);
@@ -269,4 +302,13 @@ scf_string_t*  abc_obj_to_string(abc_obj_t* obj);
 
 scf_string_t*  abc_ol_list_style(abc_obj_t* obj, int num);
 
 
 scf_string_t*  abc_ol_list_style(abc_obj_t* obj, int num);
 
+
+static inline abc_obj_t* abc_obj_get_attr(abc_obj_t* obj, int key)
+{
+       if (key < ABC_HTML_ATTR_ID || key >= ABC_HTML_CSS_NB)
+               return NULL;
+
+       return obj->attrs[key - ABC_HTML_ATTR_ID];
+}
+
 #endif
 #endif
index 0bb821b765da7b629d481d5516b8b225813ab309..78042e23d3f817ca5df4e467f2809fc6d1463df5 100644 (file)
@@ -239,7 +239,7 @@ CFILES += ../js/parse/scf_dfa_label.c
 CFILES += ../js/parse/scf_dfa_async.c
 CFILES += ../js/parse/scf_dfa_block.c
 
 CFILES += ../js/parse/scf_dfa_async.c
 CFILES += ../js/parse/scf_dfa_block.c
 
-CFLAGS += -g -O3 -D_GNU_SOURCE
+CFLAGS += -g -D_GNU_SOURCE
 CFLAGS += -I./
 CFLAGS += -I../html
 CFLAGS += -I../ffmpeg
 CFLAGS += -I./
 CFLAGS += -I../html
 CFLAGS += -I../ffmpeg
index b7735dd1fcba67bd2a1b390927968388385a1d76..84375cea54bd539830668eb4e4ed7b76771489cb 100644 (file)
@@ -153,7 +153,7 @@ 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_position(&x, &y, w, h, obj, attr->value->data);
+               abc_css_bg_position(&x, &y, w, h, 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, x: %f, y: %f, w: %f, h: %f\n", attr->value->data, x, y, w, h);
 
index a7e7796a784a4d993af31fb6bcaf04d299aaff24..3528b7822b7903686f31608c5fb57964d037a818 100644 (file)
@@ -36,6 +36,9 @@ static abc_layout_pt abc_layouts[ABC_HTML_NB] =
        [ABC_HTML_DIV]      = abc_layout_div,
 
        [ABC_CORE_TEXT]     = abc_layout_text,
        [ABC_HTML_DIV]      = abc_layout_div,
 
        [ABC_CORE_TEXT]     = abc_layout_text,
+       [ABC_HTML_B]        = abc_layout_text,
+       [ABC_HTML_I]        = abc_layout_text,
+       [ABC_HTML_A]        = abc_layout_text,
 
        [ABC_HTML_H1]       = abc_layout_h1,
        [ABC_HTML_H2]       = abc_layout_h1,
 
        [ABC_HTML_H1]       = abc_layout_h1,
        [ABC_HTML_H2]       = abc_layout_h1,
@@ -47,7 +50,6 @@ static abc_layout_pt abc_layouts[ABC_HTML_NB] =
        [ABC_HTML_P]        = abc_layout_h1,
        [ABC_HTML_BR]       = abc_layout_h1,
 
        [ABC_HTML_P]        = abc_layout_h1,
        [ABC_HTML_BR]       = abc_layout_h1,
 
-       [ABC_HTML_A]        = abc_layout_h1,
        [ABC_HTML_IMG]      = abc_layout_img,
 
        [ABC_HTML_FORM]     = abc_layout_form,
        [ABC_HTML_IMG]      = abc_layout_img,
 
        [ABC_HTML_FORM]     = abc_layout_form,
@@ -73,9 +75,6 @@ static abc_layout_pt abc_layouts[ABC_HTML_NB] =
        [ABC_HTML_SCRIPT]   = abc_layout_empty,
        [ABC_HTML_STYLE]    = abc_layout_empty,
        [ABC_HTML_LINK]     = abc_layout_empty,
        [ABC_HTML_SCRIPT]   = abc_layout_empty,
        [ABC_HTML_STYLE]    = abc_layout_empty,
        [ABC_HTML_LINK]     = abc_layout_empty,
-
-       [ABC_HTML_B]        = abc_layout_text,
-       [ABC_HTML_I]        = abc_layout_text,
 };
 
 int abc_layout_obj(abc_layout_t* layout, abc_obj_t* obj, int width, int height)
 };
 
 int abc_layout_obj(abc_layout_t* layout, abc_obj_t* obj, int width, int height)
@@ -105,9 +104,52 @@ void abc_css_update_xy(abc_obj_t* root, int dx, int dy)
        }
 }
 
        }
 }
 
-int abc_layout_css(abc_obj_t* root)
+#define LAYOUT_POS_FIXED(X, W, SET, L, R) \
+       do { \
+               if (!obj->SET) { \
+                       if (L && R) { \
+                               obj->X = parent->X + L; \
+                               obj->W = parent->W - L - R; \
+                       } else if (L) \
+                               obj->X = parent->X + L; \
+                       else if (R) \
+                               obj->X = parent->X + parent->W - R - obj->W; \
+               } else if (L) \
+                       obj->X = parent->X + L; \
+               else if (R) \
+                       obj->X = parent->X + parent->W - R - obj->W; \
+       } while (0)
+
+#define LAYOUT_POS_RELATIVE(X, L, R) \
+       do { \
+               if (L) \
+                       obj->X += L; \
+               else if (R) \
+                       obj->X += R; \
+       } while (0)
+
+#define LAYOUT_POS_ABSOLUTE(X, W, L, R) \
+       do { \
+               abc_obj_t* tmp = parent; \
+               while (tmp && ABC_HTML != tmp->type) { \
+                       abc_obj_t* attr = abc_obj_get_attr(tmp, ABC_HTML_ATTR_POSITION); \
+                       \
+                       if (attr && attr->value->len > 0 \
+                                       && __html_strcmp(attr->value->data, "static")) \
+                               break; \
+                       tmp = tmp->parent; \
+               } \
+               if (tmp) { \
+                       if (L) \
+                               obj->X = tmp->X + L; \
+                       else if (R) \
+                               obj->X = tmp->X + tmp->W - R - obj->W; \
+               } \
+       } while (0)
+
+int abc_layout_css(abc_obj_t* obj)
 {
 {
-       abc_obj_t*  parent = root->parent;
+       abc_obj_t*  parent = obj->parent;
        abc_obj_t*  attr;
 
        if (!parent || parent->w <= 0)
        abc_obj_t*  attr;
 
        if (!parent || parent->w <= 0)
@@ -123,20 +165,75 @@ int abc_layout_css(abc_obj_t* root)
                        break;
        };
 
                        break;
        };
 
-       attr = abc_obj_get_attr(root, ABC_HTML_ATTR_TEXT_ALIGN);
+       attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_TEXT_ALIGN);
        if (attr) {
        if (attr) {
-               int x = root->x;
+               int x = obj->x;
 
                if (!__html_strcmp(attr->value->data, "center"))
 
                if (!__html_strcmp(attr->value->data, "center"))
-                       root->x = parent->x + (parent->w - root->w) / 2 + 4;
+                       obj->x = parent->x + (parent->w - obj->w) / 2 + 4;
 
                else if (!__html_strcmp(attr->value->data, "right"))
 
                else if (!__html_strcmp(attr->value->data, "right"))
-                       root->x = parent->x + parent->w - root->w - 8;
+                       obj->x = parent->x + parent->w - obj->w - 8;
 
 
-               abc_css_update_xy(root, root->x - x, 0);
+               abc_css_update_xy(obj, obj->x - x, 0);
        }
 
        }
 
-       return 0;
+       attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_POSITION);
+       if (!attr || 0 == attr->value->len)
+               return 0;
+
+       int pos_type = abc_css_position(attr->value->data);
+       if (ABC_POSITION_STATIC == pos_type)
+               return 0;
+
+       int top    = 0;
+       int bottom = 0;
+       int left   = 0;
+       int right  = 0;
+
+       attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_TOP);
+       if (attr)
+               top = abc_css_length(obj, attr->value->data, obj->h);
+
+       attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_BOTTOM);
+       if (attr)
+               bottom = abc_css_length(obj, attr->value->data, obj->h);
+
+       attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_LEFT);
+       if (attr)
+               left = abc_css_length(obj, attr->value->data, obj->w);
+
+       attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_RIGHT);
+       if (attr)
+               right = abc_css_length(obj, attr->value->data, obj->w);
+
+       int x = obj->x;
+       int y = obj->y;
+
+       switch (pos_type)
+       {
+               case ABC_POSITION_FIXED:
+                       LAYOUT_POS_FIXED(x, w, w_set, left, right);
+                       LAYOUT_POS_FIXED(y, h, h_set, top,  bottom);
+                       break;
+
+               case ABC_POSITION_RELATIVE:
+                       scf_logd("top: %d, bottom: %d, left: %d, right: %d, obj->w: %d, parent->w: %d\n", top, bottom, left, right, obj->w, parent->w);
+                       LAYOUT_POS_RELATIVE(x, left, right);
+                       LAYOUT_POS_RELATIVE(y, top,  bottom);
+                       break;
+
+               case ABC_POSITION_ABSOLUTE:
+                       LAYOUT_POS_ABSOLUTE(x, w, left, right);
+                       LAYOUT_POS_ABSOLUTE(y, h, top,  bottom);
+                       break;
+               default:
+                       break;
+       };
+
+       abc_css_update_xy(obj, obj->x - x, obj->y - y);
+
+       return pos_type;
 }
 
 int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height)
 }
 
 int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height)
@@ -158,6 +255,18 @@ int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height)
                        return 0;
                        break;
 
                        return 0;
                        break;
 
+               case ABC_HTML:
+                       root->d  = abc_css_margin(root);
+                       root->w  = width;
+                       root->h  = height;
+
+                       root->w0 = width;
+                       root->h0 = height;
+
+                       root->w_set = 1;
+                       root->h_set = 1;
+                       break;
+
                case ABC_HTML_BODY:
                case ABC_HTML_DIV:
                        root->d     = abc_css_margin(root);
                case ABC_HTML_BODY:
                case ABC_HTML_DIV:
                        root->d     = abc_css_margin(root);
@@ -167,9 +276,6 @@ int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height)
                        if (root->w_set) {
                                root->w0 = root->w;
                                root_w   = root->w;
                        if (root->w_set) {
                                root->w0 = root->w;
                                root_w   = root->w;
-                       } else {
-//                             if (ABC_HTML_BODY != root->type)
-//                                     root->w = 0;
                        }
 
                        if (root->h_set) {
                        }
 
                        if (root->h_set) {
@@ -181,6 +287,7 @@ int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height)
                        }
                        break;
                default:
                        }
                        break;
                default:
+                       root->d = abc_css_margin(root);
                        break;
        };
 
                        break;
        };
 
@@ -194,6 +301,9 @@ int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height)
        int X = 0;
        int Y = 0;
 
        int X = 0;
        int Y = 0;
 
+       root_w -= root->d * 2;
+       root_h -= root->d * 2;
+
        for (l = scf_list_head(&root->childs); l != scf_list_sentinel(&root->childs); l = scf_list_next(l)) {
                child = scf_list_data(l, abc_obj_t, list);
 
        for (l = scf_list_head(&root->childs); l != scf_list_sentinel(&root->childs); l = scf_list_next(l)) {
                child = scf_list_data(l, abc_obj_t, list);
 
@@ -217,6 +327,10 @@ int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height)
                                if (ret < 0)
                                        return ret;
 
                                if (ret < 0)
                                        return ret;
 
+                               ret = abc_layout_css(child);
+                               if (ABC_POSITION_FIXED == ret || ABC_POSITION_ABSOLUTE == ret)
+                                       break;
+
                                x = root->x  + root->d;
                                y = child->y + child->h;
                                h = 0;
                                x = root->x  + root->d;
                                y = child->y + child->h;
                                h = 0;
@@ -235,6 +349,10 @@ int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height)
                                if (ret < 0)
                                        return ret;
 
                                if (ret < 0)
                                        return ret;
 
+                               ret = abc_layout_css(child);
+                               if (ABC_POSITION_FIXED == ret || ABC_POSITION_ABSOLUTE == ret)
+                                       break;
+
                                if (ABC_CORE_TEXT == child->type && child->text_splits) {
                                        abc_text_t* t =  child->text_splits;
 
                                if (ABC_CORE_TEXT == child->type && child->text_splits) {
                                        abc_text_t* t =  child->text_splits;
 
@@ -256,9 +374,7 @@ int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height)
                                                x += t->w;
                                        }
 
                                                x += t->w;
                                        }
 
-                                       scf_logd("--- x: %d, y: %d, h: %d ---\n\n", x, y, h);
-
-                               } else if (x + child->w < root_w) {
+                               } else if (x + child->w < root->x + root->d + root_w) {
                                        if (h < child->h)
                                                h = child->h;
 
                                        if (h < child->h)
                                                h = child->h;
 
@@ -273,6 +389,8 @@ int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height)
                                        if (ret < 0)
                                                return ret;
 
                                        if (ret < 0)
                                                return ret;
 
+                                       abc_layout_css(child);
+
                                        h = child->h;
                                        x = child->x + child->w;
                                }
                                        h = child->h;
                                        x = child->x + child->w;
                                }
@@ -304,8 +422,6 @@ int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height)
        int ret = abc_layout_obj(NULL, root, width, height);
        if (ret < 0)
                return ret;
        int ret = abc_layout_obj(NULL, root, width, height);
        if (ret < 0)
                return ret;
-
-       abc_layout_css(root);
 #if 0
        if (root->keys)
                scf_logw("key: %s, ", root->keys[0]);
 #if 0
        if (root->keys)
                scf_logw("key: %s, ", root->keys[0]);
index 3fd9d7ccbdbc942aada5b01bd1ceaabf87078a84..6de919bd9df9883e15348529c92ba098f0e0e657 100644 (file)
@@ -38,19 +38,14 @@ int abc_layout_div(abc_layout_t* layout, abc_obj_t* obj, int width, int height)
        surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, height);
        cr      = cairo_create(surface);
 
        surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, height);
        cr      = cairo_create(surface);
 
-       w = w / size * size;
-
-       int ret = __layout_text(cr, obj, 0, w, &extents);
+       int ret = __layout_text(cr, obj, 0, w / size * size, &extents);
        if (ret < 0)
                scf_loge("ret: %d\n", ret);
 
        if (ret < 0)
                scf_loge("ret: %d\n", ret);
 
-       w = extents.width  + extents.x_bearing  + obj->d * 2;
        h = extents.height + extents.height / 2 + obj->d * 2;
 
        obj->w = obj->w_set ? obj->w0 : w;
        obj->h = obj->h_set ? obj->h0 : h + obj->h;
        h = extents.height + extents.height / 2 + obj->d * 2;
 
        obj->w = obj->w_set ? obj->w0 : w;
        obj->h = obj->h_set ? obj->h0 : h + obj->h;
-//     obj->w = (obj->w + 3) & ~0x3;
-//     obj->h = (obj->h + 3) & ~0x3;
 
        scf_logd("%s, w: %d, h: %d, d: %d, x_bearing: %lg, y_bearing: %lg, width: %lg, height: %lg, x_advance: %lg, y_advance: %lg, width: %d, height: %d\n",
                        obj->text->data, obj->w, obj->h, d,
 
        scf_logd("%s, w: %d, h: %d, d: %d, x_bearing: %lg, y_bearing: %lg, width: %lg, height: %lg, x_advance: %lg, y_advance: %lg, width: %d, height: %d\n",
                        obj->text->data, obj->w, obj->h, d,
index 981b11edae671087812683261444ae32880a87e7..bcf6f836e84fb2b6ea569f021c77bb4483f7e001 100644 (file)
@@ -45,8 +45,7 @@ int abc_layout_h1(abc_layout_t* layout, abc_obj_t* obj, int width, int height)
        if (attr)
                size = atoi(attr->value->data);
 
        if (attr)
                size = atoi(attr->value->data);
 
-       cairo_set_font_size  (cr, size);
-       cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0);
+       cairo_set_font_size(cr, size);
 
        int d     = abc_css_margin(obj);
        int w_set = abc_css_width (obj, width,  d);
 
        int d     = abc_css_margin(obj);
        int w_set = abc_css_width (obj, width,  d);
@@ -86,12 +85,8 @@ int abc_layout_h1(abc_layout_t* layout, abc_obj_t* obj, int width, int height)
 
        obj->y_bearing = extents.y_bearing;
 
 
        obj->y_bearing = extents.y_bearing;
 
-       w = extents.x_advance + extents.x_bearing + d * 2 + dw;
-
-       obj->w = w;
+       obj->w = extents.width  + d * 2 + dw;
        obj->h = extents.height + extents.height / 2 + d * 2;
        obj->h = extents.height + extents.height / 2 + d * 2;
-//     obj->w = (obj->w + 3) & ~0x3;
-//     obj->h = (obj->h + 3) & ~0x3;
 
        scf_logd("%s, w: %d, h: %d, d: %d, x_bearing: %lg, y_bearing: %lg, width: %lg, height: %lg, x_advance: %lg, y_advance: %lg, width: %d, height: %d\n",
                        obj->text->data, obj->w, obj->h, d,
 
        scf_logd("%s, w: %d, h: %d, d: %d, x_bearing: %lg, y_bearing: %lg, width: %lg, height: %lg, x_advance: %lg, y_advance: %lg, width: %d, height: %d\n",
                        obj->text->data, obj->w, obj->h, d,
index 4e6a814cc1d3ca9e60cd8b41d07c52f80abb47d7..cab16692e0690a020f86526a484428d03120dc16 100644 (file)
@@ -2,32 +2,9 @@
 
 int abc_layout_img(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)
 {
-       scf_list_t*  l;
-       abc_obj_t*   attr;
+       obj->w_set = abc_css_width (obj, width,  obj->d);
+       obj->h_set = abc_css_height(obj, height, obj->d);
 
 
-       for (l   = scf_list_head(&obj->attrs); l != scf_list_sentinel(&obj->attrs); l = scf_list_next(l)) {
-               attr = scf_list_data(l, abc_obj_t, list);
-
-               switch (attr->type) {
-
-                       case ABC_HTML_ATTR_WIDTH:
-                               obj->w = atoi(attr->value->data);
-                               break;
-
-                       case ABC_HTML_ATTR_HEIGHT:
-                               obj->h = atoi(attr->value->data);
-                               break;
-                       default:
-                               break;
-               };
-       }
-
-//     obj->x = 4;
-//     obj->y = 4;
-
-       obj->w = (obj->w + 3) & ~0x3;
-       obj->h = (obj->h + 3) & ~0x3;
-
-       scf_logd("%s, w: %d, h: %d\n", obj->text->data, obj->w, obj->h);
+       scf_logi("w: %d, h: %d, d: %d\n", obj->w, obj->h, obj->d);
        return 0;
 }
        return 0;
 }
index 694f7d8aa2091eff9c741771d7787e30a40abe7b..6640045febd8d72ac12fd864f21241a7cc5724f4 100644 (file)
@@ -58,8 +58,10 @@ 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;
-       if (x + w <= width)
+       if (x + w <= width) {
+               extents->width = w;
                return 0;
                return 0;
+       }
 
        extents->width  = width;
        extents->height = 0;
 
        extents->width  = width;
        extents->height = 0;
@@ -90,7 +92,7 @@ int __layout_text(cairo_t* cr, abc_obj_t* obj, int x, int width, cairo_text_exte
                        if (n < 0)
                                return n;
 
                        if (n < 0)
                                return n;
 
-                       w = (tmp.x_bearing + tmp.x_advance + size - 1) / size * size;
+                       w = tmp.x_bearing + tmp.x_advance;
                        if (x + w <= width) {
                                x = 0;
 
                        if (x + w <= width) {
                                x = 0;
 
@@ -126,23 +128,18 @@ int abc_layout_text(abc_layout_t* layout, abc_obj_t* obj, int width, int height)
 {
        abc_obj_t*            parent = obj->parent;
        abc_obj_t*            attr;
 {
        abc_obj_t*            parent = obj->parent;
        abc_obj_t*            attr;
-       abc_obj_t*            style;
        cairo_text_extents_t  extents;
        cairo_text_extents_t  extents;
-       cairo_text_extents_t  extents2;
        cairo_surface_t*      surface;
        cairo_t*              cr;
 
        if (!obj->text)
                return 0;
 
        cairo_surface_t*      surface;
        cairo_t*              cr;
 
        if (!obj->text)
                return 0;
 
-       int x = obj->x        - parent->x;
-       int w = parent->w_set ? parent->w0 : width;
        int d = parent->d;
        int d = parent->d;
-       int h;
+       int x = obj->x - (parent->x + d);
+       int w = width;
 
        scf_logd("obj->x: %d, parent->x: %d, w: %d, d: %d\n", obj->x, parent->x, w, d);
 
        scf_logd("obj->x: %d, parent->x: %d, w: %d, d: %d\n", obj->x, parent->x, w, d);
-       x -= d;
-       w -= d * 2;
 
        surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, height);
        cr      = cairo_create(surface);
 
        surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, height);
        cr      = cairo_create(surface);
@@ -152,11 +149,7 @@ int abc_layout_text(abc_layout_t* layout, abc_obj_t* obj, int width, int height)
        if (attr)
                size = atoi(attr->value->data);
 
        if (attr)
                size = atoi(attr->value->data);
 
-       w = w / size * size;
-
-       scf_logd("text: %s, w: %d\n", obj->text->data, w);
-
-       int ret = __layout_text(cr, obj, x, w, &extents);
+       int ret = __layout_text(cr, obj, x, w / size * size, &extents);
        if (ret < 0)
                scf_loge("ret: %d\n", ret);
 
        if (ret < 0)
                scf_loge("ret: %d\n", ret);
 
@@ -165,10 +158,8 @@ int abc_layout_text(abc_layout_t* layout, abc_obj_t* obj, int width, int height)
        if (parent->y_bearing > obj->y_bearing)
                parent->y_bearing = obj->y_bearing;
 
        if (parent->y_bearing > obj->y_bearing)
                parent->y_bearing = obj->y_bearing;
 
-       obj->w = extents.x_bearing + extents.x_advance;
-       obj->h = extents.height    + extents.height / 2;
-//     obj->w = (obj->w + 3) & ~0x3;
-//     obj->h = (obj->h + 3) & ~0x3;
+       obj->w = extents.width;
+       obj->h = extents.height + extents.height / 2;
 
        scf_logd("%s, w: %d, h: %d, d: %d, x_bearing: %lg, y_bearing: %lg, width: %lg, height: %lg, x_advance: %lg, y_advance: %lg, width: %d, height: %d\n",
                        obj->text->data, obj->w, obj->h, d,
 
        scf_logd("%s, w: %d, h: %d, d: %d, x_bearing: %lg, y_bearing: %lg, width: %lg, height: %lg, x_advance: %lg, y_advance: %lg, width: %d, height: %d\n",
                        obj->text->data, obj->w, obj->h, d,
index 0e0b02c4c42e5678adbdc563f041b35e534140b2..961f059b0cf2a8857ed807a7e344ae4a68876574 100644 (file)
@@ -37,6 +37,7 @@ static abc_render_t* abc_renders[ABC_HTML_NB] =
        [ABC_CORE_TEXT]     = &abc_render_text,
        [ABC_HTML_B]        = &abc_render_text,
        [ABC_HTML_I]        = &abc_render_text,
        [ABC_CORE_TEXT]     = &abc_render_text,
        [ABC_HTML_B]        = &abc_render_text,
        [ABC_HTML_I]        = &abc_render_text,
+       [ABC_HTML_A]        = &abc_render_text,
 
        [ABC_HTML_H1]       = &abc_render_h1,
        [ABC_HTML_H2]       = &abc_render_h1,
 
        [ABC_HTML_H1]       = &abc_render_h1,
        [ABC_HTML_H2]       = &abc_render_h1,
@@ -48,7 +49,6 @@ static abc_render_t* abc_renders[ABC_HTML_NB] =
        [ABC_HTML_P]        = &abc_render_h1,
        [ABC_HTML_BR]       = &abc_render_h1,
 
        [ABC_HTML_P]        = &abc_render_h1,
        [ABC_HTML_BR]       = &abc_render_h1,
 
-       [ABC_HTML_A]        = &abc_render_h1,
        [ABC_HTML_A_HREF]   = &abc_render_a_href,
        [ABC_HTML_IMG]      = &abc_render_img,
 
        [ABC_HTML_A_HREF]   = &abc_render_a_href,
        [ABC_HTML_IMG]      = &abc_render_img,
 
index a6106c1477325d632bf07b38b589f1b9295b9a21..7fd0394cbc3a6ad91433371f32bf5891603bd5b3 100644 (file)
@@ -41,19 +41,10 @@ static int _render_fini_audio(abc_render_t* render)
 
 static int _render_draw_audio(abc_render_t* render, abc_obj_t* obj, int width, int height)
 {
 
 static int _render_draw_audio(abc_render_t* render, abc_obj_t* obj, int width, int height)
 {
-       scf_list_t*  l;
-       abc_obj_t*   attr;
-
-       for (l   = scf_list_head(&obj->attrs); l != scf_list_sentinel(&obj->attrs); l = scf_list_next(l)) {
-               attr = scf_list_data(l, abc_obj_t, list);
-
-               if (ABC_HTML_ATTR_SRC == attr->type)
-                       break;
-       }
-
-       if (l == scf_list_sentinel(&obj->attrs)) {
-               scf_loge("src image of '%s' not found\n", obj->keys[0]);
-               return -1;
+       abc_obj_t* attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_SRC);
+       if (!attr) {
+               scf_loge("src audio of '%s' not found\n", obj->keys[0]);
+               return -EINVAL;
        }
 
        if (0 == program)
        }
 
        if (0 == program)
index 20323ca3654be979a8efde2f2de50c5770e6ff36..511e14412a548a1bb9ebbcf03596dd6a3db1efb5 100644 (file)
@@ -81,19 +81,24 @@ static int _render_draw_img(abc_render_t* render, abc_obj_t* obj, int width, int
 
        scf_logi("%s, x: %d, y: %d, w: %d, h: %d\n", obj->keys[0], obj->x, obj->y, obj->w, obj->h);
 
 
        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->d;
+       int y = obj->y + obj->d;
+       int w = obj->w - obj->d * 2;
+       int h = obj->h - obj->d * 2;
+
        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 *  x      / (float)width  - 1.0,
+               -2.0 * (y + h) / (float)height + 1.0,
 
 
-                2.0 * (obj->x + obj->w) / (float)width  - 1.0,
-               -2.0 * (obj->y + obj->h) / (float)height + 1.0,
+                2.0 * (x + w) / (float)width  - 1.0,
+               -2.0 * (y + h) / (float)height + 1.0,
 
 
-                2.0 *  obj->x           / (float)width  - 1.0,
-               -2.0 *  obj->y           / (float)height + 1.0,
+                2.0 *  x      / (float)width  - 1.0,
+               -2.0 *  y      / (float)height + 1.0,
 
 
-                2.0 * (obj->x + obj->w) / (float)width  - 1.0,
-               -2.0 *  obj->y           / (float)height + 1.0,
+                2.0 * (x + w) / (float)width  - 1.0,
+               -2.0 *  y      / (float)height + 1.0,
        };
 
        glUseProgram(program);
        };
 
        glUseProgram(program);
index c931f2ce73bd648cc412e4ea5330ce6b5941dc46..2c2f4d3386df2ea94992c21654cf6f4301a27944 100644 (file)
--- a/ui/main.c
+++ b/ui/main.c
@@ -83,11 +83,11 @@ static int __do_button_move(abc_ctx_t* ctx, int x, int y)
                g_object_unref(cursor);
 
                if (prev->visited)
                g_object_unref(cursor);
 
                if (prev->visited)
-                       css = abc_obj_get_attr(prev, ABC_CSS_VISITED);
+                       prev->css_pse_type = ABC_CSS_VISITED;
                else
                else
-                       css = abc_obj_get_attr(prev, ABC_CSS_LINK);
-               if (css)
-                       abc_obj_set_css(prev, css);
+                       prev->css_pse_type = ABC_CSS_LINK;
+
+               abc_css_active(prev);
 
                prev->clicked = 0;
                ret = 1;
 
                prev->clicked = 0;
                ret = 1;
@@ -129,11 +129,9 @@ static int __do_button_move(abc_ctx_t* ctx, int x, int y)
                                break;
                };
 
                                break;
                };
 
-               css = abc_obj_get_attr(obj, ABC_CSS_HOVER);
-               if (css) {
-                       abc_obj_set_css(obj, css);
-                       ret = 1;
-               }
+               obj->css_pse_type = ABC_CSS_HOVER;
+
+               ret |= abc_css_active(obj);
 
                ctx->current->current = obj;
        }
 
                ctx->current->current = obj;
        }
@@ -186,11 +184,10 @@ static int __do_button_release(abc_ctx_t* ctx, int x, int y)
        if (!obj)
                return __do_button_move(ctx, x, y);
 
        if (!obj)
                return __do_button_move(ctx, x, y);
 
-       obj->visited = 1;
+       obj->visited      = 1;
+       obj->css_pse_type = ABC_CSS_VISITED;
 
 
-       css = abc_obj_get_attr(obj, ABC_CSS_VISITED);
-       if (css)
-               abc_obj_set_css(obj, css);
+       abc_css_active(obj);
 
        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);
@@ -344,12 +341,10 @@ static gboolean button_press_event(GtkWidget* self, GdkEventButton* event, gpoin
                abc_obj_t*  css;
 
                if (obj) {
                abc_obj_t*  css;
 
                if (obj) {
-                       css = abc_obj_get_attr(obj, ABC_CSS_ACTIVE);
-                       if (css) {
-                               abc_obj_set_css(obj, css);
+                       obj->css_pse_type = ABC_CSS_ACTIVE;
 
 
+                       if (abc_css_active(obj) > 0)
                                gtk_gl_area_queue_render(ctx->gl_area);
                                gtk_gl_area_queue_render(ctx->gl_area);
-                       }
                }
        }
 
                }
        }