css: support 'background-color' & 'background-image' master
authoryu.dongliang <18588496441@163.com>
Tue, 7 Apr 2026 10:10:55 +0000 (18:10 +0800)
committeryu.dongliang <18588496441@163.com>
Tue, 7 Apr 2026 10:10:55 +0000 (18:10 +0800)
17 files changed:
examples/css.html
examples/img.png
examples/style.css
html/abc_css.c
html/abc_html.c
html/abc_io.h
html/abc_io_util.c
html/abc_obj.c
html/abc_obj.h
ui/Makefile
ui/abc_layout.c
ui/abc_render.c
ui/abc_render_bg_color.c [new file with mode: 0644]
ui/abc_render_bg_image.c [new file with mode: 0644]
ui/abc_render_body.c
ui/abc_render_h1.c
ui/abc_render_img.c

index 9b738ff25c400179d32b6fbfbeea65504cdcfe7c..2eb455e8e9719b46596f0f57db4a9f1b86b12943 100644 (file)
@@ -8,6 +8,7 @@
 <h1 class="red">这个段落采用CSS样式化。</h1>
 <p id="a">Hello World!</p>
 <p class="red">这个段落<b>采用</b>CSS样式化。</p>
 <h1 class="red">这个段落采用CSS样式化。</h1>
 <p id="a">Hello World!</p>
 <p class="red">这个段落<b>采用</b>CSS样式化。</p>
+<p style="color:green">这个段落采用CSS样式化。</p>
 </body>
 
 </html>
 </body>
 
 </html>
index a3a560bac13023cabcd43e8f56612dad057dcd02..17f8bd1c8b4fecfe3c8f8373b33c27d24710cbc4 100644 (file)
Binary files a/examples/img.png and b/examples/img.png differ
index 9306941209b44c3d8d5c284f13920eefa5d9ad6f..16354c1b7868b730de5e9763064584ee41ed4e4b 100644 (file)
@@ -1,3 +1,10 @@
+body
+{
+       background-color:#b0c4de;
+       background-image:url('img.png');
+}
+h1 {background-color:#6495ed;}
+
 #a /*css comment*/
 {
        color:blue;
 #a /*css comment*/
 {
        color:blue;
index c7394d2c71f32c05bcb0eb7ffa8e3088e5e90d7f..b04339d4b72c4d16f45b2dd175828304e786a243 100644 (file)
@@ -85,7 +85,7 @@ static int __css_parse_value(abc_obj_t* css, abc_obj_t* attr)
                        css->text_pos = 0;
                }
 
                        css->text_pos = 0;
                }
 
-               if (';' == c->c)
+               if (';' == c->c || EOF == c->c)
                        break;
                else
                        scf_string_cat_cstr_len(value, c->utf8, c->len);
                        break;
                else
                        scf_string_cat_cstr_len(value, c->utf8, c->len);
@@ -123,7 +123,7 @@ static int __css_parse_attr2(abc_obj_t* css, abc_obj_t* obj, const html_attr_t*
 
                css->text_pos += c->len;
 
 
                css->text_pos += c->len;
 
-               if ('}' == c->c) {
+               if ('}' == c->c || EOF == c->c) {
                        free(c);
                        scf_string_free(key);
                        return '}';
                        free(c);
                        scf_string_free(key);
                        return '}';
@@ -228,7 +228,7 @@ static int __css_parse_attr(abc_obj_t* css, abc_obj_t* obj, const html_attr_t* a
                if (ret < 0)
                        return ret;
 
                if (ret < 0)
                        return ret;
 
-               if ('}' == ret)
+               if ('}' == ret || EOF == ret)
                        break;
        }
 
                        break;
        }
 
@@ -382,7 +382,7 @@ int abc_css_parse(abc_obj_t* css)
                        if (!href)
                                return 0;
 
                        if (!href)
                                return 0;
 
-                       n = __io_url_path(&io, &spath, css->file->data, href->value->data);
+                       n = __io_url_path(&io, &spath, css->file->data, href->value->data, href->value->len);
                        if (n < 0)
                                return n;
 
                        if (n < 0)
                                return n;
 
@@ -415,12 +415,15 @@ int abc_css_parse(abc_obj_t* css)
 
        while (1) {
                c = __io_pop_char(&css->io);
 
        while (1) {
                c = __io_pop_char(&css->io);
-               if (!c)
-                       return -1;
+               if (!c) {
+                       ret = -1;
+                       break;
+               }
 
                if (EOF == c->c) {
                        free(c);
 
                if (EOF == c->c) {
                        free(c);
-                       return 0;
+                       ret = 0;
+                       break;
                }
 
                if ('\n' == c->c) {
                }
 
                if ('\n' == c->c) {
@@ -452,16 +455,31 @@ int abc_css_parse(abc_obj_t* css)
                        ret = __css_parse_obj(css, c);
                        if (ret < 0) {
                                scf_loge("css->text_line: %d, css->text_pos: %d\n", css->text_line, css->text_pos);
                        ret = __css_parse_obj(css, c);
                        if (ret < 0) {
                                scf_loge("css->text_line: %d, css->text_pos: %d\n", css->text_line, css->text_pos);
-                               return ret;
+                               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);
                        free(c);
                        }
                } else {
                        scf_loge("'%c'(%#x), css->text_line: %d, css->text_pos: %d\n", c->c, c->c, css->text_line, css->text_pos);
                        free(c);
-                       return -1;
+                       ret = -1;
+                       break;
                }
        }
 
                }
        }
 
-       return -1;
+       io->close(&css->io);
+       return ret;
+}
+
+static void __css_set_attr(abc_obj_t* obj, abc_obj_t* attr)
+{
+       switch (attr->type)
+       {
+               case ABC_HTML_ATTR_BG_COLOR:
+                       abc_obj_set_attr(obj, attr->type, attr->value->data);
+                       break;
+               default:
+                       abc_recursive_set_attr(obj, attr->type, attr->value->data);
+                       break;
+       };
 }
 
 int abc_css_use(abc_html_t* html, abc_obj_t* obj)
 }
 
 int abc_css_use(abc_html_t* html, abc_obj_t* obj)
@@ -474,53 +492,92 @@ int abc_css_use(abc_html_t* html, abc_obj_t* obj)
        scf_list_t*  l3;
        abc_obj_t*   head;
        abc_obj_t*   css;
        scf_list_t*  l3;
        abc_obj_t*   head;
        abc_obj_t*   css;
-       abc_obj_t*   label;
+       abc_obj_t*   style;
        abc_obj_t*   attr;
 
        abc_obj_t*   attr;
 
+       // for css in HTML <head>
        head = abc_obj_find_type(html->root, ABC_HTML_HEAD);
        head = abc_obj_find_type(html->root, ABC_HTML_HEAD);
-       if (!head)
-               return 0;
+       if (head) {
+               for (l  = scf_list_head(&head->childs); l != scf_list_sentinel(&head->childs); l = scf_list_next(l)) {
+                       css = scf_list_data(l, abc_obj_t, list);
 
 
-       for (l  = scf_list_head(&head->childs); l != scf_list_sentinel(&head->childs); l = scf_list_next(l)) {
-               css = scf_list_data(l, abc_obj_t, list);
+                       if (ABC_HTML_LINK == css->type)
+                       {
+                               attr = abc_obj_get_attr(css, ABC_HTML_ATTR_TYPE);
+                               if (!attr)
+                                       continue;
 
 
-               if (ABC_HTML_LINK == css->type)
-               {
-                       attr = abc_obj_get_attr(css, ABC_HTML_ATTR_TYPE);
-                       if (!attr)
-                               continue;
+                               if (strcmp(attr->value->data, "text/css"))
+                                       continue;
 
 
-                       if (strcmp(attr->value->data, "text/css"))
+                       } else if (ABC_HTML_STYLE != css->type)
                                continue;
 
                                continue;
 
-               } else if (ABC_HTML_STYLE != css->type)
-                       continue;
+                       for (l2   = scf_list_head(&css->childs); l2 != scf_list_sentinel(&css->childs); l2 = scf_list_next(l2)) {
+                               style = scf_list_data(l2, abc_obj_t, list);
 
 
-               for (l2   = scf_list_head(&css->childs); l2 != scf_list_sentinel(&css->childs); l2 = scf_list_next(l2)) {
-                       label = scf_list_data(l2, abc_obj_t, list);
+                               if (ABC_CSS_ID == style->type || ABC_CSS_CLASS == style->type)
+                               {
+                                       attr = abc_obj_get_attr(obj, style->type);
+                                       if (!attr)
+                                               continue;
 
 
-                       if (ABC_CSS_ID == label->type || ABC_CSS_CLASS == label->type)
-                       {
-                               attr = abc_obj_get_attr(obj, label->type);
-                               if (!attr)
-                                       continue;
+                                       if (strcmp(attr->value->data, style->text->data + style->css_dot + 1))
+                                               continue;
 
 
-                               if (strcmp(attr->value->data, label->text->data + label->css_dot + 1))
+                                       if (style->css_dot > 0) {
+                                               if (strncmp(obj->keys[0], style->text->data, style->css_dot))
+                                                       continue;
+                                       }
+
+                               } else if (style->type != obj->type)
                                        continue;
 
                                        continue;
 
-                               if (label->css_dot > 0) {
-                                       if (strncmp(obj->keys[0], label->text->data, label->css_dot))
-                                               continue;
+                               for (l3  = scf_list_head(&style->attrs); l3 != scf_list_sentinel(&style->attrs); l3 = scf_list_next(l3)) {
+                                       attr = scf_list_data(l3, abc_obj_t, list);
+
+                                       __css_set_attr(obj, attr);
                                }
                                }
+                       }
+               }
+       }
 
 
-                       } else if (label->type != obj->type)
-                               continue;
+       // for inline css below
+       css = abc_obj_get_attr(obj, ABC_HTML_ATTR_STYLE);
 
 
-                       for (l3  = scf_list_head(&label->attrs); l3 != scf_list_sentinel(&label->attrs); l3 = scf_list_next(l3)) {
-                               attr = scf_list_data(l3, abc_obj_t, list);
+       if (css && css->value && css->value->len > 0)
+       {
+               html_label_t*  label = __html_find_label2(obj->type);
+               abc_io_t*      io    = abc_io_array[ABC_PROTO_STR];
 
 
-                               abc_recursive_set_attr(obj, attr->type, attr->value->data);
-                       }
+               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;
+
+               css->text_line = 1;
+               css->text_pos  = 0;
+
+               int ret = io->open(&css->io, css->value->data);
+               if (ret < 0)
+                       return ret;
+
+               ret = __css_parse_attr(css, css, label->attrs, label->n_attrs);
+               io->close(&css->io);
+               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);
+
+                       __css_set_attr(obj, attr);
+
+                       scf_list_del(&attr->list);
+                       abc_obj_free(attr);
+                       attr = NULL;
                }
        }
 
                }
        }
 
index 6ab0fbabfd78beb3f32acff0811e43f011d5d98e..5cf717176ffd18616c688789b06111eeb789daf7 100644 (file)
@@ -17,6 +17,9 @@ static char* font_italic_keys[] = {"italic",    "斜体",     NULL};
 
 static char* text_align_keys[] = {"text-align", "对齐",     NULL};
 
 
 static char* text_align_keys[] = {"text-align", "对齐",     NULL};
 
+static char* bg_color_keys[]   = {"background-color", "背景颜色", NULL};
+static char* bg_image_keys[]   = {"background-image", "背景图片", NULL};
+
 static char* class_keys[]      = {"class",      "类名",     NULL};
 static char* type_keys[]       = {"type",       "类型",     NULL};
 static char* name_keys[]       = {"name",       "名字",     NULL};
 static char* class_keys[]      = {"class",      "类名",     NULL};
 static char* type_keys[]       = {"type",       "类型",     NULL};
 static char* name_keys[]       = {"name",       "名字",     NULL};
@@ -102,78 +105,101 @@ static html_attr_t  meta_attrs[] =
 
 static html_attr_t  body_attrs[] =
 {
 
 static html_attr_t  body_attrs[] =
 {
-       {font_keys,        "SimSong",    ABC_HTML_ATTR_FONT,      0},
-       {font_size_keys,   "16",         ABC_HTML_ATTR_FONT_SIZE, 0},
+       {font_keys,        "SimSong",    ABC_HTML_ATTR_FONT,       0},
+       {font_size_keys,   "16",         ABC_HTML_ATTR_FONT_SIZE,  0},
+       {bg_color_keys,    "white",      ABC_HTML_ATTR_BG_COLOR,   ABC_HTML_FLAG_SHOW},
+       {bg_image_keys,    "",           ABC_HTML_ATTR_BG_IMAGE,   ABC_HTML_FLAG_SHOW},
 };
 
 static html_attr_t  h1_attrs[] =
 {
        {class_keys,       "",           ABC_HTML_ATTR_CLASS,      ABC_HTML_FLAG_SHOW},
 };
 
 static html_attr_t  h1_attrs[] =
 {
        {class_keys,       "",           ABC_HTML_ATTR_CLASS,      ABC_HTML_FLAG_SHOW},
+       {style_keys,       "",           ABC_HTML_ATTR_STYLE,      ABC_HTML_FLAG_SHOW},
        {id_keys,          "",           ABC_HTML_ATTR_ID,         ABC_HTML_FLAG_SHOW},
        {id_keys,          "",           ABC_HTML_ATTR_ID,         ABC_HTML_FLAG_SHOW},
-       {font_keys,        "SimHei",     ABC_HTML_ATTR_FONT,      0},
-       {font_size_keys,   "40",         ABC_HTML_ATTR_FONT_SIZE, 0},
+       {font_keys,        "SimHei",     ABC_HTML_ATTR_FONT,       0},
+       {font_size_keys,   "40",         ABC_HTML_ATTR_FONT_SIZE,  0},
        {font_color_keys,  "black",      ABC_HTML_ATTR_FONT_COLOR, ABC_HTML_FLAG_SHOW},
        {text_align_keys,  "left",       ABC_HTML_ATTR_TEXT_ALIGN, ABC_HTML_FLAG_SHOW},
        {font_color_keys,  "black",      ABC_HTML_ATTR_FONT_COLOR, ABC_HTML_FLAG_SHOW},
        {text_align_keys,  "left",       ABC_HTML_ATTR_TEXT_ALIGN, ABC_HTML_FLAG_SHOW},
+
+       {bg_color_keys,    "",           ABC_HTML_ATTR_BG_COLOR,   ABC_HTML_FLAG_SHOW},
 };
 
 static html_attr_t  h2_attrs[] =
 {
        {class_keys,       "",           ABC_HTML_ATTR_CLASS,      ABC_HTML_FLAG_SHOW},
 };
 
 static html_attr_t  h2_attrs[] =
 {
        {class_keys,       "",           ABC_HTML_ATTR_CLASS,      ABC_HTML_FLAG_SHOW},
+       {style_keys,       "",           ABC_HTML_ATTR_STYLE,      ABC_HTML_FLAG_SHOW},
        {id_keys,          "",           ABC_HTML_ATTR_ID,         ABC_HTML_FLAG_SHOW},
        {id_keys,          "",           ABC_HTML_ATTR_ID,         ABC_HTML_FLAG_SHOW},
-       {font_keys,        "SimHei",     ABC_HTML_ATTR_FONT,      0},
-       {font_size_keys,   "32",         ABC_HTML_ATTR_FONT_SIZE, 0},
+       {font_keys,        "SimHei",     ABC_HTML_ATTR_FONT,       0},
+       {font_size_keys,   "32",         ABC_HTML_ATTR_FONT_SIZE,  0},
        {font_color_keys,  "black",      ABC_HTML_ATTR_FONT_COLOR, ABC_HTML_FLAG_SHOW},
        {text_align_keys,  "left",       ABC_HTML_ATTR_TEXT_ALIGN, ABC_HTML_FLAG_SHOW},
        {font_color_keys,  "black",      ABC_HTML_ATTR_FONT_COLOR, ABC_HTML_FLAG_SHOW},
        {text_align_keys,  "left",       ABC_HTML_ATTR_TEXT_ALIGN, ABC_HTML_FLAG_SHOW},
+
+       {bg_color_keys,    "",           ABC_HTML_ATTR_BG_COLOR,   ABC_HTML_FLAG_SHOW},
 };
 
 static html_attr_t  h3_attrs[] =
 {
        {class_keys,       "",           ABC_HTML_ATTR_CLASS,      ABC_HTML_FLAG_SHOW},
 };
 
 static html_attr_t  h3_attrs[] =
 {
        {class_keys,       "",           ABC_HTML_ATTR_CLASS,      ABC_HTML_FLAG_SHOW},
+       {style_keys,       "",           ABC_HTML_ATTR_STYLE,      ABC_HTML_FLAG_SHOW},
        {id_keys,          "",           ABC_HTML_ATTR_ID,         ABC_HTML_FLAG_SHOW},
        {id_keys,          "",           ABC_HTML_ATTR_ID,         ABC_HTML_FLAG_SHOW},
-       {font_keys,        "SimHei",     ABC_HTML_ATTR_FONT,      0},
-       {font_size_keys,   "28",         ABC_HTML_ATTR_FONT_SIZE, 0},
+       {font_keys,        "SimHei",     ABC_HTML_ATTR_FONT,       0},
+       {font_size_keys,   "28",         ABC_HTML_ATTR_FONT_SIZE,  0},
        {font_color_keys,  "black",      ABC_HTML_ATTR_FONT_COLOR, ABC_HTML_FLAG_SHOW},
        {text_align_keys,  "left",       ABC_HTML_ATTR_TEXT_ALIGN, ABC_HTML_FLAG_SHOW},
        {font_color_keys,  "black",      ABC_HTML_ATTR_FONT_COLOR, ABC_HTML_FLAG_SHOW},
        {text_align_keys,  "left",       ABC_HTML_ATTR_TEXT_ALIGN, ABC_HTML_FLAG_SHOW},
+
+       {bg_color_keys,    "",           ABC_HTML_ATTR_BG_COLOR,   ABC_HTML_FLAG_SHOW},
 };
 
 static html_attr_t  h4_attrs[] =
 {
        {class_keys,       "",           ABC_HTML_ATTR_CLASS,      ABC_HTML_FLAG_SHOW},
 };
 
 static html_attr_t  h4_attrs[] =
 {
        {class_keys,       "",           ABC_HTML_ATTR_CLASS,      ABC_HTML_FLAG_SHOW},
+       {style_keys,       "",           ABC_HTML_ATTR_STYLE,      ABC_HTML_FLAG_SHOW},
        {id_keys,          "",           ABC_HTML_ATTR_ID,         ABC_HTML_FLAG_SHOW},
        {id_keys,          "",           ABC_HTML_ATTR_ID,         ABC_HTML_FLAG_SHOW},
-       {font_keys,        "SimHei",     ABC_HTML_ATTR_FONT,      0},
-       {font_size_keys,   "24",         ABC_HTML_ATTR_FONT_SIZE, 0},
+       {font_keys,        "SimHei",     ABC_HTML_ATTR_FONT,       0},
+       {font_size_keys,   "24",         ABC_HTML_ATTR_FONT_SIZE,  0},
        {font_color_keys,  "black",      ABC_HTML_ATTR_FONT_COLOR, ABC_HTML_FLAG_SHOW},
        {text_align_keys,  "left",       ABC_HTML_ATTR_TEXT_ALIGN, ABC_HTML_FLAG_SHOW},
        {font_color_keys,  "black",      ABC_HTML_ATTR_FONT_COLOR, ABC_HTML_FLAG_SHOW},
        {text_align_keys,  "left",       ABC_HTML_ATTR_TEXT_ALIGN, ABC_HTML_FLAG_SHOW},
+
+       {bg_color_keys,    "",           ABC_HTML_ATTR_BG_COLOR,   ABC_HTML_FLAG_SHOW},
 };
 
 static html_attr_t  h5_attrs[] =
 {
        {class_keys,       "",           ABC_HTML_ATTR_CLASS,      ABC_HTML_FLAG_SHOW},
 };
 
 static html_attr_t  h5_attrs[] =
 {
        {class_keys,       "",           ABC_HTML_ATTR_CLASS,      ABC_HTML_FLAG_SHOW},
+       {style_keys,       "",           ABC_HTML_ATTR_STYLE,      ABC_HTML_FLAG_SHOW},
        {id_keys,          "",           ABC_HTML_ATTR_ID,         ABC_HTML_FLAG_SHOW},
        {id_keys,          "",           ABC_HTML_ATTR_ID,         ABC_HTML_FLAG_SHOW},
-       {font_keys,        "SimHei",     ABC_HTML_ATTR_FONT,      0},
-       {font_size_keys,   "20",         ABC_HTML_ATTR_FONT_SIZE, 0},
+       {font_keys,        "SimHei",     ABC_HTML_ATTR_FONT,       0},
+       {font_size_keys,   "20",         ABC_HTML_ATTR_FONT_SIZE,  0},
        {font_color_keys,  "black",      ABC_HTML_ATTR_FONT_COLOR, ABC_HTML_FLAG_SHOW},
        {text_align_keys,  "left",       ABC_HTML_ATTR_TEXT_ALIGN, ABC_HTML_FLAG_SHOW},
        {font_color_keys,  "black",      ABC_HTML_ATTR_FONT_COLOR, ABC_HTML_FLAG_SHOW},
        {text_align_keys,  "left",       ABC_HTML_ATTR_TEXT_ALIGN, ABC_HTML_FLAG_SHOW},
+
+       {bg_color_keys,    "",           ABC_HTML_ATTR_BG_COLOR,   ABC_HTML_FLAG_SHOW},
 };
 
 static html_attr_t  h6_attrs[] =
 {
        {class_keys,       "",           ABC_HTML_ATTR_CLASS,      ABC_HTML_FLAG_SHOW},
 };
 
 static html_attr_t  h6_attrs[] =
 {
        {class_keys,       "",           ABC_HTML_ATTR_CLASS,      ABC_HTML_FLAG_SHOW},
+       {style_keys,       "",           ABC_HTML_ATTR_STYLE,      ABC_HTML_FLAG_SHOW},
        {id_keys,          "",           ABC_HTML_ATTR_ID,         ABC_HTML_FLAG_SHOW},
        {id_keys,          "",           ABC_HTML_ATTR_ID,         ABC_HTML_FLAG_SHOW},
-       {font_keys,        "SimHei",     ABC_HTML_ATTR_FONT,      0},
-       {font_size_keys,   "16",         ABC_HTML_ATTR_FONT_SIZE, 0},
+       {font_keys,        "SimHei",     ABC_HTML_ATTR_FONT,       0},
+       {font_size_keys,   "16",         ABC_HTML_ATTR_FONT_SIZE,  0},
        {font_color_keys,  "black",      ABC_HTML_ATTR_FONT_COLOR, ABC_HTML_FLAG_SHOW},
        {text_align_keys,  "left",       ABC_HTML_ATTR_TEXT_ALIGN, ABC_HTML_FLAG_SHOW},
        {font_color_keys,  "black",      ABC_HTML_ATTR_FONT_COLOR, ABC_HTML_FLAG_SHOW},
        {text_align_keys,  "left",       ABC_HTML_ATTR_TEXT_ALIGN, ABC_HTML_FLAG_SHOW},
+
+       {bg_color_keys,    "",           ABC_HTML_ATTR_BG_COLOR,   ABC_HTML_FLAG_SHOW},
 };
 
 static html_attr_t  p_attrs[] =
 {
        {class_keys,       "",           ABC_HTML_ATTR_CLASS,      ABC_HTML_FLAG_SHOW},
 };
 
 static html_attr_t  p_attrs[] =
 {
        {class_keys,       "",           ABC_HTML_ATTR_CLASS,      ABC_HTML_FLAG_SHOW},
+       {style_keys,       "",           ABC_HTML_ATTR_STYLE,      ABC_HTML_FLAG_SHOW},
        {id_keys,          "",           ABC_HTML_ATTR_ID,         ABC_HTML_FLAG_SHOW},
        {font_keys,        "SimSong",    ABC_HTML_ATTR_FONT,       0},
        {font_size_keys,   "16",         ABC_HTML_ATTR_FONT_SIZE,  0},
        {font_color_keys,  "black",      ABC_HTML_ATTR_FONT_COLOR, ABC_HTML_FLAG_SHOW},
        {text_align_keys,  "left",       ABC_HTML_ATTR_TEXT_ALIGN, ABC_HTML_FLAG_SHOW},
        {id_keys,          "",           ABC_HTML_ATTR_ID,         ABC_HTML_FLAG_SHOW},
        {font_keys,        "SimSong",    ABC_HTML_ATTR_FONT,       0},
        {font_size_keys,   "16",         ABC_HTML_ATTR_FONT_SIZE,  0},
        {font_color_keys,  "black",      ABC_HTML_ATTR_FONT_COLOR, ABC_HTML_FLAG_SHOW},
        {text_align_keys,  "left",       ABC_HTML_ATTR_TEXT_ALIGN, ABC_HTML_FLAG_SHOW},
+
+       {bg_color_keys,    "",           ABC_HTML_ATTR_BG_COLOR,   ABC_HTML_FLAG_SHOW},
 };
 
 static html_attr_t  css_id_attrs[] =
 };
 
 static html_attr_t  css_id_attrs[] =
@@ -191,6 +217,8 @@ static html_attr_t  b_attrs[] =
        {font_bold_keys,   "true",       ABC_HTML_ATTR_FONT_BOLD,  0},
        {font_color_keys,  "black",      ABC_HTML_ATTR_FONT_COLOR, ABC_HTML_FLAG_SHOW},
        {text_align_keys,  "left",       ABC_HTML_ATTR_TEXT_ALIGN, ABC_HTML_FLAG_SHOW},
        {font_bold_keys,   "true",       ABC_HTML_ATTR_FONT_BOLD,  0},
        {font_color_keys,  "black",      ABC_HTML_ATTR_FONT_COLOR, ABC_HTML_FLAG_SHOW},
        {text_align_keys,  "left",       ABC_HTML_ATTR_TEXT_ALIGN, ABC_HTML_FLAG_SHOW},
+
+       {bg_color_keys,    "",           ABC_HTML_ATTR_BG_COLOR,   ABC_HTML_FLAG_SHOW},
 };
 
 static html_attr_t  i_attrs[] =
 };
 
 static html_attr_t  i_attrs[] =
@@ -200,6 +228,8 @@ static html_attr_t  i_attrs[] =
        {font_italic_keys, "true",       ABC_HTML_ATTR_FONT_ITALIC, 0},
        {font_color_keys,  "black",      ABC_HTML_ATTR_FONT_COLOR,  ABC_HTML_FLAG_SHOW},
        {text_align_keys,  "left",       ABC_HTML_ATTR_TEXT_ALIGN,  ABC_HTML_FLAG_SHOW},
        {font_italic_keys, "true",       ABC_HTML_ATTR_FONT_ITALIC, 0},
        {font_color_keys,  "black",      ABC_HTML_ATTR_FONT_COLOR,  ABC_HTML_FLAG_SHOW},
        {text_align_keys,  "left",       ABC_HTML_ATTR_TEXT_ALIGN,  ABC_HTML_FLAG_SHOW},
+
+       {bg_color_keys,    "",           ABC_HTML_ATTR_BG_COLOR,   ABC_HTML_FLAG_SHOW},
 };
 
 static html_attr_t  a_attrs[] =
 };
 
 static html_attr_t  a_attrs[] =
index 7092e64ffcce5bdbf96d8ac02c2d3cf6b323a0d0..d21edd1e73857d7532a0967e41151a778935c585 100644 (file)
@@ -47,6 +47,7 @@ struct abc_io_s
 
 abc_char_t*  __io_pop_char (abc_io_t*  io);
 void         __io_push_char(abc_io_t*  io, abc_char_t* c);
 
 abc_char_t*  __io_pop_char (abc_io_t*  io);
 void         __io_push_char(abc_io_t*  io, abc_char_t* c);
-int          __io_url_path (abc_io_t** io, scf_string_t** spath, const char* main, const char* current);
+int          __io_url_path (abc_io_t** io, scf_string_t** spath, const char* main, const char* current, size_t current_len);
+int          __io_url_css  (abc_io_t** io, scf_string_t** spath, const char* main, const char* current);
 
 #endif
 
 #endif
index fc86416d0f2474525136308beecace648f693b4f..a96ee22e808c98a03a57952dca56f28b0cc0f0c4 100644 (file)
@@ -96,7 +96,7 @@ void __io_push_char(abc_io_t* io, abc_char_t* c)
        io->tmp_list = c;
 }
 
        io->tmp_list = c;
 }
 
-int __io_url_path(abc_io_t** io, scf_string_t** spath, const char* main, const char* current)
+int __io_url_path(abc_io_t** io, scf_string_t** spath, const char* main, const char* current, size_t current_len)
 {
        scf_string_t* path = scf_string_alloc();
        if (!path)
 {
        scf_string_t* path = scf_string_alloc();
        if (!path)
@@ -148,13 +148,13 @@ int __io_url_path(abc_io_t** io, scf_string_t** spath, const char* main, const c
                prefix = 7;
                proto  = ABC_PROTO_FILE;
 
                prefix = 7;
                proto  = ABC_PROTO_FILE;
 
-               ret = scf_string_copy_cstr(path, current);
+               ret = scf_string_copy_cstr_len(path, current, current_len);
 
        } else if (!strncmp(current, "http://", 7)) {
                prefix = 7;
                proto  = ABC_PROTO_HTTP;
 
 
        } else if (!strncmp(current, "http://", 7)) {
                prefix = 7;
                proto  = ABC_PROTO_HTTP;
 
-               ret = scf_string_copy_cstr(path, current);
+               ret = scf_string_copy_cstr_len(path, current, current_len);
        } else {
                if (prefix < 0) {
                        prefix = 0;
        } else {
                if (prefix < 0) {
                        prefix = 0;
@@ -169,7 +169,7 @@ int __io_url_path(abc_io_t** io, scf_string_t** spath, const char* main, const c
                        }
                }
 
                        }
                }
 
-               ret = scf_string_cat_cstr(path, current);
+               ret = scf_string_cat_cstr_len(path, current, current_len);
        }
 
        if (ret < 0) {
        }
 
        if (ret < 0) {
@@ -181,3 +181,17 @@ int __io_url_path(abc_io_t** io, scf_string_t** spath, const char* main, const c
        *spath = path;
        return prefix;
 }
        *spath = path;
        return prefix;
 }
+
+int __io_url_css(abc_io_t** io, scf_string_t** spath, const char* main, const char* current)
+{
+       if (strncmp(current, "url('", 5))
+               return -EINVAL;
+
+       const char* p0 = current + 5;
+       const char* p  = p0;
+
+       while (*p && '\'' != *p)
+               p++;
+
+       return __io_url_path(io, spath, main, p0, (size_t)(p - p0));
+}
index a1177fff78f7f76a4fab63c0f1a64335556fbc14..d97be6df5c240512dbf86b5f8269ec2428f81437 100644 (file)
@@ -166,7 +166,8 @@ abc_obj_t* abc_obj_find_attr(abc_obj_t* obj, int key)
 
        while (obj) {
                attr = abc_obj_get_attr(obj, key);
 
        while (obj) {
                attr = abc_obj_get_attr(obj, key);
-               if (attr)
+
+               if (attr && attr->value && attr->value->len > 0)
                        return attr;
 
                obj = obj->parent;
                        return attr;
 
                obj = obj->parent;
@@ -193,7 +194,6 @@ 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);
 
        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);
 
index 2701a74b03a8351710ef8fae9678d224ee6427d6..c114b4a36e0314dfdafd67f152581e973ad840cb 100644 (file)
@@ -69,6 +69,7 @@ enum abc_objs
        ABC_HTML_ATTR_NAME,
        ABC_HTML_ATTR_VALUE,
        ABC_HTML_ATTR_CLASS,
        ABC_HTML_ATTR_NAME,
        ABC_HTML_ATTR_VALUE,
        ABC_HTML_ATTR_CLASS,
+       ABC_HTML_ATTR_STYLE,
 
        ABC_HTML_ATTR_HREF,
        ABC_HTML_ATTR_SRC,
 
        ABC_HTML_ATTR_HREF,
        ABC_HTML_ATTR_SRC,
@@ -87,6 +88,9 @@ enum abc_objs
 
        ABC_HTML_ATTR_TEXT_ALIGN,
 
 
        ABC_HTML_ATTR_TEXT_ALIGN,
 
+       ABC_HTML_ATTR_BG_COLOR,
+       ABC_HTML_ATTR_BG_IMAGE,
+
        ABC_HTML_ATTR_WIDTH,
        ABC_HTML_ATTR_HEIGHT,
 
        ABC_HTML_ATTR_WIDTH,
        ABC_HTML_ATTR_HEIGHT,
 
index 6aa23e1d430633da029f30466f8cf9dce285174b..6b097916e881c6c61dcec7cd472d2aa4a528fd97 100644 (file)
@@ -25,6 +25,9 @@ CFILES += abc_render_head.c
 CFILES += abc_render_body.c
 CFILES += abc_render_div.c
 
 CFILES += abc_render_body.c
 CFILES += abc_render_div.c
 
+CFILES += abc_render_bg_color.c
+CFILES += abc_render_bg_image.c
+
 CFILES += abc_render_empty.c
 
 CFILES += abc_render_h1.c
 CFILES += abc_render_empty.c
 
 CFILES += abc_render_h1.c
index d2a41c6c6eed405d0843e5054d93298093d3f300..d8cb26dc035379ad6cf4bb9daec3cf57a15f26c6 100644 (file)
@@ -29,7 +29,7 @@ static abc_layout_pt abc_layouts[ABC_HTML_NB] =
        [ABC_HTML]          = abc_layout_html,
        [ABC_HTML_TITLE]    = abc_layout_title,
        [ABC_HTML_HEAD]     = abc_layout_head,
        [ABC_HTML]          = abc_layout_html,
        [ABC_HTML_TITLE]    = abc_layout_title,
        [ABC_HTML_HEAD]     = abc_layout_head,
-       [ABC_HTML_BODY]     = abc_layout_h1,
+       [ABC_HTML_BODY]     = abc_layout_body,
        [ABC_HTML_DIV]      = abc_layout_div,
 
        [ABC_HTML_META]     = abc_layout_empty,
        [ABC_HTML_DIV]      = abc_layout_div,
 
        [ABC_HTML_META]     = abc_layout_empty,
@@ -144,6 +144,12 @@ int abc_layout_root(abc_ctx_t* abc, abc_obj_t* root, int width, int height)
 
        switch (root->type)
        {
 
        switch (root->type)
        {
+               case ABC_HTML_SCRIPT:
+               case ABC_HTML_STYLE:
+               case ABC_HTML_LINK:
+                       return 0;
+                       break;
+
                case ABC_HTML_BODY:
                        root->w = width;
                        root->h = height;
                case ABC_HTML_BODY:
                        root->w = width;
                        root->h = height;
index 45f209cc8719854ecec5966e5443ec3d8965ce74..bfdbd97dd117601d04f54ac72bd12124b26d025f 100644 (file)
@@ -30,7 +30,7 @@ static abc_render_t* abc_renders[ABC_HTML_NB] =
 {
        [ABC_HTML]          = &abc_render_empty,
        [ABC_HTML_HEAD]     = &abc_render_empty,
 {
        [ABC_HTML]          = &abc_render_empty,
        [ABC_HTML_HEAD]     = &abc_render_empty,
-       [ABC_HTML_BODY]     = &abc_render_h1,
+       [ABC_HTML_BODY]     = &abc_render_body,
        [ABC_HTML_META]     = &abc_render_empty,
        [ABC_HTML_TITLE]    = &abc_render_title,
        [ABC_HTML_DIV]      = &abc_render_div,
        [ABC_HTML_META]     = &abc_render_empty,
        [ABC_HTML_TITLE]    = &abc_render_title,
        [ABC_HTML_DIV]      = &abc_render_div,
@@ -104,6 +104,17 @@ int abc_render_draw(abc_obj_t* obj, int width, int height)
 
 static int __render_root(abc_ctx_t* ctx, abc_obj_t* root, int width, int height)
 {
 
 static int __render_root(abc_ctx_t* ctx, abc_obj_t* root, int width, int height)
 {
+       switch (root->type)
+       {
+               case ABC_HTML_SCRIPT:
+               case ABC_HTML_STYLE:
+               case ABC_HTML_LINK:
+                       return 0;
+                       break;
+               default:
+                       break;
+       };
+
        scf_list_t* l;
        abc_obj_t*  child;
 
        scf_list_t* l;
        abc_obj_t*  child;
 
diff --git a/ui/abc_render_bg_color.c b/ui/abc_render_bg_color.c
new file mode 100644 (file)
index 0000000..e7ae029
--- /dev/null
@@ -0,0 +1,101 @@
+#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 vec4 bgColor; \n"
+       "void main() { \n"
+       "    vec2 xy = v_texCoord; \n"
+       "    outputColor = bgColor; \n"
+       "} \n";
+
+
+static GLuint program = 0;
+
+static GLuint vao = 0;
+static GLuint buffers[2] = {0};
+
+static GLuint uniform_mvp;
+static GLuint uniform_bgColor;
+
+
+static int _render_fini_bg_color(abc_render_t* render)
+{
+       return 0;
+}
+
+static int _render_draw_bg_color(abc_render_t* render, abc_obj_t* obj, int width, int height)
+{
+       if (0 == program)
+               __init_program(&program, vert_shader, frag_shader);
+
+       if (0 == vao)
+               __init_buffers(&vao, buffers);
+
+       double r = 0.0;
+       double g = 0.0;
+       double b = 0.0;
+
+       abc_obj_t* attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_BG_COLOR);
+       if (attr)
+               abc_css_color(&r, &g, &b, attr->value->data);
+
+       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);
+
+       GLfloat vert_update[] =
+       {
+                2.0 *  obj->x           / (float)width  - 1.0,
+               -2.0 * (obj->y + obj->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 *  obj->x           / (float)width  - 1.0,
+               -2.0 *  obj->y           / (float)height + 1.0,
+
+                2.0 * (obj->x + obj->w) / (float)width  - 1.0,
+               -2.0 *  obj->y           / (float)height + 1.0,
+       };
+
+       glUseProgram(program);
+       uniform_bgColor = glGetUniformLocation(program, "bgColor");
+       uniform_mvp     = glGetUniformLocation(program, "mvp");
+
+       glUniformMatrix4fv(uniform_mvp,     1, GL_FALSE, mvp);
+       glUniform4f       (uniform_bgColor, r, g, b, 1.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);
+
+       glBindVertexArray(0);
+       glUseProgram(0);
+       return 0;
+}
+
+abc_render_t  abc_render_bg_color =
+{
+       .type = ABC_HTML_ATTR_BG_COLOR,
+
+       .draw = _render_draw_bg_color,
+       .fini = _render_fini_bg_color,
+};
diff --git a/ui/abc_render_bg_image.c b/ui/abc_render_bg_image.c
new file mode 100644 (file)
index 0000000..4ac8667
--- /dev/null
@@ -0,0 +1,175 @@
+#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 vec4 bgColor; \n"
+       "uniform vec4 rect; \n"
+       "uniform sampler2D tex_rgba; \n"
+       "void main() { \n"
+       "    vec2 xy = v_texCoord; \n"
+       "    if (rect.x < xy.x && xy.x < rect.x + rect.z \n"
+       "     && rect.y < xy.y && xy.y < rect.y + rect.w) { \n"
+       "        xy.x = (xy.x - rect.x) / rect.z; \n"
+       "        xy.y = (xy.y - rect.y) / rect.w; \n"
+       "        vec4 v = texture2D(tex_rgba, xy).rgba; \n"
+       "        outputColor = vec4(v.b, v.g, v.r, 1.0); \n"
+       "    } else { \n"
+       "        outputColor = bgColor; \n"
+       "    } \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_rect;
+static GLuint uniform_color;
+
+static int _render_fini_bg_image(abc_render_t* render)
+{
+       return 0;
+}
+
+static int _render_draw_bg_image(abc_render_t* render, abc_obj_t* obj, int width, int height)
+{
+       abc_obj_t* attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_BG_IMAGE);
+       if (!attr)
+               return 0;
+       if (!attr->value || attr->value->len <= 0)
+               return 0;
+
+       scf_string_t* spath = NULL;
+       abc_io_t*     io    = NULL;
+       abc_img_t*    img   = NULL;
+
+       int ret = __io_url_css(&io, &spath, obj->file->data, attr->value->data);
+       if (ret < 0)
+               return ret;
+
+       scf_logi("background-image: %s\n", spath->data);
+
+       ret = abc_img_open(&img, spath->data);
+
+       scf_string_free(spath);
+       spath = NULL;
+       if (ret < 0)
+               return ret;
+
+       uint8_t* bgra = calloc(1, img->width * img->height * 4);
+       if (!bgra) {
+               abc_img_close(img);
+               return -ENOMEM;
+       }
+
+       ret = abc_img_read(img, bgra, img->width * img->height * 4);
+       if (ret < 0) {
+               abc_img_close(img);
+               free(bgra);
+               return ret;
+       }
+
+       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);
+
+       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_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 *  obj->x           / (float)width  - 1.0,
+               -2.0 * (obj->y + obj->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 *  obj->x           / (float)width  - 1.0,
+               -2.0 *  obj->y           / (float)height + 1.0,
+
+                2.0 * (obj->x + obj->w) / (float)width  - 1.0,
+               -2.0 *  obj->y           / (float)height + 1.0,
+       };
+
+       GLfloat x = 0.0;
+       GLfloat y = 0.0;
+       GLfloat w = img->width  / (float)obj->w;
+       GLfloat h = img->height / (float)obj->h;
+
+       if (w > 1.0 || h > 1.0)
+       {
+               GLfloat max = w > h ? w : h;
+
+               w /= max;
+               h /= max;
+       }
+
+       glUseProgram(program);
+       uniform_color = glGetUniformLocation(program, "bgColor");
+       uniform_rgba  = glGetUniformLocation(program, "tex_rgba");
+       uniform_rect  = glGetUniformLocation(program, "rect");
+       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, 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);
+
+       // 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);
+
+       glBindVertexArray(0);
+       glUseProgram(0);
+
+       abc_img_close(img);
+       free(bgra);
+       return 0;
+}
+
+abc_render_t  abc_render_bg_image =
+{
+       .type = ABC_HTML_ATTR_BG_IMAGE,
+
+       .draw = _render_draw_bg_image,
+       .fini = _render_fini_bg_image,
+};
index 2008e7721e8dde8e0bb4262bea8c946220a25900..866a1a07e26743972c98c1ad46cbe569ce210735 100644 (file)
@@ -1,5 +1,9 @@
 #include"abc.h"
 
 #include"abc.h"
 
+extern abc_render_t  abc_render_h1;
+extern abc_render_t  abc_render_bg_color;
+extern abc_render_t  abc_render_bg_image;
+
 static int _render_fini_body(abc_render_t* render)
 {
        return 0;
 static int _render_fini_body(abc_render_t* render)
 {
        return 0;
@@ -7,12 +11,23 @@ static int _render_fini_body(abc_render_t* render)
 
 static int _render_draw_body(abc_render_t* render, abc_obj_t* obj, int width, int height)
 {
 
 static int _render_draw_body(abc_render_t* render, abc_obj_t* obj, int width, int height)
 {
+       abc_obj_t* attr = abc_obj_get_attr(obj, ABC_HTML_ATTR_BG_IMAGE);
+
+       if (attr && attr->value && attr->value->len > 0)
+       {
+               abc_render_bg_image.draw(&abc_render_bg_image, obj, width, height);
+       } else
+               abc_render_bg_color.draw(&abc_render_bg_color, obj, width, height);
+
+       if (obj->text)
+               abc_render_h1.draw(&abc_render_h1, obj, width, height);
+
        return 0;
 }
 
 abc_render_t  abc_render_body =
 {
        return 0;
 }
 
 abc_render_t  abc_render_body =
 {
-       .type = ABC_HTML_H1,
+       .type = ABC_HTML_BODY,
 
        .draw = _render_draw_body,
        .fini = _render_fini_body,
 
        .draw = _render_draw_body,
        .fini = _render_fini_body,
index beb45e1e194f1308441c8d10e7faabac22c59112..4993ed3f568b496c5adb7298c889d44901f29bcd 100644 (file)
@@ -38,39 +38,9 @@ static int _render_fini_h1(abc_render_t* render)
        return 0;
 }
 
        return 0;
 }
 
-static int _render_draw_h1(abc_render_t* render, abc_obj_t* obj, int width, int height)
+static int __init_text(cairo_t* cr, abc_obj_t* obj)
 {
 {
-       if (!obj->text)
-               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_obj_t*            attr;
-       cairo_text_extents_t  extents;
-       cairo_surface_t*      surface;
-       cairo_t*              cr;
-
-       uint8_t* bgra = calloc(1, obj->w * obj->h * 4);
-       if (!bgra)
-               return -ENOMEM;
-
-       surface = cairo_image_surface_create_for_data(bgra, CAIRO_FORMAT_ARGB32, obj->w, obj->h, obj->w * 4);
-       cr      = cairo_create(surface);
-
-       cairo_set_line_width(cr, 1);
-       cairo_set_source_rgb(cr, 1, 1, 1);
-       cairo_rectangle(cr, 0, 0, obj->w, obj->h);
-       cairo_fill(cr);
-       cairo_stroke(cr);
-
-       attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT);
+       abc_obj_t* attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT);
        if (attr) {
                int bold   = CAIRO_FONT_WEIGHT_NORMAL;
                int italic = CAIRO_FONT_SLANT_NORMAL;
        if (attr) {
                int bold   = CAIRO_FONT_WEIGHT_NORMAL;
                int italic = CAIRO_FONT_SLANT_NORMAL;
@@ -88,9 +58,11 @@ static int _render_draw_h1(abc_render_t* render, abc_obj_t* obj, int width, int
        if (attr)
                cairo_set_font_size(cr, atoi(attr->value->data));
 
        if (attr)
                cairo_set_font_size(cr, atoi(attr->value->data));
 
+       cairo_text_extents_t  extents;
        double r = 0.0;
        double g = 0.0;
        double b = 0.0;
        double r = 0.0;
        double g = 0.0;
        double b = 0.0;
+
        attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_COLOR);
        if (attr)
                abc_css_color(&r, &g, &b, attr->value->data);
        attr = abc_obj_find_attr(obj, ABC_HTML_ATTR_FONT_COLOR);
        if (attr)
                abc_css_color(&r, &g, &b, attr->value->data);
@@ -100,7 +72,46 @@ static int _render_draw_h1(abc_render_t* render, abc_obj_t* obj, int width, int
 
        cairo_move_to  (cr, extents.x_bearing, -extents.y_bearing);
        cairo_show_text(cr, obj->text->data);
 
        cairo_move_to  (cr, extents.x_bearing, -extents.y_bearing);
        cairo_show_text(cr, obj->text->data);
+       return 0;
+}
+
+static int _render_draw_h1(abc_render_t* render, abc_obj_t* obj, int width, int height)
+{
+       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_obj_t*        attr;
+       cairo_surface_t*  surface;
+       cairo_t*          cr;
+
+       uint8_t* bgra = calloc(1, obj->w * obj->h * 4);
+       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);
+
+       surface = cairo_image_surface_create_for_data(bgra, CAIRO_FORMAT_ARGB32, obj->w, obj->h, obj->w * 4);
+       cr      = cairo_create(surface);
+
+       cairo_set_line_width(cr, 1);
+       cairo_set_source_rgb(cr, r, g, b);
+       cairo_rectangle(cr, 0, 0, obj->w, obj->h);
+       cairo_fill(cr);
+       cairo_stroke(cr);
 
 
+       if (obj->text)
+               __init_text(cr, obj);
 //     cairo_surface_write_to_png(surface, "tmp.png");
 
        cairo_destroy(cr);
 //     cairo_surface_write_to_png(surface, "tmp.png");
 
        cairo_destroy(cr);
index e5e2f8763b3e393a31857e584e7c58e42fb9d890..20323ca3654be979a8efde2f2de50c5770e6ff36 100644 (file)
@@ -41,18 +41,11 @@ 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)
 {
 
 static int _render_draw_img(abc_render_t* render, abc_obj_t* obj, int width, int height)
 {
-       scf_list_t*  l;
-       abc_obj_t*   attr;
-       abc_img_t*   img = NULL;
+       abc_obj_t*  attr;
+       abc_img_t*  img = NULL;
 
 
-       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)) {
+       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;
        }
                scf_loge("src image of '%s' not found\n", obj->keys[0]);
                return -1;
        }
@@ -109,7 +102,6 @@ static int _render_draw_img(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);
 
-       // board
        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);
        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);